am 7390d4ab: am 3796594c: am a63cd9f4: Merge "Run finalizers before counting for StrictMode." into klp-modular-dev

* commit '7390d4ab8d12d5ffa5d28341096f4425247204a0':
  Run finalizers before counting for StrictMode.
diff --git a/Android.mk b/Android.mk
index 0355c62..45e9c76 100644
--- a/Android.mk
+++ b/Android.mk
@@ -31,6 +31,10 @@
 # So we first build the framework as a monolithic static library then split it
 # up into smaller pieces.
 # ============================================================
+
+# embedded builds use nothing in frameworks/base
+ifneq ($(ANDROID_BUILD_EMBEDDED),true)
+
 include $(CLEAR_VARS)
 
 # FRAMEWORKS_BASE_SUBDIRS comes from build/core/pathmap.mk
@@ -85,6 +89,8 @@
 	core/java/android/app/backup/IFullBackupRestoreObserver.aidl \
 	core/java/android/app/backup/IRestoreObserver.aidl \
 	core/java/android/app/backup/IRestoreSession.aidl \
+	core/java/android/app/maintenance/IIdleCallback.aidl \
+	core/java/android/app/maintenance/IIdleService.aidl \
 	core/java/android/bluetooth/IBluetooth.aidl \
 	core/java/android/bluetooth/IBluetoothA2dp.aidl \
 	core/java/android/bluetooth/IBluetoothCallback.aidl \
@@ -107,9 +113,9 @@
 	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/ISyncServiceAdapter.aidl \
 	core/java/android/content/ISyncStatusObserver.aidl \
 	core/java/android/content/pm/IPackageDataObserver.aidl \
 	core/java/android/content/pm/IPackageDeleteObserver.aidl \
@@ -152,11 +158,13 @@
 	core/java/android/nfc/INfcAdapterExtras.aidl \
 	core/java/android/nfc/INfcTag.aidl \
 	core/java/android/nfc/INfcCardEmulation.aidl \
+	core/java/android/nfc/INfcUnlockSettings.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 \
+	core/java/android/os/INetworkActivityListener.aidl \
 	core/java/android/os/INetworkManagementService.aidl \
 	core/java/android/os/IPermissionController.aidl \
 	core/java/android/os/IPowerManager.aidl \
@@ -190,7 +198,6 @@
 	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 \
 	core/java/android/view/IOnKeyguardExitResult.aidl \
@@ -256,6 +263,8 @@
 	media/java/android/media/IAudioService.aidl \
 	media/java/android/media/IAudioFocusDispatcher.aidl \
 	media/java/android/media/IAudioRoutesObserver.aidl \
+	media/java/android/media/IMediaHTTPConnection.aidl \
+	media/java/android/media/IMediaHTTPService.aidl \
 	media/java/android/media/IMediaRouterClient.aidl \
 	media/java/android/media/IMediaRouterService.aidl \
 	media/java/android/media/IMediaScannerListener.aidl \
@@ -266,6 +275,11 @@
 	media/java/android/media/IRemoteDisplayProvider.aidl \
 	media/java/android/media/IRemoteVolumeObserver.aidl \
 	media/java/android/media/IRingtonePlayer.aidl \
+	media/java/android/media/session/IMediaController.aidl \
+	media/java/android/media/session/IMediaControllerCallback.aidl \
+	media/java/android/media/session/IMediaSession.aidl \
+	media/java/android/media/session/IMediaSessionCallback.aidl \
+	media/java/android/media/session/IMediaSessionManager.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
 	telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
 	telephony/java/com/android/internal/telephony/ITelephony.aidl \
@@ -291,7 +305,7 @@
 
 LOCAL_MODULE := framework-base
 
-LOCAL_JAR_EXCLUDE_FILES := none
+LOCAL_RMTYPEDEFS := true
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
@@ -376,6 +390,17 @@
 	frameworks/base/core/java/android/os/DropBoxManager.aidl \
 	frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
 	frameworks/base/core/java/android/os/ParcelUuid.aidl \
+	frameworks/base/core/java/android/print/PrinterInfo.aidl \
+	frameworks/base/core/java/android/print/PageRange.aidl \
+	frameworks/base/core/java/android/print/PrintAttributes.aidl \
+	frameworks/base/core/java/android/print/PrinterCapabilitiesInfo.aidl \
+	frameworks/base/core/java/android/print/PrinterId.aidl \
+	frameworks/base/core/java/android/print/PrintJobId.aidl \
+	frameworks/base/core/java/android/print/PrintJobInfo.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityEvent.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityNodeInfo.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityRecord.aidl \
+	frameworks/base/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl \
 	frameworks/base/core/java/android/view/KeyEvent.aidl \
 	frameworks/base/core/java/android/view/MotionEvent.aidl \
 	frameworks/base/core/java/android/view/Surface.aidl \
@@ -593,6 +618,7 @@
 		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
 		-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_stubs_current_intermediates/src \
 		-api $(INTERNAL_PLATFORM_API_FILE) \
+		-removedApi $(INTERNAL_PLATFORM_REMOVED_API_FILE) \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
@@ -792,3 +818,5 @@
 ifeq (,$(ONE_SHOT_MAKEFILE))
 include $(call first-makefiles-under,$(LOCAL_PATH))
 endif
+
+endif # ANDROID_BUILD_EMBEDDED
diff --git a/CleanSpec.mk b/CleanSpec.mk
index ef3f4ae..4f0e603 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -171,6 +171,7 @@
 $(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)
 $(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*)
@@ -185,6 +186,9 @@
 $(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-base_intermediates/src/core/java/android/print/IPrintClient.*)
 $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/services_intermediates)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/media/java/android/media/IMedia*)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework-base_intermediates/src/core/java/android/view/IMagnificationCallbacks*)
+
 # ************************************************
 # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
 # ************************************************
diff --git a/api/current.txt b/api/current.txt
index 28042bf..ec1900e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9,6 +9,7 @@
     field public static final java.lang.String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
     field public static final java.lang.String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
     field public static final java.lang.String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
+    field public static final java.lang.String ACCESS_INPUT_FLINGER = "android.permission.ACCESS_INPUT_FLINGER";
     field public static final java.lang.String ACCESS_LOCATION_EXTRA_COMMANDS = "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";
     field public static final java.lang.String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
     field public static final java.lang.String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
@@ -108,6 +109,7 @@
     field public static final java.lang.String RECEIVE_SMS = "android.permission.RECEIVE_SMS";
     field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
     field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
+    field public static final java.lang.String RECOVERY = "android.permission.RECOVERY";
     field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS";
     field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
     field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
@@ -126,6 +128,7 @@
     field public static final java.lang.String SET_WALLPAPER = "android.permission.SET_WALLPAPER";
     field public static final java.lang.String SET_WALLPAPER_HINTS = "android.permission.SET_WALLPAPER_HINTS";
     field public static final java.lang.String SIGNAL_PERSISTENT_PROCESSES = "android.permission.SIGNAL_PERSISTENT_PROCESSES";
+    field public static final java.lang.String SIM_COMMUNICATION = "android.permission.SIM_COMMUNICATION";
     field public static final java.lang.String STATUS_BAR = "android.permission.STATUS_BAR";
     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";
@@ -396,6 +399,10 @@
     field public static final int content = 16843355; // 0x101025b
     field public static final int contentAuthority = 16843408; // 0x1010290
     field public static final int contentDescription = 16843379; // 0x1010273
+    field public static final int controlX1 = 16843770; // 0x10103fa
+    field public static final int controlX2 = 16843772; // 0x10103fc
+    field public static final int controlY1 = 16843771; // 0x10103fb
+    field public static final int controlY2 = 16843773; // 0x10103fd
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
     field public static final int customNavigationLayout = 16843474; // 0x10102d2
@@ -498,6 +505,7 @@
     field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
     field public static final int fastScrollPreviewBackgroundLeft = 16843575; // 0x1010337
     field public static final int fastScrollPreviewBackgroundRight = 16843576; // 0x1010338
+    field public static final int fastScrollStyle = 16843765; // 0x10103f5
     field public static final int fastScrollTextColor = 16843609; // 0x1010359
     field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
     field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
@@ -523,6 +531,7 @@
     field public static final int format12Hour = 16843722; // 0x10103ca
     field public static final int format24Hour = 16843723; // 0x10103cb
     field public static final int fragment = 16843491; // 0x10102e3
+    field public static final int fragmentBreadCrumbsStyle = 16843764; // 0x10103f4
     field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
     field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
     field public static final int fragmentFadeEnterAnimation = 16843497; // 0x10102e9
@@ -816,6 +825,7 @@
     field public static final int persistent = 16842765; // 0x101000d
     field public static final int persistentDrawingCache = 16842990; // 0x10100ee
     field public static final deprecated int phoneNumber = 16843111; // 0x1010167
+    field public static final int pinned = 16843777; // 0x1010401
     field public static final int pivotX = 16843189; // 0x10101b5
     field public static final int pivotY = 16843190; // 0x10101b6
     field public static final int popupAnimationStyle = 16843465; // 0x10102c9
@@ -879,6 +889,7 @@
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
+    field public static final int requiredForProfile = 16843776; // 0x1010400
     field public static final int requiresFadingEdge = 16843685; // 0x10103a5
     field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
     field public static final int resizeMode = 16843619; // 0x1010363
@@ -949,6 +960,7 @@
     field public static final int shadowRadius = 16843108; // 0x1010164
     field public static final int shape = 16843162; // 0x101019a
     field public static final int shareInterpolator = 16843195; // 0x10101bb
+    field public static final int sharedElementName = 16843774; // 0x10103fe
     field public static final int sharedUserId = 16842763; // 0x101000b
     field public static final int sharedUserLabel = 16843361; // 0x1010261
     field public static final int shouldDisableView = 16843246; // 0x10101ee
@@ -1125,6 +1137,7 @@
     field public static final int tileMode = 16843265; // 0x1010201
     field public static final int timeZone = 16843724; // 0x10103cc
     field public static final int tint = 16843041; // 0x1010121
+    field public static final int tintMode = 16843769; // 0x10103f9
     field public static final int title = 16843233; // 0x10101e1
     field public static final int titleCondensed = 16843234; // 0x10101e2
     field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -1146,9 +1159,11 @@
     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 transitionGroup = 16843775; // 0x10103ff
     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 translationZ = 16843768; // 0x10103f8
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -1205,6 +1220,8 @@
     field public static final int windowBackground = 16842836; // 0x1010054
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
     field public static final int windowContentOverlay = 16842841; // 0x1010059
+    field public static final int windowContentTransitionManager = 16843767; // 0x10103f7
+    field public static final int windowContentTransitions = 16843766; // 0x10103f6
     field public static final int windowDisablePreview = 16843298; // 0x1010222
     field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
     field public static final int windowEnterAnimation = 16842932; // 0x10100b4
@@ -1279,6 +1296,8 @@
     field public static final int dialog_min_width_minor = 17104900; // 0x1050004
     field public static final int notification_large_icon_height = 17104902; // 0x1050006
     field public static final int notification_large_icon_width = 17104901; // 0x1050005
+    field public static final int recents_thumbnail_height = 17104903; // 0x1050007
+    field public static final int recents_thumbnail_width = 17104904; // 0x1050008
     field public static final int thumbnail_height = 17104897; // 0x1050001
     field public static final int thumbnail_width = 17104898; // 0x1050002
   }
@@ -1501,6 +1520,7 @@
     field public static final int selectAll = 16908319; // 0x102001f
     field public static final int selectTextMode = 16908333; // 0x102002d
     field public static final int selectedIcon = 16908302; // 0x102000e
+    field public static final int shared_element_name = 16908334; // 0x102002e
     field public static final int startSelectingText = 16908328; // 0x1020028
     field public static final int stopSelectingText = 16908329; // 0x1020029
     field public static final int summary = 16908304; // 0x1020010
@@ -1640,6 +1660,12 @@
     field public static final int MediaButton_Play = 16973882; // 0x103003a
     field public static final int MediaButton_Previous = 16973880; // 0x1030038
     field public static final int MediaButton_Rew = 16973884; // 0x103003c
+    field public static final int Quantum_ButtonBar = 16974498; // 0x10302a2
+    field public static final int Quantum_ButtonBar_AlertDialog = 16974497; // 0x10302a1
+    field public static final int Quantum_Light_ButtonBar = 16974501; // 0x10302a5
+    field public static final int Quantum_Light_ButtonBar_AlertDialog = 16974500; // 0x10302a4
+    field public static final int Quantum_Light_SegmentedButton = 16974502; // 0x10302a6
+    field public static final int Quantum_SegmentedButton = 16974499; // 0x10302a3
     field public static final int TextAppearance = 16973886; // 0x103003e
     field public static final int TextAppearance_DeviceDefault = 16974253; // 0x10301ad
     field public static final int TextAppearance_DeviceDefault_DialogWindowTitle = 16974264; // 0x10301b8
@@ -1715,6 +1741,40 @@
     field public static final int TextAppearance_Large_Inverse = 16973891; // 0x1030043
     field public static final int TextAppearance_Medium = 16973892; // 0x1030044
     field public static final int TextAppearance_Medium_Inverse = 16973893; // 0x1030045
+    field public static final int TextAppearance_Quantum = 16974318; // 0x10301ee
+    field public static final int TextAppearance_Quantum_DialogWindowTitle = 16974319; // 0x10301ef
+    field public static final int TextAppearance_Quantum_Inverse = 16974320; // 0x10301f0
+    field public static final int TextAppearance_Quantum_Large = 16974321; // 0x10301f1
+    field public static final int TextAppearance_Quantum_Large_Inverse = 16974322; // 0x10301f2
+    field public static final int TextAppearance_Quantum_Medium = 16974323; // 0x10301f3
+    field public static final int TextAppearance_Quantum_Medium_Inverse = 16974324; // 0x10301f4
+    field public static final int TextAppearance_Quantum_SearchResult_Subtitle = 16974325; // 0x10301f5
+    field public static final int TextAppearance_Quantum_SearchResult_Title = 16974326; // 0x10301f6
+    field public static final int TextAppearance_Quantum_Small = 16974327; // 0x10301f7
+    field public static final int TextAppearance_Quantum_Small_Inverse = 16974328; // 0x10301f8
+    field public static final int TextAppearance_Quantum_Widget = 16974330; // 0x10301fa
+    field public static final int TextAppearance_Quantum_Widget_ActionBar_Menu = 16974331; // 0x10301fb
+    field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle = 16974332; // 0x10301fc
+    field public static final int TextAppearance_Quantum_Widget_ActionBar_Subtitle_Inverse = 16974333; // 0x10301fd
+    field public static final int TextAppearance_Quantum_Widget_ActionBar_Title = 16974334; // 0x10301fe
+    field public static final int TextAppearance_Quantum_Widget_ActionBar_Title_Inverse = 16974335; // 0x10301ff
+    field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle = 16974336; // 0x1030200
+    field public static final int TextAppearance_Quantum_Widget_ActionMode_Subtitle_Inverse = 16974337; // 0x1030201
+    field public static final int TextAppearance_Quantum_Widget_ActionMode_Title = 16974338; // 0x1030202
+    field public static final int TextAppearance_Quantum_Widget_ActionMode_Title_Inverse = 16974339; // 0x1030203
+    field public static final int TextAppearance_Quantum_Widget_Button = 16974340; // 0x1030204
+    field public static final int TextAppearance_Quantum_Widget_DropDownHint = 16974341; // 0x1030205
+    field public static final int TextAppearance_Quantum_Widget_DropDownItem = 16974342; // 0x1030206
+    field public static final int TextAppearance_Quantum_Widget_EditText = 16974343; // 0x1030207
+    field public static final int TextAppearance_Quantum_Widget_IconMenu_Item = 16974344; // 0x1030208
+    field public static final int TextAppearance_Quantum_Widget_PopupMenu = 16974345; // 0x1030209
+    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Large = 16974346; // 0x103020a
+    field public static final int TextAppearance_Quantum_Widget_PopupMenu_Small = 16974347; // 0x103020b
+    field public static final int TextAppearance_Quantum_Widget_TabWidget = 16974348; // 0x103020c
+    field public static final int TextAppearance_Quantum_Widget_TextView = 16974349; // 0x103020d
+    field public static final int TextAppearance_Quantum_Widget_TextView_PopupMenu = 16974350; // 0x103020e
+    field public static final int TextAppearance_Quantum_Widget_TextView_SpinnerItem = 16974351; // 0x103020f
+    field public static final int TextAppearance_Quantum_WindowTitle = 16974329; // 0x10301f9
     field public static final int TextAppearance_Small = 16973894; // 0x1030046
     field public static final int TextAppearance_Small_Inverse = 16973895; // 0x1030047
     field public static final int TextAppearance_StatusBar_EventContent = 16973927; // 0x1030067
@@ -1809,6 +1869,34 @@
     field public static final int Theme_NoTitleBar_Fullscreen = 16973831; // 0x1030007
     field public static final int Theme_NoTitleBar_OverlayActionModes = 16973930; // 0x103006a
     field public static final int Theme_Panel = 16973913; // 0x1030059
+    field public static final int Theme_Quantum = 16974352; // 0x1030210
+    field public static final int Theme_Quantum_Dialog = 16974353; // 0x1030211
+    field public static final int Theme_Quantum_DialogWhenLarge = 16974357; // 0x1030215
+    field public static final int Theme_Quantum_DialogWhenLarge_NoActionBar = 16974358; // 0x1030216
+    field public static final int Theme_Quantum_Dialog_MinWidth = 16974354; // 0x1030212
+    field public static final int Theme_Quantum_Dialog_NoActionBar = 16974355; // 0x1030213
+    field public static final int Theme_Quantum_Dialog_NoActionBar_MinWidth = 16974356; // 0x1030214
+    field public static final int Theme_Quantum_InputMethod = 16974359; // 0x1030217
+    field public static final int Theme_Quantum_Light = 16974367; // 0x103021f
+    field public static final int Theme_Quantum_Light_DarkActionBar = 16974368; // 0x1030220
+    field public static final int Theme_Quantum_Light_Dialog = 16974369; // 0x1030221
+    field public static final int Theme_Quantum_Light_DialogWhenLarge = 16974373; // 0x1030225
+    field public static final int Theme_Quantum_Light_DialogWhenLarge_NoActionBar = 16974374; // 0x1030226
+    field public static final int Theme_Quantum_Light_Dialog_MinWidth = 16974370; // 0x1030222
+    field public static final int Theme_Quantum_Light_Dialog_NoActionBar = 16974371; // 0x1030223
+    field public static final int Theme_Quantum_Light_Dialog_NoActionBar_MinWidth = 16974372; // 0x1030224
+    field public static final int Theme_Quantum_Light_NoActionBar = 16974375; // 0x1030227
+    field public static final int Theme_Quantum_Light_NoActionBar_Fullscreen = 16974376; // 0x1030228
+    field public static final int Theme_Quantum_Light_NoActionBar_Overscan = 16974377; // 0x1030229
+    field public static final int Theme_Quantum_Light_NoActionBar_TranslucentDecor = 16974378; // 0x103022a
+    field public static final int Theme_Quantum_Light_Panel = 16974379; // 0x103022b
+    field public static final int Theme_Quantum_NoActionBar = 16974360; // 0x1030218
+    field public static final int Theme_Quantum_NoActionBar_Fullscreen = 16974361; // 0x1030219
+    field public static final int Theme_Quantum_NoActionBar_Overscan = 16974362; // 0x103021a
+    field public static final int Theme_Quantum_NoActionBar_TranslucentDecor = 16974363; // 0x103021b
+    field public static final int Theme_Quantum_Panel = 16974364; // 0x103021c
+    field public static final int Theme_Quantum_Wallpaper = 16974365; // 0x103021d
+    field public static final int Theme_Quantum_Wallpaper_NoTitleBar = 16974366; // 0x103021e
     field public static final int Theme_Translucent = 16973839; // 0x103000f
     field public static final int Theme_Translucent_NoTitleBar = 16973840; // 0x1030010
     field public static final int Theme_Translucent_NoTitleBar_Fullscreen = 16973841; // 0x1030011
@@ -1865,6 +1953,8 @@
     field public static final int Widget_DeviceDefault_DropDownItem_Spinner = 16974178; // 0x1030162
     field public static final int Widget_DeviceDefault_EditText = 16974154; // 0x103014a
     field public static final int Widget_DeviceDefault_ExpandableListView = 16974155; // 0x103014b
+    field public static final int Widget_DeviceDefault_FastScroll = 16974316; // 0x10301ec
+    field public static final int Widget_DeviceDefault_FragmentBreadCrumbs = 16974311; // 0x10301e7
     field public static final int Widget_DeviceDefault_GridView = 16974156; // 0x103014c
     field public static final int Widget_DeviceDefault_HorizontalScrollView = 16974171; // 0x103015b
     field public static final int Widget_DeviceDefault_ImageButton = 16974157; // 0x103014d
@@ -1898,6 +1988,8 @@
     field public static final int Widget_DeviceDefault_Light_DropDownItem_Spinner = 16974233; // 0x1030199
     field public static final int Widget_DeviceDefault_Light_EditText = 16974206; // 0x103017e
     field public static final int Widget_DeviceDefault_Light_ExpandableListView = 16974207; // 0x103017f
+    field public static final int Widget_DeviceDefault_Light_FastScroll = 16974317; // 0x10301ed
+    field public static final int Widget_DeviceDefault_Light_FragmentBreadCrumbs = 16974312; // 0x10301e8
     field public static final int Widget_DeviceDefault_Light_GridView = 16974208; // 0x1030180
     field public static final int Widget_DeviceDefault_Light_HorizontalScrollView = 16974226; // 0x1030192
     field public static final int Widget_DeviceDefault_Light_ImageButton = 16974209; // 0x1030181
@@ -1954,6 +2046,7 @@
     field public static final int Widget_DropDownItem_Spinner = 16973868; // 0x103002c
     field public static final int Widget_EditText = 16973859; // 0x1030023
     field public static final int Widget_ExpandableListView = 16973860; // 0x1030024
+    field public static final int Widget_FastScroll = 16974313; // 0x10301e9
     field public static final int Widget_FragmentBreadCrumbs = 16973961; // 0x1030089
     field public static final int Widget_Gallery = 16973877; // 0x1030035
     field public static final int Widget_GridView = 16973874; // 0x1030032
@@ -1985,6 +2078,8 @@
     field public static final int Widget_Holo_DropDownItem_Spinner = 16973995; // 0x10300ab
     field public static final int Widget_Holo_EditText = 16973971; // 0x1030093
     field public static final int Widget_Holo_ExpandableListView = 16973972; // 0x1030094
+    field public static final int Widget_Holo_FastScroll = 16974314; // 0x10301ea
+    field public static final int Widget_Holo_FragmentBreadCrumbs = 16974309; // 0x10301e5
     field public static final int Widget_Holo_GridView = 16973973; // 0x1030095
     field public static final int Widget_Holo_HorizontalScrollView = 16973988; // 0x10300a4
     field public static final int Widget_Holo_ImageButton = 16973974; // 0x1030096
@@ -2018,6 +2113,8 @@
     field public static final int Widget_Holo_Light_DropDownItem_Spinner = 16974041; // 0x10300d9
     field public static final int Widget_Holo_Light_EditText = 16974014; // 0x10300be
     field public static final int Widget_Holo_Light_ExpandableListView = 16974015; // 0x10300bf
+    field public static final int Widget_Holo_Light_FastScroll = 16974315; // 0x10301eb
+    field public static final int Widget_Holo_Light_FragmentBreadCrumbs = 16974310; // 0x10301e6
     field public static final int Widget_Holo_Light_GridView = 16974016; // 0x10300c0
     field public static final int Widget_Holo_Light_HorizontalScrollView = 16974034; // 0x10300d2
     field public static final int Widget_Holo_Light_ImageButton = 16974017; // 0x10300c1
@@ -2087,6 +2184,127 @@
     field public static final int Widget_ProgressBar_Large_Inverse = 16973916; // 0x103005c
     field public static final int Widget_ProgressBar_Small = 16973854; // 0x103001e
     field public static final int Widget_ProgressBar_Small_Inverse = 16973917; // 0x103005d
+    field public static final int Widget_Quantum = 16974380; // 0x103022c
+    field public static final int Widget_Quantum_ActionBar = 16974381; // 0x103022d
+    field public static final int Widget_Quantum_ActionBar_Solid = 16974382; // 0x103022e
+    field public static final int Widget_Quantum_ActionBar_TabBar = 16974383; // 0x103022f
+    field public static final int Widget_Quantum_ActionBar_TabText = 16974384; // 0x1030230
+    field public static final int Widget_Quantum_ActionBar_TabView = 16974385; // 0x1030231
+    field public static final int Widget_Quantum_ActionButton = 16974386; // 0x1030232
+    field public static final int Widget_Quantum_ActionButton_CloseMode = 16974387; // 0x1030233
+    field public static final int Widget_Quantum_ActionButton_Overflow = 16974388; // 0x1030234
+    field public static final int Widget_Quantum_ActionButton_TextButton = 16974389; // 0x1030235
+    field public static final int Widget_Quantum_ActionMode = 16974390; // 0x1030236
+    field public static final int Widget_Quantum_AutoCompleteTextView = 16974391; // 0x1030237
+    field public static final int Widget_Quantum_Button = 16974392; // 0x1030238
+    field public static final int Widget_Quantum_Button_Borderless = 16974393; // 0x1030239
+    field public static final int Widget_Quantum_Button_Borderless_Small = 16974394; // 0x103023a
+    field public static final int Widget_Quantum_Button_Inset = 16974395; // 0x103023b
+    field public static final int Widget_Quantum_Button_Paper = 16974503; // 0x10302a7
+    field public static final int Widget_Quantum_Button_Paper_Color = 16974504; // 0x10302a8
+    field public static final int Widget_Quantum_Button_Small = 16974396; // 0x103023c
+    field public static final int Widget_Quantum_Button_Toggle = 16974397; // 0x103023d
+    field public static final int Widget_Quantum_CalendarView = 16974398; // 0x103023e
+    field public static final int Widget_Quantum_CheckedTextView = 16974399; // 0x103023f
+    field public static final int Widget_Quantum_CompoundButton_CheckBox = 16974400; // 0x1030240
+    field public static final int Widget_Quantum_CompoundButton_RadioButton = 16974401; // 0x1030241
+    field public static final int Widget_Quantum_CompoundButton_Star = 16974402; // 0x1030242
+    field public static final int Widget_Quantum_DatePicker = 16974403; // 0x1030243
+    field public static final int Widget_Quantum_DropDownItem = 16974404; // 0x1030244
+    field public static final int Widget_Quantum_DropDownItem_Spinner = 16974405; // 0x1030245
+    field public static final int Widget_Quantum_EditText = 16974406; // 0x1030246
+    field public static final int Widget_Quantum_ExpandableListView = 16974407; // 0x1030247
+    field public static final int Widget_Quantum_FastScroll = 16974408; // 0x1030248
+    field public static final int Widget_Quantum_FragmentBreadCrumbs = 16974409; // 0x1030249
+    field public static final int Widget_Quantum_GridView = 16974410; // 0x103024a
+    field public static final int Widget_Quantum_HorizontalScrollView = 16974411; // 0x103024b
+    field public static final int Widget_Quantum_ImageButton = 16974412; // 0x103024c
+    field public static final int Widget_Quantum_Light = 16974436; // 0x1030264
+    field public static final int Widget_Quantum_Light_ActionBar = 16974437; // 0x1030265
+    field public static final int Widget_Quantum_Light_ActionBar_Solid = 16974438; // 0x1030266
+    field public static final int Widget_Quantum_Light_ActionBar_Solid_Inverse = 16974439; // 0x1030267
+    field public static final int Widget_Quantum_Light_ActionBar_TabBar = 16974440; // 0x1030268
+    field public static final int Widget_Quantum_Light_ActionBar_TabBar_Inverse = 16974441; // 0x1030269
+    field public static final int Widget_Quantum_Light_ActionBar_TabText = 16974442; // 0x103026a
+    field public static final int Widget_Quantum_Light_ActionBar_TabText_Inverse = 16974443; // 0x103026b
+    field public static final int Widget_Quantum_Light_ActionBar_TabView = 16974444; // 0x103026c
+    field public static final int Widget_Quantum_Light_ActionBar_TabView_Inverse = 16974445; // 0x103026d
+    field public static final int Widget_Quantum_Light_ActionButton = 16974446; // 0x103026e
+    field public static final int Widget_Quantum_Light_ActionButton_CloseMode = 16974447; // 0x103026f
+    field public static final int Widget_Quantum_Light_ActionButton_Overflow = 16974448; // 0x1030270
+    field public static final int Widget_Quantum_Light_ActionMode = 16974450; // 0x1030272
+    field public static final int Widget_Quantum_Light_ActionMode_Inverse = 16974449; // 0x1030271
+    field public static final int Widget_Quantum_Light_AutoCompleteTextView = 16974451; // 0x1030273
+    field public static final int Widget_Quantum_Light_Button = 16974452; // 0x1030274
+    field public static final int Widget_Quantum_Light_Button_Borderless_Small = 16974453; // 0x1030275
+    field public static final int Widget_Quantum_Light_Button_Inset = 16974454; // 0x1030276
+    field public static final int Widget_Quantum_Light_Button_Paper = 16974505; // 0x10302a9
+    field public static final int Widget_Quantum_Light_Button_Paper_Color = 16974506; // 0x10302aa
+    field public static final int Widget_Quantum_Light_Button_Small = 16974455; // 0x1030277
+    field public static final int Widget_Quantum_Light_Button_Toggle = 16974456; // 0x1030278
+    field public static final int Widget_Quantum_Light_CalendarView = 16974457; // 0x1030279
+    field public static final int Widget_Quantum_Light_CheckedTextView = 16974458; // 0x103027a
+    field public static final int Widget_Quantum_Light_CompoundButton_CheckBox = 16974459; // 0x103027b
+    field public static final int Widget_Quantum_Light_CompoundButton_RadioButton = 16974460; // 0x103027c
+    field public static final int Widget_Quantum_Light_CompoundButton_Star = 16974461; // 0x103027d
+    field public static final int Widget_Quantum_Light_DropDownItem = 16974462; // 0x103027e
+    field public static final int Widget_Quantum_Light_DropDownItem_Spinner = 16974463; // 0x103027f
+    field public static final int Widget_Quantum_Light_EditText = 16974464; // 0x1030280
+    field public static final int Widget_Quantum_Light_ExpandableListView = 16974465; // 0x1030281
+    field public static final int Widget_Quantum_Light_FastScroll = 16974466; // 0x1030282
+    field public static final int Widget_Quantum_Light_FragmentBreadCrumbs = 16974467; // 0x1030283
+    field public static final int Widget_Quantum_Light_GridView = 16974468; // 0x1030284
+    field public static final int Widget_Quantum_Light_HorizontalScrollView = 16974469; // 0x1030285
+    field public static final int Widget_Quantum_Light_ImageButton = 16974470; // 0x1030286
+    field public static final int Widget_Quantum_Light_ListPopupWindow = 16974471; // 0x1030287
+    field public static final int Widget_Quantum_Light_ListView = 16974472; // 0x1030288
+    field public static final int Widget_Quantum_Light_ListView_DropDown = 16974473; // 0x1030289
+    field public static final int Widget_Quantum_Light_MediaRouteButton = 16974474; // 0x103028a
+    field public static final int Widget_Quantum_Light_PopupMenu = 16974475; // 0x103028b
+    field public static final int Widget_Quantum_Light_PopupWindow = 16974476; // 0x103028c
+    field public static final int Widget_Quantum_Light_ProgressBar = 16974477; // 0x103028d
+    field public static final int Widget_Quantum_Light_ProgressBar_Horizontal = 16974478; // 0x103028e
+    field public static final int Widget_Quantum_Light_ProgressBar_Inverse = 16974479; // 0x103028f
+    field public static final int Widget_Quantum_Light_ProgressBar_Large = 16974480; // 0x1030290
+    field public static final int Widget_Quantum_Light_ProgressBar_Large_Inverse = 16974481; // 0x1030291
+    field public static final int Widget_Quantum_Light_ProgressBar_Small = 16974482; // 0x1030292
+    field public static final int Widget_Quantum_Light_ProgressBar_Small_Inverse = 16974483; // 0x1030293
+    field public static final int Widget_Quantum_Light_ProgressBar_Small_Title = 16974484; // 0x1030294
+    field public static final int Widget_Quantum_Light_RatingBar = 16974485; // 0x1030295
+    field public static final int Widget_Quantum_Light_RatingBar_Indicator = 16974486; // 0x1030296
+    field public static final int Widget_Quantum_Light_RatingBar_Small = 16974487; // 0x1030297
+    field public static final int Widget_Quantum_Light_ScrollView = 16974488; // 0x1030298
+    field public static final int Widget_Quantum_Light_SeekBar = 16974489; // 0x1030299
+    field public static final int Widget_Quantum_Light_Spinner = 16974490; // 0x103029a
+    field public static final int Widget_Quantum_Light_Tab = 16974491; // 0x103029b
+    field public static final int Widget_Quantum_Light_TabWidget = 16974492; // 0x103029c
+    field public static final int Widget_Quantum_Light_TextView = 16974493; // 0x103029d
+    field public static final int Widget_Quantum_Light_TextView_SpinnerItem = 16974494; // 0x103029e
+    field public static final int Widget_Quantum_Light_WebTextView = 16974495; // 0x103029f
+    field public static final int Widget_Quantum_Light_WebView = 16974496; // 0x10302a0
+    field public static final int Widget_Quantum_ListPopupWindow = 16974413; // 0x103024d
+    field public static final int Widget_Quantum_ListView = 16974414; // 0x103024e
+    field public static final int Widget_Quantum_ListView_DropDown = 16974415; // 0x103024f
+    field public static final int Widget_Quantum_MediaRouteButton = 16974416; // 0x1030250
+    field public static final int Widget_Quantum_PopupMenu = 16974417; // 0x1030251
+    field public static final int Widget_Quantum_PopupWindow = 16974418; // 0x1030252
+    field public static final int Widget_Quantum_ProgressBar = 16974419; // 0x1030253
+    field public static final int Widget_Quantum_ProgressBar_Horizontal = 16974420; // 0x1030254
+    field public static final int Widget_Quantum_ProgressBar_Large = 16974421; // 0x1030255
+    field public static final int Widget_Quantum_ProgressBar_Small = 16974422; // 0x1030256
+    field public static final int Widget_Quantum_ProgressBar_Small_Title = 16974423; // 0x1030257
+    field public static final int Widget_Quantum_RatingBar = 16974424; // 0x1030258
+    field public static final int Widget_Quantum_RatingBar_Indicator = 16974425; // 0x1030259
+    field public static final int Widget_Quantum_RatingBar_Small = 16974426; // 0x103025a
+    field public static final int Widget_Quantum_ScrollView = 16974427; // 0x103025b
+    field public static final int Widget_Quantum_SeekBar = 16974428; // 0x103025c
+    field public static final int Widget_Quantum_Spinner = 16974429; // 0x103025d
+    field public static final int Widget_Quantum_Tab = 16974430; // 0x103025e
+    field public static final int Widget_Quantum_TabWidget = 16974431; // 0x103025f
+    field public static final int Widget_Quantum_TextView = 16974432; // 0x1030260
+    field public static final int Widget_Quantum_TextView_SpinnerItem = 16974433; // 0x1030261
+    field public static final int Widget_Quantum_WebTextView = 16974434; // 0x1030262
+    field public static final int Widget_Quantum_WebView = 16974435; // 0x1030263
     field public static final int Widget_RatingBar = 16973857; // 0x1030021
     field public static final int Widget_ScrollView = 16973869; // 0x103002d
     field public static final int Widget_SeekBar = 16973856; // 0x1030020
@@ -2111,6 +2329,7 @@
     ctor public AccessibilityService();
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
+    method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
     method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public final android.os.IBinder onBind(android.content.Intent);
     method protected boolean onGesture(int);
@@ -2176,6 +2395,7 @@
     field public static final int FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY = 8; // 0x8
     field public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 32; // 0x20
     field public static final int FLAG_REQUEST_TOUCH_EXPLORATION_MODE = 4; // 0x4
+    field public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 64; // 0x40
     field public int eventTypes;
     field public int feedbackType;
     field public int flags;
@@ -2436,11 +2656,23 @@
     method public java.lang.Object evaluate(float, java.lang.Object, java.lang.Object);
   }
 
+  public class FloatArrayEvaluator implements android.animation.TypeEvaluator {
+    ctor public FloatArrayEvaluator();
+    ctor public FloatArrayEvaluator(float[]);
+    method public float[] evaluate(float, float[], float[]);
+  }
+
   public class FloatEvaluator implements android.animation.TypeEvaluator {
     ctor public FloatEvaluator();
     method public java.lang.Float evaluate(float, java.lang.Number, java.lang.Number);
   }
 
+  public class IntArrayEvaluator implements android.animation.TypeEvaluator {
+    ctor public IntArrayEvaluator();
+    ctor public IntArrayEvaluator(int[]);
+    method public int[] evaluate(float, int[], int[]);
+  }
+
   public class IntEvaluator implements android.animation.TypeEvaluator {
     ctor public IntEvaluator();
     method public java.lang.Integer evaluate(float, java.lang.Integer, java.lang.Integer);
@@ -2509,18 +2741,39 @@
     ctor public ObjectAnimator();
     method public java.lang.String getPropertyName();
     method public java.lang.Object getTarget();
+    method public static android.animation.ObjectAnimator ofArgb(java.lang.Object, java.lang.String, int...);
+    method public static android.animation.ObjectAnimator ofArgb(T, android.util.Property<T, java.lang.Integer>, int...);
     method public static android.animation.ObjectAnimator ofFloat(java.lang.Object, java.lang.String, float...);
+    method public static android.animation.ObjectAnimator ofFloat(java.lang.Object, java.lang.String, java.lang.String, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofFloat(T, android.util.Property<T, java.lang.Float>, float...);
+    method public static android.animation.ObjectAnimator ofFloat(T, android.util.Property<T, java.lang.Float>, android.util.Property<T, java.lang.Float>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofInt(java.lang.Object, java.lang.String, int...);
+    method public static android.animation.ObjectAnimator ofInt(java.lang.Object, java.lang.String, java.lang.String, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, int...);
+    method public static android.animation.ObjectAnimator ofInt(T, android.util.Property<T, java.lang.Integer>, android.util.Property<T, java.lang.Integer>, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, float[][]);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiFloat(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, T...);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, int[][]);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, android.graphics.Path);
+    method public static android.animation.ObjectAnimator ofMultiInt(java.lang.Object, java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, T...);
     method public static android.animation.ObjectAnimator ofObject(java.lang.Object, java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
+    method public static android.animation.ObjectAnimator ofObject(java.lang.Object, java.lang.String, android.animation.TypeConverter<android.graphics.PointF, ?>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, P>, android.animation.TypeConverter<V, P>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.ObjectAnimator ofObject(T, android.util.Property<T, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
     method public static android.animation.ObjectAnimator ofPropertyValuesHolder(java.lang.Object, android.animation.PropertyValuesHolder...);
     method public void setAutoCancel(boolean);
     method public void setProperty(android.util.Property);
     method public void setPropertyName(java.lang.String);
   }
 
+  public class PointFEvaluator implements android.animation.TypeEvaluator {
+    ctor public PointFEvaluator();
+    ctor public PointFEvaluator(android.graphics.PointF);
+    method public android.graphics.PointF evaluate(float, android.graphics.PointF, android.graphics.PointF);
+  }
+
   public class PropertyValuesHolder implements java.lang.Cloneable {
     method public android.animation.PropertyValuesHolder clone();
     method public java.lang.String getPropertyName();
@@ -2530,8 +2783,20 @@
     method public static android.animation.PropertyValuesHolder ofInt(android.util.Property<?, java.lang.Integer>, int...);
     method public static android.animation.PropertyValuesHolder ofKeyframe(java.lang.String, android.animation.Keyframe...);
     method public static android.animation.PropertyValuesHolder ofKeyframe(android.util.Property, android.animation.Keyframe...);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, float[][]);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.graphics.Path);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<V, float[]>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofMultiFloat(java.lang.String, android.animation.TypeConverter<T, float[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, int[][]);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.graphics.Path);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<V, int[]>, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofMultiInt(java.lang.String, android.animation.TypeConverter<T, int[]>, android.animation.TypeEvaluator<T>, android.animation.Keyframe...);
     method public static android.animation.PropertyValuesHolder ofObject(java.lang.String, android.animation.TypeEvaluator, java.lang.Object...);
+    method public static android.animation.PropertyValuesHolder ofObject(java.lang.String, android.animation.TypeConverter<android.graphics.PointF, ?>, android.graphics.Path);
     method public static android.animation.PropertyValuesHolder ofObject(android.util.Property, android.animation.TypeEvaluator<V>, V...);
+    method public static android.animation.PropertyValuesHolder ofObject(android.util.Property<?, V>, android.animation.TypeConverter<T, V>, android.animation.TypeEvaluator<T>, T...);
+    method public static android.animation.PropertyValuesHolder ofObject(android.util.Property<?, V>, android.animation.TypeConverter<android.graphics.PointF, V>, android.graphics.Path);
+    method public void setConverter(android.animation.TypeConverter);
     method public void setEvaluator(android.animation.TypeEvaluator);
     method public void setFloatValues(float...);
     method public void setIntValues(int...);
@@ -2543,6 +2808,7 @@
 
   public class RectEvaluator implements android.animation.TypeEvaluator {
     ctor public RectEvaluator();
+    ctor public RectEvaluator(android.graphics.Rect);
     method public android.graphics.Rect evaluate(float, android.graphics.Rect, android.graphics.Rect);
   }
 
@@ -2559,6 +2825,12 @@
     method public abstract float getInterpolation(float);
   }
 
+  public abstract class TypeConverter {
+    ctor public TypeConverter(java.lang.Class<T>, java.lang.Class<V>);
+    method public abstract V convert(T);
+    method public T convertBack(V);
+  }
+
   public abstract interface TypeEvaluator {
     method public abstract T evaluate(float, T, T);
   }
@@ -2577,6 +2849,7 @@
     method public long getStartDelay();
     method public android.animation.PropertyValuesHolder[] getValues();
     method public boolean isRunning();
+    method public static android.animation.ValueAnimator ofArgb(int...);
     method public static android.animation.ValueAnimator ofFloat(float...);
     method public static android.animation.ValueAnimator ofInt(int...);
     method public static android.animation.ValueAnimator ofObject(android.animation.TypeEvaluator, java.lang.Object...);
@@ -2758,6 +3031,8 @@
     method public java.lang.String getCallingPackage();
     method public int getChangingConfigurations();
     method public android.content.ComponentName getComponentName();
+    method public android.transition.Scene getContentScene();
+    method public android.transition.TransitionManager getContentTransitionManager();
     method public android.view.View getCurrentFocus();
     method public android.app.FragmentManager getFragmentManager();
     method public android.content.Intent getIntent();
@@ -2794,6 +3069,8 @@
     method public void onAttachFragment(android.app.Fragment);
     method public void onAttachedToWindow();
     method public void onBackPressed();
+    method public void onCaptureSharedElementEnd();
+    method public void onCaptureSharedElementStart(android.transition.Transition);
     method protected void onChildTitleChanged(android.app.Activity, java.lang.CharSequence);
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public void onContentChanged();
@@ -2864,6 +3141,7 @@
     method public void reportFullyDrawn();
     method public final boolean requestWindowFeature(int);
     method public final void runOnUiThread(java.lang.Runnable);
+    method public void setContentTransitionManager(android.transition.TransitionManager);
     method public void setContentView(int);
     method public void setContentView(android.view.View);
     method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams);
@@ -2879,13 +3157,15 @@
     method public final void setProgressBarIndeterminate(boolean);
     method public final void setProgressBarIndeterminateVisibility(boolean);
     method public final void setProgressBarVisibility(boolean);
+    method public void setRecentsIcon(android.graphics.Bitmap);
+    method public void setRecentsLabel(java.lang.CharSequence);
     method public void setRequestedOrientation(int);
     method public final void setResult(int);
     method public final void setResult(int, android.content.Intent);
     method public final void setSecondaryProgress(int);
     method public void setTitle(java.lang.CharSequence);
     method public void setTitle(int);
-    method public void setTitleColor(int);
+    method public deprecated void setTitleColor(int);
     method public void setVisible(boolean);
     method public final void setVolumeControlStream(int);
     method public boolean shouldUpRecreateTask(android.content.Intent);
@@ -2999,6 +3279,8 @@
     method public void readFromParcel(android.os.Parcel);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
+    field public android.graphics.Bitmap activityIcon;
+    field public java.lang.CharSequence activityLabel;
     field public android.content.Intent baseIntent;
     field public java.lang.CharSequence description;
     field public int id;
@@ -3078,6 +3360,8 @@
   public class ActivityOptions {
     method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
     method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
+    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.view.View, java.lang.String);
+    method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.util.Pair<android.view.View, java.lang.String>...);
     method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
     method public android.os.Bundle toBundle();
     method public void update(android.app.ActivityOptions);
@@ -3168,6 +3452,7 @@
     method public android.app.AlertDialog.Builder setSingleChoiceItems(android.widget.ListAdapter, int, android.content.DialogInterface.OnClickListener);
     method public android.app.AlertDialog.Builder setTitle(int);
     method public android.app.AlertDialog.Builder setTitle(java.lang.CharSequence);
+    method public android.app.AlertDialog.Builder setView(int);
     method public android.app.AlertDialog.Builder setView(android.view.View);
     method public android.app.AlertDialog show();
   }
@@ -3317,6 +3602,7 @@
     method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
     method public void cancel();
     method public void closeOptionsMenu();
+    method public void create();
     method public void dismiss();
     method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
     method public boolean dispatchKeyEvent(android.view.KeyEvent);
@@ -3604,6 +3890,7 @@
     ctor public FragmentBreadCrumbs(android.content.Context);
     ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet);
     ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet, int);
+    ctor public FragmentBreadCrumbs(android.content.Context, android.util.AttributeSet, int, int);
     method public void onBackStackChanged();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setActivity(android.app.Activity);
@@ -3890,6 +4177,7 @@
     ctor public MediaRouteButton(android.content.Context);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet);
     ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public MediaRouteButton(android.content.Context, android.util.AttributeSet, int, int);
     method public int getRouteTypes();
     method public void onAttachedToWindow();
     method public void onDetachedFromWindow();
@@ -3919,6 +4207,20 @@
     method public int describeContents();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String CATEGORY_ALARM = "alarm";
+    field public static final java.lang.String CATEGORY_CALL = "call";
+    field public static final java.lang.String CATEGORY_EMAIL = "email";
+    field public static final java.lang.String CATEGORY_ERROR = "err";
+    field public static final java.lang.String CATEGORY_EVENT = "event";
+    field public static final java.lang.String CATEGORY_MESSAGE = "msg";
+    field public static final java.lang.String CATEGORY_PROGRESS = "progress";
+    field public static final java.lang.String CATEGORY_PROMO = "promo";
+    field public static final java.lang.String CATEGORY_RECOMMENDATION = "recommendation";
+    field public static final java.lang.String CATEGORY_SERVICE = "service";
+    field public static final java.lang.String CATEGORY_SOCIAL = "social";
+    field public static final java.lang.String CATEGORY_STATUS = "status";
+    field public static final java.lang.String CATEGORY_SYSTEM = "sys";
+    field public static final java.lang.String CATEGORY_TRANSPORT = "transport";
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int DEFAULT_ALL = -1; // 0xffffffff
     field public static final int DEFAULT_LIGHTS = 4; // 0x4
@@ -3937,6 +4239,7 @@
     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_TEMPLATE = "android.template";
     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";
@@ -3956,9 +4259,13 @@
     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 static final int VISIBILITY_PRIVATE = 0; // 0x0
+    field public static final int VISIBILITY_PUBLIC = 1; // 0x1
+    field public static final int VISIBILITY_SECRET = -1; // 0xffffffff
     field public android.app.Notification.Action[] actions;
     field public int audioStreamType;
     field public android.widget.RemoteViews bigContentView;
+    field public java.lang.String category;
     field public android.app.PendingIntent contentIntent;
     field public android.widget.RemoteViews contentView;
     field public int defaults;
@@ -3974,10 +4281,12 @@
     field public int ledOnMS;
     field public int number;
     field public int priority;
+    field public android.app.Notification publicVersion;
     field public android.net.Uri sound;
     field public java.lang.CharSequence tickerText;
     field public android.widget.RemoteViews tickerView;
     field public long[] vibrate;
+    field public int visibility;
     field public long when;
   }
 
@@ -4017,6 +4326,7 @@
     method public android.os.Bundle getExtras();
     method public deprecated android.app.Notification getNotification();
     method public android.app.Notification.Builder setAutoCancel(boolean);
+    method public android.app.Notification.Builder setCategory(java.lang.String);
     method public android.app.Notification.Builder setContent(android.widget.RemoteViews);
     method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence);
     method public android.app.Notification.Builder setContentIntent(android.app.PendingIntent);
@@ -4034,6 +4344,7 @@
     method public android.app.Notification.Builder setOnlyAlertOnce(boolean);
     method public android.app.Notification.Builder setPriority(int);
     method public android.app.Notification.Builder setProgress(int, int, boolean);
+    method public android.app.Notification.Builder setPublicVersion(android.app.Notification);
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
@@ -4045,6 +4356,7 @@
     method public android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
     method public android.app.Notification.Builder setUsesChronometer(boolean);
     method public android.app.Notification.Builder setVibrate(long[]);
+    method public android.app.Notification.Builder setVisibility(int);
     method public android.app.Notification.Builder setWhen(long);
   }
 
@@ -4311,6 +4623,7 @@
     method public android.view.accessibility.AccessibilityEvent executeAndWaitForEvent(java.lang.Runnable, android.app.UiAutomation.AccessibilityEventFilter, long) throws java.util.concurrent.TimeoutException;
     method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
     method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
+    method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
     method public boolean injectInputEvent(android.view.InputEvent, boolean);
     method public final boolean performGlobalAction(int);
     method public void setOnAccessibilityEventListener(android.app.UiAutomation.OnAccessibilityEventListener);
@@ -4445,6 +4758,7 @@
     method public void onPasswordExpiring(android.content.Context, android.content.Intent);
     method public void onPasswordFailed(android.content.Context, android.content.Intent);
     method public void onPasswordSucceeded(android.content.Context, android.content.Intent);
+    method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent);
     method public void onReceive(android.content.Context, android.content.Intent);
     field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
     field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
@@ -4453,11 +4767,14 @@
     field public static final java.lang.String ACTION_PASSWORD_EXPIRING = "android.app.action.ACTION_PASSWORD_EXPIRING";
     field public static final java.lang.String ACTION_PASSWORD_FAILED = "android.app.action.ACTION_PASSWORD_FAILED";
     field public static final java.lang.String ACTION_PASSWORD_SUCCEEDED = "android.app.action.ACTION_PASSWORD_SUCCEEDED";
+    field public static final java.lang.String ACTION_PROFILE_PROVISIONING_COMPLETE = "android.app.action.ACTION_PROFILE_PROVISIONING_COMPLETE";
     field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
     field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
   }
 
   public class DevicePolicyManager {
+    method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
+    method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
     method public java.util.List<android.content.ComponentName> getActiveAdmins();
     method public boolean getCameraDisabled(android.content.ComponentName);
     method public int getCurrentFailedPasswordAttempts();
@@ -4482,6 +4799,7 @@
     method public boolean isActivePasswordSufficient();
     method public boolean isAdminActive(android.content.ComponentName);
     method public boolean isDeviceOwnerApp(java.lang.String);
+    method public boolean isProfileOwnerApp(java.lang.String);
     method public void lockNow();
     method public void removeActiveAdmin(android.content.ComponentName);
     method public boolean resetPassword(java.lang.String, int);
@@ -4502,6 +4820,7 @@
     method public int setStorageEncryption(android.content.ComponentName, boolean);
     method public void wipeData(int);
     field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
+    field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.ACTION_PROVISION_MANAGED_PROFILE";
     field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
     field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
     field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
@@ -4510,6 +4829,8 @@
     field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0
     field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION";
     field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME = "defaultManagedProfileName";
+    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "deviceAdminPackageName";
     field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
     field public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0; // 0x0
     field public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 2; // 0x2
@@ -4609,6 +4930,20 @@
 
 }
 
+package android.app.maintenance {
+
+  public abstract class IdleService extends android.app.Service {
+    ctor public IdleService();
+    method public final void finishIdle();
+    method public final android.os.IBinder onBind(android.content.Intent);
+    method public abstract boolean onIdleStart();
+    method public abstract void onIdleStop();
+    field public static final java.lang.String PERMISSION_BIND = "android.permission.BIND_IDLE_SERVICE";
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.idle.IdleService";
+  }
+
+}
+
 package android.appwidget {
 
   public class AppWidgetHost {
@@ -4662,15 +4997,19 @@
     field public static final java.lang.String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
     field public static final java.lang.String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
     field public static final java.lang.String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
+    field public static final java.lang.String ACTION_APPWIDGET_HOST_RESTORED = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
     field public static final java.lang.String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
     field public static final java.lang.String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
+    field public static final java.lang.String ACTION_APPWIDGET_RESTORED = "android.appwidget.action.APPWIDGET_RESTORED";
     field public static final java.lang.String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
     field public static final java.lang.String EXTRA_APPWIDGET_ID = "appWidgetId";
     field public static final java.lang.String EXTRA_APPWIDGET_IDS = "appWidgetIds";
+    field public static final java.lang.String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
     field public static final java.lang.String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
     field public static final java.lang.String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
     field public static final java.lang.String EXTRA_CUSTOM_EXTRAS = "customExtras";
     field public static final java.lang.String EXTRA_CUSTOM_INFO = "customInfo";
+    field public static final java.lang.String EXTRA_HOST_ID = "hostId";
     field public static final int INVALID_APPWIDGET_ID = 0; // 0x0
     field public static final java.lang.String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
     field public static final java.lang.String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
@@ -4687,6 +5026,7 @@
     method public void onDisabled(android.content.Context);
     method public void onEnabled(android.content.Context);
     method public void onReceive(android.content.Context, android.content.Intent);
+    method public void onRestored(android.content.Context, int[], int[]);
     method public void onUpdate(android.content.Context, android.appwidget.AppWidgetManager, int[]);
   }
 
@@ -5761,6 +6101,8 @@
     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 static void cancelSync(android.content.ComponentName);
+    method public static void cancelSync(android.content.SyncRequest);
     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();
@@ -5769,14 +6111,18 @@
     method public static boolean getMasterSyncAutomatically();
     method public java.util.List<android.content.UriPermission> getOutgoingPersistedUriPermissions();
     method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.accounts.Account, java.lang.String);
+    method public static java.util.List<android.content.PeriodicSync> getPeriodicSyncs(android.content.ComponentName);
     method public java.util.List<android.content.UriPermission> getPersistedUriPermissions();
     method public java.lang.String[] getStreamTypes(android.net.Uri, java.lang.String);
     method public static android.content.SyncAdapterType[] getSyncAdapterTypes();
     method public static boolean getSyncAutomatically(android.accounts.Account, java.lang.String);
     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 static boolean isServiceActive(android.content.ComponentName);
     method public static boolean isSyncActive(android.accounts.Account, java.lang.String);
+    method public static boolean isSyncActive(android.content.ComponentName);
     method public static boolean isSyncPending(android.accounts.Account, java.lang.String);
+    method public static boolean isSyncPending(android.content.ComponentName);
     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;
@@ -5798,6 +6144,7 @@
     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 setServiceActive(android.content.ComponentName, 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 void takePersistableUriPermission(android.net.Uri, int);
@@ -5805,6 +6152,7 @@
     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);
+    field public static final java.lang.String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*";
     field public static final java.lang.String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir";
     field public static final java.lang.String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item";
     field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource";
@@ -5903,6 +6251,7 @@
     method public abstract android.content.ContentResolver getContentResolver();
     method public abstract java.io.File getDatabasePath(java.lang.String);
     method public abstract java.io.File getDir(java.lang.String, int);
+    method public final android.graphics.drawable.Drawable getDrawable(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);
@@ -5984,6 +6333,7 @@
     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";
@@ -6002,6 +6352,7 @@
     field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";
     field public static final java.lang.String LOCATION_SERVICE = "location";
     field public static final java.lang.String MEDIA_ROUTER_SERVICE = "media_router";
+    field public static final java.lang.String MEDIA_SESSION_SERVICE = "media_session";
     field public static final int MODE_APPEND = 32768; // 0x8000
     field public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8; // 0x8
     field public static final int MODE_MULTI_PROCESS = 4; // 0x4
@@ -6527,6 +6878,7 @@
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
     field public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; // 0x8000000
+    field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 268959744; // 0x10080000
     field public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; // 0x10000000
     field public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; // 0x10000
     field public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; // 0x40000000
@@ -6743,7 +7095,9 @@
     field public final android.accounts.Account account;
     field public final java.lang.String authority;
     field public final android.os.Bundle extras;
+    field public final boolean isService;
     field public final long period;
+    field public final android.content.ComponentName service;
   }
 
   public class ReceiverCallNotAllowedException extends android.util.AndroidRuntimeException {
@@ -6859,11 +7213,13 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public final android.accounts.Account account;
     field public final java.lang.String authority;
+    field public final android.content.ComponentName service;
     field public final long startTime;
   }
 
   public class SyncRequest implements android.os.Parcelable {
     method public int describeContents();
+    method public boolean isExpedited();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -6878,7 +7234,10 @@
     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 setPriority(int);
     method public android.content.SyncRequest.Builder setSyncAdapter(android.accounts.Account, java.lang.String);
+    method public android.content.SyncRequest.Builder setSyncAdapter(android.content.ComponentName);
+    method public android.content.SyncRequest.Builder setTransferSize(long, long);
     method public android.content.SyncRequest.Builder syncOnce();
     method public android.content.SyncRequest.Builder syncPeriodic(long, long);
   }
@@ -6906,6 +7265,13 @@
     field public boolean tooManyRetries;
   }
 
+  public abstract class SyncService extends android.app.Service {
+    ctor public SyncService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public abstract void onPerformSync(android.os.Bundle, android.content.SyncResult);
+    method protected boolean parallelSyncsEnabled();
+  }
+
   public class SyncStats implements android.os.Parcelable {
     ctor public SyncStats();
     ctor public SyncStats(android.os.Parcel);
@@ -7564,7 +7930,6 @@
   public final class AssetManager.AssetInputStream extends java.io.InputStream {
     method public final int available() throws java.io.IOException;
     method public final void close() throws java.io.IOException;
-    method public final int getAssetInt();
     method public final void mark(int);
     method public final boolean markSupported();
     method public final int read() throws java.io.IOException;
@@ -7580,6 +7945,7 @@
     method public int describeContents();
     method public int getColorForState(int[], int);
     method public int getDefaultColor();
+    method public boolean isOpaque();
     method public boolean isStateful();
     method public static android.content.res.ColorStateList valueOf(int);
     method public android.content.res.ColorStateList withAlpha(int);
@@ -7712,7 +8078,9 @@
     method public int getDimensionPixelSize(int) throws android.content.res.Resources.NotFoundException;
     method public android.util.DisplayMetrics getDisplayMetrics();
     method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawable(int, android.content.res.Resources.Theme) throws android.content.res.Resources.NotFoundException;
     method public android.graphics.drawable.Drawable getDrawableForDensity(int, int) throws android.content.res.Resources.NotFoundException;
+    method public android.graphics.drawable.Drawable getDrawableForDensity(int, int, android.content.res.Resources.Theme);
     method public float getFraction(int, int, int);
     method public int getIdentifier(java.lang.String, java.lang.String, java.lang.String);
     method public int[] getIntArray(int) throws android.content.res.Resources.NotFoundException;
@@ -7756,6 +8124,7 @@
   public final class Resources.Theme {
     method public void applyStyle(int, boolean);
     method public void dump(int, java.lang.String, java.lang.String);
+    method public android.graphics.drawable.Drawable getDrawable(int) throws android.content.res.Resources.NotFoundException;
     method public android.content.res.TypedArray obtainStyledAttributes(int[]);
     method public android.content.res.TypedArray obtainStyledAttributes(int, int[]) throws android.content.res.Resources.NotFoundException;
     method public android.content.res.TypedArray obtainStyledAttributes(android.util.AttributeSet, int[], int, int);
@@ -8769,6 +9138,7 @@
     ctor public GestureOverlayView(android.content.Context);
     ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet);
     ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet, int);
+    ctor public GestureOverlayView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addOnGestureListener(android.gesture.GestureOverlayView.OnGestureListener);
     method public void addOnGesturePerformedListener(android.gesture.GestureOverlayView.OnGesturePerformedListener);
     method public void addOnGesturingListener(android.gesture.GestureOverlayView.OnGesturingListener);
@@ -9237,6 +9607,9 @@
   public class ColorMatrixColorFilter extends android.graphics.ColorFilter {
     ctor public ColorMatrixColorFilter(android.graphics.ColorMatrix);
     ctor public ColorMatrixColorFilter(float[]);
+    method public android.graphics.ColorMatrix getColorMatrix();
+    method public void setColorMatrix(android.graphics.ColorMatrix);
+    method public void setColorMatrix(float[]);
   }
 
   public class ComposePathEffect extends android.graphics.PathEffect {
@@ -9274,6 +9647,7 @@
     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
@@ -9311,6 +9685,10 @@
 
   public class LightingColorFilter extends android.graphics.ColorFilter {
     ctor public LightingColorFilter(int, int);
+    method public int getColorAdd();
+    method public int getColorMultiply();
+    method public void setColorAdd(int);
+    method public void setColorMultiply(int);
   }
 
   public class LinearGradient extends android.graphics.Shader {
@@ -9421,6 +9799,13 @@
     method public void setPaint(android.graphics.Paint);
   }
 
+  public class Outline {
+    ctor public Outline();
+    method public final boolean isValid();
+    method public void set(android.graphics.Outline);
+    method public void setRoundRect(int, int, int, int, float);
+  }
+
   public class Paint {
     ctor public Paint();
     ctor public Paint(int);
@@ -9599,6 +9984,7 @@
     method public void cubicTo(float, float, float, float, float, float);
     method public android.graphics.Path.FillType getFillType();
     method public void incReserve(int);
+    method public boolean isConvex();
     method public boolean isEmpty();
     method public boolean isInverseFillType();
     method public boolean isRect(android.graphics.RectF);
@@ -9785,6 +10171,10 @@
 
   public class PorterDuffColorFilter extends android.graphics.ColorFilter {
     ctor public PorterDuffColorFilter(int, android.graphics.PorterDuff.Mode);
+    method public int getColor();
+    method public android.graphics.PorterDuff.Mode getMode();
+    method public void setColor(int);
+    method public void setMode(android.graphics.PorterDuff.Mode);
   }
 
   public class PorterDuffXfermode extends android.graphics.Xfermode {
@@ -10058,6 +10448,7 @@
     method public final android.graphics.Paint getPaint();
     method public android.graphics.Shader.TileMode getTileModeX();
     method public android.graphics.Shader.TileMode getTileModeY();
+    method public android.content.res.ColorStateList getTint();
     method public boolean hasAntiAlias();
     method public boolean hasMipMap();
     method public final boolean isAutoMirrored();
@@ -10072,6 +10463,7 @@
     method public void setTileModeX(android.graphics.Shader.TileMode);
     method public void setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode);
     method public final void setTileModeY(android.graphics.Shader.TileMode);
+    method public void setTint(android.content.res.ColorStateList);
   }
 
   public class ClipDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
@@ -10114,6 +10506,7 @@
     method public final android.graphics.Rect getBounds();
     method public android.graphics.drawable.Drawable.Callback getCallback();
     method public int getChangingConfigurations();
+    method public android.graphics.ColorFilter getColorFilter();
     method public android.graphics.drawable.Drawable.ConstantState getConstantState();
     method public android.graphics.drawable.Drawable getCurrent();
     method public int getIntrinsicHeight();
@@ -10122,6 +10515,7 @@
     method public int getMinimumHeight();
     method public int getMinimumWidth();
     method public abstract int getOpacity();
+    method public android.graphics.Outline getOutline();
     method public boolean getPadding(android.graphics.Rect);
     method public int[] getState();
     method public android.graphics.Region getTransparentRegion();
@@ -10210,10 +10604,12 @@
     ctor public GradientDrawable();
     ctor public GradientDrawable(android.graphics.drawable.GradientDrawable.Orientation, int[]);
     method public void draw(android.graphics.Canvas);
+    method public float getGradientRadius();
     method public int getOpacity();
     method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
     method public void setAlpha(int);
     method public void setColor(int);
+    method public void setColor(android.content.res.ColorStateList);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void setColors(int[]);
     method public void setCornerRadii(float[]);
@@ -10225,7 +10621,9 @@
     method public void setShape(int);
     method public void setSize(int, int);
     method public void setStroke(int, int);
+    method public void setStroke(int, android.content.res.ColorStateList);
     method public void setStroke(int, int, float, float);
+    method public void setStroke(int, android.content.res.ColorStateList, float, float);
     method public void setUseLevel(boolean);
     field public static final int LINE = 2; // 0x2
     field public static final int LINEAR_GRADIENT = 0; // 0x0
@@ -10270,6 +10668,7 @@
     method public int getId(int);
     method public int getNumberOfLayers();
     method public int getOpacity();
+    method public int getPaddingMode();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
@@ -10278,7 +10677,10 @@
     method public void setId(int, int);
     method public void setLayerInset(int, int, int, int, int);
     method public void setOpacity(int);
+    method public void setPaddingMode(int);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+    field public static final int PADDING_MODE_NEST = 0; // 0x0
+    field public static final int PADDING_MODE_STACK = 1; // 0x1
   }
 
   public class LevelListDrawable extends android.graphics.drawable.DrawableContainer {
@@ -10294,11 +10696,13 @@
     method public void draw(android.graphics.Canvas);
     method public int getOpacity();
     method public android.graphics.Paint getPaint();
+    method public android.content.res.ColorStateList getTint();
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void setTargetDensity(android.graphics.Canvas);
     method public void setTargetDensity(android.util.DisplayMetrics);
     method public void setTargetDensity(int);
+    method public void setTint(android.content.res.ColorStateList);
   }
 
   public class PaintDrawable extends android.graphics.drawable.ShapeDrawable {
@@ -10318,15 +10722,32 @@
     method public void setPicture(android.graphics.Picture);
   }
 
+  public class RevealDrawable extends android.graphics.drawable.LayerDrawable {
+    ctor public RevealDrawable(android.graphics.drawable.Drawable[]);
+  }
+
   public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
     ctor public RotateDrawable();
     method public void draw(android.graphics.Canvas);
     method public android.graphics.drawable.Drawable getDrawable();
+    method public float getFromDegrees();
     method public int getOpacity();
+    method public float getPivotX();
+    method public float getPivotY();
+    method public float getToDegrees();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public boolean isPivotXRelative();
+    method public boolean isPivotYRelative();
     method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setDrawable(android.graphics.drawable.Drawable);
+    method public void setFromDegrees(float);
+    method public void setPivotX(float);
+    method public void setPivotXRelative(boolean);
+    method public void setPivotY(float);
+    method public void setPivotYRelative(boolean);
+    method public void setToDegrees(float);
     method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
   }
 
@@ -10350,6 +10771,7 @@
     method public android.graphics.Paint getPaint();
     method public android.graphics.drawable.ShapeDrawable.ShaderFactory getShaderFactory();
     method public android.graphics.drawable.shapes.Shape getShape();
+    method public android.content.res.ColorStateList getTint();
     method protected boolean inflateTag(java.lang.String, android.content.res.Resources, org.xmlpull.v1.XmlPullParser, android.util.AttributeSet);
     method protected void onDraw(android.graphics.drawable.shapes.Shape, android.graphics.Canvas, android.graphics.Paint);
     method public void setAlpha(int);
@@ -10360,6 +10782,7 @@
     method public void setPadding(android.graphics.Rect);
     method public void setShaderFactory(android.graphics.drawable.ShapeDrawable.ShaderFactory);
     method public void setShape(android.graphics.drawable.shapes.Shape);
+    method public void setTint(android.content.res.ColorStateList);
   }
 
   public static abstract class ShapeDrawable.ShaderFactory {
@@ -10881,6 +11304,484 @@
 
 }
 
+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 = 1; // 0x1
+    field public static final int CAMERA_DISCONNECTED = 2; // 0x2
+    field public static final int CAMERA_ERROR = 3; // 0x3
+  }
+
+  public final class CameraCharacteristics extends android.hardware.camera2.CameraMetadata {
+    method public T get(android.hardware.camera2.CameraMetadata.Key<T>);
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureRequestKeys();
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getAvailableCaptureResultKeys();
+    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_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 EDGE_AVAILABLE_EDGE_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key FLASH_INFO_AVAILABLE;
+    field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
+    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_FOCUS_DISTANCE_CALIBRATION;
+    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 NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_AVAILABLE_CAPABILITIES;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_INPUT_STREAMS;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_MAX_NUM_OUTPUT_STREAMS;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PARTIAL_RESULT_COUNT;
+    field public static final android.hardware.camera2.CameraMetadata.Key REQUEST_PIPELINE_MAX_DEPTH;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_FORMATS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP;
+    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_MIN_FRAME_DURATIONS;
+    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 SCALER_AVAILABLE_STALL_DURATIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_AVAILABLE_TEST_PATTERN_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BASE_GAIN_FACTOR;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_BLACK_LEVEL_PATTERN;
+    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_PIXEL_ARRAY_SIZE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_SENSITIVITY_RANGE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_INFO_WHITE_LEVEL;
+    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 SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS;
+    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_AVAILABLE_HOT_PIXEL_MAP_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_MAX_FACE_COUNT;
+    field public static final android.hardware.camera2.CameraMetadata.Key SYNC_MAX_LATENCY;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_AVAILABLE_TONE_MAP_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MAX_CURVE_POINTS;
+  }
+
+  public abstract interface CameraDevice implements java.lang.AutoCloseable {
+    method public abstract int capture(android.hardware.camera2.CaptureRequest, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract int 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();
+    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 int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraDevice.CaptureListener, android.os.Handler) throws android.hardware.camera2.CameraAccessException;
+    method public abstract int 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;
+    field public static final int TEMPLATE_MANUAL = 6; // 0x6
+    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
+    field public static final int TEMPLATE_ZERO_SHUTTER_LAG = 5; // 0x5
+  }
+
+  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, android.hardware.camera2.CaptureFailure);
+    method public void onCaptureSequenceCompleted(android.hardware.camera2.CameraDevice, int, int);
+    method public void onCaptureStarted(android.hardware.camera2.CameraDevice, android.hardware.camera2.CaptureRequest, long);
+  }
+
+  public static abstract class CameraDevice.StateListener {
+    ctor public CameraDevice.StateListener();
+    method public void onActive(android.hardware.camera2.CameraDevice);
+    method public void onBusy(android.hardware.camera2.CameraDevice);
+    method public void onClosed(android.hardware.camera2.CameraDevice);
+    method public abstract void onDisconnected(android.hardware.camera2.CameraDevice);
+    method public abstract void onError(android.hardware.camera2.CameraDevice, int);
+    method public void onIdle(android.hardware.camera2.CameraDevice);
+    method public abstract void onOpened(android.hardware.camera2.CameraDevice);
+    method public void onUnconfigured(android.hardware.camera2.CameraDevice);
+    field public static final int ERROR_CAMERA_DEVICE = 4; // 0x4
+    field public static final int ERROR_CAMERA_DISABLED = 3; // 0x3
+    field public static final int ERROR_CAMERA_IN_USE = 1; // 0x1
+    field public static final int ERROR_CAMERA_SERVICE = 5; // 0x5
+    field public static final int ERROR_MAX_CAMERAS_IN_USE = 2; // 0x2
+  }
+
+  public final class CameraManager {
+    method public void addAvailabilityListener(android.hardware.camera2.CameraManager.AvailabilityListener, android.os.Handler);
+    method public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(java.lang.String) throws android.hardware.camera2.CameraAccessException;
+    method public java.lang.String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
+    method public void openCamera(java.lang.String, android.hardware.camera2.CameraDevice.StateListener, android.os.Handler) 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>);
+    method public java.util.List<android.hardware.camera2.CameraMetadata.Key<?>> getKeys();
+    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_STATE_PASSIVE_UNFOCUSED = 6; // 0x6
+    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_OFF_KEEP_STATE = 3; // 0x3
+    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_DISABLED = 0; // 0x0
+    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 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 HOT_PIXEL_MODE_FAST = 1; // 0x1
+    field public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int HOT_PIXEL_MODE_OFF = 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_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1; // 0x1
+    field public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2; // 0x2
+    field public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 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 REQUEST_AVAILABLE_CAPABILITIES_DNG = 5; // 0x5
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 2; // 0x2
+    field public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4; // 0x4
+    field public static final int SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT = 1; // 0x1
+    field public static final int SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT = 0; // 0x0
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_CLOUDY_WEATHER = 10; // 0xa
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_COOL_WHITE_FLUORESCENT = 14; // 0xe
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_D50 = 23; // 0x17
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_D55 = 20; // 0x14
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_D65 = 21; // 0x15
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_D75 = 22; // 0x16
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT = 1; // 0x1
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT_FLUORESCENT = 12; // 0xc
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_DAY_WHITE_FLUORESCENT = 13; // 0xd
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_FINE_WEATHER = 9; // 0x9
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_FLASH = 4; // 0x4
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_FLUORESCENT = 2; // 0x2
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_ISO_STUDIO_TUNGSTEN = 24; // 0x18
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_SHADE = 11; // 0xb
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_A = 17; // 0x11
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_B = 18; // 0x12
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_C = 19; // 0x13
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_TUNGSTEN = 3; // 0x3
+    field public static final int SENSOR_REFERENCE_ILLUMINANT_WHITE_FLUORESCENT = 15; // 0xf
+    field public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS = 2; // 0x2
+    field public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY = 3; // 0x3
+    field public static final int SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256; // 0x100
+    field public static final int SENSOR_TEST_PATTERN_MODE_OFF = 0; // 0x0
+    field public static final int SENSOR_TEST_PATTERN_MODE_PN9 = 4; // 0x4
+    field public static final int SENSOR_TEST_PATTERN_MODE_SOLID_COLOR = 1; // 0x1
+    field public static final int SHADING_MODE_FAST = 1; // 0x1
+    field public static final int SHADING_MODE_HIGH_QUALITY = 2; // 0x2
+    field public static final int SHADING_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 SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0; // 0x0
+    field public static final int SYNC_MAX_LATENCY_UNKNOWN = -1; // 0xffffffff
+    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 class CaptureFailure {
+    method public int getFrameNumber();
+    method public int getReason();
+    method public android.hardware.camera2.CaptureRequest getRequest();
+    method public int getSequenceId();
+    method public boolean wasImageCaptured();
+    field public static final int REASON_ERROR = 0; // 0x0
+    field public static final int REASON_FLUSHED = 1; // 0x1
+  }
+
+  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 HOT_PIXEL_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 SENSOR_TEST_PATTERN_DATA;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_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>);
+    method public int getFrameNumber();
+    method public android.hardware.camera2.CaptureRequest getRequest();
+    method public int getSequenceId();
+    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_MODE;
+    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 HOT_PIXEL_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_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 REQUEST_PIPELINE_DEPTH;
+    field public static final android.hardware.camera2.CameraMetadata.Key SCALER_CROP_REGION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_CALIBRATION_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_COLOR_TRANSFORM;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_EXPOSURE_TIME;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FORWARD_MATRIX;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_FRAME_DURATION;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_GREEN_SPLIT;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_NEUTRAL_COLOR_POINT;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_PROFILE_HUE_SAT_MAP;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_PROFILE_TONE_CURVE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_REFERENCE_ILLUMINANT;
+    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_TEST_PATTERN_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TIMESTAMP;
+    field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP;
+    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 final class Face {
+    method public android.graphics.Rect getBounds();
+    method public int getId();
+    method public android.graphics.Point getLeftEyePosition();
+    method public android.graphics.Point getMouthPosition();
+    method public android.graphics.Point getRightEyePosition();
+    method public int getScore();
+    field public static final int ID_UNSUPPORTED = -1; // 0xffffffff
+    field public static final int SCORE_MAX = 100; // 0x64
+    field public static final int SCORE_MIN = 1; // 0x1
+  }
+
+  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 {
@@ -11128,6 +12029,20 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public class UsbConfiguration implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAttributes();
+    method public int getId();
+    method public android.hardware.usb.UsbInterface getInterface(int);
+    method public int getInterfaceCount();
+    method public int getMaxPower();
+    method public java.lang.String getName();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int ATTR_REMOTE_WAKEUP_MASK = 32; // 0x20
+    field public static final int ATTR_SELF_POWERED_MASK = 64; // 0x40
+    field public static final android.os.Parcelable.Creator CREATOR;
+  }
+
   public final class UsbConstants {
     ctor public UsbConstants();
     field public static final int USB_CLASS_APP_SPEC = 254; // 0xfe
@@ -11167,6 +12082,8 @@
 
   public class UsbDevice implements android.os.Parcelable {
     method public int describeContents();
+    method public android.hardware.usb.UsbConfiguration getConfiguration(int);
+    method public int getConfigurationCount();
     method public int getDeviceClass();
     method public int getDeviceId();
     method public static int getDeviceId(java.lang.String);
@@ -11197,6 +12114,8 @@
     method public java.lang.String getSerial();
     method public boolean releaseInterface(android.hardware.usb.UsbInterface);
     method public android.hardware.usb.UsbRequest requestWait();
+    method public boolean setConfiguration(android.hardware.usb.UsbConfiguration);
+    method public boolean setInterface(android.hardware.usb.UsbInterface);
   }
 
   public class UsbEndpoint implements android.os.Parcelable {
@@ -11214,12 +12133,14 @@
 
   public class UsbInterface implements android.os.Parcelable {
     method public int describeContents();
+    method public int getAlternateSetting();
     method public android.hardware.usb.UsbEndpoint getEndpoint(int);
     method public int getEndpointCount();
     method public int getId();
     method public int getInterfaceClass();
     method public int getInterfaceProtocol();
     method public int getInterfaceSubclass();
+    method public java.lang.String getName();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
   }
@@ -11289,6 +12210,7 @@
     ctor public ExtractEditText(android.content.Context);
     ctor public ExtractEditText(android.content.Context, android.util.AttributeSet);
     ctor public ExtractEditText(android.content.Context, android.util.AttributeSet, int);
+    ctor public ExtractEditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void finishInternalChanges();
     method public boolean hasVerticalScrollBar();
     method public void startInternalChanges();
@@ -11303,6 +12225,7 @@
     method public android.view.inputmethod.InputConnection getCurrentInputConnection();
     method public android.view.inputmethod.EditorInfo getCurrentInputEditorInfo();
     method public boolean getCurrentInputStarted();
+    method public int getInputMethodWindowRecommendedHeight();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getMaxWidth();
     method public java.lang.CharSequence getTextForImeAction(int);
@@ -11485,6 +12408,7 @@
   public class KeyboardView extends android.view.View implements android.view.View.OnClickListener {
     ctor public KeyboardView(android.content.Context, android.util.AttributeSet);
     ctor public KeyboardView(android.content.Context, android.util.AttributeSet, int);
+    ctor public KeyboardView(android.content.Context, android.util.AttributeSet, int, int);
     method public void closing();
     method public android.inputmethodservice.Keyboard getKeyboard();
     method protected android.inputmethodservice.KeyboardView.OnKeyboardActionListener getOnKeyboardActionListener();
@@ -11772,7 +12696,7 @@
     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 protected deprecated 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";
@@ -12048,6 +12972,7 @@
     method public int setPositionNotificationPeriod(int);
     method protected deprecated void setState(int);
     method public int setStereoVolume(float, float);
+    method public int setVolume(float);
     method public void stop() throws java.lang.IllegalStateException;
     method public int write(byte[], int, int);
     method public int write(short[], int, int);
@@ -12252,9 +13177,9 @@
 
   public final class MediaCodec {
     method public void configure(android.media.MediaFormat, android.view.Surface, android.media.MediaCrypto, int);
-    method public static android.media.MediaCodec createByCodecName(java.lang.String);
-    method public static android.media.MediaCodec createDecoderByType(java.lang.String);
-    method public static android.media.MediaCodec createEncoderByType(java.lang.String);
+    method public static android.media.MediaCodec createByCodecName(java.lang.String) throws java.io.IOException;
+    method public static android.media.MediaCodec createDecoderByType(java.lang.String) throws java.io.IOException;
+    method public static android.media.MediaCodec createEncoderByType(java.lang.String) throws java.io.IOException;
     method public final android.view.Surface createInputSurface();
     method public final int dequeueInputBuffer(long);
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
@@ -12268,6 +13193,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 void setNotificationCallback(android.media.MediaCodec.NotificationCallback);
     method public final void setParameters(android.os.Bundle);
     method public final void setVideoScalingMode(int);
     method public final void signalEndOfInputStream();
@@ -12317,6 +13243,10 @@
     field public int numSubSamples;
   }
 
+  public static abstract interface MediaCodec.NotificationCallback {
+    method public abstract void onCodecNotify(android.media.MediaCodec);
+  }
+
   public final class MediaCodecInfo {
     method public final android.media.MediaCodecInfo.CodecCapabilities getCapabilitiesForType(java.lang.String);
     method public final java.lang.String getName();
@@ -12684,6 +13614,7 @@
 
   public static final class MediaMuxer.OutputFormat {
     field public static final int MUXER_OUTPUT_MPEG_4 = 0; // 0x0
+    field public static final int MUXER_OUTPUT_WEBM = 1; // 0x1
   }
 
   public class MediaPlayer {
@@ -12808,6 +13739,7 @@
     ctor public MediaRecorder();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
+    method public android.view.Surface getSurface();
     method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
     method public void release();
     method public void reset();
@@ -12892,6 +13824,7 @@
   public final class MediaRecorder.VideoSource {
     field public static final int CAMERA = 1; // 0x1
     field public static final int DEFAULT = 0; // 0x0
+    field public static final int SURFACE = 2; // 0x2
   }
 
   public class MediaRouter {
@@ -13064,6 +13997,7 @@
     field public static final int RATING_4_STARS = 4; // 0x4
     field public static final int RATING_5_STARS = 5; // 0x5
     field public static final int RATING_HEART = 1; // 0x1
+    field public static final int RATING_NONE = 0; // 0x0
     field public static final int RATING_PERCENTAGE = 6; // 0x6
     field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
   }
@@ -13701,6 +14635,227 @@
 
 }
 
+package android.media.session {
+
+  public final class MediaController {
+    method public void addCallback(android.media.session.MediaController.Callback);
+    method public void addCallback(android.media.session.MediaController.Callback, android.os.Handler);
+    method public static android.media.session.MediaController fromToken(android.media.session.MediaSessionToken);
+    method public android.media.session.TransportController getTransportController();
+    method public void removeCallback(android.media.session.MediaController.Callback);
+    method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public void sendMediaButton(int);
+  }
+
+  public static abstract class MediaController.Callback {
+    ctor public MediaController.Callback();
+    method public void onEvent(java.lang.String, android.os.Bundle);
+    method public void onRouteChanged(android.os.Bundle);
+  }
+
+  public final class MediaMetadata implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.graphics.Bitmap getBitmap(java.lang.String);
+    method public long getLong(java.lang.String);
+    method public android.media.Rating getRating(java.lang.String);
+    method public java.lang.String getString(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final java.lang.String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+    field public static final java.lang.String METADATA_KEY_ART = "android.media.metadata.ART";
+    field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+    field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+    field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+    field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+    field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
+    field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+    field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+    field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+    field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+    field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
+    field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+    field public static final java.lang.String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+    field public static final java.lang.String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+    field public static final java.lang.String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+    field public static final java.lang.String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+  }
+
+  public static final class MediaMetadata.Builder {
+    ctor public MediaMetadata.Builder();
+    ctor public MediaMetadata.Builder(android.media.session.MediaMetadata);
+    method public android.media.session.MediaMetadata build();
+    method public android.media.session.MediaMetadata.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+    method public android.media.session.MediaMetadata.Builder putLong(java.lang.String, long);
+    method public android.media.session.MediaMetadata.Builder putRating(java.lang.String, android.media.Rating);
+    method public android.media.session.MediaMetadata.Builder putString(java.lang.String, java.lang.String);
+  }
+
+  public final class MediaSession {
+    method public void addCallback(android.media.session.MediaSession.Callback);
+    method public void addCallback(android.media.session.MediaSession.Callback, android.os.Handler);
+    method public android.media.session.MediaSessionToken getSessionToken();
+    method public android.media.session.TransportPerformer getTransportPerformer();
+    method public void publish();
+    method public void release();
+    method public void removeCallback(android.media.session.MediaSession.Callback);
+    method public void sendEvent(java.lang.String, android.os.Bundle);
+    method public android.media.session.TransportPerformer setTransportPerformerEnabled();
+  }
+
+  public static abstract class MediaSession.Callback {
+    ctor public MediaSession.Callback();
+    method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public void onMediaButton(android.content.Intent);
+    method public void onRequestRouteChange(android.os.Bundle);
+  }
+
+  public final class MediaSessionManager {
+    method public android.media.session.MediaSession createSession(java.lang.String);
+    method public java.util.List<android.media.session.MediaController> getActiveSessions();
+  }
+
+  public class MediaSessionToken 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 final class PlaybackState implements android.os.Parcelable {
+    ctor public PlaybackState();
+    ctor public PlaybackState(android.media.session.PlaybackState);
+    method public int describeContents();
+    method public long getActions();
+    method public long getBufferPosition();
+    method public java.lang.String getErrorMessage();
+    method public long getPosition();
+    method public float getSpeed();
+    method public int getState();
+    method public void setActions(long);
+    method public void setBufferPosition(long);
+    method public void setErrorMessage(java.lang.String);
+    method public void setPosition(long);
+    method public void setSpeed(float);
+    method public void setState(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final long ACTION_FASTFORWARD = 64L; // 0x40L
+    field public static final long ACTION_NEXT_ITEM = 32L; // 0x20L
+    field public static final long ACTION_PAUSE = 2L; // 0x2L
+    field public static final long ACTION_PLAY = 4L; // 0x4L
+    field public static final long ACTION_PREVIOUS_ITEM = 16L; // 0x10L
+    field public static final long ACTION_RATING = 128L; // 0x80L
+    field public static final long ACTION_REWIND = 8L; // 0x8L
+    field public static final long ACTION_SEEK_TO = 256L; // 0x100L
+    field public static final long ACTION_STOP = 1L; // 0x1L
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int PLAYSTATE_BUFFERING = 6; // 0x6
+    field public static final int PLAYSTATE_ERROR = 7; // 0x7
+    field public static final int PLAYSTATE_FAST_FORWARDING = 4; // 0x4
+    field public static final int PLAYSTATE_NONE = 0; // 0x0
+    field public static final int PLAYSTATE_PAUSED = 2; // 0x2
+    field public static final int PLAYSTATE_PLAYING = 3; // 0x3
+    field public static final int PLAYSTATE_REWINDING = 5; // 0x5
+    field public static final int PLAYSTATE_STOPPED = 1; // 0x1
+  }
+
+  public final class RouteInterface {
+    method public void addListener(android.media.session.RouteInterface.EventListener);
+    method public void addListener(android.media.session.RouteInterface.EventListener, android.os.Handler);
+    method public void removeListener(android.media.session.RouteInterface.EventListener);
+    method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+  }
+
+  public static abstract class RouteInterface.EventListener {
+    ctor public RouteInterface.EventListener();
+    method public abstract void onEvent(java.lang.String, android.os.Bundle);
+  }
+
+  public static abstract class RouteInterface.Stub {
+    ctor public RouteInterface.Stub();
+    method public abstract java.lang.String getName();
+    method public abstract void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public final void sendEvent(android.media.session.MediaSession, java.lang.String, android.os.Bundle);
+  }
+
+  public final class RouteTransportControls {
+    method public void addListener(android.media.session.RouteTransportControls.Listener);
+    method public void addListener(android.media.session.RouteTransportControls.Listener, android.os.Handler);
+    method public void fastForward(float);
+    method public static android.media.session.RouteTransportControls from(android.media.session.MediaController);
+    method public void getCapabilities(android.os.ResultReceiver);
+    method public void getCurrentPosition(android.os.ResultReceiver);
+    method public void pause();
+    method public void play();
+    method public void removeListener(android.media.session.RouteTransportControls.Listener);
+    field public static final java.lang.String NAME = "android.media.session.RouteTransportControls";
+  }
+
+  public static abstract class RouteTransportControls.Listener {
+    ctor public RouteTransportControls.Listener();
+    method public void onMetadataUpdate(android.os.Bundle);
+    method public void onPlaybackStateChange(int);
+  }
+
+  public static abstract class RouteTransportControls.Stub extends android.media.session.RouteInterface.Stub {
+    ctor public RouteTransportControls.Stub(android.media.session.MediaSession);
+    method public void fastForward(float);
+    method public long getCapabilities();
+    method public long getCurrentPosition();
+    method public java.lang.String getName();
+    method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public final void updatePlaybackState(int);
+  }
+
+  public final class TransportController {
+    method public void addStateListener(android.media.session.TransportController.TransportStateListener);
+    method public void addStateListener(android.media.session.TransportController.TransportStateListener, android.os.Handler);
+    method public void fastForward();
+    method public android.media.session.MediaMetadata getMetadata();
+    method public android.media.session.PlaybackState getPlaybackState();
+    method public int getRatingType();
+    method public void next();
+    method public void pause();
+    method public void play();
+    method public void previous();
+    method public void rate(android.media.Rating);
+    method public void removeStateListener(android.media.session.TransportController.TransportStateListener);
+    method public void rewind();
+    method public void seekTo(long);
+    method public void stop();
+  }
+
+  public static abstract class TransportController.TransportStateListener {
+    ctor public TransportController.TransportStateListener();
+    method public void onMetadataChanged(android.media.session.MediaMetadata);
+    method public void onPlaybackStateChanged(android.media.session.PlaybackState);
+  }
+
+  public final class TransportPerformer {
+    method public void addListener(android.media.session.TransportPerformer.Listener);
+    method public void addListener(android.media.session.TransportPerformer.Listener, android.os.Handler);
+    method public void removeListener(android.media.session.TransportPerformer.Listener);
+    method public final void setMetadata(android.media.session.MediaMetadata);
+    method public final void setPlaybackState(android.media.session.PlaybackState);
+  }
+
+  public static abstract class TransportPerformer.Listener {
+    ctor public TransportPerformer.Listener();
+    method public void onFastForward();
+    method public void onNext();
+    method public void onPause();
+    method public void onPlay();
+    method public void onPrevious();
+    method public void onRate(android.media.Rating);
+    method public void onRewind();
+    method public void onRouteFocusChange(int);
+    method public void onSeekTo(long);
+    method public void onStop();
+  }
+
+}
+
 package android.mtp {
 
   public final class MtpConstants {
@@ -13837,11 +14992,14 @@
     method public android.net.NetworkInfo getNetworkInfo(int);
     method public int getNetworkPreference();
     method public boolean isActiveNetworkMetered();
+    method public boolean isNetworkActive();
     method public static boolean isNetworkTypeValid(int);
+    method public void registerNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
     method public boolean requestRouteToHost(int, int);
     method public void setNetworkPreference(int);
     method public int startUsingNetworkFeature(int, java.lang.String);
     method public int stopUsingNetworkFeature(int, java.lang.String);
+    method public void unregisterNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
     field public static final deprecated java.lang.String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
     field public static final java.lang.String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
     field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
@@ -13864,6 +15022,10 @@
     field public static final int TYPE_WIMAX = 6; // 0x6
   }
 
+  public static abstract interface ConnectivityManager.OnNetworkActiveListener {
+    method public abstract void onNetworkActive();
+  }
+
   public class Credentials {
     ctor public Credentials(int, int, int);
     method public int getGid();
@@ -14318,6 +15480,7 @@
   public class X509TrustManagerExtensions {
     ctor public X509TrustManagerExtensions(javax.net.ssl.X509TrustManager) throws java.lang.IllegalArgumentException;
     method public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, java.lang.String) throws java.security.cert.CertificateException;
+    method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
   }
 
 }
@@ -14759,6 +15922,7 @@
     method public int describeContents();
     method public java.lang.String getBSSID();
     method public static android.net.NetworkInfo.DetailedState getDetailedStateOf(android.net.wifi.SupplicantState);
+    method public int getFrequency();
     method public boolean getHiddenSSID();
     method public int getIpAddress();
     method public int getLinkSpeed();
@@ -14768,6 +15932,7 @@
     method public java.lang.String getSSID();
     method public android.net.wifi.SupplicantState getSupplicantState();
     method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String FREQUENCY_UNITS = "MHz";
     field public static final java.lang.String LINK_SPEED_UNITS = "Mbps";
   }
 
@@ -15080,6 +16245,7 @@
     method public static android.nfc.NdefRecord createApplicationRecord(java.lang.String);
     method public static android.nfc.NdefRecord createExternal(java.lang.String, java.lang.String, byte[]);
     method public static android.nfc.NdefRecord createMime(java.lang.String, byte[]);
+    method public static android.nfc.NdefRecord createTextRecord(java.lang.String, java.lang.String);
     method public static android.nfc.NdefRecord createUri(android.net.Uri);
     method public static android.nfc.NdefRecord createUri(java.lang.String);
     method public int describeContents();
@@ -15116,6 +16282,7 @@
     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 invokeBeam(android.app.Activity);
     method public boolean isEnabled();
     method public boolean isNdefPushEnabled();
     method public void setBeamPushUris(android.net.Uri[], android.app.Activity);
@@ -15169,6 +16336,11 @@
     method public android.nfc.NfcAdapter getDefaultAdapter();
   }
 
+  public class NfcUnlock {
+    method public static synchronized android.nfc.NfcUnlock getInstance(android.nfc.NfcAdapter);
+    method public boolean getNfcUnlockEnabled();
+  }
+
   public final class Tag implements android.os.Parcelable {
     method public int describeContents();
     method public byte[] getId();
@@ -15541,8 +16713,10 @@
   }
 
   public abstract class EGLObjectHandle {
-    ctor protected EGLObjectHandle(int);
-    method public int getHandle();
+    ctor protected deprecated EGLObjectHandle(int);
+    ctor protected EGLObjectHandle(long);
+    method public deprecated int getHandle();
+    method public long getNativeHandle();
   }
 
   public class EGLSurface extends android.opengl.EGLObjectHandle {
@@ -16454,11 +17628,9 @@
     method public static void glGenTextures(int, java.nio.IntBuffer);
     method public static void glGenerateMipmap(int);
     method public static void glGetActiveAttrib(int, int, int, int[], int, int[], int, int[], int, byte[], int);
-    method public static void glGetActiveAttrib(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
     method public static java.lang.String glGetActiveAttrib(int, int, int[], int, int[], int);
     method public static java.lang.String glGetActiveAttrib(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
     method public static void glGetActiveUniform(int, int, int, int[], int, int[], int, int[], int, byte[], int);
-    method public static void glGetActiveUniform(int, int, int, java.nio.IntBuffer, java.nio.IntBuffer, java.nio.IntBuffer, byte);
     method public static java.lang.String glGetActiveUniform(int, int, int[], int, int[], int);
     method public static java.lang.String glGetActiveUniform(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
     method public static void glGetAttachedShaders(int, int, int[], int, int[], int);
@@ -16484,7 +17656,6 @@
     method public static void glGetShaderPrecisionFormat(int, int, int[], int, int[], int);
     method public static void glGetShaderPrecisionFormat(int, int, java.nio.IntBuffer, java.nio.IntBuffer);
     method public static void glGetShaderSource(int, int, int[], int, byte[], int);
-    method public static void glGetShaderSource(int, int, java.nio.IntBuffer, byte);
     method public static java.lang.String glGetShaderSource(int);
     method public static void glGetShaderiv(int, int, int[], int);
     method public static void glGetShaderiv(int, int, java.nio.IntBuffer);
@@ -17613,6 +18784,7 @@
     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 = 19; // 0x13
+    field public static final int L = 10000; // 0x2710
   }
 
   public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
@@ -17732,7 +18904,7 @@
 
   public abstract class CountDownTimer {
     ctor public CountDownTimer(long, long);
-    method public final void cancel();
+    method public final synchronized void cancel();
     method public abstract void onFinish();
     method public abstract void onTick(long);
     method public final synchronized android.os.CountDownTimer start();
@@ -17884,10 +19056,13 @@
     method public static java.io.File getExternalStorageDirectory();
     method public static java.io.File getExternalStoragePublicDirectory(java.lang.String);
     method public static java.lang.String getExternalStorageState();
+    method public static java.lang.String getExternalStorageState(java.io.File);
     method public static java.io.File getRootDirectory();
-    method public static java.lang.String getStorageState(java.io.File);
+    method public static deprecated java.lang.String getStorageState(java.io.File);
     method public static boolean isExternalStorageEmulated();
+    method public static boolean isExternalStorageEmulated(java.io.File);
     method public static boolean isExternalStorageRemovable();
+    method public static boolean isExternalStorageRemovable(java.io.File);
     field public static java.lang.String DIRECTORY_ALARMS;
     field public static java.lang.String DIRECTORY_DCIM;
     field public static java.lang.String DIRECTORY_DOCUMENTS;
@@ -18118,7 +19293,6 @@
     method public final boolean hasFileDescriptors();
     method public final byte[] marshall();
     method public static android.os.Parcel obtain();
-    method protected static final android.os.Parcel obtain(int);
     method public final java.lang.Object[] readArray(java.lang.ClassLoader);
     method public final java.util.ArrayList readArrayList(java.lang.ClassLoader);
     method public final void readBinderArray(android.os.IBinder[]);
@@ -18306,6 +19480,7 @@
     field public static final deprecated int FULL_WAKE_LOCK = 26; // 0x1a
     field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
     field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1
+    field public static final java.lang.String REBOOT_RECOVERY = "recovery";
     field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
     field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
   }
@@ -18536,8 +19711,10 @@
   public abstract class Vibrator {
     method public abstract void cancel();
     method public abstract boolean hasVibrator();
-    method public abstract void vibrate(long);
-    method public abstract void vibrate(long[], int);
+    method public void vibrate(long);
+    method public void vibrate(long, int);
+    method public void vibrate(long[], int);
+    method public void vibrate(long[], int, int);
   }
 
   public class WorkSource implements android.os.Parcelable {
@@ -18575,6 +19752,10 @@
     method public boolean isObbMounted(java.lang.String);
     method public boolean mountObb(java.lang.String, java.lang.String, android.os.storage.OnObbStateChangeListener);
     method public boolean unmountObb(java.lang.String, boolean, android.os.storage.OnObbStateChangeListener);
+    field public static final int CRYPT_TYPE_DEFAULT = 1; // 0x1
+    field public static final int CRYPT_TYPE_PASSWORD = 0; // 0x0
+    field public static final int CRYPT_TYPE_PATTERN = 2; // 0x2
+    field public static final int CRYPT_TYPE_PIN = 3; // 0x3
   }
 
 }
@@ -18583,13 +19764,16 @@
 
   public class CheckBoxPreference extends android.preference.TwoStatePreference {
     ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public CheckBoxPreference(android.content.Context, android.util.AttributeSet);
     ctor public CheckBoxPreference(android.content.Context);
   }
 
   public abstract class DialogPreference extends android.preference.Preference implements android.content.DialogInterface.OnClickListener android.content.DialogInterface.OnDismissListener android.preference.PreferenceManager.OnActivityDestroyListener {
+    ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public DialogPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public DialogPreference(android.content.Context, android.util.AttributeSet);
+    ctor public DialogPreference(android.content.Context);
     method public android.app.Dialog getDialog();
     method public android.graphics.drawable.Drawable getDialogIcon();
     method public int getDialogLayoutResource();
@@ -18619,6 +19803,7 @@
   }
 
   public class EditTextPreference extends android.preference.DialogPreference {
+    ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public EditTextPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public EditTextPreference(android.content.Context, android.util.AttributeSet);
     ctor public EditTextPreference(android.content.Context);
@@ -18629,6 +19814,8 @@
   }
 
   public class ListPreference extends android.preference.DialogPreference {
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public ListPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public ListPreference(android.content.Context, android.util.AttributeSet);
     ctor public ListPreference(android.content.Context);
     method public int findIndexOfValue(java.lang.String);
@@ -18645,6 +19832,8 @@
   }
 
   public class MultiSelectListPreference extends android.preference.DialogPreference {
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public MultiSelectListPreference(android.content.Context, android.util.AttributeSet);
     ctor public MultiSelectListPreference(android.content.Context);
     method public int findIndexOfValue(java.lang.String);
@@ -18659,6 +19848,7 @@
   }
 
   public class Preference implements java.lang.Comparable {
+    ctor public Preference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public Preference(android.content.Context, android.util.AttributeSet, int);
     ctor public Preference(android.content.Context, android.util.AttributeSet);
     ctor public Preference(android.content.Context);
@@ -18824,6 +20014,7 @@
   }
 
   public class PreferenceCategory extends android.preference.PreferenceGroup {
+    ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int, int);
     ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet, int);
     ctor public PreferenceCategory(android.content.Context, android.util.AttributeSet);
     ctor public PreferenceCategory(android.content.Context);
@@ -18845,6 +20036,7 @@
   }
 
   public abstract class PreferenceGroup extends android.preference.Preference {
+    ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int, int);
     ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet, int);
     ctor public PreferenceGroup(android.content.Context, android.util.AttributeSet);
     method public void addItemFromInflater(android.preference.Preference);
@@ -18899,6 +20091,7 @@
   }
 
   public class RingtonePreference extends android.preference.Preference implements android.preference.PreferenceManager.OnActivityResultListener {
+    ctor public RingtonePreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public RingtonePreference(android.content.Context, android.util.AttributeSet, int);
     ctor public RingtonePreference(android.content.Context, android.util.AttributeSet);
     ctor public RingtonePreference(android.content.Context);
@@ -18915,6 +20108,7 @@
   }
 
   public class SwitchPreference extends android.preference.TwoStatePreference {
+    ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public SwitchPreference(android.content.Context, android.util.AttributeSet, int);
     ctor public SwitchPreference(android.content.Context, android.util.AttributeSet);
     ctor public SwitchPreference(android.content.Context);
@@ -18927,6 +20121,7 @@
   }
 
   public abstract class TwoStatePreference extends android.preference.Preference {
+    ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int, int);
     ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet, int);
     ctor public TwoStatePreference(android.content.Context, android.util.AttributeSet);
     ctor public TwoStatePreference(android.content.Context);
@@ -19682,16 +20877,24 @@
   public static class CallLog.Calls implements android.provider.BaseColumns {
     ctor public CallLog.Calls();
     method public static java.lang.String getLastOutgoingCall(android.content.Context);
+    field public static final java.lang.String CACHED_FORMATTED_NUMBER = "formatted_number";
+    field public static final java.lang.String CACHED_LOOKUP_URI = "lookup_uri";
+    field public static final java.lang.String CACHED_MATCHED_NUMBER = "matched_number";
     field public static final java.lang.String CACHED_NAME = "name";
+    field public static final java.lang.String CACHED_NORMALIZED_NUMBER = "normalized_number";
     field public static final java.lang.String CACHED_NUMBER_LABEL = "numberlabel";
     field public static final java.lang.String CACHED_NUMBER_TYPE = "numbertype";
+    field public static final java.lang.String CACHED_PHOTO_ID = "photo_id";
     field public static final android.net.Uri CONTENT_FILTER_URI;
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final android.net.Uri CONTENT_URI_WITH_VOICEMAIL;
+    field public static final java.lang.String COUNTRY_ISO = "countryiso";
     field public static final java.lang.String DATE = "date";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "date DESC";
     field public static final java.lang.String DURATION = "duration";
+    field public static final java.lang.String GEOCODED_LOCATION = "geocoded_location";
     field public static final int INCOMING_TYPE = 1; // 0x1
     field public static final java.lang.String IS_READ = "is_read";
     field public static final java.lang.String LIMIT_PARAM_KEY = "limit";
@@ -19706,6 +20909,8 @@
     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";
+    field public static final int VOICEMAIL_TYPE = 4; // 0x4
+    field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
   }
 
   public deprecated class Contacts {
@@ -20012,6 +21217,8 @@
     field public static final java.lang.String LIMIT_PARAM_KEY = "limit";
     field public static final java.lang.String PRIMARY_ACCOUNT_NAME = "name_for_primary_account";
     field public static final java.lang.String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account";
+    field public static final java.lang.String REMOVE_DUPLICATE_ENTRIES = "remove_duplicate_entries";
+    field public static final java.lang.String STREQUENT_PHONE_ONLY = "strequent_phone_only";
   }
 
   public static final class ContactsContract.AggregationExceptions implements android.provider.BaseColumns {
@@ -20040,6 +21247,12 @@
     field public static final int TYPE_CUSTOM = 0; // 0x0
   }
 
+  public static final class ContactsContract.CommonDataKinds.Callable implements android.provider.ContactsContract.CommonDataKinds.CommonColumns android.provider.ContactsContract.DataColumnsWithJoins {
+    ctor public ContactsContract.CommonDataKinds.Callable();
+    field public static final android.net.Uri CONTENT_FILTER_URI;
+    field public static final android.net.Uri CONTENT_URI;
+  }
+
   protected static abstract interface ContactsContract.CommonDataKinds.CommonColumns implements android.provider.ContactsContract.CommonDataKinds.BaseTypes {
     field public static final java.lang.String DATA = "data1";
     field public static final java.lang.String LABEL = "data3";
@@ -20218,6 +21431,7 @@
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/name";
     field public static final java.lang.String DISPLAY_NAME = "data1";
     field public static final java.lang.String FAMILY_NAME = "data3";
+    field public static final java.lang.String FULL_NAME_STYLE = "data10";
     field public static final java.lang.String GIVEN_NAME = "data2";
     field public static final java.lang.String MIDDLE_NAME = "data5";
     field public static final java.lang.String PHONETIC_FAMILY_NAME = "data9";
@@ -20271,6 +21485,7 @@
   protected static abstract interface ContactsContract.ContactOptionsColumns {
     field public static final java.lang.String CUSTOM_RINGTONE = "custom_ringtone";
     field public static final java.lang.String LAST_TIME_CONTACTED = "last_time_contacted";
+    field public static final java.lang.String PINNED = "pinned";
     field public static final java.lang.String SEND_TO_VOICEMAIL = "send_to_voicemail";
     field public static final java.lang.String STARRED = "starred";
     field public static final java.lang.String TIMES_CONTACTED = "times_contacted";
@@ -20297,6 +21512,7 @@
     field public static final android.net.Uri CONTENT_GROUP_URI;
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/contact";
     field public static final android.net.Uri CONTENT_LOOKUP_URI;
+    field public static final android.net.Uri CONTENT_MULTI_VCARD_URI;
     field public static final android.net.Uri CONTENT_STREQUENT_FILTER_URI;
     field public static final android.net.Uri CONTENT_STREQUENT_URI;
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/contact";
@@ -20529,6 +21745,7 @@
 
   public static final class ContactsContract.PhoneLookup implements android.provider.BaseColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactsColumns android.provider.ContactsContract.PhoneLookupColumns {
     field public static final android.net.Uri CONTENT_FILTER_URI;
+    field public static final java.lang.String QUERY_PARAMETER_SIP_ADDRESS = "sip";
   }
 
   protected static abstract interface ContactsContract.PhoneLookupColumns {
@@ -20545,6 +21762,25 @@
     field public static final int UNDEFINED = 0; // 0x0
   }
 
+  public static final class ContactsContract.PinnedPositions {
+    ctor public ContactsContract.PinnedPositions();
+    field public static final int DEMOTED = -1; // 0xffffffff
+    field public static final java.lang.String STAR_WHEN_PINNING = "star_when_pinning";
+    field public static final java.lang.String UNDEMOTE = "undemote";
+    field public static final int UNPINNED = 2147483647; // 0x7fffffff
+    field public static final android.net.Uri UPDATE_URI;
+  }
+
+  public static final class ContactsContract.Preferences {
+    ctor public ContactsContract.Preferences();
+    field public static final java.lang.String DISPLAY_ORDER = "android.contacts.DISPLAY_ORDER";
+    field public static final int DISPLAY_ORDER_ALTERNATIVE = 2; // 0x2
+    field public static final int DISPLAY_ORDER_PRIMARY = 1; // 0x1
+    field public static final java.lang.String SORT_ORDER = "android.contacts.SORT_ORDER";
+    field public static final int SORT_ORDER_ALTERNATIVE = 2; // 0x2
+    field public static final int SORT_ORDER_PRIMARY = 1; // 0x1
+  }
+
   public static final deprecated class ContactsContract.Presence extends android.provider.ContactsContract.StatusUpdates {
     ctor public ContactsContract.Presence();
   }
@@ -20846,6 +22082,8 @@
     field public static final java.lang.String EXTRA_MEDIA_ALBUM = "android.intent.extra.album";
     field public static final java.lang.String EXTRA_MEDIA_ARTIST = "android.intent.extra.artist";
     field public static final java.lang.String EXTRA_MEDIA_FOCUS = "android.intent.extra.focus";
+    field public static final java.lang.String EXTRA_MEDIA_GENRE = "android.intent.extra.genre";
+    field public static final java.lang.String EXTRA_MEDIA_RADIO_CHANNEL = "android.intent.extra.radio_channel";
     field public static final java.lang.String EXTRA_MEDIA_TITLE = "android.intent.extra.title";
     field public static final java.lang.String EXTRA_OUTPUT = "output";
     field public static final java.lang.String EXTRA_SCREEN_ORIENTATION = "android.intent.extra.screenOrientation";
@@ -20964,6 +22202,7 @@
     method public static android.net.Uri getContentUriForPath(java.lang.String);
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/audio";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "title_key";
+    field public static final java.lang.String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/audio";
     field public static final android.net.Uri EXTERNAL_CONTENT_URI;
     field public static final java.lang.String EXTRA_MAX_BYTES = "android.provider.MediaStore.extra.MAX_BYTES";
     field public static final android.net.Uri INTERNAL_CONTENT_URI;
@@ -20999,6 +22238,11 @@
     field public static final java.lang.String NAME = "name";
   }
 
+  public static final class MediaStore.Audio.Radio {
+    ctor public MediaStore.Audio.Radio();
+    field public static final java.lang.String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/radio";
+  }
+
   public static final class MediaStore.Files {
     ctor public MediaStore.Files();
     method public static android.net.Uri getContentUri(java.lang.String);
@@ -21312,6 +22556,7 @@
     field public static final java.lang.String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
     field public static final deprecated java.lang.String LOGGING_ID = "logging_id";
     field public static final deprecated java.lang.String NETWORK_PREFERENCE = "network_preference";
+    field public static final java.lang.String NFC_UNLOCK_ENABLED = "nfc_unlock_enabled";
     field public static final java.lang.String PARENTAL_CONTROL_ENABLED = "parental_control_enabled";
     field public static final java.lang.String PARENTAL_CONTROL_LAST_UPDATE = "parental_control_last_update";
     field public static final java.lang.String PARENTAL_CONTROL_REDIRECT_URL = "parental_control_redirect_url";
@@ -21852,15 +23097,18 @@
 package android.renderscript {
 
   public class Allocation extends android.renderscript.BaseObj {
+    method public void copy1DRangeFrom(int, int, java.lang.Object);
     method public void copy1DRangeFrom(int, int, int[]);
     method public void copy1DRangeFrom(int, int, short[]);
     method public void copy1DRangeFrom(int, int, byte[]);
     method public void copy1DRangeFrom(int, int, float[]);
     method public void copy1DRangeFrom(int, int, android.renderscript.Allocation, int);
+    method public void copy1DRangeFromUnchecked(int, int, java.lang.Object);
     method public void copy1DRangeFromUnchecked(int, int, int[]);
     method public void copy1DRangeFromUnchecked(int, int, short[]);
     method public void copy1DRangeFromUnchecked(int, int, byte[]);
     method public void copy1DRangeFromUnchecked(int, int, float[]);
+    method public void copy2DRangeFrom(int, int, int, int, java.lang.Object);
     method public void copy2DRangeFrom(int, int, int, int, byte[]);
     method public void copy2DRangeFrom(int, int, int, int, short[]);
     method public void copy2DRangeFrom(int, int, int, int, int[]);
@@ -21868,17 +23116,20 @@
     method public void copy2DRangeFrom(int, int, int, int, android.renderscript.Allocation, int, int);
     method public void copy2DRangeFrom(int, int, android.graphics.Bitmap);
     method public void copyFrom(android.renderscript.BaseObj[]);
+    method public void copyFrom(java.lang.Object);
     method public void copyFrom(int[]);
     method public void copyFrom(short[]);
     method public void copyFrom(byte[]);
     method public void copyFrom(float[]);
     method public void copyFrom(android.graphics.Bitmap);
     method public void copyFrom(android.renderscript.Allocation);
+    method public void copyFromUnchecked(java.lang.Object);
     method public void copyFromUnchecked(int[]);
     method public void copyFromUnchecked(short[]);
     method public void copyFromUnchecked(byte[]);
     method public void copyFromUnchecked(float[]);
     method public void copyTo(android.graphics.Bitmap);
+    method public void copyTo(java.lang.Object);
     method public void copyTo(byte[]);
     method public void copyTo(short[]);
     method public void copyTo(int[]);
@@ -22535,6 +23786,7 @@
   public final class ScriptIntrinsic3DLUT extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsic3DLUT create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setLUT(android.renderscript.Allocation);
   }
@@ -22542,20 +23794,35 @@
   public class ScriptIntrinsicBlend extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicBlend create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachAdd(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachClear(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDst(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachDstOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachMultiply(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrc(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcAtop(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcIn(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcOut(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSrcOver(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachSubtract(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation);
+    method public void forEachXor(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelIDAdd();
     method public android.renderscript.Script.KernelID getKernelIDClear();
     method public android.renderscript.Script.KernelID getKernelIDDst();
@@ -22576,6 +23843,7 @@
   public final class ScriptIntrinsicBlur extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicBlur create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setInput(android.renderscript.Allocation);
@@ -22586,6 +23854,7 @@
     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 void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setAdd(android.renderscript.Float4);
     method public void setAdd(float, float, float, float);
@@ -22599,6 +23868,7 @@
   public final class ScriptIntrinsicConvolve3x3 extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicConvolve3x3 create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setCoefficients(float[]);
@@ -22608,6 +23878,7 @@
   public final class ScriptIntrinsicConvolve5x5 extends android.renderscript.ScriptIntrinsic {
     method public static android.renderscript.ScriptIntrinsicConvolve5x5 create(android.renderscript.RenderScript, android.renderscript.Element);
     method public void forEach(android.renderscript.Allocation);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setCoefficients(float[]);
@@ -22617,7 +23888,9 @@
   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(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public void forEach_Dot(android.renderscript.Allocation);
+    method public void forEach_Dot(android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.FieldID getFieldID_Input();
     method public android.renderscript.Script.KernelID getKernelID_Separate();
     method public void setDotCoefficients(float, float, float, float);
@@ -22627,6 +23900,7 @@
   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);
+    method public void forEach(android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.Script.LaunchOptions);
     method public android.renderscript.Script.KernelID getKernelID();
     method public void setAlpha(int, int);
     method public void setBlue(int, int);
@@ -23058,11 +24332,52 @@
 
 package android.speech.tts {
 
+  public final class RequestConfig {
+    method public android.os.Bundle getAudioParams();
+    method public android.speech.tts.VoiceInfo getVoice();
+    method public android.os.Bundle getVoiceParams();
+  }
+
+  public static final class RequestConfig.Builder {
+    method public android.speech.tts.RequestConfig build();
+    method public static android.speech.tts.RequestConfig.Builder newBuilder();
+    method public static android.speech.tts.RequestConfig.Builder newBuilder(android.speech.tts.RequestConfig);
+    method public android.speech.tts.RequestConfig.Builder setAudioParam(java.lang.String, java.lang.Object);
+    method public void setAudioParamPan(float);
+    method public void setAudioParamStream(int);
+    method public void setAudioParamVolume(float);
+    method public android.speech.tts.RequestConfig.Builder setVoice(android.speech.tts.VoiceInfo);
+    method public android.speech.tts.RequestConfig.Builder setVoiceParam(java.lang.String, java.lang.Object);
+  }
+
+  public final class RequestConfigHelper {
+    method public static android.speech.tts.RequestConfig highestQuality(android.speech.tts.TextToSpeechClient.EngineStatus, boolean, android.speech.tts.RequestConfigHelper.VoiceScorer);
+    method public static android.speech.tts.RequestConfig highestQuality(android.speech.tts.TextToSpeechClient.EngineStatus, boolean);
+  }
+
+  public static final class RequestConfigHelper.ExactLocaleMatcher implements android.speech.tts.RequestConfigHelper.VoiceScorer {
+    ctor public RequestConfigHelper.ExactLocaleMatcher(java.util.Locale);
+    method public int scoreVoice(android.speech.tts.VoiceInfo);
+  }
+
+  public static final class RequestConfigHelper.LanguageMatcher implements android.speech.tts.RequestConfigHelper.VoiceScorer {
+    ctor public RequestConfigHelper.LanguageMatcher(java.util.Locale);
+    method public int scoreVoice(android.speech.tts.VoiceInfo);
+  }
+
+  public static abstract interface RequestConfigHelper.VoiceScorer {
+    method public abstract int scoreVoice(android.speech.tts.VoiceInfo);
+  }
+
   public abstract interface SynthesisCallback {
     method public abstract int audioAvailable(byte[], int, int);
     method public abstract int done();
     method public abstract void error();
+    method public abstract void error(int);
+    method public abstract int fallback();
     method public abstract int getMaxBufferSize();
+    method public abstract boolean hasFinished();
+    method public abstract boolean hasStarted();
     method public abstract int start(int, int, int);
   }
 
@@ -23078,7 +24393,18 @@
     method public java.lang.String getVariant();
   }
 
-  public class TextToSpeech {
+  public final class SynthesisRequestV2 implements android.os.Parcelable {
+    ctor public SynthesisRequestV2(java.lang.String, java.lang.String, java.lang.String, android.os.Bundle, android.os.Bundle);
+    method public int describeContents();
+    method public android.os.Bundle getAudioParams();
+    method public java.lang.String getText();
+    method public java.lang.String getUtteranceId();
+    method public java.lang.String getVoiceName();
+    method public android.os.Bundle getVoiceParams();
+    method public void writeToParcel(android.os.Parcel, int);
+  }
+
+  public deprecated class TextToSpeech {
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener);
     ctor public TextToSpeech(android.content.Context, android.speech.tts.TextToSpeech.OnInitListener, java.lang.String);
     method public int addEarcon(java.lang.String, java.lang.String, int);
@@ -23163,8 +24489,79 @@
     method public abstract void onUtteranceCompleted(java.lang.String);
   }
 
+  public final class TextToSpeechClient {
+    ctor public TextToSpeechClient(android.content.Context, java.lang.String, boolean, android.speech.tts.TextToSpeechClient.RequestCallbacks, android.speech.tts.TextToSpeechClient.ConnectionCallbacks);
+    ctor public TextToSpeechClient(android.content.Context, android.speech.tts.TextToSpeechClient.RequestCallbacks, android.speech.tts.TextToSpeechClient.ConnectionCallbacks);
+    method public void connect();
+    method public void disconnect();
+    method public android.speech.tts.TextToSpeechClient.EngineStatus getEngineStatus();
+    method public boolean isConnected();
+    method public void queueAudio(android.net.Uri, android.speech.tts.TextToSpeechClient.UtteranceId, android.speech.tts.RequestConfig, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void queueSilence(long, android.speech.tts.TextToSpeechClient.UtteranceId, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void queueSpeak(java.lang.String, android.speech.tts.TextToSpeechClient.UtteranceId, android.speech.tts.RequestConfig, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void queueSynthesizeToFile(java.lang.String, android.speech.tts.TextToSpeechClient.UtteranceId, java.io.File, android.speech.tts.RequestConfig, android.speech.tts.TextToSpeechClient.RequestCallbacks);
+    method public void stop();
+  }
+
+  public static abstract interface TextToSpeechClient.ConnectionCallbacks {
+    method public abstract void onConnectionFailure();
+    method public abstract void onConnectionSuccess();
+    method public abstract void onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus);
+    method public abstract void onServiceDisconnected();
+  }
+
+  public static final class TextToSpeechClient.EngineStatus {
+    method public java.lang.String getEnginePackage();
+    method public java.util.List<android.speech.tts.VoiceInfo> getVoices();
+  }
+
+  public static final class TextToSpeechClient.Params {
+    field public static final java.lang.String AUDIO_PARAM_PAN = "pan";
+    field public static final java.lang.String AUDIO_PARAM_STREAM = "streamType";
+    field public static final java.lang.String AUDIO_PARAM_VOLUME = "volume";
+    field public static final java.lang.String FALLBACK_VOICE_NAME = "fallbackVoiceName";
+    field public static final java.lang.String NETWORK_RETRIES_COUNT = "networkRetriesCount";
+    field public static final java.lang.String NETWORK_TIMEOUT_MS = "networkTimeoutMs";
+    field public static final java.lang.String SPEECH_PITCH = "speechPitch";
+    field public static final java.lang.String SPEECH_SPEED = "speechSpeed";
+    field public static final java.lang.String TRACK_SUBUTTERANCE_PROGRESS = "trackSubutteranceProgress";
+  }
+
+  public static abstract class TextToSpeechClient.RequestCallbacks {
+    ctor public TextToSpeechClient.RequestCallbacks();
+    method public void onSynthesisFailure(android.speech.tts.TextToSpeechClient.UtteranceId, int);
+    method public void onSynthesisFallback(android.speech.tts.TextToSpeechClient.UtteranceId);
+    method public void onSynthesisProgress(android.speech.tts.TextToSpeechClient.UtteranceId, int, int);
+    method public void onSynthesisStart(android.speech.tts.TextToSpeechClient.UtteranceId);
+    method public void onSynthesisStop(android.speech.tts.TextToSpeechClient.UtteranceId);
+    method public void onSynthesisSuccess(android.speech.tts.TextToSpeechClient.UtteranceId);
+  }
+
+  public static final class TextToSpeechClient.Status {
+    field public static final int ERROR_DOWNLOADING_ADDITIONAL_DATA = 17; // 0x11
+    field public static final int ERROR_INVALID_REQUEST = 15; // 0xf
+    field public static final int ERROR_NETWORK = 13; // 0xd
+    field public static final int ERROR_NETWORK_TIMEOUT = 14; // 0xe
+    field public static final int ERROR_NON_UNIQUE_UTTERANCE_ID = 16; // 0x10
+    field public static final int ERROR_OUTPUT = 12; // 0xc
+    field public static final int ERROR_SERVICE = 11; // 0xb
+    field public static final int ERROR_SYNTHESIS = 10; // 0xa
+    field public static final int ERROR_UNKNOWN = -1; // 0xffffffff
+    field public static final int STOPPED = 100; // 0x64
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public static class TextToSpeechClient.UtteranceId {
+    ctor public TextToSpeechClient.UtteranceId();
+    method public final java.lang.String toUniqueString();
+  }
+
   public abstract class TextToSpeechService extends android.app.Service {
     ctor public TextToSpeechService();
+    method protected java.util.List<android.speech.tts.VoiceInfo> checkVoicesInfo();
+    method public void forceVoicesInfoCheck();
+    method public android.speech.tts.VoiceInfo getVoicesInfoWithName(java.lang.String);
+    method protected boolean implementsV2API();
     method public android.os.IBinder onBind(android.content.Intent);
     method protected java.util.Set<java.lang.String> onGetFeaturesForLanguage(java.lang.String, java.lang.String, java.lang.String);
     method protected abstract java.lang.String[] onGetLanguage();
@@ -23172,6 +24569,8 @@
     method protected abstract int onLoadLanguage(java.lang.String, java.lang.String, java.lang.String);
     method protected abstract void onStop();
     method protected abstract void onSynthesizeText(android.speech.tts.SynthesisRequest, android.speech.tts.SynthesisCallback);
+    method protected void onSynthesizeTextV2(android.speech.tts.SynthesisRequestV2, android.speech.tts.VoiceInfo, android.speech.tts.SynthesisCallback);
+    method protected void onVoicesInfoChange();
   }
 
   public abstract class UtteranceProgressListener {
@@ -23181,6 +24580,44 @@
     method public abstract void onStart(java.lang.String);
   }
 
+  public final class VoiceInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.Bundle getAdditionalFeatures();
+    method public int getLatency();
+    method public java.util.Locale getLocale();
+    method public java.lang.String getName();
+    method public android.os.Bundle getParamsWithDefaults();
+    method public int getQuality();
+    method public boolean getRequiresNetworkConnection();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String FEATURE_MAY_AUTOINSTALL = "mayAutoInstall";
+    field public static final java.lang.String FEATURE_SPEAKER_GENDER = "speakerGender";
+    field public static final java.lang.String FEATURE_WORDS_PER_MINUTE = "wordsPerMinute";
+    field public static final int LATENCY_HIGH = 400; // 0x190
+    field public static final int LATENCY_LOW = 200; // 0xc8
+    field public static final int LATENCY_NORMAL = 300; // 0x12c
+    field public static final int LATENCY_VERY_HIGH = 500; // 0x1f4
+    field public static final int LATENCY_VERY_LOW = 100; // 0x64
+    field public static final int QUALITY_HIGH = 400; // 0x190
+    field public static final int QUALITY_LOW = 200; // 0xc8
+    field public static final int QUALITY_NORMAL = 300; // 0x12c
+    field public static final int QUALITY_VERY_HIGH = 500; // 0x1f4
+    field public static final int QUALITY_VERY_LOW = 100; // 0x64
+  }
+
+  public static final class VoiceInfo.Builder {
+    ctor public VoiceInfo.Builder();
+    ctor public VoiceInfo.Builder(android.speech.tts.VoiceInfo);
+    method public android.speech.tts.VoiceInfo build();
+    method public android.speech.tts.VoiceInfo.Builder setAdditionalFeatures(android.os.Bundle);
+    method public android.speech.tts.VoiceInfo.Builder setLatency(int);
+    method public android.speech.tts.VoiceInfo.Builder setLocale(java.util.Locale);
+    method public android.speech.tts.VoiceInfo.Builder setName(java.lang.String);
+    method public android.speech.tts.VoiceInfo.Builder setParamsWithDefaults(android.os.Bundle);
+    method public android.speech.tts.VoiceInfo.Builder setQuality(int);
+    method public android.speech.tts.VoiceInfo.Builder setRequiresNetworkConnection(boolean);
+  }
+
 }
 
 package android.telephony {
@@ -23352,6 +24789,7 @@
 
   public class PhoneNumberFormattingTextWatcher implements android.text.TextWatcher {
     ctor public PhoneNumberFormattingTextWatcher();
+    ctor public PhoneNumberFormattingTextWatcher(java.lang.String);
     method public synchronized void afterTextChanged(android.text.Editable);
     method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
     method public void onTextChanged(java.lang.CharSequence, int, int, int);
@@ -23366,11 +24804,14 @@
     method public static java.lang.String convertKeypadLettersToDigits(java.lang.String);
     method public static java.lang.String extractNetworkPortion(java.lang.String);
     method public static java.lang.String extractPostDialPortion(java.lang.String);
-    method public static void formatJapaneseNumber(android.text.Editable);
-    method public static void formatNanpNumber(android.text.Editable);
-    method public static java.lang.String formatNumber(java.lang.String);
-    method public static void formatNumber(android.text.Editable, int);
-    method public static int getFormatTypeForLocale(java.util.Locale);
+    method public static deprecated void formatJapaneseNumber(android.text.Editable);
+    method public static deprecated void formatNanpNumber(android.text.Editable);
+    method public static deprecated java.lang.String formatNumber(java.lang.String);
+    method public static deprecated void formatNumber(android.text.Editable, int);
+    method public static java.lang.String formatNumber(java.lang.String, java.lang.String);
+    method public static java.lang.String formatNumber(java.lang.String, java.lang.String, java.lang.String);
+    method public static java.lang.String formatNumberToE164(java.lang.String, java.lang.String);
+    method public static deprecated int getFormatTypeForLocale(java.util.Locale);
     method public static java.lang.String getNumberFromIntent(android.content.Intent, android.content.Context);
     method public static java.lang.String getStrippedReversed(java.lang.String);
     method public static final boolean is12Key(char);
@@ -23378,13 +24819,17 @@
     method public static boolean isEmergencyNumber(java.lang.String);
     method public static boolean isGlobalPhoneNumber(java.lang.String);
     method public static boolean isISODigit(char);
+    method public static boolean isLocalEmergencyNumber(java.lang.String, android.content.Context);
     method public static final boolean isNonSeparator(char);
     method public static final boolean isReallyDialable(char);
     method public static final boolean isStartsPostDial(char);
+    method public static boolean isVoiceMailNumber(java.lang.String);
     method public static boolean isWellFormedSmsAddress(java.lang.String);
     method public static byte[] networkPortionToCalledPartyBCD(java.lang.String);
     method public static byte[] networkPortionToCalledPartyBCDWithLength(java.lang.String);
+    method public static java.lang.String normalizeNumber(java.lang.String);
     method public static byte[] numberToCalledPartyBCD(java.lang.String);
+    method public static java.lang.String replaceUnicodeDigits(java.lang.String);
     method public static java.lang.String stringFromStringAndTOA(java.lang.String, int);
     method public static java.lang.String stripSeparators(java.lang.String);
     method public static java.lang.String toCallerIDMinMatch(java.lang.String);
@@ -23566,6 +25011,9 @@
     method public java.lang.String getVoiceMailAlphaTag();
     method public java.lang.String getVoiceMailNumber();
     method public boolean hasIccCard();
+    method public boolean iccCloseLogicalChannel(int);
+    method public int iccOpenLogicalChannel(java.lang.String);
+    method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
     method public boolean isNetworkRoaming();
     method public void listen(android.telephony.PhoneStateListener, int);
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
@@ -25738,7 +27186,8 @@
 
   public final class Scene {
     ctor public Scene(android.view.ViewGroup);
-    ctor public Scene(android.view.ViewGroup, android.view.ViewGroup);
+    ctor public Scene(android.view.ViewGroup, android.view.View);
+    ctor public deprecated 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);
@@ -25752,6 +27201,7 @@
     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 boolean canRemoveViews();
     method public abstract void captureEndValues(android.transition.TransitionValues);
     method public abstract void captureStartValues(android.transition.TransitionValues);
     method public android.transition.Transition clone();
@@ -25798,6 +27248,7 @@
     method public static void beginDelayedTransition(android.view.ViewGroup, android.transition.Transition);
     method public static void go(android.transition.Scene);
     method public static void go(android.transition.Scene, android.transition.Transition);
+    method public void setExitTransition(android.transition.Scene, 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);
@@ -26143,6 +27594,7 @@
     method public final V put(K, V);
     method public final synchronized int putCount();
     method public final V remove(K);
+    method public void resize(int);
     method public final synchronized int size();
     method protected int sizeOf(K, V);
     method public final synchronized java.util.Map<K, V> snapshot();
@@ -26632,6 +28084,7 @@
   }
 
   public class HapticFeedbackConstants {
+    field public static final int CLOCK_TICK = 4; // 0x4
     field public static final int FLAG_IGNORE_GLOBAL_SETTING = 2; // 0x2
     field public static final int FLAG_IGNORE_VIEW_SETTING = 1; // 0x1
     field public static final int KEYBOARD_TAP = 3; // 0x3
@@ -27584,6 +29037,7 @@
     ctor public SurfaceView(android.content.Context);
     ctor public SurfaceView(android.content.Context, android.util.AttributeSet);
     ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int);
+    ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean gatherTransparentRegion(android.graphics.Region);
     method public android.view.SurfaceHolder getHolder();
     method public void setSecure(boolean);
@@ -27595,6 +29049,7 @@
     ctor public TextureView(android.content.Context);
     ctor public TextureView(android.content.Context, android.util.AttributeSet);
     ctor public TextureView(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextureView(android.content.Context, android.util.AttributeSet, int, int);
     method public final void draw(android.graphics.Canvas);
     method public android.graphics.Bitmap getBitmap();
     method public android.graphics.Bitmap getBitmap(int, int);
@@ -27646,6 +29101,7 @@
     ctor public View(android.content.Context);
     ctor public View(android.content.Context, android.util.AttributeSet);
     ctor public View(android.content.Context, android.util.AttributeSet, int);
+    ctor public View(android.content.Context, android.util.AttributeSet, int, int);
     method public void addChildrenForAccessibility(java.util.ArrayList<android.view.View>);
     method public void addFocusables(java.util.ArrayList<android.view.View>, int);
     method public void addFocusables(java.util.ArrayList<android.view.View>, int, int);
@@ -27683,6 +29139,7 @@
     method public android.view.accessibility.AccessibilityNodeInfo createAccessibilityNodeInfo();
     method public void createContextMenu(android.view.ContextMenu);
     method public void destroyDrawingCache();
+    method public android.view.WindowInsets dispatchApplyWindowInsets(android.view.WindowInsets);
     method public void dispatchConfigurationChanged(android.content.res.Configuration);
     method public void dispatchDisplayHint(int);
     method public boolean dispatchDragEvent(android.view.DragEvent);
@@ -27714,7 +29171,7 @@
     method public final android.view.View findViewById(int);
     method public final android.view.View findViewWithTag(java.lang.Object);
     method public void findViewsWithText(java.util.ArrayList<android.view.View>, java.lang.CharSequence, int);
-    method protected boolean fitSystemWindows(android.graphics.Rect);
+    method protected deprecated boolean fitSystemWindows(android.graphics.Rect);
     method public android.view.View focusSearch(int);
     method public void forceLayout();
     method public static int generateViewId();
@@ -27730,6 +29187,7 @@
     method protected int getBottomPaddingOffset();
     method public float getCameraDistance();
     method public android.graphics.Rect getClipBounds();
+    method public final boolean getClipToOutline();
     method public java.lang.CharSequence getContentDescription();
     method public final android.content.Context getContext();
     method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
@@ -27809,6 +29267,7 @@
     method public int getScrollBarStyle();
     method public final int getScrollX();
     method public final int getScrollY();
+    method public java.lang.String getSharedElementName();
     method public int getSolidColor();
     method protected int getSuggestedMinimumHeight();
     method protected int getSuggestedMinimumWidth();
@@ -27824,6 +29283,7 @@
     method public java.util.ArrayList<android.view.View> getTouchables();
     method public float getTranslationX();
     method public float getTranslationY();
+    method public float getTranslationZ();
     method public int getVerticalFadingEdgeLength();
     method public int getVerticalScrollbarPosition();
     method public int getVerticalScrollbarWidth();
@@ -27851,6 +29311,7 @@
     method public void invalidate(int, int, int, int);
     method public void invalidate();
     method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public boolean isAccessibilityFocused();
     method public boolean isActivated();
     method public boolean isAttachedToWindow();
     method public boolean isClickable();
@@ -27866,6 +29327,7 @@
     method public boolean isHorizontalFadingEdgeEnabled();
     method public boolean isHorizontalScrollBarEnabled();
     method public boolean isHovered();
+    method public boolean isImportantForAccessibility();
     method public boolean isInEditMode();
     method public boolean isInLayout();
     method public boolean isInTouchMode();
@@ -27896,6 +29358,7 @@
     method public void offsetTopAndBottom(int);
     method protected void onAnimationEnd();
     method protected void onAnimationStart();
+    method public android.view.WindowInsets onApplyWindowInsets(android.view.WindowInsets);
     method protected void onAttachedToWindow();
     method public void onCancelPendingInputEvents();
     method public boolean onCheckIsTextEditor();
@@ -27962,7 +29425,8 @@
     method public boolean removeCallbacks(java.lang.Runnable);
     method public void removeOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener);
     method public void removeOnLayoutChangeListener(android.view.View.OnLayoutChangeListener);
-    method public void requestFitSystemWindows();
+    method public void requestApplyInsets();
+    method public deprecated void requestFitSystemWindows();
     method public final boolean requestFocus();
     method public final boolean requestFocus(int);
     method public boolean requestFocus(int, android.graphics.Rect);
@@ -27992,6 +29456,7 @@
     method public void setCameraDistance(float);
     method public void setClickable(boolean);
     method public void setClipBounds(android.graphics.Rect);
+    method public void setClipToOutline(boolean);
     method public void setContentDescription(java.lang.CharSequence);
     method public void setDrawingCacheBackgroundColor(int);
     method public void setDrawingCacheEnabled(boolean);
@@ -28026,6 +29491,7 @@
     method public void setNextFocusLeftId(int);
     method public void setNextFocusRightId(int);
     method public void setNextFocusUpId(int);
+    method public void setOnApplyWindowInsetsListener(android.view.View.OnApplyWindowInsetsListener);
     method public void setOnClickListener(android.view.View.OnClickListener);
     method public void setOnCreateContextMenuListener(android.view.View.OnCreateContextMenuListener);
     method public void setOnDragListener(android.view.View.OnDragListener);
@@ -28036,6 +29502,7 @@
     method public void setOnLongClickListener(android.view.View.OnLongClickListener);
     method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
     method public void setOnTouchListener(android.view.View.OnTouchListener);
+    method public void setOutline(android.graphics.Outline);
     method public void setOverScrollMode(int);
     method public void setPadding(int, int, int, int);
     method public void setPaddingRelative(int, int, int, int);
@@ -28059,6 +29526,7 @@
     method public void setScrollY(int);
     method public void setScrollbarFadingEnabled(boolean);
     method public void setSelected(boolean);
+    method public void setSharedElementName(java.lang.String);
     method public void setSoundEffectsEnabled(boolean);
     method public void setSystemUiVisibility(int);
     method public void setTag(java.lang.Object);
@@ -28069,6 +29537,7 @@
     method public void setTouchDelegate(android.view.TouchDelegate);
     method public void setTranslationX(float);
     method public void setTranslationY(float);
+    method public void setTranslationZ(float);
     method public void setVerticalFadingEdgeEnabled(boolean);
     method public void setVerticalScrollBarEnabled(boolean);
     method public void setVerticalScrollbarPosition(int);
@@ -28199,6 +29668,7 @@
     field public static final int TEXT_DIRECTION_RTL = 4; // 0x4
     field public static final android.util.Property TRANSLATION_X;
     field public static final android.util.Property TRANSLATION_Y;
+    field public static final android.util.Property TRANSLATION_Z;
     field protected static final java.lang.String VIEW_LOG_TAG = "View";
     field public static final int VISIBLE = 0; // 0x0
     field protected static final int[] WINDOW_FOCUSED_STATE_SET;
@@ -28244,6 +29714,10 @@
     field public static final int UNSPECIFIED = 0; // 0x0
   }
 
+  public static abstract interface View.OnApplyWindowInsetsListener {
+    method public abstract android.view.WindowInsets onApplyWindowInsets(android.view.View, android.view.WindowInsets);
+  }
+
   public static abstract interface View.OnAttachStateChangeListener {
     method public abstract void onViewAttachedToWindow(android.view.View);
     method public abstract void onViewDetachedFromWindow(android.view.View);
@@ -28384,6 +29858,7 @@
     ctor public ViewGroup(android.content.Context);
     ctor public ViewGroup(android.content.Context, android.util.AttributeSet);
     ctor public ViewGroup(android.content.Context, android.util.AttributeSet, int);
+    ctor public ViewGroup(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean addStatesFromChildren();
     method public void addView(android.view.View);
     method public void addView(android.view.View, int);
@@ -28441,6 +29916,7 @@
     method protected boolean isChildrenDrawingOrderEnabled();
     method protected boolean isChildrenDrawnWithCacheEnabled();
     method public boolean isMotionEventSplittingEnabled();
+    method public boolean isTransitionGroup();
     method public final void layout(int, int, int, int);
     method protected void measureChild(android.view.View, int, int);
     method protected void measureChildWithMargins(android.view.View, int, int, int, int);
@@ -28485,6 +29961,7 @@
     method public void setOnHierarchyChangeListener(android.view.ViewGroup.OnHierarchyChangeListener);
     method public void setPersistentDrawingCache(int);
     method protected void setStaticTransformationsEnabled(boolean);
+    method public void setTransitionGroup(boolean);
     method public boolean shouldDelayChildPressedState();
     method public boolean showContextMenuForChild(android.view.View);
     method public android.view.ActionMode startActionModeForChild(android.view.View, android.view.ActionMode.Callback);
@@ -28621,6 +30098,8 @@
     method public android.view.ViewPropertyAnimator translationXBy(float);
     method public android.view.ViewPropertyAnimator translationY(float);
     method public android.view.ViewPropertyAnimator translationYBy(float);
+    method public android.view.ViewPropertyAnimator translationZ(float);
+    method public android.view.ViewPropertyAnimator translationZBy(float);
     method public android.view.ViewPropertyAnimator withEndAction(java.lang.Runnable);
     method public android.view.ViewPropertyAnimator withLayer();
     method public android.view.ViewPropertyAnimator withStartAction(java.lang.Runnable);
@@ -28635,6 +30114,7 @@
     ctor public ViewStub(android.content.Context, int);
     ctor public ViewStub(android.content.Context, android.util.AttributeSet);
     ctor public ViewStub(android.content.Context, android.util.AttributeSet, int);
+    ctor public ViewStub(android.content.Context, android.util.AttributeSet, int, int);
     method public int getInflatedId();
     method public android.view.LayoutInflater getLayoutInflater();
     method public int getLayoutResource();
@@ -28717,6 +30197,7 @@
     method public final android.view.WindowManager.LayoutParams getAttributes();
     method public final android.view.Window.Callback getCallback();
     method public final android.view.Window getContainer();
+    method public android.transition.Scene getContentScene();
     method public final android.content.Context getContext();
     method public abstract android.view.View getCurrentFocus();
     method public abstract android.view.View getDecorView();
@@ -28724,6 +30205,7 @@
     method protected final int getForcedWindowFlags();
     method public abstract android.view.LayoutInflater getLayoutInflater();
     method protected final int getLocalFeatures();
+    method public android.transition.TransitionManager getTransitionManager();
     method public abstract int getVolumeControlStream();
     method public android.view.WindowManager getWindowManager();
     method public final android.content.res.TypedArray getWindowStyle();
@@ -28736,6 +30218,7 @@
     method public abstract boolean isFloating();
     method public abstract boolean isShortcutKey(int, android.view.KeyEvent);
     method public final void makeActive();
+    method public void mapTransitionTargets(java.util.Map<java.lang.String, java.lang.String>);
     method protected abstract void onActive();
     method public abstract void onConfigurationChanged(android.content.res.Configuration);
     method public abstract void openPanel(int, android.view.KeyEvent);
@@ -28772,7 +30255,9 @@
     method public void setLogo(int);
     method public void setSoftInputMode(int);
     method public abstract void setTitle(java.lang.CharSequence);
-    method public abstract void setTitleColor(int);
+    method public abstract deprecated void setTitleColor(int);
+    method public void setTransitionManager(android.transition.TransitionManager);
+    method public void setTriggerEarlyEnterTransition(boolean);
     method public void setType(int);
     method public void setUiOptions(int);
     method public void setUiOptions(int, int);
@@ -28793,6 +30278,7 @@
     field public static final int FEATURE_ACTION_BAR = 8; // 0x8
     field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
     field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+    field public static final int FEATURE_CONTENT_TRANSITIONS = 12; // 0xc
     field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6
     field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7
     field public static final int FEATURE_INDETERMINATE_PROGRESS = 5; // 0x5
@@ -28853,6 +30339,27 @@
     method public abstract void onFocusLost(android.view.WindowId);
   }
 
+  public class WindowInsets {
+    ctor public WindowInsets(android.view.WindowInsets);
+    method public android.view.WindowInsets cloneWithSystemWindowInsets(int, int, int, int);
+    method public android.view.WindowInsets cloneWithSystemWindowInsetsConsumed();
+    method public android.view.WindowInsets cloneWithSystemWindowInsetsConsumed(boolean, boolean, boolean, boolean);
+    method public android.view.WindowInsets cloneWithWindowDecorInsets(int, int, int, int);
+    method public android.view.WindowInsets cloneWithWindowDecorInsetsConsumed();
+    method public android.view.WindowInsets cloneWithWindowDecorInsetsConsumed(boolean, boolean, boolean, boolean);
+    method public int getSystemWindowInsetBottom();
+    method public int getSystemWindowInsetLeft();
+    method public int getSystemWindowInsetRight();
+    method public int getSystemWindowInsetTop();
+    method public int getWindowDecorInsetBottom();
+    method public int getWindowDecorInsetLeft();
+    method public int getWindowDecorInsetRight();
+    method public int getWindowDecorInsetTop();
+    method public boolean hasInsets();
+    method public boolean hasSystemWindowInsets();
+    method public boolean hasWindowDecorInsets();
+  }
+
   public abstract interface WindowManager implements android.view.ViewManager {
     method public abstract android.view.Display getDefaultDisplay();
     method public abstract void removeViewImmediate(android.view.View);
@@ -29057,6 +30564,7 @@
     field public static final int TYPE_VIEW_TEXT_CHANGED = 16; // 0x10
     field public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 8192; // 0x2000
     field public static final int TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 131072; // 0x20000
+    field public static final int TYPE_WINDOWS_CHANGED = 4194304; // 0x400000
     field public static final int TYPE_WINDOW_CONTENT_CHANGED = 2048; // 0x800
     field public static final int TYPE_WINDOW_STATE_CHANGED = 32; // 0x20
   }
@@ -29120,6 +30628,7 @@
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
     method public java.lang.String getViewIdResourceName();
+    method public android.view.accessibility.AccessibilityWindowInfo getWindow();
     method public int getWindowId();
     method public boolean isAccessibilityFocused();
     method public boolean isCheckable();
@@ -29145,6 +30654,9 @@
     method public boolean performAction(int, android.os.Bundle);
     method public void recycle();
     method public boolean refresh();
+    method public void removeAction(int);
+    method public boolean removeChild(android.view.View);
+    method public boolean removeChild(android.view.View, int);
     method public void setAccessibilityFocused(boolean);
     method public void setBoundsInParent(android.graphics.Rect);
     method public void setBoundsInScreen(android.graphics.Rect);
@@ -29191,6 +30703,7 @@
     field public static final java.lang.String ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT = "ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT";
     field public static final java.lang.String ACTION_ARGUMENT_SELECTION_END_INT = "ACTION_ARGUMENT_SELECTION_END_INT";
     field public static final java.lang.String ACTION_ARGUMENT_SELECTION_START_INT = "ACTION_ARGUMENT_SELECTION_START_INT";
+    field public static final java.lang.String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE = "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
     field public static final int ACTION_CLEAR_ACCESSIBILITY_FOCUS = 128; // 0x80
     field public static final int ACTION_CLEAR_FOCUS = 2; // 0x2
     field public static final int ACTION_CLEAR_SELECTION = 8; // 0x8
@@ -29211,6 +30724,7 @@
     field public static final int ACTION_SCROLL_FORWARD = 4096; // 0x1000
     field public static final int ACTION_SELECT = 4; // 0x4
     field public static final int ACTION_SET_SELECTION = 131072; // 0x20000
+    field public static final int ACTION_SET_TEXT = 2097152; // 0x200000
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int FOCUS_ACCESSIBILITY = 2; // 0x2
     field public static final int FOCUS_INPUT = 1; // 0x1
@@ -29224,8 +30738,13 @@
   public static final class AccessibilityNodeInfo.CollectionInfo {
     method public int getColumnCount();
     method public int getRowCount();
+    method public int getSelectionMode();
     method public boolean isHierarchical();
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionInfo obtain(int, int, boolean);
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionInfo obtain(int, int, boolean, int);
+    field public static final int SELECTION_MODE_MULTIPLE = 2; // 0x2
+    field public static final int SELECTION_MODE_NONE = 0; // 0x0
+    field public static final int SELECTION_MODE_SINGLE = 1; // 0x1
   }
 
   public static final class AccessibilityNodeInfo.CollectionItemInfo {
@@ -29234,7 +30753,9 @@
     method public int getRowIndex();
     method public int getRowSpan();
     method public boolean isHeading();
+    method public boolean isSelected();
     method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean);
+    method public static android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo obtain(int, int, int, int, boolean, boolean);
   }
 
   public static final class AccessibilityNodeInfo.RangeInfo {
@@ -29254,6 +30775,7 @@
     method public java.util.List<android.view.accessibility.AccessibilityNodeInfo> findAccessibilityNodeInfosByText(java.lang.String, int);
     method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
     method public boolean performAction(int, int, android.os.Bundle);
+    field public static final int HOST_VIEW_ID = -1; // 0xffffffff
   }
 
   public class AccessibilityRecord {
@@ -29305,6 +30827,28 @@
     method public void setToIndex(int);
   }
 
+  public final class AccessibilityWindowInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public void getBoundsInScreen(android.graphics.Rect);
+    method public android.view.accessibility.AccessibilityWindowInfo getChild(int);
+    method public int getChildCount();
+    method public int getId();
+    method public int getLayer();
+    method public android.view.accessibility.AccessibilityWindowInfo getParent();
+    method public android.view.accessibility.AccessibilityNodeInfo getRoot();
+    method public int getType();
+    method public boolean isActive();
+    method public boolean isFocused();
+    method public static android.view.accessibility.AccessibilityWindowInfo obtain();
+    method public static android.view.accessibility.AccessibilityWindowInfo obtain(android.view.accessibility.AccessibilityWindowInfo);
+    method public void recycle();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int TYPE_APPLICATION = 1; // 0x1
+    field public static final int TYPE_INPUT_METHOD = 2; // 0x2
+    field public static final int TYPE_SYSTEM = 3; // 0x3
+  }
+
   public class CaptioningManager {
     method public void addCaptioningChangeListener(android.view.accessibility.CaptioningManager.CaptioningChangeListener);
     method public final float getFontScale();
@@ -29316,13 +30860,16 @@
 
   public static final class CaptioningManager.CaptionStyle {
     method public android.graphics.Typeface getTypeface();
+    field public static final int EDGE_TYPE_DEPRESSED = 4; // 0x4
     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 static final int EDGE_TYPE_RAISED = 3; // 0x3
     field public final int backgroundColor;
     field public final int edgeColor;
     field public final int edgeType;
     field public final int foregroundColor;
+    field public final int windowColor;
   }
 
   public static abstract class CaptioningManager.CaptioningChangeListener {
@@ -29560,6 +31107,14 @@
     method public float getInterpolation(float);
   }
 
+  public class PathInterpolator implements android.view.animation.Interpolator {
+    ctor public PathInterpolator(android.graphics.Path);
+    ctor public PathInterpolator(float, float);
+    ctor public PathInterpolator(float, float, float, float);
+    ctor public PathInterpolator(android.content.Context, android.util.AttributeSet);
+    method public float getInterpolation(float);
+  }
+
   public class RotateAnimation extends android.view.animation.Animation {
     ctor public RotateAnimation(android.content.Context, android.util.AttributeSet);
     ctor public RotateAnimation(float, float);
@@ -30398,6 +31953,7 @@
     ctor public WebView(android.content.Context);
     ctor public WebView(android.content.Context, android.util.AttributeSet);
     ctor public WebView(android.content.Context, android.util.AttributeSet, int);
+    ctor public WebView(android.content.Context, android.util.AttributeSet, int, int);
     ctor public deprecated WebView(android.content.Context, android.util.AttributeSet, int, boolean);
     method public void addJavascriptInterface(java.lang.Object, java.lang.String);
     method public boolean canGoBack();
@@ -30572,6 +32128,7 @@
     ctor public AbsListView(android.content.Context);
     ctor public AbsListView(android.content.Context, android.util.AttributeSet);
     ctor public AbsListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsListView(android.content.Context, android.util.AttributeSet, int, int);
     method public void afterTextChanged(android.text.Editable);
     method public void beforeTextChanged(java.lang.CharSequence, int, int, int);
     method public boolean canScrollList(int);
@@ -30623,6 +32180,7 @@
     method public void setDrawSelectorOnTop(boolean);
     method public void setFastScrollAlwaysVisible(boolean);
     method public void setFastScrollEnabled(boolean);
+    method public void setFastScrollStyle(int);
     method public void setFilterText(java.lang.String);
     method public void setFriction(float);
     method public void setItemChecked(int, boolean);
@@ -30632,6 +32190,7 @@
     method public void setRemoteViewsAdapter(android.content.Intent);
     method public void setScrollIndicators(android.view.View, android.view.View);
     method public void setScrollingCacheEnabled(boolean);
+    method public void setSelectionFromTop(int, int);
     method public void setSelector(int);
     method public void setSelector(android.graphics.drawable.Drawable);
     method public void setSmoothScrollbarEnabled(boolean);
@@ -30685,6 +32244,7 @@
     ctor public AbsSeekBar(android.content.Context);
     ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet);
     ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsSeekBar(android.content.Context, android.util.AttributeSet, int, int);
     method public int getKeyProgressIncrement();
     method public android.graphics.drawable.Drawable getThumb();
     method public int getThumbOffset();
@@ -30697,6 +32257,7 @@
     ctor public AbsSpinner(android.content.Context);
     ctor public AbsSpinner(android.content.Context, android.util.AttributeSet);
     ctor public AbsSpinner(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsSpinner(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.SpinnerAdapter getAdapter();
     method public android.view.View getSelectedView();
     method public void onRestoreInstanceState(android.os.Parcelable);
@@ -30711,6 +32272,7 @@
     ctor public AbsoluteLayout(android.content.Context);
     ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet);
     ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public AbsoluteLayout(android.content.Context, android.util.AttributeSet, int, int);
     method protected void onLayout(boolean, int, int, int, int);
   }
 
@@ -30723,6 +32285,21 @@
     field public int y;
   }
 
+  public class ActionMenuView extends android.widget.LinearLayout {
+    ctor public ActionMenuView(android.content.Context);
+    ctor public ActionMenuView(android.content.Context, android.util.AttributeSet);
+    method public android.view.Menu getMenu();
+    method public void onConfigurationChanged(android.content.res.Configuration);
+    method public void onDetachedFromWindow();
+  }
+
+  public static class ActionMenuView.LayoutParams extends android.widget.LinearLayout.LayoutParams {
+    ctor public ActionMenuView.LayoutParams(android.content.Context, android.util.AttributeSet);
+    ctor public ActionMenuView.LayoutParams(android.view.ViewGroup.LayoutParams);
+    ctor public ActionMenuView.LayoutParams(android.widget.ActionMenuView.LayoutParams);
+    ctor public ActionMenuView.LayoutParams(int, int);
+  }
+
   public abstract interface Adapter {
     method public abstract int getCount();
     method public abstract java.lang.Object getItem(int);
@@ -30742,6 +32319,7 @@
     ctor public AdapterView(android.content.Context);
     ctor public AdapterView(android.content.Context, android.util.AttributeSet);
     ctor public AdapterView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterView(android.content.Context, android.util.AttributeSet, int, int);
     method public abstract T getAdapter();
     method public int getCount();
     method public android.view.View getEmptyView();
@@ -30795,6 +32373,7 @@
     ctor public AdapterViewAnimator(android.content.Context);
     ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet);
     ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int, int);
     method public void advance();
     method public void deferNotifyDataSetChanged();
     method public void fyiWillBeAdvancedByHostKThx();
@@ -30824,6 +32403,8 @@
   public class AdapterViewFlipper extends android.widget.AdapterViewAnimator {
     ctor public AdapterViewFlipper(android.content.Context);
     ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet);
+    ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet, int);
+    ctor public AdapterViewFlipper(android.content.Context, android.util.AttributeSet, int, int);
     method public int getFlipInterval();
     method public boolean isAutoStart();
     method public boolean isFlipping();
@@ -30854,6 +32435,7 @@
     ctor public AnalogClock(android.content.Context);
     ctor public AnalogClock(android.content.Context, android.util.AttributeSet);
     ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int);
+    ctor public AnalogClock(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class ArrayAdapter extends android.widget.BaseAdapter implements android.widget.Filterable {
@@ -30886,6 +32468,7 @@
     ctor public AutoCompleteTextView(android.content.Context);
     ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet);
     ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public AutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int);
     method public void clearListSelection();
     method protected java.lang.CharSequence convertSelectionToString(java.lang.Object);
     method public void dismissDropDown();
@@ -30978,12 +32561,14 @@
     ctor public Button(android.content.Context);
     ctor public Button(android.content.Context, android.util.AttributeSet);
     ctor public Button(android.content.Context, android.util.AttributeSet, int);
+    ctor public Button(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class CalendarView extends android.widget.FrameLayout {
     ctor public CalendarView(android.content.Context);
     ctor public CalendarView(android.content.Context, android.util.AttributeSet);
     ctor public CalendarView(android.content.Context, android.util.AttributeSet, int);
+    ctor public CalendarView(android.content.Context, android.util.AttributeSet, int, int);
     method public long getDate();
     method public int getDateTextAppearance();
     method public int getFirstDayOfWeek();
@@ -31025,6 +32610,7 @@
     ctor public CheckBox(android.content.Context);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet);
     ctor public CheckBox(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckBox(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public abstract interface Checkable {
@@ -31037,6 +32623,7 @@
     ctor public CheckedTextView(android.content.Context);
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet);
     ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public CheckedTextView(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getCheckMarkDrawable();
     method public boolean isChecked();
     method public void setCheckMarkDrawable(int);
@@ -31049,6 +32636,7 @@
     ctor public Chronometer(android.content.Context);
     ctor public Chronometer(android.content.Context, android.util.AttributeSet);
     ctor public Chronometer(android.content.Context, android.util.AttributeSet, int);
+    ctor public Chronometer(android.content.Context, android.util.AttributeSet, int, int);
     method public long getBase();
     method public java.lang.String getFormat();
     method public android.widget.Chronometer.OnChronometerTickListener getOnChronometerTickListener();
@@ -31067,6 +32655,7 @@
     ctor public CompoundButton(android.content.Context);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet);
     ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean isChecked();
     method public void setButtonDrawable(int);
     method public void setButtonDrawable(android.graphics.drawable.Drawable);
@@ -31138,6 +32727,7 @@
     ctor public DatePicker(android.content.Context);
     ctor public DatePicker(android.content.Context, android.util.AttributeSet);
     ctor public DatePicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public DatePicker(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.CalendarView getCalendarView();
     method public boolean getCalendarViewShown();
     method public int getDayOfMonth();
@@ -31201,6 +32791,7 @@
     ctor public EditText(android.content.Context);
     ctor public EditText(android.content.Context, android.util.AttributeSet);
     ctor public EditText(android.content.Context, android.util.AttributeSet, int);
+    ctor public EditText(android.content.Context, android.util.AttributeSet, int, int);
     method public void extendSelection(int);
     method public void selectAll();
     method public void setSelection(int, int);
@@ -31232,6 +32823,7 @@
     ctor public ExpandableListView(android.content.Context);
     ctor public ExpandableListView(android.content.Context, android.util.AttributeSet);
     ctor public ExpandableListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ExpandableListView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean collapseGroup(int);
     method public boolean expandGroup(int);
     method public boolean expandGroup(int, boolean);
@@ -31321,6 +32913,7 @@
     ctor public FrameLayout(android.content.Context);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet);
     ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public FrameLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public deprecated boolean getConsiderGoneChildrenWhenMeasuring();
     method public android.graphics.drawable.Drawable getForeground();
     method public int getForegroundGravity();
@@ -31345,6 +32938,7 @@
     ctor public Gallery(android.content.Context);
     ctor public Gallery(android.content.Context, android.util.AttributeSet);
     ctor public Gallery(android.content.Context, android.util.AttributeSet, int);
+    ctor public Gallery(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean onDown(android.view.MotionEvent);
     method public boolean onFling(android.view.MotionEvent, android.view.MotionEvent, float, float);
     method public void onLongPress(android.view.MotionEvent);
@@ -31365,9 +32959,10 @@
   }
 
   public class GridLayout extends android.view.ViewGroup {
-    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
-    ctor public GridLayout(android.content.Context, android.util.AttributeSet);
     ctor public GridLayout(android.content.Context);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public GridLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getAlignmentMode();
     method public int getColumnCount();
     method public int getOrientation();
@@ -31425,6 +33020,7 @@
     ctor public GridView(android.content.Context);
     ctor public GridView(android.content.Context, android.util.AttributeSet);
     ctor public GridView(android.content.Context, android.util.AttributeSet, int);
+    ctor public GridView(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.ListAdapter getAdapter();
     method public int getColumnWidth();
     method public int getGravity();
@@ -31482,6 +33078,7 @@
     ctor public HorizontalScrollView(android.content.Context);
     ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet);
     ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet, int);
+    ctor public HorizontalScrollView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean arrowScroll(int);
     method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
     method public boolean executeKeyEvent(android.view.KeyEvent);
@@ -31501,6 +33098,7 @@
     ctor public ImageButton(android.content.Context);
     ctor public ImageButton(android.content.Context, android.util.AttributeSet);
     ctor public ImageButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public ImageButton(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class ImageSwitcher extends android.widget.ViewSwitcher {
@@ -31515,6 +33113,7 @@
     ctor public ImageView(android.content.Context);
     ctor public ImageView(android.content.Context, android.util.AttributeSet);
     ctor public ImageView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ImageView(android.content.Context, android.util.AttributeSet, int, int);
     method public final void clearColorFilter();
     method public boolean getAdjustViewBounds();
     method public boolean getBaselineAlignBottom();
@@ -31566,6 +33165,7 @@
     ctor public LinearLayout(android.content.Context);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet);
     ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public LinearLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getBaselineAlignedChildIndex();
     method public android.graphics.drawable.Drawable getDividerDrawable();
     method public int getDividerPadding();
@@ -31676,6 +33276,7 @@
     ctor public ListView(android.content.Context);
     ctor public ListView(android.content.Context, android.util.AttributeSet);
     ctor public ListView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ListView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addFooterView(android.view.View, java.lang.Object, boolean);
     method public void addFooterView(android.view.View);
     method public void addHeaderView(android.view.View, java.lang.Object, boolean);
@@ -31705,7 +33306,6 @@
     method public void setOverscrollHeader(android.graphics.drawable.Drawable);
     method public void setSelection(int);
     method public void setSelectionAfterHeaderView();
-    method public void setSelectionFromTop(int, int);
     method public void smoothScrollByOffset(int);
   }
 
@@ -31748,6 +33348,7 @@
     ctor public MultiAutoCompleteTextView(android.content.Context);
     ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet);
     ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public MultiAutoCompleteTextView(android.content.Context, android.util.AttributeSet, int, int);
     method protected void performFiltering(java.lang.CharSequence, int, int, int);
     method public void setTokenizer(android.widget.MultiAutoCompleteTextView.Tokenizer);
   }
@@ -31769,6 +33370,7 @@
     ctor public NumberPicker(android.content.Context);
     ctor public NumberPicker(android.content.Context, android.util.AttributeSet);
     ctor public NumberPicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public NumberPicker(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.String[] getDisplayedValues();
     method public int getMaxValue();
     method public int getMinValue();
@@ -31914,6 +33516,7 @@
     ctor public ProgressBar(android.content.Context);
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet);
     ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public ProgressBar(android.content.Context, android.util.AttributeSet, int, int);
     method public android.graphics.drawable.Drawable getIndeterminateDrawable();
     method public android.view.animation.Interpolator getInterpolator();
     method public synchronized int getMax();
@@ -31927,11 +33530,13 @@
     method public android.os.Parcelable onSaveInstanceState();
     method public synchronized void setIndeterminate(boolean);
     method public void setIndeterminateDrawable(android.graphics.drawable.Drawable);
+    method public void setIndeterminateDrawableTiled(android.graphics.drawable.Drawable);
     method public void setInterpolator(android.content.Context, int);
     method public void setInterpolator(android.view.animation.Interpolator);
     method public synchronized void setMax(int);
     method public synchronized void setProgress(int);
     method public void setProgressDrawable(android.graphics.drawable.Drawable);
+    method public void setProgressDrawableTiled(android.graphics.drawable.Drawable);
     method public synchronized void setSecondaryProgress(int);
   }
 
@@ -31939,6 +33544,7 @@
     ctor public QuickContactBadge(android.content.Context);
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet);
     ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet, int);
+    ctor public QuickContactBadge(android.content.Context, android.util.AttributeSet, int, int);
     method public void assignContactFromEmail(java.lang.String, boolean);
     method public void assignContactFromEmail(java.lang.String, boolean, android.os.Bundle);
     method public void assignContactFromPhone(java.lang.String, boolean);
@@ -31955,6 +33561,7 @@
     ctor public RadioButton(android.content.Context);
     ctor public RadioButton(android.content.Context, android.util.AttributeSet);
     ctor public RadioButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public RadioButton(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class RadioGroup extends android.widget.LinearLayout {
@@ -31980,6 +33587,7 @@
 
   public class RatingBar extends android.widget.AbsSeekBar {
     ctor public RatingBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public RatingBar(android.content.Context, android.util.AttributeSet, int, int);
     ctor public RatingBar(android.content.Context, android.util.AttributeSet);
     ctor public RatingBar(android.content.Context);
     method public int getNumStars();
@@ -32002,6 +33610,7 @@
     ctor public RelativeLayout(android.content.Context);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet);
     ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int);
+    ctor public RelativeLayout(android.content.Context, android.util.AttributeSet, int, int);
     method public int getGravity();
     method protected void onLayout(boolean, int, int, int, int);
     method public void setGravity(int);
@@ -32150,6 +33759,7 @@
     ctor public ScrollView(android.content.Context);
     ctor public ScrollView(android.content.Context, android.util.AttributeSet);
     ctor public ScrollView(android.content.Context, android.util.AttributeSet, int);
+    ctor public ScrollView(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean arrowScroll(int);
     method protected int computeScrollDeltaToGetChildRectOnScreen(android.graphics.Rect);
     method public boolean executeKeyEvent(android.view.KeyEvent);
@@ -32194,6 +33804,8 @@
   public class SearchView extends android.widget.LinearLayout implements android.view.CollapsibleActionView {
     ctor public SearchView(android.content.Context);
     ctor public SearchView(android.content.Context, android.util.AttributeSet);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet, int);
+    ctor public SearchView(android.content.Context, android.util.AttributeSet, int, int);
     method public int getImeOptions();
     method public int getInputType();
     method public int getMaxWidth();
@@ -32248,6 +33860,7 @@
     ctor public SeekBar(android.content.Context);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet);
     ctor public SeekBar(android.content.Context, android.util.AttributeSet, int);
+    ctor public SeekBar(android.content.Context, android.util.AttributeSet, int, int);
     method public void setOnSeekBarChangeListener(android.widget.SeekBar.OnSeekBarChangeListener);
   }
 
@@ -32349,6 +33962,7 @@
   public deprecated class SlidingDrawer extends android.view.ViewGroup {
     ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet);
     ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet, int);
+    ctor public SlidingDrawer(android.content.Context, android.util.AttributeSet, int, int);
     method public void animateClose();
     method public void animateOpen();
     method public void animateToggle();
@@ -32383,6 +33997,7 @@
   }
 
   public final class Space extends android.view.View {
+    ctor public Space(android.content.Context, android.util.AttributeSet, int, int);
     ctor public Space(android.content.Context, android.util.AttributeSet, int);
     ctor public Space(android.content.Context, android.util.AttributeSet);
     ctor public Space(android.content.Context);
@@ -32394,6 +34009,7 @@
     ctor public Spinner(android.content.Context, android.util.AttributeSet);
     ctor public Spinner(android.content.Context, android.util.AttributeSet, int);
     ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int);
+    ctor public Spinner(android.content.Context, android.util.AttributeSet, int, int, int);
     method public int getDropDownHorizontalOffset();
     method public int getDropDownVerticalOffset();
     method public int getDropDownWidth();
@@ -32421,12 +34037,14 @@
     ctor public StackView(android.content.Context);
     ctor public StackView(android.content.Context, android.util.AttributeSet);
     ctor public StackView(android.content.Context, android.util.AttributeSet, int);
+    ctor public StackView(android.content.Context, android.util.AttributeSet, int, int);
   }
 
   public class Switch extends android.widget.CompoundButton {
     ctor public Switch(android.content.Context);
     ctor public Switch(android.content.Context, android.util.AttributeSet);
     ctor public Switch(android.content.Context, android.util.AttributeSet, int);
+    ctor public Switch(android.content.Context, android.util.AttributeSet, int, int);
     method public int getSwitchMinWidth();
     method public int getSwitchPadding();
     method public java.lang.CharSequence getTextOff();
@@ -32452,6 +34070,8 @@
   public class TabHost extends android.widget.FrameLayout implements android.view.ViewTreeObserver.OnTouchModeChangeListener {
     ctor public TabHost(android.content.Context);
     ctor public TabHost(android.content.Context, android.util.AttributeSet);
+    ctor public TabHost(android.content.Context, android.util.AttributeSet, int);
+    ctor public TabHost(android.content.Context, android.util.AttributeSet, int, int);
     method public void addTab(android.widget.TabHost.TabSpec);
     method public void clearAllTabs();
     method public int getCurrentTab();
@@ -32491,6 +34111,7 @@
     ctor public TabWidget(android.content.Context);
     ctor public TabWidget(android.content.Context, android.util.AttributeSet);
     ctor public TabWidget(android.content.Context, android.util.AttributeSet, int);
+    ctor public TabWidget(android.content.Context, android.util.AttributeSet, int, int);
     method public void dispatchDraw(android.graphics.Canvas);
     method public void focusCurrentTab(int);
     method public android.view.View getChildTabViewAt(int);
@@ -32553,6 +34174,7 @@
     ctor public TextClock(android.content.Context);
     ctor public TextClock(android.content.Context, android.util.AttributeSet);
     ctor public TextClock(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextClock(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.CharSequence getFormat12Hour();
     method public java.lang.CharSequence getFormat24Hour();
     method public java.lang.String getTimeZone();
@@ -32575,6 +34197,7 @@
     ctor public TextView(android.content.Context);
     ctor public TextView(android.content.Context, android.util.AttributeSet);
     ctor public TextView(android.content.Context, android.util.AttributeSet, int);
+    ctor public TextView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addTextChangedListener(android.text.TextWatcher);
     method public final void append(java.lang.CharSequence);
     method public void append(java.lang.CharSequence, int, int);
@@ -32782,6 +34405,7 @@
     ctor public TimePicker(android.content.Context);
     ctor public TimePicker(android.content.Context, android.util.AttributeSet);
     ctor public TimePicker(android.content.Context, android.util.AttributeSet, int);
+    ctor public TimePicker(android.content.Context, android.util.AttributeSet, int, int);
     method public java.lang.Integer getCurrentHour();
     method public java.lang.Integer getCurrentMinute();
     method public boolean is24HourView();
@@ -32819,6 +34443,7 @@
   }
 
   public class ToggleButton extends android.widget.CompoundButton {
+    ctor public ToggleButton(android.content.Context, android.util.AttributeSet, int, int);
     ctor public ToggleButton(android.content.Context, android.util.AttributeSet, int);
     ctor public ToggleButton(android.content.Context, android.util.AttributeSet);
     ctor public ToggleButton(android.content.Context);
@@ -32832,6 +34457,7 @@
     ctor public TwoLineListItem(android.content.Context);
     ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet);
     ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet, int);
+    ctor public TwoLineListItem(android.content.Context, android.util.AttributeSet, int, int);
     method public android.widget.TextView getText1();
     method public android.widget.TextView getText2();
   }
@@ -32840,6 +34466,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);
+    ctor public VideoView(android.content.Context, android.util.AttributeSet, int, int);
     method public void addSubtitleSource(java.io.InputStream, android.media.MediaFormat);
     method public boolean canPause();
     method public boolean canSeekBackward();
@@ -32914,6 +34541,7 @@
     ctor public ZoomButton(android.content.Context);
     ctor public ZoomButton(android.content.Context, android.util.AttributeSet);
     ctor public ZoomButton(android.content.Context, android.util.AttributeSet, int);
+    ctor public ZoomButton(android.content.Context, android.util.AttributeSet, int, int);
     method public boolean onLongClick(android.view.View);
     method public void setZoomSpeed(long);
   }
@@ -34838,6 +36466,109 @@
     field public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
   }
 
+  public static final class Character.UnicodeScript extends java.lang.Enum {
+    method public static java.lang.Character.UnicodeScript forName(java.lang.String);
+    method public static java.lang.Character.UnicodeScript of(int);
+    method public static java.lang.Character.UnicodeScript valueOf(java.lang.String);
+    method public static final java.lang.Character.UnicodeScript[] values();
+    enum_constant public static final java.lang.Character.UnicodeScript ARABIC;
+    enum_constant public static final java.lang.Character.UnicodeScript ARMENIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript AVESTAN;
+    enum_constant public static final java.lang.Character.UnicodeScript BALINESE;
+    enum_constant public static final java.lang.Character.UnicodeScript BAMUM;
+    enum_constant public static final java.lang.Character.UnicodeScript BATAK;
+    enum_constant public static final java.lang.Character.UnicodeScript BENGALI;
+    enum_constant public static final java.lang.Character.UnicodeScript BOPOMOFO;
+    enum_constant public static final java.lang.Character.UnicodeScript BRAHMI;
+    enum_constant public static final java.lang.Character.UnicodeScript BRAILLE;
+    enum_constant public static final java.lang.Character.UnicodeScript BUGINESE;
+    enum_constant public static final java.lang.Character.UnicodeScript BUHID;
+    enum_constant public static final java.lang.Character.UnicodeScript CANADIAN_ABORIGINAL;
+    enum_constant public static final java.lang.Character.UnicodeScript CARIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript CHAM;
+    enum_constant public static final java.lang.Character.UnicodeScript CHEROKEE;
+    enum_constant public static final java.lang.Character.UnicodeScript COMMON;
+    enum_constant public static final java.lang.Character.UnicodeScript COPTIC;
+    enum_constant public static final java.lang.Character.UnicodeScript CUNEIFORM;
+    enum_constant public static final java.lang.Character.UnicodeScript CYPRIOT;
+    enum_constant public static final java.lang.Character.UnicodeScript CYRILLIC;
+    enum_constant public static final java.lang.Character.UnicodeScript DESERET;
+    enum_constant public static final java.lang.Character.UnicodeScript DEVANAGARI;
+    enum_constant public static final java.lang.Character.UnicodeScript EGYPTIAN_HIEROGLYPHS;
+    enum_constant public static final java.lang.Character.UnicodeScript ETHIOPIC;
+    enum_constant public static final java.lang.Character.UnicodeScript GEORGIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript GLAGOLITIC;
+    enum_constant public static final java.lang.Character.UnicodeScript GOTHIC;
+    enum_constant public static final java.lang.Character.UnicodeScript GREEK;
+    enum_constant public static final java.lang.Character.UnicodeScript GUJARATI;
+    enum_constant public static final java.lang.Character.UnicodeScript GURMUKHI;
+    enum_constant public static final java.lang.Character.UnicodeScript HAN;
+    enum_constant public static final java.lang.Character.UnicodeScript HANGUL;
+    enum_constant public static final java.lang.Character.UnicodeScript HANUNOO;
+    enum_constant public static final java.lang.Character.UnicodeScript HEBREW;
+    enum_constant public static final java.lang.Character.UnicodeScript HIRAGANA;
+    enum_constant public static final java.lang.Character.UnicodeScript IMPERIAL_ARAMAIC;
+    enum_constant public static final java.lang.Character.UnicodeScript INHERITED;
+    enum_constant public static final java.lang.Character.UnicodeScript INSCRIPTIONAL_PAHLAVI;
+    enum_constant public static final java.lang.Character.UnicodeScript INSCRIPTIONAL_PARTHIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript JAVANESE;
+    enum_constant public static final java.lang.Character.UnicodeScript KAITHI;
+    enum_constant public static final java.lang.Character.UnicodeScript KANNADA;
+    enum_constant public static final java.lang.Character.UnicodeScript KATAKANA;
+    enum_constant public static final java.lang.Character.UnicodeScript KAYAH_LI;
+    enum_constant public static final java.lang.Character.UnicodeScript KHAROSHTHI;
+    enum_constant public static final java.lang.Character.UnicodeScript KHMER;
+    enum_constant public static final java.lang.Character.UnicodeScript LAO;
+    enum_constant public static final java.lang.Character.UnicodeScript LATIN;
+    enum_constant public static final java.lang.Character.UnicodeScript LEPCHA;
+    enum_constant public static final java.lang.Character.UnicodeScript LIMBU;
+    enum_constant public static final java.lang.Character.UnicodeScript LINEAR_B;
+    enum_constant public static final java.lang.Character.UnicodeScript LISU;
+    enum_constant public static final java.lang.Character.UnicodeScript LYCIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript LYDIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript MALAYALAM;
+    enum_constant public static final java.lang.Character.UnicodeScript MANDAIC;
+    enum_constant public static final java.lang.Character.UnicodeScript MEETEI_MAYEK;
+    enum_constant public static final java.lang.Character.UnicodeScript MONGOLIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript MYANMAR;
+    enum_constant public static final java.lang.Character.UnicodeScript NEW_TAI_LUE;
+    enum_constant public static final java.lang.Character.UnicodeScript NKO;
+    enum_constant public static final java.lang.Character.UnicodeScript OGHAM;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_ITALIC;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_PERSIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_SOUTH_ARABIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_TURKIC;
+    enum_constant public static final java.lang.Character.UnicodeScript OL_CHIKI;
+    enum_constant public static final java.lang.Character.UnicodeScript ORIYA;
+    enum_constant public static final java.lang.Character.UnicodeScript OSMANYA;
+    enum_constant public static final java.lang.Character.UnicodeScript PHAGS_PA;
+    enum_constant public static final java.lang.Character.UnicodeScript PHOENICIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript REJANG;
+    enum_constant public static final java.lang.Character.UnicodeScript RUNIC;
+    enum_constant public static final java.lang.Character.UnicodeScript SAMARITAN;
+    enum_constant public static final java.lang.Character.UnicodeScript SAURASHTRA;
+    enum_constant public static final java.lang.Character.UnicodeScript SHAVIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript SINHALA;
+    enum_constant public static final java.lang.Character.UnicodeScript SUNDANESE;
+    enum_constant public static final java.lang.Character.UnicodeScript SYLOTI_NAGRI;
+    enum_constant public static final java.lang.Character.UnicodeScript SYRIAC;
+    enum_constant public static final java.lang.Character.UnicodeScript TAGALOG;
+    enum_constant public static final java.lang.Character.UnicodeScript TAGBANWA;
+    enum_constant public static final java.lang.Character.UnicodeScript TAI_LE;
+    enum_constant public static final java.lang.Character.UnicodeScript TAI_THAM;
+    enum_constant public static final java.lang.Character.UnicodeScript TAI_VIET;
+    enum_constant public static final java.lang.Character.UnicodeScript TAMIL;
+    enum_constant public static final java.lang.Character.UnicodeScript TELUGU;
+    enum_constant public static final java.lang.Character.UnicodeScript THAANA;
+    enum_constant public static final java.lang.Character.UnicodeScript THAI;
+    enum_constant public static final java.lang.Character.UnicodeScript TIBETAN;
+    enum_constant public static final java.lang.Character.UnicodeScript TIFINAGH;
+    enum_constant public static final java.lang.Character.UnicodeScript UGARITIC;
+    enum_constant public static final java.lang.Character.UnicodeScript UNKNOWN;
+    enum_constant public static final java.lang.Character.UnicodeScript VAI;
+    enum_constant public static final java.lang.Character.UnicodeScript YI;
+  }
+
   public final class Class implements java.lang.reflect.AnnotatedElement java.lang.reflect.GenericDeclaration java.io.Serializable java.lang.reflect.Type {
     method public java.lang.Class<? extends U> asSubclass(java.lang.Class<U>);
     method public T cast(java.lang.Object);
@@ -37073,6 +38804,11 @@
     method public abstract java.net.SocketImpl createSocketImpl();
   }
 
+  public abstract interface SocketOption {
+    method public abstract java.lang.String name();
+    method public abstract java.lang.Class<T> type();
+  }
+
   public abstract interface SocketOptions {
     method public abstract java.lang.Object getOption(int) throws java.net.SocketException;
     method public abstract void setOption(int, java.lang.Object) throws java.net.SocketException;
@@ -37103,6 +38839,21 @@
     ctor public SocketTimeoutException(java.lang.String);
   }
 
+  public final class StandardSocketOptions {
+    ctor public StandardSocketOptions();
+    field public static final java.net.SocketOption IP_MULTICAST_IF;
+    field public static final java.net.SocketOption IP_MULTICAST_LOOP;
+    field public static final java.net.SocketOption IP_MULTICAST_TTL;
+    field public static final java.net.SocketOption IP_TOS;
+    field public static final java.net.SocketOption SO_BROADCAST;
+    field public static final java.net.SocketOption SO_KEEPALIVE;
+    field public static final java.net.SocketOption SO_LINGER;
+    field public static final java.net.SocketOption SO_RCVBUF;
+    field public static final java.net.SocketOption SO_REUSEADDR;
+    field public static final java.net.SocketOption SO_SNDBUF;
+    field public static final java.net.SocketOption TCP_NODELAY;
+  }
+
   public final class URI implements java.lang.Comparable java.io.Serializable {
     ctor public URI(java.lang.String) throws java.net.URISyntaxException;
     ctor public URI(java.lang.String, java.lang.String, java.lang.String) throws java.net.URISyntaxException;
@@ -37198,6 +38949,7 @@
     method public java.lang.Object getContent(java.lang.Class[]) throws java.io.IOException;
     method public java.lang.String getContentEncoding();
     method public int getContentLength();
+    method public long getContentLengthLong();
     method public java.lang.String getContentType();
     method public long getDate();
     method public static boolean getDefaultAllowUserInteraction();
@@ -37212,6 +38964,7 @@
     method public long getHeaderFieldDate(java.lang.String, long);
     method public int getHeaderFieldInt(java.lang.String, int);
     method public java.lang.String getHeaderFieldKey(int);
+    method public long getHeaderFieldLong(java.lang.String, long);
     method public java.util.Map<java.lang.String, java.util.List<java.lang.String>> getHeaderFields();
     method public long getIfModifiedSince();
     method public java.io.InputStream getInputStream() throws java.io.IOException;
@@ -37562,6 +39315,10 @@
 
 package java.nio.channels {
 
+  public class AlreadyBoundException extends java.lang.IllegalStateException {
+    ctor public AlreadyBoundException();
+  }
+
   public class AlreadyConnectedException extends java.lang.IllegalStateException {
     ctor public AlreadyConnectedException();
   }
@@ -37611,8 +39368,11 @@
 
   public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
     ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
+    method public java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
     method public abstract java.nio.channels.DatagramChannel disconnect() throws java.io.IOException;
+    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
     method public abstract boolean isConnected();
     method public static java.nio.channels.DatagramChannel open() throws java.io.IOException;
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
@@ -37620,14 +39380,16 @@
     method public final synchronized long read(java.nio.ByteBuffer[]) throws java.io.IOException;
     method public abstract java.net.SocketAddress receive(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract int send(java.nio.ByteBuffer, java.net.SocketAddress) throws java.io.IOException;
+    method public java.nio.channels.DatagramChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
     method public abstract java.net.DatagramSocket socket();
+    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
     method public final int validOps();
     method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
     method public final synchronized long write(java.nio.ByteBuffer[]) throws java.io.IOException;
   }
 
-  public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel java.nio.channels.SeekableByteChannel {
     ctor protected FileChannel();
     method public abstract void force(boolean) throws java.io.IOException;
     method public final java.nio.channels.FileLock lock() throws java.io.IOException;
@@ -37691,6 +39453,14 @@
     method public abstract void close() throws java.io.IOException;
   }
 
+  public abstract interface NetworkChannel implements java.lang.AutoCloseable java.nio.channels.Channel java.io.Closeable {
+    method public abstract java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public abstract T getOption(java.net.SocketOption<T>) throws java.io.IOException;
+    method public abstract java.nio.channels.NetworkChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+    method public abstract java.util.Set<java.net.SocketOption<?>> supportedOptions();
+  }
+
   public class NoConnectionPendingException extends java.lang.IllegalStateException {
     ctor public NoConnectionPendingException();
   }
@@ -37741,6 +39511,15 @@
     method public abstract long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
   }
 
+  public abstract interface SeekableByteChannel implements java.nio.channels.ByteChannel {
+    method public abstract long position() throws java.io.IOException;
+    method public abstract java.nio.channels.SeekableByteChannel position(long) throws java.io.IOException;
+    method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
+    method public abstract long size() throws java.io.IOException;
+    method public abstract java.nio.channels.SeekableByteChannel truncate(long) throws java.io.IOException;
+    method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
+  }
+
   public abstract class SelectableChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.Channel {
     ctor protected SelectableChannel();
     method public abstract java.lang.Object blockingLock();
@@ -37789,18 +39568,27 @@
     method public abstract java.nio.channels.Selector wakeup();
   }
 
-  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel {
+  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.NetworkChannel {
     ctor protected ServerSocketChannel(java.nio.channels.spi.SelectorProvider);
     method public abstract java.nio.channels.SocketChannel accept() throws java.io.IOException;
+    method public final java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
+    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
     method public static java.nio.channels.ServerSocketChannel open() throws java.io.IOException;
+    method public java.nio.channels.ServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
     method public abstract java.net.ServerSocket socket();
+    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
     method public final int validOps();
   }
 
-  public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel {
+  public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
     ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
+    method public java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
     method public abstract boolean connect(java.net.SocketAddress) throws java.io.IOException;
     method public abstract boolean finishConnect() throws java.io.IOException;
+    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public T getOption(java.net.SocketOption<T>) throws java.io.IOException;
     method public abstract boolean isConnected();
     method public abstract boolean isConnectionPending();
     method public static java.nio.channels.SocketChannel open() throws java.io.IOException;
@@ -37808,7 +39596,9 @@
     method public abstract int read(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
     method public final synchronized long read(java.nio.ByteBuffer[]) throws java.io.IOException;
+    method public java.nio.channels.SocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
     method public abstract java.net.Socket socket();
+    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
     method public final int validOps();
     method public abstract int write(java.nio.ByteBuffer) throws java.io.IOException;
     method public abstract long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
@@ -42052,6 +43842,13 @@
     method public int getWidth();
   }
 
+  public class IllformedLocaleException extends java.lang.RuntimeException {
+    ctor public IllformedLocaleException();
+    ctor public IllformedLocaleException(java.lang.String);
+    ctor public IllformedLocaleException(java.lang.String, int);
+    method public int getErrorIndex();
+  }
+
   public class InputMismatchException extends java.util.NoSuchElementException implements java.io.Serializable {
     ctor public InputMismatchException();
     ctor public InputMismatchException(java.lang.String);
@@ -42166,6 +43963,7 @@
     ctor public Locale(java.lang.String, java.lang.String);
     ctor public Locale(java.lang.String, java.lang.String, java.lang.String);
     method public java.lang.Object clone();
+    method public static java.util.Locale forLanguageTag(java.lang.String);
     method public static java.util.Locale[] getAvailableLocales();
     method public java.lang.String getCountry();
     method public static java.util.Locale getDefault();
@@ -42175,15 +43973,24 @@
     method public java.lang.String getDisplayLanguage(java.util.Locale);
     method public final java.lang.String getDisplayName();
     method public java.lang.String getDisplayName(java.util.Locale);
+    method public java.lang.String getDisplayScript();
+    method public java.lang.String getDisplayScript(java.util.Locale);
     method public final java.lang.String getDisplayVariant();
     method public java.lang.String getDisplayVariant(java.util.Locale);
+    method public java.lang.String getExtension(char);
+    method public java.util.Set<java.lang.Character> getExtensionKeys();
     method public java.lang.String getISO3Country();
     method public java.lang.String getISO3Language();
     method public static java.lang.String[] getISOCountries();
     method public static java.lang.String[] getISOLanguages();
     method public java.lang.String getLanguage();
+    method public java.lang.String getScript();
+    method public java.util.Set<java.lang.String> getUnicodeLocaleAttributes();
+    method public java.util.Set<java.lang.String> getUnicodeLocaleKeys();
+    method public java.lang.String getUnicodeLocaleType(java.lang.String);
     method public java.lang.String getVariant();
     method public static synchronized void setDefault(java.util.Locale);
+    method public java.lang.String toLanguageTag();
     method public final java.lang.String toString();
     field public static final java.util.Locale CANADA;
     field public static final java.util.Locale CANADA_FRENCH;
@@ -42201,14 +44008,33 @@
     field public static final java.util.Locale KOREA;
     field public static final java.util.Locale KOREAN;
     field public static final java.util.Locale PRC;
+    field public static final char PRIVATE_USE_EXTENSION = 120; // 0x0078 'x'
     field public static final java.util.Locale ROOT;
     field public static final java.util.Locale SIMPLIFIED_CHINESE;
     field public static final java.util.Locale TAIWAN;
     field public static final java.util.Locale TRADITIONAL_CHINESE;
     field public static final java.util.Locale UK;
+    field public static final char UNICODE_LOCALE_EXTENSION = 117; // 0x0075 'u'
     field public static final java.util.Locale US;
   }
 
+  public static final class Locale.Builder {
+    ctor public Locale.Builder();
+    method public java.util.Locale.Builder addUnicodeLocaleAttribute(java.lang.String);
+    method public java.util.Locale build();
+    method public java.util.Locale.Builder clear();
+    method public java.util.Locale.Builder clearExtensions();
+    method public java.util.Locale.Builder removeUnicodeLocaleAttribute(java.lang.String);
+    method public java.util.Locale.Builder setExtension(char, java.lang.String);
+    method public java.util.Locale.Builder setLanguage(java.lang.String);
+    method public java.util.Locale.Builder setLanguageTag(java.lang.String);
+    method public java.util.Locale.Builder setLocale(java.util.Locale);
+    method public java.util.Locale.Builder setRegion(java.lang.String);
+    method public java.util.Locale.Builder setScript(java.lang.String);
+    method public java.util.Locale.Builder setUnicodeLocaleKeyword(java.lang.String, java.lang.String);
+    method public java.util.Locale.Builder setVariant(java.lang.String);
+  }
+
   public abstract interface Map {
     method public abstract void clear();
     method public abstract boolean containsKey(java.lang.Object);
@@ -42895,6 +44721,35 @@
     method public V replace(K, V);
   }
 
+  public class ConcurrentLinkedDeque extends java.util.AbstractCollection implements java.util.Deque java.io.Serializable {
+    ctor public ConcurrentLinkedDeque();
+    ctor public ConcurrentLinkedDeque(java.util.Collection<? extends E>);
+    method public void addFirst(E);
+    method public void addLast(E);
+    method public java.util.Iterator<E> descendingIterator();
+    method public E element();
+    method public E getFirst();
+    method public E getLast();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offerFirst(E);
+    method public boolean offerLast(E);
+    method public E peek();
+    method public E peekFirst();
+    method public E peekLast();
+    method public E poll();
+    method public E pollFirst();
+    method public E pollLast();
+    method public E pop();
+    method public void push(E);
+    method public E remove();
+    method public E removeFirst();
+    method public boolean removeFirstOccurrence(java.lang.Object);
+    method public E removeLast();
+    method public boolean removeLastOccurrence(java.lang.Object);
+    method public int size();
+  }
+
   public class ConcurrentLinkedQueue extends java.util.AbstractQueue implements java.util.Queue java.io.Serializable {
     ctor public ConcurrentLinkedQueue();
     ctor public ConcurrentLinkedQueue(java.util.Collection<? extends E>);
@@ -43135,6 +44990,94 @@
     method public static java.util.concurrent.ScheduledExecutorService unconfigurableScheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
   }
 
+  public class ForkJoinPool extends java.util.concurrent.AbstractExecutorService {
+    ctor public ForkJoinPool();
+    ctor public ForkJoinPool(int);
+    ctor public ForkJoinPool(int, java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory, java.lang.Thread.UncaughtExceptionHandler, boolean);
+    method public boolean awaitQuiescence(long, java.util.concurrent.TimeUnit);
+    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method protected int drainTasksTo(java.util.Collection<? super java.util.concurrent.ForkJoinTask<?>>);
+    method public void execute(java.util.concurrent.ForkJoinTask<?>);
+    method public void execute(java.lang.Runnable);
+    method public int getActiveThreadCount();
+    method public boolean getAsyncMode();
+    method public java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory getFactory();
+    method public int getParallelism();
+    method public int getPoolSize();
+    method public int getQueuedSubmissionCount();
+    method public long getQueuedTaskCount();
+    method public int getRunningThreadCount();
+    method public long getStealCount();
+    method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
+    method public boolean hasQueuedSubmissions();
+    method public T invoke(java.util.concurrent.ForkJoinTask<T>);
+    method public boolean isQuiescent();
+    method public boolean isShutdown();
+    method public boolean isTerminated();
+    method public boolean isTerminating();
+    method public static void managedBlock(java.util.concurrent.ForkJoinPool.ManagedBlocker) throws java.lang.InterruptedException;
+    method protected java.util.concurrent.ForkJoinTask<?> pollSubmission();
+    method public void shutdown();
+    method public java.util.List<java.lang.Runnable> shutdownNow();
+    method public java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
+    field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
+  }
+
+  public static abstract interface ForkJoinPool.ForkJoinWorkerThreadFactory {
+    method public abstract java.util.concurrent.ForkJoinWorkerThread newThread(java.util.concurrent.ForkJoinPool);
+  }
+
+  public static abstract interface ForkJoinPool.ManagedBlocker {
+    method public abstract boolean block() throws java.lang.InterruptedException;
+    method public abstract boolean isReleasable();
+  }
+
+  public abstract class ForkJoinTask implements java.util.concurrent.Future java.io.Serializable {
+    ctor public ForkJoinTask();
+    method public static java.util.concurrent.ForkJoinTask<?> adapt(java.lang.Runnable);
+    method public static java.util.concurrent.ForkJoinTask<T> adapt(java.lang.Runnable, T);
+    method public static java.util.concurrent.ForkJoinTask<T> adapt(java.util.concurrent.Callable<? extends T>);
+    method public boolean cancel(boolean);
+    method public void complete(V);
+    method public void completeExceptionally(java.lang.Throwable);
+    method protected abstract boolean exec();
+    method public final java.util.concurrent.ForkJoinTask<V> fork();
+    method public final V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public final V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public final java.lang.Throwable getException();
+    method public static java.util.concurrent.ForkJoinPool getPool();
+    method public static int getQueuedTaskCount();
+    method public abstract V getRawResult();
+    method public static int getSurplusQueuedTaskCount();
+    method public static void helpQuiesce();
+    method public static boolean inForkJoinPool();
+    method public final V invoke();
+    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>, java.util.concurrent.ForkJoinTask<?>);
+    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>...);
+    method public static java.util.Collection<T> invokeAll(java.util.Collection<T>);
+    method public final boolean isCancelled();
+    method public final boolean isCompletedAbnormally();
+    method public final boolean isCompletedNormally();
+    method public final boolean isDone();
+    method public final V join();
+    method protected static java.util.concurrent.ForkJoinTask<?> peekNextLocalTask();
+    method protected static java.util.concurrent.ForkJoinTask<?> pollNextLocalTask();
+    method protected static java.util.concurrent.ForkJoinTask<?> pollTask();
+    method public final void quietlyInvoke();
+    method public final void quietlyJoin();
+    method public void reinitialize();
+    method protected abstract void setRawResult(V);
+    method public boolean tryUnfork();
+  }
+
+  public class ForkJoinWorkerThread extends java.lang.Thread {
+    ctor protected ForkJoinWorkerThread(java.util.concurrent.ForkJoinPool);
+    method public java.util.concurrent.ForkJoinPool getPool();
+    method public int getPoolIndex();
+    method protected void onStart();
+    method protected void onTermination(java.lang.Throwable);
+  }
+
   public abstract interface Future {
     method public abstract boolean cancel(boolean);
     method public abstract V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
@@ -43219,6 +45162,52 @@
     method public E take() throws java.lang.InterruptedException;
   }
 
+  public class LinkedTransferQueue extends java.util.AbstractQueue implements java.io.Serializable java.util.concurrent.TransferQueue {
+    ctor public LinkedTransferQueue();
+    ctor public LinkedTransferQueue(java.util.Collection<? extends E>);
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public int getWaitingConsumerCount();
+    method public boolean hasWaitingConsumer();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
+    method public boolean offer(E);
+    method public E peek();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E poll();
+    method public void put(E);
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+    method public void transfer(E) throws java.lang.InterruptedException;
+    method public boolean tryTransfer(E);
+    method public boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
+  public class Phaser {
+    ctor public Phaser();
+    ctor public Phaser(int);
+    ctor public Phaser(java.util.concurrent.Phaser);
+    ctor public Phaser(java.util.concurrent.Phaser, int);
+    method public int arrive();
+    method public int arriveAndAwaitAdvance();
+    method public int arriveAndDeregister();
+    method public int awaitAdvance(int);
+    method public int awaitAdvanceInterruptibly(int) throws java.lang.InterruptedException;
+    method public int awaitAdvanceInterruptibly(int, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public int bulkRegister(int);
+    method public void forceTermination();
+    method public int getArrivedParties();
+    method public java.util.concurrent.Phaser getParent();
+    method public final int getPhase();
+    method public int getRegisteredParties();
+    method public java.util.concurrent.Phaser getRoot();
+    method public int getUnarrivedParties();
+    method public boolean isTerminated();
+    method protected boolean onAdvance(int, int);
+    method public int register();
+  }
+
   public class PriorityBlockingQueue extends java.util.AbstractQueue implements java.util.concurrent.BlockingQueue java.io.Serializable {
     ctor public PriorityBlockingQueue();
     ctor public PriorityBlockingQueue(int);
@@ -43239,6 +45228,22 @@
     method public E take() throws java.lang.InterruptedException;
   }
 
+  public abstract class RecursiveAction extends java.util.concurrent.ForkJoinTask {
+    ctor public RecursiveAction();
+    method protected abstract void compute();
+    method protected final boolean exec();
+    method public final java.lang.Void getRawResult();
+    method protected final void setRawResult(java.lang.Void);
+  }
+
+  public abstract class RecursiveTask extends java.util.concurrent.ForkJoinTask {
+    ctor public RecursiveTask();
+    method protected abstract V compute();
+    method protected final boolean exec();
+    method public final V getRawResult();
+    method protected final void setRawResult(V);
+  }
+
   public class RejectedExecutionException extends java.lang.RuntimeException {
     ctor public RejectedExecutionException();
     ctor public RejectedExecutionException(java.lang.String);
@@ -43277,12 +45282,14 @@
     method protected java.util.concurrent.RunnableScheduledFuture<V> decorateTask(java.util.concurrent.Callable<V>, java.util.concurrent.RunnableScheduledFuture<V>);
     method public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy();
     method public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy();
+    method public boolean getRemoveOnCancelPolicy();
     method public java.util.concurrent.ScheduledFuture<?> schedule(java.lang.Runnable, long, java.util.concurrent.TimeUnit);
     method public java.util.concurrent.ScheduledFuture<V> schedule(java.util.concurrent.Callable<V>, long, java.util.concurrent.TimeUnit);
     method public java.util.concurrent.ScheduledFuture<?> scheduleAtFixedRate(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit);
     method public java.util.concurrent.ScheduledFuture<?> scheduleWithFixedDelay(java.lang.Runnable, long, long, java.util.concurrent.TimeUnit);
     method public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean);
     method public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean);
+    method public void setRemoveOnCancelPolicy(boolean);
   }
 
   public class Semaphore implements java.io.Serializable {
@@ -43328,6 +45335,15 @@
     method public abstract java.lang.Thread newThread(java.lang.Runnable);
   }
 
+  public class ThreadLocalRandom extends java.util.Random {
+    method public static java.util.concurrent.ThreadLocalRandom current();
+    method public double nextDouble(double);
+    method public double nextDouble(double, double);
+    method public int nextInt(int, int);
+    method public long nextLong(long);
+    method public long nextLong(long, long);
+  }
+
   public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
     ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>);
     ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory);
@@ -43415,6 +45431,14 @@
     ctor public TimeoutException(java.lang.String);
   }
 
+  public abstract interface TransferQueue implements java.util.concurrent.BlockingQueue {
+    method public abstract int getWaitingConsumerCount();
+    method public abstract boolean hasWaitingConsumer();
+    method public abstract void transfer(E) throws java.lang.InterruptedException;
+    method public abstract boolean tryTransfer(E);
+    method public abstract boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
 }
 
 package java.util.concurrent.atomic {
@@ -43624,6 +45648,7 @@
     method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method public final boolean hasContended();
+    method public final boolean hasQueuedPredecessors();
     method public final boolean hasQueuedThreads();
     method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
     method protected boolean isHeldExclusively();
@@ -43670,6 +45695,7 @@
     method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
     method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
     method public final boolean hasContended();
+    method public final boolean hasQueuedPredecessors();
     method public final boolean hasQueuedThreads();
     method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
     method protected boolean isHeldExclusively();
diff --git a/api/removed.txt b/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/api/removed.txt
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 89e15d2..92cb52c 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -114,6 +114,8 @@
                 "       am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
                 "       am stack list\n" +
                 "       am stack info <STACK_ID>\n" +
+                "       am lock-task <TASK_ID>\n" +
+                "       am lock-task stop\n" +
                 "\n" +
                 "am start: start an Activity.  Options are:\n" +
                 "    -D: enable debugging\n" +
@@ -218,6 +220,8 @@
                 "\n" +
                 "am stack info: display the information about activity stack <STACK_ID>.\n" +
                 "\n" +
+                "am lock-task: bring <TASK_ID> to the front and don't allow other tasks to run\n" +
+                "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
                 "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
                 "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -232,6 +236,8 @@
                 "    [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" +
                 "    [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" +
                 "    [--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]]\n" +
+                "    [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]\n" +
+                "        (to embed a comma into a string escape it using \"\\,\")\n" +
                 "    [-n <COMPONENT>] [-f <FLAGS>]\n" +
                 "    [--grant-read-uri-permission] [--grant-write-uri-permission]\n" +
                 "    [--debug-log-resolution] [--exclude-stopped-packages]\n" +
@@ -307,6 +313,8 @@
             runStopUser();
         } else if (op.equals("stack")) {
             runStack();
+        } else if (op.equals("lock-task")) {
+            runLockTask();
         } else {
             showError("Error: unknown command '" + op + "'");
         }
@@ -419,6 +427,15 @@
                 }
                 intent.putExtra(key, list);
                 hasIntentInfo = true;
+            } else if (opt.equals("--esa")) {
+                String key = nextArgRequired();
+                String value = nextArgRequired();
+                // Split on commas unless they are preceeded by an escape.
+                // The escape character must be escaped for the string and
+                // again for the regex, thus four escape characters become one.
+                String[] strings = value.split("(?<!\\\\),");
+                intent.putExtra(key, strings);
+                hasIntentInfo = true;
             } else if (opt.equals("--ez")) {
                 String key = nextArgRequired();
                 String value = nextArgRequired();
@@ -1630,4 +1647,19 @@
         } catch (RemoteException e) {
         }
     }
+
+    private void runLockTask() throws Exception {
+        String taskIdStr = nextArgRequired();
+        try {
+            if (taskIdStr.equals("stop")) {
+                mAm.stopLockTaskMode();
+            } else {
+                int taskId = Integer.valueOf(taskIdStr);
+                mAm.startLockTaskMode(taskId);
+            }
+            System.err.println("Activity manager is " + (mAm.isInLockTaskMode() ? "" : "not ") +
+                    "in lockTaskMode");
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index dd987e0..c4fe6cf 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -19,9 +19,6 @@
     libGLESv1_CM \
     libgui
 
-LOCAL_C_INCLUDES := \
-	$(call include-path-for, corecg graphics)
-
 LOCAL_MODULE:= bootanimation
 
 ifdef TARGET_32_BIT_SURFACEFLINGER
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 1a2ab81..41afa39 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -36,15 +36,14 @@
 #include <ui/Rect.h>
 #include <ui/Region.h>
 #include <ui/DisplayInfo.h>
-#include <ui/FramebufferNativeWindow.h>
 
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
 
-#include <core/SkBitmap.h>
-#include <core/SkStream.h>
-#include <core/SkImageDecoder.h>
+#include <SkBitmap.h>
+#include <SkStream.h>
+#include <SkImageDecoder.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -127,7 +126,7 @@
     glGenTextures(1, &texture->name);
     glBindTexture(GL_TEXTURE_2D, texture->name);
 
-    switch (bitmap.getConfig()) {
+    switch (bitmap.config()) {
         case SkBitmap::kA8_Config:
             glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_ALPHA,
                     GL_UNSIGNED_BYTE, p);
@@ -185,7 +184,7 @@
     if (tw < w) tw <<= 1;
     if (th < h) th <<= 1;
 
-    switch (bitmap.getConfig()) {
+    switch (bitmap.config()) {
         case SkBitmap::kARGB_8888_Config:
             if (tw != w || th != h) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
diff --git a/cmds/bu/src/com/android/commands/bu/Backup.java b/cmds/bu/src/com/android/commands/bu/Backup.java
index 73fd660..2673031 100644
--- a/cmds/bu/src/com/android/commands/bu/Backup.java
+++ b/cmds/bu/src/com/android/commands/bu/Backup.java
@@ -68,6 +68,7 @@
         boolean saveObbs = false;
         boolean saveShared = false;
         boolean doEverything = false;
+        boolean doWidgets = false;
         boolean allIncludesSystem = true;
 
         String arg;
@@ -89,6 +90,10 @@
                     allIncludesSystem = true;
                 } else if ("-nosystem".equals(arg)) {
                     allIncludesSystem = false;
+                } else if ("-widgets".equals(arg)) {
+                    doWidgets = true;
+                } else if ("-nowidgets".equals(arg)) {
+                    doWidgets = false;
                 } else if ("-all".equals(arg)) {
                     doEverything = true;
                 } else {
@@ -114,8 +119,8 @@
         try {
             fd = ParcelFileDescriptor.adoptFd(socketFd);
             String[] packArray = new String[packages.size()];
-            mBackupManager.fullBackup(fd, saveApks, saveObbs, saveShared, doEverything,
-                    allIncludesSystem, packages.toArray(packArray));
+            mBackupManager.fullBackup(fd, saveApks, saveObbs, saveShared, doWidgets,
+                    doEverything, allIncludesSystem, packages.toArray(packArray));
         } catch (RemoteException e) {
             Log.e(TAG, "Unable to invoke backup manager for backup");
         } finally {
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index e66bdf4..466dcd4 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -498,7 +498,7 @@
                                     columnValue = String.valueOf(cursor.getFloat(columnIndex));
                                     break;
                                 case Cursor.FIELD_TYPE_INTEGER:
-                                    columnValue = String.valueOf(cursor.getInt(columnIndex));
+                                    columnValue = String.valueOf(cursor.getLong(columnIndex));
                                     break;
                                 case Cursor.FIELD_TYPE_STRING:
                                     columnValue = cursor.getString(columnIndex);
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index d1ded10..d513a10 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -18,6 +18,7 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ContainerEncryptionParams;
@@ -39,6 +40,7 @@
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.IUserManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -1011,6 +1013,27 @@
 
     public void runCreateUser() {
         String name;
+        int relatedUserId = -1;
+        int flags = 0;
+        String opt;
+        while ((opt = nextOption()) != null) {
+            if ("--relatedTo".equals(opt)) {
+                String optionData = nextOptionData();
+                if (optionData == null || !isNumber(optionData)) {
+                    System.err.println("Error: no USER_ID specified");
+                    showUsage();
+                    return;
+                } else {
+                    relatedUserId = Integer.parseInt(optionData);
+                }
+            } else if ("--managed".equals(opt)) {
+                flags |= UserInfo.FLAG_MANAGED_PROFILE;
+            } else {
+                System.err.println("Error: unknown option " + opt);
+                showUsage();
+                return;
+            }
+        }
         String arg = nextArg();
         if (arg == null) {
             System.err.println("Error: no user name specified.");
@@ -1018,7 +1041,16 @@
         }
         name = arg;
         try {
-            final UserInfo info = mUm.createUser(name, 0);
+            UserInfo info = null;
+            if (relatedUserId < 0) {
+                info = mUm.createUser(name, flags);
+            } else {
+                if (Process.myUid() != 0) {
+                    System.err.println("Error: not running as root.");
+                    return;
+                }
+                info = mUm.createRelatedUser(name, flags, relatedUserId);
+            }
             if (info != null) {
                 System.out.println("Success: created user id " + info.id);
             } else {
@@ -1058,13 +1090,16 @@
 
     public void runListUsers() {
         try {
+            IActivityManager am = ActivityManagerNative.getDefault();
+
             List<UserInfo> users = mUm.getUsers(false);
             if (users == null) {
                 System.err.println("Error: couldn't get users");
             } else {
                 System.out.println("Users:");
                 for (int i = 0; i < users.size(); i++) {
-                    System.out.println("\t" + users.get(i).toString());
+                    String running = am.isUserRunning(users.get(i).id, false) ? " running" : "";
+                    System.out.println("\t" + users.get(i).toString() + running);
                 }
             }
         } catch (RemoteException e) {
@@ -1530,7 +1565,7 @@
         System.err.println("       pm get-install-location");
         System.err.println("       pm set-permission-enforced PERMISSION [true|false]");
         System.err.println("       pm trim-caches DESIRED_FREE_SPACE");
-        System.err.println("       pm create-user USER_NAME");
+        System.err.println("       pm create-user [--relatedTo USER_ID] [--managed] USER_NAME");
         System.err.println("       pm remove-user USER_ID");
         System.err.println("       pm get-max-users");
         System.err.println("");
diff --git a/cmds/screencap/Android.mk b/cmds/screencap/Android.mk
index ca8008b..5c11b75 100644
--- a/cmds/screencap/Android.mk
+++ b/cmds/screencap/Android.mk
@@ -16,11 +16,4 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_C_INCLUDES += \
-	external/skia/include/core \
-	external/skia/include/effects \
-	external/skia/include/images \
-	external/skia/src/ports \
-	external/skia/include/utils
-
 include $(BUILD_EXECUTABLE)
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index a57de01..2efe4d3 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -141,7 +141,7 @@
 
     ScreenshotClient screenshot;
     sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
-    if (display != NULL && screenshot.update(display) == NO_ERROR) {
+    if (display != NULL && screenshot.update(display, false) == NO_ERROR) {
         base = screenshot.getPixels();
         w = screenshot.getWidth();
         h = screenshot.getHeight();
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 1e3d5be..b01d92c 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -23,14 +23,18 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 import com.android.internal.os.HandlerCaller;
 
+import java.util.List;
+
 /**
  * An accessibility service runs in the background and receives callbacks by the system
  * when {@link AccessibilityEvent}s are fired. Such events denote some state transition
@@ -180,28 +184,37 @@
  * event generation has settled down.</p>
  * <h3>Event types</h3>
  * <ul>
- * <li>{@link AccessibilityEvent#TYPE_VIEW_CLICKED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_FOCUSED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_SELECTED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}
- * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_SCROLLED}
- * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}
- * <li>{@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_CLICKED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_FOCUSED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_SELECTED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_SCROLLED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_ANNOUNCEMENT}</li>
+ * <li>{@link AccessibilityEvent#TYPE_GESTURE_DETECTION_START}</li>
+ * <li>{@link AccessibilityEvent#TYPE_GESTURE_DETECTION_END}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_INTERACTION_START}</li>
+ * <li>{@link AccessibilityEvent#TYPE_TOUCH_INTERACTION_END}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_WINDOWS_CHANGED}</li>
+ * <li>{@link AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED}</li>
  * </ul>
  * <h3>Feedback types</h3>
  * <ul>
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_VISUAL}
- * <li>{@link AccessibilityServiceInfo#FEEDBACK_GENERIC}
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_HAPTIC}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_AUDIBLE}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_VISUAL}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_GENERIC}</li>
+ * <li>{@link AccessibilityServiceInfo#FEEDBACK_BRAILLE}</li>
  * </ul>
  * @see AccessibilityEvent
  * @see AccessibilityServiceInfo
@@ -443,8 +456,41 @@
     }
 
     /**
+     * Gets the windows on the screen. This method returns only the windows
+     * that a sighted user can interact with, as opposed to all windows.
+     * For example, if there is a modal dialog shown and the user cannot touch
+     * anything behind it, then only the modal window will be reported
+     * (assuming it is the top one). For convenience the returned windows
+     * are ordered in a descending layer order, which is the windows that
+     * are higher in the Z-order are reported first.
+     * <p>
+     * <strong>Note:</strong> In order to access the windows your service has
+     * to declare the capability to retrieve window content by setting the
+     * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
+     * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
+     * Also the service has to opt-in to retrieve the interactive windows by
+     * setting the {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS}
+     * flag.
+     * </p>
+     *
+     * @return The windows if there are windows and the service is can retrieve
+     *         them, otherwise an empty list.
+     */
+    public List<AccessibilityWindowInfo> getWindows() {
+        return AccessibilityInteractionClient.getInstance().getWindows(mConnectionId);
+    }
+
+    /**
      * Gets the root node in the currently active window if this service
-     * can retrieve window content.
+     * can retrieve window content. The active window is the one that the user
+     * is currently touching or the window with input focus, if the user is not
+     * touching any window.
+     * <p>
+     * <strong>Note:</strong> In order to access the root node your service has
+     * to declare the capability to retrieve window content by setting the
+     * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
+     * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
+     * </p>
      *
      * @return The root node if this service can retrieve window content.
      */
@@ -584,12 +630,13 @@
 
         static final int NO_ID = -1;
 
-        private static final int DO_SET_SET_CONNECTION = 10;
-        private static final int DO_ON_INTERRUPT = 20;
-        private static final int DO_ON_ACCESSIBILITY_EVENT = 30;
-        private static final int DO_ON_GESTURE = 40;
-        private static final int DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE = 50;
-        private static final int DO_ON_KEY_EVENT = 60;
+        private static final int DO_SET_SET_CONNECTION = 1;
+        private static final int DO_ON_INTERRUPT = 2;
+        private static final int DO_ON_ACCESSIBILITY_EVENT = 3;
+        private static final int DO_ON_GESTURE = 4;
+        private static final int DO_CLEAR_ACCESSIBILITY_CACHE = 5;
+        private static final int DO_ON_KEY_EVENT = 6;
+        private static final int DO_ON_WINDOWS_CHANGED = 7;
 
         private final HandlerCaller mCaller;
 
@@ -624,8 +671,8 @@
             mCaller.sendMessage(message);
         }
 
-        public void clearAccessibilityNodeInfoCache() {
-            Message message = mCaller.obtainMessage(DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE);
+        public void clearAccessibilityCache() {
+            Message message = mCaller.obtainMessage(DO_CLEAR_ACCESSIBILITY_CACHE);
             mCaller.sendMessage(message);
         }
 
@@ -635,6 +682,13 @@
             mCaller.sendMessage(message);
         }
 
+        @Override
+        public void onWindowsChanged(int[] windowIds) {
+            Message message = mCaller.obtainMessageO(DO_ON_WINDOWS_CHANGED, windowIds);
+            mCaller.sendMessage(message);
+        }
+
+        @Override
         public void executeMessage(Message message) {
             switch (message.what) {
                 case DO_ON_ACCESSIBILITY_EVENT: {
@@ -642,12 +696,19 @@
                     if (event != null) {
                         AccessibilityInteractionClient.getInstance().onAccessibilityEvent(event);
                         mCallback.onAccessibilityEvent(event);
-                        event.recycle();
+                        // Make sure the event is recycled.
+                        try {
+                            event.recycle();
+                        } catch (IllegalStateException ise) {
+                            /* ignore - best effort */
+                        }
                     }
                 } return;
+
                 case DO_ON_INTERRUPT: {
                     mCallback.onInterrupt();
                 } return;
+
                 case DO_SET_SET_CONNECTION: {
                     mConnectionId = message.arg1;
                     IAccessibilityServiceConnection connection =
@@ -658,18 +719,22 @@
                         mCallback.onSetConnectionId(mConnectionId);
                         mCallback.onServiceConnected();
                     } else {
-                        AccessibilityInteractionClient.getInstance().removeConnection(mConnectionId);
+                        AccessibilityInteractionClient.getInstance().removeConnection(
+                                mConnectionId);
                         AccessibilityInteractionClient.getInstance().clearCache();
                         mCallback.onSetConnectionId(AccessibilityInteractionClient.NO_ID);
                     }
                 } return;
+
                 case DO_ON_GESTURE: {
                     final int gestureId = message.arg1;
                     mCallback.onGesture(gestureId);
                 } return;
-                case DO_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE: {
+
+                case DO_CLEAR_ACCESSIBILITY_CACHE: {
                     AccessibilityInteractionClient.getInstance().clearCache();
                 } return;
+
                 case DO_ON_KEY_EVENT: {
                     KeyEvent event = (KeyEvent) message.obj;
                     try {
@@ -685,9 +750,40 @@
                             }
                         }
                     } finally {
-                        event.recycle();
+                        // Make sure the event is recycled.
+                        try {
+                            event.recycle();
+                        } catch (IllegalStateException ise) {
+                            /* ignore - best effort */
+                        }
                     }
                 } return;
+
+                case DO_ON_WINDOWS_CHANGED: {
+                    final int[] windowIds = (int[]) message.obj;
+
+                    // Update the cached windows first.
+                    // NOTE: The cache will hold on to the windows so do not recycle.
+                    if (windowIds != null) {
+                        AccessibilityInteractionClient.getInstance().removeWindows(windowIds);
+                    }
+
+                    // Let the client know the windows changed.
+                    AccessibilityEvent event = AccessibilityEvent.obtain(
+                            AccessibilityEvent.TYPE_WINDOWS_CHANGED);
+                    event.setEventTime(SystemClock.uptimeMillis());
+                    event.setSealed(true);
+
+                    mCallback.onAccessibilityEvent(event);
+
+                    // Make sure the event is recycled.
+                    try {
+                        event.recycle();
+                    } catch (IllegalStateException ise) {
+                        /* ignore - best effort */
+                    }
+                } break;
+
                 default :
                     Log.w(LOG_TAG, "Unknown message type " + message.what);
             }
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index bdc4fdde..4f9ba59 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -284,6 +284,27 @@
     public static final int FLAG_REQUEST_FILTER_KEY_EVENTS = 0x00000020;
 
     /**
+     * This flag indicates to the system that the accessibility service wants
+     * to access content of all interactive windows. An interactive window is a
+     * window that can be touched by a sighted user when explore by touch is not
+     * enabled. If this flag is not set your service will not receive
+     * {@link android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED}
+     * events, calling AccessibilityService{@link AccessibilityService#getWindows()
+     * AccessibilityService.getWindows()} will return an empty list, and {@link
+     * AccessibilityNodeInfo#getWindow() AccessibilityNodeInfo.getWindow()} will
+     * return null.
+     * <p>
+     * Services that want to set this flag have to declare the capability
+     * to retrieve window content in their meta-data by setting the attribute
+     * {@link android.R.attr#canRetrieveWindowContent canRetrieveWindowContent} to
+     * true, otherwise this flag will be ignored. For how to declare the meta-data
+     * of a service refer to {@value AccessibilityService#SERVICE_META_DATA}.
+     * </p>
+     * @see android.R.styleable#AccessibilityService_canRetrieveWindowContent
+     */
+    public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000040;
+
+    /**
      * The event types an {@link AccessibilityService} is interested in.
      * <p>
      *   <strong>Can be dynamically set at runtime.</strong>
@@ -302,6 +323,15 @@
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SCROLLED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_START
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_TOUCH_INTERACTION_END
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_ANNOUNCEMENT
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_START
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_GESTURE_DETECTION_END
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOWS_CHANGED
      */
     public int eventTypes;
 
@@ -354,6 +384,7 @@
      * @see #FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY
      * @see #FLAG_REQUEST_FILTER_KEY_EVENTS
      * @see #FLAG_REPORT_VIEW_IDS
+     * @see #FLAG_RETRIEVE_INTERACTIVE_WINDOWS
      */
     public int flags;
 
@@ -449,7 +480,7 @@
                     com.android.internal.R.styleable.AccessibilityService_accessibilityFeedbackType,
                     0);
             notificationTimeout = asAttributes.getInt(
-                    com.android.internal.R.styleable.AccessibilityService_notificationTimeout, 
+                    com.android.internal.R.styleable.AccessibilityService_notificationTimeout,
                     0);
             flags = asAttributes.getInt(
                     com.android.internal.R.styleable.AccessibilityService_accessibilityFlags, 0);
@@ -861,6 +892,8 @@
                 return "FLAG_REPORT_VIEW_IDS";
             case FLAG_REQUEST_FILTER_KEY_EVENTS:
                 return "FLAG_REQUEST_FILTER_KEY_EVENTS";
+            case FLAG_RETRIEVE_INTERACTIVE_WINDOWS:
+                return "FLAG_RETRIEVE_INTERACTIVE_WINDOWS";
             default:
                 return null;
         }
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
index c5e3d43a..edd8727 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl
@@ -18,6 +18,7 @@
 
 import android.accessibilityservice.IAccessibilityServiceConnection;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.KeyEvent;
 
 /**
@@ -35,7 +36,9 @@
 
     void onGesture(int gesture);
 
-    void clearAccessibilityNodeInfoCache();
+    void clearAccessibilityCache();
 
     void onKeyEvent(in KeyEvent event, int sequence);
+
+    void onWindowsChanged(in int[] changedWindowIds);
 }
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 3df06b5..5f7a17d 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -21,6 +21,7 @@
 import android.view.MagnificationSpec;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+import android.view.accessibility.AccessibilityWindowInfo;
 
 /**
  * Interface given to an AccessibilitySerivce to talk to the AccessibilityManagerService.
@@ -53,6 +54,10 @@
         int action, in Bundle arguments, int interactionId,
         IAccessibilityInteractionConnectionCallback callback, long threadId);
 
+    AccessibilityWindowInfo getWindow(int windowId);
+
+    List<AccessibilityWindowInfo> getWindows();
+
     AccessibilityServiceInfo getServiceInfo();
 
     boolean performGlobalAction(int action);
diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java
index 6a55ddf..f9284e67 100644
--- a/core/java/android/accounts/AccountAuthenticatorActivity.java
+++ b/core/java/android/accounts/AccountAuthenticatorActivity.java
@@ -17,7 +17,6 @@
 package android.accounts;
 
 import android.app.Activity;
-import android.content.Intent;
 import android.os.Bundle;
 
 /**
diff --git a/core/java/android/accounts/AccountManagerFuture.java b/core/java/android/accounts/AccountManagerFuture.java
index a1ab00c..af00a08 100644
--- a/core/java/android/accounts/AccountManagerFuture.java
+++ b/core/java/android/accounts/AccountManagerFuture.java
@@ -15,10 +15,7 @@
  */
 package android.accounts;
 
-import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
 import java.io.IOException;
 
 /**
diff --git a/core/java/android/accounts/ChooseAccountActivity.java b/core/java/android/accounts/ChooseAccountActivity.java
index bfbae24..242b3ea 100644
--- a/core/java/android/accounts/ChooseAccountActivity.java
+++ b/core/java/android/accounts/ChooseAccountActivity.java
@@ -100,7 +100,7 @@
             try {
                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
             } catch (PackageManager.NameNotFoundException e) {
                 // Nothing we can do much here, just log
                 if (Log.isLoggable(TAG, Log.WARN)) {
diff --git a/core/java/android/accounts/ChooseAccountTypeActivity.java b/core/java/android/accounts/ChooseAccountTypeActivity.java
index acc8549..a3222d8 100644
--- a/core/java/android/accounts/ChooseAccountTypeActivity.java
+++ b/core/java/android/accounts/ChooseAccountTypeActivity.java
@@ -129,7 +129,7 @@
             Drawable icon = null;
             try {
                 Context authContext = createPackageContext(desc.packageName, 0);
-                icon = authContext.getResources().getDrawable(desc.iconId);
+                icon = authContext.getDrawable(desc.iconId);
                 final CharSequence sequence = authContext.getResources().getText(desc.labelId);
                 if (sequence != null) {
                     name = sequence.toString();
diff --git a/core/java/android/accounts/GrantCredentialsPermissionActivity.java b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
index 8b01c6a..12b2b9c 100644
--- a/core/java/android/accounts/GrantCredentialsPermissionActivity.java
+++ b/core/java/android/accounts/GrantCredentialsPermissionActivity.java
@@ -16,7 +16,6 @@
 package android.accounts;
 
 import android.app.Activity;
-import android.content.pm.RegisteredServicesCache;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.widget.TextView;
@@ -30,7 +29,6 @@
 import com.android.internal.R;
 
 import java.io.IOException;
-import java.net.Authenticator;
 
 /**
  * @hide
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index d753e32..20236aa 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -215,7 +215,7 @@
                 (toType <= TypedValue.TYPE_LAST_COLOR_INT))) {
             // special case for colors: ignore valueType and get ints
             getFloats = false;
-            anim.setEvaluator(new ArgbEvaluator());
+            evaluator = ArgbEvaluator.getInstance();
         }
 
         if (getFloats) {
diff --git a/core/java/android/animation/ArgbEvaluator.java b/core/java/android/animation/ArgbEvaluator.java
index 717a3d9..ed07195 100644
--- a/core/java/android/animation/ArgbEvaluator.java
+++ b/core/java/android/animation/ArgbEvaluator.java
@@ -21,6 +21,19 @@
  * values that represent ARGB colors.
  */
 public class ArgbEvaluator implements TypeEvaluator {
+    private static final ArgbEvaluator sInstance = new ArgbEvaluator();
+
+    /**
+     * Returns an instance of <code>ArgbEvaluator</code> that may be used in
+     * {@link ValueAnimator#setEvaluator(TypeEvaluator)}. The same instance may
+     * be used in multiple <code>Animator</code>s because it holds no state.
+     * @return An instance of <code>ArgbEvalutor</code>.
+     *
+     * @hide
+     */
+    public static ArgbEvaluator getInstance() {
+        return sInstance;
+    }
 
     /**
      * This function returns the calculated in-between value for a color
diff --git a/core/java/android/animation/FloatArrayEvaluator.java b/core/java/android/animation/FloatArrayEvaluator.java
new file mode 100644
index 0000000..9ae1197
--- /dev/null
+++ b/core/java/android/animation/FloatArrayEvaluator.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.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>float[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class FloatArrayEvaluator implements TypeEvaluator<float[]> {
+
+    private float[] mArray;
+
+    /**
+     * Create a FloatArrayEvaluator that does not reuse the animated value. Care must be taken
+     * when using this option because on every evaluation a new <code>float[]</code> will be
+     * allocated.
+     *
+     * @see #FloatArrayEvaluator(float[])
+     */
+    public FloatArrayEvaluator() {
+    }
+
+    /**
+     * Create a FloatArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+     * Caution must be taken to ensure that the value returned from
+     * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+     * used across threads. The value will be modified on each <code>evaluate()</code> call.
+     *
+     * @param reuseArray The array to modify and return from <code>evaluate</code>.
+     */
+    public FloatArrayEvaluator(float[] reuseArray) {
+        mArray = reuseArray;
+    }
+
+    /**
+     * Interpolates the value at each index by the fraction. If
+     * {@link #FloatArrayEvaluator(float[])} was used to construct this object,
+     * <code>reuseArray</code> will be returned, otherwise a new <code>float[]</code>
+     * will be returned.
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start value.
+     * @param endValue   The end value.
+     * @return A <code>float[]</code> where each element is an interpolation between
+     *         the same index in startValue and endValue.
+     */
+    @Override
+    public float[] evaluate(float fraction, float[] startValue, float[] endValue) {
+        float[] array = mArray;
+        if (array == null) {
+            array = new float[startValue.length];
+        }
+
+        for (int i = 0; i < array.length; i++) {
+            float start = startValue[i];
+            float end = endValue[i];
+            array[i] = start + (fraction * (end - start));
+        }
+        return array;
+    }
+}
diff --git a/core/java/android/animation/IntArrayEvaluator.java b/core/java/android/animation/IntArrayEvaluator.java
new file mode 100644
index 0000000..d7f10f3
--- /dev/null
+++ b/core/java/android/animation/IntArrayEvaluator.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.animation;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>int[]</code> values.
+ * Each index into the array is treated as a separate value to interpolate. For example,
+ * evaluating <code>{100, 200}</code> and <code>{300, 400}</code> will interpolate the value at
+ * the first index between 100 and 300 and the value at the second index value between 200 and 400.
+ */
+public class IntArrayEvaluator implements TypeEvaluator<int[]> {
+
+    private int[] mArray;
+
+    /**
+     * Create an IntArrayEvaluator that does not reuse the animated value. Care must be taken
+     * when using this option because on every evaluation a new <code>int[]</code> will be
+     * allocated.
+     *
+     * @see #IntArrayEvaluator(int[])
+     */
+    public IntArrayEvaluator() {
+    }
+
+    /**
+     * Create an IntArrayEvaluator that reuses <code>reuseArray</code> for every evaluate() call.
+     * Caution must be taken to ensure that the value returned from
+     * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+     * used across threads. The value will be modified on each <code>evaluate()</code> call.
+     *
+     * @param reuseArray The array to modify and return from <code>evaluate</code>.
+     */
+    public IntArrayEvaluator(int[] reuseArray) {
+        mArray = reuseArray;
+    }
+
+    /**
+     * Interpolates the value at each index by the fraction. If {@link #IntArrayEvaluator(int[])}
+     * was used to construct this object, <code>reuseArray</code> will be returned, otherwise
+     * a new <code>int[]</code> will be returned.
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start value.
+     * @param endValue   The end value.
+     * @return An <code>int[]</code> where each element is an interpolation between
+     *         the same index in startValue and endValue.
+     */
+    @Override
+    public int[] evaluate(float fraction, int[] startValue, int[] endValue) {
+        int[] array = mArray;
+        if (array == null) {
+            array = new int[startValue.length];
+        }
+        for (int i = 0; i < array.length; i++) {
+            int start = startValue[i];
+            int end = endValue[i];
+            array[i] = (int) (start + (fraction * (end - start)));
+        }
+        return array;
+    }
+}
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 9c88ccf..c0ce795 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -16,6 +16,8 @@
 
 package android.animation;
 
+import android.graphics.Path;
+import android.graphics.PointF;
 import android.util.Log;
 import android.util.Property;
 
@@ -191,7 +193,7 @@
 
     /**
      * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -210,8 +212,33 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integers that are set to separate properties designated by
+     * <code>xPropertyName</code> and <code>yPropertyName</code>.
+     *
+     * @param target The object whose properties are to be animated. This object should
+     *               have public methods on it called <code>setNameX()</code> and
+     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
+     *               are the value of <code>xPropertyName</code> and <code>yPropertyName</code>
+     *               parameters, respectively.
+     * @param xPropertyName The name of the property for the x coordinate being animated.
+     * @param yPropertyName The name of the property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofInt(Object target, String xPropertyName, String yPropertyName,
+            Path path) {
+        Keyframe[][] keyframes = PropertyValuesHolder.createKeyframes(path, true);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframe(xPropertyName, keyframes[0]);
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframe(yPropertyName, keyframes[1]);
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between int values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -228,8 +255,135 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties.  A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integers that are set to separate properties, <code>xProperty</code> and
+     * <code>yProperty</code>.
+     *
+     * @param target The object whose properties are to be animated.
+     * @param xProperty The property for the x coordinate being animated.
+     * @param yProperty The property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T> ObjectAnimator ofInt(T target, Property<T, Integer> xProperty,
+            Property<T, Integer> yProperty, Path path) {
+        Keyframe[][] keyframes = PropertyValuesHolder.createKeyframes(path, true);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframe(xProperty, keyframes[0]);
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframe(yProperty, keyframes[1]);
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over int values for a multiple
+     * parameters setter. Only public methods that take only int parameters are supported.
+     * Each <code>int[]</code> contains a complete set of parameters to the setter method.
+     * At least two <code>int[]</code> values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofMultiInt(Object target, String propertyName, int[][] values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates the target using a multi-int setter
+     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
+     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are integer x and y coordinates used in the first and second parameter of the
+     * setter, respectively.
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofMultiInt(Object target, String propertyName, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over values for a multiple int
+     * parameters setter. Only public methods that take only int parameters are supported.
+     * <p>At least two values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).</p>
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param converter Converts T objects into int parameters for the multi-value setter.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofMultiInt(Object target, String propertyName,
+            TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiInt(propertyName, converter,
+                evaluator, values);
+        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object should
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter.
+     * @param propertyName The name of the property being animated.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofArgb(Object target, String propertyName, int... values) {
+        ObjectAnimator animator = ofInt(target, propertyName, values);
+        animator.setEvaluator(ArgbEvaluator.getInstance());
+        return animator;
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation).
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofArgb(T target, Property<T, Integer> property,
+            int... values) {
+        ObjectAnimator animator = ofInt(target, property, values);
+        animator.setEvaluator(ArgbEvaluator.getInstance());
+        return animator;
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -248,8 +402,33 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are floats that are set to separate properties designated by
+     * <code>xPropertyName</code> and <code>yPropertyName</code>.
+     *
+     * @param target The object whose properties are to be animated. This object should
+     *               have public methods on it called <code>setNameX()</code> and
+     *               <code>setNameY</code>, where <code>nameX</code> and <code>nameY</code>
+     *               are the value of the <code>xPropertyName</code> and <code>yPropertyName</code>
+     *               parameters, respectively.
+     * @param xPropertyName The name of the property for the x coordinate being animated.
+     * @param yPropertyName The name of the property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofFloat(Object target, String xPropertyName, String yPropertyName,
+            Path path) {
+        Keyframe[][] keyframes = PropertyValuesHolder.createKeyframes(path, false);
+        PropertyValuesHolder x = PropertyValuesHolder.ofKeyframe(xPropertyName, keyframes[0]);
+        PropertyValuesHolder y = PropertyValuesHolder.ofKeyframe(yPropertyName, keyframes[1]);
+        return ofPropertyValuesHolder(target, x, y);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between float values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -267,8 +446,94 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates coordinates along a <code>Path</code>
+     * using two properties. A <code>Path</code></> animation moves in two dimensions, animating
+     * coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are floats that are set to separate properties, <code>xProperty</code> and
+     * <code>yProperty</code>.
+     *
+     * @param target The object whose properties are to be animated.
+     * @param xProperty The property for the x coordinate being animated.
+     * @param yProperty The property for the y coordinate being animated.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T> ObjectAnimator ofFloat(T target, Property<T, Float> xProperty,
+            Property<T, Float> yProperty, Path path) {
+        return ofFloat(target, xProperty.getName(), yProperty.getName(), path);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over float values for a multiple
+     * parameters setter. Only public methods that take only float parameters are supported.
+     * Each <code>float[]</code> contains a complete set of parameters to the setter method.
+     * At least two <code>float[]</code> values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static ObjectAnimator ofMultiFloat(Object target, String propertyName,
+            float[][] values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates the target using a multi-float setter
+     * along the given <code>Path</code>. A <code>Path</code></> animation moves in two dimensions,
+     * animating coordinates <code>(x, y)</code> together to follow the line. In this variation, the
+     * coordinates are float x and y coordinates used in the first and second parameter of the
+     * setter, respectively.
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofMultiFloat(Object target, String propertyName, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates over values for a multiple float
+     * parameters setter. Only public methods that take only float parameters are supported.
+     * <p>At least two values must be provided, a start and end. More than two
+     * values imply a starting value, values to animate through along the way, and an ending
+     * value (these values will be distributed evenly across the duration of the animation).</p>
+     *
+     * @param target The object whose property is to be animated. This object may
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter. <code>propertyName</code> may also
+     * be the case-sensitive complete name of the public setter method.
+     * @param propertyName The name of the property being animated or the name of the setter method.
+     * @param converter Converts T objects into float parameters for the multi-value setter.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T> ObjectAnimator ofMultiFloat(Object target, String propertyName,
+            TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofMultiFloat(propertyName, converter,
+                evaluator, values);
+        return ObjectAnimator.ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -292,8 +557,32 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
+     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
+     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
+     * in a <code>PointF</code> to follow the <code>Path</code>. If the <code>Property</code>
+     * associated with <code>propertyName</code> uses a type other than <code>PointF</code>,
+     * <code>converter</code> can be used to change from <code>PointF</code> to the type
+     * associated with the <code>Property</code>.
+     *
+     * @param target The object whose property is to be animated. This object should
+     * have a public method on it called <code>setName()</code>, where <code>name</code> is
+     * the value of the <code>propertyName</code> parameter.
+     * @param propertyName The name of the property being animated.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static ObjectAnimator ofObject(Object target, String propertyName,
+            TypeConverter<PointF, ?> converter, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(propertyName, converter, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between Object values. A single
-     * value implies that that value is the one being animated to. Two values imply a starting
+     * value implies that that value is the one being animated to. Two values imply starting
      * and ending values. More than two values imply a starting value, values to animate through
      * along the way, and an ending value (these values will be distributed evenly across
      * the duration of the animation).
@@ -315,6 +604,53 @@
     }
 
     /**
+     * Constructs and returns an ObjectAnimator that animates between Object values. A single
+     * value implies that that value is the one being animated to. Two values imply starting
+     * and ending values. More than two values imply a starting value, values to animate through
+     * along the way, and an ending value (these values will be distributed evenly across
+     * the duration of the animation). This variant supplies a <code>TypeConverter</code> to
+     * convert from the animated values to the type of the property. If only one value is
+     * supplied, the <code>TypeConverter</code> must implement
+     * {@link TypeConverter#convertBack(Object)} to retrieve the current value.
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated.
+     * @param converter Converts the animated object to the Property type.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values A set of values that the animation will animate between over time.
+     * @return An ObjectAnimator object that is set up to animate between the given values.
+     */
+    public static <T, V, P> ObjectAnimator ofObject(T target, Property<T, P> property,
+            TypeConverter<V, P> converter, TypeEvaluator<V> evaluator, V... values) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, evaluator,
+                values);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
+     * Constructs and returns an ObjectAnimator that animates a property along a <code>Path</code>.
+     * A <code>Path</code></> animation moves in two dimensions, animating coordinates
+     * <code>(x, y)</code> together to follow the line. This variant animates the coordinates
+     * in a <code>PointF</code> to follow the <code>Path</code>. If <code>property</code>
+     * uses a type other than <code>PointF</code>, <code>converter</code> can be used to change
+     * from <code>PointF</code> to the type associated with the <code>Property</code>.
+     *
+     * @param target The object whose property is to be animated.
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The <code>Path</code> to animate values along.
+     * @return An ObjectAnimator object that is set up to animate along <code>path</code>.
+     */
+    public static <T, V> ObjectAnimator ofObject(T target, Property<T, V> property,
+            TypeConverter<PointF, V> converter, Path path) {
+        PropertyValuesHolder pvh = PropertyValuesHolder.ofObject(property, converter, path);
+        return ofPropertyValuesHolder(target, pvh);
+    }
+
+    /**
      * Constructs and returns an ObjectAnimator that animates between the sets of values specified
      * in <code>PropertyValueHolder</code> objects. This variant should be used when animating
      * several properties at once with the same ObjectAnimator, since PropertyValuesHolder allows
diff --git a/core/java/android/animation/PointFEvaluator.java b/core/java/android/animation/PointFEvaluator.java
new file mode 100644
index 0000000..91d501f
--- /dev/null
+++ b/core/java/android/animation/PointFEvaluator.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.animation;
+
+import android.graphics.PointF;
+
+/**
+ * This evaluator can be used to perform type interpolation between <code>PointF</code> values.
+ */
+public class PointFEvaluator implements TypeEvaluator<PointF> {
+
+    /**
+     * When null, a new PointF is returned on every evaluate call. When non-null,
+     * mPoint will be modified and returned on every evaluate.
+     */
+    private PointF mPoint;
+
+    /**
+     * Construct a PointFEvaluator that returns a new PointF on every evaluate call.
+     * To avoid creating an object for each evaluate call,
+     * {@link PointFEvaluator#PointFEvaluator(android.graphics.PointF)} should be used
+     * whenever possible.
+     */
+    public PointFEvaluator() {
+    }
+
+    /**
+     * Constructs a PointFEvaluator that modifies and returns <code>reuse</code>
+     * in {@link #evaluate(float, android.graphics.PointF, android.graphics.PointF)} calls.
+     * The value returned from
+     * {@link #evaluate(float, android.graphics.PointF, android.graphics.PointF)} should
+     * not be cached because it will change over time as the object is reused on each
+     * call.
+     *
+     * @param reuse A PointF to be modified and returned by evaluate.
+     */
+    public PointFEvaluator(PointF reuse) {
+        mPoint = reuse;
+    }
+
+    /**
+     * This function returns the result of linearly interpolating the start and
+     * end PointF values, with <code>fraction</code> representing the proportion
+     * between the start and end values. The calculation is a simple parametric
+     * calculation on each of the separate components in the PointF objects
+     * (x, y).
+     *
+     * <p>If {@link #PointFEvaluator(android.graphics.PointF)} was used to construct
+     * this PointFEvaluator, the object returned will be the <code>reuse</code>
+     * passed into the constructor.</p>
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue The start PointF
+     * @param endValue   The end PointF
+     * @return A linear interpolation between the start and end values, given the
+     *         <code>fraction</code> parameter.
+     */
+    @Override
+    public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
+        float x = startValue.x + (fraction * (endValue.x - startValue.x));
+        float y = startValue.y + (fraction * (endValue.y - startValue.y));
+
+        if (mPoint != null) {
+            mPoint.set(x, y);
+            return mPoint;
+        } else {
+            return new PointF(x, y);
+        }
+    }
+}
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 21f6eda..8fce80a 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -16,6 +16,9 @@
 
 package android.animation;
 
+import android.graphics.Path;
+import android.graphics.PointF;
+import android.util.FloatMath;
 import android.util.FloatProperty;
 import android.util.IntProperty;
 import android.util.Log;
@@ -124,6 +127,11 @@
     private Object mAnimatedValue;
 
     /**
+     * Converts from the source Object type to the setter Object type.
+     */
+    private TypeConverter mConverter;
+
+    /**
      * Internal utility constructor, used by the factory methods to set the property name.
      * @param propertyName The name of the property for this holder.
      */
@@ -166,6 +174,104 @@
 
     /**
      * Constructs and returns a PropertyValuesHolder with a given property name and
+     * set of <code>int[]</code> values. At least two <code>int[]</code> values must be supplied,
+     * a start and end value. If more values are supplied, the values will be animated from the
+     * start, through all intermediate values to the end value. When used with ObjectAnimator,
+     * the elements of the array represent the parameters of the setter function.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see IntArrayEvaluator#IntArrayEvaluator(int[])
+     * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static PropertyValuesHolder ofMultiInt(String propertyName, int[][] values) {
+        if (values.length < 2) {
+            throw new IllegalArgumentException("At least 2 values must be supplied");
+        }
+        int numParameters = 0;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == null) {
+                throw new IllegalArgumentException("values must not be null");
+            }
+            int length = values[i].length;
+            if (i == 0) {
+                numParameters = length;
+            } else if (length != numParameters) {
+                throw new IllegalArgumentException("Values must all have the same length");
+            }
+        }
+        IntArrayEvaluator evaluator = new IntArrayEvaluator(new int[numParameters]);
+        return new MultiIntValuesHolder(propertyName, null, evaluator, (Object[]) values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name to use
+     * as a multi-int setter. The values are animated along the path, with the first
+     * parameter of the setter set to the x coordinate and the second set to the y coordinate.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     *                     The setter must take exactly two <code>int</code> parameters.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static PropertyValuesHolder ofMultiInt(String propertyName, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(keyframes);
+        TypeEvaluator<PointF> evaluator = new PointFEvaluator(new PointF());
+        PointFToIntArray converter = new PointFToIntArray();
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values for use with ObjectAnimator multi-value setters. The Object
+     * values are converted to <code>int[]</code> using the converter.
+     *
+     * @param propertyName The property being animated or complete name of the setter.
+     *                     Should not be null.
+     * @param converter Used to convert the animated value to setter parameters.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofMultiInt(Object, String, TypeConverter, TypeEvaluator, Object[])
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static <V> PropertyValuesHolder ofMultiInt(String propertyName,
+            TypeConverter<V, int[]> converter, TypeEvaluator<V> evaluator, V... values) {
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder object with the specified property name or
+     * setter name for use in a multi-int setter function using ObjectAnimator. The values can be
+     * of any type, but the type should be consistent so that the supplied
+     * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+     * <code>converter</code> converts the values to parameters in the setter function.
+     *
+     * <p>At least two values must be supplied, a start and an end value.</p>
+     *
+     * @param propertyName The name of the property to associate with the set of values. This
+     *                     may also be the complete name of a setter function.
+     * @param converter    Converts <code>values</code> into int parameters for the setter.
+     *                     Can be null if the Keyframes have int[] values.
+     * @param evaluator    Used to interpolate between values.
+     * @param values       The values at specific fractional times to evaluate between
+     * @return A PropertyValuesHolder for a multi-int parameter setter.
+     */
+    public static <T> PropertyValuesHolder ofMultiInt(String propertyName,
+            TypeConverter<T, int[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+        return new MultiIntValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
      * set of float values.
      * @param propertyName The name of the property being animated.
      * @param values The values that the named property will animate between.
@@ -188,6 +294,103 @@
 
     /**
      * Constructs and returns a PropertyValuesHolder with a given property name and
+     * set of <code>float[]</code> values. At least two <code>float[]</code> values must be supplied,
+     * a start and end value. If more values are supplied, the values will be animated from the
+     * start, through all intermediate values to the end value. When used with ObjectAnimator,
+     * the elements of the array represent the parameters of the setter function.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see FloatArrayEvaluator#FloatArrayEvaluator(float[])
+     * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static PropertyValuesHolder ofMultiFloat(String propertyName, float[][] values) {
+        if (values.length < 2) {
+            throw new IllegalArgumentException("At least 2 values must be supplied");
+        }
+        int numParameters = 0;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] == null) {
+                throw new IllegalArgumentException("values must not be null");
+            }
+            int length = values[i].length;
+            if (i == 0) {
+                numParameters = length;
+            } else if (length != numParameters) {
+                throw new IllegalArgumentException("Values must all have the same length");
+            }
+        }
+        FloatArrayEvaluator evaluator = new FloatArrayEvaluator(new float[numParameters]);
+        return new MultiFloatValuesHolder(propertyName, null, evaluator, (Object[]) values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name to use
+     * as a multi-float setter. The values are animated along the path, with the first
+     * parameter of the setter set to the x coordinate and the second set to the y coordinate.
+     *
+     * @param propertyName The name of the property being animated. Can also be the
+     *                     case-sensitive name of the entire setter method. Should not be null.
+     *                     The setter must take exactly two <code>float</code> parameters.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofPropertyValuesHolder(Object, PropertyValuesHolder...)
+     */
+    public static PropertyValuesHolder ofMultiFloat(String propertyName, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(keyframes);
+        TypeEvaluator<PointF> evaluator = new PointFEvaluator(new PointF());
+        PointFToFloatArray converter = new PointFToFloatArray();
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values for use with ObjectAnimator multi-value setters. The Object
+     * values are converted to <code>float[]</code> using the converter.
+     *
+     * @param propertyName The property being animated or complete name of the setter.
+     *                     Should not be null.
+     * @param converter Used to convert the animated value to setter parameters.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see ObjectAnimator#ofMultiFloat(Object, String, TypeConverter, TypeEvaluator, Object[])
+     */
+    public static <V> PropertyValuesHolder ofMultiFloat(String propertyName,
+            TypeConverter<V, float[]> converter, TypeEvaluator<V> evaluator, V... values) {
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, values);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder object with the specified property name or
+     * setter name for use in a multi-float setter function using ObjectAnimator. The values can be
+     * of any type, but the type should be consistent so that the supplied
+     * {@link android.animation.TypeEvaluator} can be used to to evaluate the animated value. The
+     * <code>converter</code> converts the values to parameters in the setter function.
+     *
+     * <p>At least two values must be supplied, a start and an end value.</p>
+     *
+     * @param propertyName The name of the property to associate with the set of values. This
+     *                     may also be the complete name of a setter function.
+     * @param converter    Converts <code>values</code> into float parameters for the setter.
+     *                     Can be null if the Keyframes have float[] values.
+     * @param evaluator    Used to interpolate between values.
+     * @param values       The values at specific fractional times to evaluate between
+     * @return A PropertyValuesHolder for a multi-float parameter setter.
+     */
+    public static <T> PropertyValuesHolder ofMultiFloat(String propertyName,
+            TypeConverter<T, float[]> converter, TypeEvaluator<T> evaluator, Keyframe... values) {
+        KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+        return new MultiFloatValuesHolder(propertyName, converter, evaluator, keyframeSet);
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
      * set of Object values. This variant also takes a TypeEvaluator because the system
      * cannot automatically interpolate between objects of unknown type.
      *
@@ -207,6 +410,27 @@
     }
 
     /**
+     * Constructs and returns a PropertyValuesHolder with a given property name and
+     * a Path along which the values should be animated. This variant supports a
+     * <code>TypeConverter</code> to convert from <code>PointF</code> to the target
+     * type.
+     *
+     * @param propertyName The name of the property being animated.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     */
+    public static PropertyValuesHolder ofObject(String propertyName,
+            TypeConverter<PointF, ?> converter, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        PropertyValuesHolder pvh = ofKeyframe(propertyName, keyframes);
+        pvh.setEvaluator(new PointFEvaluator(new PointF()));
+        pvh.setConverter(converter);
+        return pvh;
+    }
+
+    /**
      * Constructs and returns a PropertyValuesHolder with a given property and
      * set of Object values. This variant also takes a TypeEvaluator because the system
      * cannot automatically interpolate between objects of unknown type.
@@ -227,6 +451,55 @@
     }
 
     /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * set of Object values. This variant also takes a TypeEvaluator because the system
+     * cannot automatically interpolate between objects of unknown type. This variant also
+     * takes a <code>TypeConverter</code> to convert from animated values to the type
+     * of the property. If only one value is supplied, the <code>TypeConverter</code>
+     * must implement {@link TypeConverter#convertBack(Object)} to retrieve the current
+     * value.
+     *
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts the animated object to the Property type.
+     * @param evaluator A TypeEvaluator that will be called on each animation frame to
+     * provide the necessary interpolation between the Object values to derive the animated
+     * value.
+     * @param values The values that the property will animate between.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     * @see #setConverter(TypeConverter)
+     * @see TypeConverter
+     */
+    public static <T, V> PropertyValuesHolder ofObject(Property<?, V> property,
+            TypeConverter<T, V> converter, TypeEvaluator<T> evaluator, T... values) {
+        PropertyValuesHolder pvh = new PropertyValuesHolder(property);
+        pvh.setConverter(converter);
+        pvh.setObjectValues(values);
+        pvh.setEvaluator(evaluator);
+        return pvh;
+    }
+
+    /**
+     * Constructs and returns a PropertyValuesHolder with a given property and
+     * a Path along which the values should be animated. This variant supports a
+     * <code>TypeConverter</code> to convert from <code>PointF</code> to the target
+     * type.
+     *
+     * @param property The property being animated. Should not be null.
+     * @param converter Converts a PointF to the type associated with the setter. May be
+     *                  null if conversion is unnecessary.
+     * @param path The Path along which the values should be animated.
+     * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
+     */
+    public static <V> PropertyValuesHolder ofObject(Property<?, V> property,
+            TypeConverter<PointF, V> converter, Path path) {
+        Keyframe[] keyframes = createKeyframes(path);
+        PropertyValuesHolder pvh = ofKeyframe(property, keyframes);
+        pvh.setEvaluator(new PointFEvaluator(new PointF()));
+        pvh.setConverter(converter);
+        return pvh;
+    }
+
+    /**
      * Constructs and returns a PropertyValuesHolder object with the specified property name and set
      * of values. These values can be of any type, but the type should be consistent so that
      * an appropriate {@link android.animation.TypeEvaluator} can be found that matches
@@ -361,6 +634,14 @@
     }
 
     /**
+     * Sets the converter to convert from the values type to the setter's parameter type.
+     * @param converter The converter to use to convert values.
+     */
+    public void setConverter(TypeConverter converter) {
+        mConverter = converter;
+    }
+
+    /**
      * Determine the setter or getter function using the JavaBeans convention of setFoo or
      * getFoo for a property named 'foo'. This function figures out what the name of the
      * function should be and uses reflection to find the Method with that name on the
@@ -389,22 +670,24 @@
         } else {
             args = new Class[1];
             Class typeVariants[];
-            if (mValueType.equals(Float.class)) {
+            if (valueType.equals(Float.class)) {
                 typeVariants = FLOAT_VARIANTS;
-            } else if (mValueType.equals(Integer.class)) {
+            } else if (valueType.equals(Integer.class)) {
                 typeVariants = INTEGER_VARIANTS;
-            } else if (mValueType.equals(Double.class)) {
+            } else if (valueType.equals(Double.class)) {
                 typeVariants = DOUBLE_VARIANTS;
             } else {
                 typeVariants = new Class[1];
-                typeVariants[0] = mValueType;
+                typeVariants[0] = valueType;
             }
             for (Class typeVariant : typeVariants) {
                 args[0] = typeVariant;
                 try {
                     returnVal = targetClass.getMethod(methodName, args);
-                    // change the value type to suit
-                    mValueType = typeVariant;
+                    if (mConverter == null) {
+                        // change the value type to suit
+                        mValueType = typeVariant;
+                    }
                     return returnVal;
                 } catch (NoSuchMethodException e) {
                     // Swallow the error and keep trying other variants
@@ -415,7 +698,7 @@
 
         if (returnVal == null) {
             Log.w("PropertyValuesHolder", "Method " +
-                    getMethodName(prefix, mPropertyName) + "() with type " + mValueType +
+                    getMethodName(prefix, mPropertyName) + "() with type " + valueType +
                     " not found on target class " + targetClass);
         }
 
@@ -465,7 +748,8 @@
      * @param targetClass The Class on which the requested method should exist.
      */
     void setupSetter(Class targetClass) {
-        mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
+        Class<?> propertyType = mConverter == null ? mValueType : mConverter.getTargetType();
+        mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", propertyType);
     }
 
     /**
@@ -489,10 +773,13 @@
         if (mProperty != null) {
             // check to make sure that mProperty is on the class of target
             try {
-                Object testValue = mProperty.get(target);
+                Object testValue = null;
                 for (Keyframe kf : mKeyframeSet.mKeyframes) {
                     if (!kf.hasValue()) {
-                        kf.setValue(mProperty.get(target));
+                        if (testValue == null) {
+                            testValue = convertBack(mProperty.get(target));
+                        }
+                        kf.setValue(testValue);
                     }
                 }
                 return;
@@ -516,7 +803,8 @@
                     }
                 }
                 try {
-                    kf.setValue(mGetter.invoke(target));
+                    Object value = convertBack(mGetter.invoke(target));
+                    kf.setValue(value);
                 } catch (InvocationTargetException e) {
                     Log.e("PropertyValuesHolder", e.toString());
                 } catch (IllegalAccessException e) {
@@ -526,6 +814,18 @@
         }
     }
 
+    private Object convertBack(Object value) {
+        if (mConverter != null) {
+            value = mConverter.convertBack(value);
+            if (value == null) {
+                throw new IllegalArgumentException("Converter "
+                        + mConverter.getClass().getName()
+                        + " must implement convertBack and not return null.");
+            }
+        }
+        return value;
+    }
+
     /**
      * Utility function to set the value stored in a particular Keyframe. The value used is
      * whatever the value is for the property name specified in the keyframe on the target object.
@@ -535,7 +835,8 @@
      */
     private void setupValue(Object target, Keyframe kf) {
         if (mProperty != null) {
-            kf.setValue(mProperty.get(target));
+            Object value = convertBack(mProperty.get(target));
+            kf.setValue(value);
         }
         try {
             if (mGetter == null) {
@@ -546,7 +847,8 @@
                     return;
                 }
             }
-            kf.setValue(mGetter.invoke(target));
+            Object value = convertBack(mGetter.invoke(target));
+            kf.setValue(value);
         } catch (InvocationTargetException e) {
             Log.e("PropertyValuesHolder", e.toString());
         } catch (IllegalAccessException e) {
@@ -657,7 +959,8 @@
      * @param fraction The elapsed, interpolated fraction of the animation.
      */
     void calculateValue(float fraction) {
-        mAnimatedValue = mKeyframeSet.getValue(fraction);
+        Object value = mKeyframeSet.getValue(fraction);
+        mAnimatedValue = mConverter == null ? value : mConverter.convert(value);
     }
 
     /**
@@ -1015,8 +1318,334 @@
 
     }
 
+    static class MultiFloatValuesHolder extends PropertyValuesHolder {
+        private long mJniSetter;
+        private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap =
+                new HashMap<Class, HashMap<String, Long>>();
+
+        public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Object... values) {
+            super(propertyName);
+            setConverter(converter);
+            setObjectValues(values);
+            setEvaluator(evaluator);
+        }
+
+        public MultiFloatValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, KeyframeSet keyframeSet) {
+            super(propertyName);
+            setConverter(converter);
+            mKeyframeSet = keyframeSet;
+            setEvaluator(evaluator);
+        }
+
+        /**
+         * Internal function to set the value on the target object, using the setter set up
+         * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+         * to handle turning the value calculated by ValueAnimator into a value set on the object
+         * according to the name of the property.
+         *
+         * @param target The target object on which the value is set
+         */
+        @Override
+        void setAnimatedValue(Object target) {
+            float[] values = (float[]) getAnimatedValue();
+            int numParameters = values.length;
+            if (mJniSetter != 0) {
+                switch (numParameters) {
+                    case 1:
+                        nCallFloatMethod(target, mJniSetter, values[0]);
+                        break;
+                    case 2:
+                        nCallTwoFloatMethod(target, mJniSetter, values[0], values[1]);
+                        break;
+                    case 4:
+                        nCallFourFloatMethod(target, mJniSetter, values[0], values[1],
+                                values[2], values[3]);
+                        break;
+                    default: {
+                        nCallMultipleFloatMethod(target, mJniSetter, values);
+                        break;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Internal function (called from ObjectAnimator) to set up the setter and getter
+         * prior to running the animation. No getter can be used for multiple parameters.
+         *
+         * @param target The object on which the setter exists.
+         */
+        @Override
+        void setupSetterAndGetter(Object target) {
+            setupSetter(target.getClass());
+        }
+
+        @Override
+        void setupSetter(Class targetClass) {
+            if (mJniSetter != 0) {
+                return;
+            }
+            try {
+                mPropertyMapLock.writeLock().lock();
+                HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
+                if (propertyMap != null) {
+                    Long jniSetterLong = propertyMap.get(mPropertyName);
+                    if (jniSetterLong != null) {
+                        mJniSetter = jniSetterLong;
+                    }
+                }
+                if (mJniSetter == 0) {
+                    String methodName = getMethodName("set", mPropertyName);
+                    calculateValue(0f);
+                    float[] values = (float[]) getAnimatedValue();
+                    int numParams = values.length;
+                    try {
+                        mJniSetter = nGetMultipleFloatMethod(targetClass, methodName, numParams);
+                    } catch (NoSuchMethodError e) {
+                        // try without the 'set' prefix
+                        mJniSetter = nGetMultipleFloatMethod(targetClass, mPropertyName, numParams);
+                    }
+                    if (mJniSetter != 0) {
+                        if (propertyMap == null) {
+                            propertyMap = new HashMap<String, Long>();
+                            sJNISetterPropertyMap.put(targetClass, propertyMap);
+                        }
+                        propertyMap.put(mPropertyName, mJniSetter);
+                    }
+                }
+            } finally {
+                mPropertyMapLock.writeLock().unlock();
+            }
+        }
+    }
+
+    static class MultiIntValuesHolder extends PropertyValuesHolder {
+        private long mJniSetter;
+        private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap =
+                new HashMap<Class, HashMap<String, Long>>();
+
+        public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, Object... values) {
+            super(propertyName);
+            setConverter(converter);
+            setObjectValues(values);
+            setEvaluator(evaluator);
+        }
+
+        public MultiIntValuesHolder(String propertyName, TypeConverter converter,
+                TypeEvaluator evaluator, KeyframeSet keyframeSet) {
+            super(propertyName);
+            setConverter(converter);
+            mKeyframeSet = keyframeSet;
+            setEvaluator(evaluator);
+        }
+
+        /**
+         * Internal function to set the value on the target object, using the setter set up
+         * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+         * to handle turning the value calculated by ValueAnimator into a value set on the object
+         * according to the name of the property.
+         *
+         * @param target The target object on which the value is set
+         */
+        @Override
+        void setAnimatedValue(Object target) {
+            int[] values = (int[]) getAnimatedValue();
+            int numParameters = values.length;
+            if (mJniSetter != 0) {
+                switch (numParameters) {
+                    case 1:
+                        nCallIntMethod(target, mJniSetter, values[0]);
+                        break;
+                    case 2:
+                        nCallTwoIntMethod(target, mJniSetter, values[0], values[1]);
+                        break;
+                    case 4:
+                        nCallFourIntMethod(target, mJniSetter, values[0], values[1],
+                                values[2], values[3]);
+                        break;
+                    default: {
+                        nCallMultipleIntMethod(target, mJniSetter, values);
+                        break;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Internal function (called from ObjectAnimator) to set up the setter and getter
+         * prior to running the animation. No getter can be used for multiple parameters.
+         *
+         * @param target The object on which the setter exists.
+         */
+        @Override
+        void setupSetterAndGetter(Object target) {
+            setupSetter(target.getClass());
+        }
+
+        @Override
+        void setupSetter(Class targetClass) {
+            if (mJniSetter != 0) {
+                return;
+            }
+            try {
+                mPropertyMapLock.writeLock().lock();
+                HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
+                if (propertyMap != null) {
+                    Long jniSetterLong = propertyMap.get(mPropertyName);
+                    if (jniSetterLong != null) {
+                        mJniSetter = jniSetterLong;
+                    }
+                }
+                if (mJniSetter == 0) {
+                    String methodName = getMethodName("set", mPropertyName);
+                    calculateValue(0f);
+                    int[] values = (int[]) getAnimatedValue();
+                    int numParams = values.length;
+                    try {
+                        mJniSetter = nGetMultipleIntMethod(targetClass, methodName, numParams);
+                    } catch (NoSuchMethodError e) {
+                        // try without the 'set' prefix
+                        mJniSetter = nGetMultipleIntMethod(targetClass, mPropertyName, numParams);
+                    }
+                    if (mJniSetter != 0) {
+                        if (propertyMap == null) {
+                            propertyMap = new HashMap<String, Long>();
+                            sJNISetterPropertyMap.put(targetClass, propertyMap);
+                        }
+                        propertyMap.put(mPropertyName, mJniSetter);
+                    }
+                }
+            } finally {
+                mPropertyMapLock.writeLock().unlock();
+            }
+        }
+    }
+
+    /* Path interpolation relies on approximating the Path as a series of line segments.
+       The line segments are recursively divided until there is less than 1/2 pixel error
+       between the lines and the curve. Each point of the line segment is converted
+       to a Keyframe and a linear interpolation between Keyframes creates a good approximation
+       of the curve.
+
+       The fraction for each Keyframe is the length along the Path to the point, divided by
+       the total Path length. Two points may have the same fraction in the case of a move
+       command causing a disjoint Path.
+
+       The value for each Keyframe is either the point as a PointF or one of the x or y
+       coordinates as an int or float. In the latter case, two Keyframes are generated for
+       each point that have the same fraction. */
+
+    /**
+     * Returns separate Keyframes arrays for the x and y coordinates along a Path. If
+     * isInt is true, the Keyframes will be IntKeyframes, otherwise they will be FloatKeyframes.
+     * The element at index 0 are the x coordinate Keyframes and element at index 1 are the
+     * y coordinate Keyframes. The returned values can be linearly interpolated and get less
+     * than 1/2 pixel error.
+     */
+    static Keyframe[][] createKeyframes(Path path, boolean isInt) {
+        if (path == null || path.isEmpty()) {
+            throw new IllegalArgumentException("The path must not be null or empty");
+        }
+        float[] pointComponents = path.approximate(0.5f);
+
+        int numPoints = pointComponents.length / 3;
+
+        Keyframe[][] keyframes = new Keyframe[2][];
+        keyframes[0] = new Keyframe[numPoints];
+        keyframes[1] = new Keyframe[numPoints];
+        int componentIndex = 0;
+        for (int i = 0; i < numPoints; i++) {
+            float fraction = pointComponents[componentIndex++];
+            float x = pointComponents[componentIndex++];
+            float y = pointComponents[componentIndex++];
+            if (isInt) {
+                keyframes[0][i] = Keyframe.ofInt(fraction, Math.round(x));
+                keyframes[1][i] = Keyframe.ofInt(fraction, Math.round(y));
+            } else {
+                keyframes[0][i] = Keyframe.ofFloat(fraction, x);
+                keyframes[1][i] = Keyframe.ofFloat(fraction, y);
+            }
+        }
+        return keyframes;
+    }
+
+    /**
+     * Returns PointF Keyframes for a Path. The resulting points can be linearly interpolated
+     * with less than 1/2 pixel in error.
+     */
+    private static Keyframe[] createKeyframes(Path path) {
+        if (path == null || path.isEmpty()) {
+            throw new IllegalArgumentException("The path must not be null or empty");
+        }
+        float[] pointComponents = path.approximate(0.5f);
+
+        int numPoints = pointComponents.length / 3;
+
+        Keyframe[] keyframes = new Keyframe[numPoints];
+        int componentIndex = 0;
+        for (int i = 0; i < numPoints; i++) {
+            float fraction = pointComponents[componentIndex++];
+            float x = pointComponents[componentIndex++];
+            float y = pointComponents[componentIndex++];
+            keyframes[i] = Keyframe.ofObject(fraction, new PointF(x, y));
+        }
+        return keyframes;
+    }
+
+    /**
+     * Convert from PointF to float[] for multi-float setters along a Path.
+     */
+    private static class PointFToFloatArray extends TypeConverter<PointF, float[]> {
+        private float[] mCoordinates = new float[2];
+
+        public PointFToFloatArray() {
+            super(PointF.class, float[].class);
+        }
+
+        @Override
+        public float[] convert(PointF value) {
+            mCoordinates[0] = value.x;
+            mCoordinates[1] = value.y;
+            return mCoordinates;
+        }
+    };
+
+    /**
+     * Convert from PointF to int[] for multi-int setters along a Path.
+     */
+    private static class PointFToIntArray extends TypeConverter<PointF, int[]> {
+        private int[] mCoordinates = new int[2];
+
+        public PointFToIntArray() {
+            super(PointF.class, int[].class);
+        }
+
+        @Override
+        public int[] convert(PointF value) {
+            mCoordinates[0] = Math.round(value.x);
+            mCoordinates[1] = Math.round(value.y);
+            return mCoordinates;
+        }
+    };
+
     native static private long nGetIntMethod(Class targetClass, String methodName);
     native static private long nGetFloatMethod(Class targetClass, String methodName);
+    native static private long nGetMultipleIntMethod(Class targetClass, String methodName,
+            int numParams);
+    native static private long nGetMultipleFloatMethod(Class targetClass, String methodName,
+            int numParams);
     native static private void nCallIntMethod(Object target, long methodID, int arg);
     native static private void nCallFloatMethod(Object target, long methodID, float arg);
+    native static private void nCallTwoIntMethod(Object target, long methodID, int arg1, int arg2);
+    native static private void nCallFourIntMethod(Object target, long methodID, int arg1, int arg2,
+            int arg3, int arg4);
+    native static private void nCallMultipleIntMethod(Object target, long methodID, int[] args);
+    native static private void nCallTwoFloatMethod(Object target, long methodID, float arg1,
+            float arg2);
+    native static private void nCallFourFloatMethod(Object target, long methodID, float arg1,
+            float arg2, float arg3, float arg4);
+    native static private void nCallMultipleFloatMethod(Object target, long methodID, float[] args);
 }
diff --git a/core/java/android/animation/RectEvaluator.java b/core/java/android/animation/RectEvaluator.java
index 28d496b..23eb766 100644
--- a/core/java/android/animation/RectEvaluator.java
+++ b/core/java/android/animation/RectEvaluator.java
@@ -23,12 +23,45 @@
 public class RectEvaluator implements TypeEvaluator<Rect> {
 
     /**
+     * When null, a new Rect is returned on every evaluate call. When non-null,
+     * mRect will be modified and returned on every evaluate.
+     */
+    private Rect mRect;
+
+    /**
+     * Construct a RectEvaluator that returns a new Rect on every evaluate call.
+     * To avoid creating an object for each evaluate call,
+     * {@link RectEvaluator#RectEvaluator(android.graphics.Rect)} should be used
+     * whenever possible.
+     */
+    public RectEvaluator() {
+    }
+
+    /**
+     * Constructs a RectEvaluator that modifies and returns <code>reuseRect</code>
+     * in {@link #evaluate(float, android.graphics.Rect, android.graphics.Rect)} calls.
+     * The value returned from
+     * {@link #evaluate(float, android.graphics.Rect, android.graphics.Rect)} should
+     * not be cached because it will change over time as the object is reused on each
+     * call.
+     *
+     * @param reuseRect A Rect to be modified and returned by evaluate.
+     */
+    public RectEvaluator(Rect reuseRect) {
+        mRect = reuseRect;
+    }
+
+    /**
      * This function returns the result of linearly interpolating the start and
      * end Rect values, with <code>fraction</code> representing the proportion
      * between the start and end values. The calculation is a simple parametric
      * calculation on each of the separate components in the Rect objects
      * (left, top, right, and bottom).
      *
+     * <p>If {@link #RectEvaluator(android.graphics.Rect)} was used to construct
+     * this RectEvaluator, the object returned will be the <code>reuseRect</code>
+     * passed into the constructor.</p>
+     *
      * @param fraction   The fraction from the starting to the ending values
      * @param startValue The start Rect
      * @param endValue   The end Rect
@@ -37,9 +70,15 @@
      */
     @Override
     public Rect evaluate(float fraction, Rect startValue, Rect endValue) {
-        return new Rect(startValue.left + (int)((endValue.left - startValue.left) * fraction),
-                startValue.top + (int)((endValue.top - startValue.top) * fraction),
-                startValue.right + (int)((endValue.right - startValue.right) * fraction),
-                startValue.bottom + (int)((endValue.bottom - startValue.bottom) * fraction));
+        int left = startValue.left + (int) ((endValue.left - startValue.left) * fraction);
+        int top = startValue.top + (int) ((endValue.top - startValue.top) * fraction);
+        int right = startValue.right + (int) ((endValue.right - startValue.right) * fraction);
+        int bottom = startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction);
+        if (mRect == null) {
+            return new Rect(left, top, right, bottom);
+        } else {
+            mRect.set(left, top, right, bottom);
+            return mRect;
+        }
     }
 }
diff --git a/core/java/android/animation/TypeConverter.java b/core/java/android/animation/TypeConverter.java
new file mode 100644
index 0000000..03b3eb5
--- /dev/null
+++ b/core/java/android/animation/TypeConverter.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 android.animation;
+
+/**
+ * Abstract base class used convert type T to another type V. This
+ * is necessary when the value types of in animation are different
+ * from the property type.
+ * @see PropertyValuesHolder#setConverter(TypeConverter)
+ */
+public abstract class TypeConverter<T, V> {
+    private Class<T> mFromClass;
+    private Class<V> mToClass;
+
+    public TypeConverter(Class<T> fromClass, Class<V> toClass) {
+        mFromClass = fromClass;
+        mToClass = toClass;
+    }
+
+    /**
+     * Returns the target converted type. Used by the animation system to determine
+     * the proper setter function to call.
+     * @return The Class to convert the input to.
+     */
+    Class<V> getTargetType() {
+        return mToClass;
+    }
+
+    /**
+     * Returns the source conversion type.
+     */
+    Class<T> getSourceType() {
+        return mFromClass;
+    }
+
+    /**
+     * Converts a value from one type to another.
+     * @param value The Object to convert.
+     * @return A value of type V, converted from <code>value</code>.
+     */
+    public abstract V convert(T value);
+
+    /**
+     * Does a conversion from the target type back to the source type. The subclass
+     * must implement this when a TypeConverter is used in animations and current
+     * values will need to be read for an animation. By default, this will return null,
+     * indicating that back-conversion is not supported.
+     * @param value The Object to convert.
+     * @return A value of type T, converted from <code>value</code>.
+     */
+    public T convertBack(V value) {
+        return null;
+    }
+}
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 86da673..5338dd0 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -280,6 +280,24 @@
     }
 
     /**
+     * Constructs and returns a ValueAnimator that animates between color values. A single
+     * value implies that that value is the one being animated to. However, this is not typically
+     * useful in a ValueAnimator object because there is no way for the object to determine the
+     * starting value for the animation (unlike ObjectAnimator, which can derive that value
+     * from the target object and property being animated). Therefore, there should typically
+     * be two or more values.
+     *
+     * @param values A set of values that the animation will animate between over time.
+     * @return A ValueAnimator object that is set up to animate between the given values.
+     */
+    public static ValueAnimator ofArgb(int... values) {
+        ValueAnimator anim = new ValueAnimator();
+        anim.setIntValues(values);
+        anim.setEvaluator(ArgbEvaluator.getInstance());
+        return anim;
+    }
+
+    /**
      * Constructs and returns a ValueAnimator that animates between float values. A single
      * value implies that that value is the one being animated to. However, this is not typically
      * useful in a ValueAnimator object because there is no way for the object to determine the
@@ -1106,28 +1124,27 @@
         if (!mStartedDelay) {
             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);
-                }
+        }
+        if (mPaused) {
+            if (mPauseTime < 0) {
+                mPauseTime = currentTime;
             }
-            long deltaTime = currentTime - mDelayStartTime;
-            if (deltaTime > mStartDelay) {
-                // startDelay ended - start the anim and record the
-                // mStartTime appropriately
-                mStartTime = currentTime - (deltaTime - mStartDelay);
-                mPlayingState = RUNNING;
-                return true;
+            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
+            // mStartTime appropriately
+            mStartTime = currentTime - (deltaTime - mStartDelay);
+            mPlayingState = RUNNING;
+            return true;
+        }
         return false;
     }
 
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
new file mode 100644
index 0000000..3cae9c5
--- /dev/null
+++ b/core/java/android/annotation/IntDef.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.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element of integer type, represents
+ * a logical type and that its value should be one of the explicitly
+ * named constants. If the {@link #flag()} attribute is set to true,
+ * multiple constants can be combined.
+ * <p>
+ * Example:
+ * <pre>{@code
+ *  &#64;Retention(CLASS)
+ *  &#64;IntDef(&#123;NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS&#125;)
+ *  public &#64;interface NavigationMode &#123;&#125;
+ *  public static final int NAVIGATION_MODE_STANDARD = 0;
+ *  public static final int NAVIGATION_MODE_LIST = 1;
+ *  public static final int NAVIGATION_MODE_TABS = 2;
+ *  ...
+ *  public abstract void setNavigationMode(&#64;NavigationMode int mode);
+ *  &#64;NavigationMode
+ *  public abstract int getNavigationMode();
+ * }</pre>
+ * For a flag, set the flag attribute:
+ * <pre>{@code
+ *  &#64;IntDef(
+ *      flag = true
+ *      value = &#123;NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS&#125;)
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE})
+public @interface IntDef {
+    /** Defines the allowed constants for this element */
+    long[] value() default {};
+
+    /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
+    boolean flag() default false;
+}
diff --git a/core/java/android/annotation/NonNull.java b/core/java/android/annotation/NonNull.java
new file mode 100644
index 0000000..3ca9eea
--- /dev/null
+++ b/core/java/android/annotation/NonNull.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 android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can never be null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface NonNull {
+}
diff --git a/core/java/android/annotation/Nullable.java b/core/java/android/annotation/Nullable.java
new file mode 100644
index 0000000..43f42fa
--- /dev/null
+++ b/core/java/android/annotation/Nullable.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+/**
+ * Denotes that a parameter, field or method return value can be null.
+ * <p>
+ * When decorating a method call parameter, this denotes that the parameter can
+ * legitimately be null and the method will gracefully deal with it. Typically
+ * used on optional parameters.
+ * <p>
+ * When decorating a method, this denotes the method might legitimately return
+ * null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface Nullable {
+}
diff --git a/core/java/android/annotation/StringDef.java b/core/java/android/annotation/StringDef.java
new file mode 100644
index 0000000..5f7f380
--- /dev/null
+++ b/core/java/android/annotation/StringDef.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated String element, represents a logical
+ * type and that its value should be one of the explicitly named constants.
+ * <p>
+ * Example:
+ * <pre>{@code
+ *  &#64;Retention(SOURCE)
+ *  &#64;StringDef(&#123;
+ *     POWER_SERVICE,
+ *     WINDOW_SERVICE,
+ *     LAYOUT_INFLATER_SERVICE
+ *  &#125;)
+ *  public &#64;interface ServiceName &#123;&#125;
+ *  public static final String POWER_SERVICE = "power";
+ *  public static final String WINDOW_SERVICE = "window";
+ *  public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
+ *  ...
+ *  public abstract Object getSystemService(&#64;ServiceName String name);
+ * }</pre>
+ *
+ * @hide
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE})
+public @interface StringDef {
+    /** Defines the allowed constants for this element */
+    String[] value() default {};
+}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index c4ddf1f..fbe8987 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -28,6 +31,9 @@
 import android.view.Window;
 import android.widget.SpinnerAdapter;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A window feature at the top of the activity that may display the activity title, navigation
  * modes, and other interactive items.
@@ -57,6 +63,11 @@
  * </div>
  */
 public abstract class ActionBar {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
+    public @interface NavigationMode {}
+
     /**
      * Standard navigation mode. Consists of either a logo or icon
      * and title text with an optional subtitle. Clicking any of these elements
@@ -78,6 +89,19 @@
      */
     public static final int NAVIGATION_MODE_TABS = 2;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            value = {
+                    DISPLAY_USE_LOGO,
+                    DISPLAY_SHOW_HOME,
+                    DISPLAY_HOME_AS_UP,
+                    DISPLAY_SHOW_TITLE,
+                    DISPLAY_SHOW_CUSTOM,
+                    DISPLAY_TITLE_MULTIPLE_LINES
+            })
+    public @interface DisplayOptions {}
+
     /**
      * Use logo instead of icon if available. This flag will cause appropriate
      * navigation modes to use a wider logo in place of the standard icon.
@@ -341,7 +365,7 @@
      * @param options A combination of the bits defined by the DISPLAY_ constants
      *                defined in ActionBar.
      */
-    public abstract void setDisplayOptions(int options);
+    public abstract void setDisplayOptions(@DisplayOptions int options);
     
     /**
      * Set selected display options. Only the options specified by mask will be changed.
@@ -356,7 +380,7 @@
      *                defined in ActionBar.
      * @param mask A bit mask declaring which display options should be changed.
      */
-    public abstract void setDisplayOptions(int options, int mask);
+    public abstract void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask);
 
     /**
      * Set whether to display the activity logo rather than the activity icon.
@@ -431,7 +455,7 @@
      * @see #setStackedBackgroundDrawable(Drawable)
      * @see #setSplitBackgroundDrawable(Drawable)
      */
-    public abstract void setBackgroundDrawable(Drawable d);
+    public abstract void setBackgroundDrawable(@Nullable Drawable d);
 
     /**
      * Set the ActionBar's stacked background. This will appear
@@ -484,6 +508,7 @@
      *
      * @return The current navigation mode.
      */
+    @NavigationMode
     public abstract int getNavigationMode();
 
     /**
@@ -494,7 +519,7 @@
      * @see #NAVIGATION_MODE_LIST
      * @see #NAVIGATION_MODE_TABS
      */
-    public abstract void setNavigationMode(int mode);
+    public abstract void setNavigationMode(@NavigationMode int mode);
 
     /**
      * @return The current set of display options. 
@@ -1024,7 +1049,7 @@
         })
         public int gravity = Gravity.NO_GRAVITY;
 
-        public LayoutParams(Context c, AttributeSet attrs) {
+        public LayoutParams(@NonNull Context c, AttributeSet attrs) {
             super(c, attrs);
 
             TypedArray a = c.obtainStyledAttributes(attrs,
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 63c9fec..e38bbb3 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -16,11 +16,18 @@
 
 package android.app;
 
+import android.annotation.NonNull;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
 import android.util.ArrayMap;
+import android.util.Pair;
 import android.util.SuperNotCalledException;
 import com.android.internal.app.ActionBarImpl;
 import com.android.internal.policy.PolicyManager;
 
+import android.annotation.IntDef;
+import android.annotation.Nullable;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -84,6 +91,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 
@@ -763,6 +772,7 @@
 
     private Thread mUiThread;
     final Handler mHandler = new Handler();
+    private ActivityOptions mTransitionActivityOptions;
 
     /** Return the intent that started this activity. */
     public Intent getIntent() {
@@ -852,6 +862,7 @@
      * @see #getWindow
      * @see android.view.Window#getCurrentFocus
      */
+    @Nullable
     public View getCurrentFocus() {
         return mWindow != null ? mWindow.getCurrentFocus() : null;
     }
@@ -882,7 +893,7 @@
      * @see #onRestoreInstanceState
      * @see #onPostCreate
      */
-    protected void onCreate(Bundle savedInstanceState) {
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
         if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
         if (mLastNonConfigurationInstances != null) {
             mAllLoaderManagers = mLastNonConfigurationInstances.loaders;
@@ -1010,7 +1021,7 @@
      *     recently supplied in {@link #onSaveInstanceState}.  <b><i>Note: Otherwise it is null.</i></b>
      * @see #onCreate
      */
-    protected void onPostCreate(Bundle savedInstanceState) {
+    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
         if (!isChild()) {
             mTitleReady = true;
             onTitleChanged(getTitle(), getTitleColor());
@@ -1021,7 +1032,7 @@
     /**
      * Called after {@link #onCreate} &mdash; or after {@link #onRestart} when  
      * the activity had been stopped, but is now again being displayed to the 
-	 * user.  It will be followed by {@link #onResume}.
+     * user.  It will be followed by {@link #onResume}.
      *
      * <p><em>Derived classes must call through to the super class's
      * implementation of this method.  If they do not, an exception will be
@@ -1347,6 +1358,7 @@
      * @see #onSaveInstanceState
      * @see #onPause
      */
+    @Nullable
     public CharSequence onCreateDescription() {
         return null;
     }
@@ -1551,6 +1563,7 @@
      * {@link Fragment#setRetainInstance(boolean)} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     public Object getLastNonConfigurationInstance() {
         return mLastNonConfigurationInstances != null
@@ -1630,6 +1643,7 @@
      * @return Returns the object previously returned by
      * {@link #onRetainNonConfigurationChildInstances()}
      */
+    @Nullable
     HashMap<String, Object> getLastNonConfigurationChildInstances() {
         return mLastNonConfigurationInstances != null
                 ? mLastNonConfigurationInstances.children : null;
@@ -1642,6 +1656,7 @@
      * set of child activities, such as ActivityGroup.  The same guarantees and restrictions apply
      * as for {@link #onRetainNonConfigurationInstance()}.  The default implementation returns null.
      */
+    @Nullable
     HashMap<String,Object> onRetainNonConfigurationChildInstances() {
         return null;
     }
@@ -1889,6 +1904,7 @@
      *
      * @return The Activity's ActionBar, or null if it does not have one.
      */
+    @Nullable
     public ActionBar getActionBar() {
         initActionBar();
         return mActionBar;
@@ -1979,13 +1995,58 @@
     }
 
     /**
+     * Retrieve the {@link TransitionManager} responsible for default transitions in this window.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return non-null after content has been initialized (e.g. by using
+     * {@link #setContentView}) if {@link Window#FEATURE_CONTENT_TRANSITIONS} has been granted.</p>
+     *
+     * @return This window's content TransitionManager or null if none is set.
+     */
+    public TransitionManager getContentTransitionManager() {
+        return getWindow().getTransitionManager();
+    }
+
+    /**
+     * Set the {@link TransitionManager} to use for default transitions in this window.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * @param tm The TransitionManager to use for scene changes.
+     */
+    public void setContentTransitionManager(TransitionManager tm) {
+        getWindow().setTransitionManager(tm);
+    }
+
+    /**
+     * Retrieve the {@link Scene} representing this window's current content.
+     * Requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return null if the current content is not represented by a Scene.</p>
+     *
+     * @return Current Scene being shown or null
+     */
+    public Scene getContentScene() {
+        return getWindow().getContentScene();
+    }
+
+    /**
      * Sets whether this activity is finished when touched outside its window's
      * bounds.
      */
     public void setFinishOnTouchOutside(boolean finish) {
         mWindow.setCloseOnTouchOutside(finish);
     }
-    
+
+    /** @hide */
+    @IntDef({
+            DEFAULT_KEYS_DISABLE,
+            DEFAULT_KEYS_DIALER,
+            DEFAULT_KEYS_SHORTCUT,
+            DEFAULT_KEYS_SEARCH_LOCAL,
+            DEFAULT_KEYS_SEARCH_GLOBAL})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DefaultKeyMode {}
+
     /**
      * Use with {@link #setDefaultKeyMode} to turn off default handling of
      * keys.
@@ -2055,7 +2116,7 @@
      * @see #DEFAULT_KEYS_SEARCH_GLOBAL
      * @see #onKeyDown
      */
-    public final void setDefaultKeyMode(int mode) {
+    public final void setDefaultKeyMode(@DefaultKeyMode int mode) {
         mDefaultKeyMode = mode;
         
         // Some modes use a SpannableStringBuilder to track & dispatch input events
@@ -2528,6 +2589,7 @@
      * simply returns null so that all panel sub-windows will have the default
      * menu behavior.
      */
+    @Nullable
     public View onCreatePanelView(int featureId) {
         return null;
     }
@@ -3025,6 +3087,7 @@
      * {@link FragmentManager} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     protected Dialog onCreateDialog(int id, Bundle args) {
         return onCreateDialog(id);
@@ -3112,6 +3175,7 @@
      * {@link FragmentManager} instead; this is also
      * available on older platforms through the Android compatibility package.
      */
+    @Nullable
     @Deprecated
     public final boolean showDialog(int id, Bundle args) {
         if (mManagedDialogs == null) {
@@ -3233,13 +3297,13 @@
      * <p>It is typically called from onSearchRequested(), either directly from 
      * Activity.onSearchRequested() or from an overridden version in any given 
      * Activity.  If your goal is simply to activate search, it is preferred to call
-     * onSearchRequested(), which may have been overriden elsewhere in your Activity.  If your goal
+     * onSearchRequested(), which may have been overridden elsewhere in your Activity.  If your goal
      * is to inject specific data such as context data, it is preferred to <i>override</i>
      * onSearchRequested(), so that any callers to it will benefit from the override.
      * 
      * @param initialQuery Any non-null non-empty string will be inserted as 
      * pre-entered text in the search query box.
-     * @param selectInitialQuery If true, the intial query will be preselected, which means that
+     * @param selectInitialQuery If true, the initial query will be preselected, which means that
      * any further typing will replace it.  This is useful for cases where an entire pre-formed
      * query is being inserted.  If false, the selection point will be placed at the end of the
      * inserted query.  This is useful when the inserted query is text that the user entered,
@@ -3257,11 +3321,11 @@
      * @see android.app.SearchManager
      * @see #onSearchRequested
      */
-    public void startSearch(String initialQuery, boolean selectInitialQuery, 
-            Bundle appSearchData, boolean globalSearch) {
+    public void startSearch(@Nullable String initialQuery, boolean selectInitialQuery,
+            @Nullable Bundle appSearchData, boolean globalSearch) {
         ensureSearchManager();
         mSearchManager.startSearch(initialQuery, selectInitialQuery, getComponentName(),
-                        appSearchData, globalSearch); 
+                appSearchData, globalSearch); 
     }
 
     /**
@@ -3274,7 +3338,7 @@
      * searches.  This data will be returned with SEARCH intent(s).  Null if
      * no extra data is required.
      */
-    public void triggerSearch(String query, Bundle appSearchData) {
+    public void triggerSearch(String query, @Nullable Bundle appSearchData) {
         ensureSearchManager();
         mSearchManager.triggerSearch(query, getComponentName(), appSearchData);
     }
@@ -3341,6 +3405,7 @@
      * Convenience for calling
      * {@link android.view.Window#getLayoutInflater}.
      */
+    @NonNull
     public LayoutInflater getLayoutInflater() {
         return getWindow().getLayoutInflater();
     }
@@ -3348,6 +3413,7 @@
     /**
      * Returns a {@link MenuInflater} with this context.
      */
+    @NonNull
     public MenuInflater getMenuInflater() {
         // Make sure that action views can get an appropriate theme.
         if (mMenuInflater == null) {
@@ -3386,16 +3452,21 @@
      *
      * @throws android.content.ActivityNotFoundException
      *
-     * @see #startActivity 
+     * @see #startActivity
      */
     public void startActivityForResult(Intent intent, int requestCode) {
-        startActivityForResult(intent, requestCode, null);
+        Bundle options = null;
+        if (mWindow.hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
+            final Pair<View, String>[] noSharedElements = null;
+            options = ActivityOptions.makeSceneTransitionAnimation(noSharedElements).toBundle();
+        }
+        startActivityForResult(intent, requestCode, options);
     }
 
     /**
      * Launch an activity for which you would like a result when it finished.
      * When this activity exits, your
-     * onActivityResult() method will be called with the given requestCode. 
+     * onActivityResult() method will be called with the given requestCode.
      * Using a negative requestCode is the same as calling 
      * {@link #startActivity} (the activity is not launched as a sub-activity).
      *
@@ -3408,9 +3479,9 @@
      *
      * <p>As a special case, if you call startActivityForResult() with a requestCode 
      * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
-     * activity, then your window will not be displayed until a result is 
-     * returned back from the started activity.  This is to avoid visible 
-     * flickering when redirecting to another activity. 
+     * activity, then your window will not be displayed until a result is
+     * returned back from the started activity.  This is to avoid visible
+     * flickering when redirecting to another activity.
      *
      * <p>This method throws {@link android.content.ActivityNotFoundException}
      * if there was no Activity found to run the given Intent.
@@ -3424,9 +3495,20 @@
      *
      * @throws android.content.ActivityNotFoundException
      *
-     * @see #startActivity 
+     * @see #startActivity
      */
-    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
+    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
+        if (options != null) {
+            ActivityOptions activityOptions = new ActivityOptions(options);
+            if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+                if (mActionBar != null) {
+                    ArrayMap<String, View> sharedElementMap = new ArrayMap<String, View>();
+                    mActionBar.captureSharedElements(sharedElementMap);
+                    activityOptions.addSharedElements(sharedElementMap);
+                }
+                options = mWindow.startExitTransition(activityOptions);
+            }
+        }
         if (mParent == null) {
             Instrumentation.ActivityResult ar =
                 mInstrumentation.execStartActivity(
@@ -3505,7 +3587,7 @@
      * @param extraFlags Always set to 0.
      */
     public void startIntentSenderForResult(IntentSender intent, int requestCode,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
             throws IntentSender.SendIntentException {
         startIntentSenderForResult(intent, requestCode, fillInIntent, flagsMask,
                 flagsValues, extraFlags, null);
@@ -3537,7 +3619,7 @@
      * override any that conflict with those given by the IntentSender.
      */
     public void startIntentSenderForResult(IntentSender intent, int requestCode,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException {
         if (mParent == null) {
             startIntentSenderForResultInner(intent, requestCode, fillInIntent,
@@ -3599,7 +3681,7 @@
      */
     @Override
     public void startActivity(Intent intent) {
-        startActivity(intent, null);
+        this.startActivity(intent, null);
     }
 
     /**
@@ -3625,7 +3707,7 @@
      * @see #startActivityForResult 
      */
     @Override
-    public void startActivity(Intent intent, Bundle options) {
+    public void startActivity(Intent intent, @Nullable Bundle options) {
         if (options != null) {
             startActivityForResult(intent, -1, options);
         } else {
@@ -3674,7 +3756,7 @@
      * @see #startActivityForResult
      */
     @Override
-    public void startActivities(Intent[] intents, Bundle options) {
+    public void startActivities(Intent[] intents, @Nullable Bundle options) {
         mInstrumentation.execStartActivities(this, mMainThread.getApplicationThread(),
                 mToken, this, intents, options);
     }
@@ -3693,7 +3775,7 @@
      * @param extraFlags Always set to 0.
      */
     public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
             throws IntentSender.SendIntentException {
         startIntentSender(intent, fillInIntent, flagsMask, flagsValues,
                 extraFlags, null);
@@ -3720,7 +3802,7 @@
      * override any that conflict with those given by the IntentSender.
      */
     public void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException {
         if (options != null) {
             startIntentSenderForResult(intent, -1, fillInIntent, flagsMask,
@@ -3748,7 +3830,7 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public boolean startActivityIfNeeded(Intent intent, int requestCode) {
+    public boolean startActivityIfNeeded(@NonNull Intent intent, int requestCode) {
         return startActivityIfNeeded(intent, requestCode, null);
     }
 
@@ -3782,7 +3864,8 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public boolean startActivityIfNeeded(Intent intent, int requestCode, Bundle options) {
+    public boolean startActivityIfNeeded(@NonNull Intent intent, int requestCode,
+            @Nullable Bundle options) {
         if (mParent == null) {
             int result = ActivityManager.START_RETURN_INTENT_TO_CALLER;
             try {
@@ -3831,7 +3914,7 @@
      * wasn't.  In general, if true is returned you will then want to call
      * finish() on yourself.
      */
-    public boolean startNextMatchingActivity(Intent intent) {
+    public boolean startNextMatchingActivity(@NonNull Intent intent) {
         return startNextMatchingActivity(intent, null);
     }
 
@@ -3854,7 +3937,7 @@
      * wasn't.  In general, if true is returned you will then want to call
      * finish() on yourself.
      */
-    public boolean startNextMatchingActivity(Intent intent, Bundle options) {
+    public boolean startNextMatchingActivity(@NonNull Intent intent, @Nullable Bundle options) {
         if (mParent == null) {
             try {
                 intent.migrateExtraStreamToClipData();
@@ -3884,7 +3967,7 @@
      * @see #startActivity
      * @see #startActivityForResult
      */
-    public void startActivityFromChild(Activity child, Intent intent,
+    public void startActivityFromChild(@NonNull Activity child, Intent intent,
             int requestCode) {
         startActivityFromChild(child, intent, requestCode, null);
     }
@@ -3908,8 +3991,8 @@
      * @see #startActivity 
      * @see #startActivityForResult 
      */
-    public void startActivityFromChild(Activity child, Intent intent, 
-            int requestCode, Bundle options) {
+    public void startActivityFromChild(@NonNull Activity child, Intent intent,
+            int requestCode, @Nullable Bundle options) {
         Instrumentation.ActivityResult ar =
             mInstrumentation.execStartActivity(
                 this, mMainThread.getApplicationThread(), mToken, child,
@@ -3934,7 +4017,7 @@
      * @see Fragment#startActivity
      * @see Fragment#startActivityForResult
      */
-    public void startActivityFromFragment(Fragment fragment, Intent intent, 
+    public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
             int requestCode) {
         startActivityFromFragment(fragment, intent, requestCode, null);
     }
@@ -3959,8 +4042,8 @@
      * @see Fragment#startActivity 
      * @see Fragment#startActivityForResult 
      */
-    public void startActivityFromFragment(Fragment fragment, Intent intent, 
-            int requestCode, Bundle options) {
+    public void startActivityFromFragment(@NonNull Fragment fragment, Intent intent,
+            int requestCode, @Nullable Bundle options) {
         Instrumentation.ActivityResult ar =
             mInstrumentation.execStartActivity(
                 this, mMainThread.getApplicationThread(), mToken, fragment,
@@ -3992,7 +4075,7 @@
      */
     public void startIntentSenderFromChild(Activity child, IntentSender intent,
             int requestCode, Intent fillInIntent, int flagsMask, int flagsValues,
-            int extraFlags, Bundle options)
+            int extraFlags, @Nullable Bundle options)
             throws IntentSender.SendIntentException {
         startIntentSenderForResultInner(intent, requestCode, fillInIntent,
                 flagsMask, flagsValues, child, options);
@@ -4091,6 +4174,7 @@
      * @return The package of the activity that will receive your
      *         reply, or null if none.
      */
+    @Nullable
     public String getCallingPackage() {
         try {
             return ActivityManagerNative.getDefault().getCallingPackage(mToken);
@@ -4113,6 +4197,7 @@
      * @return The ComponentName of the activity that will receive your
      *         reply, or null if none.
      */
+    @Nullable
     public ComponentName getCallingActivity() {
         try {
             return ActivityManagerNative.getDefault().getCallingActivity(mToken);
@@ -4305,7 +4390,7 @@
      * @param requestCode Request code that had been used to start the
      *                    activity.
      */
-    public void finishActivityFromChild(Activity child, int requestCode) {
+    public void finishActivityFromChild(@NonNull Activity child, int requestCode) {
         try {
             ActivityManagerNative.getDefault()
                 .finishSubActivity(mToken, child.mEmbeddedID, requestCode);
@@ -4366,8 +4451,8 @@
      * 
      * @see PendingIntent
      */
-    public PendingIntent createPendingResult(int requestCode, Intent data,
-            int flags) {
+    public PendingIntent createPendingResult(int requestCode, @NonNull Intent data,
+            @PendingIntent.Flags int flags) {
         String packageName = getPackageName();
         try {
             data.prepareToLeaveProcess();
@@ -4394,7 +4479,7 @@
      * @param requestedOrientation An orientation constant as used in
      * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
      */
-    public void setRequestedOrientation(int requestedOrientation) {
+    public void setRequestedOrientation(@ActivityInfo.ScreenOrientation int requestedOrientation) {
         if (mParent == null) {
             try {
                 ActivityManagerNative.getDefault().setRequestedOrientation(
@@ -4416,6 +4501,7 @@
      * @return Returns an orientation constant as used in
      * {@link ActivityInfo#screenOrientation ActivityInfo.screenOrientation}.
      */
+    @ActivityInfo.ScreenOrientation
     public int getRequestedOrientation() {
         if (mParent == null) {
             try {
@@ -4487,6 +4573,7 @@
      * 
      * @return The local class name.
      */
+    @NonNull
     public String getLocalClassName() {
         final String pkg = getPackageName();
         final String cls = mComponent.getClassName();
@@ -4532,9 +4619,9 @@
         
         mSearchManager = new SearchManager(this, null);
     }
-    
+
     @Override
-    public Object getSystemService(String name) {
+    public Object getSystemService(@ServiceName @NonNull String name) {
         if (getBaseContext() == null) {
             throw new IllegalStateException(
                     "System services not available to Activities before onCreate()");
@@ -4574,6 +4661,17 @@
         setTitle(getText(titleId));
     }
 
+    /**
+     * Change the color of the title associated with this activity.
+     * <p>
+     * This method is deprecated starting in API Level 11 and replaced by action
+     * bar styles. For information on styling the Action Bar, read the <a
+     * href="{@docRoot} guide/topics/ui/actionbar.html">Action Bar</a> developer
+     * guide.
+     *
+     * @deprecated Use action bar styles instead.
+     */
+    @Deprecated
     public void setTitleColor(int textColor) {
         mTitleColor = textColor;
         onTitleChanged(mTitle, textColor);
@@ -4603,6 +4701,47 @@
     }
 
     /**
+     * Set a label to be used in the Recents task display. The activities of a task are traversed
+     * in order from the topmost activity to the bottommost. As soon as one activity returns a
+     * non-null Recents label the traversal is ended and that value will be used in
+     * {@link ActivityManager.RecentTaskInfo#activityLabel}
+     *
+     * @see ActivityManager#getRecentTasks
+     *
+     * @param recentsLabel The label to use in the RecentTaskInfo.
+     */
+    public void setRecentsLabel(CharSequence recentsLabel) {
+        try {
+            ActivityManagerNative.getDefault().setRecentsLabel(mToken, recentsLabel);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Set an icon to be used in the Recents task display. The activities of a task are traversed
+     * in order from the topmost activity to the bottommost. As soon as one activity returns a
+     * non-null Recents icon the traversal is ended and that value will be used in
+     * {@link ActivityManager.RecentTaskInfo#activityIcon}.
+     *
+     * @see ActivityManager#getRecentTasks
+     *
+     * @param recentsIcon The Bitmap to use in the RecentTaskInfo.
+     */
+    public void setRecentsIcon(Bitmap recentsIcon) {
+        final Bitmap scaledIcon;
+        if (recentsIcon != null) {
+            final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
+            scaledIcon = Bitmap.createScaledBitmap(recentsIcon, size, size, true);
+        } else {
+            scaledIcon = null;
+        }
+        try {
+            ActivityManagerNative.getDefault().setRecentsIcon(mToken, scaledIcon);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
      * Sets the visibility of the progress bar in the title.
      * <p>
      * In order for the progress bar to be shown, the feature must be requested
@@ -4639,7 +4778,8 @@
      */
     public final void setProgressBarIndeterminate(boolean indeterminate) {
         getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
-                indeterminate ? Window.PROGRESS_INDETERMINATE_ON : Window.PROGRESS_INDETERMINATE_OFF);
+                indeterminate ? Window.PROGRESS_INDETERMINATE_ON
+                        : Window.PROGRESS_INDETERMINATE_OFF);
     }
     
     /**
@@ -4696,7 +4836,7 @@
 
     /**
      * Gets the suggested audio stream whose volume should be changed by the
-     * harwdare volume controls.
+     * hardware volume controls.
      * 
      * @return The suggested audio stream type whose volume should be changed by
      *         the hardware volume controls.
@@ -4732,6 +4872,7 @@
      * @see android.view.LayoutInflater#createView
      * @see android.view.Window#getLayoutInflater
      */
+    @Nullable
     public View onCreateView(String name, Context context, AttributeSet attrs) {
         return null;
     }
@@ -4990,6 +5131,7 @@
      *
      * @see ActionMode
      */
+    @Nullable
     public ActionMode startActionMode(ActionMode.Callback callback) {
         return mWindow.getDecorView().startActionMode(callback);
     }
@@ -5005,6 +5147,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.)
      */
+    @Nullable
     @Override
     public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
         initActionBar();
@@ -5148,6 +5291,7 @@
      * @return a new Intent targeting the defined parent of this activity or null if
      *         there is no valid parent.
      */
+    @Nullable
     public Intent getParentActivityIntent() {
         final String parentName = mActivityInfo.parentActivityName;
         if (TextUtils.isEmpty(parentName)) {
@@ -5190,6 +5334,16 @@
             CharSequence title, Activity parent, String id,
             NonConfigurationInstances lastNonConfigurationInstances,
             Configuration config) {
+        attach(context, aThread, instr, token, ident, application, intent, info, title, parent, id,
+                lastNonConfigurationInstances, config, null);
+    }
+
+    final void attach(Context context, ActivityThread aThread,
+            Instrumentation instr, IBinder token, int ident,
+            Application application, Intent intent, ActivityInfo info,
+            CharSequence title, Activity parent, String id,
+            NonConfigurationInstances lastNonConfigurationInstances,
+            Configuration config, Bundle options) {
         attachBaseContext(context);
 
         mFragments.attachActivity(this, mContainer, null);
@@ -5204,7 +5358,7 @@
             mWindow.setUiOptions(info.uiOptions);
         }
         mUiThread = Thread.currentThread();
-        
+
         mMainThread = aThread;
         mInstrumentation = instr;
         mToken = token;
@@ -5227,6 +5381,43 @@
         }
         mWindowManager = mWindow.getWindowManager();
         mCurrentConfig = config;
+        mTransitionActivityOptions = null;
+        Window.SceneTransitionListener sceneTransitionListener = null;
+        if (options != null) {
+            ActivityOptions activityOptions = new ActivityOptions(options);
+            if (activityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+                mTransitionActivityOptions = activityOptions;
+                sceneTransitionListener = new Window.SceneTransitionListener() {
+                    @Override
+                    public void nullPendingTransition() {
+                        overridePendingTransition(0, 0);
+                    }
+
+                    @Override
+                    public void convertFromTranslucent() {
+                        Activity.this.convertFromTranslucent();
+                    }
+
+                    @Override
+                    public void convertToTranslucent() {
+                        Activity.this.convertToTranslucent(null);
+                    }
+
+                    @Override
+                    public void sharedElementStart(Transition transition) {
+                        Activity.this.onCaptureSharedElementStart(transition);
+                    }
+
+                    @Override
+                    public void sharedElementEnd() {
+                        Activity.this.onCaptureSharedElementEnd();
+                    }
+                };
+
+            }
+        }
+
+        mWindow.setTransitionOptions(mTransitionActivityOptions, sceneTransitionListener);
     }
 
     /** @hide */
@@ -5240,7 +5431,7 @@
                 com.android.internal.R.styleable.Window_windowNoDisplay, false);
         mFragments.dispatchActivityCreated();
     }
-    
+
     final void performStart() {
         mFragments.noteStateNotSaved();
         mCalled = false;
@@ -5397,7 +5588,7 @@
                     }
                 }
             }
-    
+
             mStopped = true;
         }
         mResumed = false;
@@ -5412,7 +5603,27 @@
             mLoaderManager.doDestroy();
         }
     }
-    
+
+    /**
+     * Called when setting up Activity Scene transitions when the start state for shared
+     * elements has been captured. Override this method to modify the start position of shared
+     * elements for the entry Transition.
+     *
+     * @param transition The <code>Transition</code> being used to change
+     *                   bounds of shared elements in the source Activity to
+     *                   the bounds defined by the entering Scene.
+     */
+    public void onCaptureSharedElementStart(Transition transition) {
+    }
+
+    /**
+     * Called when setting up Activity Scene transitions when the final state for
+     * shared elements state has been captured. Override this method to modify the destination
+     * position of shared elements for the entry Transition.
+     */
+    public void onCaptureSharedElementEnd() {
+    }
+
     /**
      * @hide
      */
@@ -5420,7 +5631,7 @@
         return mResumed;
     }
 
-    void dispatchActivityResult(String who, int requestCode, 
+    void dispatchActivityResult(String who, int requestCode,
         int resultCode, Intent data) {
         if (false) Log.v(
             TAG, "Dispatching result: who=" + who + ", reqCode=" + requestCode
@@ -5436,6 +5647,22 @@
         }
     }
 
+    /** @hide */
+    public void startLockTask() {
+        try {
+            ActivityManagerNative.getDefault().startLockTaskMode(mToken);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /** @hide */
+    public void stopLockTask() {
+        try {
+            ActivityManagerNative.getDefault().stopLockTaskMode();
+        } catch (RemoteException e) {
+        }
+    }
+
     /**
      * 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
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index c877cd3..d386eff 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -155,6 +155,13 @@
     public static final int START_SWITCHES_CANCELED = 4;
 
     /**
+     * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
+     * while in Lock Task Mode.
+     * @hide
+     */
+    public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION = 5;
+
+    /**
      * Flag for IActivityManaqer.startActivity: do special start mode where
      * a new activity is launched only if it is needed.
      * @hide
@@ -502,6 +509,24 @@
          */
         public int stackId;
 
+        /**
+         * The id of the user the task was running as.
+         * @hide
+         */
+        public int userId;
+
+        /**
+         * The label of the highest activity in the task stack to have set a label
+         * {@link Activity#setRecentsLabel}.
+         */
+        public CharSequence activityLabel;
+
+        /**
+         * The Bitmap icon of the highest activity in the task stack to set a Bitmap using
+         * {@link Activity#setRecentsIcon}.
+         */
+        public Bitmap activityIcon;
+
         public RecentTaskInfo() {
         }
 
@@ -523,7 +548,16 @@
             ComponentName.writeToParcel(origActivity, dest);
             TextUtils.writeToParcel(description, dest,
                     Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            TextUtils.writeToParcel(activityLabel, dest,
+                    Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+            if (activityIcon == null) {
+                dest.writeInt(0);
+            } else {
+                dest.writeInt(1);
+                activityIcon.writeToParcel(dest, 0);
+            }
             dest.writeInt(stackId);
+            dest.writeInt(userId);
         }
 
         public void readFromParcel(Parcel source) {
@@ -536,7 +570,10 @@
             }
             origActivity = ComponentName.readFromParcel(source);
             description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+            activityLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+            activityIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
             stackId = source.readInt();
+            userId = source.readInt();
         }
 
         public static final Creator<RecentTaskInfo> CREATOR
@@ -560,7 +597,7 @@
      * {@link android.content.Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag.
      */
     public static final int RECENT_WITH_EXCLUDED = 0x0001;
-    
+
     /**
      * Provides a list that does not contain any
      * recent tasks that currently are not available to the user.
@@ -568,6 +605,13 @@
     public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
 
     /**
+     * Provides a list that also contains recent tasks for user
+     * and related users.
+     * @hide
+     */
+    public static final int RECENT_INCLUDE_RELATED = 0x0004;
+
+    /**
      * Return a list of the tasks that the user has recently launched, with
      * the most recent being first and older ones after in order.
      *
@@ -933,6 +977,16 @@
         }
     }
 
+    /** @hide */
+    public boolean isInHomeStack(int taskId) {
+        try {
+            return ActivityManagerNative.getDefault().isInHomeStack(taskId);
+        } catch (RemoteException e) {
+            // System dead, we will be dead too soon!
+            return false;
+        }
+    }
+
     /**
      * Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
      * activity along with the task, so it is positioned immediately behind
@@ -1938,7 +1992,11 @@
      * @return dimensions of square icons in terms of pixels
      */
     public int getLauncherLargeIconSize() {
-        final Resources res = mContext.getResources();
+        return getLauncherLargeIconSizeInner(mContext);
+    }
+
+    static int getLauncherLargeIconSizeInner(Context context) {
+        final Resources res = context.getResources();
         final int size = res.getDimensionPixelSize(android.R.dimen.app_icon_size);
         final int sw = res.getConfiguration().smallestScreenWidthDp;
 
@@ -2222,4 +2280,35 @@
             e.printStackTrace(pw);
         }
     }
+
+    /**
+     * @hide
+     */
+    public void startLockTaskMode(int taskId) {
+        try {
+            ActivityManagerNative.getDefault().startLockTaskMode(taskId);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void stopLockTaskMode() {
+        try {
+            ActivityManagerNative.getDefault().stopLockTaskMode();
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isInLockTaskMode() {
+        try {
+            return ActivityManagerNative.getDefault().isInLockTaskMode();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 7695ecc..707a038 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -101,9 +101,9 @@
         }
     }
 
-    static public void noteWakeupAlarm(PendingIntent ps) {
+    static public void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg) {
         try {
-            getDefault().noteWakeupAlarm(ps.getTarget());
+            getDefault().noteWakeupAlarm(ps.getTarget(), sourceUid, sourcePkg);
         } catch (RemoteException ex) {
         }
     }
@@ -654,6 +654,15 @@
             return true;
         }
 
+        case IS_IN_HOME_STACK_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int taskId = data.readInt();
+            boolean isInHomeStack = isInHomeStack(taskId);
+            reply.writeNoException();
+            reply.writeInt(isInHomeStack ? 1 : 0);
+            return true;
+        }
+
         case SET_FOCUSED_STACK_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int stackId = data.readInt();
@@ -1258,7 +1267,9 @@
             data.enforceInterface(IActivityManager.descriptor);
             IIntentSender is = IIntentSender.Stub.asInterface(
                     data.readStrongBinder());
-            noteWakeupAlarm(is);
+            int sourceUid = data.readInt();
+            String sourcePkg = data.readString();
+            noteWakeupAlarm(is, sourceUid, sourcePkg);
             reply.writeNoException();
             return true;
         }
@@ -1711,6 +1722,15 @@
             return true;
         }
 
+        case START_USER_IN_BACKGROUND_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            int userid = data.readInt();
+            boolean result = startUserInBackground(userid);
+            reply.writeNoException();
+            reply.writeInt(result ? 1 : 0);
+            return true;
+        }
+
         case STOP_USER_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int userid = data.readInt();
@@ -1841,6 +1861,17 @@
             return true;
         }
 
+        case GET_TAG_FOR_INTENT_SENDER_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IIntentSender r = IIntentSender.Stub.asInterface(
+                data.readStrongBinder());
+            String prefix = data.readString();
+            String tag = getTagForIntentSender(r, prefix);
+            reply.writeNoException();
+            reply.writeString(tag);
+            return true;
+        }
+
         case UPDATE_PERSISTENT_CONFIGURATION_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             Configuration config = Configuration.CREATOR.createFromParcel(data);
@@ -2066,6 +2097,56 @@
             reply.writeStrongBinder(homeActivityToken);
             return true;
         }
+
+        case START_LOCK_TASK_BY_TASK_ID_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final int taskId = data.readInt();
+            startLockTaskMode(taskId);
+            reply.writeNoException();
+            return true;
+        }
+
+        case START_LOCK_TASK_BY_TOKEN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            startLockTaskMode(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case STOP_LOCK_TASK_MODE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            stopLockTaskMode();
+            reply.writeNoException();
+            return true;
+        }
+
+        case IS_IN_LOCK_TASK_MODE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final boolean isInLockTaskMode = isInLockTaskMode();
+            reply.writeNoException();
+            reply.writeInt(isInLockTaskMode ? 1 : 0);
+            return true;
+        }
+
+        case SET_RECENTS_LABEL_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            CharSequence recentsLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data);
+            setRecentsLabel(token, recentsLabel);
+            reply.writeNoException();
+            return true;
+        }
+
+        case SET_RECENTS_ICON_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            Bitmap recentsIcon = data.readInt() != 0
+                    ? Bitmap.CREATOR.createFromParcel(data) : null;
+            setRecentsIcon(token, recentsIcon);
+            reply.writeNoException();
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -2811,6 +2892,19 @@
         return info;
     }
     @Override
+    public boolean isInHomeStack(int taskId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        mRemote.transact(IS_IN_HOME_STACK_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean isInHomeStack = reply.readInt() > 0;
+        data.recycle();
+        reply.recycle();
+        return isInHomeStack;
+    }
+    @Override
     public void setFocusedStack(int stackId) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -3660,10 +3754,13 @@
         mRemote.transact(ENTER_SAFE_MODE_TRANSACTION, data, null, 0);
         data.recycle();
     }
-    public void noteWakeupAlarm(IIntentSender sender) throws RemoteException {
+    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
-        data.writeStrongBinder(sender.asBinder());
         data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(sender.asBinder());
+        data.writeInt(sourceUid);
+        data.writeString(sourcePkg);
         mRemote.transact(NOTE_WAKEUP_ALARM_TRANSACTION, data, null, 0);
         data.recycle();
     }
@@ -4288,6 +4385,19 @@
         return result;
     }
 
+    public boolean startUserInBackground(int userid) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(userid);
+        mRemote.transact(START_USER_IN_BACKGROUND_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean result = reply.readInt() != 0;
+        reply.recycle();
+        data.recycle();
+        return result;
+    }
+
     public int stopUser(int userid, IStopUserCallback callback) throws RemoteException {
         Parcel data = Parcel.obtain();
         Parcel reply = Parcel.obtain();
@@ -4430,6 +4540,21 @@
         return res;
     }
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(sender.asBinder());
+        data.writeString(prefix);
+        mRemote.transact(GET_TAG_FOR_INTENT_SENDER_TRANSACTION, data, reply, 0);
+        reply.readException();
+        String res = reply.readString();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException
     {
         Parcel data = Parcel.obtain();
@@ -4745,5 +4870,84 @@
         return res;
     }
 
+    @Override
+    public void startLockTaskMode(int taskId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        mRemote.transact(START_LOCK_TASK_BY_TASK_ID_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void startLockTaskMode(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(START_LOCK_TASK_BY_TOKEN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void stopLockTaskMode() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(STOP_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public boolean isInLockTaskMode() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(IS_IN_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean isInLockTaskMode = reply.readInt() == 1;
+        data.recycle();
+        reply.recycle();
+        return isInLockTaskMode;
+    }
+
+    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        TextUtils.writeToParcel(recentsLabel, data, 0);
+        mRemote.transact(SET_RECENTS_LABEL_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    public void setRecentsIcon(IBinder token, Bitmap recentsBitmap) throws RemoteException
+    {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        if (recentsBitmap != null) {
+            data.writeInt(1);
+            recentsBitmap.writeToParcel(data, 0);
+        } else {
+            data.writeInt(0);
+        }
+        mRemote.transact(SET_RECENTS_ICON_TRANSACTION, data, reply, IBinder.FLAG_ONEWAY);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 87b1e24..07247ff 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -22,14 +22,22 @@
 import android.os.Handler;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
+import android.transition.Transition;
+import android.util.Log;
+import android.util.Pair;
 import android.view.View;
 
+import java.util.ArrayList;
+import java.util.Map;
+
 /**
  * Helper class for building an options Bundle that can be used with
  * {@link android.content.Context#startActivity(android.content.Intent, android.os.Bundle)
  * Context.startActivity(Intent, Bundle)} and related methods.
  */
 public class ActivityOptions {
+    private static final String TAG = "ActivityOptions";
+
     /**
      * The package name that created the options.
      * @hide
@@ -90,6 +98,31 @@
      */
     public static final String KEY_ANIM_START_LISTENER = "android:animStartListener";
 
+    /**
+     * For Activity transitions, the calling Activity's TransitionListener used to
+     * notify the called Activity when the shared element and the exit transitions
+     * complete.
+     */
+    private static final String KEY_TRANSITION_COMPLETE_LISTENER
+            = "android:transitionCompleteListener";
+
+    /**
+     * For Activity transitions, the called Activity's listener to receive calls
+     * when transitions complete.
+     */
+    private static final String KEY_TRANSITION_TARGET_LISTENER = "android:transitionTargetListener";
+
+    /**
+     * The names of shared elements that are transitioned to the started Activity.
+     * This is also the name of shared elements that the started Activity accepted.
+     */
+    private static final String KEY_SHARED_ELEMENT_NAMES = "android:shared_element_names";
+
+    /**
+     * The shared elements names of the views in the calling Activity.
+     */
+    private static final String KEY_LOCAL_ELEMENT_NAMES = "android:local_element_names";
+
     /** @hide */
     public static final int ANIM_NONE = 0;
     /** @hide */
@@ -100,6 +133,8 @@
     public static final int ANIM_THUMBNAIL_SCALE_UP = 3;
     /** @hide */
     public static final int ANIM_THUMBNAIL_SCALE_DOWN = 4;
+    /** @hide */
+    public static final int ANIM_SCENE_TRANSITION = 5;
 
     private String mPackageName;
     private int mAnimationType = ANIM_NONE;
@@ -111,6 +146,9 @@
     private int mStartWidth;
     private int mStartHeight;
     private IRemoteCallback mAnimationStartedListener;
+    private IRemoteCallback mTransitionCompleteListener;
+    private ArrayList<String> mSharedElementNames;
+    private ArrayList<String> mLocalElementNames;
 
     /**
      * Create an ActivityOptions specifying a custom animation to run when
@@ -156,11 +194,12 @@
         opts.mAnimationType = ANIM_CUSTOM;
         opts.mCustomEnterResId = enterResId;
         opts.mCustomExitResId = exitResId;
-        opts.setListener(handler, listener);
+        opts.setOnAnimationStartedListener(handler, listener);
         return opts;
     }
 
-    private void setListener(Handler handler, OnAnimationStartedListener listener) {
+    private void setOnAnimationStartedListener(Handler handler,
+            OnAnimationStartedListener listener) {
         if (listener != null) {
             final Handler h = handler;
             final OnAnimationStartedListener finalListener = listener;
@@ -185,6 +224,12 @@
         void onAnimationStarted();
     }
 
+    /** @hide */
+    public interface ActivityTransitionTarget {
+        void sharedElementTransitionComplete(Bundle transitionArgs);
+        void exitTransitionComplete();
+    }
+
     /**
      * Create an ActivityOptions specifying an animation where the new
      * activity is scaled from a small originating area of the screen to
@@ -298,7 +343,56 @@
         source.getLocationOnScreen(pts);
         opts.mStartX = pts[0] + startX;
         opts.mStartY = pts[1] + startY;
-        opts.setListener(source.getHandler(), listener);
+        opts.setOnAnimationStartedListener(source.getHandler(), listener);
+        return opts;
+    }
+
+    /**
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of one shared element to the started Activity.
+     *
+     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
+     * enabled on the calling Activity to cause an exit transition. The same must be in
+     * the called Activity to get an entering transition.</p>
+     * @param sharedElement The View to transition to the started Activity. sharedElement must
+     *                      have a non-null sharedElementName.
+     * @param sharedElementName The shared element name as used in the target Activity. This may
+     *                          be null if it has the same name as sharedElement.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
+     */
+    public static ActivityOptions makeSceneTransitionAnimation(View sharedElement,
+            String sharedElementName) {
+        return makeSceneTransitionAnimation(
+                new Pair<View, String>(sharedElement, sharedElementName));
+    }
+
+    /**
+     * Create an ActivityOptions to transition between Activities using cross-Activity scene
+     * animations. This method carries the position of multiple shared elements to the started
+     * Activity.
+     *
+     * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
+     * enabled on the calling Activity to cause an exit transition. The same must be in
+     * the called Activity to get an entering transition.</p>
+     * @param sharedElements The View to transition to the started Activity along with the
+     *                       shared element name as used in the started Activity. The view
+     *                       must have a non-null sharedElementName.
+     * @return Returns a new ActivityOptions object that you can use to
+     *         supply these options as the options Bundle when starting an activity.
+     */
+    public static ActivityOptions makeSceneTransitionAnimation(
+            Pair<View, String>... sharedElements) {
+        ActivityOptions opts = new ActivityOptions();
+        opts.mAnimationType = ANIM_SCENE_TRANSITION;
+        opts.mSharedElementNames = new ArrayList<String>();
+        opts.mLocalElementNames = new ArrayList<String>();
+
+        if (sharedElements != null) {
+            for (Pair<View, String> sharedElement : sharedElements) {
+                opts.addSharedElement(sharedElement.first, sharedElement.second);
+            }
+        }
         return opts;
     }
 
@@ -309,23 +403,36 @@
     public ActivityOptions(Bundle opts) {
         mPackageName = opts.getString(KEY_PACKAGE_NAME);
         mAnimationType = opts.getInt(KEY_ANIM_TYPE);
-        if (mAnimationType == ANIM_CUSTOM) {
-            mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
-            mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
-            mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
-                    opts.getIBinder(KEY_ANIM_START_LISTENER));
-        } else if (mAnimationType == ANIM_SCALE_UP) {
-            mStartX = opts.getInt(KEY_ANIM_START_X, 0);
-            mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
-            mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
-            mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
-        } else if (mAnimationType == ANIM_THUMBNAIL_SCALE_UP ||
-                mAnimationType == ANIM_THUMBNAIL_SCALE_DOWN) {
-            mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
-            mStartX = opts.getInt(KEY_ANIM_START_X, 0);
-            mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
-            mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
-                    opts.getIBinder(KEY_ANIM_START_LISTENER));
+        switch (mAnimationType) {
+            case ANIM_CUSTOM:
+                mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0);
+                mCustomExitResId = opts.getInt(KEY_ANIM_EXIT_RES_ID, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_SCALE_UP:
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
+                mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
+                break;
+
+            case ANIM_THUMBNAIL_SCALE_UP:
+            case ANIM_THUMBNAIL_SCALE_DOWN:
+                mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
+                mStartX = opts.getInt(KEY_ANIM_START_X, 0);
+                mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
+                mAnimationStartedListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_ANIM_START_LISTENER));
+                break;
+
+            case ANIM_SCENE_TRANSITION:
+                mTransitionCompleteListener = IRemoteCallback.Stub.asInterface(
+                        opts.getBinder(KEY_TRANSITION_COMPLETE_LISTENER));
+                mSharedElementNames = opts.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
+                mLocalElementNames = opts.getStringArrayList(KEY_LOCAL_ELEMENT_NAMES);
+                break;
         }
     }
 
@@ -380,6 +487,54 @@
     }
 
     /** @hide */
+    public ArrayList<String> getSharedElementNames() { return mSharedElementNames; }
+
+    /** @hide */
+    public ArrayList<String> getLocalElementNames() { return mLocalElementNames; }
+
+    /** @hide */
+    public void dispatchSceneTransitionStarted(final ActivityTransitionTarget target,
+            ArrayList<String> sharedElementNames) {
+        boolean listenerSent = false;
+        if (mTransitionCompleteListener != null) {
+            IRemoteCallback callback = new IRemoteCallback.Stub() {
+                @Override
+                public void sendResult(Bundle data) throws RemoteException {
+                    if (data == null) {
+                        target.exitTransitionComplete();
+                    } else {
+                        target.sharedElementTransitionComplete(data);
+                    }
+                }
+            };
+            Bundle bundle = new Bundle();
+            bundle.putBinder(KEY_TRANSITION_TARGET_LISTENER, callback.asBinder());
+            bundle.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, sharedElementNames);
+            try {
+                mTransitionCompleteListener.sendResult(bundle);
+                listenerSent = true;
+            } catch (RemoteException e) {
+                Log.w(TAG, "Couldn't retrieve transition notifications", e);
+            }
+        }
+        if (!listenerSent) {
+            target.sharedElementTransitionComplete(null);
+            target.exitTransitionComplete();
+        }
+    }
+
+    /** @hide */
+    public void dispatchSharedElementsReady() {
+        if (mTransitionCompleteListener != null) {
+            try {
+                mTransitionCompleteListener.sendResult(null);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Couldn't synchronize shared elements", e);
+            }
+        }
+    }
+
+    /** @hide */
     public void abort() {
         if (mAnimationStartedListener != null) {
             try {
@@ -405,19 +560,22 @@
         if (otherOptions.mPackageName != null) {
             mPackageName = otherOptions.mPackageName;
         }
+        mSharedElementNames = null;
+        mLocalElementNames = null;
         switch (otherOptions.mAnimationType) {
             case ANIM_CUSTOM:
                 mAnimationType = otherOptions.mAnimationType;
                 mCustomEnterResId = otherOptions.mCustomEnterResId;
                 mCustomExitResId = otherOptions.mCustomExitResId;
                 mThumbnail = null;
-                if (otherOptions.mAnimationStartedListener != null) {
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
+                mTransitionCompleteListener = null;
                 break;
             case ANIM_SCALE_UP:
                 mAnimationType = otherOptions.mAnimationType;
@@ -425,13 +583,14 @@
                 mStartY = otherOptions.mStartY;
                 mStartWidth = otherOptions.mStartWidth;
                 mStartHeight = otherOptions.mStartHeight;
-                if (otherOptions.mAnimationStartedListener != null) {
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = null;
+                mTransitionCompleteListener = null;
                 break;
             case ANIM_THUMBNAIL_SCALE_UP:
             case ANIM_THUMBNAIL_SCALE_DOWN:
@@ -439,13 +598,22 @@
                 mThumbnail = otherOptions.mThumbnail;
                 mStartX = otherOptions.mStartX;
                 mStartY = otherOptions.mStartY;
-                if (otherOptions.mAnimationStartedListener != null) {
+                if (mAnimationStartedListener != null) {
                     try {
-                        otherOptions.mAnimationStartedListener.sendResult(null);
+                        mAnimationStartedListener.sendResult(null);
                     } catch (RemoteException e) {
                     }
                 }
                 mAnimationStartedListener = otherOptions.mAnimationStartedListener;
+                mTransitionCompleteListener = null;
+                break;
+            case ANIM_SCENE_TRANSITION:
+                mAnimationType = otherOptions.mAnimationType;
+                mTransitionCompleteListener = otherOptions.mTransitionCompleteListener;
+                mThumbnail = null;
+                mAnimationStartedListener = null;
+                mSharedElementNames = otherOptions.mSharedElementNames;
+                mLocalElementNames = otherOptions.mLocalElementNames;
                 break;
         }
     }
@@ -468,7 +636,7 @@
                 b.putInt(KEY_ANIM_TYPE, mAnimationType);
                 b.putInt(KEY_ANIM_ENTER_RES_ID, mCustomEnterResId);
                 b.putInt(KEY_ANIM_EXIT_RES_ID, mCustomExitResId);
-                b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                         != null ? mAnimationStartedListener.asBinder() : null);
                 break;
             case ANIM_SCALE_UP:
@@ -484,10 +652,151 @@
                 b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
                 b.putInt(KEY_ANIM_START_X, mStartX);
                 b.putInt(KEY_ANIM_START_Y, mStartY);
-                b.putIBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
+                b.putBinder(KEY_ANIM_START_LISTENER, mAnimationStartedListener
                         != null ? mAnimationStartedListener.asBinder() : null);
                 break;
+            case ANIM_SCENE_TRANSITION:
+                b.putInt(KEY_ANIM_TYPE, mAnimationType);
+                if (mTransitionCompleteListener != null) {
+                    b.putBinder(KEY_TRANSITION_COMPLETE_LISTENER,
+                            mTransitionCompleteListener.asBinder());
+                }
+                b.putStringArrayList(KEY_SHARED_ELEMENT_NAMES, mSharedElementNames);
+                b.putStringArrayList(KEY_LOCAL_ELEMENT_NAMES, mLocalElementNames);
+                break;
         }
         return b;
     }
+
+    /**
+     * Return the filtered options only meant to be seen by the target activity itself
+     * @hide
+     */
+    public ActivityOptions forTargetActivity() {
+        if (mAnimationType == ANIM_SCENE_TRANSITION) {
+            final ActivityOptions result = new ActivityOptions();
+            result.update(this);
+            return result;
+        }
+
+        return null;
+    }
+
+    /** @hide */
+    public void addSharedElements(Map<String, View> sharedElements) {
+        for (Map.Entry<String, View> entry : sharedElements.entrySet()) {
+            addSharedElement(entry.getValue(), entry.getKey());
+        }
+    }
+
+    /** @hide */
+    public void updateSceneTransitionAnimation(Transition exitTransition,
+            Transition sharedElementTransition, SharedElementSource sharedElementSource) {
+        mTransitionCompleteListener = new ExitTransitionListener(exitTransition,
+                sharedElementTransition, sharedElementSource);
+    }
+
+    private void addSharedElement(View view, String name) {
+        String sharedElementName = view.getSharedElementName();
+        if (name == null) {
+            name = sharedElementName;
+        }
+        mSharedElementNames.add(name);
+        mLocalElementNames.add(sharedElementName);
+    }
+
+    /** @hide */
+    public interface SharedElementSource {
+        Bundle getSharedElementExitState();
+        void acceptedSharedElements(ArrayList<String> sharedElementNames);
+        void hideSharedElements();
+    }
+
+    private static class ExitTransitionListener extends IRemoteCallback.Stub
+            implements Transition.TransitionListener {
+        private boolean mSharedElementNotified;
+        private Transition mExitTransition;
+        private Transition mSharedElementTransition;
+        private IRemoteCallback mTransitionCompleteCallback;
+        private boolean mExitComplete;
+        private boolean mSharedElementComplete;
+        private SharedElementSource mSharedElementSource;
+
+        public ExitTransitionListener(Transition exitTransition, Transition sharedElementTransition,
+                SharedElementSource sharedElementSource) {
+            mSharedElementSource = sharedElementSource;
+            mExitTransition = exitTransition;
+            mExitTransition.addListener(this);
+            mSharedElementTransition = sharedElementTransition;
+            mSharedElementTransition.addListener(this);
+        }
+
+        @Override
+        public void sendResult(Bundle data) throws RemoteException {
+            if (data != null) {
+                mTransitionCompleteCallback = IRemoteCallback.Stub.asInterface(
+                        data.getBinder(KEY_TRANSITION_TARGET_LISTENER));
+                ArrayList<String> sharedElementNames
+                        = data.getStringArrayList(KEY_SHARED_ELEMENT_NAMES);
+                mSharedElementSource.acceptedSharedElements(sharedElementNames);
+                notifySharedElement();
+                notifyExit();
+            } else {
+                mSharedElementSource.hideSharedElements();
+            }
+        }
+
+        @Override
+        public void onTransitionStart(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionEnd(Transition transition) {
+            if (transition == mExitTransition) {
+                mExitComplete = true;
+                notifyExit();
+                mExitTransition.removeListener(this);
+            } else {
+                mSharedElementComplete = true;
+                notifySharedElement();
+                mSharedElementTransition.removeListener(this);
+            }
+        }
+
+        @Override
+        public void onTransitionCancel(Transition transition) {
+            onTransitionEnd(transition);
+        }
+
+        @Override
+        public void onTransitionPause(Transition transition) {
+        }
+
+        @Override
+        public void onTransitionResume(Transition transition) {
+        }
+
+        private void notifySharedElement() {
+            if (!mSharedElementNotified && mSharedElementComplete
+                    && mTransitionCompleteCallback != null) {
+                mSharedElementNotified = true;
+                try {
+                    Bundle sharedElementState = mSharedElementSource.getSharedElementExitState();
+                    mTransitionCompleteCallback.sendResult(sharedElementState);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Couldn't notify that the transition ended", e);
+                }
+            }
+        }
+
+        private void notifyExit() {
+            if (mExitComplete && mTransitionCompleteCallback != null) {
+                try {
+                    mTransitionCompleteCallback.sendResult(null);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Couldn't notify that the transition ended", e);
+                }
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7f8dbba..69ada6a 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -56,6 +56,7 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IRemoteCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
@@ -68,6 +69,8 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.transition.Scene;
+import android.transition.TransitionManager;
 import android.provider.Settings;
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
@@ -75,6 +78,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.LogPrinter;
+import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
 import android.util.SuperNotCalledException;
@@ -289,6 +293,7 @@
         boolean isForward;
         int pendingConfigChanges;
         boolean onlyLocalRequest;
+        Bundle activityOptions;
 
         View mPendingRemoveWindow;
         WindowManager mPendingRemoveWindowManager;
@@ -581,9 +586,10 @@
         }
 
         public final void scheduleResumeActivity(IBinder token, int processState,
-                boolean isForward) {
+                boolean isForward, Bundle resumeArgs) {
             updateProcessState(processState, false);
-            sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
+            sendMessage(H.RESUME_ACTIVITY, new Pair<IBinder, Bundle>(token, resumeArgs),
+                    isForward ? 1 : 0);
         }
 
         public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
@@ -599,7 +605,8 @@
                 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
                 int procState, Bundle state, List<ResultInfo> pendingResults,
                 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
+                String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler,
+                Bundle resumeArgs) {
 
             updateProcessState(procState, false);
 
@@ -621,6 +628,7 @@
             r.profileFile = profileName;
             r.profileFd = profileFd;
             r.autoStopProfiler = autoStopProfiler;
+            r.activityOptions = resumeArgs;
 
             updatePendingConfiguration(curConfig);
 
@@ -1244,7 +1252,7 @@
             switch (msg.what) {
                 case LAUNCH_ACTIVITY: {
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
-                    ActivityClientRecord r = (ActivityClientRecord)msg.obj;
+                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
 
                     r.packageInfo = getPackageInfoNoCheck(
                             r.activityInfo.applicationInfo, r.compatInfo);
@@ -1290,7 +1298,8 @@
                     break;
                 case RESUME_ACTIVITY:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
-                    handleResumeActivity((IBinder)msg.obj, true,
+                    final Pair<IBinder, Bundle> resumeArgs = (Pair<IBinder, Bundle>) msg.obj;
+                    handleResumeActivity(resumeArgs.first, resumeArgs.second, true,
                             msg.arg1 != 0, true);
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
@@ -2076,7 +2085,7 @@
                     + ", comp=" + name
                     + ", token=" + token);
         }
-        return performLaunchActivity(r, null);
+        return performLaunchActivity(r, null, null);
     }
 
     public final Activity getActivity(IBinder token) {
@@ -2129,7 +2138,8 @@
         sendMessage(H.CLEAN_UP_CONTEXT, cci);
     }
 
-    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
+    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent,
+            Bundle options) {
         // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
 
         ActivityInfo aInfo = r.activityInfo;
@@ -2187,7 +2197,7 @@
                         + r.activityInfo.name + " with config " + config);
                 activity.attach(appContext, this, getInstrumentation(), r.token,
                         r.ident, app, r.intent, r.activityInfo, title, r.parent,
-                        r.embeddedID, r.lastNonConfigurationInstances, config);
+                        r.embeddedID, r.lastNonConfigurationInstances, config, options);
 
                 if (customIntent != null) {
                     activity.mIntent = customIntent;
@@ -2297,12 +2307,13 @@
 
         if (localLOGV) Slog.v(
             TAG, "Handling launch of " + r);
-        Activity a = performLaunchActivity(r, customIntent);
+
+        Activity a = performLaunchActivity(r, customIntent, r.activityOptions);
 
         if (a != null) {
             r.createdConfig = new Configuration(mConfiguration);
             Bundle oldState = r.state;
-            handleResumeActivity(r.token, false, r.isForward,
+            handleResumeActivity(r.token, r.activityOptions, false, r.isForward,
                     !r.activity.mFinished && !r.startsNotResumed);
 
             if (!r.activity.mFinished && r.startsNotResumed) {
@@ -2861,12 +2872,13 @@
         r.mPendingRemoveWindowManager = null;
     }
 
-    final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
-            boolean reallyResume) {
+    final void handleResumeActivity(IBinder token, Bundle resumeArgs,
+            boolean clearHide, boolean isForward, boolean reallyResume) {
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
 
+        // TODO Push resumeArgs into the activity for consideration
         ActivityClientRecord r = performResumeActivity(token, clearHide);
 
         if (r != null) {
@@ -2991,11 +3003,17 @@
                 int h;
                 if (w < 0) {
                     Resources res = r.activity.getResources();
-                    mThumbnailHeight = h =
-                        res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
-
-                    mThumbnailWidth = w =
-                        res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
+                    if (SystemProperties.getBoolean("persist.recents.use_alternate", false)) {
+                        int wId = com.android.internal.R.dimen.recents_thumbnail_width;
+                        int hId = com.android.internal.R.dimen.recents_thumbnail_height;
+                        mThumbnailWidth = w = res.getDimensionPixelSize(wId);
+                        mThumbnailHeight = h = res.getDimensionPixelSize(hId);
+                    } else {
+                        mThumbnailHeight = h =
+                            res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
+                        mThumbnailWidth = w =
+                            res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
+                    }
                 } else {
                     h = mThumbnailHeight;
                 }
@@ -3787,6 +3805,7 @@
             }
         }
         r.startsNotResumed = tmp.startsNotResumed;
+        r.activityOptions = null;
 
         handleLaunchActivity(r, currentIntent);
     }
@@ -3964,6 +3983,7 @@
         ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
 
         // Cleanup hardware accelerated stuff
+        // TODO: Do we actually want to do this in response to all config changes?
         WindowManagerGlobal.getInstance().trimLocalMemory();
 
         freeTextLayoutCachesIfNeeded(configDiff);
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index 10d5e25..ab148a9 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -27,7 +27,6 @@
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.AdapterView;
@@ -147,10 +146,10 @@
     }
 
     /**
-     * Gets one of the buttons used in the dialog.
-     * <p>
-     * If a button does not exist in the dialog, null will be returned.
-     * 
+     * Gets one of the buttons used in the dialog. Returns null if the specified
+     * button does not exist or the dialog has not yet been fully created (for
+     * example, via {@link #show()} or {@link #create()}).
+     *
      * @param whichButton The identifier of the button that should be returned.
      *            For example, this can be
      *            {@link DialogInterface#BUTTON_POSITIVE}.
@@ -159,7 +158,7 @@
     public Button getButton(int whichButton) {
         return mAlert.getButton(whichButton);
     }
-    
+
     /**
      * Gets the list view used in the dialog.
      *  
@@ -853,6 +852,21 @@
         }
         
         /**
+         * Set a custom view resource to be the contents of the Dialog. The
+         * resource will be inflated, adding all top-level views to the screen.
+         *
+         * @param layoutResId Resource ID to be inflated.
+         * @return This Builder object to allow for chaining of calls to set
+         *         methods
+         */
+        public Builder setView(int layoutResId) {
+            P.mView = null;
+            P.mViewLayoutResId = layoutResId;
+            P.mViewSpacingSpecified = false;
+            return this;
+        }
+
+        /**
          * Set a custom view to be the contents of the Dialog. If the supplied view is an instance
          * of a {@link ListView} the light background will be used.
          *
@@ -862,6 +876,7 @@
          */
         public Builder setView(View view) {
             P.mView = view;
+            P.mViewLayoutResId = 0;
             P.mViewSpacingSpecified = false;
             return this;
         }
@@ -891,6 +906,7 @@
         public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,
                 int viewSpacingRight, int viewSpacingBottom) {
             P.mView = view;
+            P.mViewLayoutResId = 0;
             P.mViewSpacingSpecified = true;
             P.mViewSpacingLeft = viewSpacingLeft;
             P.mViewSpacingTop = viewSpacingTop;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 079cf7a..b616c1e 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -780,6 +780,25 @@
         }
     }
 
+    /**
+     * Set a non-persisted restriction on an audio operation at a stream-level.
+     * Restrictions are temporary additional constraints imposed on top of the persisted rules
+     * defined by {@link #setMode}.
+     *
+     * @param code The operation to restrict.
+     * @param stream The {@link android.media.AudioManager} stream type.
+     * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
+     * @param exceptionPackages Optional list of packages to exclude from the restriction.
+     * @hide
+     */
+    public void setRestriction(int code, int stream, int mode, String[] exceptionPackages) {
+        try {
+            final int uid = Binder.getCallingUid();
+            mService.setAudioRestriction(code, stream, uid, mode, exceptionPackages);
+        } catch (RemoteException e) {
+        }
+    }
+
     /** @hide */
     public void resetAllModes() {
         try {
@@ -1009,6 +1028,35 @@
     }
 
     /**
+     * Like {@link #checkOp} but at a stream-level for audio operations.
+     * @hide
+     */
+    public int checkAudioOp(int op, int stream, int uid, String packageName) {
+        try {
+            final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
+            if (mode == MODE_ERRORED) {
+                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
+            }
+            return mode;
+        } catch (RemoteException e) {
+        }
+        return MODE_IGNORED;
+    }
+
+    /**
+     * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
+     * returns {@link #MODE_ERRORED}.
+     * @hide
+     */
+    public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
+        try {
+            return mService.checkAudioOperation(op, stream, uid, packageName);
+        } catch (RemoteException e) {
+        }
+        return MODE_IGNORED;
+    }
+
+    /**
      * 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
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index c117486..8b132e0 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -24,7 +24,6 @@
 import android.content.pm.ResolveInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Printer;
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 4ddabd9..8165fa1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -57,8 +57,6 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 
 /*package*/
@@ -1094,7 +1092,7 @@
     }
 
     @Override
-	  public void installPackageWithVerificationAndEncryption(Uri packageURI,
+    public void installPackageWithVerificationAndEncryption(Uri packageURI,
             IPackageInstallObserver observer, int flags, String installerPackageName,
             VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
         try {
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index cb453e2..f1c632e 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -113,7 +113,8 @@
             IBinder b = data.readStrongBinder();
             int procState = data.readInt();
             boolean isForward = data.readInt() != 0;
-            scheduleResumeActivity(b, procState, isForward);
+            Bundle resumeArgs = data.readBundle();
+            scheduleResumeActivity(b, procState, isForward, resumeArgs);
             return true;
         }
         
@@ -145,8 +146,10 @@
             ParcelFileDescriptor profileFd = data.readInt() != 0
                     ? ParcelFileDescriptor.CREATOR.createFromParcel(data) : null;
             boolean autoStopProfiler = data.readInt() != 0;
+            Bundle resumeArgs = data.readBundle();
             scheduleLaunchActivity(intent, b, ident, info, curConfig, compatInfo, procState, state,
-                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler);
+                    ri, pi, notResumed, isForward, profileName, profileFd, autoStopProfiler,
+                    resumeArgs);
             return true;
         }
         
@@ -705,20 +708,22 @@
         data.recycle();
     }
 
-    public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
+    public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
+            Bundle resumeArgs)
             throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
         data.writeInt(procState);
         data.writeInt(isForward ? 1 : 0);
+        data.writeBundle(resumeArgs);
         mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
     }
 
     public final void scheduleSendResult(IBinder token, List<ResultInfo> results)
-    		throws RemoteException {
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
@@ -731,9 +736,10 @@
     public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
             ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
             int procState, Bundle state, List<ResultInfo> pendingResults,
-    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
-    		throws RemoteException {
+            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+            String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler,
+            Bundle resumeArgs)
+            throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         intent.writeToParcel(data, 0);
@@ -756,6 +762,7 @@
             data.writeInt(0);
         }
         data.writeInt(autoStopProfiler ? 1 : 0);
+        data.writeBundle(resumeArgs);
         mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                 IBinder.FLAG_ONEWAY);
         data.recycle();
@@ -886,7 +893,7 @@
     }
 
     public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-	    int flags, Intent args) throws RemoteException {
+            int flags, Intent args) throws RemoteException {
         Parcel data = Parcel.obtain();
         data.writeInterfaceToken(IApplicationThread.descriptor);
         data.writeStrongBinder(token);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 924d656..87f47a1 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.os.Build;
+
 import com.android.internal.policy.PolicyManager;
 import com.android.internal.util.Preconditions;
 
@@ -64,6 +65,7 @@
 import android.location.LocationManager;
 import android.media.AudioManager;
 import android.media.MediaRouter;
+import android.media.session.MediaSessionManager;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
 import android.net.INetworkPolicyManager;
@@ -604,6 +606,12 @@
             public Object createService(ContextImpl ctx) {
                 return new ConsumerIrManager(ctx);
             }});
+
+        registerService(MEDIA_SESSION_SERVICE, new ServiceFetcher() {
+            public Object createService(ContextImpl ctx) {
+                return new MediaSessionManager(ctx);
+            }
+        });
     }
 
     static ContextImpl getImpl(Context context) {
@@ -1480,13 +1488,13 @@
 
     private void validateServiceIntent(Intent service) {
         if (service.getComponent() == null && service.getPackage() == null) {
-            if (true || getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
+            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+                IllegalArgumentException ex = new IllegalArgumentException(
+                        "Service Intent must be explicit: " + service);
+                throw ex;
+            } else {
                 Log.w(TAG, "Implicit intents with startService are not safe: " + service
                         + " " + Debug.getCallers(2, 3));
-                //IllegalArgumentException ex = new IllegalArgumentException(
-                //        "Service Intent must be explicit: " + service);
-                //Log.e(TAG, "This will become an error", ex);
-                //throw ex;
             }
         }
     }
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index a8277b5..fb96d8d 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -17,7 +17,6 @@
 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;
 
@@ -240,6 +239,18 @@
     }
 
     /**
+     * Forces immediate creation of the dialog.
+     * <p>
+     * Note that you should not override this method to perform dialog creation.
+     * Rather, override {@link #onCreate(Bundle)}.
+     */
+    public void create() {
+        if (!mCreated) {
+            dispatchOnCreate(null);
+        }
+    }
+
+    /**
      * Start the dialog and display it on screen.  The window is placed in the
      * application layer and opaque.  Note that you should not override this
      * method to do initialization when the dialog is shown, instead implement
@@ -457,11 +468,12 @@
     }
 
     /**
-     * Finds a view that was identified by the id attribute from the XML that
-     * was processed in {@link #onStart}.
+     * Finds a child view with the given identifier. Returns null if the
+     * specified child view does not exist or the dialog has not yet been fully
+     * created (for example, via {@link #show()} or {@link #create()}).
      *
      * @param id the identifier of the view to find
-     * @return The view if found or null otherwise.
+     * @return The view with the given id or null.
      */
     public View findViewById(int id) {
         return mWindow.findViewById(id);
@@ -480,7 +492,7 @@
     /**
      * Set the screen content to an explicit view.  This view is placed
      * directly into the screen's view hierarchy.  It can itself be a complex
-     * view hierarhcy.
+     * view hierarchy.
      * 
      * @param view The desired content to display.
      */
diff --git a/core/java/android/app/ExpandableListActivity.java b/core/java/android/app/ExpandableListActivity.java
index 9651078..e08f25a 100644
--- a/core/java/android/app/ExpandableListActivity.java
+++ b/core/java/android/app/ExpandableListActivity.java
@@ -27,7 +27,6 @@
 import android.widget.ExpandableListView;
 import android.widget.SimpleCursorTreeAdapter;
 import android.widget.SimpleExpandableListAdapter;
-import android.widget.AdapterView.AdapterContextMenuInfo;
 
 import java.util.Map;
 
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index af8f177..6c0d379 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -17,6 +17,7 @@
 package android.app;
 
 import android.animation.Animator;
+import android.annotation.Nullable;
 import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.Intent;
@@ -575,7 +576,7 @@
      * the given fragment class.  This is a runtime exception; it is not
      * normally expected to happen.
      */
-    public static Fragment instantiate(Context context, String fname, Bundle args) {
+    public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
         try {
             Class<?> clazz = sClassMap.get(fname);
             if (clazz == null) {
@@ -1213,7 +1214,8 @@
      * 
      * @return Return the View for the fragment's UI, or null.
      */
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+    @Nullable
+    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
             Bundle savedInstanceState) {
         return null;
     }
@@ -1228,7 +1230,7 @@
      * @param savedInstanceState If non-null, this fragment is being re-constructed
      * from a previous saved state as given here.
      */
-    public void onViewCreated(View view, Bundle savedInstanceState) {
+    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
     }
     
     /**
@@ -1237,6 +1239,7 @@
      * 
      * @return The fragment's root view, or null if it has no layout.
      */
+    @Nullable
     public View getView() {
         return mView;
     }
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index b810b89..e4de7af 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -81,14 +81,19 @@
     }
 
     public FragmentBreadCrumbs(Context context, AttributeSet attrs) {
-        this(context, attrs, android.R.style.Widget_FragmentBreadCrumbs);
+        this(context, attrs, com.android.internal.R.attr.fragmentBreadCrumbsStyle);
     }
 
-    public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyle, 0);
+    public FragmentBreadCrumbs(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyleAttr, defStyleRes);
 
         mGravity = a.getInt(com.android.internal.R.styleable.FragmentBreadCrumbs_gravity,
                 DEFAULT_GRAVITY);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 02a6343..3b56839 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -122,6 +122,7 @@
     public void resizeStack(int stackId, Rect bounds) throws RemoteException;
     public List<StackInfo> getAllStackInfos() throws RemoteException;
     public StackInfo getStackInfo(int stackId) throws RemoteException;
+    public boolean isInHomeStack(int taskId) throws RemoteException;
     public void setFocusedStack(int stackId) throws RemoteException;
     public int getTaskForActivity(IBinder token, boolean onlyRoot) throws RemoteException;
     /* oneway */
@@ -243,7 +244,8 @@
 
     public void enterSafeMode() throws RemoteException;
     
-    public void noteWakeupAlarm(IIntentSender sender) throws RemoteException;
+    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg)
+            throws RemoteException;
 
     public boolean killPids(int[] pids, String reason, boolean secure) throws RemoteException;
     public boolean killProcessesBelowForeground(String reason) throws RemoteException;
@@ -348,6 +350,7 @@
 
     // Multi-user APIs
     public boolean switchUser(int userid) throws RemoteException;
+    public boolean startUserInBackground(int userid) throws RemoteException;
     public int stopUser(int userid, IStopUserCallback callback) throws RemoteException;
     public UserInfo getCurrentUser() throws RemoteException;
     public boolean isUserRunning(int userid, boolean orStopping) throws RemoteException;
@@ -366,6 +369,8 @@
 
     public Intent getIntentForIntentSender(IIntentSender sender) throws RemoteException;
 
+    public String getTagForIntentSender(IIntentSender sender, String prefix) throws RemoteException;
+
     public void updatePersistentConfiguration(Configuration values) throws RemoteException;
 
     public long[] getProcessPss(int[] pids) throws RemoteException;
@@ -419,6 +424,24 @@
 
     public IBinder getHomeActivityToken() throws RemoteException;
 
+    /** @hide */
+    public void startLockTaskMode(int taskId) throws RemoteException;
+
+    /** @hide */
+    public void startLockTaskMode(IBinder token) throws RemoteException;
+
+    /** @hide */
+    public void stopLockTaskMode() throws RemoteException;
+
+    /** @hide */
+    public boolean isInLockTaskMode() throws RemoteException;
+
+    /** @hide */
+    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) throws RemoteException;
+
+    /** @hide */
+    public void setRecentsIcon(IBinder token, Bitmap recentsBitmap) throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -708,4 +731,16 @@
     int GET_HOME_ACTIVITY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+183;
     int GET_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+184;
     int DELETE_ACTIVITY_CONTAINER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+185;
+
+
+    // Start of L transactions
+    int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
+    int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
+    int IS_IN_HOME_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+212;
+    int START_LOCK_TASK_BY_TASK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+213;
+    int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;
+    int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;
+    int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216;
+    int SET_RECENTS_LABEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+217;
+    int SET_RECENTS_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+218;
 }
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 3aceff9..ac8ac8f 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -50,15 +50,16 @@
             int configChanges) throws RemoteException;
     void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
     void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
-    void scheduleResumeActivity(IBinder token, int procState, boolean isForward)
+    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
             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,
             int procState, Bundle state, List<ResultInfo> pendingResults,
-    		List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
-    		String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler)
-    		throws RemoteException;
+            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
+            String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler,
+            Bundle resumeArgs)
+            throws RemoteException;
     void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
             List<Intent> pendingNewIntents, int configChanges,
             boolean notResumed, Configuration config) throws RemoteException;
diff --git a/core/java/android/app/IBackupAgent.aidl b/core/java/android/app/IBackupAgent.aidl
index 087f83c..4ca06ed 100644
--- a/core/java/android/app/IBackupAgent.aidl
+++ b/core/java/android/app/IBackupAgent.aidl
@@ -76,8 +76,9 @@
      * @param callbackBinder Binder on which to indicate operation completion,
      *        passed here as a convenience to the agent.
      */
-    void doRestore(in ParcelFileDescriptor data, int appVersionCode,
-            in ParcelFileDescriptor newState, int token, IBackupManager callbackBinder);
+    void doRestore(in ParcelFileDescriptor data,
+            int appVersionCode, in ParcelFileDescriptor newState,
+            int token, IBackupManager callbackBinder);
 
     /**
      * Perform a "full" backup to the given file descriptor.  The output file is presumed
@@ -112,8 +113,15 @@
      * @param path Relative path of the file within its semantic domain.
      * @param mode Access mode of the file system entity, e.g. 0660.
      * @param mtime Last modification time of the file system entity.
+     * @param token Opaque token identifying this transaction.  This must
+     *        be echoed back to the backup service binder once the agent is
+     *        finished restoring the application based on the restore data
+     *        contents.
+     * @param callbackBinder Binder on which to indicate operation completion,
+     *        passed here as a convenience to the agent.
      */
     void doRestoreFile(in ParcelFileDescriptor data, long size,
             int type, String domain, String path, long mode, long mtime,
             int token, IBackupManager callbackBinder);
+
 }
diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java
index a7982f4..fa2813e 100644
--- a/core/java/android/app/MediaRouteButton.java
+++ b/core/java/android/app/MediaRouteButton.java
@@ -73,13 +73,18 @@
     }
 
     public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MediaRouteButton(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
         mCallback = new MediaRouterCallback();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, defStyleRes);
         setRemoteIndicatorDrawable(a.getDrawable(
                 com.android.internal.R.styleable.MediaRouteButton_externalRouteEnabledDrawable));
         mMinWidth = a.getDimensionPixelSize(
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 6be2b7b..13e74da 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.R;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -37,6 +38,8 @@
 import android.widget.ProgressBar;
 import android.widget.RemoteViews;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.text.NumberFormat;
 import java.util.ArrayList;
 
@@ -201,6 +204,15 @@
      */
     public RemoteViews bigContentView;
 
+
+    /**
+     * @hide
+     * A medium-format version of {@link #contentView}, giving the Notification an
+     * opportunity to add action buttons to contentView. The system UI may
+     * choose to show this as a popup notification at its discretion.
+     */
+    public RemoteViews headsUpContentView;
+
     /**
      * The bitmap that may escape the bounds of the panel and bar.
      */
@@ -357,6 +369,11 @@
 
     public int flags;
 
+    /** @hide */
+    @IntDef({PRIORITY_DEFAULT,PRIORITY_LOW,PRIORITY_MIN,PRIORITY_HIGH,PRIORITY_MAX})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Priority {}
+
     /**
      * Default notification {@link #priority}. If your application does not prioritize its own
      * notifications, use this value for all notifications.
@@ -398,44 +415,111 @@
      * system will make a determination about how to interpret this priority when presenting
      * the notification.
      */
+    @Priority
     public int priority;
 
-    /**
-     * @hide
-     * Notification type: incoming call (voice or video) or similar synchronous communication request.
-     */
-    public static final String KIND_CALL = "android.call";
 
     /**
-     * @hide
-     * Notification type: incoming direct message (SMS, instant message, etc.).
+     * Sphere of visibility of this notification, which affects how and when the SystemUI reveals 
+     * the notification's presence and contents in untrusted situations (namely, on the secure 
+     * lockscreen).
+     *
+     * The default level, {@link #VISIBILITY_PRIVATE}, behaves exactly as notifications have always
+     * done on Android: The notification's {@link #icon} and {@link #tickerText} (if available) are
+     * shown in all situations, but the contents are only available if the device is unlocked for
+     * the appropriate user.
+     *
+     * A more permissive policy can be expressed by {@link #VISIBILITY_PUBLIC}; such a notification
+     * can be read even in an "insecure" context (that is, above a secure lockscreen).
+     * To modify the public version of this notification—for example, to redact some portions—see
+     * {@link Builder#setPublicVersion(Notification)}.
+     *
+     * Finally, a notification can be made {@link #VISIBILITY_SECRET}, which will suppress its icon
+     * and ticker until the user has bypassed the lockscreen.
      */
-    public static final String KIND_MESSAGE = "android.message";
+    public int visibility;
+
+    public static final int VISIBILITY_PUBLIC = 1;
+    public static final int VISIBILITY_PRIVATE = 0;
+    public static final int VISIBILITY_SECRET = -1;
 
     /**
-     * @hide
-     * Notification type: asynchronous bulk message (email).
+     * Notification category: incoming call (voice or video) or similar synchronous communication request.
      */
-    public static final String KIND_EMAIL = "android.email";
+    public static final String CATEGORY_CALL = "call";
 
     /**
-     * @hide
-     * Notification type: calendar event.
+     * Notification category: incoming direct message (SMS, instant message, etc.).
      */
-    public static final String KIND_EVENT = "android.event";
+    public static final String CATEGORY_MESSAGE = "msg";
 
     /**
-     * @hide
-     * Notification type: promotion or advertisement.
+     * Notification category: asynchronous bulk message (email).
      */
-    public static final String KIND_PROMO = "android.promo";
+    public static final String CATEGORY_EMAIL = "email";
 
     /**
-     * @hide
-     * If this notification matches of one or more special types (see the <code>KIND_*</code>
-     * constants), add them here, best match first.
+     * Notification category: calendar event.
      */
-    public String[] kind;
+    public static final String CATEGORY_EVENT = "event";
+
+    /**
+     * Notification category: promotion or advertisement.
+     */
+    public static final String CATEGORY_PROMO = "promo";
+
+    /**
+     * Notification category: alarm or timer.
+     */
+    public static final String CATEGORY_ALARM = "alarm";
+
+    /**
+     * Notification category: progress of a long-running background operation.
+     */
+    public static final String CATEGORY_PROGRESS = "progress";
+
+    /**
+     * Notification category: social network or sharing update.
+     */
+    public static final String CATEGORY_SOCIAL = "social";
+
+    /**
+     * Notification category: error in background operation or authentication status.
+     */
+    public static final String CATEGORY_ERROR = "err";
+
+    /**
+     * Notification category: media transport control for playback.
+     */
+    public static final String CATEGORY_TRANSPORT = "transport";
+
+    /**
+     * Notification category: system or device status update.  Reserved for system use.
+     */
+    public static final String CATEGORY_SYSTEM = "sys";
+
+    /**
+     * Notification category: indication of running background service.
+     */
+    public static final String CATEGORY_SERVICE = "service";
+
+    /**
+     * Notification category: a specific, timely recommendation for a single thing.
+     * For example, a news app might want to recommend a news story it believes the user will
+     * want to read next.
+     */
+    public static final String CATEGORY_RECOMMENDATION = "recommendation";
+
+    /**
+     * Notification category: ongoing information about device or contextual status.
+     */
+    public static final String CATEGORY_STATUS = "status";
+
+    /**
+     * One of the predefined notification categories (see the <code>CATEGORY_*</code> constants)
+     * that best describes this Notification.  May be used by the system for ranking and filtering.
+     */
+    public String category;
 
     /**
      * Additional semantic data to be carried around with this Notification.
@@ -547,6 +631,7 @@
      * notifications, each of which was supplied to {@link InboxStyle#addLine(CharSequence)}.
      */
     public static final String EXTRA_TEXT_LINES = "android.textLines";
+    public static final String EXTRA_TEMPLATE = "android.template";
 
     /**
      * {@link #extras} key: An array of people that this notification relates to, specified
@@ -568,6 +653,20 @@
     public static final String EXTRA_AS_HEADS_UP = "headsup";
 
     /**
+     * Extra added from {@link Notification.Builder} to indicate that the remote views were inflated
+     * from the builder, as opposed to being created directly from the application.
+     * @hide
+     */
+    public static final String EXTRA_BUILDER_REMOTE_VIEWS = "android.builderRemoteViews";
+
+    /**
+     * Allow certain system-generated notifications to appear before the device is provisioned.
+     * Only available to notifications coming from the android package.
+     * @hide
+     */
+    public static final String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
+
+    /**
      * Value for {@link #EXTRA_AS_HEADS_UP}.
      * @hide
      */
@@ -668,6 +767,13 @@
     public Action[] actions;
 
     /**
+     * Replacement version of this notification whose content will be shown
+     * in an insecure context such as atop a secure keyguard. See {@link #visibility}
+     * and {@link #VISIBILITY_PUBLIC}.
+     */
+    public Notification publicVersion;
+
+    /**
      * Constructs a Notification object with default values.
      * You might want to consider using {@link Builder} instead.
      */
@@ -757,7 +863,7 @@
 
         priority = parcel.readInt();
 
-        kind = parcel.createStringArray(); // may set kind to null
+        category = parcel.readString();
 
         extras = parcel.readBundle(); // may be null
 
@@ -766,6 +872,16 @@
         if (parcel.readInt() != 0) {
             bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
         }
+
+        if (parcel.readInt() != 0) {
+            headsUpContentView = RemoteViews.CREATOR.createFromParcel(parcel);
+        }
+
+        visibility = parcel.readInt();
+
+        if (parcel.readInt() != 0) {
+            publicVersion = Notification.CREATOR.createFromParcel(parcel);
+        }
     }
 
     @Override
@@ -822,12 +938,7 @@
 
         that.priority = this.priority;
 
-        final String[] thiskind = this.kind;
-        if (thiskind != null) {
-            final int N = thiskind.length;
-            final String[] thatkind = that.kind = new String[N];
-            System.arraycopy(thiskind, 0, thatkind, 0, N);
-        }
+        that.category = this.category;
 
         if (this.extras != null) {
             try {
@@ -851,6 +962,17 @@
             that.bigContentView = this.bigContentView.clone();
         }
 
+        if (heavy && this.headsUpContentView != null) {
+            that.headsUpContentView = this.headsUpContentView.clone();
+        }
+
+        that.visibility = this.visibility;
+
+        if (this.publicVersion != null) {
+            that.publicVersion = new Notification();
+            this.publicVersion.cloneInto(that.publicVersion, heavy);
+        }
+
         if (!heavy) {
             that.lightenPayload(); // will clean out extras
         }
@@ -865,6 +987,7 @@
         tickerView = null;
         contentView = null;
         bigContentView = null;
+        headsUpContentView = null;
         largeIcon = null;
         if (extras != null) {
             extras.remove(Notification.EXTRA_LARGE_ICON);
@@ -964,7 +1087,7 @@
 
         parcel.writeInt(priority);
 
-        parcel.writeStringArray(kind); // ok for null
+        parcel.writeString(category);
 
         parcel.writeBundle(extras); // null ok
 
@@ -976,6 +1099,22 @@
         } else {
             parcel.writeInt(0);
         }
+
+        if (headsUpContentView != null) {
+            parcel.writeInt(1);
+            headsUpContentView.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
+
+        parcel.writeInt(visibility);
+
+        if (publicVersion != null) {
+            parcel.writeInt(1);
+            publicVersion.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
     }
 
     /**
@@ -1084,16 +1223,7 @@
         sb.append(Integer.toHexString(this.defaults));
         sb.append(" flags=0x");
         sb.append(Integer.toHexString(this.flags));
-        sb.append(" kind=[");
-        if (this.kind == null) {
-            sb.append("null");
-        } else {
-            for (int i=0; i<this.kind.length; i++) {
-                if (i>0) sb.append(",");
-                sb.append(this.kind[i]);
-            }
-        }
-        sb.append("]");
+        sb.append(" category="); sb.append(this.category);
         if (actions != null) {
             sb.append(" ");
             sb.append(actions.length);
@@ -1118,6 +1248,9 @@
         if (bigContentView != null) {
             bigContentView.setUser(user);
         }
+        if (headsUpContentView != null) {
+            headsUpContentView.setUser(user);
+        }
     }
 
     /**
@@ -1172,13 +1305,16 @@
         private int mProgressMax;
         private int mProgress;
         private boolean mProgressIndeterminate;
-        private ArrayList<String> mKindList = new ArrayList<String>(1);
+        private String mCategory;
         private Bundle mExtras;
         private int mPriority;
         private ArrayList<Action> mActions = new ArrayList<Action>(MAX_ACTION_BUTTONS);
         private boolean mUseChronometer;
         private Style mStyle;
         private boolean mShowWhen = true;
+        private int mVisibility = VISIBILITY_PRIVATE;
+        private Notification mPublicVersion = null;
+        private boolean mQuantumTheme;
 
         /**
          * Constructs a new Builder with the defaults:
@@ -1206,6 +1342,9 @@
             mWhen = System.currentTimeMillis();
             mAudioStreamType = STREAM_DEFAULT;
             mPriority = PRIORITY_DEFAULT;
+
+            // TODO: Decide on targetSdk from calling app whether to use quantum theme.
+            mQuantumTheme = true;
         }
 
         /**
@@ -1568,20 +1707,18 @@
          *
          * @see Notification#priority
          */
-        public Builder setPriority(int pri) {
+        public Builder setPriority(@Priority int pri) {
             mPriority = pri;
             return this;
         }
 
         /**
-         * @hide
+         * Set the notification category.
          *
-         * Add a kind (category) to this notification. Optional.
-         *
-         * @see Notification#kind
+         * @see Notification#category
          */
-        public Builder addKind(String k) {
-            mKindList.add(k);
+        public Builder setCategory(String category) {
+            mCategory = category;
             return this;
         }
 
@@ -1672,6 +1809,30 @@
             return this;
         }
 
+        /**
+         * Specify the value of {@link #visibility}.
+
+         * @param visibility One of {@link #VISIBILITY_PRIVATE} (the default),
+         * {@link #VISIBILITY_SECRET}, or {@link #VISIBILITY_PUBLIC}.
+         *
+         * @return The same Builder.
+         */
+        public Builder setVisibility(int visibility) {
+            mVisibility = visibility;
+            return this;
+        }
+
+        /**
+         * Supply a replacement Notification whose contents should be shown in insecure contexts
+         * (i.e. atop the secure lockscreen). See {@link #visibility} and {@link #VISIBILITY_PUBLIC}.
+         * @param n A replacement notification, presumably with some or all info redacted.
+         * @return The same Builder.
+         */
+        public Builder setPublicVersion(Notification n) {
+            mPublicVersion = n;
+            return this;
+        }
+
         private void setFlag(int mask, boolean value) {
             if (value) {
                 mFlags |= mask;
@@ -1689,7 +1850,7 @@
                 contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
                 smallIconImageViewId = R.id.right_icon;
             }
-            if (mPriority < PRIORITY_LOW) {
+            if (!mQuantumTheme && mPriority < PRIORITY_LOW) {
                 contentView.setInt(R.id.icon,
                         "setBackgroundResource", R.drawable.notification_template_icon_low_bg);
                 contentView.setInt(R.id.status_bar_latest_event_content,
@@ -1803,7 +1964,7 @@
             if (mContentView != null) {
                 return mContentView;
             } else {
-                return applyStandardTemplate(R.layout.notification_template_base, true); // no more special large_icon flavor
+                return applyStandardTemplate(getBaseLayoutResource(), true); // no more special large_icon flavor
             }
         }
 
@@ -1824,14 +1985,21 @@
         private RemoteViews makeBigContentView() {
             if (mActions.size() == 0) return null;
 
-            return applyStandardTemplateWithActions(R.layout.notification_template_big_base);
+            return applyStandardTemplateWithActions(getBigBaseLayoutResource());
         }
 
+        private RemoteViews makeHeadsUpContentView() {
+            if (mActions.size() == 0) return null;
+
+            return applyStandardTemplateWithActions(getBigBaseLayoutResource());
+        }
+
+
         private RemoteViews generateActionButton(Action action) {
             final boolean tombstone = (action.actionIntent == null);
             RemoteViews button = new RemoteViews(mContext.getPackageName(),
-                    tombstone ? R.layout.notification_action_tombstone
-                              : R.layout.notification_action);
+                    tombstone ? getActionTombstoneLayoutResource()
+                              : getActionLayoutResource());
             button.setTextViewCompoundDrawablesRelative(R.id.action0, action.icon, 0, 0, 0);
             button.setTextViewText(R.id.action0, action.title);
             if (!tombstone) {
@@ -1867,23 +2035,25 @@
             n.defaults = mDefaults;
             n.flags = mFlags;
             n.bigContentView = makeBigContentView();
+            n.headsUpContentView = makeHeadsUpContentView();
             if (mLedOnMs != 0 || mLedOffMs != 0) {
                 n.flags |= FLAG_SHOW_LIGHTS;
             }
             if ((mDefaults & DEFAULT_LIGHTS) != 0) {
                 n.flags |= FLAG_SHOW_LIGHTS;
             }
-            if (mKindList.size() > 0) {
-                n.kind = new String[mKindList.size()];
-                mKindList.toArray(n.kind);
-            } else {
-                n.kind = null;
-            }
+            n.category = mCategory;
             n.priority = mPriority;
             if (mActions.size() > 0) {
                 n.actions = new Action[mActions.size()];
                 mActions.toArray(n.actions);
             }
+            n.visibility = mVisibility;
+
+            if (mPublicVersion != null) {
+                n.publicVersion = new Notification();
+                mPublicVersion.cloneInto(n.publicVersion, true);
+            }
 
             return n;
         }
@@ -1905,6 +2075,7 @@
             extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate);
             extras.putBoolean(EXTRA_SHOW_CHRONOMETER, mUseChronometer);
             extras.putBoolean(EXTRA_SHOW_WHEN, mShowWhen);
+            extras.putBoolean(EXTRA_BUILDER_REMOTE_VIEWS, mContentView == null);
             if (mLargeIcon != null) {
                 extras.putParcelable(EXTRA_LARGE_ICON, mLargeIcon);
             }
@@ -1948,6 +2119,49 @@
             build().cloneInto(n, true);
             return n;
         }
+
+
+        private int getBaseLayoutResource() {
+            return mQuantumTheme
+                    ? R.layout.notification_template_quantum_base
+                    : R.layout.notification_template_base;
+        }
+
+        private int getBigBaseLayoutResource() {
+            return mQuantumTheme
+                    ? R.layout.notification_template_quantum_big_base
+                    : R.layout.notification_template_big_base;
+        }
+
+        private int getBigPictureLayoutResource() {
+            return mQuantumTheme
+                    ? R.layout.notification_template_quantum_big_picture
+                    : R.layout.notification_template_big_picture;
+        }
+
+        private int getBigTextLayoutResource() {
+            return mQuantumTheme
+                    ? R.layout.notification_template_quantum_big_text
+                    : R.layout.notification_template_big_text;
+        }
+
+        private int getInboxLayoutResource() {
+            return mQuantumTheme
+                    ? R.layout.notification_template_quantum_inbox
+                    : R.layout.notification_template_inbox;
+        }
+
+        private int getActionLayoutResource() {
+            return mQuantumTheme
+                    ? R.layout.notification_quantum_action
+                    : R.layout.notification_action;
+        }
+
+        private int getActionTombstoneLayoutResource() {
+            return mQuantumTheme
+                    ? R.layout.notification_quantum_action_tombstone
+                    : R.layout.notification_action_tombstone;
+        }
     }
 
     /**
@@ -2033,6 +2247,7 @@
             if (mBigContentTitle != null) {
                 extras.putCharSequence(EXTRA_TITLE_BIG, mBigContentTitle);
             }
+            extras.putString(EXTRA_TEMPLATE, this.getClass().getName());
         }
 
         /**
@@ -2116,7 +2331,7 @@
         }
 
         private RemoteViews makeBigContentView() {
-            RemoteViews contentView = getStandardView(R.layout.notification_template_big_picture);
+            RemoteViews contentView = getStandardView(mBuilder.getBigPictureLayoutResource());
 
             contentView.setImageViewBitmap(R.id.big_picture, mPicture);
 
@@ -2215,7 +2430,7 @@
             final boolean hadThreeLines = (mBuilder.mContentText != null && mBuilder.mSubText != null);
             mBuilder.mContentText = null;
 
-            RemoteViews contentView = getStandardView(R.layout.notification_template_big_text);
+            RemoteViews contentView = getStandardView(mBuilder.getBigTextLayoutResource());
 
             if (hadThreeLines) {
                 // vertical centering
@@ -2309,7 +2524,7 @@
         private RemoteViews makeBigContentView() {
             // Remove the content text so line3 disappears unless you have a summary
             mBuilder.mContentText = null;
-            RemoteViews contentView = getStandardView(R.layout.notification_template_inbox);
+            RemoteViews contentView = getStandardView(mBuilder.getInboxLayoutResource());
 
             contentView.setViewVisibility(R.id.text2, View.GONE);
 
diff --git a/core/java/android/app/OnActivityPausedListener.java b/core/java/android/app/OnActivityPausedListener.java
index 379f133..5003973 100644
--- a/core/java/android/app/OnActivityPausedListener.java
+++ b/core/java/android/app/OnActivityPausedListener.java
@@ -5,7 +5,7 @@
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- *	    http://www.apache.org/licenses/LICENSE-2.0
+ *        http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 45467b8..8efc14f 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -16,6 +16,9 @@
 
 package android.app;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IIntentReceiver;
@@ -30,6 +33,9 @@
 import android.os.UserHandle;
 import android.util.AndroidException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A description of an Intent and target action to perform with it.  Instances
  * of this class are created with {@link #getActivity}, {@link #getActivities},
@@ -86,6 +92,26 @@
 public final class PendingIntent implements Parcelable {
     private final IIntentSender mTarget;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    FLAG_ONE_SHOT,
+                    FLAG_NO_CREATE,
+                    FLAG_CANCEL_CURRENT,
+                    FLAG_UPDATE_CURRENT,
+
+                    Intent.FILL_IN_ACTION,
+                    Intent.FILL_IN_DATA,
+                    Intent.FILL_IN_CATEGORIES,
+                    Intent.FILL_IN_COMPONENT,
+                    Intent.FILL_IN_PACKAGE,
+                    Intent.FILL_IN_SOURCE_BOUNDS,
+                    Intent.FILL_IN_SELECTOR,
+                    Intent.FILL_IN_CLIP_DATA
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Flags {}
+
     /**
      * Flag indicating that this PendingIntent can be used only once.
      * For use with {@link #getActivity}, {@link #getBroadcast}, and
@@ -222,7 +248,7 @@
      * supplied.
      */
     public static PendingIntent getActivity(Context context, int requestCode,
-            Intent intent, int flags) {
+            Intent intent, @Flags int flags) {
         return getActivity(context, requestCode, intent, flags, null);
     }
 
@@ -255,7 +281,7 @@
      * supplied.
      */
     public static PendingIntent getActivity(Context context, int requestCode,
-            Intent intent, int flags, Bundle options) {
+            @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -280,7 +306,7 @@
      * activity is started, not when the pending intent is created.
      */
     public static PendingIntent getActivityAsUser(Context context, int requestCode,
-            Intent intent, int flags, Bundle options, UserHandle user) {
+            @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -345,7 +371,7 @@
      * supplied.
      */
     public static PendingIntent getActivities(Context context, int requestCode,
-            Intent[] intents, int flags) {
+            @NonNull Intent[] intents, @Flags int flags) {
         return getActivities(context, requestCode, intents, flags, null);
     }
 
@@ -395,7 +421,7 @@
      * supplied.
      */
     public static PendingIntent getActivities(Context context, int requestCode,
-            Intent[] intents, int flags, Bundle options) {
+            @NonNull Intent[] intents, @Flags int flags, @Nullable Bundle options) {
         String packageName = context.getPackageName();
         String[] resolvedTypes = new String[intents.length];
         for (int i=0; i<intents.length; i++) {
@@ -421,7 +447,7 @@
      * activity is started, not when the pending intent is created.
      */
     public static PendingIntent getActivitiesAsUser(Context context, int requestCode,
-            Intent[] intents, int flags, Bundle options, UserHandle user) {
+            @NonNull Intent[] intents, int flags, Bundle options, UserHandle user) {
         String packageName = context.getPackageName();
         String[] resolvedTypes = new String[intents.length];
         for (int i=0; i<intents.length; i++) {
@@ -465,7 +491,7 @@
      * supplied.
      */
     public static PendingIntent getBroadcast(Context context, int requestCode,
-            Intent intent, int flags) {
+            Intent intent, @Flags int flags) {
         return getBroadcastAsUser(context, requestCode, intent, flags,
                 new UserHandle(UserHandle.myUserId()));
     }
@@ -519,7 +545,7 @@
      * supplied.
      */
     public static PendingIntent getService(Context context, int requestCode,
-            Intent intent, int flags) {
+            @NonNull Intent intent, @Flags int flags) {
         String packageName = context.getPackageName();
         String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
                 context.getContentResolver()) : null;
@@ -749,6 +775,7 @@
      * @return The package name of the PendingIntent, or null if there is
      * none associated with it.
      */
+    @Nullable
     public String getCreatorPackage() {
         try {
             return ActivityManagerNative.getDefault()
@@ -807,6 +834,7 @@
      * @return The user handle of the PendingIntent, or null if there is
      * none associated with it.
      */
+    @Nullable
     public UserHandle getCreatorUserHandle() {
         try {
             int uid = ActivityManagerNative.getDefault()
@@ -861,6 +889,20 @@
     }
 
     /**
+     * @hide
+     * Return descriptive tag for this PendingIntent.
+     */
+    public String getTag(String prefix) {
+        try {
+            return ActivityManagerNative.getDefault()
+                .getTagForIntentSender(mTarget, prefix);
+        } catch (RemoteException e) {
+            // Should never happen.
+            return null;
+        }
+    }
+
+    /**
      * Comparison operator on two PendingIntent objects, such that true
      * is returned then they both represent the same operation from the
      * same package.  This allows you to use {@link #getActivity},
@@ -922,8 +964,8 @@
      * @param sender The PendingIntent to write, or null.
      * @param out Where to write the PendingIntent.
      */
-    public static void writePendingIntentOrNullToParcel(PendingIntent sender,
-            Parcel out) {
+    public static void writePendingIntentOrNullToParcel(@Nullable PendingIntent sender,
+            @NonNull Parcel out) {
         out.writeStrongBinder(sender != null ? sender.mTarget.asBinder()
                 : null);
     }
@@ -938,7 +980,8 @@
      * @return Returns the Messenger read from the Parcel, or null if null had
      * been written.
      */
-    public static PendingIntent readPendingIntentOrNullFromParcel(Parcel in) {
+    @Nullable
+    public static PendingIntent readPendingIntentOrNullFromParcel(@NonNull Parcel in) {
         IBinder b = in.readStrongBinder();
         return b != null ? new PendingIntent(b) : null;
     }
diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java
index 48a0fc2..5e0867c 100644
--- a/core/java/android/app/ResultInfo.java
+++ b/core/java/android/app/ResultInfo.java
@@ -17,12 +17,8 @@
 package android.app;
 
 import android.content.Intent;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Bundle;
-
-import java.util.Map;
 
 /**
  * {@hide}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index d04e9db..af1810b 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -188,8 +188,7 @@
                 mSearchView.findViewById(com.android.internal.R.id.search_src_text);
         mAppIcon = (ImageView) findViewById(com.android.internal.R.id.search_app_icon);
         mSearchPlate = mSearchView.findViewById(com.android.internal.R.id.search_plate);
-        mWorkingSpinner = getContext().getResources().
-                getDrawable(com.android.internal.R.drawable.search_spinner);
+        mWorkingSpinner = getContext().getDrawable(com.android.internal.R.drawable.search_spinner);
         // TODO: Restore the spinner for slow suggestion lookups
         // mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
         //        null, null, mWorkingSpinner, null);
@@ -458,7 +457,7 @@
 
         // optionally show one or the other.
         if (mSearchable.useBadgeIcon()) {
-            icon = mActivityContext.getResources().getDrawable(mSearchable.getIconId());
+            icon = mActivityContext.getDrawable(mSearchable.getIconId());
             visibility = View.VISIBLE;
             if (DBG) Log.d(LOG_TAG, "Using badge icon: " + mSearchable.getIconId());
         } else if (mSearchable.useBadgeLabel()) {
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index f9c245e..33c3409 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.graphics.Rect;
@@ -34,7 +33,6 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Slog;
 import android.view.KeyEvent;
 
 import java.util.List;
diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java
index a292ecb..1b838fb 100644
--- a/core/java/android/app/SharedPreferencesImpl.java
+++ b/core/java/android/app/SharedPreferencesImpl.java
@@ -42,7 +42,6 @@
 import java.util.Set;
 import java.util.WeakHashMap;
 import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
 
 import libcore.io.ErrnoException;
 import libcore.io.IoUtils;
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 2045ed8..a6a04d1 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -38,8 +38,11 @@
     public static final int DISABLE_NOTIFICATION_ICONS = View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS;
     public static final int DISABLE_NOTIFICATION_ALERTS
             = View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS;
+    @Deprecated
     public static final int DISABLE_NOTIFICATION_TICKER
             = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
+    public static final int DISABLE_PRIVATE_NOTIFICATIONS
+            = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
     public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
     public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
     public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index 3e0ac7e..0077db1 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.annotation.NonNull;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -244,7 +245,7 @@
      *
      * @return The obtained PendingIntent
      */
-    public PendingIntent getPendingIntent(int requestCode, int flags) {
+    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags) {
         return getPendingIntent(requestCode, flags, null);
     }
 
@@ -263,7 +264,8 @@
      *
      * @return The obtained PendingIntent
      */
-    public PendingIntent getPendingIntent(int requestCode, int flags, Bundle options) {
+    public PendingIntent getPendingIntent(int requestCode, @PendingIntent.Flags int flags,
+            Bundle options) {
         if (mIntents.isEmpty()) {
             throw new IllegalStateException(
                     "No intents added to TaskStackBuilder; cannot getPendingIntent");
@@ -294,6 +296,7 @@
      *
      * @return An array containing the intents added to this builder.
      */
+    @NonNull
     public Intent[] getIntents() {
         Intent[] intents = new Intent[mIntents.size()];
         if (intents.length == 0) return intents;
diff --git a/core/java/android/app/TimePickerDialog.java b/core/java/android/app/TimePickerDialog.java
index 952227f..a85c61f 100644
--- a/core/java/android/app/TimePickerDialog.java
+++ b/core/java/android/app/TimePickerDialog.java
@@ -16,17 +16,19 @@
 
 package android.app;
 
-import com.android.internal.R;
-
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
 import android.os.Bundle;
+import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.TimePicker;
 import android.widget.TimePicker.OnTimeChangedListener;
 
+import com.android.internal.R;
+
+
 /**
  * A dialog that prompts the user for the time of day using a {@link TimePicker}.
  *
@@ -38,7 +40,7 @@
 
     /**
      * The callback interface used to indicate the user is done filling in
-     * the time (they clicked on the 'Set' button).
+     * the time (they clicked on the 'Done' button).
      */
     public interface OnTimeSetListener {
 
@@ -55,7 +57,7 @@
     private static final String IS_24_HOUR = "is24hour";
 
     private final TimePicker mTimePicker;
-    private final OnTimeSetListener mCallback;
+    private final OnTimeSetListener mTimeSetCallback;
 
     int mInitialHourOfDay;
     int mInitialMinute;
@@ -74,6 +76,16 @@
         this(context, 0, callBack, hourOfDay, minute, is24HourView);
     }
 
+    static int resolveDialogTheme(Context context, int resid) {
+        if (resid == 0) {
+            TypedValue outValue = new TypedValue();
+            context.getTheme().resolveAttribute(R.attr.timePickerDialogTheme, outValue, true);
+            return outValue.resourceId;
+        } else {
+            return resid;
+        }
+    }
+
     /**
      * @param context Parent.
      * @param theme the theme to apply to this dialog
@@ -86,17 +98,13 @@
             int theme,
             OnTimeSetListener callBack,
             int hourOfDay, int minute, boolean is24HourView) {
-        super(context, theme);
-        mCallback = callBack;
+        super(context, resolveDialogTheme(context, theme));
+        mTimeSetCallback = callBack;
         mInitialHourOfDay = hourOfDay;
         mInitialMinute = minute;
         mIs24HourView = is24HourView;
 
-        setIcon(0);
-        setTitle(R.string.time_picker_dialog_title);
-
         Context themeContext = getContext();
-        setButton(BUTTON_POSITIVE, themeContext.getText(R.string.date_time_done), this);
 
         LayoutInflater inflater =
                 (LayoutInflater) themeContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -104,7 +112,18 @@
         setView(view);
         mTimePicker = (TimePicker) view.findViewById(R.id.timePicker);
 
-        // initialize state
+        // Initialize state
+        mTimePicker.setLegacyMode(false /* will show new UI */);
+        mTimePicker.setShowDoneButton(true);
+        mTimePicker.setDismissCallback(new TimePicker.TimePickerDismissCallback() {
+            @Override
+            public void dismiss(TimePicker view, boolean isCancel, int hourOfDay, int minute) {
+                if (!isCancel) {
+                    mTimeSetCallback.onTimeSet(view, hourOfDay, minute);
+                }
+                TimePickerDialog.this.dismiss();
+            }
+        });
         mTimePicker.setIs24HourView(mIs24HourView);
         mTimePicker.setCurrentHour(mInitialHourOfDay);
         mTimePicker.setCurrentMinute(mInitialMinute);
@@ -125,9 +144,9 @@
     }
 
     private void tryNotifyTimeSet() {
-        if (mCallback != null) {
+        if (mTimeSetCallback != null) {
             mTimePicker.clearFocus();
-            mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
+            mTimeSetCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
                     mTimePicker.getCurrentMinute());
         }
     }
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index 498fa42..354a19f 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -36,9 +36,11 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.TimeoutException;
 
 /**
@@ -269,10 +271,10 @@
      * @param action The action to perform.
      * @return Whether the action was successfully performed.
      *
-     * @see AccessibilityService#GLOBAL_ACTION_BACK
-     * @see AccessibilityService#GLOBAL_ACTION_HOME
-     * @see AccessibilityService#GLOBAL_ACTION_NOTIFICATIONS
-     * @see AccessibilityService#GLOBAL_ACTION_RECENTS
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_HOME
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_NOTIFICATIONS
+     * @see android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_RECENTS
      */
     public final boolean performGlobalAction(int action) {
         final IAccessibilityServiceConnection connection;
@@ -346,6 +348,33 @@
     }
 
     /**
+     * Gets the windows on the screen. This method returns only the windows
+     * that a sighted user can interact with, as opposed to all windows.
+     * For example, if there is a modal dialog shown and the user cannot touch
+     * anything behind it, then only the modal window will be reported
+     * (assuming it is the top one). For convenience the returned windows
+     * are ordered in a descending layer order, which is the windows that
+     * are higher in the Z-order are reported first.
+     * <p>
+     * <strong>Note:</strong> In order to access the windows you have to opt-in
+     * to retrieve the interactive windows by setting the
+     * {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS} flag.
+     * </p>
+     *
+     * @return The windows if there are windows such, otherwise an empty list.
+     */
+    public List<AccessibilityWindowInfo> getWindows() {
+        final int connectionId;
+        synchronized (mLock) {
+            throwIfNotConnectedLocked();
+            connectionId = mConnectionId;
+        }
+        // Calling out without a lock held.
+        return AccessibilityInteractionClient.getInstance()
+                .getWindows(connectionId);
+    }
+
+    /**
      * Gets the root {@link AccessibilityNodeInfo} in the active window.
      *
      * @return The root info.
@@ -632,7 +661,7 @@
      * potentially undesirable actions such as calling 911 or posting on public forums etc.
      *
      * @param enable whether to run in a "monkey" mode or not. Default is not.
-     * @see {@link ActivityManager#isUserAMonkey()}
+     * @see {@link android.app.ActivityManager#isUserAMonkey()}
      */
     public void setRunAsMonkey(boolean enable) {
         synchronized (mLock) {
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index f291e82..e6e0f35 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -41,7 +41,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -219,24 +218,9 @@
         
         private static final int MSG_CLEAR_WALLPAPER = 1;
         
-        private final Handler mHandler;
-        
         Globals(Looper looper) {
             IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
             mService = IWallpaperManager.Stub.asInterface(b);
-            mHandler = new Handler(looper) {
-                @Override
-                public void handleMessage(Message msg) {
-                    switch (msg.what) {
-                        case MSG_CLEAR_WALLPAPER:
-                            synchronized (this) {
-                                mWallpaper = null;
-                                mDefaultWallpaper = null;
-                            }
-                            break;
-                    }
-                }
-            };
         }
         
         public void onWallpaperChanged() {
@@ -245,7 +229,10 @@
              * to null so if the user requests the wallpaper again then we'll
              * fetch it.
              */
-            mHandler.sendEmptyMessage(MSG_CLEAR_WALLPAPER);
+            synchronized (this) {
+                mWallpaper = null;
+                mDefaultWallpaper = null;
+            }
         }
 
         public Bitmap peekWallpaperBitmap(Context context, boolean returnDefault) {
@@ -278,7 +265,6 @@
             synchronized (this) {
                 mWallpaper = null;
                 mDefaultWallpaper = null;
-                mHandler.removeMessages(MSG_CLEAR_WALLPAPER);
             }
         }
 
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 30b65de..f9d9059 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -29,25 +29,25 @@
  * Base class for implementing a device administration component.  This
  * class provides a convenience for interpreting the raw intent actions
  * that are sent by the system.
- * 
+ *
  * <p>The callback methods, like the base
  * {@link BroadcastReceiver#onReceive(Context, Intent) BroadcastReceiver.onReceive()}
  * method, happen on the main thread of the process.  Thus long running
  * operations must be done on another thread.  Note that because a receiver
  * is done once returning from its receive function, such long-running operations
  * should probably be done in a {@link Service}.
- * 
+ *
  * <p>When publishing your DeviceAdmin subclass as a receiver, it must
  * handle {@link #ACTION_DEVICE_ADMIN_ENABLED} and require the
  * {@link android.Manifest.permission#BIND_DEVICE_ADMIN} permission.  A typical
  * manifest entry would look like:</p>
- * 
+ *
  * {@sample development/samples/ApiDemos/AndroidManifest.xml device_admin_declaration}
- *   
+ *
  * <p>The meta-data referenced here provides addition information specific
  * to the device administrator, as parsed by the {@link DeviceAdminInfo} class.
  * A typical file would be:</p>
- * 
+ *
  * {@sample development/samples/ApiDemos/res/xml/device_admin_sample.xml meta_data}
  *
  * <div class="special reference">
@@ -86,7 +86,7 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
             = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
-    
+
     /**
      * A CharSequence that can be shown to the user informing them of the
      * impact of disabling your admin.
@@ -94,7 +94,7 @@
      * @see #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED
      */
     public static final String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
-    
+
     /**
      * Action sent to a device administrator when the user has disabled
      * it.  Upon return, the application no longer has access to the
@@ -107,7 +107,7 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DEVICE_ADMIN_DISABLED
             = "android.app.action.DEVICE_ADMIN_DISABLED";
-    
+
     /**
      * Action sent to a device administrator when the user has changed the
      * password of their device.  You can at this point check the characteristics
@@ -115,7 +115,7 @@
      * DevicePolicyManager.isActivePasswordSufficient()}.
      * You will generally
      * handle this in {@link DeviceAdminReceiver#onPasswordChanged}.
-     * 
+     *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_LIMIT_PASSWORD} to receive
      * this broadcast.
@@ -123,7 +123,7 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PASSWORD_CHANGED
             = "android.app.action.ACTION_PASSWORD_CHANGED";
-    
+
     /**
      * Action sent to a device administrator when the user has failed at
      * attempted to enter the password.  You can at this point check the
@@ -131,7 +131,7 @@
      * {@link DevicePolicyManager#getCurrentFailedPasswordAttempts
      * DevicePolicyManager.getCurrentFailedPasswordAttempts()}.  You will generally
      * handle this in {@link DeviceAdminReceiver#onPasswordFailed}.
-     * 
+     *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
      * this broadcast.
@@ -139,11 +139,11 @@
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_PASSWORD_FAILED
             = "android.app.action.ACTION_PASSWORD_FAILED";
-    
+
     /**
      * Action sent to a device administrator when the user has successfully
      * entered their password, after failing one or more times.
-     * 
+     *
      * <p>The calling device admin must have requested
      * {@link DeviceAdminInfo#USES_POLICY_WATCH_LOGIN} to receive
      * this broadcast.
@@ -165,15 +165,31 @@
             = "android.app.action.ACTION_PASSWORD_EXPIRING";
 
     /**
+     * Broadcast Action: This broadcast is sent to the newly created profile when
+     * the provisioning of a managed profile has completed successfully.
+     *
+     * <p>The broadcast is limited to the package which started the provisioning as specified in
+     * the extra {@link DevicePolicyManager#EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} of the
+     * {@link DevicePolicyManager#ACTION_PROVISION_MANAGED_PROFILE} intent that started the
+     * provisioning. It is also limited to the managed profile.
+     *
+     * <p>Input: Nothing.</p>
+     * <p>Output: Nothing</p>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PROFILE_PROVISIONING_COMPLETE =
+            "android.app.action.ACTION_PROFILE_PROVISIONING_COMPLETE";
+
+    /**
      * Name under which a DevicePolicy component publishes information
      * about itself.  This meta-data must reference an XML resource containing
      * a device-admin tag.  XXX TO DO: describe syntax.
      */
     public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
-    
+
     private DevicePolicyManager mManager;
     private ComponentName mWho;
-    
+
     /**
      * Retrieve the DevicePolicyManager interface for this administrator to work
      * with the system.
@@ -186,7 +202,7 @@
                 Context.DEVICE_POLICY_SERVICE);
         return mManager;
     }
-    
+
     /**
      * Retrieve the ComponentName describing who this device administrator is, for
      * use in {@link DevicePolicyManager} APIs that require the administrator to
@@ -199,7 +215,7 @@
         mWho = new ComponentName(context, getClass());
         return mWho;
     }
-    
+
     /**
      * Called after the administrator is first enabled, as a result of
      * receiving {@link #ACTION_DEVICE_ADMIN_ENABLED}.  At this point you
@@ -209,7 +225,7 @@
      */
     public void onEnabled(Context context, Intent intent) {
     }
-    
+
     /**
      * Called when the user has asked to disable the administrator, as a result of
      * receiving {@link #ACTION_DEVICE_ADMIN_DISABLE_REQUESTED}, giving you
@@ -224,7 +240,7 @@
     public CharSequence onDisableRequested(Context context, Intent intent) {
         return null;
     }
-    
+
     /**
      * Called prior to the administrator being disabled, as a result of
      * receiving {@link #ACTION_DEVICE_ADMIN_DISABLED}.  Upon return, you
@@ -235,7 +251,7 @@
      */
     public void onDisabled(Context context, Intent intent) {
     }
-    
+
     /**
      * Called after the user has changed their password, as a result of
      * receiving {@link #ACTION_PASSWORD_CHANGED}.  At this point you
@@ -247,7 +263,7 @@
      */
     public void onPasswordChanged(Context context, Intent intent) {
     }
-    
+
     /**
      * Called after the user has failed at entering their current password, as a result of
      * receiving {@link #ACTION_PASSWORD_FAILED}.  At this point you
@@ -258,7 +274,7 @@
      */
     public void onPasswordFailed(Context context, Intent intent) {
     }
-    
+
     /**
      * Called after the user has succeeded at entering their current password,
      * as a result of receiving {@link #ACTION_PASSWORD_SUCCEEDED}.  This will
@@ -292,6 +308,26 @@
     }
 
     /**
+     * Called on the new profile when managed profile provisioning has completed.
+     * Managed profile provisioning is the process of setting up the device so that it has a
+     * separate profile which is managed by the mobile device management(mdm) application that
+     * triggered the provisioning.
+     *
+     * <p>As part of provisioning a new profile is created, the mdm is moved to the new profile and
+     * set as the owner of the profile so that it has full control over it.
+     * This intent is only received by the mdm package that is set as profile owner during
+     * provisioning.
+     *
+     * <p>Provisioning can be triggered via an intent with the action
+     * android.managedprovisioning.ACTION_PROVISION_MANAGED_PROFILE.
+     *
+     * @param context The running context as per {@link #onReceive}.
+     * @param intent The received intent as per {@link #onReceive}.
+     */
+    public void onProfileProvisioningComplete(Context context, Intent intent) {
+    }
+
+    /**
      * Intercept standard device administrator broadcasts.  Implementations
      * should not override this method; it is better to implement the
      * convenience callbacks for each action.
@@ -299,6 +335,7 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         String action = intent.getAction();
+
         if (ACTION_PASSWORD_CHANGED.equals(action)) {
             onPasswordChanged(context, intent);
         } else if (ACTION_PASSWORD_FAILED.equals(action)) {
@@ -317,6 +354,8 @@
             onDisabled(context, intent);
         } else if (ACTION_PASSWORD_EXPIRING.equals(action)) {
             onPasswordExpiring(context, intent);
+        } else if (ACTION_PROFILE_PROVISIONING_COMPLETE.equals(action)) {
+            onProfileProvisioningComplete(context, intent);
         }
     }
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ab82531..30c84f6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -22,10 +22,12 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Handler;
+import android.os.Process;
 import android.os.RemoteCallback;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -75,6 +77,43 @@
     }
 
     /**
+     * Activity action: Starts the provisioning flow which sets up a managed profile.
+     * This intent will typically be sent by a mobile device management application(mdm).
+     * Managed profile provisioning creates a profile, moves the mdm to the profile,
+     * sets the mdm as the profile owner and removes all non required applications from the profile.
+     * As a profile owner the mdm than has full control over the managed profile.
+     *
+     * <p>The intent must contain the extras {@link #EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME} and
+     * {@link #EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME}.
+     *
+     * <p> When managed provisioning has completed, an intent of the type
+     * {@link DeviceAdminReceiver#ACTION_PROFILE_PROVISIONING_COMPLETE} is broadcasted to the
+     * mdm app on the managed profile.
+     *
+     * <p>Input: Nothing.</p>
+     * <p>Output: Nothing</p>
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_PROVISION_MANAGED_PROFILE
+        = "android.app.action.ACTION_PROVISION_MANAGED_PROFILE";
+
+    /**
+     * A String extra holding the name of the package of the mobile device management application
+     * that starts the managed provisioning flow. This package will be set as the profile owner.
+     * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}.
+     */
+    public static final String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME
+        = "deviceAdminPackageName";
+
+    /**
+     * A String extra holding the default name of the profile that is created during managed profile
+     * provisioning.
+     * <p>Use with {@link #ACTION_PROVISION_MANAGED_PROFILE}
+     */
+    public static final String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME
+        = "defaultManagedProfileName";
+
+    /**
      * Activity action: ask the user to add a new device administrator to the system.
      * The desired policy is the ComponentName of the policy in the
      * {@link #EXTRA_DEVICE_ADMIN} extra field.  This will invoke a UI to
@@ -1153,7 +1192,9 @@
                         }
                         exclSpec = listBuilder.toString();
                     }
-                    android.net.Proxy.validate(hostName, Integer.toString(port), exclSpec);
+                    if (android.net.Proxy.validate(hostName, Integer.toString(port), exclSpec)
+                            != android.net.Proxy.PROXY_VALID)
+                        throw new IllegalArgumentException();
                 }
                 return mService.setGlobalProxy(admin, hostSpec, exclSpec, UserHandle.myUserId());
             } catch (RemoteException e) {
@@ -1681,4 +1722,137 @@
         }
         return null;
     }
+
+    /**
+     * @hide
+     * Sets the given package as the profile owner of the given user profile. The package must
+     * already be installed and there shouldn't be an existing profile owner registered for this
+     * user. Also, this method must be called before the user has been used for the first time.
+     * @param packageName the package name of the application to be registered as profile owner.
+     * @param ownerName the human readable name of the organisation associated with this DPM.
+     * @param userHandle the userId to set the profile owner for.
+     * @return whether the package was successfully registered as the profile owner.
+     * @throws IllegalArgumentException if packageName is null, the package isn't installed, or
+     *         the user has already been set up.
+     */
+    public boolean setProfileOwner(String packageName, String ownerName, int userHandle)
+            throws IllegalArgumentException {
+        if (mService != null) {
+            try {
+                return mService.setProfileOwner(packageName, ownerName, userHandle);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to set profile owner", re);
+                throw new IllegalArgumentException("Couldn't set profile owner.", re);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Used to determine if a particular package is registered as the Profile Owner for the
+     * current user. A profile owner is a special device admin that has additional priviledges
+     * within the managed profile.
+     *
+     * @param packageName The package name of the app to compare with the registered profile owner.
+     * @return Whether or not the package is registered as the profile owner.
+     */
+    public boolean isProfileOwnerApp(String packageName) {
+        if (mService != null) {
+            try {
+                String profileOwnerPackage = mService.getProfileOwner(
+                        Process.myUserHandle().getIdentifier());
+                return profileOwnerPackage != null && profileOwnerPackage.equals(packageName);
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to check profile owner");
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     * @return the packageName of the owner of the given user profile or null if no profile
+     * owner has been set for that user.
+     * @throws IllegalArgumentException if the userId is invalid.
+     */
+    public String getProfileOwner() throws IllegalArgumentException {
+        if (mService != null) {
+            try {
+                return mService.getProfileOwner(Process.myUserHandle().getIdentifier());
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to get profile owner");
+                throw new IllegalArgumentException(
+                        "Requested profile owner for invalid userId", re);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     * @return the human readable name of the organisation associated with this DPM or null if
+     *         one is not set.
+     * @throws IllegalArgumentException if the userId is invalid.
+     */
+    public String getProfileOwnerName() throws IllegalArgumentException {
+        if (mService != null) {
+            try {
+                return mService.getProfileOwnerName(Process.myUserHandle().getIdentifier());
+            } catch (RemoteException re) {
+                Log.w(TAG, "Failed to get profile owner");
+                throw new IllegalArgumentException(
+                        "Requested profile owner for invalid userId", re);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Called by a profile owner or device owner to add a default intent handler activity for
+     * intents that match a certain intent filter. This activity will remain the default intent
+     * handler even if the set of potential event handlers for the intent filter changes and if
+     * the intent preferences are reset.
+     *
+     * <p>The default disambiguation mechanism takes over if the activity is not installed
+     * (anymore). When the activity is (re)installed, it is automatically reset as default
+     * intent handler for the filter.
+     *
+     * <p>The calling device admin must be a profile owner or device owner. If it is not, a
+     * security exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param filter The IntentFilter for which a default handler is added.
+     * @param activity The Activity that is added as default intent handler.
+     */
+    public void addPersistentPreferredActivity(ComponentName admin, IntentFilter filter,
+            ComponentName activity) {
+        if (mService != null) {
+            try {
+                mService.addPersistentPreferredActivity(admin, filter, activity);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
+
+    /**
+     * Called by a profile owner or device owner to remove all persistent intent handler preferences
+     * associated with the given package that were set by {@link #addPersistentPreferredActivity}.
+     *
+     * <p>The calling device admin must be a profile owner. If it is not, a security
+     * exception will be thrown.
+     *
+     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+     * @param packageName The name of the package for which preferences are removed.
+     */
+    public void clearPackagePersistentPreferredActivities(ComponentName admin,
+            String packageName) {
+        if (mService != null) {
+            try {
+                mService.clearPackagePersistentPreferredActivities(admin, packageName);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed talking with device policy service", e);
+            }
+        }
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 172c47c..8119585 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -18,6 +18,7 @@
 package android.app.admin;
 
 import android.content.ComponentName;
+import android.content.IntentFilter;
 import android.os.RemoteCallback;
 
 /**
@@ -103,6 +104,13 @@
     String getDeviceOwner();
     String getDeviceOwnerName();
 
+    boolean setProfileOwner(String packageName, String ownerName, int userHandle);
+    String getProfileOwner(int userHandle);
+    String getProfileOwnerName(int userHandle);
+
     boolean installCaCert(in byte[] certBuffer);
     void uninstallCaCert(in byte[] certBuffer);
+
+    void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
+    void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
 }
diff --git a/core/java/android/app/backup/BackupDataOutput.java b/core/java/android/app/backup/BackupDataOutput.java
index 3a070b6..845784f 100644
--- a/core/java/android/app/backup/BackupDataOutput.java
+++ b/core/java/android/app/backup/BackupDataOutput.java
@@ -17,6 +17,7 @@
 package android.app.backup;
 
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -76,13 +77,19 @@
     /**
      * Mark the beginning of one record in the backup data stream. This must be called before
      * {@link #writeEntityData}.
-     * @param key A string key that uniquely identifies the data record within the application
+     * @param key A string key that uniquely identifies the data record within the application.
+     *    Keys whose first character is \uFF00 or higher are not valid.
      * @param dataSize The size in bytes of this record's data.  Passing a dataSize
      *    of -1 indicates that the record under this key should be deleted.
      * @return The number of bytes written to the backup stream
      * @throws IOException if the write failed
      */
     public int writeEntityHeader(String key, int dataSize) throws IOException {
+        if (key != null && key.charAt(0) >= 0xff00) {
+            if (Process.myUid() != Process.SYSTEM_UID) {
+                throw new IllegalArgumentException("Invalid key " + key);
+            }
+        }
         int result = writeEntityHeader_native(mBackupWriter, key, dataSize);
         if (result >= 0) {
             return result;
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index cb0737e..cfd0a65 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -16,9 +16,6 @@
 
 package android.app.backup;
 
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index 12ee3b6..c629a2e 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -167,7 +167,7 @@
      *     are to be backed up.  The <code>allApps</code> parameter supersedes this.
      */
     void fullBackup(in ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
-            boolean includeShared, boolean allApps, boolean allIncludesSystem,
+            boolean includeShared, boolean doWidgets, boolean allApps, boolean allIncludesSystem,
             in String[] packageNames);
 
     /**
diff --git a/core/java/android/app/backup/SharedPreferencesBackupHelper.java b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
index 213bd31..939616b 100644
--- a/core/java/android/app/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/app/backup/SharedPreferencesBackupHelper.java
@@ -18,7 +18,6 @@
 
 import android.app.QueuedWork;
 import android.content.Context;
-import android.content.SharedPreferences;
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
diff --git a/core/java/android/app/maintenance/IIdleCallback.aidl b/core/java/android/app/maintenance/IIdleCallback.aidl
new file mode 100644
index 0000000..582dede
--- /dev/null
+++ b/core/java/android/app/maintenance/IIdleCallback.aidl
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.maintenance;
+
+import android.app.maintenance.IIdleService;
+
+/**
+ * The server side of the idle maintenance IPC protocols.  The app-side implementation
+ * invokes on this interface to indicate completion of the (asynchronous) instructions
+ * issued by the server.
+ *
+ * In all cases, the 'who' parameter is the caller's service binder, used to track
+ * which idle service instance is reporting.
+ *
+ * {@hide}
+ */
+interface IIdleCallback {
+    /**
+     * Acknowledge receipt and processing of the asynchronous "start idle work" incall.
+     * 'result' is true if the app wants some time to perform ongoing background
+     * idle-time work; or false if the app declares that it does not need any time
+     * for such work.
+     */
+    void acknowledgeStart(int token, boolean result);
+
+    /**
+     * Acknowledge receipt and processing of the asynchronous "stop idle work" incall.
+     */
+    void acknowledgeStop(int token);
+
+    /*
+     * Tell the idle service manager that we're done with our idle maintenance, so that
+     * it can go on to the next one and stop attributing wakelock time to us etc.
+     *
+     * @param opToken The identifier passed in the startIdleMaintenance() call that
+     *        indicated the beginning of this service's idle timeslice.
+     */
+    void idleFinished(int token);
+}
diff --git a/core/java/android/app/maintenance/IIdleService.aidl b/core/java/android/app/maintenance/IIdleService.aidl
new file mode 100644
index 0000000..54abccd
--- /dev/null
+++ b/core/java/android/app/maintenance/IIdleService.aidl
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.maintenance;
+
+import android.app.maintenance.IIdleCallback;
+
+/**
+ * Interface that the framework uses to communicate with application code
+ * that implements an idle-time "maintenance" service.  End user code does
+ * not implement this interface directly; instead, the app's idle service
+ * implementation will extend android.app.maintenance.IdleService.
+ * {@hide}
+ */
+oneway interface IIdleService {
+    /**
+     * Begin your idle-time work.
+     */
+    void startIdleMaintenance(IIdleCallback callbackBinder, int token);
+    void stopIdleMaintenance(IIdleCallback callbackBinder, int token);
+}
diff --git a/core/java/android/app/maintenance/IdleService.java b/core/java/android/app/maintenance/IdleService.java
new file mode 100644
index 0000000..2331b81
--- /dev/null
+++ b/core/java/android/app/maintenance/IdleService.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.maintenance;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.app.Service;
+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.util.Log;
+import android.util.Slog;
+
+/**
+ * Idle maintenance API.  Full docs TBW (to be written).
+ */
+public abstract class IdleService extends Service {
+    private static final String TAG = "IdleService";
+
+    static final int MSG_START = 1;
+    static final int MSG_STOP = 2;
+    static final int MSG_FINISH = 3;
+
+    IdleHandler mHandler;
+    IIdleCallback mCallbackBinder;
+    int mToken;
+    final Object mHandlerLock = new Object();
+
+    void ensureHandler() {
+        synchronized (mHandlerLock) {
+            if (mHandler == null) {
+                mHandler = new IdleHandler(getMainLooper());
+            }
+        }
+    }
+
+    /**
+     * TBW: the idle service should supply an intent-filter handling this intent
+     * <p>
+     * <p class="note">The application must also protect the idle service with the
+     * {@code "android.permission.BIND_IDLE_SERVICE"} permission to ensure that other
+     * applications cannot maliciously bind to it.  If an idle service's manifest
+     * declaration does not require that permission, it will never be invoked.
+     * </p>
+     */
+    @SdkConstant(SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.service.idle.IdleService";
+
+    /**
+     * Idle services must be protected with this permission:
+     *
+     * <pre class="prettyprint">
+     *     <service android:name="MyIdleService"
+     *              android:permission="android.permission.BIND_IDLE_SERVICE" >
+     *         ...
+     *     </service>
+     * </pre>
+     *
+     * <p>If an idle service is declared in the manifest but not protected with this
+     * permission, that service will be ignored by the OS.
+     */
+    public static final String PERMISSION_BIND =
+            "android.permission.BIND_IDLE_SERVICE";
+
+    // Trampoline: the callbacks are always run on the main thread
+    IIdleService mBinder = new IIdleService.Stub() {
+        @Override
+        public void startIdleMaintenance(IIdleCallback callbackBinder, int token)
+                throws RemoteException {
+            ensureHandler();
+            Message msg = mHandler.obtainMessage(MSG_START, token, 0, callbackBinder);
+            mHandler.sendMessage(msg);
+        }
+
+        @Override
+        public void stopIdleMaintenance(IIdleCallback callbackBinder, int token)
+                throws RemoteException {
+            ensureHandler();
+            Message msg = mHandler.obtainMessage(MSG_STOP, token, 0, callbackBinder);
+            mHandler.sendMessage(msg);
+        }
+    };
+
+    /**
+     * Your application may begin doing "idle" maintenance work in the background.
+     * <p>
+     * Your application may continue to run in the background until it receives a call
+     * to {@link #onIdleStop()}, at which point you <i>must</i> cease doing work.  The
+     * OS will hold a wakelock on your application's behalf from the time this method is
+     * called until after the following call to {@link #onIdleStop()} returns.
+     * </p>
+     * <p>
+     * Returning {@code false} from this method indicates that you have no ongoing work
+     * to do at present.  The OS will respond by immediately calling {@link #onIdleStop()}
+     * and returning your application to its normal stopped state.  Returning {@code true}
+     * indicates that the application is indeed performing ongoing work, so the OS will
+     * let your application run in this state until it's no longer appropriate.
+     * </p>
+     * <p>
+     * You will always receive a matching call to {@link #onIdleStop()} even if your
+     * application returns {@code false} from this method.
+     *
+     * @return {@code true} to indicate that the application wishes to perform some ongoing
+     *     background work; {@code false} to indicate that it does not need to perform such
+     *     work at present.
+     */
+    public abstract boolean onIdleStart();
+
+    /**
+     * Your app's maintenance opportunity is over.  Once the application returns from
+     * this method, the wakelock held by the OS on its behalf will be released.
+     */
+    public abstract void onIdleStop();
+
+    /**
+     * Tell the OS that you have finished your idle work.  Calling this more than once,
+     * or calling it when you have not received an {@link #onIdleStart()} callback, is
+     * an error.
+     *
+     * <p>It is safe to call {@link #finishIdle()} from any thread.
+     */
+    public final void finishIdle() {
+        ensureHandler();
+        mHandler.sendEmptyMessage(MSG_FINISH);
+    }
+
+    class IdleHandler extends Handler {
+        IdleHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_START: {
+                    // Call the concrete onIdleStart(), reporting its return value back to
+                    // the OS.  If onIdleStart() throws, report it as a 'false' return but
+                    // rethrow the exception at the offending app.
+                    boolean result = false;
+                    IIdleCallback callbackBinder = (IIdleCallback) msg.obj;
+                    mCallbackBinder = callbackBinder;
+                    final int token = mToken = msg.arg1;
+                    try {
+                        result = IdleService.this.onIdleStart();
+                    } catch (Exception e) {
+                        Log.e(TAG, "Unable to start idle workload", e);
+                        throw new RuntimeException(e);
+                    } finally {
+                        // don't bother if the service already called finishIdle()
+                        if (mCallbackBinder != null) {
+                            try {
+                                callbackBinder.acknowledgeStart(token, result);
+                            } catch (RemoteException re) {
+                                Log.e(TAG, "System unreachable to start idle workload");
+                            }
+                        }
+                    }
+                    break;
+                }
+
+                case MSG_STOP: {
+                    // Structured just like MSG_START for the stop-idle bookend call.
+                    IIdleCallback callbackBinder = (IIdleCallback) msg.obj;
+                    final int token = msg.arg1;
+                    try {
+                        IdleService.this.onIdleStop();
+                    } catch (Exception e) {
+                        Log.e(TAG, "Unable to stop idle workload", e);
+                        throw new RuntimeException(e);
+                    } finally {
+                        if (mCallbackBinder != null) {
+                            try {
+                                callbackBinder.acknowledgeStop(token);
+                            } catch (RemoteException re) {
+                                Log.e(TAG, "System unreachable to stop idle workload");
+                            }
+                        }
+                    }
+                    break;
+                }
+
+                case MSG_FINISH: {
+                    if (mCallbackBinder != null) {
+                        try {
+                            mCallbackBinder.idleFinished(mToken);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "System unreachable to finish idling");
+                        } finally {
+                            mCallbackBinder = null;
+                        }
+                    } else {
+                        Log.e(TAG, "finishIdle() called but the idle service is not started");
+                    }
+                    break;
+                }
+
+                default: {
+                    Slog.w(TAG, "Unknown message " + msg.what);
+                }
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return mBinder.asBinder();
+    }
+
+}
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index f104d71..84d3835 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -19,7 +19,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
-import android.app.ActivityThread;
 import android.content.Context;
 import android.os.Binder;
 import android.os.Handler;
@@ -31,7 +30,6 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.TypedValue;
 import android.widget.RemoteViews;
 import android.widget.RemoteViews.OnClickHandler;
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index d1c7bec..dd3a871 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -16,7 +16,6 @@
 
 package android.appwidget;
 
-import android.app.ActivityManagerNative;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -215,6 +214,12 @@
     public static final String EXTRA_CUSTOM_INFO = "customInfo";
 
     /**
+     * An intent extra attached to the {@link #ACTION_APPWIDGET_HOST_RESTORED} broadcast,
+     * indicating the integer ID of the host whose widgets have just been restored.
+     */
+    public static final String EXTRA_HOST_ID = "hostId";
+
+    /**
      * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
      * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are
      * installed.  It will be added to the extras object on the {@link android.content.Intent}
@@ -311,6 +316,86 @@
     public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
 
     /**
+     * Sent to providers after AppWidget state related to the provider has been restored from
+     * backup. The intent contains information about how to translate AppWidget ids from the
+     * restored data to their new equivalents.
+     *
+     * <p>The intent will contain the following extras:
+     *
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
+     *     <td>The set of appWidgetIds represented in a restored backup that have been successfully
+     *     incorporated into the current environment.  This may be all of the AppWidgets known
+     *     to this application, or just a subset.  Each entry in this array of appWidgetIds has
+     *     a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
+     *  </tr>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
+     *     <td>The set of appWidgetIds now valid for this application.  The app should look at
+     *     its restored widget configuration and translate each appWidgetId in the
+     *     {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
+     *     index within this array.</td>
+     *  </tr>
+     * </table>
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * @see {@link #ACTION_APPWIDGET_HOST_RESTORED} for the corresponding host broadcast
+     */
+    public static final String ACTION_APPWIDGET_RESTORED
+            = "android.appwidget.action.APPWIDGET_RESTORED";
+
+    /**
+     * Sent to widget hosts after AppWidget state related to the host has been restored from
+     * backup. The intent contains information about how to translate AppWidget ids from the
+     * restored data to their new equivalents.  If an application maintains multiple separate
+     * widget hosts instances, it will receive this broadcast separately for each one.
+     *
+     * <p>The intent will contain the following extras:
+     *
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td>
+     *     <td>The set of appWidgetIds represented in a restored backup that have been successfully
+     *     incorporated into the current environment.  This may be all of the AppWidgets known
+     *     to this application, or just a subset.  Each entry in this array of appWidgetIds has
+     *     a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td>
+     *  </tr>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
+     *     <td>The set of appWidgetIds now valid for this application.  The app should look at
+     *     its restored widget configuration and translate each appWidgetId in the
+     *     {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding
+     *     index within this array.</td>
+     *  </tr>
+     *  <tr>
+     *     <td>{@link #EXTRA_HOST_ID}</td>
+     *     <td>The integer ID of the widget host instance whose state has just been restored.</td>
+     *  </tr>
+     * </table>
+     *
+     * <p class="note">This is a protected intent that can only be sent
+     * by the system.
+     *
+     * @see {@link #ACTION_APPWIDGET_RESTORED} for the corresponding provider broadcast
+     */
+    public static final String ACTION_APPWIDGET_HOST_RESTORED
+            = "android.appwidget.action.APPWIDGET_HOST_RESTORED";
+
+    /**
+     * An intent extra that contains multiple appWidgetIds.  These are id values as
+     * they were provided to the application during a recent restore from backup.  It is
+     * attached to the {@link #ACTION_APPWIDGET_RESTORED} broadcast intent.
+     *
+     * <p>
+     * The value will be an int array that can be retrieved like this:
+     * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
+     */
+    public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
+
+    /**
      * Field for the manifest meta-data tag.
      *
      * @see AppWidgetProviderInfo
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
index edf142b..ab91edf 100644
--- a/core/java/android/appwidget/AppWidgetProvider.java
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -66,15 +66,13 @@
                     this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
                 }
             }
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
             Bundle extras = intent.getExtras();
             if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) {
                 final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
                 this.onDeleted(context, new int[] { appWidgetId });
             }
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED.equals(action)) {
             Bundle extras = intent.getExtras();
             if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)
                     && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS)) {
@@ -83,19 +81,28 @@
                 this.onAppWidgetOptionsChanged(context, AppWidgetManager.getInstance(context),
                         appWidgetId, widgetExtras);
             }
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
             this.onEnabled(context);
-        }
-        else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
+        } else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
             this.onDisabled(context);
+        } else if (AppWidgetManager.ACTION_APPWIDGET_RESTORED.equals(action)) {
+            Bundle extras = intent.getExtras();
+            if (extras != null) {
+                int[] oldIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS);
+                int[] newIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
+                if (oldIds != null && oldIds.length > 0) {
+                    this.onRestored(context, oldIds, newIds);
+                    this.onUpdate(context, AppWidgetManager.getInstance(context), newIds);
+                }
+            }
         }
     }
     // END_INCLUDE(onReceive)
 
     /**
-     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} broadcast when
-     * this AppWidget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} and
+     * {@link AppWidgetManager#ACTION_APPWIDGET_RESTORED} broadcasts when this AppWidget
+     * provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
      * for a set of AppWidgets.  Override this method to implement your own AppWidget functionality.
      *
      * {@more}
@@ -123,8 +130,8 @@
      *                  running.
      * @param appWidgetManager A {@link AppWidgetManager} object you can call {@link
      *                  AppWidgetManager#updateAppWidget} on.
-     * @param appWidgetId The appWidgetId of the widget who's size changed.
-     * @param newOptions The appWidgetId of the widget who's size changed.
+     * @param appWidgetId The appWidgetId of the widget whose size changed.
+     * @param newOptions The appWidgetId of the widget whose size changed.
      *
      * @see AppWidgetManager#ACTION_APPWIDGET_OPTIONS_CHANGED
      */
@@ -181,4 +188,24 @@
      */
     public void onDisabled(Context context) {
     }
+
+    /**
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_RESTORED} broadcast
+     * when instances of this AppWidget provider have been restored from backup.  If your
+     * provider maintains any persistent data about its widget instances, override this method
+     * to remap the old AppWidgetIds to the new values and update any other app state that may
+     * be relevant.
+     *
+     * <p>This callback will be followed immediately by a call to {@link #onUpdate} so your
+     * provider can immediately generate new RemoteViews suitable for its newly-restored set
+     * of instances.
+     *
+     * {@more}
+     *
+     * @param context
+     * @param oldWidgetIds
+     * @param newWidgetIds
+     */
+    public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
+    }
 }
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index 7b8b286..4b33799 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -172,7 +172,7 @@
      * <p>This field corresponds to the <code>android:previewImage</code> attribute in
      * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
      */
-	public int previewImage;
+    public int previewImage;
 
     /**
      * The rules by which a widget can be resized. See {@link #RESIZE_NONE},
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index 6f929f2..7b709ac 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -162,7 +162,8 @@
         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)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 75b007c..a4374b8 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -19,11 +19,9 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
-import android.os.Message;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -39,7 +37,6 @@
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 import java.util.UUID;
 
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index d789a944..a396a05 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -19,12 +19,10 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.IOException;
@@ -947,8 +945,13 @@
       *               was started.
       */
      public boolean fetchUuidsWithSdp() {
+        IBluetooth service = sService;
+        if (service == null) {
+            Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
+            return false;
+        }
         try {
-            return sService.fetchRemoteUuids(this);
+            return service.fetchRemoteUuids(this);
         } catch (RemoteException e) {Log.e(TAG, "", e);}
             return false;
     }
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index ae6ad3b..39305b0 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -16,20 +16,9 @@
 
 package android.bluetooth;
 
-import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
index f0ecbb4..a86677c 100644
--- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java
+++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java
@@ -16,7 +16,6 @@
 package android.bluetooth;
 
 import java.util.ArrayList;
-import java.util.IllegalFormatConversionException;
 import java.util.List;
 import java.util.UUID;
 
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 153215c..0c00c06 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -19,18 +19,9 @@
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
-import android.bluetooth.BluetoothProfile.ServiceListener;
-import android.bluetooth.IBluetoothManager;
-import android.bluetooth.IBluetoothStateChangeCallback;
-
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index f9f1d97..fc3ffe8 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -18,8 +18,6 @@
 
 import android.bluetooth.BluetoothDevice;
 
-import android.util.Log;
-
 /**
  * This abstract class is used to implement {@link BluetoothGattServer} callbacks.
  */
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 8ee955d..f88a173 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -280,7 +280,8 @@
         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)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Headset Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index 2e950fa..4949c24 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -23,7 +23,6 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -488,7 +487,8 @@
         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)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Health Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index c48b15d..554df3e 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -24,7 +24,6 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -260,7 +259,8 @@
         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)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 92a2f1e..7f57acf 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -22,9 +22,7 @@
 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.os.*;
 import android.util.Log;
 
 /**
@@ -106,7 +104,8 @@
         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)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth MAP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index b7a37f4..4f81f98 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -24,7 +24,6 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -146,7 +145,8 @@
         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)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Pan Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index 7f45652..dc01fc7 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -22,7 +22,6 @@
 import android.content.ServiceConnection;
 import android.os.RemoteException;
 import android.os.IBinder;
-import android.os.ServiceManager;
 import android.util.Log;
 
 /**
@@ -161,7 +160,8 @@
         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)) {
+        if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
+                android.os.Process.myUserHandle())) {
             Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 96be8a2..bc56e55 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -17,7 +17,6 @@
 package android.bluetooth;
 
 import android.os.Handler;
-import android.os.Message;
 import android.os.ParcelUuid;
 
 import java.io.Closeable;
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 1e75fc2..f532f7c 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -16,21 +16,16 @@
 
 package android.bluetooth;
 
-import android.os.IBinder;
 import android.os.ParcelUuid;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.Log;
 
 import java.io.Closeable;
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
 import android.net.LocalSocket;
@@ -462,8 +457,10 @@
                     mSocket.close();
                     mSocket = null;
                 }
-                if(mPfd != null)
-                    mPfd.detachFd();
+                if (mPfd != null) {
+                    mPfd.close();
+                    mPfd = null;
+                }
            }
         }
     }
diff --git a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
index a9b7176..6dd551e 100644
--- a/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
+++ b/core/java/android/bluetooth/BluetoothTetheringDataTracker.java
@@ -17,9 +17,6 @@
 package android.bluetooth;
 
 import android.net.BaseNetworkStateTracker;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.os.INetworkManagementService;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.DhcpResults;
@@ -35,11 +32,6 @@
 import android.os.Messenger;
 import android.text.TextUtils;
 import android.util.Log;
-import java.net.InterfaceAddress;
-import android.net.LinkAddress;
-import android.net.RouteInfo;
-import java.net.Inet4Address;
-import android.os.SystemProperties;
 
 import com.android.internal.util.AsyncChannel;
 
@@ -143,11 +135,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
diff --git a/core/java/android/content/AsyncTaskLoader.java b/core/java/android/content/AsyncTaskLoader.java
index eb7426e..7241e0d 100644
--- a/core/java/android/content/AsyncTaskLoader.java
+++ b/core/java/android/content/AsyncTaskLoader.java
@@ -20,7 +20,7 @@
 import android.os.Handler;
 import android.os.OperationCanceledException;
 import android.os.SystemClock;
-import android.util.Slog;
+import android.util.Log;
 import android.util.TimeUtils;
 
 import java.io.FileDescriptor;
@@ -64,10 +64,10 @@
         /* Runs on a worker thread */
         @Override
         protected D doInBackground(Void... params) {
-            if (DEBUG) Slog.v(TAG, this + " >>> doInBackground");
+            if (DEBUG) Log.v(TAG, this + " >>> doInBackground");
             try {
                 D data = AsyncTaskLoader.this.onLoadInBackground();
-                if (DEBUG) Slog.v(TAG, this + "  <<< doInBackground");
+                if (DEBUG) Log.v(TAG, this + "  <<< doInBackground");
                 return data;
             } catch (OperationCanceledException ex) {
                 if (!isCancelled()) {
@@ -79,7 +79,7 @@
                     // So we treat this case as an unhandled exception.
                     throw ex;
                 }
-                if (DEBUG) Slog.v(TAG, this + "  <<< doInBackground (was canceled)", ex);
+                if (DEBUG) Log.v(TAG, this + "  <<< doInBackground (was canceled)", ex);
                 return null;
             }
         }
@@ -87,7 +87,7 @@
         /* Runs on the UI thread */
         @Override
         protected void onPostExecute(D data) {
-            if (DEBUG) Slog.v(TAG, this + " onPostExecute");
+            if (DEBUG) Log.v(TAG, this + " onPostExecute");
             try {
                 AsyncTaskLoader.this.dispatchOnLoadComplete(this, data);
             } finally {
@@ -98,7 +98,7 @@
         /* Runs on the UI thread */
         @Override
         protected void onCancelled(D data) {
-            if (DEBUG) Slog.v(TAG, this + " onCancelled");
+            if (DEBUG) Log.v(TAG, this + " onCancelled");
             try {
                 AsyncTaskLoader.this.dispatchOnCancelled(this, data);
             } finally {
@@ -162,18 +162,18 @@
         super.onForceLoad();
         cancelLoad();
         mTask = new LoadTask();
-        if (DEBUG) Slog.v(TAG, "Preparing load: mTask=" + mTask);
+        if (DEBUG) Log.v(TAG, "Preparing load: mTask=" + mTask);
         executePendingTask();
     }
 
     @Override
     protected boolean onCancelLoad() {
-        if (DEBUG) Slog.v(TAG, "onCancelLoad: mTask=" + mTask);
+        if (DEBUG) Log.v(TAG, "onCancelLoad: mTask=" + mTask);
         if (mTask != null) {
             if (mCancellingTask != null) {
                 // There was a pending task already waiting for a previous
                 // one being canceled; just drop it.
-                if (DEBUG) Slog.v(TAG,
+                if (DEBUG) Log.v(TAG,
                         "cancelLoad: still waiting for cancelled task; dropping next");
                 if (mTask.waiting) {
                     mTask.waiting = false;
@@ -184,14 +184,14 @@
             } else if (mTask.waiting) {
                 // There is a task, but it is waiting for the time it should
                 // execute.  We can just toss it.
-                if (DEBUG) Slog.v(TAG, "cancelLoad: task is waiting, dropping it");
+                if (DEBUG) Log.v(TAG, "cancelLoad: task is waiting, dropping it");
                 mTask.waiting = false;
                 mHandler.removeCallbacks(mTask);
                 mTask = null;
                 return false;
             } else {
                 boolean cancelled = mTask.cancel(false);
-                if (DEBUG) Slog.v(TAG, "cancelLoad: cancelled=" + cancelled);
+                if (DEBUG) Log.v(TAG, "cancelLoad: cancelled=" + cancelled);
                 if (cancelled) {
                     mCancellingTask = mTask;
                     cancelLoadInBackground();
@@ -223,7 +223,7 @@
                 long now = SystemClock.uptimeMillis();
                 if (now < (mLastLoadCompleteTime+mUpdateThrottle)) {
                     // Not yet time to do another load.
-                    if (DEBUG) Slog.v(TAG, "Waiting until "
+                    if (DEBUG) Log.v(TAG, "Waiting until "
                             + (mLastLoadCompleteTime+mUpdateThrottle)
                             + " to execute: " + mTask);
                     mTask.waiting = true;
@@ -231,7 +231,7 @@
                     return;
                 }
             }
-            if (DEBUG) Slog.v(TAG, "Executing: " + mTask);
+            if (DEBUG) Log.v(TAG, "Executing: " + mTask);
             mTask.executeOnExecutor(mExecutor, (Void[]) null);
         }
     }
@@ -239,11 +239,11 @@
     void dispatchOnCancelled(LoadTask task, D data) {
         onCanceled(data);
         if (mCancellingTask == task) {
-            if (DEBUG) Slog.v(TAG, "Cancelled task is now canceled!");
+            if (DEBUG) Log.v(TAG, "Cancelled task is now canceled!");
             rollbackContentChanged();
             mLastLoadCompleteTime = SystemClock.uptimeMillis();
             mCancellingTask = null;
-            if (DEBUG) Slog.v(TAG, "Delivering cancellation");
+            if (DEBUG) Log.v(TAG, "Delivering cancellation");
             deliverCancellation();
             executePendingTask();
         }
@@ -251,7 +251,7 @@
 
     void dispatchOnLoadComplete(LoadTask task, D data) {
         if (mTask != task) {
-            if (DEBUG) Slog.v(TAG, "Load complete of old task, trying to cancel");
+            if (DEBUG) Log.v(TAG, "Load complete of old task, trying to cancel");
             dispatchOnCancelled(task, data);
         } else {
             if (isAbandoned()) {
@@ -261,7 +261,7 @@
                 commitContentChanged();
                 mLastLoadCompleteTime = SystemClock.uptimeMillis();
                 mTask = null;
-                if (DEBUG) Slog.v(TAG, "Delivering result");
+                if (DEBUG) Log.v(TAG, "Delivering result");
                 deliverResult(data);
             }
         }
diff --git a/core/java/android/content/ClipboardManager.java b/core/java/android/content/ClipboardManager.java
index 73e6fd0..5653cad 100644
--- a/core/java/android/content/ClipboardManager.java
+++ b/core/java/android/content/ClipboardManager.java
@@ -22,8 +22,6 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.ServiceManager;
-import android.os.StrictMode;
-import android.util.Log;
 
 import java.util.ArrayList;
 
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 2bf4d7d..f3c803d 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -141,7 +141,7 @@
     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";
+    public static final String SYNC_EXTRAS_DISALLOW_METERED = "allow_metered";
 
     /**
      * Set by the SyncManager to request that the SyncAdapter initialize itself for
@@ -192,6 +192,14 @@
      */
     public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir";
 
+    /**
+     * This is the Android platform's generic MIME type to match any MIME
+     * type of the form "{@link #CURSOR_ITEM_BASE_TYPE}/{@code SUB_TYPE}".
+     * {@code SUB_TYPE} is the sub-type of the application-dependent
+     * content, e.g., "audio", "video", "playlist".
+     */
+    public static final String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*";
+
     /** @hide */
     public static final int SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS = 1;
     /** @hide */
@@ -368,9 +376,7 @@
     }
 
     /**
-     * <p>
      * Query the given URI, returning a {@link Cursor} over the result set.
-     * </p>
      * <p>
      * For best performance, the caller should follow these guidelines:
      * <ul>
@@ -405,9 +411,8 @@
     }
 
     /**
-     * <p>
-     * Query the given URI, returning a {@link Cursor} over the result set.
-     * </p>
+     * Query the given URI, returning a {@link Cursor} over the result set
+     * with optional support for cancellation.
      * <p>
      * For best performance, the caller should follow these guidelines:
      * <ul>
@@ -1751,7 +1756,7 @@
             new SyncRequest.Builder()
                 .setSyncAdapter(account, authority)
                 .setExtras(extras)
-                .syncOnce()
+                .syncOnce()     // Immediate sync.
                 .build();
         requestSync(request);
     }
@@ -1759,9 +1764,6 @@
     /**
      * 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 {
@@ -1829,12 +1831,25 @@
      */
     public static void cancelSync(Account account, String authority) {
         try {
-            getContentService().cancelSync(account, authority);
+            getContentService().cancelSync(account, authority, null);
         } catch (RemoteException e) {
         }
     }
 
     /**
+     * Cancel any active or pending syncs that are running on this service.
+     *
+     * @param cname the service for which to cancel all active/pending operations.
+     */
+    public static void cancelSync(ComponentName cname) {
+        try {
+            getContentService().cancelSync(null, null, cname);
+        } catch (RemoteException e) {
+            
+        }
+    }
+
+    /**
      * Get information about the SyncAdapters that are known to the system.
      * @return an array of SyncAdapters that have registered with the system
      */
@@ -1897,12 +1912,13 @@
      * {@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}.
+     * <p>The bundle for a periodic sync can be queried by applications with the correct
+     * permissions using
+     * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no
+     * sensitive data should be transferred here.
      *
      * @param account the account to specify in the sync
      * @param authority the provider to specify in the sync request
@@ -1932,6 +1948,26 @@
     }
 
     /**
+     * {@hide}
+     * Helper function to throw an <code>IllegalArgumentException</code> if any illegal
+     * extras were set for a periodic sync.
+     *
+     * @param extras bundle to validate.
+     */
+    public static boolean invalidPeriodicExtras(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)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
      * Remove a periodic sync. Has no affect if account, authority and extras don't match
      * an existing periodic sync.
      * <p>This method requires the caller to hold the permission
@@ -1951,6 +1987,31 @@
     }
 
     /**
+     * Remove the specified sync. This will cancel any pending or active syncs. If the request is
+     * for a periodic sync, this call will remove any future occurrences.
+     * <p>If a periodic sync is specified, the caller must hold the permission
+     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}. If this SyncRequest targets a
+     * SyncService adapter,the calling application must be signed with the same certificate as the
+     * adapter.
+     *</p>It is possible to cancel a sync using a SyncRequest object that is not the same object
+     * with which you requested the sync. Do so by building a SyncRequest with the same
+     * service/adapter, frequency, <b>and</b> extras bundle.
+     *
+     * @param request SyncRequest object containing information about sync to cancel.
+     */
+    public static void cancelSync(SyncRequest request) {
+        if (request == null) {
+            throw new IllegalArgumentException("request cannot be null");
+        }
+        try {
+            getContentService().cancelRequest(request);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+    /**
      * Get the list of information about the periodic syncs for the given account and authority.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#READ_SYNC_SETTINGS}.
@@ -1961,7 +2022,23 @@
      */
     public static List<PeriodicSync> getPeriodicSyncs(Account account, String authority) {
         try {
-            return getContentService().getPeriodicSyncs(account, authority);
+            return getContentService().getPeriodicSyncs(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
+     * Return periodic syncs associated with the provided component.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     */
+    public static List<PeriodicSync> getPeriodicSyncs(ComponentName cname) {
+        if (cname == null) {
+            throw new IllegalArgumentException("Component must not be null");
+        }
+        try {
+            return getContentService().getPeriodicSyncs(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -1997,6 +2074,38 @@
     }
 
     /**
+     * Set whether the provided {@link SyncService} is available to process work.
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#WRITE_SYNC_SETTINGS}.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     */
+    public static void setServiceActive(ComponentName cname, boolean active) {
+        try {
+            getContentService().setServiceActive(cname, active);
+        } catch (RemoteException e) {
+            // exception ignored; if this is thrown then it means the runtime is in the midst of
+            // being restarted
+        }
+    }
+
+    /**
+     * Query the state of this sync service.
+     * <p>Set with {@link #setServiceActive(ComponentName cname, boolean active)}.
+     * <p>The calling application must be signed with the same certificate as the target component,
+     * otherwise this call will fail.
+     * @param cname ComponentName referring to a {@link SyncService}
+     * @return true if jobs will be run on this service, false otherwise.
+     */
+    public static boolean isServiceActive(ComponentName cname) {
+        try {
+            return getContentService().isServiceActive(cname);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    /**
      * Gets the master auto-sync setting that applies to all the providers and accounts.
      * If this is false then the per-provider auto-sync setting is ignored.
      * <p>This method requires the caller to hold the permission
@@ -2030,8 +2139,8 @@
     }
 
     /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority in the pending list, or actively being processed.
+     * Returns true if there is currently a sync operation for the given account or authority
+     * actively being processed.
      * <p>This method requires the caller to hold the permission
      * {@link android.Manifest.permission#READ_SYNC_STATS}.
      * @param account the account whose setting we are querying
@@ -2039,8 +2148,26 @@
      * @return true if a sync is active for the given account or authority.
      */
     public static boolean isSyncActive(Account account, String authority) {
+        if (account == null) {
+            throw new IllegalArgumentException("account must not be null");
+        }
+        if (authority == null) {
+            throw new IllegalArgumentException("authority must not be null");
+        }
+
         try {
-            return getContentService().isSyncActive(account, authority);
+            return getContentService().isSyncActive(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static boolean isSyncActive(ComponentName cname) {
+        if (cname == null) {
+            throw new IllegalArgumentException("component name must not be null");
+        }
+        try {
+            return getContentService().isSyncActive(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -2098,7 +2225,7 @@
      */
     public static SyncStatusInfo getSyncStatus(Account account, String authority) {
         try {
-            return getContentService().getSyncStatus(account, authority);
+            return getContentService().getSyncStatus(account, authority, null);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
@@ -2114,7 +2241,15 @@
      */
     public static boolean isSyncPending(Account account, String authority) {
         try {
-            return getContentService().isSyncPending(account, authority);
+            return getContentService().isSyncPending(account, authority, null);
+        } catch (RemoteException e) {
+            throw new RuntimeException("the ContentService should always be reachable", e);
+        }
+    }
+
+    public static boolean isSyncPending(ComponentName cname) {
+        try {
+            return getContentService().isSyncPending(null, null, cname);
         } catch (RemoteException e) {
             throw new RuntimeException("the ContentService should always be reachable", e);
         }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f4b1afe..9f0c384 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -16,6 +16,10 @@
 
 package android.content;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringDef;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -47,6 +51,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * Interface to global information about an application environment.  This is
@@ -132,6 +138,20 @@
      */
     public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0x0008;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                BIND_AUTO_CREATE,
+                BIND_AUTO_CREATE,
+                BIND_DEBUG_UNBIND,
+                BIND_NOT_FOREGROUND,
+                BIND_ABOVE_CLIENT,
+                BIND_ALLOW_OOM_MANAGEMENT,
+                BIND_WAIVE_PRIORITY
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BindServiceFlags {}
+
     /**
      * Flag for {@link #bindService}: automatically create the service as long
      * as the binding exists.  Note that while this will create the service,
@@ -222,6 +242,16 @@
     public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
 
     /**
+     * @hide Flag for {@link #bindService}: Treat the binding as hosting
+     * an activity, an unbinding as the activity going in the background.
+     * That is, when unbinding, the process when empty will go on the activity
+     * LRU list instead of the regular one, keeping it around more aggressively
+     * than it otherwise would be.  This is intended for use with IMEs to try
+     * to keep IME processes around for faster keyboard switching.
+     */
+    public static final int BIND_TREAT_LIKE_ACTIVITY = 0x08000000;
+
+    /**
      * @hide An idea that is not yet implemented.
      * Flag for {@link #bindService}: If binding from an activity, consider
      * this service to be visible like the binding activity is.  That is,
@@ -356,6 +386,19 @@
         return getResources().getString(resId, formatArgs);
     }
 
+    /**
+     * Return a drawable object associated with a particular resource ID and
+     * styled for the current theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt
+     *           tool. This integer encodes the package, type, and resource
+     *           entry. The value 0 is an invalid identifier.
+     * @return Drawable An object that can be used to draw this resource.
+     */
+    public final Drawable getDrawable(int id) {
+        return getResources().getDrawable(id, getTheme());
+    }
+
      /**
      * Set the base theme for this context.  Note that this should be called
      * before any views are instantiated in the Context (for example before
@@ -495,7 +538,7 @@
      * and {@link #MODE_WORLD_WRITEABLE} to control permissions.  The bit
      * {@link #MODE_MULTI_PROCESS} can also be used if multiple processes
      * are mutating the same SharedPreferences file.  {@link #MODE_MULTI_PROCESS}
-     * is always on in apps targetting Gingerbread (Android 2.3) and below, and
+     * is always on in apps targeting Gingerbread (Android 2.3) and below, and
      * off by default in later versions.
      *
      * @return The single {@link SharedPreferences} instance that can be used
@@ -674,7 +717,8 @@
      * @see #getFilesDir
      * @see android.os.Environment#getExternalStoragePublicDirectory
      */
-    public abstract File getExternalFilesDir(String type);
+    @Nullable
+    public abstract File getExternalFilesDir(@Nullable String type);
 
     /**
      * Returns absolute paths to application-specific directories on all
@@ -707,7 +751,7 @@
      * Returned paths may be {@code null} if a storage device is unavailable.
      *
      * @see #getExternalFilesDir(String)
-     * @see Environment#getStorageState(File)
+     * @see Environment#getExternalStorageState(File)
      */
     public abstract File[] getExternalFilesDirs(String type);
 
@@ -771,7 +815,7 @@
      * Returned paths may be {@code null} if a storage device is unavailable.
      *
      * @see #getObbDir()
-     * @see Environment#getStorageState(File)
+     * @see Environment#getExternalStorageState(File)
      */
     public abstract File[] getObbDirs();
 
@@ -840,6 +884,7 @@
      *
      * @see #getCacheDir
      */
+    @Nullable
     public abstract File getExternalCacheDir();
 
     /**
@@ -873,7 +918,7 @@
      * Returned paths may be {@code null} if a storage device is unavailable.
      *
      * @see #getExternalCacheDir()
-     * @see Environment#getStorageState(File)
+     * @see Environment#getExternalStorageState(File)
      */
     public abstract File[] getExternalCacheDirs();
 
@@ -960,7 +1005,8 @@
      * @see #deleteDatabase
      */
     public abstract SQLiteDatabase openOrCreateDatabase(String name,
-            int mode, CursorFactory factory, DatabaseErrorHandler errorHandler);
+            int mode, CursorFactory factory,
+            @Nullable DatabaseErrorHandler errorHandler);
 
     /**
      * Delete an existing private SQLiteDatabase associated with this Context's
@@ -1106,7 +1152,7 @@
      * @see #startActivity(Intent)
      * @see PackageManager#resolveActivity
      */
-    public abstract void startActivity(Intent intent, Bundle options);
+    public abstract void startActivity(Intent intent, @Nullable Bundle options);
 
     /**
      * Version of {@link #startActivity(Intent, Bundle)} that allows you to specify the
@@ -1122,7 +1168,7 @@
      * @throws ActivityNotFoundException &nbsp;
      * @hide
      */
-    public void startActivityAsUser(Intent intent, Bundle options, UserHandle userId) {
+    public void startActivityAsUser(Intent intent, @Nullable Bundle options, UserHandle userId) {
         throw new RuntimeException("Not implemented. Must override in a subclass.");
     }
 
@@ -1241,7 +1287,7 @@
      * @see #startIntentSender(IntentSender, Intent, int, int, int)
      */
     public abstract void startIntentSender(IntentSender intent,
-            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
+            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
             Bundle options) throws IntentSender.SendIntentException;
 
     /**
@@ -1291,11 +1337,11 @@
      * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendBroadcast(Intent intent,
-            String receiverPermission);
+            @Nullable String receiverPermission);
 
     /**
      * Like {@link #sendBroadcast(Intent, String)}, but also allows specification
-     * of an assocated app op as per {@link android.app.AppOpsManager}.
+     * of an associated app op as per {@link android.app.AppOpsManager}.
      * @hide
      */
     public abstract void sendBroadcast(Intent intent,
@@ -1322,7 +1368,7 @@
      * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendOrderedBroadcast(Intent intent,
-            String receiverPermission);
+            @Nullable String receiverPermission);
 
     /**
      * Version of {@link #sendBroadcast(Intent)} that allows you to
@@ -1366,15 +1412,15 @@
      * @see #registerReceiver
      * @see android.app.Activity#RESULT_OK
      */
-    public abstract void sendOrderedBroadcast(Intent intent,
-            String receiverPermission, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras);
+    public abstract void sendOrderedBroadcast(@NonNull Intent intent,
+            @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable Bundle initialExtras);
 
     /**
      * Like {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler,
      * int, String, android.os.Bundle)}, but also allows specification
-     * of an assocated app op as per {@link android.app.AppOpsManager}.
+     * of an associated app op as per {@link android.app.AppOpsManager}.
      * @hide
      */
     public abstract void sendOrderedBroadcast(Intent intent,
@@ -1409,7 +1455,7 @@
      * @see #sendBroadcast(Intent, String)
      */
     public abstract void sendBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission);
+            @Nullable String receiverPermission);
 
     /**
      * Version of
@@ -1442,8 +1488,9 @@
      * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
      */
     public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
-            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
-            int initialCode, String initialData, Bundle initialExtras);
+            @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable  Bundle initialExtras);
 
     /**
      * Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
@@ -1508,8 +1555,8 @@
      */
     public abstract void sendStickyOrderedBroadcast(Intent intent,
             BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras);
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable Bundle initialExtras);
 
     /**
      * Remove the data previously sent with {@link #sendStickyBroadcast},
@@ -1569,8 +1616,8 @@
      */
     public abstract void sendStickyOrderedBroadcastAsUser(Intent intent,
             UserHandle user, BroadcastReceiver resultReceiver,
-            Handler scheduler, int initialCode, String initialData,
-            Bundle initialExtras);
+            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
+            @Nullable Bundle initialExtras);
 
     /**
      * Version of {@link #removeStickyBroadcast(Intent)} that allows you to specify the
@@ -1637,7 +1684,8 @@
      * @see #sendBroadcast
      * @see #unregisterReceiver
      */
-    public abstract Intent registerReceiver(BroadcastReceiver receiver,
+    @Nullable
+    public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
                                             IntentFilter filter);
 
     /**
@@ -1671,8 +1719,10 @@
      * @see #sendBroadcast
      * @see #unregisterReceiver
      */
+    @Nullable
     public abstract Intent registerReceiver(BroadcastReceiver receiver,
-            IntentFilter filter, String broadcastPermission, Handler scheduler);
+            IntentFilter filter, @Nullable String broadcastPermission,
+            @Nullable Handler scheduler);
 
     /**
      * @hide
@@ -1698,9 +1748,10 @@
      * @see #sendBroadcast
      * @see #unregisterReceiver
      */
+    @Nullable
     public abstract Intent registerReceiverAsUser(BroadcastReceiver receiver,
-            UserHandle user, IntentFilter filter, String broadcastPermission,
-            Handler scheduler);
+            UserHandle user, IntentFilter filter, @Nullable String broadcastPermission,
+            @Nullable Handler scheduler);
 
     /**
      * Unregister a previously registered BroadcastReceiver.  <em>All</em>
@@ -1759,6 +1810,7 @@
      * @see #stopService
      * @see #bindService
      */
+    @Nullable
     public abstract ComponentName startService(Intent service);
 
     /**
@@ -1798,7 +1850,7 @@
      * @hide like {@link #stopService(Intent)} but for a specific user.
      */
     public abstract boolean stopServiceAsUser(Intent service, UserHandle user);
-    
+
     /**
      * Connect to an application service, creating it if needed.  This defines
      * a dependency between your application and the service.  The given
@@ -1846,8 +1898,8 @@
      * @see #BIND_DEBUG_UNBIND
      * @see #BIND_NOT_FOREGROUND
      */
-    public abstract boolean bindService(Intent service, ServiceConnection conn,
-            int flags);
+    public abstract boolean bindService(Intent service, @NonNull ServiceConnection conn,
+            @BindServiceFlags int flags);
 
     /**
      * Same as {@link #bindService(Intent, ServiceConnection, int)}, but with an explicit userHandle
@@ -1868,7 +1920,7 @@
      *
      * @see #bindService
      */
-    public abstract void unbindService(ServiceConnection conn);
+    public abstract void unbindService(@NonNull ServiceConnection conn);
 
     /**
      * Start executing an {@link android.app.Instrumentation} class.  The given
@@ -1893,8 +1945,65 @@
      * @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);
+    public abstract boolean startInstrumentation(@NonNull ComponentName className,
+            @Nullable String profileFile, @Nullable Bundle arguments);
+
+    /** @hide */
+    @StringDef({
+            POWER_SERVICE,
+            WINDOW_SERVICE,
+            LAYOUT_INFLATER_SERVICE,
+            ACCOUNT_SERVICE,
+            ACTIVITY_SERVICE,
+            ALARM_SERVICE,
+            NOTIFICATION_SERVICE,
+            ACCESSIBILITY_SERVICE,
+            CAPTIONING_SERVICE,
+            KEYGUARD_SERVICE,
+            LOCATION_SERVICE,
+            //@hide: COUNTRY_DETECTOR,
+            SEARCH_SERVICE,
+            SENSOR_SERVICE,
+            STORAGE_SERVICE,
+            WALLPAPER_SERVICE,
+            VIBRATOR_SERVICE,
+            //@hide: STATUS_BAR_SERVICE,
+            CONNECTIVITY_SERVICE,
+            //@hide: UPDATE_LOCK_SERVICE,
+            //@hide: NETWORKMANAGEMENT_SERVICE,
+            //@hide: NETWORK_STATS_SERVICE,
+            //@hide: NETWORK_POLICY_SERVICE,
+            WIFI_SERVICE,
+            WIFI_P2P_SERVICE,
+            NSD_SERVICE,
+            AUDIO_SERVICE,
+            MEDIA_ROUTER_SERVICE,
+            TELEPHONY_SERVICE,
+            CLIPBOARD_SERVICE,
+            INPUT_METHOD_SERVICE,
+            TEXT_SERVICES_MANAGER_SERVICE,
+            //@hide: APPWIDGET_SERVICE,
+            //@hide: BACKUP_SERVICE,
+            DROPBOX_SERVICE,
+            DEVICE_POLICY_SERVICE,
+            UI_MODE_SERVICE,
+            DOWNLOAD_SERVICE,
+            NFC_SERVICE,
+            BLUETOOTH_SERVICE,
+            //@hide: SIP_SERVICE,
+            USB_SERVICE,
+            //@hide: SERIAL_SERVICE,
+            INPUT_SERVICE,
+            DISPLAY_SERVICE,
+            //@hide: SCHEDULING_POLICY_SERVICE,
+            USER_SERVICE,
+            //@hide: APP_OPS_SERVICE
+            CAMERA_SERVICE,
+            PRINT_SERVICE,
+            MEDIA_SESSION_SERVICE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ServiceName {}
 
     /**
      * Return the handle to a system-level service by name. The class of the
@@ -1997,7 +2106,7 @@
      * @see #DOWNLOAD_SERVICE
      * @see android.app.DownloadManager
      */
-    public abstract Object getSystemService(String name);
+    public abstract Object getSystemService(@ServiceName @NonNull String name);
 
     /**
      * Use with {@link #getSystemService} to retrieve a
@@ -2255,6 +2364,15 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
+     * {@link android.media.session.MediaSessionManager} for managing media Sessions.
+     *
+     * @see #getSystemService
+     * @see android.media.session.MediaSessionManager
+     */
+    public static final String MEDIA_SESSION_SERVICE = "media_session";
+
+    /**
+     * Use with {@link #getSystemService} to retrieve a
      * {@link android.telephony.TelephonyManager} for handling management the
      * telephony features of the device.
      *
@@ -2443,7 +2561,6 @@
      *
      * @see #getSystemService
      * @see android.hardware.camera2.CameraManager
-     * @hide
      */
     public static final String CAMERA_SERVICE = "camera";
 
@@ -2482,7 +2599,8 @@
      * @see PackageManager#checkPermission(String, String)
      * @see #checkCallingPermission
      */
-    public abstract int checkPermission(String permission, int pid, int uid);
+    @PackageManager.PermissionResult
+    public abstract int checkPermission(@NonNull String permission, int pid, int uid);
 
     /**
      * Determine whether the calling process of an IPC you are handling has been
@@ -2505,7 +2623,8 @@
      * @see #checkPermission
      * @see #checkCallingOrSelfPermission
      */
-    public abstract int checkCallingPermission(String permission);
+    @PackageManager.PermissionResult
+    public abstract int checkCallingPermission(@NonNull String permission);
 
     /**
      * Determine whether the calling process of an IPC <em>or you</em> have been
@@ -2523,7 +2642,8 @@
      * @see #checkPermission
      * @see #checkCallingPermission
      */
-    public abstract int checkCallingOrSelfPermission(String permission);
+    @PackageManager.PermissionResult
+    public abstract int checkCallingOrSelfPermission(@NonNull String permission);
 
     /**
      * If the given permission is not allowed for a particular process
@@ -2538,7 +2658,7 @@
      * @see #checkPermission(String, int, int)
      */
     public abstract void enforcePermission(
-            String permission, int pid, int uid, String message);
+            @NonNull String permission, int pid, int uid, @Nullable String message);
 
     /**
      * If the calling process of an IPC you are handling has not been
@@ -2559,7 +2679,7 @@
      * @see #checkCallingPermission(String)
      */
     public abstract void enforceCallingPermission(
-            String permission, String message);
+            @NonNull String permission, @Nullable String message);
 
     /**
      * If neither you nor the calling process of an IPC you are
@@ -2575,7 +2695,7 @@
      * @see #checkCallingOrSelfPermission(String)
      */
     public abstract void enforceCallingOrSelfPermission(
-            String permission, String message);
+            @NonNull String permission, @Nullable String message);
 
     /**
      * Grant permission to access a specific Uri to another package, regardless
@@ -2611,7 +2731,7 @@
      * @see #revokeUriPermission
      */
     public abstract void grantUriPermission(String toPackage, Uri uri,
-            int modeFlags);
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * Remove all permissions to access a particular content provider Uri
@@ -2630,7 +2750,7 @@
      *
      * @see #grantUriPermission
      */
-    public abstract void revokeUriPermission(Uri uri, int modeFlags);
+    public abstract void revokeUriPermission(Uri uri, @Intent.GrantUriMode int modeFlags);
 
     /**
      * Determine whether a particular process and user ID has been granted
@@ -2653,7 +2773,8 @@
      *
      * @see #checkCallingUriPermission
      */
-    public abstract int checkUriPermission(Uri uri, int pid, int uid, int modeFlags);
+    public abstract int checkUriPermission(Uri uri, int pid, int uid,
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * Determine whether the calling process and user ID has been
@@ -2676,7 +2797,7 @@
      *
      * @see #checkUriPermission(Uri, int, int, int)
      */
-    public abstract int checkCallingUriPermission(Uri uri, int modeFlags);
+    public abstract int checkCallingUriPermission(Uri uri, @Intent.GrantUriMode int modeFlags);
 
     /**
      * Determine whether the calling process of an IPC <em>or you</em> has been granted
@@ -2695,7 +2816,8 @@
      *
      * @see #checkCallingUriPermission
      */
-    public abstract int checkCallingOrSelfUriPermission(Uri uri, int modeFlags);
+    public abstract int checkCallingOrSelfUriPermission(Uri uri,
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * Check both a Uri and normal permission.  This allows you to perform
@@ -2707,7 +2829,7 @@
      * @param readPermission The permission that provides overall read access,
      * or null to not do this check.
      * @param writePermission The permission that provides overall write
-     * acess, or null to not do this check.
+     * access, or null to not do this check.
      * @param pid The process ID being checked against.  Must be &gt; 0.
      * @param uid The user ID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
@@ -2719,8 +2841,9 @@
      * is allowed to access that uri or holds one of the given permissions, or
      * {@link PackageManager#PERMISSION_DENIED} if it is not.
      */
-    public abstract int checkUriPermission(Uri uri, String readPermission,
-            String writePermission, int pid, int uid, int modeFlags);
+    public abstract int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission,
+            @Nullable String writePermission, int pid, int uid,
+            @Intent.GrantUriMode int modeFlags);
 
     /**
      * If a particular process and user ID has not been granted
@@ -2742,7 +2865,7 @@
      * @see #checkUriPermission(Uri, int, int, int)
      */
     public abstract void enforceUriPermission(
-            Uri uri, int pid, int uid, int modeFlags, String message);
+            Uri uri, int pid, int uid, @Intent.GrantUriMode int modeFlags, String message);
 
     /**
      * If the calling process and user ID has not been granted
@@ -2764,7 +2887,7 @@
      * @see #checkCallingUriPermission(Uri, int)
      */
     public abstract void enforceCallingUriPermission(
-            Uri uri, int modeFlags, String message);
+            Uri uri, @Intent.GrantUriMode int modeFlags, String message);
 
     /**
      * If the calling process of an IPC <em>or you</em> has not been
@@ -2783,7 +2906,7 @@
      * @see #checkCallingOrSelfUriPermission(Uri, int)
      */
     public abstract void enforceCallingOrSelfUriPermission(
-            Uri uri, int modeFlags, String message);
+            Uri uri, @Intent.GrantUriMode int modeFlags, String message);
 
     /**
      * Enforce both a Uri and normal permission.  This allows you to perform
@@ -2795,7 +2918,7 @@
      * @param readPermission The permission that provides overall read access,
      * or null to not do this check.
      * @param writePermission The permission that provides overall write
-     * acess, or null to not do this check.
+     * access, or null to not do this check.
      * @param pid The process ID being checked against.  Must be &gt; 0.
      * @param uid The user ID being checked against.  A uid of 0 is the root
      * user, which will pass every permission check.
@@ -2807,8 +2930,15 @@
      * @see #checkUriPermission(Uri, String, String, int, int, int)
      */
     public abstract void enforceUriPermission(
-            Uri uri, String readPermission, String writePermission,
-            int pid, int uid, int modeFlags, String message);
+            @Nullable Uri uri, @Nullable String readPermission,
+            @Nullable String writePermission, int pid, int uid, @Intent.GrantUriMode int modeFlags,
+            @Nullable String message);
+
+    /** @hide */
+    @IntDef(flag = true,
+            value = {CONTEXT_INCLUDE_CODE, CONTEXT_IGNORE_SECURITY, CONTEXT_RESTRICTED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CreatePackageOptions {}
 
     /**
      * Flag for use with {@link #createPackageContext}: include the application
@@ -2866,7 +2996,7 @@
      * the given package name.
      */
     public abstract Context createPackageContext(String packageName,
-            int flags) throws PackageManager.NameNotFoundException;
+            @CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;
 
     /**
      * Similar to {@link #createPackageContext(String, int)}, but with a
@@ -2902,7 +3032,8 @@
      *
      * @return A {@link Context} with the given configuration override.
      */
-    public abstract Context createConfigurationContext(Configuration overrideConfiguration);
+    public abstract Context createConfigurationContext(
+            @NonNull Configuration overrideConfiguration);
 
     /**
      * Return a new Context object for the current Context but whose resources
@@ -2922,7 +3053,7 @@
      *
      * @return A {@link Context} for the display.
      */
-    public abstract Context createDisplayContext(Display display);
+    public abstract Context createDisplayContext(@NonNull Display display);
 
     /**
      * Gets the display adjustments holder for this context.  This information
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index a708dad..93f6cdf 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -16,9 +16,6 @@
 
 package android.content;
 
-import android.app.Activity;
-import android.app.ActivityManagerNative;
-import android.app.LoadedApk;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
@@ -33,7 +30,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.view.DisplayAdjustments;
 import android.view.Display;
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index 5d7d677..c78871c 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -16,7 +16,6 @@
 
 package android.content;
 
-import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.CancellationSignal;
diff --git a/core/java/android/content/Entity.java b/core/java/android/content/Entity.java
index 7842de0..607cb3f 100644
--- a/core/java/android/content/Entity.java
+++ b/core/java/android/content/Entity.java
@@ -16,10 +16,7 @@
 
 package android.content;
 
-import android.os.Parcelable;
-import android.os.Parcel;
 import android.net.Uri;
-import android.util.Log;
 
 import java.util.ArrayList;
 
diff --git a/core/java/android/content/IAnonymousSyncAdapter.aidl b/core/java/android/content/IAnonymousSyncAdapter.aidl
deleted file mode 100644
index a80cea3..0000000
--- a/core/java/android/content/IAnonymousSyncAdapter.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package 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/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 9ad5a19..73a76e8 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -17,6 +17,7 @@
 package android.content;
 
 import android.accounts.Account;
+import android.content.ComponentName;
 import android.content.SyncInfo;
 import android.content.ISyncStatusObserver;
 import android.content.SyncAdapterType;
@@ -55,8 +56,14 @@
             int userHandle);
 
     void requestSync(in Account account, String authority, in Bundle extras);
+    /**
+     * Start a sync given a request.
+     */
     void sync(in SyncRequest request);
-    void cancelSync(in Account account, String authority);
+    void cancelSync(in Account account, String authority, in ComponentName cname);
+
+    /** Cancel a sync, providing information about the sync to be cancelled. */
+     void cancelRequest(in SyncRequest request);
 
     /**
      * Check if the provider should be synced when a network tickle is received
@@ -74,12 +81,14 @@
     void setSyncAutomatically(in Account account, String providerName, boolean sync);
 
     /**
-     * Get the frequency of the periodic poll, if any.
-     * @param providerName the provider whose setting we are querying
-     * @return the frequency of the periodic sync in seconds. If 0 then no periodic syncs
-     * will take place.
+     * Get a list of periodic operations for a specified authority, or service.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    List<PeriodicSync> getPeriodicSyncs(in Account account, String providerName);
+    List<PeriodicSync> getPeriodicSyncs(in Account account, String providerName,
+        in ComponentName cname);
 
     /**
      * Set whether or not the provider is to be synced on a periodic basis.
@@ -112,16 +121,23 @@
      */
     void setIsSyncable(in Account account, String providerName, int syncable);
 
+    /**
+     * Corresponds roughly to setIsSyncable(String account, String provider) for syncs that bind
+     * to a SyncService.
+     */
+    void setServiceActive(in ComponentName cname, boolean active);
+
+    /**
+     * Corresponds roughly to getIsSyncable(String account, String provider) for syncs that bind
+     * to a SyncService.
+     * @return 0 if this SyncService is not enabled, 1 if enabled, <0 if unknown.
+     */
+    boolean isServiceActive(in ComponentName cname);
+
     void setMasterSyncAutomatically(boolean flag);
 
     boolean getMasterSyncAutomatically();
 
-    /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority in the pending list, or actively being processed.
-     */
-    boolean isSyncActive(in Account account, String authority);
-
     List<SyncInfo> getCurrentSyncs();
 
     /**
@@ -131,17 +147,33 @@
     SyncAdapterType[] getSyncAdapterTypes();
 
     /**
+     * Returns true if there is currently a operation for the given account/authority or service
+     * actively being processed.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
+     */
+    boolean isSyncActive(in Account account, String authority, in ComponentName cname);
+
+    /**
      * Returns the status that matches the authority. If there are multiples accounts for
      * the authority, the one with the latest "lastSuccessTime" status is returned.
-     * @param authority the authority whose row should be selected
-     * @return the SyncStatusInfo for the authority, or null if none exists
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    SyncStatusInfo getSyncStatus(in Account account, String authority);
+    SyncStatusInfo getSyncStatus(in Account account, String authority, in ComponentName cname);
 
     /**
      * Return true if the pending status is true of any matching authorities.
+     * @param account account for authority, must be null if cname is non-null.
+     * @param providerName name of provider, must be null if cname is non-null.
+     * @param cname component to identify sync service, must be null if account/providerName are
+     * non-null.
      */
-    boolean isSyncPending(in Account account, String authority);
+    boolean isSyncPending(in Account account, String authority, in ComponentName cname);
 
     void addStatusChangeListener(int mask, ISyncStatusObserver callback);
 
diff --git a/core/java/android/content/ISyncServiceAdapter.aidl b/core/java/android/content/ISyncServiceAdapter.aidl
new file mode 100644
index 0000000..d419307
--- /dev/null
+++ b/core/java/android/content/ISyncServiceAdapter.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 ISyncServiceAdapter {
+
+    /**
+     * 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/Intent.java b/core/java/android/content/Intent.java
index 65e2268..0175d62 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -21,6 +21,7 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.pm.ActivityInfo;
@@ -45,6 +46,8 @@
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.List;
@@ -3350,6 +3353,12 @@
     // ---------------------------------------------------------------------
     // Intent flags (see mFlags variable).
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GrantUriMode {}
+
     /**
      * If set, the recipient of this Intent will be granted permission to
      * perform read operations on the URI in the Intent's data and any URIs
@@ -3448,7 +3457,16 @@
      */
     public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
     /**
-     * <strong>Do not use this flag unless you are implementing your own
+     * This flag is used to create a new task and launch an activity into it.
+     * This flag is always paired with either {@link #FLAG_ACTIVITY_NEW_DOCUMENT}
+     * or {@link #FLAG_ACTIVITY_NEW_TASK}. In both cases these flags alone would
+     * search through existing tasks for ones matching this Intent. Only if no such
+     * task is found would a new task be created. When paired with
+     * FLAG_ACTIVITY_MULTIPLE_TASK both of these behaviors are modified to skip
+     * the search for a matching task and unconditionally start a new task.
+     *
+     * <strong>When used with {@link #FLAG_ACTIVITY_NEW_TASK} do not use this
+     * flag unless you are implementing your own
      * top-level application launcher.</strong>  Used in conjunction with
      * {@link #FLAG_ACTIVITY_NEW_TASK} to disable the
      * behavior of bringing an existing task to the foreground.  When set,
@@ -3460,12 +3478,18 @@
      * you should not use this flag unless you provide some way for a user to
      * return back to the tasks you have launched.</strong>
      *
-     * <p>This flag is ignored if
-     * {@link #FLAG_ACTIVITY_NEW_TASK} is not set.
+     * See {@link #FLAG_ACTIVITY_NEW_DOCUMENT} for details of this flag's use for
+     * creating new document tasks.
+     *
+     * <p>This flag is ignored if one of {@link #FLAG_ACTIVITY_NEW_TASK} or
+     * {@link #FLAG_ACTIVITY_NEW_TASK} is not also set.
      *
      * <p>See
      * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
      * Stack</a> for more information about tasks.
+     *
+     * @see #FLAG_ACTIVITY_NEW_DOCUMENT
+     * @see #FLAG_ACTIVITY_NEW_TASK
      */
     public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000;
     /**
@@ -3572,6 +3596,34 @@
      */
     public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
     /**
+     * This flag is used to break out "documents" into separate tasks that can
+     * be reached via the Recents mechanism. Such a document is any kind of
+     * item for which an application may want to maintain multiple simultaneous
+     * instances. Examples might be text files, web pages, spreadsheets, or
+     * emails. Each such document will be in a separate task in the Recents list.
+     *
+     * <p>When set, the activity specified by this Intent will launch into a
+     * separate task rooted at that activity. The activity launched must be
+     * defined with {@link android.R.attr#launchMode} "standard" or "singleTop".
+     *
+     * <p>If FLAG_ACTIVITY_NEW_DOCUMENT is used without
+     * {@link #FLAG_ACTIVITY_MULTIPLE_TASK} then the activity manager will
+     * search for an existing task with a matching target activity and Intent
+     * data URI and relaunch that task, first finishing all activities down to
+     * the root activity and then calling the root activity's
+     * {@link android.app.Activity#onNewIntent(Intent)} method. If no existing
+     * task's root activity matches the Intent's data URI then a new task will
+     * be launched with the target activity as root.
+     *
+     * <p>When paired with {@link #FLAG_ACTIVITY_MULTIPLE_TASK} this will
+     * always create a new task. Thus the same document may be made to appear
+     * more than one time in Recents.
+     *
+     * @see #FLAG_ACTIVITY_MULTIPLE_TASK
+     */
+    public static final int FLAG_ACTIVITY_NEW_DOCUMENT =
+            FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | FLAG_ACTIVITY_NEW_TASK;
+    /**
      * If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint}
      * callback from occurring on the current frontmost activity before it is
      * paused as the newly-started activity is brought to the front.
@@ -6237,6 +6289,7 @@
      * @see #FLAG_ACTIVITY_FORWARD_RESULT
      * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
      * @see #FLAG_ACTIVITY_MULTIPLE_TASK
+     * @see #FLAG_ACTIVITY_NEW_DOCUMENT
      * @see #FLAG_ACTIVITY_NEW_TASK
      * @see #FLAG_ACTIVITY_NO_ANIMATION
      * @see #FLAG_ACTIVITY_NO_HISTORY
@@ -6394,6 +6447,21 @@
         }
     }
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    FILL_IN_ACTION,
+                    FILL_IN_DATA,
+                    FILL_IN_CATEGORIES,
+                    FILL_IN_COMPONENT,
+                    FILL_IN_PACKAGE,
+                    FILL_IN_SOURCE_BOUNDS,
+                    FILL_IN_SELECTOR,
+                    FILL_IN_CLIP_DATA
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FillInFlags {}
+
     /**
      * Use with {@link #fillIn} to allow the current action value to be
      * overwritten, even if it is already set.
@@ -6487,10 +6555,12 @@
      *
      * @return Returns a bit mask of {@link #FILL_IN_ACTION},
      * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, {@link #FILL_IN_PACKAGE},
-     * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS}, and
-     * {@link #FILL_IN_SELECTOR} indicating which fields were changed.
+     * {@link #FILL_IN_COMPONENT}, {@link #FILL_IN_SOURCE_BOUNDS},
+     * {@link #FILL_IN_SELECTOR} and {@link #FILL_IN_CLIP_DATA indicating which fields were
+     * changed.
      */
-    public int fillIn(Intent other, int flags) {
+    @FillInFlags
+    public int fillIn(Intent other, @FillInFlags int flags) {
         int changes = 0;
         if (other.mAction != null
                 && (mAction == null || (flags&FILL_IN_ACTION) != 0)) {
@@ -7316,4 +7386,9 @@
         String htmlText = htmlTexts != null ? htmlTexts.get(which) : null;
         return new ClipData.Item(text, htmlText, null, uri);
     }
+
+    /** @hide */
+    public boolean isDocument() {
+        return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT;
+    }
 }
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index a045b3a..e9d82af 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -413,7 +413,7 @@
      * {@link #onReset()} happens.  You can retrieve the current abandoned
      * state with {@link #isAbandoned}.
      */
-    protected void onAbandon() {        
+    protected void onAbandon() {
     }
     
     /**
diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java
index b586eec..836c6f8 100644
--- a/core/java/android/content/PeriodicSync.java
+++ b/core/java/android/content/PeriodicSync.java
@@ -29,13 +29,17 @@
     public final Account account;
     /** The authority of the sync. Can be null. */
     public final String authority;
+    /** The service for syncing, if this is an anonymous sync. Can be null.*/
+    public final ComponentName service;
     /** 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. Kept around for API purposes. */
     public final long period;
+    /** Whether this periodic sync runs on a {@link SyncService}. */
+    public final boolean isService;
     /**
-     * {@hide}
      * How much flexibility can be taken in scheduling the sync, in seconds.
+     * {@hide}
      */
     public final long flexTime;
 
@@ -48,44 +52,74 @@
     public PeriodicSync(Account account, String authority, Bundle extras, long periodInSeconds) {
         this.account = account;
         this.authority = authority;
+        this.service = null;
+        this.isService = false;
         if (extras == null) {
             this.extras = new Bundle();
         } else {
             this.extras = new Bundle(extras);
         }
         this.period = periodInSeconds;
-        // Initialise to a sane value.
+        // Old API uses default flex time. No-one should be using this ctor anyway.
         this.flexTime = 0L;
     }
 
     /**
-     * {@hide}
      * Create a copy of a periodic sync.
+     * {@hide}
      */
     public PeriodicSync(PeriodicSync other) {
         this.account = other.account;
         this.authority = other.authority;
+        this.service = other.service;
+        this.isService = other.isService;
         this.extras = new Bundle(other.extras);
         this.period = other.period;
         this.flexTime = other.flexTime;
     }
 
     /**
-     * {@hide}
      * A PeriodicSync for a sync with a specified provider.
+     * {@hide}
      */
     public PeriodicSync(Account account, String authority, Bundle extras,
             long period, long flexTime) {
         this.account = account;
         this.authority = authority;
+        this.service = null;
+        this.isService = false;
+        this.extras = new Bundle(extras);
+        this.period = period;
+        this.flexTime = flexTime;
+    }
+
+    /**
+     * A PeriodicSync for a sync with a specified SyncService.
+     * {@hide}
+     */
+    public PeriodicSync(ComponentName service, Bundle extras,
+            long period,
+            long flexTime) {
+        this.account = null;
+        this.authority = null;
+        this.service = service;
+        this.isService = true;
         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.isService = (in.readInt() != 0);
+        if (this.isService) {
+            this.service = in.readParcelable(null);
+            this.account = null;
+            this.authority = null;
+        } else {
+            this.account = in.readParcelable(null);
+            this.authority = in.readString();
+            this.service = null;
+        }
         this.extras = in.readBundle();
         this.period = in.readLong();
         this.flexTime = in.readLong();
@@ -98,8 +132,13 @@
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeParcelable(account, flags);
-        dest.writeString(authority);
+        dest.writeInt(isService ? 1 : 0);
+        if (account == null && authority == null) {
+            dest.writeParcelable(service, flags);
+        } else {
+            dest.writeParcelable(account, flags);
+            dest.writeString(authority);
+        }
         dest.writeBundle(extras);
         dest.writeLong(period);
         dest.writeLong(flexTime);
@@ -126,14 +165,24 @@
             return false;
         }
         final PeriodicSync other = (PeriodicSync) o;
-        return account.equals(other.account)
-            && authority.equals(other.authority)
+        if (this.isService != other.isService) {
+            return false;
+        }
+        boolean equal = false;
+        if (this.isService) {
+            equal = service.equals(other.service);
+        } else {
+            equal = account.equals(other.account)
+                    && authority.equals(other.authority);
+        }
+        return equal
             && period == other.period
             && syncExtrasEquals(extras, other.extras);
     }
 
     /**
-     * Periodic sync extra comparison function.
+     * Periodic sync extra comparison function. Duplicated from
+     * {@link com.android.server.content.SyncManager#syncExtrasEquals(Bundle b1, Bundle b2)}
      * {@hide}
      */
     public static boolean syncExtrasEquals(Bundle b1, Bundle b2) {
@@ -158,6 +207,7 @@
     public String toString() {
         return "account: " + account +
                ", authority: " + authority +
+               ", service: " + service +
                ". period: " + period + "s " +
                ", flex: " + flexTime;
     }
diff --git a/core/java/android/content/RestrictionEntry.java b/core/java/android/content/RestrictionEntry.java
index 283a097..3ff53bf 100644
--- a/core/java/android/content/RestrictionEntry.java
+++ b/core/java/android/content/RestrictionEntry.java
@@ -19,8 +19,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.lang.annotation.Inherited;
-
 /**
  * Applications can expose restrictions for a restricted user on a
  * multiuser device. The administrator can configure these restrictions that will then be
diff --git a/core/java/android/content/SyncActivityTooManyDeletes.java b/core/java/android/content/SyncActivityTooManyDeletes.java
index 350f35e..093fb08 100644
--- a/core/java/android/content/SyncActivityTooManyDeletes.java
+++ b/core/java/android/content/SyncActivityTooManyDeletes.java
@@ -95,7 +95,7 @@
 //                try {
 //                    final Context authContext = createPackageContext(desc.packageName, 0);
 //                    ImageView imageView = new ImageView(this);
-//                    imageView.setImageDrawable(authContext.getResources().getDrawable(desc.iconId));
+//                    imageView.setImageDrawable(authContext.getDrawable(desc.iconId));
 //                    ll.addView(imageView, lp);
 //                } catch (PackageManager.NameNotFoundException e) {
 //                }
diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java
index cffc653..146dd99 100644
--- a/core/java/android/content/SyncInfo.java
+++ b/core/java/android/content/SyncInfo.java
@@ -19,7 +19,6 @@
 import android.accounts.Account;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Parcelable.Creator;
 
 /**
  * Information about the sync operation that is currently underway.
@@ -29,16 +28,24 @@
     public final int authorityId;
 
     /**
-     * The {@link Account} that is currently being synced.
+     * The {@link Account} that is currently being synced. Will be null if this sync is running via
+     * a {@link SyncService}.
      */
     public final Account account;
 
     /**
-     * The authority of the provider that is currently being synced.
+     * The authority of the provider that is currently being synced. Will be null if this sync
+     * is running via a {@link SyncService}.
      */
     public final String authority;
 
     /**
+     * The {@link SyncService} that is targeted by this operation. Null if this sync is running via
+     * a {@link AbstractThreadedSyncAdapter}. 
+     */
+    public final ComponentName service;
+
+    /**
      * The start time of the current sync operation in milliseconds since boot.
      * This is represented in elapsed real time.
      * See {@link android.os.SystemClock#elapsedRealtime()}.
@@ -46,12 +53,13 @@
     public final long startTime;
 
     /** @hide */
-    public SyncInfo(int authorityId, Account account, String authority,
+    public SyncInfo(int authorityId, Account account, String authority, ComponentName service,
             long startTime) {
         this.authorityId = authorityId;
         this.account = account;
         this.authority = authority;
         this.startTime = startTime;
+        this.service = service;
     }
 
     /** @hide */
@@ -60,6 +68,7 @@
         this.account = new Account(other.account.name, other.account.type);
         this.authority = other.authority;
         this.startTime = other.startTime;
+        this.service = other.service;
     }
 
     /** @hide */
@@ -70,17 +79,20 @@
     /** @hide */
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(authorityId);
-        account.writeToParcel(parcel, 0);
+        parcel.writeParcelable(account, flags);
         parcel.writeString(authority);
         parcel.writeLong(startTime);
+        parcel.writeParcelable(service, flags);
+        
     }
 
     /** @hide */
     SyncInfo(Parcel parcel) {
         authorityId = parcel.readInt();
-        account = new Account(parcel);
+        account = parcel.readParcelable(Account.class.getClassLoader());
         authority = parcel.readString();
         startTime = parcel.readLong();
+        service = parcel.readParcelable(ComponentName.class.getClassLoader());
     }
 
     /** @hide */
diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java
index 6ca283d..a9a62a7 100644
--- a/core/java/android/content/SyncRequest.java
+++ b/core/java/android/content/SyncRequest.java
@@ -23,15 +23,15 @@
 
 public class SyncRequest implements Parcelable {
     private static final String TAG = "SyncRequest";
-    /** Account to pass to the sync adapter. May be null. */
+    /** Account to pass to the sync adapter. Can be null. */
     private final Account mAccountToSync;
     /** Authority string that corresponds to a ContentProvider. */
     private final String mAuthority;
-    /** Sync service identifier. May be null.*/
+    /** {@link SyncService} identifier. */
     private final ComponentName mComponentInfo;
     /** Bundle containing user info as well as sync settings. */
     private final Bundle mExtras;
-    /** Disallow this sync request on metered networks. */
+    /** Don't allow this sync request on metered networks. */
     private final boolean mDisallowMetered;
     /**
      * Anticipated upload size in bytes.
@@ -69,18 +69,14 @@
         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.
+     * @return true if this sync uses an account/authority pair, or false if
+     *         this is an anonymous sync bound to an @link AnonymousSyncService.
      */
     public boolean hasAuthority() {
         return mIsAuthority;
@@ -88,34 +84,51 @@
 
     /**
      * {@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.
+     * @throws IllegalArgumentException if this function is called for a request that targets a
+     * sync service.
      */
     public Account getAccount() {
         if (!hasAuthority()) {
-            throw new IllegalArgumentException("Cannot getAccount() for a sync that does not"
-                    + "specify an authority.");
+            throw new IllegalArgumentException("Cannot getAccount() for a sync that targets a sync"
+                    + "service.");
         }
         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.
+     * @throws IllegalArgumentException if this function is called for a request that targets a
+     * sync service.
      */
     public String getProvider() {
         if (!hasAuthority()) {
-            throw new IllegalArgumentException("Cannot getProvider() for a sync that does not"
-                    + "specify a provider.");
+            throw new IllegalArgumentException("Cannot getProvider() for a sync that targets a"
+                    + "sync service.");
         }
         return mAuthority;
     }
 
     /**
      * {@hide}
+     * Throws a runtime IllegalArgumentException if this function is called for a
+     * SyncRequest that is bound to an account/provider.
+     *
+     * @return ComponentName for the service that this sync will bind to.
+     */
+    public ComponentName getService() {
+        if (hasAuthority()) {
+            throw new IllegalArgumentException(
+                    "Cannot getAnonymousService() for a sync that has specified a provider.");
+        }
+        return mComponentInfo;
+    }
+
+    /**
+     * {@hide}
      * Retrieve bundle for this SyncRequest. Will not be null.
      */
     public Bundle getBundle() {
@@ -129,7 +142,6 @@
     public long getSyncFlexTime() {
         return mSyncFlexTimeSecs;
     }
-
     /**
      * {@hide}
      * @return the last point in time at which this sync must scheduled.
@@ -216,7 +228,7 @@
     }
 
     /**
-     * Builder class for a {@link SyncRequest}. As you build your SyncRequest this class will also
+     * Builder class for a @link SyncRequest. As you build your SyncRequest this class will also
      * perform validation.
      */
     public static class Builder {
@@ -232,9 +244,12 @@
         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. */
+        /**
+         * 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. */
+        /** Displacement into the future at which this sync must occur. */
         private long mSyncRunTimeSecs;
         /**
          * Sync configuration information - custom user data explicitly provided by the developer.
@@ -283,8 +298,9 @@
         private boolean mExpedited;
 
         /**
-         * The sync component that contains the sync logic if this is a provider-less sync,
-         * otherwise null.
+         * The {@link SyncService} component that
+         * contains the sync logic if this is a provider-less sync, otherwise
+         * null.
          */
         private ComponentName mComponentName;
         /**
@@ -320,11 +336,15 @@
 
         /**
          * 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>
+         * Syncs are identified by target {@link SyncService}/{@link android.provider} and by the
+         * contents of the extras bundle.
+         * You cannot reuse the same builder for one-time syncs after having specified a periodic
+         * sync (by calling this function). If you do, an <code>IllegalArgumentException</code>
          * will be thrown.
+         * <p>The bundle for a periodic sync can be queried by applications with the correct
+         * permissions using
+         * {@link ContentResolver#getPeriodicSyncs(Account account, String provider)}, so no
+         * sensitive data should be transferred here.
          *
          * Example usage.
          *
@@ -375,7 +395,6 @@
         }
 
         /**
-         * {@hide}
          * Developer can provide insight into their payload size; optional. -1 specifies unknown,
          * so that you are not restricted to defining both fields.
          *
@@ -389,20 +408,28 @@
         }
 
         /**
-         * @see android.net.ConnectivityManager#isActiveNetworkMetered()
-         * @param disallow true to enforce that this transfer not occur on metered networks.
-         *                 Default false.
+         * Will throw an <code>IllegalArgumentException</code> if called and
+         * {@link #setIgnoreSettings(boolean ignoreSettings)} has already been called.
+         * @param disallow true to allow this transfer on metered networks. Default false.
+         * 
          */
         public Builder setDisallowMetered(boolean disallow) {
+            if (mIgnoreSettings && disallow) {
+                throw new IllegalArgumentException("setDisallowMetered(true) after having"
+                        + "specified that settings are ignored.");
+            }
             mDisallowMetered = disallow;
             return this;
         }
 
         /**
-         * Specify an authority and account for this transfer.
+         * Specify an authority and account for this transfer. Cannot be used with
+         * {@link #setSyncAdapter(ComponentName cname)}.
          *
-         * @param authority String identifying which content provider to sync.
-         * @param account Account to sync. Can be null unless this is a periodic sync.
+         * @param authority
+         * @param account Account to sync. Can be null unless this is a periodic
+         *            sync, for which verification by the ContentResolver will
+         *            fail. If a sync is performed without an account, the
          */
         public Builder setSyncAdapter(Account account, String authority) {
             if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
@@ -419,10 +446,26 @@
         }
 
         /**
-         * 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()}.
+         * Specify the {@link SyncService} component for this sync. This is not validated until
+         * sync time so providing an incorrect component name here will not fail. Cannot be used
+         * with {@link #setSyncAdapter(Account account, String authority)}.
+         *
+         * @param cname ComponentName to identify your Anonymous service
+         */
+        public Builder setSyncAdapter(ComponentName cname) {
+            if (mSyncTarget != SYNC_TARGET_UNKNOWN) {
+                throw new IllegalArgumentException("Sync target has already been defined.");
+            }
+            mSyncTarget = SYNC_TARGET_SERVICE;
+            mComponentName = cname;
+            mAccount = null;
+            mAuthority = null;
+            return this;
+        }
+
+        /**
+         * Developer-provided extras handed back when sync actually occurs. This bundle is copied
+         * into the SyncRequest returned by {@link #build()}.
          *
          * Example:
          * <pre>
@@ -436,7 +479,7 @@
          *     Bundle extras = new Bundle();
          *     extras.setString("data", syncData);
          *     builder.setExtras(extras);
-         *     ContentResolver.sync(builder.build()); // Each sync() request is for a unique sync.
+         *     ContentResolver.sync(builder.build()); // Each sync() request creates a unique sync.
          *   }
          * </pre>
          * Only values of the following types may be used in the extras bundle:
@@ -477,13 +520,19 @@
         /**
          * 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
+         * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
          * {@link #build()}.
+         * <p>Throws <code>IllegalArgumentException</code> if called and
+         * {@link #setDisallowMetered(boolean)} has been set.
+         * 
          *
          * @param ignoreSettings true to ignore the sync automatically settings. Default false.
          */
         public Builder setIgnoreSettings(boolean ignoreSettings) {
+            if (mDisallowMetered && ignoreSettings) {
+                throw new IllegalArgumentException("setIgnoreSettings(true) after having specified"
+                        + " sync settings with this builder.");
+            }
             mIgnoreSettings = ignoreSettings;
             return this;
         }
@@ -491,13 +540,13 @@
         /**
          * 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()}.
+         * Ignoring back-off will 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.
+         * @param ignoreBackoff ignore back off settings. Default false.
          */
         public Builder setIgnoreBackoff(boolean ignoreBackoff) {
             mIgnoreBackoff = ignoreBackoff;
@@ -507,9 +556,8 @@
         /**
          * 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()}.
+         * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
+         * {@link #build()}.
          *
          * @param isManual User-initiated sync or not. Default false.
          */
@@ -519,7 +567,7 @@
         }
 
         /**
-         * An expedited sync runs immediately and will preempt another non-expedited running sync.
+         * An expedited sync runs immediately and can preempt other non-expedited running syncs.
          *
          * Not valid for periodic sync and will throw an <code>IllegalArgumentException</code> in
          * {@link #build()}.
@@ -532,7 +580,6 @@
         }
 
         /**
-         * {@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.
          */
@@ -552,11 +599,11 @@
          *         builder.
          */
         public SyncRequest build() {
+            // Validate the extras bundle
+            ContentResolver.validateSyncExtrasBundle(mCustomExtras);
             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) {
@@ -575,51 +622,33 @@
                 mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
             }
             if (mIsManual) {
-                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
+                mSyncConfigExtras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, 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.");
+                if (ContentResolver.invalidPeriodicExtras(mCustomExtras) || 
+                        ContentResolver.invalidPeriodicExtras(mSyncConfigExtras)) {
+                    throw new IllegalArgumentException("Illegal extras were set");
                 }
             } else if (mSyncType == SYNC_TYPE_UNKNOWN) {
                 throw new IllegalArgumentException("Must call either syncOnce() or syncPeriodic()");
             }
+            if (mSyncTarget == SYNC_TARGET_SERVICE) {
+                if (mSyncConfigExtras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
+                    throw new IllegalArgumentException("Cannot specify an initialisation sync"
+                            + " that targets a service.");
+                }
+            }
             // 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");
+                throw new IllegalArgumentException("Must specify an adapter with one of"
+                    + "setSyncAdapter(ComponentName) or 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/SyncService.java b/core/java/android/content/SyncService.java
new file mode 100644
index 0000000..4df998c
--- /dev/null
+++ b/core/java/android/content/SyncService.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.app.Service;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.Trace;
+import android.util.SparseArray;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+/**
+ * Simplified @link android.content.AbstractThreadedSyncAdapter. Folds that
+ * behaviour into a service to which the system can bind when requesting an
+ * anonymous (providerless/accountless) sync.
+ * <p>
+ * In order to perform an anonymous sync operation you must extend this service, implementing the
+ * abstract methods. This service must be declared in the application's manifest as usual. You
+ * can use this service for other work, however you <b> must not </b> override the onBind() method
+ * unless you know what you're doing, which limits the usefulness of this service for other work.
+ * <p>A {@link SyncService} can either be active or inactive. Different to an
+ * {@link AbstractThreadedSyncAdapter}, there is no
+ * {@link ContentResolver#setSyncAutomatically(android.accounts.Account account, String provider, boolean sync)},
+ * as well as no concept of initialisation (you can handle your own if needed).
+ *
+ * <pre>
+ * &lt;service android:name=".MySyncService"/&gt;
+ * </pre>
+ * Like @link android.content.AbstractThreadedSyncAdapter this service supports
+ * multiple syncs at the same time. Each incoming startSync() with a unique tag
+ * will spawn a thread to do the work of that sync. If startSync() is called
+ * with a tag that already exists, a SyncResult.ALREADY_IN_PROGRESS is returned.
+ * Remember that your service will spawn multiple threads if you schedule multiple syncs
+ * at once, so if you mutate local objects you must ensure synchronization.
+ */
+public abstract class SyncService extends Service {
+    private static final String TAG = "SyncService";
+
+    private final SyncAdapterImpl mSyncAdapter = new SyncAdapterImpl();
+
+    /** Keep track of on-going syncs, keyed by bundle. */
+    @GuardedBy("mSyncThreadLock")
+    private final SparseArray<SyncThread>
+            mSyncThreads = new SparseArray<SyncThread>();
+    /** Lock object for accessing the SyncThreads HashMap. */
+    private final Object mSyncThreadLock = new Object();
+    /**
+     * Default key for if this sync service does not support parallel operations. Currently not
+     * sure if null keys will make it into the ArrayMap for KLP, so keeping our default for now.
+     */
+    private static final int KEY_DEFAULT = 0;
+    /** Identifier for this sync service. */
+    private ComponentName mServiceComponent;
+
+    /** {@hide} */
+    public IBinder onBind(Intent intent) {
+        mServiceComponent = new ComponentName(this, getClass());
+        return mSyncAdapter.asBinder();
+    }
+
+    /** {@hide} */
+    private class SyncAdapterImpl extends ISyncServiceAdapter.Stub {
+        @Override
+        public void startSync(ISyncContext syncContext, Bundle extras) {
+            // Wrap the provided Sync Context because it may go away by the time
+            // we call it.
+            final SyncContext syncContextClient = new SyncContext(syncContext);
+            boolean alreadyInProgress = false;
+            final int extrasAsKey = extrasToKey(extras);
+            synchronized (mSyncThreadLock) {
+                if (mSyncThreads.get(extrasAsKey) == null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "starting sync for : " + mServiceComponent);
+                    }
+                    // Start sync.
+                    SyncThread syncThread = new SyncThread(syncContextClient, extras);
+                    mSyncThreads.put(extrasAsKey, syncThread);
+                    syncThread.start();
+                } else {
+                    // Don't want to call back to SyncManager while still
+                    // holding lock.
+                    alreadyInProgress = true;
+                }
+            }
+            if (alreadyInProgress) {
+                syncContextClient.onFinished(SyncResult.ALREADY_IN_PROGRESS);
+            }
+        }
+
+        /**
+         * Used by the SM to cancel a specific sync using the
+         * com.android.server.content.SyncManager.ActiveSyncContext as a handle.
+         */
+        @Override
+        public void cancelSync(ISyncContext syncContext) {
+            SyncThread runningSync = null;
+            synchronized (mSyncThreadLock) {
+                for (int i = 0; i < mSyncThreads.size(); i++) {
+                    SyncThread thread = mSyncThreads.valueAt(i);
+                    if (thread.mSyncContext.getSyncContextBinder() == syncContext.asBinder()) {
+                        runningSync = thread;
+                        break;
+                    }
+                }
+            }
+            if (runningSync != null) {
+                runningSync.interrupt();
+            }
+        }
+    }
+
+    /**
+     * 
+     * @param extras Bundle for which to compute hash
+     * @return an integer hash that is equal to that of another bundle if they both contain the
+     * same key -> value mappings, however, not necessarily in order.
+     * Based on the toString() representation of the value mapped.
+     */
+    private int extrasToKey(Bundle extras) {
+        int hash = KEY_DEFAULT; // Empty bundle, or no parallel operations enabled.
+        if (parallelSyncsEnabled()) {
+            for (String key : extras.keySet()) {
+                String mapping = key + " " + extras.get(key).toString();
+                hash += mapping.hashCode();
+            }
+        }
+        return hash;
+    }
+
+    /**
+     * {@hide}
+     * Similar to {@link android.content.AbstractThreadedSyncAdapter.SyncThread}. However while
+     * the ATSA considers an already in-progress sync to be if the account provided is currently
+     * syncing, this anonymous sync has no notion of account and considers a sync unique if the
+     * provided bundle is different.
+     */
+    private class SyncThread extends Thread {
+        private final SyncContext mSyncContext;
+        private final Bundle mExtras;
+        private final int mThreadsKey;
+
+        public SyncThread(SyncContext syncContext, Bundle extras) {
+            mSyncContext = syncContext;
+            mExtras = extras;
+            mThreadsKey = extrasToKey(extras);
+        }
+
+        @Override
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+            Trace.traceBegin(Trace.TRACE_TAG_SYNC_MANAGER, getApplication().getPackageName());
+
+            SyncResult syncResult = new SyncResult();
+            try {
+                if (isCancelled()) return;
+                // Run the sync.
+                SyncService.this.onPerformSync(mExtras, syncResult);
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_SYNC_MANAGER);
+                if (!isCancelled()) {
+                    mSyncContext.onFinished(syncResult);
+                }
+                // Synchronize so that the assignment will be seen by other
+                // threads that also synchronize accesses to mSyncThreads.
+                synchronized (mSyncThreadLock) {
+                    mSyncThreads.remove(mThreadsKey);
+                }
+            }
+        }
+
+        private boolean isCancelled() {
+            return Thread.currentThread().isInterrupted();
+        }
+    }
+
+    /**
+     * Initiate an anonymous sync using this service. SyncAdapter-specific
+     * parameters may be specified in extras, which is guaranteed to not be
+     * null.
+     */
+    public abstract void onPerformSync(Bundle extras, SyncResult syncResult);
+
+    /**
+     * Override this function to indicated whether you want to support parallel syncs.
+     * <p>If you override and return true multiple threads will be spawned within your Service to
+     * handle each concurrent sync request.
+     *
+     * @return false to indicate that this service does not support parallel operations by default.
+     */
+    protected boolean parallelSyncsEnabled() {
+        return false;
+    }
+}
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index b8ac3bf..40275d8 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -16,11 +16,15 @@
 
 package android.content.pm;
 
+import android.annotation.IntDef;
 import android.content.res.Configuration;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Printer;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Information you can retrieve about a particular application
  * activity or receiver. This corresponds to information collected
@@ -212,6 +216,28 @@
      */
     public int flags;
 
+    /** @hide */
+    @IntDef({
+            SCREEN_ORIENTATION_UNSPECIFIED,
+            SCREEN_ORIENTATION_LANDSCAPE,
+            SCREEN_ORIENTATION_PORTRAIT,
+            SCREEN_ORIENTATION_USER,
+            SCREEN_ORIENTATION_BEHIND,
+            SCREEN_ORIENTATION_SENSOR,
+            SCREEN_ORIENTATION_NOSENSOR,
+            SCREEN_ORIENTATION_SENSOR_LANDSCAPE,
+            SCREEN_ORIENTATION_SENSOR_PORTRAIT,
+            SCREEN_ORIENTATION_REVERSE_LANDSCAPE,
+            SCREEN_ORIENTATION_REVERSE_PORTRAIT,
+            SCREEN_ORIENTATION_FULL_SENSOR,
+            SCREEN_ORIENTATION_USER_LANDSCAPE,
+            SCREEN_ORIENTATION_USER_PORTRAIT,
+            SCREEN_ORIENTATION_FULL_USER,
+            SCREEN_ORIENTATION_LOCKED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScreenOrientation {}
+
     /**
      * Constant corresponding to <code>unspecified</code> in
      * the {@link android.R.attr#screenOrientation} attribute.
@@ -323,6 +349,7 @@
      * {@link #SCREEN_ORIENTATION_FULL_USER},
      * {@link #SCREEN_ORIENTATION_LOCKED},
      */
+    @ScreenOrientation
     public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
     
     /**
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 9c46d96..8434c5d 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -338,7 +338,7 @@
      * the normal application lifecycle.
      *
      * <p>Comes from the
-     * {@link android.R.styleable#AndroidManifestApplication_cantSaveState android:cantSaveState}
+     * android.R.styleable#AndroidManifestApplication_cantSaveState
      * attribute of the &lt;application&gt; tag.
      *
      * {@hide}
@@ -456,7 +456,13 @@
      * behavior was introduced.
      */
     public int targetSdkVersion;
-    
+
+    /**
+     * The app's declared version code.
+     * @hide
+     */
+    public int versionCode;
+
     /**
      * When false, indicates that all components within this application are
      * considered disabled, regardless of their individually set enabled status.
@@ -508,7 +514,8 @@
         if (sharedLibraryFiles != null) {
             pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
         }
-        pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion);
+        pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion
+                + " versionCode=" + versionCode);
         if (manageSpaceActivityName != null) {
             pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
         }
@@ -576,6 +583,7 @@
         dataDir = orig.dataDir;
         uid = orig.uid;
         targetSdkVersion = orig.targetSdkVersion;
+        versionCode = orig.versionCode;
         enabled = orig.enabled;
         enabledSetting = orig.enabledSetting;
         installLocation = orig.installLocation;
@@ -616,6 +624,7 @@
         dest.writeString(dataDir);
         dest.writeInt(uid);
         dest.writeInt(targetSdkVersion);
+        dest.writeInt(versionCode);
         dest.writeInt(enabled ? 1 : 0);
         dest.writeInt(enabledSetting);
         dest.writeInt(installLocation);
@@ -655,6 +664,7 @@
         dataDir = source.readString();
         uid = source.readInt();
         targetSdkVersion = source.readInt();
+        versionCode = source.readInt();
         enabled = source.readInt() != 0;
         enabledSetting = source.readInt();
         installLocation = source.readInt();
diff --git a/core/java/android/content/pm/FeatureInfo.java b/core/java/android/content/pm/FeatureInfo.java
index 89394f9..d919fc3 100644
--- a/core/java/android/content/pm/FeatureInfo.java
+++ b/core/java/android/content/pm/FeatureInfo.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Parcelable.Creator;
 
 /**
  * A single feature that can be requested by an application. This corresponds
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 20002ad..c9fb530 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -237,6 +237,10 @@
     int getPreferredActivities(out List<IntentFilter> outFilters,
             out List<ComponentName> outActivities, String packageName);
 
+    void addPersistentPreferredActivity(in IntentFilter filter, in ComponentName activity, int userId);
+
+    void clearPackagePersistentPreferredActivities(String packageName, int userId);
+
     /**
      * Report the set of 'Home' activity candidates, plus (if any) which of them
      * is the current "always use this one" setting.
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 785f2b4..ef0c4d5 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -209,6 +209,19 @@
      */
     public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2;
     /**
+     * Flag for {@link #requiredForProfile}
+     * The application will always be installed for a restricted profile.
+     * @hide
+     */
+    public static final int RESTRICTED_PROFILE = 1;
+    /**
+     * Flag for {@link #requiredForProfile}
+     * The application will always be installed for a managed profile.
+     * @hide
+     */
+    public static final int MANAGED_PROFILE = 2;
+
+    /**
      * The install location requested by the activity.  From the
      * {@link android.R.attr#installLocation} attribute, one of
      * {@link #INSTALL_LOCATION_AUTO},
@@ -218,6 +231,12 @@
      */
     public int installLocation = INSTALL_LOCATION_INTERNAL_ONLY;
 
+    /**
+     * Defines which profiles this app is required for.
+     * @hide
+     */
+    public int requiredForProfile;
+
     /** @hide */
     public boolean requiredForAllUsers;
 
@@ -276,6 +295,7 @@
         dest.writeTypedArray(reqFeatures, parcelableFlags);
         dest.writeInt(installLocation);
         dest.writeInt(requiredForAllUsers ? 1 : 0);
+        dest.writeInt(requiredForProfile);
         dest.writeString(restrictedAccountType);
         dest.writeString(requiredAccountType);
         dest.writeString(overlayTarget);
@@ -318,6 +338,7 @@
         reqFeatures = source.createTypedArray(FeatureInfo.CREATOR);
         installLocation = source.readInt();
         requiredForAllUsers = source.readInt() != 0;
+        requiredForProfile = source.readInt();
         restrictedAccountType = source.readString();
         requiredAccountType = source.readString();
         overlayTarget = source.readString();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 34a6f1d..e86833b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -16,6 +16,7 @@
 
 package android.content.pm;
 
+import android.annotation.IntDef;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ComponentName;
@@ -33,6 +34,8 @@
 import android.util.DisplayMetrics;
 
 import java.io.File;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -190,6 +193,11 @@
      */
     public static final int MATCH_DEFAULT_ONLY   = 0x00010000;
 
+    /** @hide */
+    @IntDef({PERMISSION_GRANTED, PERMISSION_DENIED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PermissionResult {}
+
     /**
      * Permission check result: this is returned by {@link #checkPermission}
      * if the permission has been granted to the given package.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a07ec1a..f76aada 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -306,6 +306,7 @@
         if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0
                 || (pi.applicationInfo.flags&ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
             pi.requiredForAllUsers = p.mRequiredForAllUsers;
+            pi.requiredForProfile = p.mRequiredForProfile;
         }
         pi.restrictedAccountType = p.mRestrictedAccountType;
         pi.requiredAccountType = p.mRequiredAccountType;
@@ -988,7 +989,7 @@
         
         TypedArray sa = res.obtainAttributes(attrs,
                 com.android.internal.R.styleable.AndroidManifest);
-        pkg.mVersionCode = sa.getInteger(
+        pkg.mVersionCode = pkg.applicationInfo.versionCode = sa.getInteger(
                 com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
         pkg.mVersionName = sa.getNonConfigurationString(
                 com.android.internal.R.styleable.AndroidManifest_versionName, 0);
@@ -1986,6 +1987,8 @@
                 false)) {
             owner.mRequiredForAllUsers = true;
         }
+        owner.mRequiredForProfile = sa.getInt(
+                com.android.internal.R.styleable.AndroidManifestApplication_requiredForProfile, 0);
 
         String restrictedAccountType = sa.getString(com.android.internal.R.styleable
                 .AndroidManifestApplication_restrictedAccountType);
@@ -3586,6 +3589,9 @@
         /* An app that's required for all users and cannot be uninstalled for a user */
         public boolean mRequiredForAllUsers;
 
+        /* For which types of profile this app is required */
+        public int mRequiredForProfile;
+
         /* The restricted account authenticator type that is used by this application */
         public String mRestrictedAccountType;
 
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 875e8de..4a743a5 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -140,12 +140,33 @@
         mContext.registerReceiver(mExternalReceiver, sdFilter);
     }
 
+    private final void handlePackageEvent(Intent intent, int userId) {
+        // Don't regenerate the services map when the package is removed or its
+        // ASEC container unmounted as a step in replacement.  The subsequent
+        // _ADDED / _AVAILABLE call will regenerate the map in the final state.
+        final String action = intent.getAction();
+        // it's a new-component action if it isn't some sort of removal
+        final boolean isRemoval = Intent.ACTION_PACKAGE_REMOVED.equals(action)
+                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action);
+        // if it's a removal, is it part of an update-in-place step?
+        final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+        if (isRemoval && replacing) {
+            // package is going away, but it's the middle of an upgrade: keep the current
+            // state and do nothing here.  This clause is intentionally empty.
+        } else {
+            // either we're adding/changing, or it's a removal without replacement, so
+            // we need to recalculate the set of available services
+            generateServicesMap(userId);
+        }
+    }
+
     private final BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
             if (uid != -1) {
-                generateServicesMap(UserHandle.getUserId(uid));
+                handlePackageEvent(intent, UserHandle.getUserId(uid));
             }
         }
     };
@@ -154,7 +175,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             // External apps can't coexist with multi-user, so scan owner
-            generateServicesMap(UserHandle.USER_OWNER);
+            handlePackageEvent(intent, UserHandle.USER_OWNER);
         }
     };
 
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 4c87830..6f1d4f8 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 
 /**
@@ -63,6 +64,15 @@
      */
     public static final int FLAG_INITIALIZED = 0x00000010;
 
+    /**
+     * Indicates that this user is a profile of another user, for example holding a users
+     * corporate data.
+     */
+    public static final int FLAG_MANAGED_PROFILE = 0x00000020;
+
+
+    public static final int NO_RELATED_GROUP_ID = -1;
+
     public int id;
     public int serialNumber;
     public String name;
@@ -70,6 +80,7 @@
     public int flags;
     public long creationTime;
     public long lastLoggedInTime;
+    public int relatedGroupId;
 
     /** User is only partially created. */
     public boolean partial;
@@ -83,6 +94,7 @@
         this.name = name;
         this.flags = flags;
         this.iconPath = iconPath;
+        this.relatedGroupId = NO_RELATED_GROUP_ID;
     }
 
     public boolean isPrimary() {
@@ -101,6 +113,18 @@
         return (flags & FLAG_RESTRICTED) == FLAG_RESTRICTED;
     }
 
+    public boolean isManagedProfile() {
+        return (flags & FLAG_MANAGED_PROFILE) == FLAG_MANAGED_PROFILE;
+    }
+
+    /**
+     * @return true if this user can be switched to.
+     **/
+    public boolean supportsSwitchTo() {
+        // TODO remove fw.show_hidden_users when we have finished developing managed profiles.
+        return !isManagedProfile() || SystemProperties.getBoolean("fw.show_hidden_users", false);
+    }
+
     public UserInfo() {
     }
 
@@ -113,6 +137,7 @@
         creationTime = orig.creationTime;
         lastLoggedInTime = orig.lastLoggedInTime;
         partial = orig.partial;
+        relatedGroupId = orig.relatedGroupId;
     }
 
     public UserHandle getUserHandle() {
@@ -137,6 +162,7 @@
         dest.writeLong(creationTime);
         dest.writeLong(lastLoggedInTime);
         dest.writeInt(partial ? 1 : 0);
+        dest.writeInt(relatedGroupId);
     }
 
     public static final Parcelable.Creator<UserInfo> CREATOR
@@ -158,5 +184,6 @@
         creationTime = source.readLong();
         lastLoggedInTime = source.readLong();
         partial = source.readInt() != 0;
+        relatedGroupId = source.readInt();
     }
 }
diff --git a/core/java/android/content/pm/XmlSerializerAndParser.java b/core/java/android/content/pm/XmlSerializerAndParser.java
index 935fc02..20cb61c 100644
--- a/core/java/android/content/pm/XmlSerializerAndParser.java
+++ b/core/java/android/content/pm/XmlSerializerAndParser.java
@@ -19,7 +19,6 @@
 import org.xmlpull.v1.XmlSerializer;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
-import android.os.Parcel;
 
 import java.io.IOException;
 
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 9ce17e4..a41b4f9 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -17,7 +17,6 @@
 package android.content.res;
 
 import android.os.ParcelFileDescriptor;
-import android.os.Trace;
 import android.util.Log;
 import android.util.TypedValue;
 
@@ -536,6 +535,9 @@
     }
     
     public final class AssetInputStream extends InputStream {
+        /**
+         * @hide
+         */
         public final int getAssetInt() {
             throw new UnsupportedOperationException();
         }
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index bd23db4..419abf2 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -16,12 +16,15 @@
 
 package android.content.res;
 
+import android.graphics.Color;
+
 import com.android.internal.util.ArrayUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.util.AttributeSet;
+import android.util.MathUtils;
 import android.util.SparseArray;
 import android.util.StateSet;
 import android.util.Xml;
@@ -171,7 +174,7 @@
      * Fill in this object based on the contents of an XML "selector" element.
      */
     private void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
-        throws XmlPullParserException, IOException {
+            throws XmlPullParserException, IOException {
 
         int type;
 
@@ -194,6 +197,8 @@
                 continue;
             }
 
+            int alphaRes = 0;
+            float alpha = 1.0f;
             int colorRes = 0;
             int color = 0xffff0000;
             boolean haveColor = false;
@@ -205,17 +210,20 @@
             for (i = 0; i < numAttrs; i++) {
                 final int stateResId = attrs.getAttributeNameResource(i);
                 if (stateResId == 0) break;
-                if (stateResId == com.android.internal.R.attr.color) {
+                if (stateResId == com.android.internal.R.attr.alpha) {
+                    alphaRes = attrs.getAttributeResourceValue(i, 0);
+                    if (alphaRes == 0) {
+                        alpha = attrs.getAttributeFloatValue(i, 1.0f);
+                    }
+                } else if (stateResId == com.android.internal.R.attr.color) {
                     colorRes = attrs.getAttributeResourceValue(i, 0);
-
                     if (colorRes == 0) {
                         color = attrs.getAttributeIntValue(i, color);
                         haveColor = true;
                     }
                 } else {
                     stateSpec[j++] = attrs.getAttributeBooleanValue(i, false)
-                                  ? stateResId
-                                  : -stateResId;
+                            ? stateResId : -stateResId;
                 }
             }
             stateSpec = StateSet.trimStateSet(stateSpec, j);
@@ -228,10 +236,18 @@
                         + ": <item> tag requires a 'android:color' attribute.");
             }
 
+            if (alphaRes != 0) {
+                alpha = r.getFraction(alphaRes, 1, 1);
+            }
+
+            // Apply alpha modulation.
+            final int alphaMod = MathUtils.constrain((int) (Color.alpha(color) * alpha), 0, 255);
+            color = (color & 0xFFFFFF) | (alphaMod << 24);
+
             if (listSize == 0 || stateSpec.length == 0) {
                 mDefaultColor = color;
             }
-            
+
             if (listSize + 1 >= listAllocated) {
                 listAllocated = ArrayUtils.idealIntArraySize(listSize + 1);
 
@@ -259,7 +275,17 @@
     public boolean isStateful() {
         return mStateSpecs.length > 1;
     }
-    
+
+    public boolean isOpaque() {
+        final int n = mColors.length;
+        for (int i = 0; i < n; i++) {
+            if (Color.alpha(mColors[i]) != 0xFF) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /**
      * Return the color associated with the given set of {@link android.view.View} states.
      *
@@ -289,6 +315,25 @@
         return mDefaultColor;
     }
 
+    /**
+     * Return the states in this {@link ColorStateList}.
+     * @return the states in this {@link ColorStateList}
+     * @hide
+     */
+    public int[][] getStates() {
+        return mStateSpecs;
+    }
+
+    /**
+     * Return the colors in this {@link ColorStateList}.
+     * @return the colors in this {@link ColorStateList}
+     * @hide
+     */
+    public int[] getColors() {
+        return mColors;
+    }
+
+    @Override
     public String toString() {
         return "ColorStateList{" +
                "mStateSpecs=" + Arrays.deepToString(mStateSpecs) +
@@ -296,14 +341,16 @@
                "mDefaultColor=" + mDefaultColor + '}';
     }
 
+    @Override
     public int describeContents() {
         return 0;
     }
 
+    @Override
     public void writeToParcel(Parcel dest, int flags) {
         final int N = mStateSpecs.length;
         dest.writeInt(N);
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             dest.writeIntArray(mStateSpecs[i]);
         }
         dest.writeIntArray(mColors);
@@ -311,17 +358,19 @@
 
     public static final Parcelable.Creator<ColorStateList> CREATOR =
             new Parcelable.Creator<ColorStateList>() {
+        @Override
         public ColorStateList[] newArray(int size) {
             return new ColorStateList[size];
         }
 
+        @Override
         public ColorStateList createFromParcel(Parcel source) {
             final int N = source.readInt();
-            int[][] stateSpecs = new int[N][];
-            for (int i=0; i<N; i++) {
+            final int[][] stateSpecs = new int[N][];
+            for (int i = 0; i < N; i++) {
                 stateSpecs[i] = source.createIntArray();
             }
-            int[] colors = source.createIntArray();
+            final int[] colors = source.createIntArray();
             return new ColorStateList(stateSpecs, colors);
         }
     };
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 3d9daca..5c27072 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -36,7 +36,6 @@
 import android.util.Slog;
 import android.util.TypedValue;
 import android.util.LongSparseArray;
-import android.view.DisplayAdjustments;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -72,16 +71,19 @@
  */
 public class Resources {
     static final String TAG = "Resources";
+
     private static final boolean DEBUG_LOAD = false;
     private static final boolean DEBUG_CONFIG = false;
     private static final boolean DEBUG_ATTRIBUTES_CACHE = false;
     private static final boolean TRACE_FOR_PRELOAD = false;
     private static final boolean TRACE_FOR_MISS_PRELOAD = false;
 
+    private static final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigToNative(
+            ActivityInfo.CONFIG_LAYOUT_DIRECTION);
+
     private static final int ID_OTHER = 0x01000004;
 
     private static final Object sSync = new Object();
-    /*package*/ static Resources mSystem = null;
 
     // Information about preloaded resources.  Note that they are not
     // protected by a lock, because while preloading in zygote we are all
@@ -92,32 +94,35 @@
     private static final LongSparseArray<ColorStateList> sPreloadedColorStateLists
             = new LongSparseArray<ColorStateList>();
 
+    // Used by BridgeResources in layoutlib
+    static Resources mSystem = null;
+
     private static boolean sPreloaded;
     private static int sPreloadedDensity;
 
     // These are protected by mAccessLock.
+    private final Object mAccessLock = new Object();
+    private final Configuration mTmpConfig = new Configuration();
+    private final LongSparseArray<WeakReference<Drawable.ConstantState>> mDrawableCache
+            = new LongSparseArray<WeakReference<Drawable.ConstantState>>(0);
+    private final LongSparseArray<WeakReference<ColorStateList>> mColorStateListCache
+            = new LongSparseArray<WeakReference<ColorStateList>>(0);
+    private final LongSparseArray<WeakReference<Drawable.ConstantState>> mColorDrawableCache
+            = new LongSparseArray<WeakReference<Drawable.ConstantState>>(0);
 
-    /*package*/ final Object mAccessLock = new Object();
-    /*package*/ final Configuration mTmpConfig = new Configuration();
-    /*package*/ TypedValue mTmpValue = new TypedValue();
-    /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache
-            = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0);
-    /*package*/ final LongSparseArray<WeakReference<ColorStateList> > mColorStateListCache
-            = new LongSparseArray<WeakReference<ColorStateList> >(0);
-    /*package*/ final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache
-            = new LongSparseArray<WeakReference<Drawable.ConstantState> >(0);
-    /*package*/ boolean mPreloading;
+    private TypedValue mTmpValue = new TypedValue();
+    private boolean mPreloading;
 
-    /*package*/ TypedArray mCachedStyledAttributes = null;
-    RuntimeException mLastRetrievedAttrs = null;
+    private TypedArray mCachedStyledAttributes = null;
+    private RuntimeException mLastRetrievedAttrs = null;
 
     private int mLastCachedXmlBlockIndex = -1;
     private final int[] mCachedXmlBlockIds = { 0, 0, 0, 0 };
     private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[4];
 
-    /*package*/ final AssetManager mAssets;
+    private final AssetManager mAssets;
     private final Configuration mConfiguration = new Configuration();
-    /*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
+    private final DisplayMetrics mMetrics = new DisplayMetrics();
     private NativePluralRules mPluralRule;
 
     private CompatibilityInfo mCompatibilityInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
@@ -681,12 +686,27 @@
      * @param id The desired resource identifier, as generated by the aapt
      *           tool. This integer encodes the package, type, and resource
      *           entry. The value 0 is an invalid identifier.
-     *
-     * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
-     * 
      * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *         not exist.
      */
     public Drawable getDrawable(int id) throws NotFoundException {
+        return getDrawable(id, null);
+    }
+
+    /**
+     * Return a drawable object associated with a particular resource ID and
+     * styled for the specified theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt
+     *           tool. This integer encodes the package, type, and resource
+     *           entry. The value 0 is an invalid identifier.
+     * @param theme The theme used to style the drawable attributes.
+     * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *         not exist.
+     */
+    public Drawable getDrawable(int id, Theme theme) throws NotFoundException {
         TypedValue value;
         synchronized (mAccessLock) {
             value = mTmpValue;
@@ -697,7 +717,7 @@
             }
             getValue(id, value, true);
         }
-        Drawable res = loadDrawable(value, id);
+        final Drawable res = loadDrawable(value, id, theme);
         synchronized (mAccessLock) {
             if (mTmpValue == null) {
                 mTmpValue = value;
@@ -715,17 +735,36 @@
      * depending on the underlying resource -- for example, a solid color, PNG
      * image, scalable image, etc. The Drawable API hides these implementation
      * details.
-     * 
+     *
      * @param id The desired resource identifier, as generated by the aapt tool.
      *            This integer encodes the package, type, and resource entry.
      *            The value 0 is an invalid identifier.
      * @param density the desired screen density indicated by the resource as
      *            found in {@link DisplayMetrics}.
+     * @return Drawable An object that can be used to draw this resource.
      * @throws NotFoundException Throws NotFoundException if the given ID does
      *             not exist.
-     * @return Drawable An object that can be used to draw this resource.
+     * @see #getDrawableForDensity(int, int, Theme)
      */
     public Drawable getDrawableForDensity(int id, int density) throws NotFoundException {
+        return getDrawableForDensity(id, density, null);
+    }
+
+    /**
+     * Return a drawable object associated with a particular resource ID for the
+     * given screen density in DPI and styled for the specified theme.
+     *
+     * @param id The desired resource identifier, as generated by the aapt tool.
+     *            This integer encodes the package, type, and resource entry.
+     *            The value 0 is an invalid identifier.
+     * @param density The desired screen density indicated by the resource as
+     *            found in {@link DisplayMetrics}.
+     * @param theme The theme used to style the drawable attributes.
+     * @return Drawable An object that can be used to draw this resource.
+     * @throws NotFoundException Throws NotFoundException if the given ID does
+     *             not exist.
+     */
+    public Drawable getDrawableForDensity(int id, int density, Theme theme) {
         TypedValue value;
         synchronized (mAccessLock) {
             value = mTmpValue;
@@ -752,7 +791,7 @@
             }
         }
 
-        Drawable res = loadDrawable(value, id);
+        final Drawable res = loadDrawable(value, id, theme);
         synchronized (mAccessLock) {
             if (mTmpValue == null) {
                 mTmpValue = value;
@@ -1246,8 +1285,9 @@
          * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
          */
         public TypedArray obtainStyledAttributes(int[] attrs) {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
+            array.mTheme = this;
             array.mRsrcs = attrs;
             AssetManager.applyStyle(mTheme, 0, 0, 0, attrs,
                     array.mData, array.mIndices);
@@ -1274,10 +1314,10 @@
          * @see #obtainStyledAttributes(int[])
          * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
          */
-        public TypedArray obtainStyledAttributes(int resid, int[] attrs)
-                throws NotFoundException {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+        public TypedArray obtainStyledAttributes(int resid, int[] attrs) throws NotFoundException {
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
+            array.mTheme = this;
             array.mRsrcs = attrs;
 
             AssetManager.applyStyle(mTheme, 0, resid, 0, attrs,
@@ -1361,19 +1401,18 @@
          */
         public TypedArray obtainStyledAttributes(AttributeSet set,
                 int[] attrs, int defStyleAttr, int defStyleRes) {
-            int len = attrs.length;
-            TypedArray array = getCachedStyledAttributes(len);
+            final int len = attrs.length;
+            final TypedArray array = getCachedStyledAttributes(len);
 
             // XXX note that for now we only work with compiled XML files.
             // To support generic XML files we will need to manually parse
             // out the attributes from the XML file (applying type information
             // contained in the resources and such).
-            XmlBlock.Parser parser = (XmlBlock.Parser)set;
-            AssetManager.applyStyle(
-                mTheme, defStyleAttr, defStyleRes,
-                parser != null ? parser.mParseState : 0, attrs,
-                        array.mData, array.mIndices);
+            final XmlBlock.Parser parser = (XmlBlock.Parser)set;
+            AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
+                    parser != null ? parser.mParseState : 0, attrs, array.mData, array.mIndices);
 
+            array.mTheme = this;
             array.mRsrcs = attrs;
             array.mXml = parser;
 
@@ -1439,6 +1478,21 @@
         }
 
         /**
+         * Return a drawable object associated with a particular resource ID
+         * and styled for the Theme.
+         *
+         * @param id The desired resource identifier, as generated by the aapt
+         *           tool. This integer encodes the package, type, and resource
+         *           entry. The value 0 is an invalid identifier.
+         * @return Drawable An object that can be used to draw this resource.
+         * @throws NotFoundException Throws NotFoundException if the given ID
+         *         does not exist.
+         */
+        public Drawable getDrawable(int id) throws NotFoundException {
+            return Resources.this.getDrawable(id, this);
+        }
+
+        /**
          * Print contents of this theme out to the log.  For debugging only.
          * 
          * @param priority The log priority to use.
@@ -1448,7 +1502,8 @@
         public void dump(int priority, String tag, String prefix) {
             AssetManager.dumpTheme(mTheme, priority, tag, prefix);
         }
-        
+
+        @Override
         protected void finalize() throws Throwable {
             super.finalize();
             mAssets.releaseTheme(mTheme);
@@ -1459,6 +1514,7 @@
             mTheme = mAssets.createTheme();
         }
 
+        @SuppressWarnings("hiding")
         private final AssetManager mAssets;
         private final long mTheme;
     }
@@ -1569,7 +1625,7 @@
 
             String locale = null;
             if (mConfiguration.locale != null) {
-                locale = mConfiguration.locale.toLanguageTag();
+                locale = adjustLanguageTag(localeToLanguageTag(mConfiguration.locale));
             }
             int width, height;
             if (mMetrics.widthPixels >= mMetrics.heightPixels) {
@@ -1650,6 +1706,47 @@
         }
     }
 
+    // Locale.toLanguageTag() is not available in Java6. LayoutLib overrides
+    // this method to enable users to use Java6.
+    private String localeToLanguageTag(Locale locale) {
+        return locale.toLanguageTag();
+    }
+
+    /**
+     * {@code Locale.toLanguageTag} will transform the obsolete (and deprecated)
+     * language codes "in", "ji" and "iw" to "id", "yi" and "he" respectively.
+     *
+     * All released versions of android prior to "L" used the deprecated language
+     * tags, so we will need to support them for backwards compatibility.
+     *
+     * Note that this conversion needs to take place *after* the call to
+     * {@code toLanguageTag} because that will convert all the deprecated codes to
+     * the new ones, even if they're set manually.
+     */
+    private static String adjustLanguageTag(String languageTag) {
+        final int separator = languageTag.indexOf('-');
+        final String language;
+        final String remainder;
+
+        if (separator == -1) {
+            language = languageTag;
+            remainder = "";
+        } else {
+            language = languageTag.substring(0, separator);
+            remainder = languageTag.substring(separator);
+        }
+
+        if ("id".equals(language)) {
+            return "in" + remainder;
+        } else if ("yi".equals(language)) {
+            return "ji" + remainder;
+        } else if ("he".equals(language)) {
+            return "iw" + remainder;
+        } else {
+            return languageTag;
+        }
+    }
+
     /**
      * Update the system resources configuration if they have previously
      * been initialized.
@@ -2020,17 +2117,14 @@
         return true;
     }
 
-    static private final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigToNative(
-            ActivityInfo.CONFIG_LAYOUT_DIRECTION);
-
-    /*package*/ Drawable loadDrawable(TypedValue value, int id)
-            throws NotFoundException {
-
+    /*package*/ Drawable loadDrawable(TypedValue value, int id, Theme theme) throws NotFoundException {
         if (TRACE_FOR_PRELOAD) {
             // Log only framework resources
             if ((id >>> 24) == 0x1) {
                 final String name = getResourceName(id);
-                if (name != null) android.util.Log.d("PreloadDrawable", name);
+                if (name != null) {
+                    Log.d("PreloadDrawable", name);
+                }
             }
         }
 
@@ -2235,12 +2329,12 @@
                     "Resource is not a ColorStateList (color or path): " + value);
         }
         
-        String file = value.string.toString();
+        final String file = value.string.toString();
 
         if (file.endsWith(".xml")) {
             Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, file);
             try {
-                XmlResourceParser rp = loadXmlResourceParser(
+                final XmlResourceParser rp = loadXmlResourceParser(
                         file, id, value.assetCookie, "colorstatelist"); 
                 csl = ColorStateList.createFromXml(this, rp);
                 rp.close();
@@ -2363,6 +2457,15 @@
                 + Integer.toHexString(id));
     }
 
+    /*package*/ void recycleCachedStyledAttributes(TypedArray attrs) {
+        synchronized (mAccessLock) {
+            final TypedArray cached = mCachedStyledAttributes;
+            if (cached == null || cached.mData.length < attrs.mData.length) {
+                mCachedStyledAttributes = attrs;
+            }
+        }
+    }
+
     private TypedArray getCachedStyledAttributes(int len) {
         synchronized (mAccessLock) {
             TypedArray attrs = mCachedStyledAttributes;
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 83d48aa..4858d08 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -16,7 +16,6 @@
 
 package android.content.res;
 
-import android.content.pm.ActivityInfo;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
@@ -38,13 +37,16 @@
  */
 public class TypedArray {
     private final Resources mResources;
+    private final DisplayMetrics mMetrics;
+    private final AssetManager mAssets;
     /*package*/ XmlBlock.Parser mXml;
     /*package*/ int[] mRsrcs;
     /*package*/ int[] mData;
     /*package*/ int[] mIndices;
     /*package*/ int mLength;
     /*package*/ TypedValue mValue = new TypedValue();
-   
+    /*package*/ Resources.Theme mTheme;
+
     /**
      * Return the number of values in this array.
      */
@@ -393,7 +395,7 @@
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimension(
-                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
+                data[index+AssetManager.STYLE_DATA], mMetrics);
         }
 
         throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
@@ -425,7 +427,7 @@
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimensionPixelOffset(
-                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
+                data[index+AssetManager.STYLE_DATA], mMetrics);
         }
 
         throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
@@ -458,7 +460,7 @@
             return defValue;
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimensionPixelSize(
-                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
+                data[index+AssetManager.STYLE_DATA], mMetrics);
         }
 
         throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
@@ -486,7 +488,7 @@
             return data[index+AssetManager.STYLE_DATA];
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimensionPixelSize(
-                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
+                data[index+AssetManager.STYLE_DATA], mMetrics);
         }
 
         throw new RuntimeException(getPositionDescription()
@@ -515,7 +517,7 @@
             return data[index+AssetManager.STYLE_DATA];
         } else if (type == TypedValue.TYPE_DIMENSION) {
             return TypedValue.complexToDimensionPixelSize(
-                data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
+                data[index+AssetManager.STYLE_DATA], mMetrics);
         }
 
         return defValue;
@@ -599,7 +601,7 @@
                                    + " cookie=" + value.assetCookie);
                 System.out.println("******************************************************************");
             }
-            return mResources.loadDrawable(value, value.resourceId);
+            return mResources.loadDrawable(value, value.resourceId, mTheme);
         }
         return null;
     }
@@ -688,13 +690,11 @@
      * Give back a previously retrieved array, for later re-use.
      */
     public void recycle() {
-        synchronized (mResources.mAccessLock) {
-            TypedArray cached = mResources.mCachedStyledAttributes;
-            if (cached == null || cached.mData.length < mData.length) {
-                mXml = null;
-                mResources.mCachedStyledAttributes = this;
-            }
-        }
+        mResources.recycleCachedStyledAttributes(this);
+
+        mXml = null;
+        mRsrcs = null;
+        mTheme = null;
     }
 
     private boolean getValueAt(int index, TypedValue outValue) {
@@ -723,18 +723,19 @@
             }
             return null;
         }
-        //System.out.println("Getting pooled from: " + v);
-        return mResources.mAssets.getPooledString(
-            cookie, data[index+AssetManager.STYLE_DATA]);
+        return mAssets.getPooledString(cookie, data[index+AssetManager.STYLE_DATA]);
     }
 
     /*package*/ TypedArray(Resources resources, int[] data, int[] indices, int len) {
         mResources = resources;
+        mMetrics = mResources.getDisplayMetrics();
+        mAssets = mResources.getAssets();
         mData = data;
         mIndices = indices;
         mLength = len;
     }
 
+    @Override
     public String toString() {
         return Arrays.toString(mData);
     }
diff --git a/core/java/android/database/CursorToBulkCursorAdaptor.java b/core/java/android/database/CursorToBulkCursorAdaptor.java
index 82a61d4..7dcfae2 100644
--- a/core/java/android/database/CursorToBulkCursorAdaptor.java
+++ b/core/java/android/database/CursorToBulkCursorAdaptor.java
@@ -20,7 +20,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
-import android.util.Log;
 
 
 /**
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 431eca2..2dd4800 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.database.DatabaseErrorHandler;
-import android.database.DefaultDatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 import android.util.Log;
 
diff --git a/core/java/android/ddm/DdmHandleNativeHeap.java b/core/java/android/ddm/DdmHandleNativeHeap.java
index 6bd65aa..775c570 100644
--- a/core/java/android/ddm/DdmHandleNativeHeap.java
+++ b/core/java/android/ddm/DdmHandleNativeHeap.java
@@ -20,7 +20,6 @@
 import org.apache.harmony.dalvik.ddmc.ChunkHandler;
 import org.apache.harmony.dalvik.ddmc.DdmServer;
 import android.util.Log;
-import java.nio.ByteBuffer;
 
 /**
  * Handle thread-related traffic.
diff --git a/core/java/android/ddm/DdmHandleProfiling.java b/core/java/android/ddm/DdmHandleProfiling.java
index 537763d..cce4dd2 100644
--- a/core/java/android/ddm/DdmHandleProfiling.java
+++ b/core/java/android/ddm/DdmHandleProfiling.java
@@ -21,7 +21,6 @@
 import org.apache.harmony.dalvik.ddmc.DdmServer;
 import android.os.Debug;
 import android.util.Log;
-import java.io.IOException;
 import java.nio.ByteBuffer;
 
 /**
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
index 2d47f28..6e3a00f 100644
--- a/core/java/android/gesture/GestureOverlayView.java
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -134,11 +134,16 @@
         this(context, attrs, com.android.internal.R.attr.gestureOverlayViewStyle);
     }
 
-    public GestureOverlayView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public GestureOverlayView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.GestureOverlayView, defStyle, 0);
+    public GestureOverlayView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.GestureOverlayView, defStyleAttr, defStyleRes);
 
         mGestureStrokeWidth = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth,
                 mGestureStrokeWidth);
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 111062d..35c86e7 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -45,8 +45,8 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * The Camera class is used to set image capture settings, start/stop preview,
@@ -2150,10 +2150,20 @@
         private static final String PIXEL_FORMAT_JPEG = "jpeg";
         private static final String PIXEL_FORMAT_BAYER_RGGB = "bayer-rggb";
 
-        private HashMap<String, String> mMap;
+        /**
+         * Order matters: Keys that are {@link #set(String, String) set} later
+         * will take precedence over keys that are set earlier (if the two keys
+         * conflict with each other).
+         *
+         * <p>One example is {@link #setPreviewFpsRange(int, int)} , since it
+         * conflicts with {@link #setPreviewFrameRate(int)} whichever key is set later
+         * is the one that will take precedence.
+         * </p>
+         */
+        private final LinkedHashMap<String, String> mMap;
 
         private Parameters() {
-            mMap = new HashMap<String, String>(64);
+            mMap = new LinkedHashMap<String, String>(/*initialCapacity*/64);
         }
 
         /**
@@ -2233,7 +2243,7 @@
                 return;
             }
 
-            mMap.put(key, value);
+            put(key, value);
         }
 
         /**
@@ -2243,7 +2253,18 @@
          * @param value the int value of the parameter
          */
         public void set(String key, int value) {
-            mMap.put(key, Integer.toString(value));
+            put(key, Integer.toString(value));
+        }
+
+        private void put(String key, String value) {
+            /*
+             * Remove the key if it already exists.
+             *
+             * This way setting a new value for an already existing key will always move
+             * that key to be ordered the latest in the map.
+             */
+            mMap.remove(key);
+            mMap.put(key, value);
         }
 
         private void set(String key, List<Area> areas) {
diff --git a/core/java/android/hardware/GeomagneticField.java b/core/java/android/hardware/GeomagneticField.java
index 0369825..ef05732 100644
--- a/core/java/android/hardware/GeomagneticField.java
+++ b/core/java/android/hardware/GeomagneticField.java
@@ -361,7 +361,7 @@
             mP[0] = new float[] { 1.0f };
             mPDeriv[0] = new float[] { 0.0f };
             for (int n = 1; n <= maxN; n++) {
-            	mP[n] = new float[n + 1];
+                mP[n] = new float[n + 1];
                 mPDeriv[n] = new float[n + 1];
                 for (int m = 0; m <= n; m++) {
                     if (n == m) {
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 542af6a..4c50dda 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -61,4 +61,12 @@
     int removeListener(ICameraServiceListener listener);
 
     int getCameraCharacteristics(int cameraId, out CameraMetadataNative info);
+
+    /**
+     * The java stubs for this method are not intended to be used.  Please use
+     * the native stub in frameworks/av/include/camera/ICameraService.h instead.
+     * The BinderHolder output is being used as a placeholder, and will not be
+     * well-formatted in the generated java method.
+     */
+    int getCameraVendorTagDescriptor(out BinderHolder desc);
 }
diff --git a/core/java/android/hardware/SerialManager.java b/core/java/android/hardware/SerialManager.java
index c5e1c2b..e0680bf22 100644
--- a/core/java/android/hardware/SerialManager.java
+++ b/core/java/android/hardware/SerialManager.java
@@ -17,16 +17,12 @@
 
 package android.hardware;
 
-import android.app.PendingIntent;
 import android.content.Context;
-import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
-import android.os.SystemProperties;
 import android.util.Log;
 
 import java.io.IOException;
-import java.util.HashMap;
 
 /**
  * @hide
diff --git a/core/java/android/hardware/SerialPort.java b/core/java/android/hardware/SerialPort.java
index f50cdef..5d83d9c 100644
--- a/core/java/android/hardware/SerialPort.java
+++ b/core/java/android/hardware/SerialPort.java
@@ -17,14 +17,9 @@
 package android.hardware;
 
 import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 
 import java.nio.ByteBuffer;
 
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index a38beec..45d6e88 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -126,206 +126,300 @@
      * modify the comment blocks at the start or end.
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
 
+
     /**
-     * <p>
-     * Which set of antibanding modes are
-     * supported
-     * </p>
+     * <p>The set of auto-exposure antibanding modes that are
+     * supported by this camera device.</p>
+     * <p>Not all of the auto-exposure anti-banding modes may be
+     * supported by a given camera device. This field lists the
+     * valid anti-banding modes that the application may request
+     * for this camera device; they must include AUTO.</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>
+     * <p>The set of auto-exposure modes that are supported by this
+     * camera device.</p>
+     * <p>Not all the auto-exposure modes may be supported by a
+     * given camera device, especially if no flash unit is
+     * available. This entry lists the valid modes for
+     * {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} for this camera device.</p>
+     * <p>All camera devices support ON, and all camera devices with
+     * flash units support ON_AUTO_FLASH and
+     * ON_ALWAYS_FLASH.</p>
+     * <p>FULL mode camera devices always support OFF mode,
+     * which enables application control of camera exposure time,
+     * sensitivity, and frame duration.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     */
+    public static final Key<byte[]> CONTROL_AE_AVAILABLE_MODES =
+            new Key<byte[]>("android.control.aeAvailableModes", 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
+     * <p>Maximum and minimum exposure compensation
      * setting, in counts of
-     * android.control.aeCompensationStepSize
-     * </p>
+     * {@link CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP android.control.aeCompensationStep}.</p>
+     *
+     * @see CameraCharacteristics#CONTROL_AE_COMPENSATION_STEP
      */
     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>
+     * <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>
+     * <p>List of AF modes that can be
+     * selected with {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}.</p>
+     * <p>Not all the auto-focus modes may be supported by a
+     * given camera device. This entry lists the valid modes for
+     * {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} for this camera device.</p>
+     * <p>All camera devices will support OFF mode, and all camera devices with
+     * adjustable focuser units (<code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>)
+     * will support AUTO mode.</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      */
     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>
+     * <p>List containing the subset of color effects
+     * specified in {@link CaptureRequest#CONTROL_EFFECT_MODE android.control.effectMode} that is supported by
+     * this device.</p>
+     * <p>This list contains the color effect modes that can be applied to
+     * images produced by the camera device. Only modes that have
+     * been fully implemented for the current device may be included here.
+     * Implementations are not expected to be consistent across all devices.
+     * If no color effect modes are available for a device, this should
+     * simply be set to OFF.</p>
+     * <p>A color effect will only be applied if
+     * {@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF.</p>
+     *
+     * @see CaptureRequest#CONTROL_EFFECT_MODE
+     * @see CaptureRequest#CONTROL_MODE
      */
     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>
+     * <p>List containing a subset of scene modes
+     * specified in {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode}.</p>
+     * <p>This list contains scene modes that can be set for the camera device.
+     * Only scene modes that have been fully implemented for the
+     * camera device may be included here. Implementations are not expected
+     * to be consistent across all devices. If no scene modes are supported
+     * by the camera device, this will be set to <code>[DISABLED]</code>.</p>
+     *
+     * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     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>
+     * <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);
 
     /**
+     * <p>The set of auto-white-balance modes ({@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode})
+     * that are supported by this camera device.</p>
+     * <p>Not all the auto-white-balance modes may be supported by a
+     * given camera device. This entry lists the valid modes for
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} for this camera device.</p>
+     * <p>All camera devices will support ON mode.</p>
+     * <p>FULL mode camera devices will always support OFF mode,
+     * which enables application control of white balance, by using
+     * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform} and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}({@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} must be set to TRANSFORM_MATRIX).</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
+     * @see CaptureRequest#CONTROL_AWB_MODE
      */
     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>
+     * <p>List of the maximum number of regions that can be used for metering in
+     * auto-exposure (AE), auto-white balance (AWB), and auto-focus (AF);
+     * this corresponds to the the maximum number of elements in
+     * {@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}, {@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions},
+     * and {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_REGIONS
+     * @see CaptureRequest#CONTROL_AF_REGIONS
+     * @see CaptureRequest#CONTROL_AWB_REGIONS
      */
-    public static final Key<Integer> CONTROL_MAX_REGIONS =
-            new Key<Integer>("android.control.maxRegions", int.class);
+    public static final Key<int[]> CONTROL_MAX_REGIONS =
+            new Key<int[]>("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>
+     * <p>The set of edge enhancement modes supported by this camera device.</p>
+     * <p>This tag lists the valid modes for {@link CaptureRequest#EDGE_MODE android.edge.mode}.</p>
+     * <p>Full-capability camera devices must always support OFF and FAST.</p>
+     *
+     * @see CaptureRequest#EDGE_MODE
      */
-    public static final Key<Byte> FLASH_INFO_AVAILABLE =
-            new Key<Byte>("android.flash.info.available", byte.class);
+    public static final Key<byte[]> EDGE_AVAILABLE_EDGE_MODES =
+            new Key<byte[]>("android.edge.availableEdgeModes", byte[].class);
 
     /**
-     * <p>
-     * Supported resolutions for the JPEG
-     * thumbnail
-     * </p>
+     * <p>Whether this camera device 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<Boolean> FLASH_INFO_AVAILABLE =
+            new Key<Boolean>("android.flash.info.available", boolean.class);
+
+    /**
+     * <p>The set of hot pixel correction modes that are supported by this
+     * camera device.</p>
+     * <p>This tag lists valid modes for {@link CaptureRequest#HOT_PIXEL_MODE android.hotPixel.mode}.</p>
+     * <p>FULL mode camera devices will always support FAST.</p>
+     *
+     * @see CaptureRequest#HOT_PIXEL_MODE
+     */
+    public static final Key<byte[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =
+            new Key<byte[]>("android.hotPixel.availableHotPixelModes", byte[].class);
+
+    /**
+     * <p>Supported resolutions for the JPEG thumbnail</p>
+     * <p>Below condiditions will be satisfied for this size list:</p>
+     * <ul>
+     * <li>The sizes will be sorted by increasing pixel area (width x height).
+     * If several resolutions have the same area, they will be sorted by increasing width.</li>
+     * <li>The aspect ratio of the largest thumbnail size will be same as the
+     * aspect ratio of largest JPEG output size in {@link CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS android.scaler.availableStreamConfigurations}.
+     * The largest size is defined as the size that has the largest pixel area
+     * in a given size list.</li>
+     * <li>Each output JPEG size in {@link CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS android.scaler.availableStreamConfigurations} will have at least
+     * one corresponding size that has the same aspect ratio in availableThumbnailSizes,
+     * and vice versa.</li>
+     * <li>All non (0, 0) sizes will have non-zero widths and heights.</li>
+     * </ul>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS
      */
     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>
+     * <p>List of supported aperture
+     * values.</p>
+     * <p>If the camera device doesn't support variable apertures,
+     * listed value will be the fixed aperture.</p>
+     * <p>If the camera device supports variable apertures, the aperture value
+     * in this list will be sorted in ascending order.</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>
+     * <p>List of supported neutral density filter values for
+     * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity}.</p>
+     * <p>If changing {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} is not supported,
+     * availableFilterDensities must contain only 0. Otherwise, this
+     * list contains only the exact filter density values available on
+     * this camera device.</p>
+     *
+     * @see CaptureRequest#LENS_FILTER_DENSITY
      */
     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>
+     * <p>The available focal lengths for this device for use with
+     * {@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}.</p>
+     * <p>If optical zoom is not supported, this will only report
+     * a single value corresponding to the static focal length of the
+     * device. Otherwise, this will report every focal length supported
+     * by the device.</p>
+     *
+     * @see CaptureRequest#LENS_FOCAL_LENGTH
      */
     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>
+     * <p>List containing a subset of the optical image
+     * stabilization (OIS) modes specified in
+     * {@link CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE android.lens.opticalStabilizationMode}.</p>
+     * <p>If OIS is not implemented for a given camera device, this should
+     * contain only OFF.</p>
+     *
+     * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
      */
     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>
+     * <p>Optional. Hyperfocal distance for this lens.</p>
+     * <p>If the lens is fixed focus, the camera device will report 0.</p>
+     * <p>If the lens is not fixed focus, the camera device will report this
+     * field when {@link CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION android.lens.info.focusDistanceCalibration} is APPROXIMATE or CALIBRATED.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
      */
     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>
+     * <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>
+     * <p>Dimensions of lens shading map.</p>
+     * <p>The map should be on the order of 30-40 rows and columns, and
+     * must be smaller than 64x64.</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>
+     * <p>The lens focus distance calibration quality.</p>
+     * <p>The lens focus distance calibration quality determines the reliability of
+     * focus related metadata entries, i.e. {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
+     * {@link CaptureResult#LENS_FOCUS_RANGE android.lens.focusRange}, {@link CameraCharacteristics#LENS_INFO_HYPERFOCAL_DISTANCE android.lens.info.hyperfocalDistance}, and
+     * {@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance}.</p>
+     *
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
+     * @see CaptureResult#LENS_FOCUS_RANGE
+     * @see CameraCharacteristics#LENS_INFO_HYPERFOCAL_DISTANCE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
+     * @see #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED
+     * @see #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE
+     * @see #LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED
+     */
+    public static final Key<Integer> LENS_INFO_FOCUS_DISTANCE_CALIBRATION =
+            new Key<Integer>("android.lens.info.focusDistanceCalibration", int.class);
+
+    /**
+     * <p>Direction the camera faces relative to
+     * device screen</p>
      * @see #LENS_FACING_FRONT
      * @see #LENS_FACING_BACK
      */
@@ -333,292 +427,806 @@
             new Key<Integer>("android.lens.facing", int.class);
 
     /**
-     * <p>
-     * If set to 1, the HAL will always split result
+     * <p>The set of noise reduction modes supported by this camera device.</p>
+     * <p>This tag lists the valid modes for {@link CaptureRequest#NOISE_REDUCTION_MODE android.noiseReduction.mode}.</p>
+     * <p>Full-capability camera devices must laways support OFF and FAST.</p>
+     *
+     * @see CaptureRequest#NOISE_REDUCTION_MODE
+     */
+    public static final Key<byte[]> NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES =
+            new Key<byte[]>("android.noiseReduction.availableNoiseReductionModes", byte[].class);
+
+    /**
+     * <p>If set to 1, the HAL will always split result
      * metadata for a single capture into multiple buffers,
-     * returned using multiple process_capture_result calls.
-     * </p>
-     * <p>
-     * Does not need to be listed in static
+     * returned using multiple process_capture_result calls.</p>
+     * <p>Does not need to be listed in static
      * metadata. Support for partial results will be reworked in
      * future versions of camera service. This quirk will stop
      * working at that point; DO NOT USE without careful
-     * consideration of future support.
-     * </p>
-     *
-     * <b>Optional</b> - This value may be null on some devices.
-     *
+     * consideration of future support.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      * @hide
      */
     public static final Key<Byte> QUIRKS_USE_PARTIAL_RESULT =
             new Key<Byte>("android.quirks.usePartialResult", byte.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>
+     * <p>The maximum numbers of different types of output streams
+     * that can be configured and used simultaneously by a camera device.</p>
+     * <p>This is a 3 element tuple that contains the max number of output simultaneous
+     * streams for raw sensor, processed (and uncompressed), and JPEG formats respectively.
+     * For example, if max raw sensor format output stream number is 1, max YUV streams
+     * number is 3, and max JPEG stream number is 2, then this tuple should be <code>(1, 3, 2)</code>.</p>
+     * <p>This lists the upper bound of the number of output streams supported by
+     * the camera device. Using more streams simultaneously may require more hardware and
+     * CPU resources that will consume more power. The image format for a output stream can
+     * be any supported format provided by {@link CameraCharacteristics#SCALER_AVAILABLE_FORMATS android.scaler.availableFormats}. The formats
+     * defined in {@link CameraCharacteristics#SCALER_AVAILABLE_FORMATS android.scaler.availableFormats} can be catergorized into the 3 stream types
+     * as below:</p>
+     * <ul>
+     * <li>JPEG-compressed format: BLOB.</li>
+     * <li>Raw formats: RAW_SENSOR and RAW_OPAQUE.</li>
+     * <li>processed, uncompressed formats: YCbCr_420_888, YCrCb_420_SP, YV12.</li>
+     * </ul>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_FORMATS
      */
     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>
+     * <p>The maximum numbers of any type of input streams
+     * that can be configured and used simultaneously by a camera device.</p>
+     * <p>When set to 0, it means no input stream is supported.</p>
+     * <p>The image format for a input stream can be any supported
+     * format provided by
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP android.scaler.availableInputOutputFormatsMap}. When using an
+     * input stream, there must be at least one output stream
+     * configured to to receive the reprocessed images.</p>
+     * <p>For example, for Zero Shutter Lag (ZSL) still capture use case, the input
+     * stream image format will be RAW_OPAQUE, the associated output stream image format
+     * should be JPEG.</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP
+     */
+    public static final Key<Integer> REQUEST_MAX_NUM_INPUT_STREAMS =
+            new Key<Integer>("android.request.maxNumInputStreams", int.class);
+
+    /**
+     * <p>Specifies the number of maximum pipeline stages a frame
+     * has to go through from when it's exposed to when it's available
+     * to the framework.</p>
+     * <p>A typical minimum value for this is 2 (one stage to expose,
+     * one stage to readout) from the sensor. The ISP then usually adds
+     * its own stages to do custom HW processing. Further stages may be
+     * added by SW processing.</p>
+     * <p>Depending on what settings are used (e.g. YUV, JPEG) and what
+     * processing is enabled (e.g. face detection), the actual pipeline
+     * depth (specified by {@link CaptureResult#REQUEST_PIPELINE_DEPTH android.request.pipelineDepth}) may be less than
+     * the max pipeline depth.</p>
+     * <p>A pipeline depth of X stages is equivalent to a pipeline latency of
+     * X frame intervals.</p>
+     * <p>This value will be 8 or less.</p>
+     *
+     * @see CaptureResult#REQUEST_PIPELINE_DEPTH
+     */
+    public static final Key<Byte> REQUEST_PIPELINE_MAX_DEPTH =
+            new Key<Byte>("android.request.pipelineMaxDepth", byte.class);
+
+    /**
+     * <p>Optional. Defaults to 1. Defines how many sub-components
+     * a result will be composed of.</p>
+     * <p>In order to combat the pipeline latency, partial results
+     * may be delivered to the application layer from the camera device as
+     * soon as they are available.</p>
+     * <p>A value of 1 means that partial results are not supported.</p>
+     * <p>A typical use case for this might be: after requesting an AF lock the
+     * new AF state might be available 50% of the way through the pipeline.
+     * The camera device could then immediately dispatch this state via a
+     * partial result to the framework/application layer, and the rest of
+     * the metadata via later partial results.</p>
+     */
+    public static final Key<Integer> REQUEST_PARTIAL_RESULT_COUNT =
+            new Key<Integer>("android.request.partialResultCount", int.class);
+
+    /**
+     * <p>List of capabilities that the camera device
+     * advertises as fully supporting.</p>
+     * <p>A capability is a contract that the camera device makes in order
+     * to be able to satisfy one or more use cases.</p>
+     * <p>Listing a capability guarantees that the whole set of features
+     * required to support a common use will all be available.</p>
+     * <p>Using a subset of the functionality provided by an unsupported
+     * capability may be possible on a specific camera device implementation;
+     * to do this query each of android.request.availableRequestKeys,
+     * android.request.availableResultKeys,
+     * android.request.availableCharacteristicsKeys.</p>
+     * <p>XX: Maybe these should go into {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}
+     * as a table instead?</p>
+     * <p>The following capabilities are guaranteed to be available on
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} <code>==</code> FULL devices:</p>
+     * <ul>
+     * <li>MANUAL_SENSOR</li>
+     * <li>ZSL</li>
+     * </ul>
+     * <p>Other capabilities may be available on either FULL or LIMITED
+     * devices, but the app. should query this field to be sure.</p>
+     *
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_OPTIONAL
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_GCAM
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_ZSL
+     * @see #REQUEST_AVAILABLE_CAPABILITIES_DNG
+     */
+    public static final Key<Integer> REQUEST_AVAILABLE_CAPABILITIES =
+            new Key<Integer>("android.request.availableCapabilities", int.class);
+
+    /**
+     * <p>A list of all keys that the camera device has available
+     * to use with CaptureRequest.</p>
+     * <p>Attempting to set a key into a CaptureRequest that is not
+     * listed here will result in an invalid request and will be rejected
+     * by the camera device.</p>
+     * <p>This field can be used to query the feature set of a camera device
+     * at a more granular level than capabilities. This is especially
+     * important for optional keys that are not listed under any capability
+     * in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
+     * <p>TODO: This should be used by #getAvailableCaptureRequestKeys.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @hide
+     */
+    public static final Key<int[]> REQUEST_AVAILABLE_REQUEST_KEYS =
+            new Key<int[]>("android.request.availableRequestKeys", int[].class);
+
+    /**
+     * <p>A list of all keys that the camera device has available
+     * to use with CaptureResult.</p>
+     * <p>Attempting to get a key from a CaptureResult that is not
+     * listed here will always return a <code>null</code> value. Getting a key from
+     * a CaptureResult that is listed here must never return a <code>null</code>
+     * value.</p>
+     * <p>The following keys may return <code>null</code> unless they are enabled:</p>
+     * <ul>
+     * <li>{@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} (non-null iff {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} == ON)</li>
+     * </ul>
+     * <p>(Those sometimes-null keys should nevertheless be listed here
+     * if they are available.)</p>
+     * <p>This field can be used to query the feature set of a camera device
+     * at a more granular level than capabilities. This is especially
+     * important for optional keys that are not listed under any capability
+     * in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
+     * <p>TODO: This should be used by #getAvailableCaptureResultKeys.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
+     * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+     * @hide
+     */
+    public static final Key<int[]> REQUEST_AVAILABLE_RESULT_KEYS =
+            new Key<int[]>("android.request.availableResultKeys", int[].class);
+
+    /**
+     * <p>A list of all keys that the camera device has available
+     * to use with CameraCharacteristics.</p>
+     * <p>This entry follows the same rules as
+     * android.request.availableResultKeys (except that it applies for
+     * CameraCharacteristics instead of CaptureResult). See above for more
+     * details.</p>
+     * <p>TODO: This should be used by CameraCharacteristics#getKeys.</p>
+     * @hide
+     */
+    public static final Key<int[]> REQUEST_AVAILABLE_CHARACTERISTICS_KEYS =
+            new Key<int[]>("android.request.availableCharacteristicsKeys", int[].class);
+
+    /**
+     * <p>The list of image formats that are supported by this
+     * camera device for output streams.</p>
+     * <p>All camera devices will support JPEG and YUV_420_888 formats.</p>
+     * <p>When set to YUV_420_888, application can access the YUV420 data directly.</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>
+     * <p>The minimum frame duration that is supported
+     * for each resolution in {@link CameraCharacteristics#SCALER_AVAILABLE_JPEG_SIZES android.scaler.availableJpegSizes}.</p>
+     * <p>This corresponds to the minimum steady-state frame duration when only
+     * that JPEG stream is active and captured in a burst, with all
+     * processing (typically in android.*.mode) set to FAST.</p>
+     * <p>When multiple streams are configured, the minimum
+     * frame duration will be &gt;= max(individual stream min
+     * durations)</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_JPEG_SIZES
      */
     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>
+     * <p>The JPEG resolutions that are supported by this camera device.</p>
+     * <p>The resolutions are listed as <code>(width, height)</code> pairs. All camera devices will support
+     * sensor maximum resolution (defined by {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}).</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     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
+     * <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>
+     * 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>
+     * <p>For each available processed output size (defined in
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_PROCESSED_SIZES android.scaler.availableProcessedSizes}), this property lists the
+     * minimum supportable frame duration for that size.</p>
+     * <p>This should correspond to the frame duration when only that processed
+     * stream is active, with all processing (typically in android.*.mode)
+     * set to FAST.</p>
+     * <p>When multiple streams are configured, the minimum frame duration will
+     * be &gt;= max(individual stream min durations).</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_PROCESSED_SIZES
      */
     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
+     * <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>
-     * <p>
-     * The actual supported resolution list may be limited by
-     * consumer end points for different use cases. For example, for
-     * recording use case, the largest supported resolution may be
-     * limited by max supported size from encoder, for preview use
-     * case, the largest supported resolution may be limited by max
-     * resolution SurfaceTexture/SurfaceView can support.
-     * </p>
+     * encoders.</p>
+     * <p>The resolutions are listed as <code>(width, height)</code> pairs.</p>
+     * <p>For a given use case, the actual maximum supported resolution
+     * may be lower than what is listed here, depending on the destination
+     * Surface for the image data. For example, for recording video,
+     * the video encoder chosen may have a maximum size limit (e.g. 1080p)
+     * smaller than what the camera (e.g. maximum resolution is 3264x2448)
+     * can provide.</p>
+     * <p>Please reference the documentation for the image data destination to
+     * check if it limits the maximum size for image data.</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>
+     * <p>The mapping of image formats that are supported by this
+     * camera device for input streams, to their corresponding output formats.</p>
+     * <p>All camera devices with at least 1
+     * {@link CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS android.request.maxNumInputStreams} will have at least one
+     * available input format.</p>
+     * <p>The camera device will support the following map of formats,
+     * if its dependent capability is supported:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="left">Input Format</th>
+     * <th align="left">Output Format</th>
+     * <th align="left">Capability</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="left">RAW_OPAQUE</td>
+     * <td align="left">JPEG</td>
+     * <td align="left">ZSL</td>
+     * </tr>
+     * <tr>
+     * <td align="left">RAW_OPAQUE</td>
+     * <td align="left">YUV_420_888</td>
+     * <td align="left">ZSL</td>
+     * </tr>
+     * <tr>
+     * <td align="left">RAW_OPAQUE</td>
+     * <td align="left">RAW16</td>
+     * <td align="left">DNG</td>
+     * </tr>
+     * <tr>
+     * <td align="left">RAW16</td>
+     * <td align="left">YUV_420_888</td>
+     * <td align="left">DNG</td>
+     * </tr>
+     * <tr>
+     * <td align="left">RAW16</td>
+     * <td align="left">JPEG</td>
+     * <td align="left">DNG</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>For ZSL-capable camera devices, using the RAW_OPAQUE format
+     * as either input or output will never hurt maximum frame rate (i.e.
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS android.scaler.availableStallDurations} will not have RAW_OPAQUE).</p>
+     * <p>Attempting to configure an input stream with output streams not
+     * listed as available in this map is not valid.</p>
+     * <p>TODO: Add java type mapping for this property.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_MAX_NUM_INPUT_STREAMS
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS
+     */
+    public static final Key<int[]> SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP =
+            new Key<int[]>("android.scaler.availableInputOutputFormatsMap", int[].class);
+
+    /**
+     * <p>The available stream configurations that this
+     * camera device supports
+     * (i.e. format, width, height, output/input stream).</p>
+     * <p>The configurations are listed as <code>(format, width, height, input?)</code>
+     * tuples.</p>
+     * <p>All camera devices will support sensor maximum resolution (defined by
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}) for the JPEG format.</p>
+     * <p>For a given use case, the actual maximum supported resolution
+     * may be lower than what is listed here, depending on the destination
+     * Surface for the image data. For example, for recording video,
+     * the video encoder chosen may have a maximum size limit (e.g. 1080p)
+     * smaller than what the camera (e.g. maximum resolution is 3264x2448)
+     * can provide.</p>
+     * <p>Please reference the documentation for the image data destination to
+     * check if it limits the maximum size for image data.</p>
+     * <p>Not all output formats may be supported in a configuration with
+     * an input stream of a particular format. For more details, see
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP android.scaler.availableInputOutputFormatsMap}.</p>
+     * <p>The following table describes the minimum required output stream
+     * configurations based on the hardware level
+     * ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel}):</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">Format</th>
+     * <th align="center">Size</th>
+     * <th align="center">Hardware Level</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">{@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}</td>
+     * <td align="center">Any</td>
+     * <td align="center"></td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">1920x1080 (1080p)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 1080p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">1280x720 (720)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 720p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">640x480 (480p)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 480p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">JPEG</td>
+     * <td align="center">320x240 (240p)</td>
+     * <td align="center">Any</td>
+     * <td align="center">if 240p &lt;= activeArraySize</td>
+     * </tr>
+     * <tr>
+     * <td align="center">YUV_420_888</td>
+     * <td align="center">all output sizes available for JPEG</td>
+     * <td align="center">FULL</td>
+     * <td align="center"></td>
+     * </tr>
+     * <tr>
+     * <td align="center">YUV_420_888</td>
+     * <td align="center">all output sizes available for JPEG, up to the maximum video size</td>
+     * <td align="center">LIMITED</td>
+     * <td align="center"></td>
+     * </tr>
+     * <tr>
+     * <td align="center">IMPLEMENTATION_DEFINED</td>
+     * <td align="center">same as YUV_420_888</td>
+     * <td align="center">Any</td>
+     * <td align="center"></td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>Refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities} for additional
+     * mandatory stream configurations on a per-capability basis.</p>
+     *
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @see CameraCharacteristics#SCALER_AVAILABLE_INPUT_OUTPUT_FORMATS_MAP
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see #SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT
+     * @see #SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT
+     */
+    public static final Key<int[]> SCALER_AVAILABLE_STREAM_CONFIGURATIONS =
+            new Key<int[]>("android.scaler.availableStreamConfigurations", int[].class);
+
+    /**
+     * <p>This lists the minimum frame duration for each
+     * format/size combination.</p>
+     * <p>This should correspond to the frame duration when only that
+     * stream is active, with all processing (typically in android.*.mode)
+     * set to either OFF or FAST.</p>
+     * <p>When multiple streams are used in a request, the minimum frame
+     * duration will be max(individual stream min durations).</p>
+     * <p>The minimum frame duration of a stream (of a particular format, size)
+     * is the same regardless of whether the stream is input or output.</p>
+     * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} and
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS android.scaler.availableStallDurations} for more details about
+     * calculating the max frame rate.</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     */
+    public static final Key<long[]> SCALER_AVAILABLE_MIN_FRAME_DURATIONS =
+            new Key<long[]>("android.scaler.availableMinFrameDurations", long[].class);
+
+    /**
+     * <p>This lists the maximum stall duration for each
+     * format/size combination.</p>
+     * <p>A stall duration is how much extra time would get added
+     * to the normal minimum frame duration for a repeating request
+     * that has streams with non-zero stall.</p>
+     * <p>For example, consider JPEG captures which have the following
+     * characteristics:</p>
+     * <ul>
+     * <li>JPEG streams act like processed YUV streams in requests for which
+     * they are not included; in requests in which they are directly
+     * referenced, they act as JPEG streams. This is because supporting a
+     * JPEG stream requires the underlying YUV data to always be ready for
+     * use by a JPEG encoder, but the encoder will only be used (and impact
+     * frame duration) on requests that actually reference a JPEG stream.</li>
+     * <li>The JPEG processor can run concurrently to the rest of the camera
+     * pipeline, but cannot process more than 1 capture at a time.</li>
+     * </ul>
+     * <p>In other words, using a repeating YUV request would result
+     * in a steady frame rate (let's say it's 30 FPS). If a single
+     * JPEG request is submitted periodically, the frame rate will stay
+     * at 30 FPS (as long as we wait for the previous JPEG to return each
+     * time). If we try to submit a repeating YUV + JPEG request, then
+     * the frame rate will drop from 30 FPS.</p>
+     * <p>In general, submitting a new request with a non-0 stall time
+     * stream will <em>not</em> cause a frame rate drop unless there are still
+     * outstanding buffers for that stream from previous requests.</p>
+     * <p>Submitting a repeating request with streams (call this <code>S</code>)
+     * is the same as setting the minimum frame duration from
+     * the normal minimum frame duration corresponding to <code>S</code>, added with
+     * the maximum stall duration for <code>S</code>.</p>
+     * <p>If interleaving requests with and without a stall duration,
+     * a request will stall by the maximum of the remaining times
+     * for each can-stall stream with outstanding buffers.</p>
+     * <p>This means that a stalling request will not have an exposure start
+     * until the stall has completed.</p>
+     * <p>This should correspond to the stall duration when only that stream is
+     * active, with all processing (typically in android.*.mode) set to FAST
+     * or OFF. Setting any of the processing modes to HIGH_QUALITY
+     * effectively results in an indeterminate stall duration for all
+     * streams in a request (the regular stall calculation rules are
+     * ignored).</p>
+     * <p>The following formats may always have a stall duration:</p>
+     * <ul>
+     * <li>JPEG</li>
+     * <li>RAW16</li>
+     * </ul>
+     * <p>The following formats will never have a stall duration:</p>
+     * <ul>
+     * <li>YUV_420_888</li>
+     * <li>IMPLEMENTATION_DEFINED</li>
+     * </ul>
+     * <p>All other formats may or may not have an allowed stall duration on
+     * a per-capability basis; refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
+     * for more details.</p>
+     * <p>See {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} for more information about
+     * calculating the max frame rate (absent stalls).</p>
+     *
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     */
+    public static final Key<long[]> SCALER_AVAILABLE_STALL_DURATIONS =
+            new Key<long[]>("android.scaler.availableStallDurations", long[].class);
+
+    /**
+     * <p>Area of raw data which corresponds to only
+     * active pixels.</p>
+     * <p>It is smaller or equal to
+     * sensor full pixel array, which could include the black calibration pixels.</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>
+     * <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>
+     * <p>Range of valid exposure
+     * times used by {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}.</p>
+     *
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      */
     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>
+     * <p>Maximum possible frame duration (minimum frame
+     * rate).</p>
+     * <p>The largest possible {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration}
+     * that will be accepted by the camera device. Attempting to use
+     * frame durations beyond the maximum will result in the frame duration
+     * being clipped to the maximum. See that control
+     * for a full definition of frame durations.</p>
+     * <p>Refer to
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS android.scaler.availableProcessedMinDurations},
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_JPEG_MIN_DURATIONS android.scaler.availableJpegMinDurations}, and
+     * android.scaler.availableRawMinDurations for the minimum
+     * frame duration values.</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_JPEG_MIN_DURATIONS
+     * @see CameraCharacteristics#SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
      */
     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>
+     * <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>
+     * <p>Dimensions of full pixel array, possibly
+     * including black calibration pixels.</p>
+     * <p>Maximum output resolution for raw format must
+     * match this in
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS android.scaler.availableStreamConfigurations}.</p>
      *
-     * <b>Optional</b> - This value may be null on some devices.
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+     */
+    public static final Key<android.hardware.camera2.Size> SENSOR_INFO_PIXEL_ARRAY_SIZE =
+            new Key<android.hardware.camera2.Size>("android.sensor.info.pixelArraySize", android.hardware.camera2.Size.class);
+
+    /**
+     * <p>Maximum raw value output by sensor.</p>
+     * <p>This specifies the fully-saturated encoding level for the raw
+     * sample values from the sensor.  This is typically caused by the
+     * sensor becoming highly non-linear or clipping. The minimum for
+     * each channel is specified by the offset in the
+     * {@link CameraCharacteristics#SENSOR_BLACK_LEVEL_PATTERN android.sensor.blackLevelPattern} tag.</p>
+     * <p>The white level is typically determined either by sensor bit depth
+     * (10-14 bits is expected), or by the point where the sensor response
+     * becomes too non-linear to be useful.  The default value for this is
+     * maximum representable value for a 16-bit raw sample (2^16 - 1).</p>
      *
-     * <b>{@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL}</b> -
-     * Present on all devices that report being FULL level hardware devices in the
-     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL HARDWARE_LEVEL} key.
+     * @see CameraCharacteristics#SENSOR_BLACK_LEVEL_PATTERN
+     */
+    public static final Key<Integer> SENSOR_INFO_WHITE_LEVEL =
+            new Key<Integer>("android.sensor.info.whiteLevel", int.class);
+
+    /**
+     * <p>Gain factor from electrons to raw units when
+     * ISO=100</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * <p><b>Full capability</b> -
+     * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
+     *
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     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
+     * <p>A fixed black level offset for each of the color filter arrangement
+     * (CFA) mosaic channels.</p>
+     * <p>This tag specifies the zero light value for each of the CFA mosaic
+     * channels in the camera sensor.  The maximal value output by the
+     * sensor is represented by the value in {@link CameraCharacteristics#SENSOR_INFO_WHITE_LEVEL android.sensor.info.whiteLevel}.</p>
+     * <p>The values are given in row-column scan order, with the first value
+     * corresponding to the element of the CFA in row=0, column=0.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_WHITE_LEVEL
+     */
+    public static final Key<int[]> SENSOR_BLACK_LEVEL_PATTERN =
+            new Key<int[]>("android.sensor.blackLevelPattern", int[].class);
+
+    /**
+     * <p>Maximum sensitivity that is implemented
+     * purely through analog gain.</p>
+     * <p>For {@link CaptureRequest#SENSOR_SENSITIVITY 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>
+     * values above this, the gain applied can be a mix of analog and
+     * digital.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * <p><b>Full capability</b> -
+     * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
      *
-     * <b>Optional</b> - This value may be null on some devices.
-     *
-     * <b>{@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL}</b> -
-     * Present on all devices that report being FULL level hardware devices in the
-     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL HARDWARE_LEVEL} key.
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      */
     public static final Key<Integer> SENSOR_MAX_ANALOG_SENSITIVITY =
             new Key<Integer>("android.sensor.maxAnalogSensitivity", int.class);
 
     /**
-     * <p>
-     * Clockwise angle through which the output
+     * <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>
+     * 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
+     * <p>The number of input samples for each dimension of
+     * {@link CaptureResult#SENSOR_PROFILE_HUE_SAT_MAP android.sensor.profileHueSatMap}.</p>
+     * <p>The number of input samples for the hue, saturation, and value
+     * dimension of {@link CaptureResult#SENSOR_PROFILE_HUE_SAT_MAP android.sensor.profileHueSatMap}. The order of the
+     * dimensions given is hue, saturation, value; where hue is the 0th
+     * element.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CaptureResult#SENSOR_PROFILE_HUE_SAT_MAP
+     */
+    public static final Key<int[]> SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS =
+            new Key<int[]>("android.sensor.profileHueSatMapDimensions", int[].class);
+
+    /**
+     * <p>Optional. Defaults to [OFF]. Lists the supported test
+     * pattern modes for {@link CaptureRequest#SENSOR_TEST_PATTERN_MODE android.sensor.testPatternMode}.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final Key<Byte> SENSOR_AVAILABLE_TEST_PATTERN_MODES =
+            new Key<Byte>("android.sensor.availableTestPatternModes", byte.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.faceScores outputs.</p>
+     * <p>FULL means the device additionally supports the
      * android.statistics.faceIds and
-     * android.statistics.faceLandmarks outputs.
-     * </p>
+     * 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>
+     * <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>
+     * <p>The set of hot pixel map output modes supported by this camera device.</p>
+     * <p>This tag lists valid output modes for {@link CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE android.statistics.hotPixelMapMode}.</p>
+     * <p>If no hotpixel map is available for this camera device, this will contain
+     * only OFF.  If the hotpixel map is available, this should include both
+     * the ON and OFF options.</p>
+     *
+     * @see CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE
+     */
+    public static final Key<boolean[]> STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES =
+            new Key<boolean[]>("android.statistics.info.availableHotPixelMapModes", boolean[].class);
+
+    /**
+     * <p>Maximum number of supported points in the
+     * tonemap curve that can be used for {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed}, or
+     * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}, or {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}.</p>
+     * <p>If the actual number of points provided by the application (in
+     * android.tonemap.curve*)  is less than max, the camera device will
+     * resample the curve to its internal representation, using linear
+     * interpolation.</p>
+     * <p>The output curves in the result metadata may have a different number
+     * of points than the input curves, and will represent the actual
+     * hardware curves used as closely as possible when linearly interpolated.</p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_BLUE
+     * @see CaptureRequest#TONEMAP_CURVE_GREEN
+     * @see CaptureRequest#TONEMAP_CURVE_RED
      */
     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
+     * <p>The set of tonemapping modes supported by this camera device.</p>
+     * <p>This tag lists the valid modes for {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode}.</p>
+     * <p>Full-capability camera devices must always support CONTRAST_CURVE and
+     * FAST.</p>
      *
+     * @see CaptureRequest#TONEMAP_MODE
+     */
+    public static final Key<byte[]> TONEMAP_AVAILABLE_TONE_MAP_MODES =
+            new Key<byte[]>("android.tonemap.availableToneMapModes", byte[].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>
+     * <p>Generally classifies the overall set of the camera device functionality.</p>
+     * <p>Camera devices will come in two flavors: LIMITED and FULL.</p>
+     * <p>A FULL device has the most support possible and will enable the
+     * widest range of use cases such as:</p>
+     * <ul>
+     * <li>30 FPS at maximum resolution (== sensor resolution)</li>
+     * <li>Per frame control</li>
+     * <li>Manual sensor control</li>
+     * <li>Zero Shutter Lag (ZSL)</li>
+     * </ul>
+     * <p>A LIMITED device may have some or none of the above characteristics.
+     * To find out more refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
      * @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);
 
+    /**
+     * <p>The maximum number of frames that can occur after a request
+     * (different than the previous) has been submitted, and before the
+     * result's state becomes synchronized (by setting
+     * android.sync.frameNumber to a non-negative value).</p>
+     * <p>This defines the maximum distance (in number of metadata results),
+     * between android.sync.frameNumber and the equivalent
+     * android.request.frameCount.</p>
+     * <p>In other words this acts as an upper boundary for how many frames
+     * must occur before the camera device knows for a fact that the new
+     * submitted camera settings have been applied in outgoing frames.</p>
+     * <p>For example if the distance was 2,</p>
+     * <pre><code>initial request = X (repeating)
+     * request1 = X
+     * request2 = Y
+     * request3 = Y
+     * request4 = Y
+     *
+     * where requestN has frameNumber N, and the first of the repeating
+     * initial request's has frameNumber F (and F &lt; 1).
+     *
+     * initial result = X' + { android.sync.frameNumber == F }
+     * result1 = X' + { android.sync.frameNumber == F }
+     * result2 = X' + { android.sync.frameNumber == CONVERGING }
+     * result3 = X' + { android.sync.frameNumber == CONVERGING }
+     * result4 = X' + { android.sync.frameNumber == 2 }
+     *
+     * where resultN has frameNumber N.
+     * </code></pre>
+     * <p>Since <code>result4</code> has a <code>frameNumber == 4</code> and
+     * <code>android.sync.frameNumber == 2</code>, the distance is clearly
+     * <code>4 - 2 = 2</code>.</p>
+     * @see #SYNC_MAX_LATENCY_PER_FRAME_CONTROL
+     * @see #SYNC_MAX_LATENCY_UNKNOWN
+     */
+    public static final Key<Integer> SYNC_MAX_LATENCY =
+            new Key<Integer>("android.sync.maxLatency", int.class);
+
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 9e8d7d1..2c53f03 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -92,7 +92,6 @@
      * AE/AWB/AF should be on auto mode.
      *
      * @see #createCaptureRequest
-     * @hide
      */
     public static final int TEMPLATE_ZERO_SHUTTER_LAG = 5;
 
@@ -105,7 +104,6 @@
      * application depending on the intended use case.
      *
      * @see #createCaptureRequest
-     * @hide
      */
     public static final int TEMPLATE_MANUAL = 6;
 
@@ -501,31 +499,6 @@
     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;
-
-    /**
      * Flush all captures currently pending and in-progress as fast as
      * possible.
      *
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 65b6c7a..0fcd598 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -19,7 +19,6 @@
 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;
@@ -49,6 +48,8 @@
  */
 public final class CameraManager {
 
+    private static final String TAG = "CameraManager";
+
     /**
      * This should match the ICameraService definition
      */
@@ -80,6 +81,14 @@
         mCameraService = CameraBinderDecorator.newInstance(cameraServiceRaw);
 
         try {
+            CameraBinderDecorator.throwOnError(
+                    CameraMetadataNative.nativeSetupGlobalVendorTagDescriptor());
+        } catch(CameraRuntimeException e) {
+            throw new IllegalStateException("Failed to setup camera vendor tags",
+                    e.asChecked());
+        }
+
+        try {
             mCameraService.addListener(new CameraServiceListener());
         } catch(CameraRuntimeException e) {
             throw new IllegalStateException("Failed to register a camera service listener",
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 1d6ff7d..a3fbfbe 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -168,7 +168,7 @@
 
             Key lhs = (Key) o;
 
-            return mName.equals(lhs.mName);
+            return mName.equals(lhs.mName) && mType.equals(lhs.mType);
         }
 
         /**
@@ -206,6 +206,45 @@
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
 
     //
+    // Enumeration values for CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+    //
+
+    /**
+     * <p>The lens focus distance is not accurate, and the units used for
+     * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} do not correspond to any physical units.
+     * Setting the lens to the same focus distance on separate occasions may
+     * result in a different real focus distance, depending on factors such
+     * as the orientation of the device, the age of the focusing mechanism,
+     * and the device temperature. The focus distance value will still be
+     * in the range of <code>[0, {@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance}]</code>, where 0
+     * represents the farthest focus.</p>
+     *
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
+     * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+     */
+    public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED = 0;
+
+    /**
+     * <p>The lens focus distance is measured in diopters. However, setting the lens
+     * to the same focus distance on separate occasions may result in a
+     * different real focus distance, depending on factors such as the
+     * orientation of the device, the age of the focusing mechanism, and
+     * the device temperature.</p>
+     * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+     */
+    public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_APPROXIMATE = 1;
+
+    /**
+     * <p>The lens focus distance is measured in diopters. The lens mechanism is
+     * calibrated so that setting the same focus distance is repeatable on
+     * multiple occasions with good accuracy, and the focus distance corresponds
+     * to the real physical distance to the plane of best focus.</p>
+     * @see CameraCharacteristics#LENS_INFO_FOCUS_DISTANCE_CALIBRATION
+     */
+    public static final int LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED = 2;
+
+    //
     // Enumeration values for CameraCharacteristics#LENS_FACING
     //
 
@@ -220,13 +259,177 @@
     public static final int LENS_FACING_BACK = 1;
 
     //
+    // Enumeration values for CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+    //
+
+    /**
+     * <p>The minimal set of capabilities that every camera
+     * device (regardless of {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel})
+     * will support.</p>
+     * <p>The full set of features supported by this capability makes
+     * the camera2 api backwards compatible with the camera1
+     * (android.hardware.Camera) API.</p>
+     * <p>TODO: @hide this. Doesn't really mean anything except
+     * act as a catch-all for all the 'base' functionality.</p>
+     *
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0;
+
+    /**
+     * <p>This is a catch-all capability to include all other
+     * tags or functionality not encapsulated by one of the other
+     * capabilities.</p>
+     * <p>A typical example is all tags marked 'optional'.</p>
+     * <p>TODO: @hide. We may not need this if we @hide all the optional
+     * tags not belonging to a capability.</p>
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_OPTIONAL = 1;
+
+    /**
+     * <p>The camera device can be manually controlled (3A algorithms such
+     * as auto exposure, and auto focus can be
+     * bypassed), this includes but is not limited to:</p>
+     * <ul>
+     * <li>Manual exposure control<ul>
+     * <li>{@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}</li>
+     * <li>{@link CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE android.sensor.info.exposureTimeRange}</li>
+     * </ul>
+     * </li>
+     * <li>Manual sensitivity control<ul>
+     * <li>{@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}</li>
+     * <li>{@link CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE android.sensor.info.sensitivityRange}</li>
+     * <li>{@link CameraCharacteristics#SENSOR_BASE_GAIN_FACTOR android.sensor.baseGainFactor}</li>
+     * </ul>
+     * </li>
+     * <li>Manual lens control<ul>
+     * <li>android.lens.*</li>
+     * </ul>
+     * </li>
+     * <li>Manual flash control<ul>
+     * <li>android.flash.*</li>
+     * </ul>
+     * </li>
+     * <li>Manual black level locking<ul>
+     * <li>{@link CaptureRequest#BLACK_LEVEL_LOCK android.blackLevel.lock}</li>
+     * </ul>
+     * </li>
+     * </ul>
+     * <p>If any of the above 3A algorithms are enabled, then the camera
+     * device will accurately report the values applied by 3A in the
+     * result.</p>
+     *
+     * @see CaptureRequest#BLACK_LEVEL_LOCK
+     * @see CameraCharacteristics#SENSOR_BASE_GAIN_FACTOR
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CameraCharacteristics#SENSOR_INFO_EXPOSURE_TIME_RANGE
+     * @see CameraCharacteristics#SENSOR_INFO_SENSITIVITY_RANGE
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 2;
+
+    /**
+     * <p>TODO: This should be @hide</p>
+     * <ul>
+     * <li>Manual tonemap control<ul>
+     * <li>{@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}</li>
+     * <li>{@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}</li>
+     * <li>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed}</li>
+     * <li>{@link CaptureRequest#TONEMAP_MODE android.tonemap.mode}</li>
+     * <li>{@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</li>
+     * </ul>
+     * </li>
+     * <li>Manual white balance control<ul>
+     * <li>{@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}</li>
+     * <li>{@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}</li>
+     * </ul>
+     * </li>
+     * <li>Lens shading map information<ul>
+     * <li>{@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap}</li>
+     * <li>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}</li>
+     * </ul>
+     * </li>
+     * </ul>
+     * <p>If auto white balance is enabled, then the camera device
+     * will accurately report the values applied by AWB in the result.</p>
+     * <p>The camera device will also support everything in MANUAL_SENSOR
+     * except manual lens control and manual flash control.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
+     * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
+     * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
+     * @see CaptureRequest#TONEMAP_CURVE_BLUE
+     * @see CaptureRequest#TONEMAP_CURVE_GREEN
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
+     * @see CaptureRequest#TONEMAP_MODE
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_GCAM = 3;
+
+    /**
+     * <p>The camera device supports the Zero Shutter Lag use case.</p>
+     * <ul>
+     * <li>At least one input stream can be used.</li>
+     * <li>RAW_OPAQUE is supported as an output/input format</li>
+     * <li>Using RAW_OPAQUE does not cause a frame rate drop
+     * relative to the sensor's maximum capture rate (at that
+     * resolution).</li>
+     * <li>RAW_OPAQUE will be reprocessable into both YUV_420_888
+     * and JPEG formats.</li>
+     * <li>The maximum available resolution for RAW_OPAQUE streams
+     * (both input/output) will match the maximum available
+     * resolution of JPEG streams.</li>
+     * </ul>
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_ZSL = 4;
+
+    /**
+     * <p>The camera device supports outputting RAW buffers that can be
+     * saved offline into a DNG format. It can reprocess DNG
+     * files (produced from the same camera device) back into YUV.</p>
+     * <ul>
+     * <li>At least one input stream can be used.</li>
+     * <li>RAW16 is supported as output/input format.</li>
+     * <li>RAW16 is reprocessable into both YUV_420_888 and JPEG
+     * formats.</li>
+     * <li>The maximum available resolution for RAW16 streams (both
+     * input/output) will match the value in
+     * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.</li>
+     * <li>All DNG-related optional metadata entries are provided
+     * by the camera device.</li>
+     * </ul>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public static final int REQUEST_AVAILABLE_CAPABILITIES_DNG = 5;
+
+    //
+    // Enumeration values for CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+    //
+
+    /**
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+     */
+    public static final int SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT = 0;
+
+    /**
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STREAM_CONFIGURATIONS
+     */
+    public static final int SCALER_AVAILABLE_STREAM_CONFIGURATIONS_INPUT = 1;
+
+    //
     // Enumeration values for CameraCharacteristics#LED_AVAILABLE_LEDS
     //
 
     /**
-     * <p>
-     * android.led.transmit control is used
-     * </p>
+     * <p>android.led.transmit control is used</p>
      * @see CameraCharacteristics#LED_AVAILABLE_LEDS
      * @hide
      */
@@ -247,32 +450,75 @@
     public static final int INFO_SUPPORTED_HARDWARE_LEVEL_FULL = 1;
 
     //
+    // Enumeration values for CameraCharacteristics#SYNC_MAX_LATENCY
+    //
+
+    /**
+     * <p>Every frame has the requests immediately applied.
+     * (and furthermore for all results,
+     * <code>android.sync.frameNumber == android.request.frameCount</code>)</p>
+     * <p>Changing controls over multiple requests one after another will
+     * produce results that have those controls applied atomically
+     * each frame.</p>
+     * <p>All FULL capability devices will have this as their maxLatency.</p>
+     * @see CameraCharacteristics#SYNC_MAX_LATENCY
+     */
+    public static final int SYNC_MAX_LATENCY_PER_FRAME_CONTROL = 0;
+
+    /**
+     * <p>Each new frame has some subset (potentially the entire set)
+     * of the past requests applied to the camera settings.</p>
+     * <p>By submitting a series of identical requests, the camera device
+     * will eventually have the camera settings applied, but it is
+     * unknown when that exact point will be.</p>
+     * @see CameraCharacteristics#SYNC_MAX_LATENCY
+     */
+    public static final int SYNC_MAX_LATENCY_UNKNOWN = -1;
+
+    //
     // Enumeration values for CaptureRequest#COLOR_CORRECTION_MODE
     //
 
     /**
-     * <p>
-     * Use the android.colorCorrection.transform matrix
-     * and android.colorCorrection.gains to do color conversion
-     * </p>
+     * <p>Use the {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform} matrix
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} to do color conversion.</p>
+     * <p>All advanced white balance adjustments (not specified
+     * by our white balance pipeline) must be disabled.</p>
+     * <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
+     * TRANSFORM_MATRIX is ignored. The camera device will override
+     * this value to either FAST or HIGH_QUALITY.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
+     * @see CaptureRequest#CONTROL_AWB_MODE
      * @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>
+     * <p>Must not slow down capture rate relative to sensor raw
+     * output.</p>
+     * <p>Advanced white balance adjustments above and beyond
+     * the specified white balance pipeline may be applied.</p>
+     * <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
+     * the camera device uses the last frame's AWB values
+     * (or defaults if AWB has never been run).</p>
+     *
+     * @see CaptureRequest#CONTROL_AWB_MODE
      * @see CaptureRequest#COLOR_CORRECTION_MODE
      */
     public static final int COLOR_CORRECTION_MODE_FAST = 1;
 
     /**
-     * <p>
-     * Frame rate may be reduced by high
-     * quality
-     * </p>
+     * <p>Capture rate (relative to sensor raw output)
+     * may be reduced by high quality.</p>
+     * <p>Advanced white balance adjustments above and beyond
+     * the specified white balance pipeline may be applied.</p>
+     * <p>If AWB is enabled with <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != OFF</code>, then
+     * the camera device uses the last frame's AWB values
+     * (or defaults if AWB has never been run).</p>
+     *
+     * @see CaptureRequest#CONTROL_AWB_MODE
      * @see CaptureRequest#COLOR_CORRECTION_MODE
      */
     public static final int COLOR_CORRECTION_MODE_HIGH_QUALITY = 2;
@@ -282,21 +528,31 @@
     //
 
     /**
+     * <p>The camera device will not adjust exposure duration to
+     * avoid banding problems.</p>
      * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
      */
     public static final int CONTROL_AE_ANTIBANDING_MODE_OFF = 0;
 
     /**
+     * <p>The camera device will adjust exposure duration to
+     * avoid banding problems with 50Hz illumination sources.</p>
      * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
      */
     public static final int CONTROL_AE_ANTIBANDING_MODE_50HZ = 1;
 
     /**
+     * <p>The camera device will adjust exposure duration to
+     * avoid banding problems with 60Hz illumination
+     * sources.</p>
      * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
      */
     public static final int CONTROL_AE_ANTIBANDING_MODE_60HZ = 2;
 
     /**
+     * <p>The camera device will automatically adapt its
+     * antibanding routine to the current illumination
+     * conditions. This is the default.</p>
      * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
      */
     public static final int CONTROL_AE_ANTIBANDING_MODE_AUTO = 3;
@@ -306,52 +562,73 @@
     //
 
     /**
-     * <p>
-     * Autoexposure is disabled; sensor.exposureTime,
-     * sensor.sensitivity and sensor.frameDuration are used
-     * </p>
+     * <p>The camera device's autoexposure routine is disabled;
+     * the application-selected {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity} and
+     * {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} are used by the camera
+     * device, along with android.flash.* fields, if there's
+     * a flash unit for this camera device.</p>
+     *
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see CaptureRequest#CONTROL_AE_MODE
      */
     public static final int CONTROL_AE_MODE_OFF = 0;
 
     /**
-     * <p>
-     * Autoexposure is active, no flash
-     * control
-     * </p>
+     * <p>The camera device's autoexposure routine is active,
+     * with no flash control. The application's values for
+     * {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and
+     * {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration} are ignored. The
+     * application has control over the various
+     * android.flash.* fields.</p>
+     *
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      * @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>
+     * <p>Like ON, except that the camera device also controls
+     * the camera's flash unit, firing it in low-light
+     * conditions. The flash may be fired during a
+     * precapture sequence (triggered by
+     * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and may be fired
+     * for captures for which the
+     * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
+     * STILL_CAPTURE</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      * @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>
+     * <p>Like ON, except that the camera device also controls
+     * the camera's flash unit, always firing it for still
+     * captures. The flash may be fired during a precapture
+     * sequence (triggered by
+     * {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}) and will always
+     * be fired for captures for which the
+     * {@link CaptureRequest#CONTROL_CAPTURE_INTENT android.control.captureIntent} field is set to
+     * STILL_CAPTURE</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      * @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>
+     * <p>Like ON_AUTO_FLASH, but with automatic red eye
+     * reduction. If deemed necessary by the camera device,
+     * a red eye reduction flash will fire during the
+     * precapture sequence.</p>
      * @see CaptureRequest#CONTROL_AE_MODE
      */
     public static final int CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE = 4;
@@ -361,20 +638,15 @@
     //
 
     /**
-     * <p>
-     * The trigger is idle.
-     * </p>
+     * <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>
+     * <p>The precapture metering sequence will be started
+     * by the camera device. 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;
@@ -384,55 +656,47 @@
     //
 
     /**
-     * <p>
-     * The 3A routines do not control the lens;
-     * android.lens.focusDistance is controlled by the
-     * application
-     * </p>
+     * <p>The auto-focus routine does not control the lens;
+     * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} is controlled by the
+     * application</p>
+     *
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
      * @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
+     * <p>If lens is not fixed focus.</p>
+     * <p>Use {@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.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>
+     * the outcome of the scan (FOCUSED or NOT_FOCUSED).</p>
+     * <p>Triggering AF_CANCEL resets the lens position to default,
+     * and sets the AF state to INACTIVE.</p>
+     *
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @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
+     * <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>
+     * 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
+     * <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
+     * 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,
@@ -440,25 +704,21 @@
      * 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
+     * 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>
+     * 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
+     * <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
+     * 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
@@ -467,22 +727,18 @@
      * 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
+     * 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>
+     * 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
+     * <p>Extended depth of field (digital focus). AF
      * trigger is ignored, AF state should always be
-     * INACTIVE.
-     * </p>
+     * INACTIVE.</p>
      * @see CaptureRequest#CONTROL_AF_MODE
      */
     public static final int CONTROL_AF_MODE_EDOF = 5;
@@ -492,26 +748,20 @@
     //
 
     /**
-     * <p>
-     * The trigger is idle.
-     * </p>
+     * <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>
+     * <p>Autofocus will 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>
+     * <p>Autofocus will return to its initial
+     * state, and cancel any currently active trigger.</p>
      * @see CaptureRequest#CONTROL_AF_TRIGGER
      */
     public static final int CONTROL_AF_TRIGGER_CANCEL = 2;
@@ -521,46 +771,89 @@
     //
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the application-selected color transform matrix
+     * ({@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}) and gains
+     * ({@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}) are used by the camera
+     * device for manual white balance control.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_OFF = 0;
 
     /**
+     * <p>The camera device's auto white balance routine is active;
+     * the application's values for {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}
+     * and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} are ignored.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_AUTO = 1;
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the camera device uses incandescent light as the assumed scene
+     * illumination for white balance. While the exact white balance
+     * transforms are up to the camera device, they will approximately
+     * match the CIE standard illuminant A.</p>
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_INCANDESCENT = 2;
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the camera device uses fluorescent light as the assumed scene
+     * illumination for white balance. While the exact white balance
+     * transforms are up to the camera device, they will approximately
+     * match the CIE standard illuminant F2.</p>
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_FLUORESCENT = 3;
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the camera device uses warm fluorescent light as the assumed scene
+     * illumination for white balance. While the exact white balance
+     * transforms are up to the camera device, they will approximately
+     * match the CIE standard illuminant F4.</p>
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_WARM_FLUORESCENT = 4;
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the camera device uses daylight light as the assumed scene
+     * illumination for white balance. While the exact white balance
+     * transforms are up to the camera device, they will approximately
+     * match the CIE standard illuminant D65.</p>
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_DAYLIGHT = 5;
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the camera device uses cloudy daylight light as the assumed scene
+     * illumination for white balance.</p>
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_CLOUDY_DAYLIGHT = 6;
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the camera device uses twilight light as the assumed scene
+     * illumination for white balance.</p>
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_TWILIGHT = 7;
 
     /**
+     * <p>The camera device's auto white balance routine is disabled;
+     * the camera device uses shade light as the assumed scene
+     * illumination for white balance.</p>
      * @see CaptureRequest#CONTROL_AWB_MODE
      */
     public static final int CONTROL_AWB_MODE_SHADE = 8;
@@ -570,59 +863,47 @@
     //
 
     /**
-     * <p>
-     * This request doesn't fall into the other
+     * <p>This request doesn't fall into the other
      * categories. Default to preview-like
-     * behavior.
-     * </p>
+     * 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
+     * <p>This request is for a preview-like usecase. The
      * precapture trigger may be used to start off a metering
-     * w/flash sequence
-     * </p>
+     * 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>
+     * <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>
+     * <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>
+     * <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
+     * <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>
+     * capture</p>
      * @see CaptureRequest#CONTROL_CAPTURE_INTENT
      */
     public static final int CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG = 5;
@@ -632,46 +913,64 @@
     //
 
     /**
+     * <p>No color effect will be applied.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_OFF = 0;
 
     /**
+     * <p>A "monocolor" effect where the image is mapped into
+     * a single color.  This will typically be grayscale.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_MONO = 1;
 
     /**
+     * <p>A "photo-negative" effect where the image's colors
+     * are inverted.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_NEGATIVE = 2;
 
     /**
+     * <p>A "solarisation" effect (Sabattier effect) where the
+     * image is wholly or partially reversed in
+     * tone.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_SOLARIZE = 3;
 
     /**
+     * <p>A "sepia" effect where the image is mapped into warm
+     * gray, red, and brown tones.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_SEPIA = 4;
 
     /**
+     * <p>A "posterization" effect where the image uses
+     * discrete regions of tone rather than a continuous
+     * gradient of tones.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_POSTERIZE = 5;
 
     /**
+     * <p>A "whiteboard" effect where the image is typically displayed
+     * as regions of white, with black or grey details.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_WHITEBOARD = 6;
 
     /**
+     * <p>A "blackboard" effect where the image is typically displayed
+     * as regions of black, with white or grey details.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_BLACKBOARD = 7;
 
     /**
+     * <p>An "aqua" effect where a blue hue is added to the image.</p>
      * @see CaptureRequest#CONTROL_EFFECT_MODE
      */
     public static final int CONTROL_EFFECT_MODE_AQUA = 8;
@@ -681,137 +980,166 @@
     //
 
     /**
-     * <p>
-     * Full application control of pipeline. All 3A
+     * <p>Full application control of pipeline. All 3A
      * routines are disabled, no other settings in
-     * android.control.* have any effect
-     * </p>
+     * 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.
+     * <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>
+     * effect</p>
      * @see CaptureRequest#CONTROL_MODE
      */
     public static final int CONTROL_MODE_AUTO = 1;
 
     /**
-     * <p>
-     * Use specific scene mode. Enabling this disables
+     * <p>Use specific scene mode. Enabling this disables
      * control.aeMode, control.awbMode and control.afMode
-     * controls; the HAL must ignore those settings while
+     * controls; the camera device will 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>
+     * UNSUPPORTED</p>
      * @see CaptureRequest#CONTROL_MODE
      */
     public static final int CONTROL_MODE_USE_SCENE_MODE = 2;
 
+    /**
+     * <p>Same as OFF mode, except that this capture will not be
+     * used by camera device background auto-exposure, auto-white balance and
+     * auto-focus algorithms to update their statistics.</p>
+     * @see CaptureRequest#CONTROL_MODE
+     */
+    public static final int CONTROL_MODE_OFF_KEEP_STATE = 3;
+
     //
     // Enumeration values for CaptureRequest#CONTROL_SCENE_MODE
     //
 
     /**
+     * <p>Indicates that no scene modes are set for a given capture request.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
-    public static final int CONTROL_SCENE_MODE_UNSUPPORTED = 0;
+    public static final int CONTROL_SCENE_MODE_DISABLED = 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>
+     * <p>If face detection support exists, use face
+     * detection data for auto-focus, auto-white balance, and
+     * auto-exposure routines. If face detection statistics are
+     * disabled (i.e. {@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} is set to OFF),
+     * this should still operate correctly (but will not return
+     * face detection statistics to the framework).</p>
+     * <p>Unlike the other scene modes, {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}
+     * remain active when FACE_PRIORITY is set.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1;
 
     /**
+     * <p>Optimized for photos of quickly moving objects.
+     * Similar to SPORTS.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_ACTION = 2;
 
     /**
+     * <p>Optimized for still photos of people.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_PORTRAIT = 3;
 
     /**
+     * <p>Optimized for photos of distant macroscopic objects.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4;
 
     /**
+     * <p>Optimized for low-light settings.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_NIGHT = 5;
 
     /**
+     * <p>Optimized for still photos of people in low-light
+     * settings.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6;
 
     /**
+     * <p>Optimized for dim, indoor settings where flash must
+     * remain off.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_THEATRE = 7;
 
     /**
+     * <p>Optimized for bright, outdoor beach settings.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_BEACH = 8;
 
     /**
+     * <p>Optimized for bright, outdoor settings containing snow.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_SNOW = 9;
 
     /**
+     * <p>Optimized for scenes of the setting sun.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_SUNSET = 10;
 
     /**
+     * <p>Optimized to avoid blurry photos due to small amounts of
+     * device motion (for example: due to hand shake).</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_STEADYPHOTO = 11;
 
     /**
+     * <p>Optimized for nighttime photos of fireworks.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_FIREWORKS = 12;
 
     /**
+     * <p>Optimized for photos of quickly moving people.
+     * Similar to ACTION.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_SPORTS = 13;
 
     /**
+     * <p>Optimized for dim, indoor settings with multiple moving
+     * people.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_PARTY = 14;
 
     /**
+     * <p>Optimized for dim settings where the main light source
+     * is a flame.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_CANDLELIGHT = 15;
 
     /**
+     * <p>Optimized for accurately capturing a photo of barcode
+     * for use by camera applications that wish to read the
+     * barcode value.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_BARCODE = 16;
@@ -821,27 +1149,21 @@
     //
 
     /**
-     * <p>
-     * No edge enhancement is applied
-     * </p>
+     * <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>
+     * <p>Must not slow down frame rate relative to sensor
+     * output</p>
      * @see CaptureRequest#EDGE_MODE
      */
     public static final int EDGE_MODE_FAST = 1;
 
     /**
-     * <p>
-     * Frame rate may be reduced by high
-     * quality
-     * </p>
+     * <p>Frame rate may be reduced by high
+     * quality</p>
      * @see CaptureRequest#EDGE_MODE
      */
     public static final int EDGE_MODE_HIGH_QUALITY = 2;
@@ -851,44 +1173,74 @@
     //
 
     /**
-     * <p>
-     * Do not fire the flash for this
-     * capture
-     * </p>
+     * <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>
+     * <p>If the flash is available and charged, fire flash
+     * for this capture based on android.flash.firingPower and
+     * android.flash.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>
+     * <p>Transition flash to continuously on.</p>
      * @see CaptureRequest#FLASH_MODE
      */
     public static final int FLASH_MODE_TORCH = 2;
 
     //
+    // Enumeration values for CaptureRequest#HOT_PIXEL_MODE
+    //
+
+    /**
+     * <p>The frame rate must not be reduced relative to sensor raw output
+     * for this option.</p>
+     * <p>No hot pixel correction is applied.
+     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+     * @see CaptureRequest#HOT_PIXEL_MODE
+     */
+    public static final int HOT_PIXEL_MODE_OFF = 0;
+
+    /**
+     * <p>The frame rate must not be reduced relative to sensor raw output
+     * for this option.</p>
+     * <p>Hot pixel correction is applied.
+     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+     * @see CaptureRequest#HOT_PIXEL_MODE
+     */
+    public static final int HOT_PIXEL_MODE_FAST = 1;
+
+    /**
+     * <p>The frame rate may be reduced relative to sensor raw output
+     * for this option.</p>
+     * <p>A high-quality hot pixel correction is applied.
+     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+     * @see CaptureRequest#HOT_PIXEL_MODE
+     */
+    public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2;
+
+    //
     // Enumeration values for CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
     //
 
     /**
+     * <p>Optical stabilization is unavailable.</p>
      * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
      */
     public static final int LENS_OPTICAL_STABILIZATION_MODE_OFF = 0;
 
     /**
+     * <p>Optical stabilization is enabled.</p>
      * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE
      */
     public static final int LENS_OPTICAL_STABILIZATION_MODE_ON = 1;
@@ -898,32 +1250,153 @@
     //
 
     /**
-     * <p>
-     * No noise reduction is applied
-     * </p>
+     * <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>
+     * <p>Must not slow down frame rate relative to sensor
+     * 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>
+     * <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#SENSOR_TEST_PATTERN_MODE
+    //
+
+    /**
+     * <p>Default. No test pattern mode is used, and the camera
+     * device returns captures from the image sensor.</p>
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final int SENSOR_TEST_PATTERN_MODE_OFF = 0;
+
+    /**
+     * <p>Each pixel in <code>[R, G_even, G_odd, B]</code> is replaced by its
+     * respective color channel provided in
+     * {@link CaptureRequest#SENSOR_TEST_PATTERN_DATA android.sensor.testPatternData}.</p>
+     * <p>For example:</p>
+     * <pre><code>android.testPatternData = [0, 0xFFFFFFFF, 0xFFFFFFFF, 0]
+     * </code></pre>
+     * <p>All green pixels are 100% green. All red/blue pixels are black.</p>
+     * <pre><code>android.testPatternData = [0xFFFFFFFF, 0, 0xFFFFFFFF, 0]
+     * </code></pre>
+     * <p>All red pixels are 100% red. Only the odd green pixels
+     * are 100% green. All blue pixels are 100% black.</p>
+     *
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_DATA
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final int SENSOR_TEST_PATTERN_MODE_SOLID_COLOR = 1;
+
+    /**
+     * <p>All pixel data is replaced with an 8-bar color pattern.</p>
+     * <p>The vertical bars (left-to-right) are as follows:</p>
+     * <ul>
+     * <li>100% white</li>
+     * <li>yellow</li>
+     * <li>cyan</li>
+     * <li>green</li>
+     * <li>magenta</li>
+     * <li>red</li>
+     * <li>blue</li>
+     * <li>black</li>
+     * </ul>
+     * <p>In general the image would look like the following:</p>
+     * <pre><code>W Y C G M R B K
+     * W Y C G M R B K
+     * W Y C G M R B K
+     * W Y C G M R B K
+     * W Y C G M R B K
+     * . . . . . . . .
+     * . . . . . . . .
+     * . . . . . . . .
+     *
+     * (B = Blue, K = Black)
+     * </code></pre>
+     * <p>Each bar should take up 1/8 of the sensor pixel array width.
+     * When this is not possible, the bar size should be rounded
+     * down to the nearest integer and the pattern can repeat
+     * on the right side.</p>
+     * <p>Each bar's height must always take up the full sensor
+     * pixel array height.</p>
+     * <p>Each pixel in this test pattern must be set to either
+     * 0% intensity or 100% intensity.</p>
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS = 2;
+
+    /**
+     * <p>The test pattern is similar to COLOR_BARS, except that
+     * each bar should start at its specified color at the top,
+     * and fade to gray at the bottom.</p>
+     * <p>Furthermore each bar is further subdivided into a left and
+     * right half. The left half should have a smooth gradient,
+     * and the right half should have a quantized gradient.</p>
+     * <p>In particular, the right half's should consist of blocks of the
+     * same color for 1/16th active sensor pixel array width.</p>
+     * <p>The least significant bits in the quantized gradient should
+     * be copied from the most significant bits of the smooth gradient.</p>
+     * <p>The height of each bar should always be a multiple of 128.
+     * When this is not the case, the pattern should repeat at the bottom
+     * of the image.</p>
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final int SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY = 3;
+
+    /**
+     * <p>All pixel data is replaced by a pseudo-random sequence
+     * generated from a PN9 512-bit sequence (typically implemented
+     * in hardware with a linear feedback shift register).</p>
+     * <p>The generator should be reset at the beginning of each frame,
+     * and thus each subsequent raw frame with this test pattern should
+     * be exactly the same as the last.</p>
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final int SENSOR_TEST_PATTERN_MODE_PN9 = 4;
+
+    /**
+     * <p>The first custom test pattern. All custom patterns that are
+     * available only on this camera device are at least this numeric
+     * value.</p>
+     * <p>All of the custom test patterns will be static
+     * (that is the raw image must not vary from frame to frame).</p>
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final int SENSOR_TEST_PATTERN_MODE_CUSTOM1 = 256;
+
+    //
+    // Enumeration values for CaptureRequest#SHADING_MODE
+    //
+
+    /**
+     * <p>No lens shading correction is applied</p>
+     * @see CaptureRequest#SHADING_MODE
+     */
+    public static final int SHADING_MODE_OFF = 0;
+
+    /**
+     * <p>Must not slow down frame rate relative to sensor raw output</p>
+     * @see CaptureRequest#SHADING_MODE
+     */
+    public static final int SHADING_MODE_FAST = 1;
+
+    /**
+     * <p>Frame rate may be reduced by high quality</p>
+     * @see CaptureRequest#SHADING_MODE
+     */
+    public static final int SHADING_MODE_HIGH_QUALITY = 2;
+
+    //
     // Enumeration values for CaptureRequest#STATISTICS_FACE_DETECT_MODE
     //
 
@@ -933,19 +1406,15 @@
     public static final int STATISTICS_FACE_DETECT_MODE_OFF = 0;
 
     /**
-     * <p>
-     * Optional Return rectangle and confidence
-     * only
-     * </p>
+     * <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>
+     * <p>Optional Return all face
+     * metadata</p>
      * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE
      */
     public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
@@ -969,28 +1438,32 @@
     //
 
     /**
-     * <p>
-     * Use the tone mapping curve specified in
-     * android.tonemap.curve
-     * </p>
+     * <p>Use the tone mapping curve specified in
+     * the android.tonemap.curve* entries.</p>
+     * <p>All color enhancement and tonemapping must be disabled, except
+     * for applying the tonemapping curve specified by
+     * {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed}, {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}, or
+     * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}.</p>
+     * <p>Must not slow down frame rate relative to raw
+     * sensor output.</p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_BLUE
+     * @see CaptureRequest#TONEMAP_CURVE_GREEN
+     * @see CaptureRequest#TONEMAP_CURVE_RED
      * @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>
+     * <p>Advanced gamma mapping and color enhancement may be applied.</p>
+     * <p>Should not slow down frame rate relative to raw sensor output.</p>
      * @see CaptureRequest#TONEMAP_MODE
      */
     public static final int TONEMAP_MODE_FAST = 1;
 
     /**
-     * <p>
-     * Frame rate may be reduced by high
-     * quality
-     * </p>
+     * <p>Advanced gamma mapping and color enhancement may be applied.</p>
+     * <p>May slow down frame rate relative to raw sensor output.</p>
      * @see CaptureRequest#TONEMAP_MODE
      */
     public static final int TONEMAP_MODE_HIGH_QUALITY = 2;
@@ -1000,60 +1473,51 @@
     //
 
     /**
-     * <p>
-     * AE is off.  When a camera device is opened, it starts in
-     * this state.
-     * </p>
+     * <p>AE is off or recently reset. When a camera device is opened, it starts in
+     * this state. This is a transient state, the camera device may skip reporting
+     * this state in capture result.</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>
+     * <p>AE doesn't yet have a good set of control values
+     * for the current scene. This is a transient state, the camera device may skip
+     * reporting this state in capture result.</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>
+     * <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>
+     * <p>AE has been 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
+     * <p>AE has a good set of control values, but flash
      * needs to be fired for good quality still
-     * capture
-     * </p>
+     * 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
+     * <p>AE has been asked to do a precapture sequence
+     * (through the {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} START),
+     * and is currently executing it. Once PRECAPTURE
      * completes, AE will transition to CONVERGED or
-     * FLASH_REQUIRED as appropriate
-     * </p>
+     * FLASH_REQUIRED as appropriate. This is a transient state, the
+     * camera device may skip reporting this state in capture result.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
      * @see CaptureResult#CONTROL_AE_STATE
      */
     public static final int CONTROL_AE_STATE_PRECAPTURE = 5;
@@ -1063,71 +1527,62 @@
     //
 
     /**
-     * <p>
-     * AF off or has not yet tried to scan/been asked
+     * <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>
+     * this state. This is a transient state, the camera device may
+     * skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_INACTIVE = 0;
 
     /**
-     * <p>
-     * if CONTINUOUS_* modes are supported. AF is
+     * <p>if CONTINUOUS_* modes are supported. AF is
      * currently doing an AF scan initiated by a continuous
-     * autofocus mode
-     * </p>
+     * autofocus mode. This is a transient state, the camera device may
+     * skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_PASSIVE_SCAN = 1;
 
     /**
-     * <p>
-     * if CONTINUOUS_* modes are supported. AF currently
+     * <p>if CONTINUOUS_* modes are supported. AF currently
      * believes it is in focus, but may restart scanning at
-     * any time.
-     * </p>
+     * any time. This is a transient state, the camera device may skip
+     * reporting this state in capture result.</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>
+     * <p>if AUTO or MACRO modes are supported. AF is doing
+     * an AF scan because it was triggered by AF trigger. This is a
+     * transient state, the camera device may skip reporting
+     * this state in capture result.</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
+     * <p>if any AF mode besides OFF is supported. AF
      * believes it is focused correctly and is
-     * locked
-     * </p>
+     * 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
+     * <p>if any AF mode besides OFF is supported. AF has
      * failed to focus successfully and is
-     * locked
-     * </p>
+     * locked.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_NOT_FOCUSED_LOCKED = 5;
 
     /**
-     * <p>
-     * if CONTINUOUS_* modes are supported. AF finished a
+     * <p>if CONTINUOUS_* modes are supported. AF finished a
      * passive scan without finding focus, and may restart
-     * scanning at any time.
-     * </p>
+     * scanning at any time. This is a transient state, the camera
+     * device may skip reporting this state in capture result.</p>
      * @see CaptureResult#CONTROL_AF_STATE
      */
     public static final int CONTROL_AF_STATE_PASSIVE_UNFOCUSED = 6;
@@ -1137,37 +1592,30 @@
     //
 
     /**
-     * <p>
-     * AWB is not in auto mode.  When a camera device is opened, it
-     * starts in this state.
-     * </p>
+     * <p>AWB is not in auto mode.  When a camera device is opened, it
+     * starts in this state. This is a transient state, the camera device may
+     * skip reporting this state in capture result.</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>
+     * <p>AWB doesn't yet have a good set of control
+     * values for the current scene. This is a transient state, the camera device
+     * may skip reporting this state in capture result.</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>
+     * <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>
+     * <p>AWB has been locked.</p>
      * @see CaptureResult#CONTROL_AWB_STATE
      */
     public static final int CONTROL_AWB_STATE_LOCKED = 3;
@@ -1177,36 +1625,34 @@
     //
 
     /**
-     * <p>
-     * No flash on camera
-     * </p>
+     * <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>
+     * <p>if {@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is true Flash is
+     * charging and cannot be fired</p>
+     *
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
      * @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>
+     * <p>if {@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is true Flash is
+     * ready to fire</p>
+     *
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
      * @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>
+     * <p>if {@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is true Flash fired
+     * for this capture</p>
+     *
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
      * @see CaptureResult#FLASH_STATE
      */
     public static final int FLASH_STATE_FIRED = 3;
@@ -1216,16 +1662,134 @@
     //
 
     /**
+     * <p>The lens parameters ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
+     * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) are not changing.</p>
+     *
+     * @see CaptureRequest#LENS_APERTURE
+     * @see CaptureRequest#LENS_FILTER_DENSITY
+     * @see CaptureRequest#LENS_FOCAL_LENGTH
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
      * @see CaptureResult#LENS_STATE
      */
     public static final int LENS_STATE_STATIONARY = 0;
 
     /**
+     * <p>Any of the lens parameters ({@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
+     * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} or {@link CaptureRequest#LENS_APERTURE android.lens.aperture}) is changing.</p>
+     *
+     * @see CaptureRequest#LENS_APERTURE
+     * @see CaptureRequest#LENS_FILTER_DENSITY
+     * @see CaptureRequest#LENS_FOCAL_LENGTH
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
      * @see CaptureResult#LENS_STATE
      */
     public static final int LENS_STATE_MOVING = 1;
 
     //
+    // Enumeration values for CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+    //
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT = 1;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_FLUORESCENT = 2;
+
+    /**
+     * <p>Incandescent light</p>
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_TUNGSTEN = 3;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_FLASH = 4;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_FINE_WEATHER = 9;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_CLOUDY_WEATHER = 10;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_SHADE = 11;
+
+    /**
+     * <p>D 5700 - 7100K</p>
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT_FLUORESCENT = 12;
+
+    /**
+     * <p>N 4600 - 5400K</p>
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_DAY_WHITE_FLUORESCENT = 13;
+
+    /**
+     * <p>W 3900 - 4500K</p>
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_COOL_WHITE_FLUORESCENT = 14;
+
+    /**
+     * <p>WW 3200 - 3700K</p>
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_WHITE_FLUORESCENT = 15;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_A = 17;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_B = 18;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_STANDARD_C = 19;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_D55 = 20;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_D65 = 21;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_D75 = 22;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_D50 = 23;
+
+    /**
+     * @see CaptureResult#SENSOR_REFERENCE_ILLUMINANT
+     */
+    public static final int SENSOR_REFERENCE_ILLUMINANT_ISO_STUDIO_TUNGSTEN = 24;
+
+    //
     // Enumeration values for CaptureResult#STATISTICS_SCENE_FLICKER
     //
 
@@ -1244,6 +1808,43 @@
      */
     public static final int STATISTICS_SCENE_FLICKER_60HZ = 2;
 
+    //
+    // Enumeration values for CaptureResult#SYNC_FRAME_NUMBER
+    //
+
+    /**
+     * <p>The current result is not yet fully synchronized to any request.
+     * Synchronization is in progress, and reading metadata from this
+     * result may include a mix of data that have taken effect since the
+     * last synchronization time.</p>
+     * <p>In some future result, within {@link CameraCharacteristics#SYNC_MAX_LATENCY android.sync.maxLatency} frames,
+     * this value will update to the actual frame number frame number
+     * the result is guaranteed to be synchronized to (as long as the
+     * request settings remain constant).</p>
+     *
+     * @see CameraCharacteristics#SYNC_MAX_LATENCY
+     * @see CaptureResult#SYNC_FRAME_NUMBER
+     * @hide
+     */
+    public static final int SYNC_FRAME_NUMBER_CONVERGING = -1;
+
+    /**
+     * <p>The current result's synchronization status is unknown. The
+     * result may have already converged, or it may be in progress.
+     * Reading from this result may include some mix of settings from
+     * past requests.</p>
+     * <p>After a settings change, the new settings will eventually all
+     * take effect for the output buffers and results. However, this
+     * value will not change when that happens. Altering settings
+     * rapidly may provide outcomes using mixes of settings from recent
+     * requests.</p>
+     * <p>This value is intended primarily for backwards compatibility with
+     * the older camera implementations (for android.hardware.Camera).</p>
+     * @see CaptureResult#SYNC_FRAME_NUMBER
+     * @hide
+     */
+    public static final int SYNC_FRAME_NUMBER_UNKNOWN = -2;
+
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/camera2/CaptureFailure.java b/core/java/android/hardware/camera2/CaptureFailure.java
index 3b408cf..35f9af1 100644
--- a/core/java/android/hardware/camera2/CaptureFailure.java
+++ b/core/java/android/hardware/camera2/CaptureFailure.java
@@ -15,8 +15,6 @@
  */
 package android.hardware.camera2;
 
-import android.hardware.camera2.CameraDevice.CaptureListener;
-
 /**
  * A report of failed capture for a single image capture from the image sensor.
  *
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 898f123..7656505 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -17,7 +17,6 @@
 package android.hardware.camera2;
 
 import android.hardware.camera2.impl.CameraMetadataNative;
-import android.hardware.camera2.CameraDevice.CaptureListener;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.view.Surface;
@@ -318,11 +317,52 @@
      * modify the comment blocks at the start or end.
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~*/
 
+
     /**
-     * <p>
-     * When android.control.awbMode is not OFF, TRANSFORM_MATRIX
-     * should be ignored.
-     * </p>
+     * <p>The mode control selects how the image data is converted from the
+     * sensor's native color into linear sRGB color.</p>
+     * <p>When auto-white balance is enabled with {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, this
+     * control is overridden by the AWB routine. When AWB is disabled, the
+     * application controls how the color mapping is performed.</p>
+     * <p>We define the expected processing pipeline below. For consistency
+     * across devices, this is always the case with TRANSFORM_MATRIX.</p>
+     * <p>When either FULL or HIGH_QUALITY is used, the camera device may
+     * do additional processing but {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
+     * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform} will still be provided by the
+     * camera device (in the results) and be roughly correct.</p>
+     * <p>Switching to TRANSFORM_MATRIX and using the data provided from
+     * FAST or HIGH_QUALITY will yield a picture with the same white point
+     * as what was produced by the camera device in the earlier frame.</p>
+     * <p>The expected processing pipeline is as follows:</p>
+     * <p><img alt="White balance processing pipeline" src="../../../../images/camera2/metadata/android.colorCorrection.mode/processing_pipeline.png" /></p>
+     * <p>The white balance is encoded by two values, a 4-channel white-balance
+     * gain vector (applied in the Bayer domain), and a 3x3 color transform
+     * matrix (applied after demosaic).</p>
+     * <p>The 4-channel white-balance gains are defined as:</p>
+     * <pre><code>{@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} = [ R G_even G_odd B ]
+     * </code></pre>
+     * <p>where <code>G_even</code> is the gain for green pixels on even rows of the
+     * output, and <code>G_odd</code> is the gain for green pixels on the odd rows.
+     * These may be identical for a given camera device implementation; if
+     * the camera device does not support a separate gain for even/odd green
+     * channels, it will use the <code>G_even</code> value, and write <code>G_odd</code> equal to
+     * <code>G_even</code> in the output result metadata.</p>
+     * <p>The matrices for color transforms are defined as a 9-entry vector:</p>
+     * <pre><code>{@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform} = [ I0 I1 I2 I3 I4 I5 I6 I7 I8 ]
+     * </code></pre>
+     * <p>which define a transform from input sensor colors, <code>P_in = [ r g b ]</code>,
+     * to output linear sRGB, <code>P_out = [ r' g' b' ]</code>,</p>
+     * <p>with colors as follows:</p>
+     * <pre><code>r' = I0r + I1g + I2b
+     * g' = I3r + I4g + I5b
+     * b' = I6r + I7g + I8b
+     * </code></pre>
+     * <p>Both the input and output value ranges must match. Overflow/underflow
+     * values are clipped to fit within the range.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
+     * @see CaptureRequest#CONTROL_AWB_MODE
      * @see #COLOR_CORRECTION_MODE_TRANSFORM_MATRIX
      * @see #COLOR_CORRECTION_MODE_FAST
      * @see #COLOR_CORRECTION_MODE_HIGH_QUALITY
@@ -331,55 +371,80 @@
             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
+     * <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 the camera device when the request
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE 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>
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
+     * <p>In the latter case, the camera device may round the matrix to account
+     * for precision issues; the final rounded matrix should be reported back
+     * in this matrix result metadata. The transform should keep the magnitude
+     * of the output color values within <code>[0, 1.0]</code> (assuming input color
+     * values is within the normalized range <code>[0, 1.0]</code>), or clipping may occur.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
      */
     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
+     * <p>Gains applying to Bayer raw color channels for
+     * white-balance.</p>
+     * <p>The 4-channel white-balance gains are defined in
+     * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
+     * for green pixels on even rows of the output, and <code>G_odd</code>
+     * is the gain for green pixels 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
+     * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
+     * <code>G_even</code> in the output result metadata.</p>
+     * <p>This array is either set by the camera device when the request
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE 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>
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
+     * <p>The output should be the gains actually applied by the camera device to
+     * the current frame.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
      */
     public static final Key<float[]> COLOR_CORRECTION_GAINS =
             new Key<float[]>("android.colorCorrection.gains", float[].class);
 
     /**
-     * <p>
-     * Enum for controlling
-     * antibanding
-     * </p>
+     * <p>The desired setting for the camera device's auto-exposure
+     * algorithm's antibanding compensation.</p>
+     * <p>Some kinds of lighting fixtures, such as some fluorescent
+     * lights, flicker at the rate of the power supply frequency
+     * (60Hz or 50Hz, depending on country). While this is
+     * typically not noticeable to a person, it can be visible to
+     * a camera device. If a camera sets its exposure time to the
+     * wrong value, the flicker may become visible in the
+     * viewfinder as flicker or in a final captured image, as a
+     * set of variable-brightness bands across the image.</p>
+     * <p>Therefore, the auto-exposure routines of camera devices
+     * include antibanding routines that ensure that the chosen
+     * exposure value will not cause such banding. The choice of
+     * exposure time depends on the rate of flicker, which the
+     * camera device can detect automatically, or the expected
+     * rate can be selected by the application using this
+     * control.</p>
+     * <p>A given camera device may not support all of the possible
+     * options for the antibanding mode. The
+     * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES android.control.aeAvailableAntibandingModes} key contains
+     * the available modes for a given camera device.</p>
+     * <p>The default mode is AUTO, which must be supported by all
+     * camera devices.</p>
+     * <p>If manual exposure control is enabled (by setting
+     * {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} or {@link CaptureRequest#CONTROL_MODE android.control.mode} to OFF),
+     * then this setting has no effect, and the application must
+     * ensure it selects exposure times that do not cause banding
+     * issues. The {@link CaptureResult#STATISTICS_SCENE_FLICKER android.statistics.sceneFlicker} key can assist
+     * the application in this.</p>
+     *
+     * @see CameraCharacteristics#CONTROL_AE_AVAILABLE_ANTIBANDING_MODES
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureResult#STATISTICS_SCENE_FLICKER
      * @see #CONTROL_AE_ANTIBANDING_MODE_OFF
      * @see #CONTROL_AE_ANTIBANDING_MODE_50HZ
      * @see #CONTROL_AE_ANTIBANDING_MODE_60HZ
@@ -389,42 +454,66 @@
             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
+     * <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>
+     * 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>
+     * <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 {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is ON_AUTO_FLASH / ON_ALWAYS_FLASH /
+     * ON_AUTO_FLASH_REDEYE.</p>
+     * <p>If AE precapture is triggered (see {@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger})
+     * when AE is already locked, the camera device will not change the exposure time
+     * ({@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}) and sensitivity ({@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity})
+     * parameters. The flash may be fired if the {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}
+     * is ON_AUTO_FLASH/ON_AUTO_FLASH_REDEYE and the scene is too dark. If the
+     * {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is ON_ALWAYS_FLASH, the scene may become overexposed.</p>
+     * <p>See {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE lock related state transition details.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CaptureResult#CONTROL_AE_STATE
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      */
     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>
+     * <p>The desired mode for the camera device's
+     * auto-exposure routine.</p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is
+     * AUTO.</p>
+     * <p>When set to any of the ON modes, the camera device's
+     * auto-exposure routine is enabled, overriding the
+     * application's selected exposure time, sensor sensitivity,
+     * and frame duration ({@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and
+     * {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration}). If one of the FLASH modes
+     * is selected, the camera device's flash unit controls are
+     * also overridden.</p>
+     * <p>The FLASH modes are only available if the camera device
+     * has a flash unit ({@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is <code>true</code>).</p>
+     * <p>If flash TORCH mode is desired, this field must be set to
+     * ON or OFF, and {@link CaptureRequest#FLASH_MODE android.flash.mode} set to TORCH.</p>
+     * <p>When set to any of the ON modes, the values chosen by the
+     * camera device auto-exposure routine for the overridden
+     * fields for a given capture will be available in its
+     * CaptureResult.</p>
+     *
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
+     * @see CaptureRequest#FLASH_MODE
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      * @see #CONTROL_AE_MODE_OFF
      * @see #CONTROL_AE_MODE_ON
      * @see #CONTROL_AE_MODE_ON_AUTO_FLASH
@@ -435,60 +524,52 @@
             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,
+     * <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 to be 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
+     * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE 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>
+     * should be nonnegative.</p>
+     * <p>If all regions have 0 weight, then no specific metering area
+     * needs to be used by the camera device. If the metering region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
+     * used sections in the frame metadata.</p>
+     *
+     * @see CaptureRequest#SCALER_CROP_REGION
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     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>
+     * <p>Range over which fps can be adjusted to
+     * maintain exposure</p>
+     * <p>Only constrains AE algorithm, not manual control
+     * of {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime}</p>
+     *
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
      */
     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
+     * <p>Whether the camera device will trigger a precapture
+     * metering sequence when it processes this request.</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>
+     * set to START, the camera device will trigger the autoexposure
+     * precapture metering sequence.</p>
+     * <p>The effect of AE precapture trigger depends on the current
+     * AE mode and state; see {@link CaptureResult#CONTROL_AE_STATE android.control.aeState} for AE precapture
+     * state transition details.</p>
+     *
+     * @see CaptureResult#CONTROL_AE_STATE
      * @see #CONTROL_AE_PRECAPTURE_TRIGGER_IDLE
      * @see #CONTROL_AE_PRECAPTURE_TRIGGER_START
      */
@@ -496,10 +577,17 @@
             new Key<Integer>("android.control.aePrecaptureTrigger", int.class);
 
     /**
-     * <p>
-     * Whether AF is currently enabled, and what
-     * mode it is set to
-     * </p>
+     * <p>Whether AF is currently enabled, and what
+     * mode it is set to</p>
+     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+     * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
+     * <p>If the lens is controlled by the camera device auto-focus algorithm,
+     * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
+     * in result metadata.</p>
+     *
+     * @see CaptureResult#CONTROL_AF_STATE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -511,46 +599,40 @@
             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,
+     * <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 to be 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
+     * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE 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>
+     * should be nonnegative.</p>
+     * <p>If all regions have 0 weight, then no specific focus area
+     * needs to be used by the camera device. If the focusing region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
+     * used sections in the frame metadata.</p>
+     *
+     * @see CaptureRequest#SCALER_CROP_REGION
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     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>
+     * <p>Whether the camera device will trigger autofocus for this request.</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 camera device will trigger the
+     * autofocus algorithm. If autofocus is disabled, this trigger has no effect.</p>
+     * <p>When set to CANCEL, the camera device will cancel any active trigger,
+     * and return to its initial AF state.</p>
+     * <p>See {@link CaptureResult#CONTROL_AF_STATE android.control.afState} for what that means for each AF mode.</p>
+     *
+     * @see CaptureResult#CONTROL_AF_STATE
      * @see #CONTROL_AF_TRIGGER_IDLE
      * @see #CONTROL_AF_TRIGGER_START
      * @see #CONTROL_AF_TRIGGER_CANCEL
@@ -559,28 +641,36 @@
             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
+     * <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>
+     * 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
+     * <p>Whether AWB is currently setting the color
      * transform fields, and what its illumination target
-     * is
-     * </p>
-     * <p>
-     * [BC - AWB lock,AWB modes]
-     * </p>
+     * is.</p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
+     * <p>When set to the ON mode, the camera device's auto white balance
+     * routine is enabled, overriding the application's selected
+     * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
+     * <p>When set to the OFF mode, the camera device's auto white balance
+     * routine is disabled. The application manually controls the white
+     * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
+     * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
+     * <p>When set to any other modes, the camera device's auto white balance
+     * routine is disabled. The camera device uses each particular illumination
+     * target for white balance adjustment.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
+     * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_AWB_MODE_OFF
      * @see #CONTROL_AWB_MODE_AUTO
      * @see #CONTROL_AWB_MODE_INCANDESCENT
@@ -595,43 +685,39 @@
             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,
+     * <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 to be 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
+     * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE 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>
+     * should be nonnegative.</p>
+     * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+     * needs to be used by the camera device. If the AWB region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
+     * used sections in the frame metadata.</p>
+     *
+     * @see CaptureRequest#SCALER_CROP_REGION
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     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>
+     * <p>Information to the camera device 3A (auto-exposure,
+     * auto-focus, auto-white balance) routines about the purpose
+     * of this capture, to help the camera device to decide optimal 3A
+     * strategy.</p>
+     * <p>This control is only effective if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF</code>
+     * and any 3A routine is active.</p>
+     *
+     * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_CAPTURE_INTENT_CUSTOM
      * @see #CONTROL_CAPTURE_INTENT_PREVIEW
      * @see #CONTROL_CAPTURE_INTENT_STILL_CAPTURE
@@ -643,10 +729,17 @@
             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>
+     * <p>A special color effect to apply.</p>
+     * <p>When this mode is set, a color effect will be applied
+     * to images produced by the camera device. The interpretation
+     * and implementation of these color effects is left to the
+     * implementor of the camera device, and should not be
+     * depended on to be consistent (or present) across all
+     * devices.</p>
+     * <p>A color effect will only be applied if
+     * {@link CaptureRequest#CONTROL_MODE android.control.mode} != OFF.</p>
+     *
+     * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_EFFECT_MODE_OFF
      * @see #CONTROL_EFFECT_MODE_MONO
      * @see #CONTROL_EFFECT_MODE_NEGATIVE
@@ -661,23 +754,50 @@
             new Key<Integer>("android.control.effectMode", int.class);
 
     /**
-     * <p>
-     * Overall mode of 3A control
-     * routines
-     * </p>
+     * <p>Overall mode of 3A control
+     * routines.</p>
+     * <p>High-level 3A control. When set to OFF, all 3A control
+     * by the camera device is disabled. The application must set the fields for
+     * capture parameters itself.</p>
+     * <p>When set to AUTO, the individual algorithm controls in
+     * android.control.* are in effect, such as {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}.</p>
+     * <p>When set to USE_SCENE_MODE, the individual controls in
+     * android.control.* are mostly disabled, and the camera device implements
+     * one of the scene mode settings (such as ACTION, SUNSET, or PARTY)
+     * as it wishes. The camera device scene mode 3A settings are provided by
+     * android.control.sceneModeOverrides.</p>
+     * <p>When set to OFF_KEEP_STATE, it is similar to OFF mode, the only difference
+     * is that this frame will not be used by camera device background 3A statistics
+     * update, as if this frame is never captured. This mode can be used in the scenario
+     * where the application doesn't want a 3A manual control capture to affect
+     * the subsequent auto 3A capture results.</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
      * @see #CONTROL_MODE_OFF
      * @see #CONTROL_MODE_AUTO
      * @see #CONTROL_MODE_USE_SCENE_MODE
+     * @see #CONTROL_MODE_OFF_KEEP_STATE
      */
     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
+     * <p>A camera mode optimized for conditions typical in a particular
+     * capture setting.</p>
+     * <p>This is the mode that that is active when
+     * <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code>. Aside from FACE_PRIORITY,
+     * these modes will disable {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode},
+     * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}, and {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} while in use.</p>
+     * <p>The interpretation and implementation of these scene modes is left
+     * to the implementor of the camera device. Their behavior will not be
+     * consistent across all devices, and any given device may only implement
+     * a subset of these modes.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see #CONTROL_SCENE_MODE_DISABLED
      * @see #CONTROL_SCENE_MODE_FACE_PRIORITY
      * @see #CONTROL_SCENE_MODE_ACTION
      * @see #CONTROL_SCENE_MODE_PORTRAIT
@@ -699,24 +819,30 @@
             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>
+     * <p>Whether video stabilization is
+     * active</p>
+     * <p>If enabled, video stabilization can modify the
+     * {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion} to keep the video stream
+     * stabilized</p>
+     *
+     * @see CaptureRequest#SCALER_CROP_REGION
      */
     public static final Key<Boolean> CONTROL_VIDEO_STABILIZATION_MODE =
             new Key<Boolean>("android.control.videoStabilizationMode", boolean.class);
 
     /**
-     * <p>
-     * Operation mode for edge
-     * enhancement
-     * </p>
+     * <p>Operation mode for edge
+     * enhancement.</p>
+     * <p>Edge/sharpness/detail enhancement. OFF means no
+     * enhancement will be applied by the camera device.</p>
+     * <p>This must be set to one of the modes listed in {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes}.</p>
+     * <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
+     * will be applied. HIGH_QUALITY mode indicates that the
+     * camera device will use the highest-quality enhancement algorithms,
+     * even if it slows down capture rate. FAST means the camera device will
+     * not slow down capture rate when applying edge enhancement.</p>
+     *
+     * @see CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES
      * @see #EDGE_MODE_OFF
      * @see #EDGE_MODE_FAST
      * @see #EDGE_MODE_HIGH_QUALITY
@@ -725,9 +851,25 @@
             new Key<Integer>("android.edge.mode", int.class);
 
     /**
-     * <p>
-     * Select flash operation mode
-     * </p>
+     * <p>The desired mode for for the camera device's flash control.</p>
+     * <p>This control is only effective when flash unit is available
+     * (<code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} == true</code>).</p>
+     * <p>When this control is used, the {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} must be set to ON or OFF.
+     * Otherwise, the camera device auto-exposure related flash control (ON_AUTO_FLASH,
+     * ON_ALWAYS_FLASH, or ON_AUTO_FLASH_REDEYE) will override this control.</p>
+     * <p>When set to OFF, the camera device will not fire flash for this capture.</p>
+     * <p>When set to SINGLE, the camera device will fire flash regardless of the camera
+     * device's auto-exposure routine's result. When used in still capture case, this
+     * control should be used along with AE precapture metering sequence
+     * ({@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}), otherwise, the image may be incorrectly exposed.</p>
+     * <p>When set to TORCH, the flash will be on continuously. This mode can be used
+     * for use cases such as preview, auto-focus assist, still capture, or video recording.</p>
+     * <p>The flash status will be reported by {@link CaptureResult#FLASH_STATE android.flash.state} in the capture result metadata.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
+     * @see CaptureResult#FLASH_STATE
      * @see #FLASH_MODE_OFF
      * @see #FLASH_MODE_SINGLE
      * @see #FLASH_MODE_TORCH
@@ -736,128 +878,171 @@
             new Key<Integer>("android.flash.mode", int.class);
 
     /**
-     * <p>
-     * GPS coordinates to include in output JPEG
-     * EXIF
-     * </p>
+     * <p>Set operational mode for hot pixel correction.</p>
+     * <p>Valid modes for this camera device are listed in
+     * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}.</p>
+     * <p>Hotpixel correction interpolates out, or otherwise removes, pixels
+     * that do not accurately encode the incoming light (i.e. pixels that
+     * are stuck at an arbitrary value).</p>
+     *
+     * @see CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES
+     * @see #HOT_PIXEL_MODE_OFF
+     * @see #HOT_PIXEL_MODE_FAST
+     * @see #HOT_PIXEL_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> HOT_PIXEL_MODE =
+            new Key<Integer>("android.hotPixel.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>
+     * <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>
+     * <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>
+     * <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>
+     * <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>
+     * <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>
+     * <p>Resolution of embedded JPEG thumbnail</p>
+     * <p>When set to (0, 0) value, the JPEG EXIF will not contain thumbnail,
+     * but the captured JPEG will still be a valid image.</p>
+     * <p>When a jpeg image capture is issued, the thumbnail size selected should have
+     * the same aspect ratio as the jpeg image.</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>
+     * <p>The ratio of lens focal length to the effective
+     * aperture diameter.</p>
+     * <p>This will only be supported on the camera devices that
+     * have variable aperture lens. The aperture value can only be
+     * one of the values listed in {@link CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES android.lens.info.availableApertures}.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is OFF,
+     * this can be set along with {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration}
+     * to achieve manual exposure control.</p>
+     * <p>The requested aperture value may take several frames to reach the
+     * requested value; the camera device will report the current (intermediate)
+     * aperture size in capture result metadata while the aperture is changing.
+     * While the aperture is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of
+     * the ON modes, this will be overridden by the camera device
+     * auto-exposure algorithm, the overridden values are then provided
+     * back to the user in the corresponding result.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES
+     * @see CaptureResult#LENS_STATE
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      */
     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>
+     * <p>State of lens neutral density filter(s).</p>
+     * <p>This will not be supported on most camera devices. On devices
+     * where this is supported, this may only be set to one of the
+     * values included in {@link CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES android.lens.info.availableFilterDensities}.</p>
+     * <p>Lens filters are typically used to lower the amount of light the
+     * sensor is exposed to (measured in steps of EV). As used here, an EV
+     * step is the standard logarithmic representation, which are
+     * non-negative, and inversely proportional to the amount of light
+     * hitting the sensor.  For example, setting this to 0 would result
+     * in no reduction of the incoming light, and setting this to 2 would
+     * mean that the filter is set to reduce incoming light by two stops
+     * (allowing 1/4 of the prior amount of light to the sensor).</p>
+     * <p>It may take several frames before the lens filter density changes
+     * to the requested value. While the filter density is still changing,
+     * {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p>
+     *
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES
+     * @see CaptureResult#LENS_STATE
      */
     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>
+     * <p>The current lens focal length; used for optical zoom.</p>
+     * <p>This setting controls the physical focal length of the camera
+     * device's lens. Changing the focal length changes the field of
+     * view of the camera device, and is usually used for optical zoom.</p>
+     * <p>Like {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}, this
+     * setting won't be applied instantaneously, and it may take several
+     * frames before the lens can change to the requested focal length.
+     * While the focal length is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will
+     * be set to MOVING.</p>
+     * <p>This is expected not to be supported on most devices.</p>
+     *
+     * @see CaptureRequest#LENS_APERTURE
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
+     * @see CaptureResult#LENS_STATE
      */
     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>
+     * <p>Distance to plane of sharpest focus,
+     * measured from frontmost surface of the lens</p>
+     * <p>0 means infinity focus. Used value will be clamped
+     * to [0, {@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance}].</p>
+     * <p>Like {@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, this setting won't be applied
+     * instantaneously, and it may take several frames before the lens
+     * can move to the requested focus distance. While the lens is still moving,
+     * {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p>
+     *
+     * @see CaptureRequest#LENS_FOCAL_LENGTH
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
+     * @see CaptureResult#LENS_STATE
      */
     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>
+     * <p>Sets whether the camera device uses optical image stabilization (OIS)
+     * when capturing images.</p>
+     * <p>OIS is used to compensate for motion blur due to small movements of
+     * the camera during capture. Unlike digital image stabilization, OIS makes
+     * use of mechanical elements to stabilize the camera sensor, and thus
+     * allows for longer exposure times before camera shake becomes
+     * apparent.</p>
+     * <p>This is not expected to be supported on most devices.</p>
      * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
      * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
      */
@@ -865,10 +1050,19 @@
             new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
 
     /**
-     * <p>
-     * Mode of operation for the noise reduction
-     * algorithm
-     * </p>
+     * <p>Mode of operation for the noise reduction
+     * algorithm</p>
+     * <p>Noise filtering control. OFF means no noise reduction
+     * will be applied by the camera device.</p>
+     * <p>This must be set to a valid mode in
+     * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}.</p>
+     * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
+     * will be applied. HIGH_QUALITY mode indicates that the camera device
+     * will use the highest-quality noise filtering algorithms,
+     * even if it slows down capture rate. FAST means the camera device should not
+     * slow down capture rate when applying noise filtering.</p>
+     *
+     * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
      * @see #NOISE_REDUCTION_MODE_OFF
      * @see #NOISE_REDUCTION_MODE_FAST
      * @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
@@ -877,44 +1071,33 @@
             new Key<Integer>("android.noiseReduction.mode", int.class);
 
     /**
-     * <p>
-     * An application-specified ID for the current
+     * <p>An application-specified ID for the current
      * request. Must be maintained unchanged in output
-     * frame
-     * </p>
-     *
+     * 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
+     * <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
+     * 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
+     * (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
+     * 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
@@ -923,69 +1106,188 @@
      * 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>
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} ) and floor(
+     * activeArraySize.height /
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom}), respectively.</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
      */
     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>
+     * <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>
      */
     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>
+     * <p>Duration from start of frame exposure to
+     * start of next frame exposure.</p>
+     * <p>The maximum frame rate that can be supported by a camera subsystem is
+     * a function of many factors:</p>
+     * <ul>
+     * <li>Requested resolutions of output image streams</li>
+     * <li>Availability of binning / skipping modes on the imager</li>
+     * <li>The bandwidth of the imager interface</li>
+     * <li>The bandwidth of the various ISP processing blocks</li>
+     * </ul>
+     * <p>Since these factors can vary greatly between different ISPs and
+     * sensors, the camera abstraction tries to represent the bandwidth
+     * restrictions with as simple a model as possible.</p>
+     * <p>The model presented has the following characteristics:</p>
+     * <ul>
+     * <li>The image sensor is always configured to output the smallest
+     * resolution possible given the application's requested output stream
+     * sizes.  The smallest resolution is defined as being at least as large
+     * as the largest requested output stream size; the camera pipeline must
+     * never digitally upsample sensor data when the crop region covers the
+     * whole sensor. In general, this means that if only small output stream
+     * resolutions are configured, the sensor can provide a higher frame
+     * rate.</li>
+     * <li>Since any request may use any or all the currently configured
+     * output streams, the sensor and ISP must be configured to support
+     * scaling a single capture to all the streams at the same time.  This
+     * means the camera pipeline must be ready to produce the largest
+     * requested output size without any delay.  Therefore, the overall
+     * frame rate of a given configured stream set is governed only by the
+     * largest requested stream resolution.</li>
+     * <li>Using more than one output stream in a request does not affect the
+     * frame duration.</li>
+     * <li>Certain format-streams may need to do additional background processing
+     * before data is consumed/produced by that stream. These processors
+     * can run concurrently to the rest of the camera pipeline, but
+     * cannot process more than 1 capture at a time.</li>
+     * </ul>
+     * <p>The necessary information for the application, given the model above,
+     * is provided via the {@link CameraCharacteristics#SCALER_AVAILABLE_MIN_FRAME_DURATIONS android.scaler.availableMinFrameDurations} field.
+     * These are used to determine the maximum frame rate / minimum frame
+     * duration that is possible for a given stream configuration.</p>
+     * <p>Specifically, the application can use the following rules to
+     * determine the minimum frame duration it can request from the camera
+     * device:</p>
+     * <ol>
+     * <li>Let the set of currently configured input/output streams
+     * be called <code>S</code>.</li>
+     * <li>Find the minimum frame durations for each stream in <code>S</code>, by
+     * looking it up in {@link CameraCharacteristics#SCALER_AVAILABLE_MIN_FRAME_DURATIONS android.scaler.availableMinFrameDurations} (with
+     * its respective size/format). Let this set of frame durations be called
+     * <code>F</code>.</li>
+     * <li>For any given request <code>R</code>, the minimum frame duration allowed
+     * for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
+     * used in <code>R</code> be called <code>S_r</code>.</li>
+     * </ol>
+     * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS android.scaler.availableStallDurations}), then the frame duration in
+     * <code>F</code> determines the steady state frame rate that the application will
+     * get if it uses <code>R</code> as a repeating request. Let this special kind
+     * of request be called <code>Rsimple</code>.</p>
+     * <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
+     * by a single capture of a new request <code>Rstall</code> (which has at least
+     * one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
+     * same minimum frame duration this will not cause a frame rate loss
+     * if all buffers from the previous <code>Rstall</code> have already been
+     * delivered.</p>
+     * <p>For more details about stalling, see
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS android.scaler.availableStallDurations}.</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_MIN_FRAME_DURATIONS
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS
      */
     public static final Key<Long> SENSOR_FRAME_DURATION =
             new Key<Long>("android.sensor.frameDuration", long.class);
 
     /**
-     * <p>
-     * Gain applied to image data. Must be
+     * <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>
+     * 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
+     * <p>A pixel <code>[R, G_even, G_odd, B]</code> that supplies the test pattern
+     * when {@link CaptureRequest#SENSOR_TEST_PATTERN_MODE android.sensor.testPatternMode} is SOLID_COLOR.</p>
+     * <p>Each color channel is treated as an unsigned 32-bit integer.
+     * The camera device then uses the most significant X bits
+     * that correspond to how many bits are in its Bayer raw sensor
+     * output.</p>
+     * <p>For example, a sensor with RAW10 Bayer output would use the
+     * 10 most significant bits from each color channel.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#SENSOR_TEST_PATTERN_MODE
+     */
+    public static final Key<int[]> SENSOR_TEST_PATTERN_DATA =
+            new Key<int[]>("android.sensor.testPatternData", int[].class);
+
+    /**
+     * <p>When enabled, the sensor sends a test pattern instead of
+     * doing a real exposure from the camera.</p>
+     * <p>When a test pattern is enabled, all manual sensor controls specified
+     * by android.sensor.* should be ignored. All other controls should
+     * work as normal.</p>
+     * <p>For example, if manual flash is enabled, flash firing should still
+     * occur (and that the test pattern remain unmodified, since the flash
+     * would not actually affect it).</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * @see #SENSOR_TEST_PATTERN_MODE_OFF
+     * @see #SENSOR_TEST_PATTERN_MODE_SOLID_COLOR
+     * @see #SENSOR_TEST_PATTERN_MODE_COLOR_BARS
+     * @see #SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY
+     * @see #SENSOR_TEST_PATTERN_MODE_PN9
+     * @see #SENSOR_TEST_PATTERN_MODE_CUSTOM1
+     */
+    public static final Key<Integer> SENSOR_TEST_PATTERN_MODE =
+            new Key<Integer>("android.sensor.testPatternMode", int.class);
+
+    /**
+     * <p>Quality of lens shading correction applied
+     * to the image data.</p>
+     * <p>When set to OFF mode, no lens shading correction will be applied by the
+     * camera device, and an identity lens shading map data will be provided
+     * if <code>{@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} == ON</code>. For example, for lens
+     * shading map with size specified as <code>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize} = [ 4, 3 ]</code>,
+     * the output {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} for this case will be an identity map
+     * shown below:</p>
+     * <pre><code>[ 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,   1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0 ]
+     * </code></pre>
+     * <p>When set to other modes, lens shading correction will be applied by the
+     * camera device. Applications can request lens shading map data by setting
+     * {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} to ON, and then the camera device will provide
+     * lens shading map data in {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap}, with size specified
+     * by {@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}.</p>
+     *
+     * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
+     * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
+     * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+     * @see #SHADING_MODE_OFF
+     * @see #SHADING_MODE_FAST
+     * @see #SHADING_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> SHADING_MODE =
+            new Key<Integer>("android.shading.mode", 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>
+     * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES android.statistics.info.availableFaceDetectModes}.</p>
+     *
+     * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES
      * @see #STATISTICS_FACE_DETECT_MODE_OFF
      * @see #STATISTICS_FACE_DETECT_MODE_SIMPLE
      * @see #STATISTICS_FACE_DETECT_MODE_FULL
@@ -994,15 +1296,25 @@
             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>
+     * <p>Operating mode for hotpixel map generation.</p>
+     * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
+     * If set to OFF, no hotpixel map should be returned.</p>
+     * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+     * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
+     */
+    public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
+            new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
+
+    /**
+     * <p>Whether the camera device will output the lens
+     * shading map in output result metadata.</p>
+     * <p>When set to ON,
+     * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} must be provided in
+     * the output result metadata.</p>
+     *
+     * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_OFF
      * @see #STATISTICS_LENS_SHADING_MAP_MODE_ON
      */
@@ -1010,61 +1322,110 @@
             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>
+     * <p>Tonemapping / contrast / gamma curve for the blue
+     * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     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>
+     * <p>Tonemapping / contrast / gamma curve for the green
+     * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     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>
+     * <p>Tonemapping / contrast / gamma curve for the red
+     * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>Each channel's curve is defined by an array of control points:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} =
+     * [ P0in, P0out, P1in, P1out, P2in, P2out, P3in, P3out, ..., PNin, PNout ]
+     * 2 &lt;= N &lt;= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
+     * <p>These are sorted in order of increasing <code>Pin</code>; it is always
+     * guaranteed that input values 0.0 and 1.0 are included in the list to
+     * define a complete mapping. For input values between control points,
+     * the camera device must linearly interpolate between the control
+     * points.</p>
+     * <p>Each curve can have an independent number of points, and the number
+     * of points can be less than max (that is, the request doesn't have to
+     * always provide a curve with number of points equivalent to
+     * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
+     * <p>A few examples, and their corresponding graphical mappings; these
+     * only specify the red channel and the precision is limited to 4
+     * digits, for conciseness.</p>
+     * <p>Linear mapping:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 0, 1.0, 1.0 ]
+     * </code></pre>
+     * <p><img alt="Linear mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png" /></p>
+     * <p>Invert mapping:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 1.0, 1.0, 0 ]
+     * </code></pre>
+     * <p><img alt="Inverting mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png" /></p>
+     * <p>Gamma 1/2.2 mapping, with 16 control points:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+     * 0.0000, 0.0000, 0.0667, 0.2920, 0.1333, 0.4002, 0.2000, 0.4812,
+     * 0.2667, 0.5484, 0.3333, 0.6069, 0.4000, 0.6594, 0.4667, 0.7072,
+     * 0.5333, 0.7515, 0.6000, 0.7928, 0.6667, 0.8317, 0.7333, 0.8685,
+     * 0.8000, 0.9035, 0.8667, 0.9370, 0.9333, 0.9691, 1.0000, 1.0000 ]
+     * </code></pre>
+     * <p><img alt="Gamma = 1/2.2 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png" /></p>
+     * <p>Standard sRGB gamma mapping, per IEC 61966-2-1:1999, with 16 control points:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+     * 0.0000, 0.0000, 0.0667, 0.2864, 0.1333, 0.4007, 0.2000, 0.4845,
+     * 0.2667, 0.5532, 0.3333, 0.6125, 0.4000, 0.6652, 0.4667, 0.7130,
+     * 0.5333, 0.7569, 0.6000, 0.7977, 0.6667, 0.8360, 0.7333, 0.8721,
+     * 0.8000, 0.9063, 0.8667, 0.9389, 0.9333, 0.9701, 1.0000, 1.0000 ]
+     * </code></pre>
+     * <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
+     * @see CaptureRequest#TONEMAP_MODE
      */
     public static final Key<float[]> TONEMAP_CURVE_RED =
             new Key<float[]>("android.tonemap.curveRed", float[].class);
 
     /**
+     * <p>High-level global contrast/gamma/tonemapping control.</p>
+     * <p>When switching to an application-defined contrast curve by setting
+     * {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} to CONTRAST_CURVE, the curve is defined
+     * per-channel with a set of <code>(in, out)</code> points that specify the
+     * mapping from input high-bit-depth pixel value to the output
+     * low-bit-depth value.  Since the actual pixel ranges of both input
+     * and output may change depending on the camera pipeline, the values
+     * are specified by normalized floating-point numbers.</p>
+     * <p>More-complex color mapping operations such as 3D color look-up
+     * tables, selective chroma enhancement, or other non-linear color
+     * transforms will be disabled when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>This must be set to a valid mode in
+     * {@link CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES android.tonemap.availableToneMapModes}.</p>
+     * <p>When using either FAST or HIGH_QUALITY, the camera device will
+     * emit its own tonemap curve in {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed},
+     * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}, and {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}.
+     * These values are always available, and as close as possible to the
+     * actually used nonlinear/nonglobal transforms.</p>
+     * <p>If a request is sent with TRANSFORM_MATRIX with the camera device's
+     * provided curve in FAST or HIGH_QUALITY, the image's tonemap will be
+     * roughly the same.</p>
+     *
+     * @see CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES
+     * @see CaptureRequest#TONEMAP_CURVE_BLUE
+     * @see CaptureRequest#TONEMAP_CURVE_GREEN
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      * @see #TONEMAP_MODE_CONTRAST_CURVE
      * @see #TONEMAP_MODE_FAST
      * @see #TONEMAP_MODE_HIGH_QUALITY
@@ -1073,49 +1434,59 @@
             new Key<Integer>("android.tonemap.mode", int.class);
 
     /**
-     * <p>
-     * This LED is nominally used to indicate to the user
+     * <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>
-     *
+     * any untrusted applications.</p>
+     * <p>In particular, the LED <em>must</em> always be on when the data could be
+     * transmitted off the device. The LED <em>should</em> always be on whenever
+     * data is stored locally on the device.</p>
+     * <p>The LED <em>may</em> 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
+     * <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 will 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>
+     * compensation, the camera device must report whether setting
+     * the black level lock was successful in the output result
+     * metadata.</p>
+     * <p>For example, if a sequence of requests is as follows:</p>
+     * <ul>
+     * <li>Request 1: Exposure = 10ms, Black level lock = OFF</li>
+     * <li>Request 2: Exposure = 10ms, Black level lock = ON</li>
+     * <li>Request 3: Exposure = 10ms, Black level lock = ON</li>
+     * <li>Request 4: Exposure = 20ms, Black level lock = ON</li>
+     * <li>Request 5: Exposure = 20ms, Black level lock = ON</li>
+     * <li>Request 6: Exposure = 20ms, Black level lock = ON</li>
+     * </ul>
+     * <p>And the exposure change in Request 4 requires the camera
+     * device to reset the black level offsets, then the output
+     * result metadata is expected to be:</p>
+     * <ul>
+     * <li>Result 1: Exposure = 10ms, Black level lock = OFF</li>
+     * <li>Result 2: Exposure = 10ms, Black level lock = ON</li>
+     * <li>Result 3: Exposure = 10ms, Black level lock = ON</li>
+     * <li>Result 4: Exposure = 20ms, Black level lock = OFF</li>
+     * <li>Result 5: Exposure = 20ms, Black level lock = ON</li>
+     * <li>Result 6: Exposure = 20ms, Black level lock = ON</li>
+     * </ul>
+     * <p>This indicates to the application that on frame 4, black
+     * levels were reset due to exposure value changes, and pixel
+     * values may not be consistent across captures.</p>
+     * <p>The camera device will maintain the lock to the extent
+     * possible, only overriding the lock to OFF when changes to
+     * other request parameters require a black level recalculation
+     * or reset.</p>
      */
     public static final Key<Boolean> BLACK_LEVEL_LOCK =
             new Key<Boolean>("android.blackLevel.lock", boolean.class);
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 535b963..03661f0 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -16,8 +16,6 @@
 
 package android.hardware.camera2;
 
-import android.graphics.Point;
-import android.graphics.Rect;
 import android.hardware.camera2.impl.CameraMetadataNative;
 
 /**
@@ -124,104 +122,308 @@
      * 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
+     * <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 the camera device when the request
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE 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>
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
+     * <p>In the latter case, the camera device may round the matrix to account
+     * for precision issues; the final rounded matrix should be reported back
+     * in this matrix result metadata. The transform should keep the magnitude
+     * of the output color values within <code>[0, 1.0]</code> (assuming input color
+     * values is within the normalized range <code>[0, 1.0]</code>), or clipping may occur.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
      */
     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
+     * <p>Gains applying to Bayer raw color channels for
+     * white-balance.</p>
+     * <p>The 4-channel white-balance gains are defined in
+     * the order of <code>[R G_even G_odd B]</code>, where <code>G_even</code> is the gain
+     * for green pixels on even rows of the output, and <code>G_odd</code>
+     * is the gain for green pixels 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
+     * it should use the <code>G_even</code> value, and write <code>G_odd</code> equal to
+     * <code>G_even</code> in the output result metadata.</p>
+     * <p>This array is either set by the camera device when the request
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE 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>
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} is TRANSFORM_MATRIX.</p>
+     * <p>The output should be the gains actually applied by the camera device to
+     * the current frame.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
      */
     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
+     * <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>
-     *
+     * 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,
+     * <p>The desired mode for the camera device's
+     * auto-exposure routine.</p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is
+     * AUTO.</p>
+     * <p>When set to any of the ON modes, the camera device's
+     * auto-exposure routine is enabled, overriding the
+     * application's selected exposure time, sensor sensitivity,
+     * and frame duration ({@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and
+     * {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration}). If one of the FLASH modes
+     * is selected, the camera device's flash unit controls are
+     * also overridden.</p>
+     * <p>The FLASH modes are only available if the camera device
+     * has a flash unit ({@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} is <code>true</code>).</p>
+     * <p>If flash TORCH mode is desired, this field must be set to
+     * ON or OFF, and {@link CaptureRequest#FLASH_MODE android.flash.mode} set to TORCH.</p>
+     * <p>When set to any of the ON modes, the values chosen by the
+     * camera device auto-exposure routine for the overridden
+     * fields for a given capture will be available in its
+     * CaptureResult.</p>
+     *
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
+     * @see CaptureRequest#FLASH_MODE
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
+     * @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 to be 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
+     * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE 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>
+     * should be nonnegative.</p>
+     * <p>If all regions have 0 weight, then no specific metering area
+     * needs to be used by the camera device. If the metering region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
+     * used sections in the frame metadata.</p>
+     *
+     * @see CaptureRequest#SCALER_CROP_REGION
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     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>
+     * <p>Current state of AE algorithm</p>
+     * <p>Switching between or enabling AE modes ({@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode}) always
+     * resets the AE state to INACTIVE. Similarly, switching between {@link CaptureRequest#CONTROL_MODE android.control.mode},
+     * or {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code> resets all
+     * the algorithm states to INACTIVE.</p>
+     * <p>The camera device can do several state transitions between two results, if it is
+     * allowed by the state transition table. For example: INACTIVE may never actually be
+     * seen in a result.</p>
+     * <p>The state in the result is the state for this image (in sync with this image): if
+     * AE state becomes CONVERGED, then the image data associated with this result should
+     * be good to use.</p>
+     * <p>Below are state transition tables for different AE modes.</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device auto exposure algorithm is disabled</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is AE_MODE_ON_*:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates AE scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Camera device finishes AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Good values, not changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Camera device finishes AE scan</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Camera device initiates AE scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Camera device initiates AE scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is OFF</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values not good after unlock</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is OFF</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values good after unlock</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is OFF</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Exposure good, but too dark</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PRECAPTURE</td>
+     * <td align="center">Sequence done. {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is OFF</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Ready for high-quality capture</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PRECAPTURE</td>
+     * <td align="center">Sequence done. {@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Ready for high-quality capture</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START</td>
+     * <td align="center">PRECAPTURE</td>
+     * <td align="center">Start AE precapture metering sequence</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for above AE modes (AE_MODE_ON_*), in addition to the state transitions
+     * listed in above table, it is also legal for the camera device to skip one or more
+     * transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash after a precapture sequence, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger} is START, sequence done</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Converged after a precapture sequence, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Converged but too dark w/o flash after a new scan, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FLASH_REQUIRED</td>
+     * <td align="center">Camera device finished AE scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Converged after a new scan, transient states are skipped by camera device.</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     *
+     * @see CaptureRequest#CONTROL_AE_LOCK
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureRequest#CONTROL_SCENE_MODE
      * @see #CONTROL_AE_STATE_INACTIVE
      * @see #CONTROL_AE_STATE_SEARCHING
      * @see #CONTROL_AE_STATE_CONVERGED
@@ -233,10 +435,17 @@
             new Key<Integer>("android.control.aeState", int.class);
 
     /**
-     * <p>
-     * Whether AF is currently enabled, and what
-     * mode it is set to
-     * </p>
+     * <p>Whether AF is currently enabled, and what
+     * mode it is set to</p>
+     * <p>Only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} = AUTO and the lens is not fixed focus
+     * (i.e. <code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} &gt; 0</code>).</p>
+     * <p>If the lens is controlled by the camera device auto-focus algorithm,
+     * the camera device will report the current AF status in {@link CaptureResult#CONTROL_AF_STATE android.control.afState}
+     * in result metadata.</p>
+     *
+     * @see CaptureResult#CONTROL_AF_STATE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see #CONTROL_AF_MODE_OFF
      * @see #CONTROL_AF_MODE_AUTO
      * @see #CONTROL_AF_MODE_MACRO
@@ -248,41 +457,415 @@
             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,
+     * <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 to be 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
+     * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE 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>
+     * should be nonnegative.</p>
+     * <p>If all regions have 0 weight, then no specific focus area
+     * needs to be used by the camera device. If the focusing region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
+     * used sections in the frame metadata.</p>
+     *
+     * @see CaptureRequest#SCALER_CROP_REGION
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     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>
+     * <p>Current state of AF algorithm.</p>
+     * <p>Switching between or enabling AF modes ({@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}) always
+     * resets the AF state to INACTIVE. Similarly, switching between {@link CaptureRequest#CONTROL_MODE android.control.mode},
+     * or {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code> resets all
+     * the algorithm states to INACTIVE.</p>
+     * <p>The camera device can do several state transitions between two results, if it is
+     * allowed by the state transition table. For example: INACTIVE may never actually be
+     * seen in a result.</p>
+     * <p>The state in the result is the state for this image (in sync with this image): if
+     * AF state becomes FOCUSED, then the image data associated with this result should
+     * be sharp.</p>
+     * <p>Below are state transition tables for different AF modes.</p>
+     * <p>When {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} is AF_MODE_OFF or AF_MODE_EDOF:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Never changes</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} is AF_MODE_AUTO or AF_MODE_MACRO:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">Start AF sweep, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">AF sweep done</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focused, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">AF sweep done</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Not focused, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Cancel/reset AF, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Cancel/reset AF</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">Start new sweep, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Cancel/reset AF</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">ACTIVE_SCAN</td>
+     * <td align="center">Start new sweep, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">Any state</td>
+     * <td align="center">Mode change</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for these AF modes (AF_MODE_AUTO and AF_MODE_MACRO), in addition to the
+     * state transitions listed in above table, it is also legal for the camera device to skip
+     * one or more transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Focus failed after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is already good or good after a scan, lens is now locked.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Focus is good after a scan, lens is not locked.</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} is AF_MODE_CONTINUOUS_VIDEO:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF state query, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device completes current scan</td>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device fails current scan</td>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. If focus is good, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. if focus is bad, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Reset lens position, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode} is AF_MODE_CONTINUOUS_PICTURE:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF state query, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device completes current scan</td>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Camera device fails current scan</td>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">End AF scan, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Eventual trans. once focus good, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Eventual trans. if cannot focus, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Reset lens position, Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">Camera device initiates new scan</td>
+     * <td align="center">PASSIVE_SCAN</td>
+     * <td align="center">Start AF scan, Lens now moving</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_FOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">PASSIVE_UNFOCUSED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">Immediate trans. Lens now locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_TRIGGER</td>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">No effect</td>
+     * </tr>
+     * <tr>
+     * <td align="center">NOT_FOCUSED_LOCKED</td>
+     * <td align="center">AF_CANCEL</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Restart AF scan</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When switch between AF_MODE_CONTINUOUS_* (CAF modes) and AF_MODE_AUTO/AF_MODE_MACRO
+     * (AUTO modes), the initial INACTIVE or PASSIVE_SCAN states may be skipped by the
+     * camera device. When a trigger is included in a mode switch request, the trigger
+     * will be evaluated in the context of the new mode in the request.
+     * See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">CAF--&gt;AUTO mode switch</td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Mode switch without trigger, initial state must be INACTIVE</td>
+     * </tr>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">CAF--&gt;AUTO mode switch with AF_TRIGGER</td>
+     * <td align="center">trigger-reachable states from INACTIVE</td>
+     * <td align="center">Mode switch with trigger, INACTIVE is skipped</td>
+     * </tr>
+     * <tr>
+     * <td align="center">any state</td>
+     * <td align="center">AUTO--&gt;CAF mode switch</td>
+     * <td align="center">passively reachable states from INACTIVE</td>
+     * <td align="center">Mode switch without trigger, passive transient state is skipped</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureRequest#CONTROL_SCENE_MODE
      * @see #CONTROL_AF_STATE_INACTIVE
      * @see #CONTROL_AF_STATE_PASSIVE_SCAN
      * @see #CONTROL_AF_STATE_PASSIVE_FOCUSED
@@ -295,30 +878,37 @@
             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
+     * <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>
-     *
+     * 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
+     * <p>Whether AWB is currently setting the color
      * transform fields, and what its illumination target
-     * is
-     * </p>
-     * <p>
-     * [BC - AWB lock,AWB modes]
-     * </p>
+     * is.</p>
+     * <p>This control is only effective if {@link CaptureRequest#CONTROL_MODE android.control.mode} is AUTO.</p>
+     * <p>When set to the ON mode, the camera device's auto white balance
+     * routine is enabled, overriding the application's selected
+     * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains} and
+     * {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
+     * <p>When set to the OFF mode, the camera device's auto white balance
+     * routine is disabled. The application manually controls the white
+     * balance by {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform}, {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}
+     * and {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode}.</p>
+     * <p>When set to any other modes, the camera device's auto white balance
+     * routine is disabled. The camera device uses each particular illumination
+     * target for white balance adjustment.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
+     * @see CaptureRequest#COLOR_CORRECTION_TRANSFORM
+     * @see CaptureRequest#CONTROL_MODE
      * @see #CONTROL_AWB_MODE_OFF
      * @see #CONTROL_AWB_MODE_AUTO
      * @see #CONTROL_AWB_MODE_INCANDESCENT
@@ -333,43 +923,152 @@
             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,
+     * <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 to be 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
+     * ({@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.width - 1,
+     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE 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>
+     * should be nonnegative.</p>
+     * <p>If all regions have 0 weight, then no specific auto-white balance (AWB) area
+     * needs to be used by the camera device. If the AWB region is
+     * outside the current {@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}, the camera device
+     * will ignore the sections outside the region and output the
+     * used sections in the frame metadata.</p>
+     *
+     * @see CaptureRequest#SCALER_CROP_REGION
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
      */
     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>
+     * <p>Current state of AWB algorithm</p>
+     * <p>Switching between or enabling AWB modes ({@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode}) always
+     * resets the AWB state to INACTIVE. Similarly, switching between {@link CaptureRequest#CONTROL_MODE android.control.mode},
+     * or {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} if <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == USE_SCENE_MODE</code> resets all
+     * the algorithm states to INACTIVE.</p>
+     * <p>The camera device can do several state transitions between two results, if it is
+     * allowed by the state transition table. So INACTIVE may never actually be seen in
+     * a result.</p>
+     * <p>The state in the result is the state for this image (in sync with this image): if
+     * AWB state becomes CONVERGED, then the image data associated with this result should
+     * be good to use.</p>
+     * <p>Below are state transition tables for different AWB modes.</p>
+     * <p>When <code>{@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} != AWB_MODE_AUTO</code>:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center"></td>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device auto white balance algorithm is disabled</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>When {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} is AWB_MODE_AUTO:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device initiates AWB scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Camera device finishes AWB scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Good values, not changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Camera device initiates AWB scan</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values changing</td>
+     * </tr>
+     * <tr>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} is ON</td>
+     * <td align="center">LOCKED</td>
+     * <td align="center">Values locked</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} is OFF</td>
+     * <td align="center">SEARCHING</td>
+     * <td align="center">Values not good after unlock</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     * <p>For the above table, the camera device may skip reporting any state changes that happen
+     * without application intervention (i.e. mode switch, trigger, locking). Any state that
+     * can be skipped in that manner is called a transient state.</p>
+     * <p>For example, for this AWB mode (AWB_MODE_AUTO), in addition to the state transitions
+     * listed in above table, it is also legal for the camera device to skip one or more
+     * transient states between two results. See below table for examples:</p>
+     * <table>
+     * <thead>
+     * <tr>
+     * <th align="center">State</th>
+     * <th align="center">Transition Cause</th>
+     * <th align="center">New State</th>
+     * <th align="center">Notes</th>
+     * </tr>
+     * </thead>
+     * <tbody>
+     * <tr>
+     * <td align="center">INACTIVE</td>
+     * <td align="center">Camera device finished AWB scan</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values are already good, transient states are skipped by camera device.</td>
+     * </tr>
+     * <tr>
+     * <td align="center">LOCKED</td>
+     * <td align="center">{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock} is OFF</td>
+     * <td align="center">CONVERGED</td>
+     * <td align="center">Values good after unlock, transient states are skipped by camera device.</td>
+     * </tr>
+     * </tbody>
+     * </table>
+     *
+     * @see CaptureRequest#CONTROL_AWB_LOCK
+     * @see CaptureRequest#CONTROL_AWB_MODE
+     * @see CaptureRequest#CONTROL_MODE
+     * @see CaptureRequest#CONTROL_SCENE_MODE
      * @see #CONTROL_AWB_STATE_INACTIVE
      * @see #CONTROL_AWB_STATE_SEARCHING
      * @see #CONTROL_AWB_STATE_CONVERGED
@@ -379,22 +1078,46 @@
             new Key<Integer>("android.control.awbState", int.class);
 
     /**
-     * <p>
-     * Overall mode of 3A control
-     * routines
-     * </p>
+     * <p>Overall mode of 3A control
+     * routines.</p>
+     * <p>High-level 3A control. When set to OFF, all 3A control
+     * by the camera device is disabled. The application must set the fields for
+     * capture parameters itself.</p>
+     * <p>When set to AUTO, the individual algorithm controls in
+     * android.control.* are in effect, such as {@link CaptureRequest#CONTROL_AF_MODE android.control.afMode}.</p>
+     * <p>When set to USE_SCENE_MODE, the individual controls in
+     * android.control.* are mostly disabled, and the camera device implements
+     * one of the scene mode settings (such as ACTION, SUNSET, or PARTY)
+     * as it wishes. The camera device scene mode 3A settings are provided by
+     * android.control.sceneModeOverrides.</p>
+     * <p>When set to OFF_KEEP_STATE, it is similar to OFF mode, the only difference
+     * is that this frame will not be used by camera device background 3A statistics
+     * update, as if this frame is never captured. This mode can be used in the scenario
+     * where the application doesn't want a 3A manual control capture to affect
+     * the subsequent auto 3A capture results.</p>
+     *
+     * @see CaptureRequest#CONTROL_AF_MODE
      * @see #CONTROL_MODE_OFF
      * @see #CONTROL_MODE_AUTO
      * @see #CONTROL_MODE_USE_SCENE_MODE
+     * @see #CONTROL_MODE_OFF_KEEP_STATE
      */
     public static final Key<Integer> CONTROL_MODE =
             new Key<Integer>("android.control.mode", int.class);
 
     /**
-     * <p>
-     * Operation mode for edge
-     * enhancement
-     * </p>
+     * <p>Operation mode for edge
+     * enhancement.</p>
+     * <p>Edge/sharpness/detail enhancement. OFF means no
+     * enhancement will be applied by the camera device.</p>
+     * <p>This must be set to one of the modes listed in {@link CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES android.edge.availableEdgeModes}.</p>
+     * <p>FAST/HIGH_QUALITY both mean camera device determined enhancement
+     * will be applied. HIGH_QUALITY mode indicates that the
+     * camera device will use the highest-quality enhancement algorithms,
+     * even if it slows down capture rate. FAST means the camera device will
+     * not slow down capture rate when applying edge enhancement.</p>
+     *
+     * @see CameraCharacteristics#EDGE_AVAILABLE_EDGE_MODES
      * @see #EDGE_MODE_OFF
      * @see #EDGE_MODE_FAST
      * @see #EDGE_MODE_HIGH_QUALITY
@@ -403,9 +1126,25 @@
             new Key<Integer>("android.edge.mode", int.class);
 
     /**
-     * <p>
-     * Select flash operation mode
-     * </p>
+     * <p>The desired mode for for the camera device's flash control.</p>
+     * <p>This control is only effective when flash unit is available
+     * (<code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} == true</code>).</p>
+     * <p>When this control is used, the {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} must be set to ON or OFF.
+     * Otherwise, the camera device auto-exposure related flash control (ON_AUTO_FLASH,
+     * ON_ALWAYS_FLASH, or ON_AUTO_FLASH_REDEYE) will override this control.</p>
+     * <p>When set to OFF, the camera device will not fire flash for this capture.</p>
+     * <p>When set to SINGLE, the camera device will fire flash regardless of the camera
+     * device's auto-exposure routine's result. When used in still capture case, this
+     * control should be used along with AE precapture metering sequence
+     * ({@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}), otherwise, the image may be incorrectly exposed.</p>
+     * <p>When set to TORCH, the flash will be on continuously. This mode can be used
+     * for use cases such as preview, auto-focus assist, still capture, or video recording.</p>
+     * <p>The flash status will be reported by {@link CaptureResult#FLASH_STATE android.flash.state} in the capture result metadata.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
+     * @see CaptureResult#FLASH_STATE
      * @see #FLASH_MODE_OFF
      * @see #FLASH_MODE_SINGLE
      * @see #FLASH_MODE_TORCH
@@ -414,10 +1153,13 @@
             new Key<Integer>("android.flash.mode", int.class);
 
     /**
-     * <p>
-     * Current state of the flash
-     * unit
-     * </p>
+     * <p>Current state of the flash
+     * unit.</p>
+     * <p>When the camera device doesn't have flash unit
+     * (i.e. <code>{@link CameraCharacteristics#FLASH_INFO_AVAILABLE android.flash.info.available} == false</code>), this state will always be UNAVAILABLE.
+     * Other states indicate the current flash status.</p>
+     *
+     * @see CameraCharacteristics#FLASH_INFO_AVAILABLE
      * @see #FLASH_STATE_UNAVAILABLE
      * @see #FLASH_STATE_CHARGING
      * @see #FLASH_STATE_READY
@@ -427,140 +1169,171 @@
             new Key<Integer>("android.flash.state", int.class);
 
     /**
-     * <p>
-     * GPS coordinates to include in output JPEG
-     * EXIF
-     * </p>
+     * <p>Set operational mode for hot pixel correction.</p>
+     * <p>Valid modes for this camera device are listed in
+     * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}.</p>
+     * <p>Hotpixel correction interpolates out, or otherwise removes, pixels
+     * that do not accurately encode the incoming light (i.e. pixels that
+     * are stuck at an arbitrary value).</p>
+     *
+     * @see CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES
+     * @see #HOT_PIXEL_MODE_OFF
+     * @see #HOT_PIXEL_MODE_FAST
+     * @see #HOT_PIXEL_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> HOT_PIXEL_MODE =
+            new Key<Integer>("android.hotPixel.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>
+     * <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>
+     * <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>
+     * <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>
+     * <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>
+     * <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>
+     * <p>Resolution of embedded JPEG thumbnail</p>
+     * <p>When set to (0, 0) value, the JPEG EXIF will not contain thumbnail,
+     * but the captured JPEG will still be a valid image.</p>
+     * <p>When a jpeg image capture is issued, the thumbnail size selected should have
+     * the same aspect ratio as the jpeg image.</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>
+     * <p>The ratio of lens focal length to the effective
+     * aperture diameter.</p>
+     * <p>This will only be supported on the camera devices that
+     * have variable aperture lens. The aperture value can only be
+     * one of the values listed in {@link CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES android.lens.info.availableApertures}.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is OFF,
+     * this can be set along with {@link CaptureRequest#SENSOR_EXPOSURE_TIME android.sensor.exposureTime},
+     * {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}, and {@link CaptureRequest#SENSOR_FRAME_DURATION android.sensor.frameDuration}
+     * to achieve manual exposure control.</p>
+     * <p>The requested aperture value may take several frames to reach the
+     * requested value; the camera device will report the current (intermediate)
+     * aperture size in capture result metadata while the aperture is changing.
+     * While the aperture is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p>
+     * <p>When this is supported and {@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} is one of
+     * the ON modes, this will be overridden by the camera device
+     * auto-exposure algorithm, the overridden values are then provided
+     * back to the user in the corresponding result.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES
+     * @see CaptureResult#LENS_STATE
+     * @see CaptureRequest#SENSOR_EXPOSURE_TIME
+     * @see CaptureRequest#SENSOR_FRAME_DURATION
+     * @see CaptureRequest#SENSOR_SENSITIVITY
      */
     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>
+     * <p>State of lens neutral density filter(s).</p>
+     * <p>This will not be supported on most camera devices. On devices
+     * where this is supported, this may only be set to one of the
+     * values included in {@link CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES android.lens.info.availableFilterDensities}.</p>
+     * <p>Lens filters are typically used to lower the amount of light the
+     * sensor is exposed to (measured in steps of EV). As used here, an EV
+     * step is the standard logarithmic representation, which are
+     * non-negative, and inversely proportional to the amount of light
+     * hitting the sensor.  For example, setting this to 0 would result
+     * in no reduction of the incoming light, and setting this to 2 would
+     * mean that the filter is set to reduce incoming light by two stops
+     * (allowing 1/4 of the prior amount of light to the sensor).</p>
+     * <p>It may take several frames before the lens filter density changes
+     * to the requested value. While the filter density is still changing,
+     * {@link CaptureResult#LENS_STATE android.lens.state} will be set to MOVING.</p>
+     *
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES
+     * @see CaptureResult#LENS_STATE
      */
     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>
+     * <p>The current lens focal length; used for optical zoom.</p>
+     * <p>This setting controls the physical focal length of the camera
+     * device's lens. Changing the focal length changes the field of
+     * view of the camera device, and is usually used for optical zoom.</p>
+     * <p>Like {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}, this
+     * setting won't be applied instantaneously, and it may take several
+     * frames before the lens can change to the requested focal length.
+     * While the focal length is still changing, {@link CaptureResult#LENS_STATE android.lens.state} will
+     * be set to MOVING.</p>
+     * <p>This is expected not to be supported on most devices.</p>
+     *
+     * @see CaptureRequest#LENS_APERTURE
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
+     * @see CaptureResult#LENS_STATE
      */
     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>
+     * <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>
+     * <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>
+     * <p>Sets whether the camera device uses optical image stabilization (OIS)
+     * when capturing images.</p>
+     * <p>OIS is used to compensate for motion blur due to small movements of
+     * the camera during capture. Unlike digital image stabilization, OIS makes
+     * use of mechanical elements to stabilize the camera sensor, and thus
+     * allows for longer exposure times before camera shake becomes
+     * apparent.</p>
+     * <p>This is not expected to be supported on most devices.</p>
      * @see #LENS_OPTICAL_STABILIZATION_MODE_OFF
      * @see #LENS_OPTICAL_STABILIZATION_MODE_ON
      */
@@ -568,9 +1341,35 @@
             new Key<Integer>("android.lens.opticalStabilizationMode", int.class);
 
     /**
-     * <p>
-     * Current lens status
-     * </p>
+     * <p>Current lens status.</p>
+     * <p>For lens parameters {@link CaptureRequest#LENS_FOCAL_LENGTH android.lens.focalLength}, {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance},
+     * {@link CaptureRequest#LENS_FILTER_DENSITY android.lens.filterDensity} and {@link CaptureRequest#LENS_APERTURE android.lens.aperture}, when changes are requested,
+     * they may take several frames to reach the requested values. This state indicates
+     * the current status of the lens parameters.</p>
+     * <p>When the state is STATIONARY, the lens parameters are not changing. This could be
+     * either because the parameters are all fixed, or because the lens has had enough
+     * time to reach the most recently-requested values.
+     * If all these lens parameters are not changable for a camera device, as listed below:</p>
+     * <ul>
+     * <li>Fixed focus (<code>{@link CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE android.lens.info.minimumFocusDistance} == 0</code>), which means
+     * {@link CaptureRequest#LENS_FOCUS_DISTANCE android.lens.focusDistance} parameter will always be 0.</li>
+     * <li>Fixed focal length ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_FOCAL_LENGTHS android.lens.info.availableFocalLengths} contains single value),
+     * which means the optical zoom is not supported.</li>
+     * <li>No ND filter ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES android.lens.info.availableFilterDensities} contains only 0).</li>
+     * <li>Fixed aperture ({@link CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES android.lens.info.availableApertures} contains single value).</li>
+     * </ul>
+     * <p>Then this state will always be STATIONARY.</p>
+     * <p>When the state is MOVING, it indicates that at least one of the lens parameters
+     * is changing.</p>
+     *
+     * @see CaptureRequest#LENS_APERTURE
+     * @see CaptureRequest#LENS_FILTER_DENSITY
+     * @see CaptureRequest#LENS_FOCAL_LENGTH
+     * @see CaptureRequest#LENS_FOCUS_DISTANCE
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_APERTURES
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FILTER_DENSITIES
+     * @see CameraCharacteristics#LENS_INFO_AVAILABLE_FOCAL_LENGTHS
+     * @see CameraCharacteristics#LENS_INFO_MINIMUM_FOCUS_DISTANCE
      * @see #LENS_STATE_STATIONARY
      * @see #LENS_STATE_MOVING
      */
@@ -578,10 +1377,19 @@
             new Key<Integer>("android.lens.state", int.class);
 
     /**
-     * <p>
-     * Mode of operation for the noise reduction
-     * algorithm
-     * </p>
+     * <p>Mode of operation for the noise reduction
+     * algorithm</p>
+     * <p>Noise filtering control. OFF means no noise reduction
+     * will be applied by the camera device.</p>
+     * <p>This must be set to a valid mode in
+     * {@link CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES android.noiseReduction.availableNoiseReductionModes}.</p>
+     * <p>FAST/HIGH_QUALITY both mean camera device determined noise filtering
+     * will be applied. HIGH_QUALITY mode indicates that the camera device
+     * will use the highest-quality noise filtering algorithms,
+     * even if it slows down capture rate. FAST means the camera device should not
+     * slow down capture rate when applying noise filtering.</p>
+     *
+     * @see CameraCharacteristics#NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES
      * @see #NOISE_REDUCTION_MODE_OFF
      * @see #NOISE_REDUCTION_MODE_FAST
      * @see #NOISE_REDUCTION_MODE_HIGH_QUALITY
@@ -590,14 +1398,11 @@
             new Key<Integer>("android.noiseReduction.mode", int.class);
 
     /**
-     * <p>
-     * Whether a result given to the framework is the
+     * <p>Whether a result given to the framework is the
      * final one for the capture, or only a partial that contains a
      * subset of the full set of dynamic metadata
-     * values.
-     * </p>
-     * <p>
-     * The entries in the result metadata buffers for a
+     * values.</p>
+     * <p>The entries in the result metadata buffers for a
      * single capture may not overlap, except for this entry. The
      * FINAL buffers must retain FIFO ordering relative to the
      * requests that generate them, so the FINAL buffer for frame 3 must
@@ -605,68 +1410,64 @@
      * before the FINAL buffer for frame 4. PARTIAL buffers may be returned
      * in any order relative to other frames, but all PARTIAL buffers for a given
      * capture must arrive before the FINAL buffer for that capture. This entry may
-     * only be used by the HAL if quirks.usePartialResult is set to 1.
-     * </p>
-     *
-     * <b>Optional</b> - This value may be null on some devices.
-     *
+     * only be used by the camera device if quirks.usePartialResult is set to 1.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
      * @hide
      */
     public static final Key<Boolean> QUIRKS_PARTIAL_RESULT =
             new Key<Boolean>("android.quirks.partialResult", boolean.class);
 
     /**
-     * <p>
-     * A frame counter set by the framework. This value monotonically
+     * <p>A frame counter set by the framework. This value monotonically
      * increases with every new result (that is, each new result has a unique
-     * frameCount value).
-     * </p>
-     * <p>
-     * Reset on release()
-     * </p>
+     * frameCount value).</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
+     * <p>An application-specified ID for the current
      * request. Must be maintained unchanged in output
-     * frame
-     * </p>
-     *
+     * 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
+     * <p>Specifies the number of pipeline stages the frame went
+     * through from when it was exposed to when the final completed result
+     * was available to the framework.</p>
+     * <p>Depending on what settings are used in the request, and
+     * what streams are configured, the data may undergo less processing,
+     * and some pipeline stages skipped.</p>
+     * <p>See {@link CameraCharacteristics#REQUEST_PIPELINE_MAX_DEPTH android.request.pipelineMaxDepth} for more details.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_PIPELINE_MAX_DEPTH
+     */
+    public static final Key<Byte> REQUEST_PIPELINE_DEPTH =
+            new Key<Byte>("android.request.pipelineDepth", byte.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
+     * 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
+     * (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
+     * 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
@@ -675,100 +1476,336 @@
      * 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>
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom} ) and floor(
+     * activeArraySize.height /
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM android.scaler.availableMaxDigitalZoom}), respectively.</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_MAX_DIGITAL_ZOOM
      */
     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>
+     * <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>
      */
     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>
+     * <p>Duration from start of frame exposure to
+     * start of next frame exposure.</p>
+     * <p>The maximum frame rate that can be supported by a camera subsystem is
+     * a function of many factors:</p>
+     * <ul>
+     * <li>Requested resolutions of output image streams</li>
+     * <li>Availability of binning / skipping modes on the imager</li>
+     * <li>The bandwidth of the imager interface</li>
+     * <li>The bandwidth of the various ISP processing blocks</li>
+     * </ul>
+     * <p>Since these factors can vary greatly between different ISPs and
+     * sensors, the camera abstraction tries to represent the bandwidth
+     * restrictions with as simple a model as possible.</p>
+     * <p>The model presented has the following characteristics:</p>
+     * <ul>
+     * <li>The image sensor is always configured to output the smallest
+     * resolution possible given the application's requested output stream
+     * sizes.  The smallest resolution is defined as being at least as large
+     * as the largest requested output stream size; the camera pipeline must
+     * never digitally upsample sensor data when the crop region covers the
+     * whole sensor. In general, this means that if only small output stream
+     * resolutions are configured, the sensor can provide a higher frame
+     * rate.</li>
+     * <li>Since any request may use any or all the currently configured
+     * output streams, the sensor and ISP must be configured to support
+     * scaling a single capture to all the streams at the same time.  This
+     * means the camera pipeline must be ready to produce the largest
+     * requested output size without any delay.  Therefore, the overall
+     * frame rate of a given configured stream set is governed only by the
+     * largest requested stream resolution.</li>
+     * <li>Using more than one output stream in a request does not affect the
+     * frame duration.</li>
+     * <li>Certain format-streams may need to do additional background processing
+     * before data is consumed/produced by that stream. These processors
+     * can run concurrently to the rest of the camera pipeline, but
+     * cannot process more than 1 capture at a time.</li>
+     * </ul>
+     * <p>The necessary information for the application, given the model above,
+     * is provided via the {@link CameraCharacteristics#SCALER_AVAILABLE_MIN_FRAME_DURATIONS android.scaler.availableMinFrameDurations} field.
+     * These are used to determine the maximum frame rate / minimum frame
+     * duration that is possible for a given stream configuration.</p>
+     * <p>Specifically, the application can use the following rules to
+     * determine the minimum frame duration it can request from the camera
+     * device:</p>
+     * <ol>
+     * <li>Let the set of currently configured input/output streams
+     * be called <code>S</code>.</li>
+     * <li>Find the minimum frame durations for each stream in <code>S</code>, by
+     * looking it up in {@link CameraCharacteristics#SCALER_AVAILABLE_MIN_FRAME_DURATIONS android.scaler.availableMinFrameDurations} (with
+     * its respective size/format). Let this set of frame durations be called
+     * <code>F</code>.</li>
+     * <li>For any given request <code>R</code>, the minimum frame duration allowed
+     * for <code>R</code> is the maximum out of all values in <code>F</code>. Let the streams
+     * used in <code>R</code> be called <code>S_r</code>.</li>
+     * </ol>
+     * <p>If none of the streams in <code>S_r</code> have a stall time (listed in
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS android.scaler.availableStallDurations}), then the frame duration in
+     * <code>F</code> determines the steady state frame rate that the application will
+     * get if it uses <code>R</code> as a repeating request. Let this special kind
+     * of request be called <code>Rsimple</code>.</p>
+     * <p>A repeating request <code>Rsimple</code> can be <em>occasionally</em> interleaved
+     * by a single capture of a new request <code>Rstall</code> (which has at least
+     * one in-use stream with a non-0 stall time) and if <code>Rstall</code> has the
+     * same minimum frame duration this will not cause a frame rate loss
+     * if all buffers from the previous <code>Rstall</code> have already been
+     * delivered.</p>
+     * <p>For more details about stalling, see
+     * {@link CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS android.scaler.availableStallDurations}.</p>
+     *
+     * @see CameraCharacteristics#SCALER_AVAILABLE_MIN_FRAME_DURATIONS
+     * @see CameraCharacteristics#SCALER_AVAILABLE_STALL_DURATIONS
      */
     public static final Key<Long> SENSOR_FRAME_DURATION =
             new Key<Long>("android.sensor.frameDuration", long.class);
 
     /**
-     * <p>
-     * Gain applied to image data. Must be
+     * <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>
+     * 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>
+     * <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>
+     * <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>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * <p><b>Full capability</b> -
+     * Present on all camera devices that report being {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL} devices in the
+     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
      *
-     * <b>Optional</b> - This value may be null on some devices.
-     *
-     * <b>{@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_FULL HARDWARE_LEVEL_FULL}</b> -
-     * Present on all devices that report being FULL level hardware devices in the
-     * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL HARDWARE_LEVEL} key.
+     * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
      */
     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
+     * <p>A reference illumination source roughly matching the current scene
+     * illumination, which is used to describe the sensor color space
+     * transformations.</p>
+     * <p>The values in this tag correspond to the values defined for the
+     * EXIF LightSource tag. These illuminants are standard light sources
+     * that are often used for calibrating camera devices.</p>
+     * @see #SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT
+     * @see #SENSOR_REFERENCE_ILLUMINANT_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT_TUNGSTEN
+     * @see #SENSOR_REFERENCE_ILLUMINANT_FLASH
+     * @see #SENSOR_REFERENCE_ILLUMINANT_FINE_WEATHER
+     * @see #SENSOR_REFERENCE_ILLUMINANT_CLOUDY_WEATHER
+     * @see #SENSOR_REFERENCE_ILLUMINANT_SHADE
+     * @see #SENSOR_REFERENCE_ILLUMINANT_DAYLIGHT_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT_DAY_WHITE_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT_COOL_WHITE_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT_WHITE_FLUORESCENT
+     * @see #SENSOR_REFERENCE_ILLUMINANT_STANDARD_A
+     * @see #SENSOR_REFERENCE_ILLUMINANT_STANDARD_B
+     * @see #SENSOR_REFERENCE_ILLUMINANT_STANDARD_C
+     * @see #SENSOR_REFERENCE_ILLUMINANT_D55
+     * @see #SENSOR_REFERENCE_ILLUMINANT_D65
+     * @see #SENSOR_REFERENCE_ILLUMINANT_D75
+     * @see #SENSOR_REFERENCE_ILLUMINANT_D50
+     * @see #SENSOR_REFERENCE_ILLUMINANT_ISO_STUDIO_TUNGSTEN
+     */
+    public static final Key<Integer> SENSOR_REFERENCE_ILLUMINANT =
+            new Key<Integer>("android.sensor.referenceIlluminant", int.class);
+
+    /**
+     * <p>A per-device calibration transform matrix to be applied after the
+     * color space transform when rendering the raw image buffer.</p>
+     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a per-device calibration transform that maps colors
+     * from reference camera color space (i.e. the "golden module"
+     * colorspace) into this camera device's linear native sensor color
+     * space for the current scene illumination and white balance choice.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    public static final Key<Rational[]> SENSOR_CALIBRATION_TRANSFORM =
+            new Key<Rational[]>("android.sensor.calibrationTransform", Rational[].class);
+
+    /**
+     * <p>A matrix that transforms color values from CIE XYZ color space to
+     * reference camera color space when rendering the raw image buffer.</p>
+     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and
+     * contains a color transform matrix that maps colors from the CIE
+     * XYZ color space to the reference camera raw color space (i.e. the
+     * "golden module" colorspace) for the current scene illumination and
+     * white balance choice.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    public static final Key<Rational[]> SENSOR_COLOR_TRANSFORM =
+            new Key<Rational[]>("android.sensor.colorTransform", Rational[].class);
+
+    /**
+     * <p>A matrix that transforms white balanced camera colors to the CIE XYZ
+     * colorspace with a D50 whitepoint.</p>
+     * <p>This matrix is expressed as a 3x3 matrix in row-major-order, and contains
+     * a color transform matrix that maps a unit vector in the linear native
+     * sensor color space to the D50 whitepoint in CIE XYZ color space.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    public static final Key<Rational[]> SENSOR_FORWARD_MATRIX =
+            new Key<Rational[]>("android.sensor.forwardMatrix", Rational[].class);
+
+    /**
+     * <p>The estimated white balance at the time of capture.</p>
+     * <p>The estimated white balance encoded as the RGB values of the
+     * perfectly neutral color point in the linear native sensor color space.
+     * The order of the values is R, G, B; where R is in the lowest index.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    public static final Key<Rational[]> SENSOR_NEUTRAL_COLOR_POINT =
+            new Key<Rational[]>("android.sensor.neutralColorPoint", Rational[].class);
+
+    /**
+     * <p>A mapping containing a hue shift, saturation scale, and value scale
+     * for each pixel.</p>
+     * <p>hue_samples, saturation_samples, and value_samples are given in
+     * {@link CameraCharacteristics#SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS android.sensor.profileHueSatMapDimensions}.</p>
+     * <p>Each entry of this map contains three floats corresponding to the
+     * hue shift, saturation scale, and value scale, respectively; where the
+     * hue shift has the lowest index. The map entries are stored in the tag
+     * in nested loop order, with the value divisions in the outer loop, the
+     * hue divisions in the middle loop, and the saturation divisions in the
+     * inner loop. All zero input saturation entries are required to have a
+     * value scale factor of 1.0.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS
+     */
+    public static final Key<float[]> SENSOR_PROFILE_HUE_SAT_MAP =
+            new Key<float[]>("android.sensor.profileHueSatMap", float[].class);
+
+    /**
+     * <p>A list of x,y samples defining a tone-mapping curve for gamma adjustment.</p>
+     * <p>This tag contains a default tone curve that can be applied while
+     * processing the image as a starting point for user adjustments.
+     * The curve is specified as a list of value pairs in linear gamma.
+     * The curve is interpolated using a cubic spline.</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    public static final Key<float[]> SENSOR_PROFILE_TONE_CURVE =
+            new Key<float[]>("android.sensor.profileToneCurve", float[].class);
+
+    /**
+     * <p>The worst-case divergence between Bayer green channels.</p>
+     * <p>This value is an estimate of the worst case split between the
+     * Bayer green channels in the red and blue rows in the sensor color
+     * filter array.</p>
+     * <p>The green split is calculated as follows:</p>
+     * <ol>
+     * <li>A representative 5x5 pixel window W within the active
+     * sensor array is chosen.</li>
+     * <li>The arithmetic mean of the green channels from the red
+     * rows (mean_Gr) within W is computed.</li>
+     * <li>The arithmetic mean of the green channels from the blue
+     * rows (mean_Gb) within W is computed.</li>
+     * <li>The maximum ratio R of the two means is computed as follows:
+     * <code>R = max((mean_Gr + 1)/(mean_Gb + 1), (mean_Gb + 1)/(mean_Gr + 1))</code></li>
+     * </ol>
+     * <p>The ratio R is the green split divergence reported for this property,
+     * which represents how much the green channels differ in the mosaic
+     * pattern.  This value is typically used to determine the treatment of
+     * the green mosaic channels when demosaicing.</p>
+     * <p>The green split value can be roughly interpreted as follows:</p>
+     * <ul>
+     * <li>R &lt; 1.03 is a negligible split (&lt;3% divergence).</li>
+     * <li>1.20 &lt;= R &gt;= 1.03 will require some software
+     * correction to avoid demosaic errors (3-20% divergence).</li>
+     * <li>R &gt; 1.20 will require strong software correction to produce
+     * a usuable image (&gt;20% divergence).</li>
+     * </ul>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     */
+    public static final Key<Float> SENSOR_GREEN_SPLIT =
+            new Key<Float>("android.sensor.greenSplit", float.class);
+
+    /**
+     * <p>When enabled, the sensor sends a test pattern instead of
+     * doing a real exposure from the camera.</p>
+     * <p>When a test pattern is enabled, all manual sensor controls specified
+     * by android.sensor.* should be ignored. All other controls should
+     * work as normal.</p>
+     * <p>For example, if manual flash is enabled, flash firing should still
+     * occur (and that the test pattern remain unmodified, since the flash
+     * would not actually affect it).</p>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * @see #SENSOR_TEST_PATTERN_MODE_OFF
+     * @see #SENSOR_TEST_PATTERN_MODE_SOLID_COLOR
+     * @see #SENSOR_TEST_PATTERN_MODE_COLOR_BARS
+     * @see #SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY
+     * @see #SENSOR_TEST_PATTERN_MODE_PN9
+     * @see #SENSOR_TEST_PATTERN_MODE_CUSTOM1
+     */
+    public static final Key<Integer> SENSOR_TEST_PATTERN_MODE =
+            new Key<Integer>("android.sensor.testPatternMode", int.class);
+
+    /**
+     * <p>Quality of lens shading correction applied
+     * to the image data.</p>
+     * <p>When set to OFF mode, no lens shading correction will be applied by the
+     * camera device, and an identity lens shading map data will be provided
+     * if <code>{@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} == ON</code>. For example, for lens
+     * shading map with size specified as <code>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize} = [ 4, 3 ]</code>,
+     * the output {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} for this case will be an identity map
+     * shown below:</p>
+     * <pre><code>[ 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,   1.0, 1.0, 1.0, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.0, 1.0, 1.0, 1.0 ]
+     * </code></pre>
+     * <p>When set to other modes, lens shading correction will be applied by the
+     * camera device. Applications can request lens shading map data by setting
+     * {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE android.statistics.lensShadingMapMode} to ON, and then the camera device will provide
+     * lens shading map data in {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap}, with size specified
+     * by {@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}.</p>
+     *
+     * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
+     * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
+     * @see CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE
+     * @see #SHADING_MODE_OFF
+     * @see #SHADING_MODE_FAST
+     * @see #SHADING_MODE_HIGH_QUALITY
+     */
+    public static final Key<Integer> SHADING_MODE =
+            new Key<Integer>("android.shading.mode", 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>
+     * {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES android.statistics.info.availableFaceDetectModes}.</p>
+     *
+     * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES
      * @see #STATISTICS_FACE_DETECT_MODE_OFF
      * @see #STATISTICS_FACE_DETECT_MODE_SIMPLE
      * @see #STATISTICS_FACE_DETECT_MODE_FULL
@@ -777,129 +1814,151 @@
             new Key<Integer>("android.statistics.faceDetectMode", int.class);
 
     /**
-     * <p>
-     * List of unique IDs for detected
-     * faces
-     * </p>
-     * <p>
-     * Only available if faceDetectMode == FULL
-     * </p>
+     * <p>List of unique IDs for detected
+     * faces</p>
+     * <p>Only available if faceDetectMode == FULL</p>
+     * @hide
      */
     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>
+     * <p>List of landmarks for detected
+     * faces</p>
+     * <p>Only available if faceDetectMode == FULL</p>
+     * @hide
      */
     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>
+     * <p>List of the bounding rectangles for detected
+     * faces</p>
+     * <p>Only available if faceDetectMode != OFF</p>
+     * @hide
      */
     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>
+     * <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>
+     * @hide
      */
     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>
+     * <p>The shading map is a low-resolution floating-point map
+     * that lists the coefficients used to correct for vignetting, for each
+     * Bayer color channel.</p>
+     * <p>The least shaded section of the image should have a gain factor
+     * of 1; all other sections should have gains above 1.</p>
+     * <p>When {@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} = TRANSFORM_MATRIX, the map
+     * must take into account the colorCorrection settings.</p>
+     * <p>The shading map is for the entire active pixel array, and is not
+     * affected by the crop region specified in the request. Each shading map
+     * entry is the value of the shading compensation map over a specific
+     * pixel on the sensor.  Specifically, with a (N x M) resolution shading
+     * map, and an active pixel array size (W x H), shading map entry
+     * (x,y) ϵ (0 ... N-1, 0 ... M-1) is the value of the shading map at
+     * pixel ( ((W-1)/(N-1)) * x, ((H-1)/(M-1)) * y) for the four color channels.
+     * The map is assumed to be bilinearly interpolated between the sample points.</p>
+     * <p>The channel order is [R, Geven, Godd, B], where Geven is the green
+     * channel for the even rows of a Bayer pattern, and Godd is the odd rows.
+     * The shading map is stored in a fully interleaved format, and its size
+     * is provided in the camera static metadata by {@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize}.</p>
+     * <p>The shading map should have on the order of 30-40 rows and columns,
+     * and must be smaller than 64x64.</p>
+     * <p>As an example, given a very small map defined as:</p>
+     * <pre><code>{@link CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE android.lens.info.shadingMapSize} = [ 4, 3 ]
+     * {@link CaptureResult#STATISTICS_LENS_SHADING_MAP android.statistics.lensShadingMap} =
+     * [ 1.3, 1.2, 1.15, 1.2,  1.2, 1.2, 1.15, 1.2,
+     * 1.1, 1.2, 1.2, 1.2,  1.3, 1.2, 1.3, 1.3,
+     * 1.2, 1.2, 1.25, 1.1,  1.1, 1.1, 1.1, 1.0,
+     * 1.0, 1.0, 1.0, 1.0,  1.2, 1.3, 1.25, 1.2,
+     * 1.3, 1.2, 1.2, 1.3,   1.2, 1.15, 1.1, 1.2,
+     * 1.2, 1.1, 1.0, 1.2,  1.3, 1.15, 1.2, 1.3 ]
+     * </code></pre>
+     * <p>The low-resolution scaling map images for each channel are
+     * (displayed using nearest-neighbor interpolation):</p>
+     * <p><img alt="Red lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/red_shading.png" />
+     * <img alt="Green (even rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_e_shading.png" />
+     * <img alt="Green (odd rows) lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/green_o_shading.png" />
+     * <img alt="Blue lens shading map" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/blue_shading.png" /></p>
+     * <p>As a visualization only, inverting the full-color map to recover an
+     * image of a gray wall (using bicubic interpolation for visual quality) as captured by the sensor gives:</p>
+     * <p><img alt="Image of a uniform white wall (inverse shading map)" src="../../../../images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png" /></p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_MODE
+     * @see CameraCharacteristics#LENS_INFO_SHADING_MAP_SIZE
+     * @see CaptureResult#STATISTICS_LENS_SHADING_MAP
      */
     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,
+     * <p>The best-fit color channel gains calculated
+     * by the camera device'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>
+     * applied to that frame.</p>
+     * <p>The 4 channel gains are defined in Bayer domain,
+     * see {@link CaptureRequest#COLOR_CORRECTION_GAINS 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>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     *
+     * @see CaptureRequest#COLOR_CORRECTION_GAINS
+     * @hide
      */
     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
+     * <p>The best-fit color transform matrix estimate
+     * calculated by the camera device's statistics units for the current
+     * output frame.</p>
+     * <p>The camera device will 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
+     * for the next frame. These are the values the camera device 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>
+     * 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>
+     * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+     * @hide
      */
     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>
+     * <p>The camera device estimated scene illumination lighting
+     * frequency.</p>
+     * <p>Many light sources, such as most fluorescent lights, flicker at a rate
+     * that depends on the local utility power standards. This flicker must be
+     * accounted for by auto-exposure routines to avoid artifacts in captured images.
+     * The camera device uses this entry to tell the application what the scene
+     * illuminant frequency is.</p>
+     * <p>When manual exposure control is enabled
+     * (<code>{@link CaptureRequest#CONTROL_AE_MODE android.control.aeMode} == OFF</code> or <code>{@link CaptureRequest#CONTROL_MODE android.control.mode} == OFF</code>),
+     * the {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode} doesn't do the antibanding, and the
+     * application can ensure it selects exposure times that do not cause banding
+     * issues by looking into this metadata field. See {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE android.control.aeAntibandingMode}
+     * for more details.</p>
+     * <p>Report NONE if there doesn't appear to be flickering illumination.</p>
+     *
+     * @see CaptureRequest#CONTROL_AE_ANTIBANDING_MODE
+     * @see CaptureRequest#CONTROL_AE_MODE
+     * @see CaptureRequest#CONTROL_MODE
      * @see #STATISTICS_SCENE_FLICKER_NONE
      * @see #STATISTICS_SCENE_FLICKER_50HZ
      * @see #STATISTICS_SCENE_FLICKER_60HZ
@@ -908,61 +1967,137 @@
             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>
+     * <p>Operating mode for hotpixel map generation.</p>
+     * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
+     * If set to OFF, no hotpixel map should be returned.</p>
+     * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+     * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
+     */
+    public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
+            new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
+
+    /**
+     * <p>List of <code>(x, y)</code> coordinates of hot/defective pixels on the sensor.</p>
+     * <p>A coordinate <code>(x, y)</code> must lie between <code>(0, 0)</code>, and
+     * <code>(width - 1, height - 1)</code> (inclusive), which are the top-left and
+     * bottom-right of the pixel array, respectively. The width and
+     * height dimensions are given in {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.
+     * This may include hot pixels that lie outside of the active array
+     * bounds given by {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+     */
+    public static final Key<int[]> STATISTICS_HOT_PIXEL_MAP =
+            new Key<int[]>("android.statistics.hotPixelMap", int[].class);
+
+    /**
+     * <p>Tonemapping / contrast / gamma curve for the blue
+     * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     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>
+     * <p>Tonemapping / contrast / gamma curve for the green
+     * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>See {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} for more details.</p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      */
     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>
+     * <p>Tonemapping / contrast / gamma curve for the red
+     * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>Each channel's curve is defined by an array of control points:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} =
+     * [ P0in, P0out, P1in, P1out, P2in, P2out, P3in, P3out, ..., PNin, PNout ]
+     * 2 &lt;= N &lt;= {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}</code></pre>
+     * <p>These are sorted in order of increasing <code>Pin</code>; it is always
+     * guaranteed that input values 0.0 and 1.0 are included in the list to
+     * define a complete mapping. For input values between control points,
+     * the camera device must linearly interpolate between the control
+     * points.</p>
+     * <p>Each curve can have an independent number of points, and the number
+     * of points can be less than max (that is, the request doesn't have to
+     * always provide a curve with number of points equivalent to
+     * {@link CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS android.tonemap.maxCurvePoints}).</p>
+     * <p>A few examples, and their corresponding graphical mappings; these
+     * only specify the red channel and the precision is limited to 4
+     * digits, for conciseness.</p>
+     * <p>Linear mapping:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 0, 1.0, 1.0 ]
+     * </code></pre>
+     * <p><img alt="Linear mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png" /></p>
+     * <p>Invert mapping:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [ 0, 1.0, 1.0, 0 ]
+     * </code></pre>
+     * <p><img alt="Inverting mapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png" /></p>
+     * <p>Gamma 1/2.2 mapping, with 16 control points:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+     * 0.0000, 0.0000, 0.0667, 0.2920, 0.1333, 0.4002, 0.2000, 0.4812,
+     * 0.2667, 0.5484, 0.3333, 0.6069, 0.4000, 0.6594, 0.4667, 0.7072,
+     * 0.5333, 0.7515, 0.6000, 0.7928, 0.6667, 0.8317, 0.7333, 0.8685,
+     * 0.8000, 0.9035, 0.8667, 0.9370, 0.9333, 0.9691, 1.0000, 1.0000 ]
+     * </code></pre>
+     * <p><img alt="Gamma = 1/2.2 tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png" /></p>
+     * <p>Standard sRGB gamma mapping, per IEC 61966-2-1:1999, with 16 control points:</p>
+     * <pre><code>{@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed} = [
+     * 0.0000, 0.0000, 0.0667, 0.2864, 0.1333, 0.4007, 0.2000, 0.4845,
+     * 0.2667, 0.5532, 0.3333, 0.6125, 0.4000, 0.6652, 0.4667, 0.7130,
+     * 0.5333, 0.7569, 0.6000, 0.7977, 0.6667, 0.8360, 0.7333, 0.8721,
+     * 0.8000, 0.9063, 0.8667, 0.9389, 0.9333, 0.9701, 1.0000, 1.0000 ]
+     * </code></pre>
+     * <p><img alt="sRGB tonemapping curve" src="../../../../images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png" /></p>
+     *
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CameraCharacteristics#TONEMAP_MAX_CURVE_POINTS
+     * @see CaptureRequest#TONEMAP_MODE
      */
     public static final Key<float[]> TONEMAP_CURVE_RED =
             new Key<float[]>("android.tonemap.curveRed", float[].class);
 
     /**
+     * <p>High-level global contrast/gamma/tonemapping control.</p>
+     * <p>When switching to an application-defined contrast curve by setting
+     * {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} to CONTRAST_CURVE, the curve is defined
+     * per-channel with a set of <code>(in, out)</code> points that specify the
+     * mapping from input high-bit-depth pixel value to the output
+     * low-bit-depth value.  Since the actual pixel ranges of both input
+     * and output may change depending on the camera pipeline, the values
+     * are specified by normalized floating-point numbers.</p>
+     * <p>More-complex color mapping operations such as 3D color look-up
+     * tables, selective chroma enhancement, or other non-linear color
+     * transforms will be disabled when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
+     * CONTRAST_CURVE.</p>
+     * <p>This must be set to a valid mode in
+     * {@link CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES android.tonemap.availableToneMapModes}.</p>
+     * <p>When using either FAST or HIGH_QUALITY, the camera device will
+     * emit its own tonemap curve in {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed},
+     * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}, and {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}.
+     * These values are always available, and as close as possible to the
+     * actually used nonlinear/nonglobal transforms.</p>
+     * <p>If a request is sent with TRANSFORM_MATRIX with the camera device's
+     * provided curve in FAST or HIGH_QUALITY, the image's tonemap will be
+     * roughly the same.</p>
+     *
+     * @see CameraCharacteristics#TONEMAP_AVAILABLE_TONE_MAP_MODES
+     * @see CaptureRequest#TONEMAP_CURVE_BLUE
+     * @see CaptureRequest#TONEMAP_CURVE_GREEN
+     * @see CaptureRequest#TONEMAP_CURVE_RED
+     * @see CaptureRequest#TONEMAP_MODE
      * @see #TONEMAP_MODE_CONTRAST_CURVE
      * @see #TONEMAP_MODE_FAST
      * @see #TONEMAP_MODE_HIGH_QUALITY
@@ -971,53 +2106,95 @@
             new Key<Integer>("android.tonemap.mode", int.class);
 
     /**
-     * <p>
-     * This LED is nominally used to indicate to the user
+     * <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>
-     *
+     * any untrusted applications.</p>
+     * <p>In particular, the LED <em>must</em> always be on when the data could be
+     * transmitted off the device. The LED <em>should</em> always be on whenever
+     * data is stored locally on the device.</p>
+     * <p>The LED <em>may</em> 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>
+     * <p>Whether black-level compensation is locked
+     * to its current values, or is free to vary.</p>
+     * <p>Whether the black level offset was locked for this frame.  Should be
+     * ON if {@link CaptureRequest#BLACK_LEVEL_LOCK android.blackLevel.lock} was ON in the capture request, unless
+     * a change in other capture settings forced the camera device to
+     * perform a black level reset.</p>
+     *
+     * @see CaptureRequest#BLACK_LEVEL_LOCK
      */
     public static final Key<Boolean> BLACK_LEVEL_LOCK =
             new Key<Boolean>("android.blackLevel.lock", boolean.class);
 
+    /**
+     * <p>The frame number corresponding to the last request
+     * with which the output result (metadata + buffers) has been fully
+     * synchronized.</p>
+     * <p>When a request is submitted to the camera device, there is usually a
+     * delay of several frames before the controls get applied. A camera
+     * device may either choose to account for this delay by implementing a
+     * pipeline and carefully submit well-timed atomic control updates, or
+     * it may start streaming control changes that span over several frame
+     * boundaries.</p>
+     * <p>In the latter case, whenever a request's settings change relative to
+     * the previous submitted request, the full set of changes may take
+     * multiple frame durations to fully take effect. Some settings may
+     * take effect sooner (in less frame durations) than others.</p>
+     * <p>While a set of control changes are being propagated, this value
+     * will be CONVERGING.</p>
+     * <p>Once it is fully known that a set of control changes have been
+     * finished propagating, and the resulting updated control settings
+     * have been read back by the camera device, this value will be set
+     * to a non-negative frame number (corresponding to the request to
+     * which the results have synchronized to).</p>
+     * <p>Older camera device implementations may not have a way to detect
+     * when all camera controls have been applied, and will always set this
+     * value to UNKNOWN.</p>
+     * <p>FULL capability devices will always have this value set to the
+     * frame number of the request corresponding to this result.</p>
+     * <p><em>Further details</em>:</p>
+     * <ul>
+     * <li>Whenever a request differs from the last request, any future
+     * results not yet returned may have this value set to CONVERGING (this
+     * could include any in-progress captures not yet returned by the camera
+     * device, for more details see pipeline considerations below).</li>
+     * <li>Submitting a series of multiple requests that differ from the
+     * previous request (e.g. r1, r2, r3 s.t. r1 != r2 != r3)
+     * moves the new synchronization frame to the last non-repeating
+     * request (using the smallest frame number from the contiguous list of
+     * repeating requests).</li>
+     * <li>Submitting the same request repeatedly will not change this value
+     * to CONVERGING, if it was already a non-negative value.</li>
+     * <li>When this value changes to non-negative, that means that all of the
+     * metadata controls from the request have been applied, all of the
+     * metadata controls from the camera device have been read to the
+     * updated values (into the result), and all of the graphics buffers
+     * corresponding to this result are also synchronized to the request.</li>
+     * </ul>
+     * <p><em>Pipeline considerations</em>:</p>
+     * <p>Submitting a request with updated controls relative to the previously
+     * submitted requests may also invalidate the synchronization state
+     * of all the results corresponding to currently in-flight requests.</p>
+     * <p>In other words, results for this current request and up to
+     * {@link CameraCharacteristics#REQUEST_PIPELINE_MAX_DEPTH android.request.pipelineMaxDepth} prior requests may have their
+     * android.sync.frameNumber change to CONVERGING.</p>
+     *
+     * @see CameraCharacteristics#REQUEST_PIPELINE_MAX_DEPTH
+     * @see #SYNC_FRAME_NUMBER_CONVERGING
+     * @see #SYNC_FRAME_NUMBER_UNKNOWN
+     * @hide
+     */
+    public static final Key<Integer> SYNC_FRAME_NUMBER =
+            new Key<Integer>("android.sync.frameNumber", int.class);
+
     /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
      * End generated code
      *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/camera2/impl/CameraDevice.java b/core/java/android/hardware/camera2/impl/CameraDevice.java
index 40586f0..2c8a5c2 100644
--- a/core/java/android/hardware/camera2/impl/CameraDevice.java
+++ b/core/java/android/hardware/camera2/impl/CameraDevice.java
@@ -106,9 +106,7 @@
 
     private final Runnable mCallOnClosed = new Runnable() {
         public void run() {
-            if (!CameraDevice.this.isClosed()) {
-                mDeviceListener.onClosed(CameraDevice.this);
-            }
+            mDeviceListener.onClosed(CameraDevice.this);
         }
     };
 
@@ -351,8 +349,7 @@
         }
     }
 
-    @Override
-    public void waitUntilIdle() throws CameraAccessException {
+    private void waitUntilIdle() throws CameraAccessException {
 
         synchronized (mLock) {
             checkIfCameraClosed();
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 072c5bb..0d4a4cb 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -105,6 +105,18 @@
     }
 
     /**
+     * Set the global client-side vendor tag descriptor to allow use of vendor
+     * tags in camera applications.
+     *
+     * @return int A native status_t value corresponding to one of the
+     * {@link CameraBinderDecorator} integer constants.
+     * @see CameraBinderDecorator#throwOnError
+     *
+     * @hide
+     */
+    public static native int nativeSetupGlobalVendorTagDescriptor();
+
+    /**
      * Set a camera metadata field to a value. The field definitions can be
      * found in {@link CameraCharacteristics}, {@link CaptureResult}, and
      * {@link CaptureRequest}.
@@ -448,7 +460,7 @@
         } else if (key.equals(CaptureResult.STATISTICS_FACES)) {
             return (T) getFaces();
         } else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
-            return (T) fixFaceRectangles();
+            return (T) getFaceRectangles();
         }
 
         // For other keys, get() falls back to getBase()
@@ -457,12 +469,15 @@
 
     private int[] getAvailableFormats() {
         int[] availableFormats = getBase(CameraCharacteristics.SCALER_AVAILABLE_FORMATS);
-        for (int i = 0; i < availableFormats.length; i++) {
-            // JPEG has different value between native and managed side, need override.
-            if (availableFormats[i] == NATIVE_JPEG_FORMAT) {
-                availableFormats[i] = ImageFormat.JPEG;
+        if (availableFormats != null) {
+            for (int i = 0; i < availableFormats.length; i++) {
+                // JPEG has different value between native and managed side, need override.
+                if (availableFormats[i] == NATIVE_JPEG_FORMAT) {
+                    availableFormats[i] = ImageFormat.JPEG;
+                }
             }
         }
+
         return availableFormats;
     }
 
@@ -550,7 +565,7 @@
     // (left, top, width, height) at the native level, so the normal Rect
     // conversion that does (l, t, w, h) -> (l, t, r, b) is unnecessary. Undo
     // that conversion here for just the faces.
-    private Rect[] fixFaceRectangles() {
+    private Rect[] getFaceRectangles() {
         Rect[] faceRectangles = getBase(CaptureResult.STATISTICS_FACE_RECTANGLES);
         if (faceRectangles == null) return null;
 
@@ -590,6 +605,8 @@
     private <T> boolean setOverride(Key<T> key, T value) {
         if (key.equals(CameraCharacteristics.SCALER_AVAILABLE_FORMATS)) {
             return setAvailableFormats((int[]) value);
+        } else if (key.equals(CaptureResult.STATISTICS_FACE_RECTANGLES)) {
+            return setFaceRectangles((Rect[]) value);
         }
 
         // For other keys, set() falls back to setBase().
@@ -615,6 +632,36 @@
         return true;
     }
 
+    /**
+     * Convert Face Rectangles from managed side to native side as they have different definitions.
+     * <p>
+     * Managed side face rectangles are defined as: left, top, width, height.
+     * Native side face rectangles are defined as: left, top, right, bottom.
+     * The input face rectangle need to be converted to native side definition when set is called.
+     * </p>
+     *
+     * @param faceRects Input face rectangles.
+     * @return true if face rectangles can be set successfully. Otherwise, Let the caller
+     *             (setBase) to handle it appropriately.
+     */
+    private boolean setFaceRectangles(Rect[] faceRects) {
+        if (faceRects == null) {
+            return false;
+        }
+
+        Rect[] newFaceRects = new Rect[faceRects.length];
+        for (int i = 0; i < newFaceRects.length; i++) {
+            newFaceRects[i] = new Rect(
+                    faceRects[i].left,
+                    faceRects[i].top,
+                    faceRects[i].right + faceRects[i].left,
+                    faceRects[i].bottom + faceRects[i].top);
+        }
+
+        setBase(CaptureResult.STATISTICS_FACE_RECTANGLES, newFaceRects);
+        return true;
+    }
+
     private long mMetadataPtr; // native CameraMetadata*
 
     private native long nativeAllocate();
diff --git a/core/java/android/hardware/camera2/package.html b/core/java/android/hardware/camera2/package.html
index c619984..9f6c2a9 100644
--- a/core/java/android/hardware/camera2/package.html
+++ b/core/java/android/hardware/camera2/package.html
@@ -80,7 +80,5 @@
 asynchronously relative to the output CaptureResult, sometimes
 substantially later.</p>
 
-{@hide}
-
 </BODY>
 </HTML>
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index e535e00..328ccbe 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -64,47 +64,7 @@
             // 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 EUSERS:
-                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
-                                MAX_CAMERAS_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));
-                }
+                throwOnError(returnValue);
             }
         }
 
@@ -131,6 +91,54 @@
     }
 
     /**
+     * Throw error codes returned by the camera service as exceptions.
+     *
+     * @param errorFlag error to throw as an exception.
+     */
+    public static void throwOnError(int errorFlag) {
+        switch (errorFlag) {
+            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 EUSERS:
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        MAX_CAMERAS_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 (errorFlag < 0) {
+            throw new UnsupportedOperationException(String.format("Unknown error %d",
+                    errorFlag));
+        }
+    }
+
+    /**
      * <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
diff --git a/core/java/android/hardware/display/WifiDisplayStatus.java b/core/java/android/hardware/display/WifiDisplayStatus.java
index 5216727..b645662 100644
--- a/core/java/android/hardware/display/WifiDisplayStatus.java
+++ b/core/java/android/hardware/display/WifiDisplayStatus.java
@@ -20,8 +20,6 @@
 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
diff --git a/core/java/android/hardware/input/IInputManager.aidl b/core/java/android/hardware/input/IInputManager.aidl
index f1e7e98..465d142 100644
--- a/core/java/android/hardware/input/IInputManager.aidl
+++ b/core/java/android/hardware/input/IInputManager.aidl
@@ -19,6 +19,7 @@
 import android.hardware.input.InputDeviceIdentifier;
 import android.hardware.input.KeyboardLayout;
 import android.hardware.input.IInputDevicesChangedListener;
+import android.hardware.input.TouchCalibration;
 import android.os.IBinder;
 import android.view.InputDevice;
 import android.view.InputEvent;
@@ -39,6 +40,11 @@
     // applications, the caller must have the INJECT_EVENTS permission.
     boolean injectInputEvent(in InputEvent ev, int mode);
 
+    // Calibrate input device position
+    TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation);
+    void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int rotation,
+            in TouchCalibration calibration);
+
     // Keyboard layouts configuration.
     KeyboardLayout[] getKeyboardLayouts();
     KeyboardLayout getKeyboardLayout(String keyboardLayoutDescriptor);
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index a2aeafb..0c0dfe9 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -500,6 +500,45 @@
     }
 
     /**
+     * Gets the TouchCalibration applied to the specified input device's coordinates.
+     *
+     * @param inputDeviceDescriptor The input device descriptor.
+     * @return The TouchCalibration currently assigned for use with the given
+     * input device. If none is set, an identity TouchCalibration is returned.
+     *
+     * @hide
+     */
+    public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) {
+        try {
+            return mIm.getTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not get calibration matrix for input device.", ex);
+            return TouchCalibration.IDENTITY;
+        }
+    }
+
+    /**
+     * Sets the TouchCalibration to apply to the specified input device's coordinates.
+     * <p>
+     * This method may have the side-effect of causing the input device in question
+     * to be reconfigured. Requires {@link android.Manifest.permissions.SET_INPUT_CALIBRATION}.
+     * </p>
+     *
+     * @param inputDeviceDescriptor The input device descriptor.
+     * @param calibration The calibration to be applied
+     *
+     * @hide
+     */
+    public void setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation,
+            TouchCalibration calibration) {
+        try {
+            mIm.setTouchCalibrationForInputDevice(inputDeviceDescriptor, surfaceRotation, calibration);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Could not set calibration matrix for input device.", ex);
+        }
+    }
+
+    /**
      * Gets the mouse pointer speed.
      * <p>
      * Only returns the permanent mouse pointer speed.  Ignores any temporary pointer
@@ -814,13 +853,21 @@
             return true;
         }
 
+        /**
+         * @hide
+         */
         @Override
-        public void vibrate(long milliseconds) {
+        public void vibrate(int owningUid, String owningPackage, long milliseconds,
+                int streamHint) {
             vibrate(new long[] { 0, milliseconds}, -1);
         }
 
+        /**
+         * @hide
+         */
         @Override
-        public void vibrate(long[] pattern, int repeat) {
+        public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat,
+                int streamHint) {
             if (repeat >= pattern.length) {
                 throw new ArrayIndexOutOfBoundsException();
             }
@@ -831,22 +878,6 @@
             }
         }
 
-        /**
-         * @hide
-         */
-        @Override
-        public void vibrate(int owningUid, String owningPackage, long milliseconds) {
-            vibrate(milliseconds);
-        }
-
-        /**
-         * @hide
-         */
-        @Override
-        public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
-            vibrate(pattern, repeat);
-        }
-
         @Override
         public void cancel() {
             try {
diff --git a/core/java/android/hardware/input/TouchCalibration.aidl b/core/java/android/hardware/input/TouchCalibration.aidl
new file mode 100644
index 0000000..2c28774
--- /dev/null
+++ b/core/java/android/hardware/input/TouchCalibration.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+parcelable TouchCalibration;
diff --git a/core/java/android/hardware/input/TouchCalibration.java b/core/java/android/hardware/input/TouchCalibration.java
new file mode 100644
index 0000000..025fad0
--- /dev/null
+++ b/core/java/android/hardware/input/TouchCalibration.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.input;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Encapsulates calibration data for input devices.
+ *
+ * @hide
+ */
+public class TouchCalibration implements Parcelable {
+
+    public static final TouchCalibration IDENTITY = new TouchCalibration();
+
+    public static final Parcelable.Creator<TouchCalibration> CREATOR
+            = new Parcelable.Creator<TouchCalibration>() {
+        public TouchCalibration createFromParcel(Parcel in) {
+            return new TouchCalibration(in);
+        }
+
+        public TouchCalibration[] newArray(int size) {
+            return new TouchCalibration[size];
+        }
+    };
+
+    private final float mXScale, mXYMix, mXOffset;
+    private final float mYXMix, mYScale, mYOffset;
+
+    /**
+     * Create a new TouchCalibration initialized to the identity transformation.
+     */
+    public TouchCalibration() {
+        this(1,0,0,0,1,0);
+    }
+
+    /**
+     * Create a new TouchCalibration from affine transformation paramters.
+     * @param xScale   Influence of input x-axis value on output x-axis value.
+     * @param xyMix    Influence of input y-axis value on output x-axis value.
+     * @param xOffset  Constant offset to be applied to output x-axis value.
+     * @param yXMix    Influence of input x-axis value on output y-axis value.
+     * @param yScale   Influence of input y-axis value on output y-axis value.
+     * @param yOffset  Constant offset to be applied to output y-axis value.
+     */
+    public TouchCalibration(float xScale, float xyMix, float xOffset,
+            float yxMix, float yScale, float yOffset) {
+        mXScale  = xScale;
+        mXYMix   = xyMix;
+        mXOffset = xOffset;
+        mYXMix   = yxMix;
+        mYScale  = yScale;
+        mYOffset = yOffset;
+    }
+
+    public TouchCalibration(Parcel in) {
+        mXScale  = in.readFloat();
+        mXYMix   = in.readFloat();
+        mXOffset = in.readFloat();
+        mYXMix   = in.readFloat();
+        mYScale  = in.readFloat();
+        mYOffset = in.readFloat();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeFloat(mXScale);
+        dest.writeFloat(mXYMix);
+        dest.writeFloat(mXOffset);
+        dest.writeFloat(mYXMix);
+        dest.writeFloat(mYScale);
+        dest.writeFloat(mYOffset);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public float[] getAffineTransform() {
+        return new float[] { mXScale, mXYMix, mXOffset, mYXMix, mYScale, mYOffset };
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        } else if (obj instanceof TouchCalibration) {
+            TouchCalibration cal = (TouchCalibration)obj;
+
+            return (cal.mXScale  == mXScale)  &&
+                   (cal.mXYMix   == mXYMix)   &&
+                   (cal.mXOffset == mXOffset) &&
+                   (cal.mYXMix   == mYXMix)   &&
+                   (cal.mYScale  == mYScale)  &&
+                   (cal.mYOffset == mYOffset);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return Float.floatToIntBits(mXScale)  ^
+               Float.floatToIntBits(mXYMix)   ^
+               Float.floatToIntBits(mXOffset) ^
+               Float.floatToIntBits(mYXMix)   ^
+               Float.floatToIntBits(mYScale)  ^
+               Float.floatToIntBits(mYOffset);
+    }
+}
diff --git a/core/java/android/hardware/location/GeofenceHardwareRequest.java b/core/java/android/hardware/location/GeofenceHardwareRequest.java
index 6e7b592..796d7f8 100644
--- a/core/java/android/hardware/location/GeofenceHardwareRequest.java
+++ b/core/java/android/hardware/location/GeofenceHardwareRequest.java
@@ -16,8 +16,6 @@
 
 package android.hardware.location;
 
-import android.location.Location;
-
 /**
  * This class represents the characteristics of the geofence.
  *
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
index 5719452..2f9178c 100644
--- a/core/java/android/hardware/usb/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -16,10 +16,8 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Log;
 
 /**
  * A class representing a USB accessory, which is an external hardware component
diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java
new file mode 100644
index 0000000..92d6f75
--- /dev/null
+++ b/core/java/android/hardware/usb/UsbConfiguration.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.usb;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A class representing a configuration on a {@link UsbDevice}.
+ * A USB configuration can have one or more interfaces, each one providing a different
+ * piece of functionality, separate from the other interfaces.
+ * An interface will have one or more {@link UsbEndpoint}s, which are the
+ * channels by which the host transfers data with the device.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about communicating with USB hardware, read the
+ * <a href="{@docRoot}guide/topics/usb/index.html">USB</a> developer guide.</p>
+ * </div>
+ */
+public class UsbConfiguration implements Parcelable {
+
+    private final int mId;
+    private final String mName;
+    private final int mAttributes;
+    private final int mMaxPower;
+    private Parcelable[] mInterfaces;
+
+    /**
+     * Mask for "self-powered" bit in the configuration's attributes.
+     * @see #getAttributes
+     */
+    public static final int ATTR_SELF_POWERED_MASK = 1 << 6;
+
+    /**
+     * Mask for "remote wakeup" bit in the configuration's attributes.
+     * @see #getAttributes
+     */
+    public static final int ATTR_REMOTE_WAKEUP_MASK = 1 << 5;
+
+    /**
+     * UsbConfiguration should only be instantiated by UsbService implementation
+     * @hide
+     */
+    public UsbConfiguration(int id, String name, int attributes, int maxPower) {
+        mId = id;
+        mName = name;
+        mAttributes = attributes;
+        mMaxPower = maxPower;
+    }
+
+    /**
+     * Returns the configuration's ID field.
+     * This is an integer that uniquely identifies the configuration on the device.
+     *
+     * @return the configuration's ID
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Returns the configuration's name.
+     *
+     * @return the configuration's name
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * Returns the configuration's attributes field.
+     * This field contains a bit field with the following flags:
+     *
+     * Bit 7: always set to 1
+     * Bit 6: self-powered
+     * Bit 5: remote wakeup enabled
+     * Bit 0-4: reserved
+     * @see #ATTR_SELF_POWERED_MASK
+     * @see #ATTR_REMOTE_WAKEUP_MASK
+     * @return the configuration's attributes
+     */
+    public int getAttributes() {
+        return mAttributes;
+    }
+
+    /**
+     * Returns the configuration's max power consumption, in milliamps.
+     *
+     * @return the configuration's max power
+     */
+    public int getMaxPower() {
+        return mMaxPower * 2;
+    }
+
+    /**
+     * Returns the number of {@link UsbInterface}s this configuration contains.
+     *
+     * @return the number of endpoints
+     */
+    public int getInterfaceCount() {
+        return mInterfaces.length;
+    }
+
+    /**
+     * Returns the {@link UsbInterface} at the given index.
+     *
+     * @return the interface
+     */
+    public UsbInterface getInterface(int index) {
+        return (UsbInterface)mInterfaces[index];
+    }
+
+    /**
+     * Only used by UsbService implementation
+     * @hide
+     */
+    public void setInterfaces(Parcelable[] interfaces) {
+        mInterfaces = interfaces;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder("UsbConfiguration[mId=" + mId +
+                ",mName=" + mName + ",mAttributes=" + mAttributes +
+                ",mMaxPower=" + mMaxPower + ",mInterfaces=[");
+        for (int i = 0; i < mInterfaces.length; i++) {
+            builder.append("\n");
+            builder.append(mInterfaces[i].toString());
+        }
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public static final Parcelable.Creator<UsbConfiguration> CREATOR =
+        new Parcelable.Creator<UsbConfiguration>() {
+        public UsbConfiguration createFromParcel(Parcel in) {
+            int id = in.readInt();
+            String name = in.readString();
+            int attributes = in.readInt();
+            int maxPower = in.readInt();
+            Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader());
+            UsbConfiguration configuration = new UsbConfiguration(id, name, attributes, maxPower);
+            configuration.setInterfaces(interfaces);
+            return configuration;
+        }
+
+        public UsbConfiguration[] newArray(int size) {
+            return new UsbConfiguration[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mId);
+        parcel.writeString(mName);
+        parcel.writeInt(mAttributes);
+        parcel.writeInt(mMaxPower);
+        parcel.writeParcelableArray(mInterfaces, 0);
+   }
+}
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index d1e63f6..d90e06e 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -16,12 +16,8 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Log;
-
-import java.io.FileDescriptor;
 
 /**
  * This class represents a USB device attached to the android device with the android device
@@ -54,7 +50,10 @@
     private final int mClass;
     private final int mSubclass;
     private final int mProtocol;
-    private final Parcelable[] mInterfaces;
+    private Parcelable[] mConfigurations;
+
+    // list of all interfaces on the device
+    private UsbInterface[] mInterfaces;
 
     /**
      * UsbDevice should only be instantiated by UsbService implementation
@@ -62,8 +61,7 @@
      */
     public UsbDevice(String name, int vendorId, int productId,
             int Class, int subClass, int protocol,
-            String manufacturerName, String productName, String serialNumber,
-            Parcelable[] interfaces) {
+            String manufacturerName, String productName, String serialNumber) {
         mName = name;
         mVendorId = vendorId;
         mProductId = productId;
@@ -73,7 +71,6 @@
         mManufacturerName = manufacturerName;
         mProductName = productName;
         mSerialNumber = serialNumber;
-        mInterfaces = interfaces;
     }
 
     /**
@@ -173,21 +170,74 @@
     }
 
     /**
+     * Returns the number of {@link UsbConfiguration}s this device contains.
+     *
+     * @return the number of configurations
+     */
+    public int getConfigurationCount() {
+        return mConfigurations.length;
+    }
+
+    /**
+     * Returns the {@link UsbConfiguration} at the given index.
+     *
+     * @return the configuration
+     */
+    public UsbConfiguration getConfiguration(int index) {
+        return (UsbConfiguration)mConfigurations[index];
+    }
+
+    private UsbInterface[] getInterfaceList() {
+        if (mInterfaces == null) {
+            int configurationCount = mConfigurations.length;
+            int interfaceCount = 0;
+            for (int i = 0; i < configurationCount; i++) {
+                UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i];
+                interfaceCount += configuration.getInterfaceCount();
+            }
+
+            mInterfaces = new UsbInterface[interfaceCount];
+            int offset = 0;
+            for (int i = 0; i < configurationCount; i++) {
+                UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i];
+                interfaceCount = configuration.getInterfaceCount();
+                for (int j = 0; j < interfaceCount; j++) {
+                    mInterfaces[offset++] = configuration.getInterface(j);
+                }
+            }
+        }
+
+        return mInterfaces;
+    }
+
+    /**
      * Returns the number of {@link UsbInterface}s this device contains.
+     * For devices with multiple configurations, you will probably want to use
+     * {@link UsbConfiguration#getInterfaceCount} instead.
      *
      * @return the number of interfaces
      */
     public int getInterfaceCount() {
-        return mInterfaces.length;
+        return getInterfaceList().length;
     }
 
     /**
      * Returns the {@link UsbInterface} at the given index.
+     * For devices with multiple configurations, you will probably want to use
+     * {@link UsbConfiguration#getInterface} instead.
      *
      * @return the interface
      */
     public UsbInterface getInterface(int index) {
-        return (UsbInterface)mInterfaces[index];
+        return getInterfaceList()[index];
+    }
+
+    /**
+     * Only used by UsbService implementation
+     * @hide
+     */
+    public void setConfigurations(Parcelable[] configuration) {
+        mConfigurations = configuration;
     }
 
     @Override
@@ -208,11 +258,17 @@
 
     @Override
     public String toString() {
-        return "UsbDevice[mName=" + mName + ",mVendorId=" + mVendorId +
-                ",mProductId=" + mProductId + ",mClass=" + mClass +
-                ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
+        StringBuilder builder = new StringBuilder("UsbDevice[mName=" + mName +
+                ",mVendorId=" + mVendorId + ",mProductId=" + mProductId +
+                ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
                 ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName +
-                ",mSerialNumber=" + mSerialNumber + ",mInterfaces=" + mInterfaces + "]";
+                ",mSerialNumber=" + mSerialNumber + ",mConfigurations=[");
+        for (int i = 0; i < mConfigurations.length; i++) {
+            builder.append("\n");
+            builder.append(mConfigurations[i].toString());
+        }
+        builder.append("]");
+        return builder.toString();
     }
 
     public static final Parcelable.Creator<UsbDevice> CREATOR =
@@ -227,9 +283,11 @@
             String manufacturerName = in.readString();
             String productName = in.readString();
             String serialNumber = in.readString();
-            Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader());
-            return new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
-                                 manufacturerName, productName, serialNumber, interfaces);
+            Parcelable[] configurations = in.readParcelableArray(UsbInterface.class.getClassLoader());
+            UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
+                                 manufacturerName, productName, serialNumber);
+            device.setConfigurations(configurations);
+            return device;
         }
 
         public UsbDevice[] newArray(int size) {
@@ -251,7 +309,7 @@
         parcel.writeString(mManufacturerName);
         parcel.writeString(mProductName);
         parcel.writeString(mSerialNumber);
-        parcel.writeParcelableArray(mInterfaces, 0);
+        parcel.writeParcelableArray(mConfigurations, 0);
    }
 
     public static int getDeviceId(String name) {
diff --git a/core/java/android/hardware/usb/UsbDeviceConnection.java b/core/java/android/hardware/usb/UsbDeviceConnection.java
index 389475f..6283951 100644
--- a/core/java/android/hardware/usb/UsbDeviceConnection.java
+++ b/core/java/android/hardware/usb/UsbDeviceConnection.java
@@ -101,6 +101,25 @@
     }
 
     /**
+     * Sets the current {@link android.hardware.usb.UsbInterface}.
+     * Used to select between two interfaces with the same ID but different alternate setting.
+     *
+     * @return true if the interface was successfully released
+     */
+    public boolean setInterface(UsbInterface intf) {
+        return native_set_interface(intf.getId(), intf.getAlternateSetting());
+    }
+
+    /**
+     * Sets the device's current {@link android.hardware.usb.UsbConfiguration}.
+     *
+     * @return true if the configuration was successfully set
+     */
+    public boolean setConfiguration(UsbConfiguration configuration) {
+        return native_set_configuration(configuration.getId());
+    }
+
+    /**
      * Performs a control transaction on endpoint zero for this device.
      * The direction of the transfer is determined by the request type.
      * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is
@@ -236,6 +255,8 @@
     private native byte[] native_get_desc();
     private native boolean native_claim_interface(int interfaceID, boolean force);
     private native boolean native_release_interface(int interfaceID);
+    private native boolean native_set_interface(int interfaceID, int alternateSetting);
+    private native boolean native_set_configuration(int configurationID);
     private native int native_control_request(int requestType, int request, int value,
             int index, byte[] buffer, int offset, int length, int timeout);
     private native int native_bulk_request(int endpoint, byte[] buffer,
diff --git a/core/java/android/hardware/usb/UsbEndpoint.java b/core/java/android/hardware/usb/UsbEndpoint.java
index 753a447..708d651 100644
--- a/core/java/android/hardware/usb/UsbEndpoint.java
+++ b/core/java/android/hardware/usb/UsbEndpoint.java
@@ -16,7 +16,6 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
diff --git a/core/java/android/hardware/usb/UsbInterface.java b/core/java/android/hardware/usb/UsbInterface.java
index d6c54a8..de01a88 100644
--- a/core/java/android/hardware/usb/UsbInterface.java
+++ b/core/java/android/hardware/usb/UsbInterface.java
@@ -16,7 +16,6 @@
 
 package android.hardware.usb;
 
-import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -36,27 +35,31 @@
 public class UsbInterface implements Parcelable {
 
     private final int mId;
+    private final int mAlternateSetting;
+    private final String mName;
     private final int mClass;
     private final int mSubclass;
     private final int mProtocol;
-    private final Parcelable[] mEndpoints;
+    private Parcelable[] mEndpoints;
 
     /**
      * UsbInterface should only be instantiated by UsbService implementation
      * @hide
      */
-    public UsbInterface(int id, int Class, int subClass, int protocol,
-            Parcelable[] endpoints) {
+    public UsbInterface(int id, int alternateSetting, String name,
+            int Class, int subClass, int protocol) {
         mId = id;
+        mAlternateSetting = alternateSetting;
+        mName = name;
         mClass = Class;
         mSubclass = subClass;
         mProtocol = protocol;
-        mEndpoints = endpoints;
     }
 
     /**
-     * Returns the interface's ID field.
-     * This is an integer that uniquely identifies the interface on the device.
+     * Returns the interface's bInterfaceNumber field.
+     * This is an integer that along with the alternate setting uniquely identifies
+     * the interface on the device.
      *
      * @return the interface's ID
      */
@@ -65,6 +68,28 @@
     }
 
     /**
+     * Returns the interface's bAlternateSetting field.
+     * This is an integer that along with the ID uniquely identifies
+     * the interface on the device.
+     * {@link UsbDeviceConnection#setInterface} can be used to switch between
+     * two interfaces with the same ID but different alternate setting.
+     *
+     * @return the interface's alternate setting
+     */
+    public int getAlternateSetting() {
+        return mAlternateSetting;
+    }
+
+    /**
+     * Returns the interface's name.
+     *
+     * @return the interface's name
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
      * Returns the interface's class field.
      * Some useful constants for USB classes can be found in {@link UsbConstants}
      *
@@ -110,22 +135,42 @@
         return (UsbEndpoint)mEndpoints[index];
     }
 
+    /**
+     * Only used by UsbService implementation
+     * @hide
+     */
+    public void setEndpoints(Parcelable[] endpoints) {
+        mEndpoints = endpoints;
+    }
+
     @Override
     public String toString() {
-        return "UsbInterface[mId=" + mId + ",mClass=" + mClass +
+        StringBuilder builder = new StringBuilder("UsbInterface[mId=" + mId +
+                ",mAlternateSetting=" + mAlternateSetting +
+                ",mName=" + mName + ",mClass=" + mClass +
                 ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
-                ",mEndpoints=" + mEndpoints + "]";
+                ",mEndpoints=[");
+        for (int i = 0; i < mEndpoints.length; i++) {
+            builder.append("\n");
+            builder.append(mEndpoints[i].toString());
+        }
+        builder.append("]");
+        return builder.toString();
     }
 
     public static final Parcelable.Creator<UsbInterface> CREATOR =
         new Parcelable.Creator<UsbInterface>() {
         public UsbInterface createFromParcel(Parcel in) {
             int id = in.readInt();
+            int alternateSetting = in.readInt();
+            String name = in.readString();
             int Class = in.readInt();
             int subClass = in.readInt();
             int protocol = in.readInt();
             Parcelable[] endpoints = in.readParcelableArray(UsbEndpoint.class.getClassLoader());
-            return new UsbInterface(id, Class, subClass, protocol, endpoints);
+            UsbInterface intf = new UsbInterface(id, alternateSetting, name, Class, subClass, protocol);
+            intf.setEndpoints(endpoints);
+            return intf;
         }
 
         public UsbInterface[] newArray(int size) {
@@ -139,6 +184,8 @@
 
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mId);
+        parcel.writeInt(mAlternateSetting);
+        parcel.writeString(mName);
         parcel.writeInt(mClass);
         parcel.writeInt(mSubclass);
         parcel.writeInt(mProtocol);
diff --git a/core/java/android/inputmethodservice/ExtractButton.java b/core/java/android/inputmethodservice/ExtractButton.java
index b6b7595..fe63c1e 100644
--- a/core/java/android/inputmethodservice/ExtractButton.java
+++ b/core/java/android/inputmethodservice/ExtractButton.java
@@ -32,8 +32,12 @@
         super(context, attrs, com.android.internal.R.attr.buttonStyle);
     }
 
-    public ExtractButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ExtractButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ExtractButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
     
     /**
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index 23ae21b..48b604c 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -38,8 +38,12 @@
         super(context, attrs, com.android.internal.R.attr.editTextStyle);
     }
 
-    public ExtractEditText(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ExtractEditText(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ExtractEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
     
     void setIME(InputMethodService ime) {
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index bbea8ff..8437228 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -25,7 +25,6 @@
 import android.os.Bundle;
 import android.os.Looper;
 import android.os.Message;
-import android.os.RemoteException;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.InputChannel;
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 1b7d9ea..81ad28b 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2322,6 +2322,21 @@
     }
 
     /**
+     * @return The recommended height of the input method window.
+     * An IME author can get the last input method's height as the recommended height
+     * by calling this in
+     * {@link android.inputmethodservice.InputMethodService#onStartInputView(EditorInfo, boolean)}.
+     * If you don't need to use a predefined fixed height, you can avoid the window-resizing of IME
+     * switching by using this value as a visible inset height. It's efficient for the smooth
+     * transition between different IMEs. However, note that this may return 0 (or possibly
+     * unexpectedly low height). You should thus avoid relying on the return value of this method
+     * all the time. Please make sure to use a reasonable height for the IME.
+     */
+    public int getInputMethodWindowRecommendedHeight() {
+        return mImm.getInputMethodWindowVisibleHeight();
+    }
+
+    /**
      * Performs a dump of the InputMethodService's internal state.  Override
      * to add your own information to the dump.
      */
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 4916244..af75a0a 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -279,12 +279,15 @@
         this(context, attrs, com.android.internal.R.attr.keyboardViewStyle);
     }
 
-    public KeyboardView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public KeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, android.R.styleable.KeyboardView, defStyle, 0);
+    public KeyboardView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, android.R.styleable.KeyboardView, defStyleAttr, defStyleRes);
 
         LayoutInflater inflate =
                 (LayoutInflater) context
diff --git a/core/java/android/net/BaseNetworkStateTracker.java b/core/java/android/net/BaseNetworkStateTracker.java
index 476fefe..804f8ee 100644
--- a/core/java/android/net/BaseNetworkStateTracker.java
+++ b/core/java/android/net/BaseNetworkStateTracker.java
@@ -20,10 +20,10 @@
 import android.os.Handler;
 import android.os.Messenger;
 
-import com.android.internal.util.Preconditions;
-
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import com.android.internal.util.Preconditions;
+
 /**
  * Interface to control and observe state of a specific network, hiding
  * network-specific details from {@link ConnectivityManager}. Surfaces events
@@ -108,11 +108,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
diff --git a/core/java/android/net/CaptivePortalTracker.java b/core/java/android/net/CaptivePortalTracker.java
index d678f1e..89c17c7 100644
--- a/core/java/android/net/CaptivePortalTracker.java
+++ b/core/java/android/net/CaptivePortalTracker.java
@@ -48,7 +48,6 @@
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.Inet4Address;
-import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.net.UnknownHostException;
 import java.util.List;
@@ -84,13 +83,12 @@
     private String mServer;
     private String mUrl;
     private boolean mIsCaptivePortalCheckEnabled = false;
-    private IConnectivityManager mConnService;
-    private TelephonyManager mTelephonyManager;
-    private WifiManager mWifiManager;
-    private Context mContext;
+    private final IConnectivityManager mConnService;
+    private final TelephonyManager mTelephonyManager;
+    private final WifiManager mWifiManager;
+    private final Context mContext;
     private NetworkInfo mNetworkInfo;
 
-    private static final int CMD_DETECT_PORTAL          = 0;
     private static final int CMD_CONNECTIVITY_CHANGE    = 1;
     private static final int CMD_DELAYED_CAPTIVE_CHECK  = 2;
 
@@ -98,14 +96,15 @@
     private static final int DELAYED_CHECK_INTERVAL_MS = 10000;
     private int mDelayedCheckToken = 0;
 
-    private State mDefaultState = new DefaultState();
-    private State mNoActiveNetworkState = new NoActiveNetworkState();
-    private State mActiveNetworkState = new ActiveNetworkState();
-    private State mDelayedCaptiveCheckState = new DelayedCaptiveCheckState();
+    private final State mDefaultState = new DefaultState();
+    private final State mNoActiveNetworkState = new NoActiveNetworkState();
+    private final State mActiveNetworkState = new ActiveNetworkState();
+    private final State mDelayedCaptiveCheckState = new DelayedCaptiveCheckState();
 
     private static final String SETUP_WIZARD_PACKAGE = "com.google.android.setupwizard";
     private boolean mDeviceProvisioned = false;
-    private ProvisioningObserver mProvisioningObserver;
+    @SuppressWarnings("unused")
+    private final ProvisioningObserver mProvisioningObserver;
 
     private CaptivePortalTracker(Context context, IConnectivityManager cs) {
         super(TAG);
@@ -174,29 +173,11 @@
         return captivePortal;
     }
 
-    public void detectCaptivePortal(NetworkInfo info) {
-        sendMessage(obtainMessage(CMD_DETECT_PORTAL, info));
-    }
-
     private class DefaultState extends State {
 
         @Override
         public boolean processMessage(Message message) {
-            if (DBG) log(getName() + message.toString());
-            switch (message.what) {
-                case CMD_DETECT_PORTAL:
-                    NetworkInfo info = (NetworkInfo) message.obj;
-                    // Checking on a secondary connection is not supported
-                    // yet
-                    notifyPortalCheckComplete(info);
-                    break;
-                case CMD_CONNECTIVITY_CHANGE:
-                case CMD_DELAYED_CAPTIVE_CHECK:
-                    break;
-                default:
-                    loge("Ignoring " + message);
-                    break;
-            }
+            loge("Ignoring " + message);
             return HANDLED;
         }
     }
@@ -316,19 +297,6 @@
         }
     }
 
-    private void notifyPortalCheckComplete(NetworkInfo info) {
-        if (info == null) {
-            loge("notifyPortalCheckComplete on null");
-            return;
-        }
-        try {
-            if (DBG) log("notifyPortalCheckComplete: ni=" + info);
-            mConnService.captivePortalCheckComplete(info);
-        } catch(RemoteException e) {
-            e.printStackTrace();
-        }
-    }
-
     private void notifyPortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
         if (info == null) {
             loge("notifyPortalCheckComplete on null");
@@ -453,6 +421,13 @@
             case ConnectivityManager.TYPE_WIFI:
                 WifiInfo currentWifiInfo = mWifiManager.getConnectionInfo();
                 if (currentWifiInfo != null) {
+                    // NOTE: getSSID()'s behavior changed in API 17; before that, SSIDs were not
+                    // surrounded by double quotation marks (thus violating the Javadoc), but this
+                    // was changed to match the Javadoc in API 17. Since clients may have started
+                    // sanitizing the output of this method since API 17 was released, we should
+                    // not change it here as it would become impossible to tell whether the SSID is
+                    // simply being surrounded by quotes due to the API, or whether those quotes
+                    // are actually part of the SSID.
                     latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID());
                     latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID());
                 } else {
@@ -464,7 +439,6 @@
                 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()) {
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4eecfa9..3da00b1 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -23,10 +23,14 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Build.VERSION_CODES;
+import android.os.IBinder;
+import android.os.INetworkActivityListener;
+import android.os.INetworkManagementService;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.os.ResultReceiver;
+import android.os.ServiceManager;
 import android.provider.Settings;
+import android.util.ArrayMap;
 
 import java.net.InetAddress;
 
@@ -77,7 +81,7 @@
 
     /**
      * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
-     * applicable {@link Settings.Secure#CONNECTIVITY_CHANGE_DELAY}.
+     * applicable {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
      *
      * @hide
      */
@@ -171,6 +175,11 @@
      * {@hide}
      */
     public static final String EXTRA_IS_ACTIVE = "isActive";
+    /**
+     * The lookup key for a long that contains the timestamp (nanos) of the radio state change.
+     * {@hide}
+     */
+    public static final String EXTRA_REALTIME_NS = "tsNanos";
 
     /**
      * Broadcast Action: The setting for background data usage has changed
@@ -403,6 +412,8 @@
 
     private final String mPackageName;
 
+    private INetworkManagementService mNMService;
+
     /**
      * Tests if a given integer represents a valid network type.
      * @param networkType the type to be tested
@@ -803,6 +814,8 @@
      * Ensure that a network route exists to deliver traffic to the specified
      * host via the specified network interface. An attempt to add a route that
      * already exists is ignored, but treated as successful.
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
      * @param networkType the type of the network over which traffic to the specified
      * host is to be routed
      * @param hostAddress the IP address of the host to which the route is desired
@@ -906,6 +919,92 @@
     }
 
     /**
+     * Callback for use with {@link ConnectivityManager#registerNetworkActiveListener} to
+     * find out when the current network has gone in to a high power state.
+     */
+    public interface OnNetworkActiveListener {
+        /**
+         * Called on the main thread of the process to report that the current data network
+         * has become active, and it is now a good time to perform any pending network
+         * operations.  Note that this listener only tells you when the network becomes
+         * active; if at any other time you want to know whether it is active (and thus okay
+         * to initiate network traffic), you can retrieve its instantaneous state with
+         * {@link ConnectivityManager#isNetworkActive}.
+         */
+        public void onNetworkActive();
+    }
+
+    private INetworkManagementService getNetworkManagementService() {
+        synchronized (this) {
+            if (mNMService != null) {
+                return mNMService;
+            }
+            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+            mNMService = INetworkManagementService.Stub.asInterface(b);
+            return mNMService;
+        }
+    }
+
+    private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
+            mNetworkActivityListeners
+                    = new ArrayMap<OnNetworkActiveListener, INetworkActivityListener>();
+
+    /**
+     * Start listening to reports when the data network is active, meaning it is
+     * a good time to perform network traffic.  Use {@link #isNetworkActive()}
+     * to determine the current state of the network after registering the listener.
+     *
+     * @param l The listener to be told when the network is active.
+     */
+    public void registerNetworkActiveListener(final OnNetworkActiveListener l) {
+        INetworkActivityListener rl = new INetworkActivityListener.Stub() {
+            @Override
+            public void onNetworkActive() throws RemoteException {
+                l.onNetworkActive();
+            }
+        };
+
+        try {
+            getNetworkManagementService().registerNetworkActivityListener(rl);
+            mNetworkActivityListeners.put(l, rl);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Remove network active listener previously registered with
+     * {@link #registerNetworkActiveListener}.
+     *
+     * @param l Previously registered listener.
+     */
+    public void unregisterNetworkActiveListener(OnNetworkActiveListener l) {
+        INetworkActivityListener rl = mNetworkActivityListeners.get(l);
+        if (rl == null) {
+            throw new IllegalArgumentException("Listener not registered: " + l);
+        }
+        try {
+            getNetworkManagementService().unregisterNetworkActivityListener(rl);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * Return whether the data network is currently active.  An active network means that
+     * it is currently in a high power state for performing data transmission.  On some
+     * types of networks, it may be expensive to move and stay in such a state, so it is
+     * more power efficient to batch network traffic together when the radio is already in
+     * this state.  This method tells you whether right now is currently a good time to
+     * initiate network traffic, as the network is already active.
+     */
+    public boolean isNetworkActive() {
+        try {
+            return getNetworkManagementService().isNetworkActive();
+        } catch (RemoteException e) {
+        }
+        return false;
+    }
+
+    /**
      * {@hide}
      */
     public ConnectivityManager(IConnectivityManager service, String packageName) {
@@ -1020,7 +1119,7 @@
 
     /**
      * Check if the device allows for tethering.  It may be disabled via
-     * {@code ro.tether.denied} system property, {@link Settings#TETHER_SUPPORTED} or
+     * {@code ro.tether.denied} system property, Settings.TETHER_SUPPORTED or
      * due to device configuration.
      *
      * @return a boolean - {@code true} indicating Tethering is supported.
@@ -1208,7 +1307,7 @@
      * doing something unusual like general internal filtering this may be useful.  On
      * a private network where the proxy is not accessible, you may break HTTP using this.
      *
-     * @param proxyProperties The a {@link ProxyProperites} object defining the new global
+     * @param p The a {@link ProxyProperties} object defining the new global
      *        HTTP proxy.  A {@code null} value will clear the global HTTP proxy.
      *
      * <p>This method requires the call to hold the permission
@@ -1341,24 +1440,6 @@
 
     /**
      * Signal that the captive portal check on the indicated network
-     * is complete and we can turn the network on for general use.
-     *
-     * @param info the {@link NetworkInfo} object for the networkType
-     *        in question.
-     *
-     * <p>This method requires the call to hold the permission
-     * {@link android.Manifest.permission#CONNECTIVITY_INTERNAL}.
-     * {@hide}
-     */
-    public void captivePortalCheckComplete(NetworkInfo info) {
-        try {
-            mService.captivePortalCheckComplete(info);
-        } catch (RemoteException e) {
-        }
-    }
-
-    /**
-     * Signal that the captive portal check on the indicated network
      * is complete and whether its a captive portal or not.
      *
      * @param info the {@link NetworkInfo} object for the networkType
@@ -1379,7 +1460,7 @@
     /**
      * Supply the backend messenger for a network tracker
      *
-     * @param type NetworkType to set
+     * @param networkType NetworkType to set
      * @param messenger {@link Messenger}
      * {@hide}
      */
diff --git a/core/java/android/net/DhcpInfo.java b/core/java/android/net/DhcpInfo.java
index 3bede5d..788d7d9 100644
--- a/core/java/android/net/DhcpInfo.java
+++ b/core/java/android/net/DhcpInfo.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcelable;
 import android.os.Parcel;
-import java.net.InetAddress;
 
 /**
  * A simple object for retrieving the results of a DHCP request.
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index a3f70da..22b26b1 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -23,9 +23,6 @@
 
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
 
 /**
  * A simple object for retrieving the results of a DHCP request.
diff --git a/core/java/android/net/DummyDataStateTracker.java b/core/java/android/net/DummyDataStateTracker.java
index 51a1191..a5d059e 100644
--- a/core/java/android/net/DummyDataStateTracker.java
+++ b/core/java/android/net/DummyDataStateTracker.java
@@ -117,11 +117,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index cc8c771..10b5d0b 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -106,6 +106,24 @@
         mLinkCapabilities = new LinkCapabilities();
     }
 
+    private void interfaceUpdated() {
+        // we don't get link status indications unless the iface is up - bring it up
+        try {
+            mNMService.setInterfaceUp(mIface);
+            String hwAddr = null;
+            InterfaceConfiguration config = mNMService.getInterfaceConfig(mIface);
+            if (config != null) {
+                hwAddr = config.getHardwareAddress();
+            }
+            synchronized (this) {
+                mHwAddr = hwAddr;
+                mNetworkInfo.setExtraInfo(mHwAddr);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error upping interface " + mIface + ": " + e);
+        }
+    }
+
     private void interfaceAdded(String iface) {
         if (!iface.matches(sIfaceMatch))
             return;
@@ -118,12 +136,7 @@
             mIface = iface;
         }
 
-        // we don't get link status indications unless the iface is up - bring it up
-        try {
-            mNMService.setInterfaceUp(iface);
-        } catch (Exception e) {
-            Log.e(TAG, "Error upping interface " + iface + ": " + e);
-        }
+        interfaceUpdated();
 
         mNetworkInfo.setIsAvailable(true);
         Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
@@ -159,15 +172,21 @@
 
         Log.d(TAG, "Removing " + iface);
         disconnect();
-        mIface = "";
+        synchronized (this) {
+            mIface = "";
+            mHwAddr = null;
+            mNetworkInfo.setExtraInfo(null);
+        }
     }
 
     private void runDhcp() {
         Thread dhcpThread = new Thread(new Runnable() {
             public void run() {
                 DhcpResults dhcpResults = new DhcpResults();
+                mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
                 if (!NetworkUtils.runDhcp(mIface, dhcpResults)) {
                     Log.e(TAG, "DHCP request error:" + NetworkUtils.getDhcpError());
+                    mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, mHwAddr);
                     return;
                 }
                 mLinkProperties = dhcpResults.linkProperties;
@@ -220,15 +239,7 @@
             for (String iface : ifaces) {
                 if (iface.matches(sIfaceMatch)) {
                     mIface = iface;
-                    mNMService.setInterfaceUp(iface);
-                    InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
-                    mLinkUp = config.hasFlag("up");
-                    if (config != null && mHwAddr == null) {
-                        mHwAddr = config.getHardwareAddress();
-                        if (mHwAddr != null) {
-                            mNetworkInfo.setExtraInfo(mHwAddr);
-                        }
-                    }
+                    interfaceUpdated();
 
                     // if a DHCP client had previously been started for this interface, then stop it
                     NetworkUtils.stopDhcp(mIface);
@@ -270,11 +281,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
     }
@@ -423,4 +429,9 @@
     public void supplyMessenger(Messenger messenger) {
         // not supported on this network
     }
+
+    @Override
+    public String getNetworkInterfaceName() {
+        return mIface;
+    }
 }
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 4bca7fe..381a817 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -129,8 +129,6 @@
 
     boolean updateLockdownVpn();
 
-    void captivePortalCheckComplete(in NetworkInfo info);
-
     void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
 
     void supplyMessenger(int networkType, in Messenger messenger);
diff --git a/core/java/android/net/INetworkManagementEventObserver.aidl b/core/java/android/net/INetworkManagementEventObserver.aidl
index 5b16f8b..dd9c39f 100644
--- a/core/java/android/net/INetworkManagementEventObserver.aidl
+++ b/core/java/android/net/INetworkManagementEventObserver.aidl
@@ -86,8 +86,9 @@
      *
      * @param iface The interface.
      * @param active  True if the interface is actively transmitting data, false if it is idle.
+     * @param tsNanos Elapsed realtime in nanos when the state of the network interface changed.
      */
-    void interfaceClassDataActivityChanged(String label, boolean active);
+    void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos);
 
     /**
      * Information about available DNS servers has been received.
diff --git a/core/java/android/net/LinkSocketNotifier.java b/core/java/android/net/LinkSocketNotifier.java
index 28e2834..e2429d8 100644
--- a/core/java/android/net/LinkSocketNotifier.java
+++ b/core/java/android/net/LinkSocketNotifier.java
@@ -16,8 +16,6 @@
 
 package android.net;
 
-import java.util.Map;
-
 /**
  * Interface used to get feedback about a {@link android.net.LinkSocket}.  Instance is optionally
  * passed when a LinkSocket is constructed.  Multiple LinkSockets may use the same notifier.
diff --git a/core/java/android/net/MailTo.java b/core/java/android/net/MailTo.java
index b90dcb1..dadb6d9 100644
--- a/core/java/android/net/MailTo.java
+++ b/core/java/android/net/MailTo.java
@@ -19,7 +19,6 @@
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 /**
  *
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 21352bf..a470e88 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -306,18 +306,18 @@
                     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, "NetworkInfo = " + mNetworkInfo);
+                            Slog.d(TAG, "subType = " + mNetworkInfo.getSubtype());
                             Slog.d(TAG, "subType = " + mNetworkInfo.getSubtypeName());
                         }
                         if (mLinkProperties != null) {
-                            Slog.d(TAG, "LinkProperties = " + mLinkProperties.toString());
+                            Slog.d(TAG, "LinkProperties = " + mLinkProperties);
                         } else {
                             Slog.d(TAG, "LinkProperties = " );
                         }
 
                         if (mLinkCapabilities != null) {
-                            Slog.d(TAG, "LinkCapabilities = " + mLinkCapabilities.toString());
+                            Slog.d(TAG, "LinkCapabilities = " + mLinkCapabilities);
                         } else {
                             Slog.d(TAG, "LinkCapabilities = " );
                         }
@@ -460,11 +460,6 @@
     }
 
     @Override
-    public void captivePortalCheckComplete() {
-        // not implemented
-    }
-
-    @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         if (mIsCaptivePortal.getAndSet(isCaptivePortal) != isCaptivePortal) {
             // Captive portal change enable/disable failing fast
diff --git a/core/java/android/net/NetworkConfig.java b/core/java/android/net/NetworkConfig.java
index 5d95f41..32a2cda 100644
--- a/core/java/android/net/NetworkConfig.java
+++ b/core/java/android/net/NetworkConfig.java
@@ -16,7 +16,6 @@
 
 package android.net;
 
-import android.util.Log;
 import java.util.Locale;
 
 /**
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 4d2a70d..53b1308 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -156,18 +156,20 @@
     /** {@hide} */
     public NetworkInfo(NetworkInfo source) {
         if (source != null) {
-            mNetworkType = source.mNetworkType;
-            mSubtype = source.mSubtype;
-            mTypeName = source.mTypeName;
-            mSubtypeName = source.mSubtypeName;
-            mState = source.mState;
-            mDetailedState = source.mDetailedState;
-            mReason = source.mReason;
-            mExtraInfo = source.mExtraInfo;
-            mIsFailover = source.mIsFailover;
-            mIsRoaming = source.mIsRoaming;
-            mIsAvailable = source.mIsAvailable;
-            mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
+            synchronized (source) {
+                mNetworkType = source.mNetworkType;
+                mSubtype = source.mSubtype;
+                mTypeName = source.mTypeName;
+                mSubtypeName = source.mSubtypeName;
+                mState = source.mState;
+                mDetailedState = source.mDetailedState;
+                mReason = source.mReason;
+                mExtraInfo = source.mExtraInfo;
+                mIsFailover = source.mIsFailover;
+                mIsRoaming = source.mIsRoaming;
+                mIsAvailable = source.mIsAvailable;
+                mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
+            }
         }
     }
 
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 1ca9255..c49b1d1 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -144,11 +144,6 @@
     public boolean reconnect();
 
     /**
-     * Ready to switch on to the network after captive portal check
-     */
-    public void captivePortalCheckComplete();
-
-    /**
      * Captive portal check has completed
      */
     public void captivePortalCheckCompleted(boolean isCaptive);
diff --git a/core/java/android/net/NetworkStats.java b/core/java/android/net/NetworkStats.java
index a7aae2a..54d43d3 100644
--- a/core/java/android/net/NetworkStats.java
+++ b/core/java/android/net/NetworkStats.java
@@ -44,6 +44,8 @@
     public static final String IFACE_ALL = null;
     /** {@link #uid} value when UID details unavailable. */
     public static final int UID_ALL = -1;
+    /** {@link #tag} value matching any tag. */
+    public static final int TAG_ALL = -1;
     /** {@link #set} value when all sets combined. */
     public static final int SET_ALL = -1;
     /** {@link #set} value where background data is accounted. */
@@ -59,8 +61,9 @@
      * {@link SystemClock#elapsedRealtime()} timestamp when this data was
      * generated.
      */
-    private final long elapsedRealtime;
+    private long elapsedRealtime;
     private int size;
+    private int capacity;
     private String[] iface;
     private int[] uid;
     private int[] set;
@@ -152,20 +155,27 @@
     public NetworkStats(long elapsedRealtime, int initialSize) {
         this.elapsedRealtime = elapsedRealtime;
         this.size = 0;
-        this.iface = new String[initialSize];
-        this.uid = new int[initialSize];
-        this.set = new int[initialSize];
-        this.tag = new int[initialSize];
-        this.rxBytes = new long[initialSize];
-        this.rxPackets = new long[initialSize];
-        this.txBytes = new long[initialSize];
-        this.txPackets = new long[initialSize];
-        this.operations = new long[initialSize];
+        if (initialSize >= 0) {
+            this.capacity = initialSize;
+            this.iface = new String[initialSize];
+            this.uid = new int[initialSize];
+            this.set = new int[initialSize];
+            this.tag = new int[initialSize];
+            this.rxBytes = new long[initialSize];
+            this.rxPackets = new long[initialSize];
+            this.txBytes = new long[initialSize];
+            this.txPackets = new long[initialSize];
+            this.operations = new long[initialSize];
+        } else {
+            // Special case for use by NetworkStatsFactory to start out *really* empty.
+            this.capacity = 0;
+        }
     }
 
     public NetworkStats(Parcel parcel) {
         elapsedRealtime = parcel.readLong();
         size = parcel.readInt();
+        capacity = parcel.readInt();
         iface = parcel.createStringArray();
         uid = parcel.createIntArray();
         set = parcel.createIntArray();
@@ -181,6 +191,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeLong(elapsedRealtime);
         dest.writeInt(size);
+        dest.writeInt(capacity);
         dest.writeStringArray(iface);
         dest.writeIntArray(uid);
         dest.writeIntArray(set);
@@ -222,8 +233,8 @@
      * object can be recycled across multiple calls.
      */
     public NetworkStats addValues(Entry entry) {
-        if (size >= this.iface.length) {
-            final int newLength = Math.max(iface.length, 10) * 3 / 2;
+        if (size >= capacity) {
+            final int newLength = Math.max(size, 10) * 3 / 2;
             iface = Arrays.copyOf(iface, newLength);
             uid = Arrays.copyOf(uid, newLength);
             set = Arrays.copyOf(set, newLength);
@@ -233,6 +244,7 @@
             txBytes = Arrays.copyOf(txBytes, newLength);
             txPackets = Arrays.copyOf(txPackets, newLength);
             operations = Arrays.copyOf(operations, newLength);
+            capacity = newLength;
         }
 
         iface[size] = entry.iface;
@@ -270,6 +282,10 @@
         return elapsedRealtime;
     }
 
+    public void setElapsedRealtime(long time) {
+        elapsedRealtime = time;
+    }
+
     /**
      * Return age of this {@link NetworkStats} object with respect to
      * {@link SystemClock#elapsedRealtime()}.
@@ -284,7 +300,7 @@
 
     @VisibleForTesting
     public int internalSize() {
-        return iface.length;
+        return capacity;
     }
 
     @Deprecated
@@ -491,6 +507,17 @@
     }
 
     /**
+     * Fast path for battery stats.
+     */
+    public long getTotalPackets() {
+        long total = 0;
+        for (int i = size-1; i >= 0; i--) {
+            total += rxPackets[i] + txPackets[i];
+        }
+        return total;
+    }
+
+    /**
      * Subtract the given {@link NetworkStats}, effectively leaving the delta
      * between two snapshots in time. Assumes that statistics rows collect over
      * time, and that none of them have disappeared.
@@ -507,8 +534,25 @@
      * If counters have rolled backwards, they are clamped to {@code 0} and
      * reported to the given {@link NonMonotonicObserver}.
      */
-    public static <C> NetworkStats subtract(
-            NetworkStats left, NetworkStats right, NonMonotonicObserver<C> observer, C cookie) {
+    public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+            NonMonotonicObserver<C> observer, C cookie) {
+        return subtract(left, right, observer, cookie, null);
+    }
+
+    /**
+     * Subtract the two given {@link NetworkStats} objects, returning the delta
+     * between two snapshots in time. Assumes that statistics rows collect over
+     * time, and that none of them have disappeared.
+     * <p>
+     * If counters have rolled backwards, they are clamped to {@code 0} and
+     * reported to the given {@link NonMonotonicObserver}.
+     * <p>
+     * If <var>recycle</var> is supplied, this NetworkStats object will be
+     * reused (and returned) as the result if it is large enough to contain
+     * the data.
+     */
+    public static <C> NetworkStats subtract(NetworkStats left, NetworkStats right,
+            NonMonotonicObserver<C> observer, C cookie, NetworkStats recycle) {
         long deltaRealtime = left.elapsedRealtime - right.elapsedRealtime;
         if (deltaRealtime < 0) {
             if (observer != null) {
@@ -519,7 +563,14 @@
 
         // result will have our rows, and elapsed time between snapshots
         final Entry entry = new Entry();
-        final NetworkStats result = new NetworkStats(deltaRealtime, left.size);
+        final NetworkStats result;
+        if (recycle != null && recycle.capacity >= left.size) {
+            result = recycle;
+            result.size = 0;
+            result.elapsedRealtime = deltaRealtime;
+        } else {
+            result = new NetworkStats(deltaRealtime, left.size);
+        }
         for (int i = 0; i < left.size; i++) {
             entry.iface = left.iface[i];
             entry.uid = left.uid[i];
diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java
index c3e1438..033332c 100644
--- a/core/java/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
@@ -66,6 +66,19 @@
     /** {@hide} **/
     public static final String EXTRA_PROXY_INFO = "proxy";
 
+    /** @hide */
+    public static final int PROXY_VALID             = 0;
+    /** @hide */
+    public static final int PROXY_HOSTNAME_EMPTY    = 1;
+    /** @hide */
+    public static final int PROXY_HOSTNAME_INVALID  = 2;
+    /** @hide */
+    public static final int PROXY_PORT_EMPTY        = 3;
+    /** @hide */
+    public static final int PROXY_PORT_INVALID      = 4;
+    /** @hide */
+    public static final int PROXY_EXCLLIST_INVALID  = 5;
+
     private static ConnectivityManager sConnectivityManager = null;
 
     // Hostname / IP REGEX validation
@@ -77,8 +90,10 @@
 
     private static final Pattern HOSTNAME_PATTERN;
 
-    private static final String EXCLLIST_REGEXP = "$|^(.?" + NAME_IP_REGEX
-        + ")+(,(.?" + NAME_IP_REGEX + "))*$";
+    private static final String EXCL_REGEX =
+        "[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*(\\.[a-zA-Z0-9*]+(\\-[a-zA-Z0-9*]+)*)*";
+
+    private static final String EXCLLIST_REGEXP = "^$|^" + EXCL_REGEX + "(," + EXCL_REGEX + ")*$";
 
     private static final Pattern EXCLLIST_PATTERN;
 
@@ -236,36 +251,27 @@
      * Validate syntax of hostname, port and exclusion list entries
      * {@hide}
      */
-    public static void validate(String hostname, String port, String exclList) {
+    public static int validate(String hostname, String port, String exclList) {
         Matcher match = HOSTNAME_PATTERN.matcher(hostname);
         Matcher listMatch = EXCLLIST_PATTERN.matcher(exclList);
 
-        if (!match.matches()) {
-            throw new IllegalArgumentException();
-        }
+        if (!match.matches()) return PROXY_HOSTNAME_INVALID;
 
-        if (!listMatch.matches()) {
-            throw new IllegalArgumentException();
-        }
+        if (!listMatch.matches()) return PROXY_EXCLLIST_INVALID;
 
-        if (hostname.length() > 0 && port.length() == 0) {
-            throw new IllegalArgumentException();
-        }
+        if (hostname.length() > 0 && port.length() == 0) return PROXY_PORT_EMPTY;
 
         if (port.length() > 0) {
-            if (hostname.length() == 0) {
-                throw new IllegalArgumentException();
-            }
+            if (hostname.length() == 0) return PROXY_HOSTNAME_EMPTY;
             int portVal = -1;
             try {
                 portVal = Integer.parseInt(port);
             } catch (NumberFormatException ex) {
-                throw new IllegalArgumentException();
+                return PROXY_PORT_INVALID;
             }
-            if (portVal <= 0 || portVal > 0xFFFF) {
-                throw new IllegalArgumentException();
-            }
+            if (portVal <= 0 || portVal > 0xFFFF) return PROXY_PORT_INVALID;
         }
+        return PROXY_VALID;
     }
 
     static class AndroidProxySelectorRoutePlanner
diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java
index 010e527..50f45e8 100644
--- a/core/java/android/net/ProxyProperties.java
+++ b/core/java/android/net/ProxyProperties.java
@@ -22,7 +22,6 @@
 import android.text.TextUtils;
 
 import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
 import java.util.Locale;
 
 /**
@@ -141,13 +140,9 @@
 
     public boolean isValid() {
         if (!TextUtils.isEmpty(mPacFileUrl)) return true;
-        try {
-            Proxy.validate(mHost == null ? "" : mHost, mPort == 0 ? "" : Integer.toString(mPort),
-                    mExclusionList == null ? "" : mExclusionList);
-        } catch (IllegalArgumentException e) {
-            return false;
-        }
-        return true;
+        return Proxy.PROXY_VALID == Proxy.validate(mHost == null ? "" : mHost,
+                                                mPort == 0 ? "" : Integer.toString(mPort),
+                                                mExclusionList == null ? "" : mExclusionList);
     }
 
     public java.net.Proxy makeProxy() {
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index b0278d3..12e8791 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -135,7 +135,8 @@
      * disabled, using an optional handshake timeout and SSL session cache.
      *
      * <p class="caution"><b>Warning:</b> Sockets created using this factory
-     * are vulnerable to man-in-the-middle attacks!</p>
+     * are vulnerable to man-in-the-middle attacks!</p>. The caller must implement
+     * its own verification.
      *
      * @param handshakeTimeoutMillis to use for SSL connection handshake, or 0
      *         for none.  The socket timeout is reset to 0 after the handshake.
@@ -223,8 +224,6 @@
             if (mInsecureFactory == null) {
                 if (mSecure) {
                     Log.w(TAG, "*** BYPASSING SSL SECURITY CHECKS (socket.relaxsslcheck=yes) ***");
-                } else {
-                    Log.w(TAG, "Bypassing SSL security checks at caller's request");
                 }
                 mInsecureFactory = makeSocketFactory(mKeyManagers, INSECURE_TRUST_MANAGER);
             }
@@ -431,6 +430,7 @@
         s.setAlpnProtocols(mAlpnProtocols);
         s.setHandshakeTimeout(mHandshakeTimeoutMillis);
         s.setChannelIdPrivateKey(mChannelIdPrivateKey);
+        s.setHostname(host);
         if (mSecure) {
             verifyHostname(s, host);
         }
diff --git a/core/java/android/net/SSLSessionCache.java b/core/java/android/net/SSLSessionCache.java
index 15421de..65db2c3 100644
--- a/core/java/android/net/SSLSessionCache.java
+++ b/core/java/android/net/SSLSessionCache.java
@@ -19,12 +19,16 @@
 import android.content.Context;
 import android.util.Log;
 
+import com.android.org.conscrypt.ClientSessionContext;
 import com.android.org.conscrypt.FileClientSessionCache;
 import com.android.org.conscrypt.SSLClientSessionCache;
 
 import java.io.File;
 import java.io.IOException;
 
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSessionContext;
+
 /**
  * File-based cache of established SSL sessions.  When re-establishing a
  * connection to the same server, using an SSL session cache can save some time,
@@ -38,6 +42,40 @@
     /* package */ final SSLClientSessionCache mSessionCache;
 
     /**
+     * Installs a {@link SSLSessionCache} on a {@link SSLContext}. The cache will
+     * be used on all socket factories created by this context (including factories
+     * created before this call).
+     *
+     * @param cache the cache instance to install, or {@code null} to uninstall any
+     *         existing cache.
+     * @param context the context to install it on.
+     * @throws IllegalArgumentException if the context does not support a session
+     *         cache.
+     *
+     * @hide candidate for public API
+     */
+    public static void install(SSLSessionCache cache, SSLContext context) {
+        SSLSessionContext clientContext = context.getClientSessionContext();
+        if (clientContext instanceof ClientSessionContext) {
+            ((ClientSessionContext) clientContext).setPersistentCache(
+                    cache == null ? null : cache.mSessionCache);
+        } else {
+            throw new IllegalArgumentException("Incompatible SSLContext: " + context);
+        }
+    }
+
+    /**
+     * NOTE: This needs to be Object (and not SSLClientSessionCache) because apps
+     * that build directly against the framework (and not the SDK) might not declare
+     * a dependency on conscrypt. Javac will then has fail while resolving constructors.
+     *
+     * @hide For unit test use only
+     */
+    public SSLSessionCache(Object cache) {
+        mSessionCache = (SSLClientSessionCache) cache;
+    }
+
+    /**
      * Create a session cache using the specified directory.
      * Individual session entries will be files within the directory.
      * Multiple instances for the same directory share data internally.
diff --git a/core/java/android/net/SntpClient.java b/core/java/android/net/SntpClient.java
index 316440f..7673011 100644
--- a/core/java/android/net/SntpClient.java
+++ b/core/java/android/net/SntpClient.java
@@ -19,7 +19,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 
-import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
diff --git a/core/java/android/net/dhcp/DhcpAckPacket.java b/core/java/android/net/dhcp/DhcpAckPacket.java
index 4eca531..7b8be9c 100644
--- a/core/java/android/net/dhcp/DhcpAckPacket.java
+++ b/core/java/android/net/dhcp/DhcpAckPacket.java
@@ -19,7 +19,6 @@
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.nio.ByteBuffer;
-import java.util.List;
 
 /**
  * This class implements the DHCP-ACK packet.
diff --git a/core/java/android/net/dhcp/DhcpOfferPacket.java b/core/java/android/net/dhcp/DhcpOfferPacket.java
index 3d79f4d..f1c30e1 100644
--- a/core/java/android/net/dhcp/DhcpOfferPacket.java
+++ b/core/java/android/net/dhcp/DhcpOfferPacket.java
@@ -19,7 +19,6 @@
 import java.net.InetAddress;
 import java.net.Inet4Address;
 import java.nio.ByteBuffer;
-import java.util.List;
 
 /**
  * This class implements the DHCP-OFFER packet.
diff --git a/core/java/android/net/dhcp/DhcpPacket.java b/core/java/android/net/dhcp/DhcpPacket.java
index 317a9b4..c7c25f0 100644
--- a/core/java/android/net/dhcp/DhcpPacket.java
+++ b/core/java/android/net/dhcp/DhcpPacket.java
@@ -1,8 +1,5 @@
 package android.net.dhcp;
 
-import android.util.Log;
-
-import java.io.UnsupportedEncodingException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
diff --git a/core/java/android/net/dhcp/DhcpStateMachine.java b/core/java/android/net/dhcp/DhcpStateMachine.java
index b6c384d..bc9a798 100644
--- a/core/java/android/net/dhcp/DhcpStateMachine.java
+++ b/core/java/android/net/dhcp/DhcpStateMachine.java
@@ -17,7 +17,6 @@
 package android.net.dhcp;
 
 import java.net.InetAddress;
-import java.nio.ByteBuffer;
 import java.util.List;
 
 /**
diff --git a/core/java/android/net/http/AndroidHttpClientConnection.java b/core/java/android/net/http/AndroidHttpClientConnection.java
index eb96679..6d48fce 100644
--- a/core/java/android/net/http/AndroidHttpClientConnection.java
+++ b/core/java/android/net/http/AndroidHttpClientConnection.java
@@ -16,8 +16,6 @@
 
 package android.net.http;
 
-import org.apache.http.Header;
-
 import org.apache.http.HttpConnection;
 import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpConnectionMetrics;
@@ -27,12 +25,10 @@
 import org.apache.http.HttpInetConnection;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpResponse;
-import org.apache.http.HttpResponseFactory;
 import org.apache.http.NoHttpResponseException;
 import org.apache.http.StatusLine;
 import org.apache.http.entity.BasicHttpEntity;
 import org.apache.http.entity.ContentLengthStrategy;
-import org.apache.http.impl.DefaultHttpResponseFactory;
 import org.apache.http.impl.HttpConnectionMetricsImpl;
 import org.apache.http.impl.entity.EntitySerializer;
 import org.apache.http.impl.entity.StrictContentLengthStrategy;
diff --git a/core/java/android/net/http/Connection.java b/core/java/android/net/http/Connection.java
index 95cecd2..834ad69 100644
--- a/core/java/android/net/http/Connection.java
+++ b/core/java/android/net/http/Connection.java
@@ -21,7 +21,6 @@
 
 import java.io.IOException;
 import java.net.UnknownHostException;
-import java.util.ListIterator;
 import java.util.LinkedList;
 
 import javax.net.ssl.SSLHandshakeException;
diff --git a/core/java/android/net/http/ConnectionThread.java b/core/java/android/net/http/ConnectionThread.java
index 32191d2..d825530 100644
--- a/core/java/android/net/http/ConnectionThread.java
+++ b/core/java/android/net/http/ConnectionThread.java
@@ -19,8 +19,6 @@
 import android.content.Context;
 import android.os.SystemClock;
 
-import org.apache.http.HttpHost;
-
 import java.lang.Thread;
 
 /**
diff --git a/core/java/android/net/http/HttpConnection.java b/core/java/android/net/http/HttpConnection.java
index 6df86bf..edf8fed3 100644
--- a/core/java/android/net/http/HttpConnection.java
+++ b/core/java/android/net/http/HttpConnection.java
@@ -21,9 +21,7 @@
 import java.net.Socket;
 import java.io.IOException;
 
-import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpHost;
-import org.apache.http.impl.DefaultHttpClientConnection;
 import org.apache.http.params.BasicHttpParams;
 import org.apache.http.params.HttpConnectionParams;
 
diff --git a/core/java/android/net/http/HttpResponseCache.java b/core/java/android/net/http/HttpResponseCache.java
index 269dfb8..2785a15 100644
--- a/core/java/android/net/http/HttpResponseCache.java
+++ b/core/java/android/net/http/HttpResponseCache.java
@@ -17,9 +17,6 @@
 package android.net.http;
 
 import android.content.Context;
-import com.android.okhttp.OkResponseCache;
-import com.android.okhttp.ResponseSource;
-import com.android.okhttp.internal.DiskLruCache;
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
@@ -32,7 +29,6 @@
 import java.util.List;
 import java.util.Map;
 import javax.net.ssl.HttpsURLConnection;
-import libcore.io.IoUtils;
 import org.apache.http.impl.client.DefaultHttpClient;
 
 /**
diff --git a/core/java/android/net/http/HttpsConnection.java b/core/java/android/net/http/HttpsConnection.java
index 7a12e53..6bf01e2 100644
--- a/core/java/android/net/http/HttpsConnection.java
+++ b/core/java/android/net/http/HttpsConnection.java
@@ -40,7 +40,6 @@
 import javax.net.ssl.X509TrustManager;
 import java.io.File;
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.security.KeyManagementException;
 import java.security.cert.X509Certificate;
diff --git a/core/java/android/net/http/Request.java b/core/java/android/net/http/Request.java
index 8c0d503..76d7bb9 100644
--- a/core/java/android/net/http/Request.java
+++ b/core/java/android/net/http/Request.java
@@ -26,15 +26,12 @@
 
 import org.apache.http.entity.InputStreamEntity;
 import org.apache.http.Header;
-import org.apache.http.HttpClientConnection;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
-import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
-import org.apache.http.HttpVersion;
 import org.apache.http.ParseException;
 import org.apache.http.ProtocolVersion;
 
diff --git a/core/java/android/net/http/RequestQueue.java b/core/java/android/net/http/RequestQueue.java
index ce6b1ad..7d2da1b 100644
--- a/core/java/android/net/http/RequestQueue.java
+++ b/core/java/android/net/http/RequestQueue.java
@@ -29,10 +29,6 @@
 import android.net.NetworkInfo;
 import android.net.Proxy;
 import android.net.WebAddress;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.text.TextUtils;
 import android.util.Log;
 
 import java.io.InputStream;
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index cfe5f27..db71279 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -63,4 +63,18 @@
                                                     String host) throws CertificateException {
         return mDelegate.checkServerTrusted(chain, authType, host);
     }
+
+    /**
+     * Checks whether a CA certificate is added by an user.
+     *
+     * <p>Since {@link X509TrustManager#checkServerTrusted} allows its parameter {@code chain} to
+     * chain up to user-added CA certificates, this method can be used to perform additional
+     * policies for user-added CA certificates.
+     *
+     * @return {@code true} to indicate that the certificate was added by the user, {@code false}
+     * otherwise.
+     */
+    public boolean isUserAddedCertificate(X509Certificate cert) {
+        return mDelegate.isUserAddedCertificate(cert);
+    }
 }
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 7b2c623..d8e8e2c 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -19,8 +19,6 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.os.Binder;
-import android.os.IBinder;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 8414738..635a50f 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -25,6 +25,7 @@
 import android.nfc.INfcAdapterExtras;
 import android.nfc.INfcTag;
 import android.nfc.INfcCardEmulation;
+import android.nfc.INfcUnlockSettings;
 import android.os.Bundle;
 
 /**
@@ -35,6 +36,7 @@
     INfcTag getNfcTagInterface();
     INfcCardEmulation getNfcCardEmulationInterface();
     INfcAdapterExtras getNfcAdapterExtrasInterface(in String pkg);
+    INfcUnlockSettings getNfcUnlockSettingsInterface();
 
     int getState();
     boolean disable(boolean saveState);
@@ -46,6 +48,7 @@
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
     void setAppCallback(in IAppCallback callback);
+    void invokeBeam();
 
     void dispatch(in Tag tag);
 
diff --git a/core/java/android/nfc/INfcUnlockSettings.aidl b/core/java/android/nfc/INfcUnlockSettings.aidl
new file mode 100644
index 0000000..649eeed
--- /dev/null
+++ b/core/java/android/nfc/INfcUnlockSettings.aidl
@@ -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 android.nfc;
+
+import android.nfc.Tag;
+import java.util.List;
+
+/**
+ * Interface to NFC unlock functionality.
+ *
+ * @hide
+ */
+interface INfcUnlockSettings {
+
+    /**
+     * Checks the validity of the tag and attempts to unlock the screen.
+     *
+     * @return true if the screen was successfuly unlocked.
+     */
+    boolean tryUnlock(int userId, in Tag tag);
+
+    /**
+     * Registers the given tag as an unlock tag. Subsequent calls to {@code tryUnlock}
+     * with the same {@code tag} should succeed.
+     *
+     * @return true if the tag was successfully registered.
+     */
+    boolean registerTag(int userId, in Tag tag);
+
+    /**
+     * Deregisters the tag with the corresponding timestamp.
+     * Subsequent calls to {@code tryUnlock} with the same tag should fail.
+     *
+     * @return true if the tag was successfully deleted.
+     */
+    boolean deregisterTag(int userId, long timestamp);
+
+    /**
+     * Used for user-visible rendering of registered tags.
+     *
+     * @return a list of the times in millis since epoch when the registered tags were paired.
+     */
+    long[] getTagRegistryTimes(int userId);
+
+    /**
+     * Determines the state of the NFC unlock feature.
+     *
+     * @return true if NFC unlock is enabled.
+     */
+    boolean getNfcUnlockEnabled(int userId);
+
+    /**
+     * Sets the state [ON | OFF] of the NFC unlock feature.
+     */
+    void setNfcUnlockEnabled(int userId, boolean enabled);
+}
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 2b58818..83d17ba 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -20,6 +20,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
@@ -269,6 +270,7 @@
             "urn:epc:pat:", // 0x20
             "urn:epc:raw:", // 0x21
             "urn:epc:", // 0x22
+            "urn:nfc:", // 0x23
     };
 
     private static final int MAX_PAYLOAD_SIZE = 10 * (1 << 20);  // 10 MB payload limit
@@ -473,6 +475,45 @@
     }
 
     /**
+     * Create a new NDEF record containing UTF-8 text data.<p>
+     *
+     * The caller can either specify the language code for the provided text,
+     * or otherwise the language code corresponding to the current default
+     * locale will be used.
+     *
+     * Reference specification: NFCForum-TS-RTD_Text_1.0
+     * @param languageCode The languageCode for the record. If locale is empty or null,
+     *                     the language code of the current default locale will be used.
+     * @param text   The text to be encoded in the record. Will be represented in UTF-8 format.
+     * @throws IllegalArgumentException if text is null
+     */
+    public static NdefRecord createTextRecord(String languageCode, String text) {
+        if (text == null) throw new NullPointerException("text is null");
+
+        byte[] textBytes = text.getBytes(StandardCharsets.UTF_8);
+
+        byte[] languageCodeBytes = null;
+        if (languageCode != null && !languageCode.isEmpty()) {
+            languageCodeBytes = languageCode.getBytes(StandardCharsets.US_ASCII);
+        } else {
+            languageCodeBytes = Locale.getDefault().getLanguage().
+                    getBytes(StandardCharsets.US_ASCII);
+        }
+        // We only have 6 bits to indicate ISO/IANA language code.
+        if (languageCodeBytes.length >= 64) {
+            throw new IllegalArgumentException("language code is too long, must be <64 bytes.");
+        }
+        ByteBuffer buffer = ByteBuffer.allocate(1 + languageCodeBytes.length + textBytes.length);
+
+        byte status = (byte) (languageCodeBytes.length & 0xFF);
+        buffer.put(status);
+        buffer.put(languageCodeBytes);
+        buffer.put(textBytes);
+
+        return new NdefRecord(TNF_WELL_KNOWN, RTD_TEXT, null, buffer.array());
+    }
+
+    /**
      * Construct an NDEF Record from its component fields.<p>
      * Recommend to use helpers such as {#createUri} or
      * {{@link #createExternal} where possible, since they perform
@@ -774,7 +815,7 @@
                     throw new FormatException("expected TNF_UNCHANGED in non-leading chunk");
                 } else if (!inChunk && tnf == NdefRecord.TNF_UNCHANGED) {
                     throw new FormatException("" +
-                    		"unexpected TNF_UNCHANGED in first chunk or unchunked record");
+                            "unexpected TNF_UNCHANGED in first chunk or unchunked record");
                 }
 
                 int typeLength = buffer.get() & 0xFF;
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 77c0234..8643f2e 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.Application;
+import android.content.Intent;
 import android.net.Uri;
 import android.nfc.NfcAdapter.ReaderCallback;
 import android.os.Binder;
@@ -327,6 +328,7 @@
         NfcAdapter.CreateNdefMessageCallback ndefCallback;
         NfcAdapter.CreateBeamUrisCallback urisCallback;
         NdefMessage message;
+        Activity activity;
         Uri[] uris;
         int flags;
         synchronized (NfcActivityManager.this) {
@@ -338,6 +340,7 @@
             message = state.ndefMessage;
             uris = state.uris;
             flags = state.flags;
+            activity = state.activity;
         }
 
         // Make callbacks without lock
@@ -362,7 +365,13 @@
                 }
             }
         }
-
+        if (uris != null && uris.length > 0) {
+            for (Uri uri : uris) {
+                // Grant the NFC process permission to read these URIs
+                activity.grantUriPermission("com.android.nfc", uri,
+                        Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            }
+        }
         return new BeamShareData(message, uris, flags);
     }
 
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index 6743c6c..96a3947 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -292,6 +292,7 @@
     static INfcAdapter sService;
     static INfcTag sTagService;
     static INfcCardEmulation sCardEmulationService;
+    static INfcUnlockSettings sNfcUnlockSettingsService;
 
     /**
      * The NfcAdapter object for each application context.
@@ -432,6 +433,13 @@
                 throw new UnsupportedOperationException();
             }
 
+            try {
+               sNfcUnlockSettingsService = sService.getNfcUnlockSettingsInterface();
+            } catch (RemoteException e) {
+                Log.e(TAG, "could not retrieve NFC unlock settings service");
+                sNfcUnlockSettingsService = null;
+            }
+
             sIsInitialized = true;
         }
         if (context == null) {
@@ -549,6 +557,22 @@
     }
 
     /**
+     * Returns the binder interface to the NFC unlock service.
+     *
+     * @throws UnsupportedOperationException if the service is not available.
+     * @hide
+     */
+    public INfcUnlockSettings getNfcUnlockSettingsService() throws UnsupportedOperationException {
+         isEnabled();
+
+        if (sNfcUnlockSettingsService == null) {
+            throw new UnsupportedOperationException("NfcUnlockSettingsService not available");
+        }
+
+        return sNfcUnlockSettingsService;
+    }
+
+    /**
      * NFC service dead - attempt best effort recovery
      * @hide
      */
@@ -1225,6 +1249,45 @@
     }
 
     /**
+     * Manually invoke Android Beam to share data.
+     *
+     * <p>The Android Beam animation is normally only shown when two NFC-capable
+     * devices come into range.
+     * By calling this method, an Activity can invoke the Beam animation directly
+     * even if no other NFC device is in range yet. The Beam animation will then
+     * prompt the user to tap another NFC-capable device to complete the data
+     * transfer.
+     *
+     * <p>The main advantage of using this method is that it avoids the need for the
+     * user to tap the screen to complete the transfer, as this method already
+     * establishes the direction of the transfer and the consent of the user to
+     * share data. Callers are responsible for making sure that the user has
+     * consented to sharing data on NFC tap.
+     *
+     * <p>Note that to use this method, the passed in Activity must have already
+     * set data to share over Beam by using method calls such as
+     * {@link #setNdefPushMessageCallback} or
+     * {@link #setBeamPushUrisCallback}.
+     *
+     * @param activity the current foreground Activity that has registered data to share
+     * @return whether the Beam animation was successfully invoked
+     */
+    public boolean invokeBeam(Activity activity) {
+        if (activity == null) {
+            throw new NullPointerException("activity may not be null.");
+        }
+        enforceResumed(activity);
+        try {
+            sService.invokeBeam();
+            return true;
+        } catch (RemoteException e) {
+            Log.e(TAG, "invokeBeam: NFC process has died.");
+            attemptDeadServiceRecovery(e);
+            return false;
+        }
+    }
+
+    /**
      * 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/NfcUnlock.java b/core/java/android/nfc/NfcUnlock.java
new file mode 100644
index 0000000..82dcd96
--- /dev/null
+++ b/core/java/android/nfc/NfcUnlock.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * Provides an interface to read and update NFC unlock settings.
+ * <p/>
+ * Allows system services (currently exclusively LockSettingsService) to
+ * register NFC tags to be used to unlock the device, as well as the ability
+ * to enable/disable the service entirely.
+ *
+ */
+public class NfcUnlock {
+
+    /**
+     * Action to unlock the device.
+     *
+     * @hide
+     */
+    public static final String ACTION_NFC_UNLOCK = "android.nfc.ACTION_NFC_UNLOCK";
+    /**
+     * Permission to unlock the device.
+     *
+     * @hide
+     */
+    public static final String NFC_UNLOCK_PERMISSION = "android.permission.NFC_UNLOCK";
+
+    /**
+     * Property to enable NFC Unlock
+     *
+     * @hide
+     */
+    public static final String PROPERTY = "ro.com.android.nfc.unlock";
+
+    private static final String TAG = "NfcUnlock";
+    private static HashMap<Context, NfcUnlock> sNfcUnlocks = new HashMap<Context, NfcUnlock>();
+
+    private final Context mContext;
+    private final boolean mEnabled;
+    private INfcUnlockSettings sService;
+
+    private NfcUnlock(Context context, INfcUnlockSettings service) {
+        this.mContext = checkNotNull(context);
+        this.sService = checkNotNull(service);
+        this.mEnabled = getPropertyEnabled();
+    }
+
+    /**
+     * Returns an instance of {@link NfcUnlock}.
+     */
+    public static synchronized NfcUnlock getInstance(NfcAdapter nfcAdapter) {
+        Context context = nfcAdapter.getContext();
+        if (context == null) {
+            Log.e(TAG, "NfcAdapter context is null");
+            throw new UnsupportedOperationException();
+        }
+
+        NfcUnlock manager = sNfcUnlocks.get(context);
+        if (manager == null) {
+            INfcUnlockSettings service = nfcAdapter.getNfcUnlockSettingsService();
+            manager = new NfcUnlock(context, service);
+            sNfcUnlocks.put(context, manager);
+        }
+
+        return manager;
+    }
+
+    /**
+     * Registers the given {@code tag} as an unlock tag.
+     *
+     * @return true if the tag was successfully registered.
+     * @hide
+     */
+    public boolean registerTag(Tag tag) {
+        enforcePropertyEnabled();
+
+        int currentUser = ActivityManager.getCurrentUser();
+
+        try {
+            return sService.registerTag(currentUser, tag);
+        } catch (RemoteException e) {
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NfcUnlockSettingsService");
+                return false;
+            }
+
+            try {
+                return sService.registerTag(currentUser, tag);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach NfcUnlockSettingsService", ee);
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Deregisters the given {@code tag} as an unlock tag.
+     *
+     * @return true if the tag was successfully deregistered.
+     * @hide
+     */
+    public boolean deregisterTag(long timestamp) {
+        enforcePropertyEnabled();
+        int currentUser = ActivityManager.getCurrentUser();
+
+        try {
+            return sService.deregisterTag(currentUser, timestamp);
+        } catch (RemoteException e) {
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NfcUnlockSettingsService");
+                return false;
+            }
+
+            try {
+                return sService.deregisterTag(currentUser, timestamp);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach NfcUnlockSettingsService", ee);
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Determines the enable state of the NFC unlock feature.
+     *
+     * @return true if NFC unlock is enabled.
+     */
+    public boolean getNfcUnlockEnabled() {
+        enforcePropertyEnabled();
+        int currentUser = ActivityManager.getCurrentUser();
+
+        try {
+            return sService.getNfcUnlockEnabled(currentUser);
+        } catch (RemoteException e) {
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NfcUnlockSettingsService");
+                return false;
+            }
+
+            try {
+                return sService.getNfcUnlockEnabled(currentUser);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach NfcUnlockSettingsService", ee);
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Set the enable state of the NFC unlock feature.
+     *
+     * @return true if the setting was successfully persisted.
+     * @hide
+     */
+    public boolean setNfcUnlockEnabled(boolean enabled) {
+        enforcePropertyEnabled();
+        int currentUser = ActivityManager.getCurrentUser();
+
+        try {
+            sService.setNfcUnlockEnabled(currentUser, enabled);
+            return true;
+        }  catch (RemoteException e) {
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NfcUnlockSettingsService");
+                return false;
+            }
+
+            try {
+                sService.setNfcUnlockEnabled(currentUser, enabled);
+                return true;
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach NfcUnlockSettingsService", ee);
+                return false;
+            }
+
+        }
+    }
+
+    /**
+     * Returns a list of times (in millis since epoch) corresponding to when
+     * unlock tags were registered.
+     *
+     * @hide
+     */
+    @Nullable
+    public long[] getTagRegistryTimes() {
+        enforcePropertyEnabled();
+        int currentUser = ActivityManager.getCurrentUser();
+
+        try {
+            return sService.getTagRegistryTimes(currentUser);
+        } catch (RemoteException e) {
+            recoverService();
+            if (sService == null) {
+                Log.e(TAG, "Failed to recover NfcUnlockSettingsService");
+                return null;
+            }
+
+            try {
+                return sService.getTagRegistryTimes(currentUser);
+            } catch (RemoteException ee) {
+                Log.e(TAG, "Failed to reach NfcUnlockSettingsService", ee);
+                return null;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static boolean getPropertyEnabled() {
+        return SystemProperties.get(PROPERTY).equals("ON");
+    }
+
+    private void recoverService() {
+        NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext);
+        sService = adapter.getNfcUnlockSettingsService();
+    }
+
+
+    private void enforcePropertyEnabled() {
+        if (!mEnabled) {
+            throw new UnsupportedOperationException("NFC Unlock property is not enabled");
+        }
+    }
+}
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index f2cd232..0d261d1 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -204,6 +204,14 @@
     }
 
     /**
+     * For use by NfcService only.
+     * @hide
+     */
+    public int[] getTechCodeList() {
+        return mTechList;
+    }
+
+    /**
      * Get the Tag Identifier (if it has one).
      * <p>The tag identifier is a low level serial number, used for anti-collision
      * and identification.
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index f16dc3b..5852ce4 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -20,7 +20,6 @@
 import android.nfc.FormatException;
 import android.nfc.INfcTag;
 import android.nfc.NdefMessage;
-import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.nfc.TagLostException;
 import android.os.Bundle;
diff --git a/core/java/android/nfc/tech/NdefFormatable.java b/core/java/android/nfc/tech/NdefFormatable.java
index ffa6a2b..4175cd0 100644
--- a/core/java/android/nfc/tech/NdefFormatable.java
+++ b/core/java/android/nfc/tech/NdefFormatable.java
@@ -20,7 +20,6 @@
 import android.nfc.FormatException;
 import android.nfc.INfcTag;
 import android.nfc.NdefMessage;
-import android.nfc.NfcAdapter;
 import android.nfc.Tag;
 import android.nfc.TagLostException;
 import android.os.RemoteException;
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 26e09b6..4f91d19 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -40,7 +40,7 @@
  * and does not constitute a generic threading framework. AsyncTasks should ideally be
  * used for short operations (a few seconds at the most.) If you need to keep threads
  * running for long periods of time, it is highly recommended you use the various APIs
- * provided by the <code>java.util.concurrent</code> pacakge such as {@link Executor},
+ * provided by the <code>java.util.concurrent</code> package such as {@link Executor},
  * {@link ThreadPoolExecutor} and {@link FutureTask}.</p>
  *
  * <p>An asynchronous task is defined by a computation that runs on a background thread and
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 5df5214..8f5cf8b 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -15,9 +15,6 @@
 
 package android.os;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-
 /**
  * {@hide}
  */
@@ -30,11 +27,25 @@
     public boolean batteryPresent;
     public int batteryLevel;
     public int batteryVoltage;
-    public int batteryCurrentNow;
-    public int batteryChargeCounter;
     public int batteryTemperature;
     public String batteryTechnology;
 
+    public BatteryProperties() {
+    }
+
+    public void set(BatteryProperties other) {
+        chargerAcOnline = other.chargerAcOnline;
+        chargerUsbOnline = other.chargerUsbOnline;
+        chargerWirelessOnline = other.chargerWirelessOnline;
+        batteryStatus = other.batteryStatus;
+        batteryHealth = other.batteryHealth;
+        batteryPresent = other.batteryPresent;
+        batteryLevel = other.batteryLevel;
+        batteryVoltage = other.batteryVoltage;
+        batteryTemperature = other.batteryTemperature;
+        batteryTechnology = other.batteryTechnology;
+    }
+
     /*
      * Parcel read/write code must be kept in sync with
      * frameworks/native/services/batteryservice/BatteryProperties.cpp
@@ -49,8 +60,6 @@
         batteryPresent = p.readInt() == 1 ? true : false;
         batteryLevel = p.readInt();
         batteryVoltage = p.readInt();
-        batteryCurrentNow = p.readInt();
-        batteryChargeCounter = p.readInt();
         batteryTemperature = p.readInt();
         batteryTechnology = p.readString();
     }
@@ -64,8 +73,6 @@
         p.writeInt(batteryPresent ? 1 : 0);
         p.writeInt(batteryLevel);
         p.writeInt(batteryVoltage);
-        p.writeInt(batteryCurrentNow);
-        p.writeInt(batteryChargeCounter);
         p.writeInt(batteryTemperature);
         p.writeString(batteryTechnology);
     }
diff --git a/core/java/android/os/BatteryProperty.aidl b/core/java/android/os/BatteryProperty.aidl
new file mode 100644
index 0000000..b3f2ec3
--- /dev/null
+++ b/core/java/android/os/BatteryProperty.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 BatteryProperty;
diff --git a/core/java/android/os/BatteryProperty.java b/core/java/android/os/BatteryProperty.java
new file mode 100644
index 0000000..76b0dc4
--- /dev/null
+++ b/core/java/android/os/BatteryProperty.java
@@ -0,0 +1,71 @@
+/* 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 BatteryProperty implements Parcelable {
+    /*
+     * Battery property identifiers.  These must match the values in
+     * frameworks/native/include/batteryservice/BatteryService.h
+     */
+    public static final int BATTERY_PROP_CHARGE_COUNTER = 1;
+    public static final int BATTERY_PROP_CURRENT_NOW = 2;
+    public static final int BATTERY_PROP_CURRENT_AVG = 3;
+    public static final int BATTERY_PROP_CAPACITY = 4;
+
+    public int valueInt;
+
+    public BatteryProperty() {
+        valueInt = Integer.MIN_VALUE;
+    }
+
+    /*
+     * Parcel read/write code must be kept in sync with
+     * frameworks/native/services/batteryservice/BatteryProperty.cpp
+     */
+
+    private BatteryProperty(Parcel p) {
+        readFromParcel(p);
+    }
+
+    public void readFromParcel(Parcel p) {
+        valueInt = p.readInt();
+    }
+
+    public void writeToParcel(Parcel p, int flags) {
+        p.writeInt(valueInt);
+    }
+
+    public static final Parcelable.Creator<BatteryProperty> CREATOR
+        = new Parcelable.Creator<BatteryProperty>() {
+        public BatteryProperty createFromParcel(Parcel p) {
+            return new BatteryProperty(p);
+        }
+
+        public BatteryProperty[] newArray(int size) {
+            return new BatteryProperty[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index b1a9ea30..426f21e 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -24,13 +24,15 @@
 import java.util.List;
 import java.util.Map;
 
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.telephony.SignalStrength;
-import android.util.Log;
+import android.text.format.DateFormat;
 import android.util.Printer;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
+import com.android.internal.os.BatterySipper;
+import com.android.internal.os.BatteryStatsHelper;
 
 /**
  * A class providing access to battery usage statistics, including information on
@@ -116,19 +118,14 @@
     public static final int STATS_SINCE_CHARGED = 0;
 
     /**
-     * Include only the last run in the stats.
-     */
-    public static final int STATS_LAST = 1;
-
-    /**
      * Include only the current run in the stats.
      */
-    public static final int STATS_CURRENT = 2;
+    public static final int STATS_CURRENT = 1;
 
     /**
      * Include only the run since the last time the device was unplugged in the stats.
      */
-    public static final int STATS_SINCE_UNPLUGGED = 3;
+    public static final int STATS_SINCE_UNPLUGGED = 2;
 
     // NOTE: Update this list if you add/change any stats above.
     // These characters are supposed to represent "total", "last", "current", 
@@ -153,6 +150,7 @@
     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 WAKEUP_REASON_DATA = "wr";
     private static final String NETWORK_DATA = "nt";
     private static final String USER_ACTIVITY_DATA = "ua";
     private static final String BATTERY_DATA = "bt";
@@ -160,6 +158,8 @@
     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 GLOBAL_NETWORK_DATA = "gn";
+    private static final String HISTORY_STRING_POOL = "hsp";
     private static final String HISTORY_DATA = "h";
     private static final String SCREEN_BRIGHTNESS_DATA = "br";
     private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
@@ -167,6 +167,12 @@
     private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
     private static final String DATA_CONNECTION_TIME_DATA = "dct";
     private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
+    private static final String WIFI_STATE_TIME_DATA = "wst";
+    private static final String WIFI_STATE_COUNT_DATA = "wsc";
+    private static final String BLUETOOTH_STATE_TIME_DATA = "bst";
+    private static final String BLUETOOTH_STATE_COUNT_DATA = "bsc";
+    private static final String POWER_USE_SUMMARY_DATA = "pws";
+    private static final String POWER_USE_ITEM_DATA = "pwi";
 
     private final StringBuilder mFormatBuilder = new StringBuilder(32);
     private final Formatter mFormatter = new Formatter(mFormatBuilder);
@@ -191,6 +197,25 @@
     }
 
     /**
+     * State for keeping track of long counting information.
+     */
+    public static abstract class LongCounter {
+
+        /**
+         * Returns the count associated with this Counter for the
+         * selected type of statistics.
+         *
+         * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
+         */
+        public abstract long getCountLocked(int which);
+
+        /**
+         * Temporary for debugging.
+         */
+        public abstract void logState(Printer pw, String prefix);
+    }
+
+    /**
      * State for keeping track of timing information.
      */
     public static abstract class Timer {
@@ -207,11 +232,11 @@
          * Returns the total time in microseconds associated with this Timer for the
          * selected type of statistics.
          *
-         * @param batteryRealtime system realtime on  battery in microseconds
+         * @param elapsedRealtimeUs current elapsed realtime of system in microseconds
          * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
          * @return a time in microseconds
          */
-        public abstract long getTotalTimeLocked(long batteryRealtime, int which);
+        public abstract long getTotalTimeLocked(long elapsedRealtimeUs, int which);
 
         /**
          * Temporary for debugging.
@@ -269,30 +294,29 @@
          */
         public abstract int getUid();
 
-        public abstract void noteWifiRunningLocked();
-        public abstract void noteWifiStoppedLocked();
-        public abstract void noteFullWifiLockAcquiredLocked();
-        public abstract void noteFullWifiLockReleasedLocked();
-        public abstract void noteWifiScanStartedLocked();
-        public abstract void noteWifiScanStoppedLocked();
-        public abstract void noteWifiBatchedScanStartedLocked(int csph);
-        public abstract void noteWifiBatchedScanStoppedLocked();
-        public abstract void noteWifiMulticastEnabledLocked();
-        public abstract void noteWifiMulticastDisabledLocked();
-        public abstract void noteAudioTurnedOnLocked();
-        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);
-        public abstract long getWifiBatchedScanTime(int csphBin, long batteryRealtime, int which);
-        public abstract long getWifiMulticastTime(long batteryRealtime,
-                                                  int which);
-        public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
-        public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
+        public abstract void noteWifiRunningLocked(long elapsedRealtime);
+        public abstract void noteWifiStoppedLocked(long elapsedRealtime);
+        public abstract void noteFullWifiLockAcquiredLocked(long elapsedRealtime);
+        public abstract void noteFullWifiLockReleasedLocked(long elapsedRealtime);
+        public abstract void noteWifiScanStartedLocked(long elapsedRealtime);
+        public abstract void noteWifiScanStoppedLocked(long elapsedRealtime);
+        public abstract void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtime);
+        public abstract void noteWifiBatchedScanStoppedLocked(long elapsedRealtime);
+        public abstract void noteWifiMulticastEnabledLocked(long elapsedRealtime);
+        public abstract void noteWifiMulticastDisabledLocked(long elapsedRealtime);
+        public abstract void noteAudioTurnedOnLocked(long elapsedRealtime);
+        public abstract void noteAudioTurnedOffLocked(long elapsedRealtime);
+        public abstract void noteVideoTurnedOnLocked(long elapsedRealtime);
+        public abstract void noteVideoTurnedOffLocked(long elapsedRealtime);
+        public abstract void noteActivityResumedLocked(long elapsedRealtime);
+        public abstract void noteActivityPausedLocked(long elapsedRealtime);
+        public abstract long getWifiRunningTime(long elapsedRealtimeUs, int which);
+        public abstract long getFullWifiLockTime(long elapsedRealtimeUs, int which);
+        public abstract long getWifiScanTime(long elapsedRealtimeUs, int which);
+        public abstract long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which);
+        public abstract long getWifiMulticastTime(long elapsedRealtimeUs, int which);
+        public abstract long getAudioTurnedOnTime(long elapsedRealtimeUs, int which);
+        public abstract long getVideoTurnedOnTime(long elapsedRealtimeUs, int which);
         public abstract Timer getForegroundActivityTimer();
         public abstract Timer getVibratorOnTimer();
 
@@ -314,7 +338,10 @@
         public abstract int getUserActivityCount(int type, int which);
 
         public abstract boolean hasNetworkActivity();
-        public abstract long getNetworkActivityCount(int type, int which);
+        public abstract long getNetworkActivityBytes(int type, int which);
+        public abstract long getNetworkActivityPackets(int type, int which);
+        public abstract long getMobileRadioActiveTime(int which);
+        public abstract int getMobileRadioActiveCount(int which);
 
         public static abstract class Sensor {
             /*
@@ -331,8 +358,9 @@
         }
 
         public class Pid {
-            public long mWakeSum;
-            public long mWakeStart;
+            public int mWakeNesting;
+            public long mWakeSumMs;
+            public long mWakeStartMs;
         }
 
         /**
@@ -350,6 +378,11 @@
             }
 
             /**
+             * Returns true if this process is still active in the battery stats.
+             */
+            public abstract boolean isActive();
+
+            /**
              * Returns the total time (in 1/100 sec) spent executing in user code.
              *
              * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
@@ -440,21 +473,76 @@
         }
     }
 
+    public final static class HistoryTag {
+        public String string;
+        public int uid;
+
+        public int poolIdx;
+
+        public void setTo(HistoryTag o) {
+            string = o.string;
+            uid = o.uid;
+            poolIdx = o.poolIdx;
+        }
+
+        public void setTo(String _string, int _uid) {
+            string = _string;
+            uid = _uid;
+            poolIdx = -1;
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(string);
+            dest.writeInt(uid);
+        }
+
+        public void readFromParcel(Parcel src) {
+            string = src.readString();
+            uid = src.readInt();
+            poolIdx = -1;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            HistoryTag that = (HistoryTag) o;
+
+            if (uid != that.uid) return false;
+            if (!string.equals(that.string)) return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = string.hashCode();
+            result = 31 * result + uid;
+            return result;
+        }
+    }
+
     public final static class HistoryItem implements Parcelable {
-        static final String TAG = "HistoryItem";
-        static final boolean DEBUG = false;
-        
         public HistoryItem next;
         
         public long time;
-        
-        public static final byte CMD_NULL = 0;
-        public static final byte CMD_UPDATE = 1;
-        public static final byte CMD_START = 2;
-        public static final byte CMD_OVERFLOW = 3;
-        
+
+        public static final byte CMD_UPDATE = 0;        // These can be written as deltas
+        public static final byte CMD_NULL = -1;
+        public static final byte CMD_START = 4;
+        public static final byte CMD_CURRENT_TIME = 5;
+        public static final byte CMD_OVERFLOW = 6;
+
         public byte cmd = CMD_NULL;
         
+        /**
+         * Return whether the command code is a delta data update.
+         */
+        public boolean isDeltaData() {
+            return cmd == CMD_UPDATE;
+        }
+
         public byte batteryLevel;
         public byte batteryStatus;
         public byte batteryHealth;
@@ -464,50 +552,101 @@
         public char batteryVoltage;
         
         // Constants from SCREEN_BRIGHTNESS_*
-        public static final int STATE_BRIGHTNESS_MASK = 0x0000000f;
         public static final int STATE_BRIGHTNESS_SHIFT = 0;
+        public static final int STATE_BRIGHTNESS_MASK = 0x7;
         // Constants from SIGNAL_STRENGTH_*
-        public static final int STATE_SIGNAL_STRENGTH_MASK = 0x000000f0;
-        public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4;
+        public static final int STATE_SIGNAL_STRENGTH_SHIFT = 3;
+        public static final int STATE_SIGNAL_STRENGTH_MASK = 0x7 << STATE_SIGNAL_STRENGTH_SHIFT;
         // Constants from ServiceState.STATE_*
-        public static final int STATE_PHONE_STATE_MASK = 0x00000f00;
-        public static final int STATE_PHONE_STATE_SHIFT = 8;
+        public static final int STATE_PHONE_STATE_SHIFT = 6;
+        public static final int STATE_PHONE_STATE_MASK = 0x7 << STATE_PHONE_STATE_SHIFT;
         // Constants from DATA_CONNECTION_*
-        public static final int STATE_DATA_CONNECTION_MASK = 0x0000f000;
-        public static final int STATE_DATA_CONNECTION_SHIFT = 12;
-        
+        public static final int STATE_DATA_CONNECTION_SHIFT = 9;
+        public static final int STATE_DATA_CONNECTION_MASK = 0x1f << STATE_DATA_CONNECTION_SHIFT;
+
         // These states always appear directly in the first int token
         // of a delta change; they should be ones that change relatively
         // frequently.
+        public static final int STATE_CPU_RUNNING_FLAG = 1<<31;
         public static final int STATE_WAKE_LOCK_FLAG = 1<<30;
-        public static final int STATE_SENSOR_ON_FLAG = 1<<29;
-        public static final int STATE_GPS_ON_FLAG = 1<<28;
-        public static final int STATE_PHONE_SCANNING_FLAG = 1<<27;
-        public static final int STATE_WIFI_RUNNING_FLAG = 1<<26;
-        public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<25;
-        public static final int STATE_WIFI_SCAN_FLAG = 1<<24;
-        public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<23;
+        public static final int STATE_GPS_ON_FLAG = 1<<29;
+        public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<28;
+        public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
+        public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<26;
+        public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
+        public static final int STATE_WIFI_RUNNING_FLAG = 1<<24;
         // These are on the lower bits used for the command; if they change
         // we need to write another int of data.
+        public static final int STATE_SENSOR_ON_FLAG = 1<<23;
         public static final int STATE_AUDIO_ON_FLAG = 1<<22;
-        public static final int STATE_VIDEO_ON_FLAG = 1<<21;
+        public static final int STATE_PHONE_SCANNING_FLAG = 1<<21;
         public static final int STATE_SCREEN_ON_FLAG = 1<<20;
         public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<19;
         public static final int STATE_PHONE_IN_CALL_FLAG = 1<<18;
         public static final int STATE_WIFI_ON_FLAG = 1<<17;
         public static final int STATE_BLUETOOTH_ON_FLAG = 1<<16;
-        
+
         public static final int MOST_INTERESTING_STATES =
             STATE_BATTERY_PLUGGED_FLAG | STATE_SCREEN_ON_FLAG
             | STATE_GPS_ON_FLAG | STATE_PHONE_IN_CALL_FLAG;
 
         public int states;
 
+        public static final int STATE2_VIDEO_ON_FLAG = 1<<0;
+        public int states2;
+
+        // The wake lock that was acquired at this point.
+        public HistoryTag wakelockTag;
+
+        // Kernel wakeup reason at this point.
+        public HistoryTag wakeReasonTag;
+
+        public static final int EVENT_FLAG_START = 0x8000;
+        public static final int EVENT_FLAG_FINISH = 0x4000;
+
+        // No event in this item.
+        public static final int EVENT_NONE = 0x0000;
+        // Event is about a process that is running.
+        public static final int EVENT_PROC = 0x0001;
+        // Event is about an application package that is in the foreground.
+        public static final int EVENT_FOREGROUND = 0x0002;
+        // Event is about an application package that is at the top of the screen.
+        public static final int EVENT_TOP = 0x0003;
+        // Event is about an application package that is at the top of the screen.
+        public static final int EVENT_SYNC = 0x0004;
+        // Number of event types.
+        public static final int EVENT_COUNT = 0x0005;
+
+        public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
+        public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
+        public static final int EVENT_FOREGROUND_START = EVENT_FOREGROUND | EVENT_FLAG_START;
+        public static final int EVENT_FOREGROUND_FINISH = EVENT_FOREGROUND | EVENT_FLAG_FINISH;
+        public static final int EVENT_TOP_START = EVENT_TOP | EVENT_FLAG_START;
+        public static final int EVENT_TOP_FINISH = EVENT_TOP | EVENT_FLAG_FINISH;
+        public static final int EVENT_SYNC_START = EVENT_SYNC | EVENT_FLAG_START;
+        public static final int EVENT_SYNC_FINISH = EVENT_SYNC | EVENT_FLAG_FINISH;
+
+        // For CMD_EVENT.
+        public int eventCode;
+        public HistoryTag eventTag;
+
+        // Only set for CMD_CURRENT_TIME.
+        public long currentTime;
+
+        // Meta-data when reading.
+        public int numReadInts;
+
+        // Pre-allocated objects.
+        public final HistoryTag localWakelockTag = new HistoryTag();
+        public final HistoryTag localWakeReasonTag = new HistoryTag();
+        public final HistoryTag localEventTag = new HistoryTag();
+
         public HistoryItem() {
         }
         
         public HistoryItem(long time, Parcel src) {
             this.time = time;
+            numReadInts = 2;
             readFromParcel(src);
         }
         
@@ -521,168 +660,70 @@
                     | ((((int)batteryLevel)<<8)&0xff00)
                     | ((((int)batteryStatus)<<16)&0xf0000)
                     | ((((int)batteryHealth)<<20)&0xf00000)
-                    | ((((int)batteryPlugType)<<24)&0xf000000);
+                    | ((((int)batteryPlugType)<<24)&0xf000000)
+                    | (wakelockTag != null ? 0x10000000 : 0)
+                    | (wakeReasonTag != null ? 0x20000000 : 0)
+                    | (eventCode != EVENT_NONE ? 0x40000000 : 0);
             dest.writeInt(bat);
             bat = (((int)batteryTemperature)&0xffff)
                     | ((((int)batteryVoltage)<<16)&0xffff0000);
             dest.writeInt(bat);
             dest.writeInt(states);
+            dest.writeInt(states2);
+            if (wakelockTag != null) {
+                wakelockTag.writeToParcel(dest, flags);
+            }
+            if (wakeReasonTag != null) {
+                wakeReasonTag.writeToParcel(dest, flags);
+            }
+            if (eventCode != EVENT_NONE) {
+                dest.writeInt(eventCode);
+                eventTag.writeToParcel(dest, flags);
+            }
+            if (cmd == CMD_CURRENT_TIME) {
+                dest.writeLong(currentTime);
+            }
         }
 
-        private void readFromParcel(Parcel src) {
+        public void readFromParcel(Parcel src) {
+            int start = src.dataPosition();
             int bat = src.readInt();
             cmd = (byte)(bat&0xff);
             batteryLevel = (byte)((bat>>8)&0xff);
             batteryStatus = (byte)((bat>>16)&0xf);
             batteryHealth = (byte)((bat>>20)&0xf);
             batteryPlugType = (byte)((bat>>24)&0xf);
-            bat = src.readInt();
-            batteryTemperature = (short)(bat&0xffff);
-            batteryVoltage = (char)((bat>>16)&0xffff);
+            int bat2 = src.readInt();
+            batteryTemperature = (short)(bat2&0xffff);
+            batteryVoltage = (char)((bat2>>16)&0xffff);
             states = src.readInt();
-        }
-
-        // Part of initial delta int that specifies the time delta.
-        static final int DELTA_TIME_MASK = 0x3ffff;
-        static final int DELTA_TIME_ABS = 0x3fffd;    // Following is an entire abs update.
-        static final int DELTA_TIME_INT = 0x3fffe;    // The delta is a following int
-        static final int DELTA_TIME_LONG = 0x3ffff;   // The delta is a following long
-        // Part of initial delta int holding the command code.
-        static final int DELTA_CMD_MASK = 0x3;
-        static final int DELTA_CMD_SHIFT = 18;
-        // Flag in delta int: a new battery level int follows.
-        static final int DELTA_BATTERY_LEVEL_FLAG = 1<<20;
-        // Flag in delta int: a new full state and battery status int follows.
-        static final int DELTA_STATE_FLAG = 1<<21;
-        static final int DELTA_STATE_MASK = 0xffc00000;
-        
-        public void writeDelta(Parcel dest, HistoryItem last) {
-            if (last == null || last.cmd != CMD_UPDATE) {
-                dest.writeInt(DELTA_TIME_ABS);
-                writeToParcel(dest, 0);
-                return;
-            }
-            
-            final long deltaTime = time - last.time;
-            final int lastBatteryLevelInt = last.buildBatteryLevelInt();
-            final int lastStateInt = last.buildStateInt();
-            
-            int deltaTimeToken;
-            if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
-                deltaTimeToken = DELTA_TIME_LONG;
-            } else if (deltaTime >= DELTA_TIME_ABS) {
-                deltaTimeToken = DELTA_TIME_INT;
+            states2 = src.readInt();
+            if ((bat&0x10000000) != 0) {
+                wakelockTag = localWakelockTag;
+                wakelockTag.readFromParcel(src);
             } else {
-                deltaTimeToken = (int)deltaTime;
+                wakelockTag = null;
             }
-            int firstToken = deltaTimeToken
-                    | (cmd<<DELTA_CMD_SHIFT)
-                    | (states&DELTA_STATE_MASK);
-            final int batteryLevelInt = buildBatteryLevelInt();
-            final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
-            if (batteryLevelIntChanged) {
-                firstToken |= DELTA_BATTERY_LEVEL_FLAG;
-            }
-            final int stateInt = buildStateInt();
-            final boolean stateIntChanged = stateInt != lastStateInt;
-            if (stateIntChanged) {
-                firstToken |= DELTA_STATE_FLAG;
-            }
-            dest.writeInt(firstToken);
-            if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
-                    + " deltaTime=" + deltaTime);
-            
-            if (deltaTimeToken >= DELTA_TIME_INT) {
-                if (deltaTimeToken == DELTA_TIME_INT) {
-                    if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
-                    dest.writeInt((int)deltaTime);
-                } else {
-                    if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
-                    dest.writeLong(deltaTime);
-                }
-            }
-            if (batteryLevelIntChanged) {
-                dest.writeInt(batteryLevelInt);
-                if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
-                        + Integer.toHexString(batteryLevelInt)
-                        + " batteryLevel=" + batteryLevel
-                        + " batteryTemp=" + batteryTemperature
-                        + " batteryVolt=" + (int)batteryVoltage);
-            }
-            if (stateIntChanged) {
-                dest.writeInt(stateInt);
-                if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
-                        + Integer.toHexString(stateInt)
-                        + " batteryStatus=" + batteryStatus
-                        + " batteryHealth=" + batteryHealth
-                        + " batteryPlugType=" + batteryPlugType
-                        + " states=0x" + Integer.toHexString(states));
-            }
-        }
-        
-        private int buildBatteryLevelInt() {
-            return ((((int)batteryLevel)<<25)&0xfe000000)
-                    | ((((int)batteryTemperature)<<14)&0x01ffc000)
-                    | (((int)batteryVoltage)&0x00003fff);
-        }
-        
-        private int buildStateInt() {
-            return ((((int)batteryStatus)<<28)&0xf0000000)
-                    | ((((int)batteryHealth)<<24)&0x0f000000)
-                    | ((((int)batteryPlugType)<<22)&0x00c00000)
-                    | (states&(~DELTA_STATE_MASK));
-        }
-        
-        public void readDelta(Parcel src) {
-            int firstToken = src.readInt();
-            int deltaTimeToken = firstToken&DELTA_TIME_MASK;
-            cmd = (byte)((firstToken>>DELTA_CMD_SHIFT)&DELTA_CMD_MASK);
-            if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
-                    + " deltaTimeToken=" + deltaTimeToken);
-            
-            if (deltaTimeToken < DELTA_TIME_ABS) {
-                time += deltaTimeToken;
-            } else if (deltaTimeToken == DELTA_TIME_ABS) {
-                time = src.readLong();
-                readFromParcel(src);
-                return;
-            } else if (deltaTimeToken == DELTA_TIME_INT) {
-                int delta = src.readInt();
-                time += delta;
-                if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
+            if ((bat&0x20000000) != 0) {
+                wakeReasonTag = localWakeReasonTag;
+                wakeReasonTag.readFromParcel(src);
             } else {
-                long delta = src.readLong();
-                if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + time);
-                time += delta;
+                wakeReasonTag = null;
             }
-            
-            if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
-                int batteryLevelInt = src.readInt();
-                batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
-                batteryTemperature = (short)((batteryLevelInt<<7)>>21);
-                batteryVoltage = (char)(batteryLevelInt&0x3fff);
-                if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
-                        + Integer.toHexString(batteryLevelInt)
-                        + " batteryLevel=" + batteryLevel
-                        + " batteryTemp=" + batteryTemperature
-                        + " batteryVolt=" + (int)batteryVoltage);
-            }
-            
-            if ((firstToken&DELTA_STATE_FLAG) != 0) {
-                int stateInt = src.readInt();
-                states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
-                batteryStatus = (byte)((stateInt>>28)&0xf);
-                batteryHealth = (byte)((stateInt>>24)&0xf);
-                batteryPlugType = (byte)((stateInt>>22)&0x3);
-                if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
-                        + Integer.toHexString(stateInt)
-                        + " batteryStatus=" + batteryStatus
-                        + " batteryHealth=" + batteryHealth
-                        + " batteryPlugType=" + batteryPlugType
-                        + " states=0x" + Integer.toHexString(states));
+            if ((bat&0x40000000) != 0) {
+                eventCode = src.readInt();
+                eventTag = localEventTag;
+                eventTag.readFromParcel(src);
             } else {
-                states = (firstToken&DELTA_STATE_MASK) | (states&(~DELTA_STATE_MASK));
+                eventCode = EVENT_NONE;
+                eventTag = null;
             }
+            if (cmd == CMD_CURRENT_TIME) {
+                currentTime = src.readLong();
+            } else {
+                currentTime = 0;
+            }
+            numReadInts += (src.dataPosition()-start)/4;
         }
 
         public void clear() {
@@ -695,23 +736,26 @@
             batteryTemperature = 0;
             batteryVoltage = 0;
             states = 0;
+            states2 = 0;
+            wakelockTag = null;
+            wakeReasonTag = null;
+            eventCode = EVENT_NONE;
+            eventTag = null;
         }
         
         public void setTo(HistoryItem o) {
             time = o.time;
             cmd = o.cmd;
-            batteryLevel = o.batteryLevel;
-            batteryStatus = o.batteryStatus;
-            batteryHealth = o.batteryHealth;
-            batteryPlugType = o.batteryPlugType;
-            batteryTemperature = o.batteryTemperature;
-            batteryVoltage = o.batteryVoltage;
-            states = o.states;
+            setToCommon(o);
         }
 
         public void setTo(long time, byte cmd, HistoryItem o) {
             this.time = time;
             this.cmd = cmd;
+            setToCommon(o);
+        }
+
+        private void setToCommon(HistoryItem o) {
             batteryLevel = o.batteryLevel;
             batteryStatus = o.batteryStatus;
             batteryHealth = o.batteryHealth;
@@ -719,16 +763,70 @@
             batteryTemperature = o.batteryTemperature;
             batteryVoltage = o.batteryVoltage;
             states = o.states;
+            states2 = o.states2;
+            if (o.wakelockTag != null) {
+                wakelockTag = localWakelockTag;
+                wakelockTag.setTo(o.wakelockTag);
+            } else {
+                wakelockTag = null;
+            }
+            if (o.wakeReasonTag != null) {
+                wakeReasonTag = localWakeReasonTag;
+                wakeReasonTag.setTo(o.wakeReasonTag);
+            } else {
+                wakeReasonTag = null;
+            }
+            eventCode = o.eventCode;
+            if (o.eventTag != null) {
+                eventTag = localEventTag;
+                eventTag.setTo(o.eventTag);
+            } else {
+                eventTag = null;
+            }
+            currentTime = o.currentTime;
         }
 
-        public boolean same(HistoryItem o) {
+        public boolean sameNonEvent(HistoryItem o) {
             return batteryLevel == o.batteryLevel
                     && batteryStatus == o.batteryStatus
                     && batteryHealth == o.batteryHealth
                     && batteryPlugType == o.batteryPlugType
                     && batteryTemperature == o.batteryTemperature
                     && batteryVoltage == o.batteryVoltage
-                    && states == o.states;
+                    && states == o.states
+                    && states2 == o.states2
+                    && currentTime == o.currentTime;
+        }
+
+        public boolean same(HistoryItem o) {
+            if (!sameNonEvent(o) || eventCode != o.eventCode) {
+                return false;
+            }
+            if (wakelockTag != o.wakelockTag) {
+                if (wakelockTag == null || o.wakelockTag == null) {
+                    return false;
+                }
+                if (!wakelockTag.equals(o.wakelockTag)) {
+                    return false;
+                }
+            }
+            if (wakeReasonTag != o.wakeReasonTag) {
+                if (wakeReasonTag == null || o.wakeReasonTag == null) {
+                    return false;
+                }
+                if (!wakeReasonTag.equals(o.wakeReasonTag)) {
+                    return false;
+                }
+            }
+            if (eventTag != o.eventTag) {
+                if (eventTag == null || o.eventTag == null) {
+                    return false;
+                }
+                if (!eventTag.equals(o.eventTag)) {
+                    return false;
+                }
+            }
+            return true;
         }
     }
     
@@ -736,25 +834,44 @@
         public final int mask;
         public final int shift;
         public final String name;
+        public final String shortName;
         public final String[] values;
+        public final String[] shortValues;
         
-        public BitDescription(int mask, String name) {
+        public BitDescription(int mask, String name, String shortName) {
             this.mask = mask;
             this.shift = -1;
             this.name = name;
+            this.shortName = shortName;
             this.values = null;
+            this.shortValues = null;
         }
         
-        public BitDescription(int mask, int shift, String name, String[] values) {
+        public BitDescription(int mask, int shift, String name, String shortName,
+                String[] values, String[] shortValues) {
             this.mask = mask;
             this.shift = shift;
             this.name = name;
+            this.shortName = shortName;
             this.values = values;
+            this.shortValues = shortValues;
         }
     }
     
+    public abstract int getHistoryTotalSize();
+
+    public abstract int getHistoryUsedSize();
+
     public abstract boolean startIteratingHistoryLocked();
 
+    public abstract int getHistoryStringPoolSize();
+
+    public abstract int getHistoryStringPoolBytes();
+
+    public abstract String getHistoryTagPoolString(int index);
+
+    public abstract int getHistoryTagPoolUid(int index);
+
     public abstract boolean getNextHistoryLocked(HistoryItem out);
 
     public abstract void finishIteratingHistoryLocked();
@@ -781,8 +898,15 @@
      * 
      * {@hide}
      */
-    public abstract long getScreenOnTime(long batteryRealtime, int which);
+    public abstract long getScreenOnTime(long elapsedRealtimeUs, int which);
     
+    /**
+     * Returns the number of times the screen was turned on.
+     *
+     * {@hide}
+     */
+    public abstract int getScreenOnCount(int which);
+
     public static final int SCREEN_BRIGHTNESS_DARK = 0;
     public static final int SCREEN_BRIGHTNESS_DIM = 1;
     public static final int SCREEN_BRIGHTNESS_MEDIUM = 2;
@@ -793,6 +917,10 @@
         "dark", "dim", "medium", "light", "bright"
     };
     
+    static final String[] SCREEN_BRIGHTNESS_SHORT_NAMES = {
+        "0", "1", "2", "3", "4"
+    };
+
     public static final int NUM_SCREEN_BRIGHTNESS_BINS = 5;
     
     /**
@@ -802,7 +930,7 @@
      * {@hide}
      */
     public abstract long getScreenBrightnessTime(int brightnessBin,
-            long batteryRealtime, int which);
+            long elapsedRealtimeUs, int which);
 
     public abstract int getInputEventCount(int which);
     
@@ -812,16 +940,23 @@
      * 
      * {@hide}
      */
-    public abstract long getPhoneOnTime(long batteryRealtime, int which);
+    public abstract long getPhoneOnTime(long elapsedRealtimeUs, int which);
     
     /**
+     * Returns the number of times a phone call was activated.
+     *
+     * {@hide}
+     */
+    public abstract int getPhoneOnCount(int which);
+
+    /**
      * Returns the time in microseconds that the phone has been running with
      * the given signal strength.
      * 
      * {@hide}
      */
     public abstract long getPhoneSignalStrengthTime(int strengthBin,
-            long batteryRealtime, int which);
+            long elapsedRealtimeUs, int which);
 
     /**
      * Returns the time in microseconds that the phone has been trying to
@@ -830,7 +965,7 @@
      * {@hide}
      */
     public abstract long getPhoneSignalScanningTime(
-            long batteryRealtime, int which);
+            long elapsedRealtimeUs, int which);
 
     /**
      * Returns the number of times the phone has entered the given signal strength.
@@ -839,6 +974,46 @@
      */
     public abstract int getPhoneSignalStrengthCount(int strengthBin, int which);
 
+    /**
+     * Returns the time in microseconds that the mobile network has been active
+     * (in a high power state).
+     *
+     * {@hide}
+     */
+    public abstract long getMobileRadioActiveTime(long elapsedRealtimeUs, int which);
+
+    /**
+     * Returns the number of times that the mobile network has transitioned to the
+     * active state.
+     *
+     * {@hide}
+     */
+    public abstract int getMobileRadioActiveCount(int which);
+
+    /**
+     * Returns the time in microseconds that is the difference between the mobile radio
+     * time we saw based on the elapsed timestamp when going down vs. the given time stamp
+     * from the radio.
+     *
+     * {@hide}
+     */
+    public abstract long getMobileRadioActiveAdjustedTime(int which);
+
+    /**
+     * Returns the time in microseconds that the mobile network has been active
+     * (in a high power state) but not being able to blame on an app.
+     *
+     * {@hide}
+     */
+    public abstract long getMobileRadioActiveUnknownTime(int which);
+
+    /**
+     * Return count of number of times radio was up that could not be blamed on apps.
+     *
+     * {@hide}
+     */
+    public abstract int getMobileRadioActiveUnknownCount(int which);
+
     public static final int DATA_CONNECTION_NONE = 0;
     public static final int DATA_CONNECTION_GPRS = 1;
     public static final int DATA_CONNECTION_EDGE = 2;
@@ -872,7 +1047,7 @@
      * {@hide}
      */
     public abstract long getPhoneDataConnectionTime(int dataType,
-            long batteryRealtime, int which);
+            long elapsedRealtimeUs, int which);
 
     /**
      * Returns the number of times the phone has entered the given data
@@ -881,36 +1056,53 @@
      * {@hide}
      */
     public abstract int getPhoneDataConnectionCount(int dataType, int which);
-    
+
     public static final BitDescription[] HISTORY_STATE_DESCRIPTIONS
             = new BitDescription[] {
-        new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged"),
-        new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen"),
-        new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps"),
-        new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call"),
-        new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning"),
-        new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi"),
-        new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running"),
-        new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock"),
-        new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan"),
-        new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast"),
-        new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth"),
-        new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio"),
-        new BitDescription(HistoryItem.STATE_VIDEO_ON_FLAG, "video"),
-        new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock"),
-        new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor"),
-        new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
-                HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness",
-                SCREEN_BRIGHTNESS_NAMES),
-        new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
-                HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength",
-                SignalStrength.SIGNAL_STRENGTH_NAMES),
-        new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
-                HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state",
-                new String[] {"in", "out", "emergency", "off"}),
+        new BitDescription(HistoryItem.STATE_CPU_RUNNING_FLAG, "running", "r"),
+        new BitDescription(HistoryItem.STATE_WAKE_LOCK_FLAG, "wake_lock", "w"),
+        new BitDescription(HistoryItem.STATE_SENSOR_ON_FLAG, "sensor", "s"),
+        new BitDescription(HistoryItem.STATE_GPS_ON_FLAG, "gps", "g"),
+        new BitDescription(HistoryItem.STATE_WIFI_FULL_LOCK_FLAG, "wifi_full_lock", "Wl"),
+        new BitDescription(HistoryItem.STATE_WIFI_SCAN_FLAG, "wifi_scan", "Ws"),
+        new BitDescription(HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG, "wifi_multicast", "Wm"),
+        new BitDescription(HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG, "mobile_radio", "Pr"),
+        new BitDescription(HistoryItem.STATE_WIFI_RUNNING_FLAG, "wifi_running", "Wr"),
+        new BitDescription(HistoryItem.STATE_PHONE_SCANNING_FLAG, "phone_scanning", "Psc"),
+        new BitDescription(HistoryItem.STATE_AUDIO_ON_FLAG, "audio", "a"),
+        new BitDescription(HistoryItem.STATE_SCREEN_ON_FLAG, "screen", "S"),
+        new BitDescription(HistoryItem.STATE_BATTERY_PLUGGED_FLAG, "plugged", "BP"),
+        new BitDescription(HistoryItem.STATE_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
+        new BitDescription(HistoryItem.STATE_WIFI_ON_FLAG, "wifi", "W"),
+        new BitDescription(HistoryItem.STATE_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
         new BitDescription(HistoryItem.STATE_DATA_CONNECTION_MASK,
-                HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn",
-                DATA_CONNECTION_NAMES),
+                HistoryItem.STATE_DATA_CONNECTION_SHIFT, "data_conn", "Pcn",
+                DATA_CONNECTION_NAMES, DATA_CONNECTION_NAMES),
+        new BitDescription(HistoryItem.STATE_PHONE_STATE_MASK,
+                HistoryItem.STATE_PHONE_STATE_SHIFT, "phone_state", "Pst",
+                new String[] {"in", "out", "emergency", "off"},
+                new String[] {"in", "out", "em", "off"}),
+        new BitDescription(HistoryItem.STATE_SIGNAL_STRENGTH_MASK,
+                HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT, "signal_strength", "Pss",
+                SignalStrength.SIGNAL_STRENGTH_NAMES, new String[] {
+                    "0", "1", "2", "3", "4"
+        }),
+        new BitDescription(HistoryItem.STATE_BRIGHTNESS_MASK,
+                HistoryItem.STATE_BRIGHTNESS_SHIFT, "brightness", "Sb",
+                SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
+    };
+
+    public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
+            = new BitDescription[] {
+        new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
+    };
+
+    public static final String[] HISTORY_EVENT_NAMES = new String[] {
+            "null", "proc", "fg", "top", "sync"
+    };
+
+    public static final String[] HISTORY_EVENT_CHECKIN_NAMES = new String[] {
+            "Enl", "Epr", "Efg", "Etp", "Esy"
     };
 
     /**
@@ -919,7 +1111,7 @@
      * 
      * {@hide}
      */
-    public abstract long getWifiOnTime(long batteryRealtime, int which);
+    public abstract long getWifiOnTime(long elapsedRealtimeUs, int which);
 
     /**
      * Returns the time in microseconds that wifi has been on and the driver has
@@ -927,7 +1119,38 @@
      *
      * {@hide}
      */
-    public abstract long getGlobalWifiRunningTime(long batteryRealtime, int which);
+    public abstract long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which);
+
+    public static final int WIFI_STATE_OFF = 0;
+    public static final int WIFI_STATE_OFF_SCANNING = 1;
+    public static final int WIFI_STATE_ON_NO_NETWORKS = 2;
+    public static final int WIFI_STATE_ON_DISCONNECTED = 3;
+    public static final int WIFI_STATE_ON_CONNECTED_STA = 4;
+    public static final int WIFI_STATE_ON_CONNECTED_P2P = 5;
+    public static final int WIFI_STATE_ON_CONNECTED_STA_P2P = 6;
+    public static final int WIFI_STATE_SOFT_AP = 7;
+
+    static final String[] WIFI_STATE_NAMES = {
+        "off", "scanning", "no_net", "disconn",
+        "sta", "p2p", "sta_p2p", "soft_ap"
+    };
+
+    public static final int NUM_WIFI_STATES = WIFI_STATE_SOFT_AP+1;
+
+    /**
+     * Returns the time in microseconds that WiFi has been running in the given state.
+     *
+     * {@hide}
+     */
+    public abstract long getWifiStateTime(int wifiState,
+            long elapsedRealtimeUs, int which);
+
+    /**
+     * Returns the number of times that WiFi has entered the given state.
+     *
+     * {@hide}
+     */
+    public abstract int getWifiStateCount(int wifiState, int which);
 
     /**
      * Returns the time in microseconds that bluetooth has been on while the device was
@@ -935,16 +1158,51 @@
      * 
      * {@hide}
      */
-    public abstract long getBluetoothOnTime(long batteryRealtime, int which);
+    public abstract long getBluetoothOnTime(long elapsedRealtimeUs, 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 abstract int getBluetoothPingCount();
 
-    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_BYTES + 1;
+    public static final int BLUETOOTH_STATE_INACTIVE = 0;
+    public static final int BLUETOOTH_STATE_LOW = 1;
+    public static final int BLUETOOTH_STATE_MEDIUM = 2;
+    public static final int BLUETOOTH_STATE_HIGH = 3;
 
-    public abstract long getNetworkActivityCount(int type, int which);
+    static final String[] BLUETOOTH_STATE_NAMES = {
+        "inactive", "low", "med", "high"
+    };
+
+    public static final int NUM_BLUETOOTH_STATES = BLUETOOTH_STATE_HIGH +1;
+
+    /**
+     * Returns the time in microseconds that Bluetooth has been running in the
+     * given active state.
+     *
+     * {@hide}
+     */
+    public abstract long getBluetoothStateTime(int bluetoothState,
+            long elapsedRealtimeUs, int which);
+
+    /**
+     * Returns the number of times that Bluetooth has entered the given active state.
+     *
+     * {@hide}
+     */
+    public abstract int getBluetoothStateCount(int bluetoothState, int which);
+
+    public static final int NETWORK_MOBILE_RX_DATA = 0;
+    public static final int NETWORK_MOBILE_TX_DATA = 1;
+    public static final int NETWORK_WIFI_RX_DATA = 2;
+    public static final int NETWORK_WIFI_TX_DATA = 3;
+
+    public static final int NUM_NETWORK_ACTIVITY_TYPES = NETWORK_WIFI_TX_DATA + 1;
+
+    public abstract long getNetworkActivityBytes(int type, int which);
+    public abstract long getNetworkActivityPackets(int type, int which);
+
+    /**
+     * Return the wall clock time when battery stats data collection started.
+     */
+    public abstract long getStartClockTime();
 
     /**
      * Return whether we are currently running on battery.
@@ -964,19 +1222,6 @@
     public abstract long getBatteryUptime(long curTime);
 
     /**
-     * @deprecated use getRadioDataUptime
-     */
-    public long getRadioDataUptimeMs() {
-        return getRadioDataUptime() / 1000;
-    }
-
-    /**
-     * Returns the time that the radio was on for data transfers.
-     * @return the uptime in microseconds while unplugged
-     */
-    public abstract long getRadioDataUptime();
-
-    /**
      * Returns the current battery realtime in microseconds.
      *
      * @param curTime the amount of elapsed realtime in microseconds.
@@ -1008,6 +1253,11 @@
     public abstract int getHighDischargeAmountSinceCharge();
 
     /**
+     * Retrieve the discharge amount over the selected discharge period <var>which</var>.
+     */
+    public abstract int getDischargeAmount(int which);
+
+    /**
      * Get the amount the battery has discharged while the screen was on,
      * since the last time power was unplugged.
      */
@@ -1048,6 +1298,22 @@
     public abstract long computeBatteryRealtime(long curTime, int which);
 
     /**
+     * Returns the total, last, or current battery screen off uptime in microseconds.
+     *
+     * @param curTime the elapsed realtime in microseconds.
+     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     */
+    public abstract long computeBatteryScreenOffUptime(long curTime, int which);
+
+    /**
+     * Returns the total, last, or current battery screen off realtime in microseconds.
+     *
+     * @param curTime the current elapsed realtime in microseconds.
+     * @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
+     */
+    public abstract long computeBatteryScreenOffRealtime(long curTime, int which);
+
+    /**
      * Returns the total, last, or current uptime in microseconds.
      *
      * @param curTime the current elapsed realtime in microseconds.
@@ -1063,11 +1329,15 @@
      */
     public abstract long computeRealtime(long curTime, int which);
     
+    public abstract Map<String, ? extends LongCounter> getWakeupReasonStats();
+
     public abstract Map<String, ? extends Timer> getKernelWakelockStats();
 
     /** Returns the number of different speeds that the CPU can run at */
     public abstract int getCpuSpeedSteps();
 
+    public abstract void writeToParcelWithoutUids(Parcel out, int flags);
+
     private final static void formatTimeRaw(StringBuilder out, long seconds) {
         long days = seconds / (60 * 60 * 24);
         if (days != 0) {
@@ -1096,23 +1366,30 @@
         }
     }
 
-    private final static void formatTime(StringBuilder sb, long time) {
+    public final static void formatTime(StringBuilder sb, long time) {
         long sec = time / 100;
         formatTimeRaw(sb, sec);
         sb.append((time - (sec * 100)) * 10);
         sb.append("ms ");
     }
 
-    private final static void formatTimeMs(StringBuilder sb, long time) {
+    public final static void formatTimeMs(StringBuilder sb, long time) {
         long sec = time / 1000;
         formatTimeRaw(sb, sec);
         sb.append(time - (sec * 1000));
         sb.append("ms ");
     }
 
-    private final String formatRatioLocked(long num, long den) {
+    public final static void formatTimeMsNoSpace(StringBuilder sb, long time) {
+        long sec = time / 1000;
+        formatTimeRaw(sb, sec);
+        sb.append(time - (sec * 1000));
+        sb.append("ms");
+    }
+
+    public final String formatRatioLocked(long num, long den) {
         if (den == 0L) {
-            return "---%";
+            return "--%";
         }
         float perc = ((float)num) / ((float)den) * 100;
         mFormatBuilder.setLength(0);
@@ -1120,7 +1397,7 @@
         return mFormatBuilder.toString();
     }
 
-    private final String formatBytesLocked(long bytes) {
+    final String formatBytesLocked(long bytes) {
         mFormatBuilder.setLength(0);
         
         if (bytes < BYTES_PER_KB) {
@@ -1137,10 +1414,10 @@
         }
     }
 
-    private static long computeWakeLock(Timer timer, long batteryRealtime, int which) {
+    private static long computeWakeLock(Timer timer, long elapsedRealtimeUs, int which) {
         if (timer != null) {
             // Convert from microseconds to milliseconds with rounding
-            long totalTimeMicros = timer.getTotalTimeLocked(batteryRealtime, which);
+            long totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
             long totalTimeMillis = (totalTimeMicros + 500) / 1000;
             return totalTimeMillis;
         }
@@ -1151,17 +1428,17 @@
      *
      * @param sb a StringBuilder object.
      * @param timer a Timer object contining the wakelock times.
-     * @param batteryRealtime the current on-battery time in microseconds.
+     * @param elapsedRealtimeUs the current on-battery time in microseconds.
      * @param name the name of the wakelock.
      * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
      * @param linePrefix a String to be prepended to each line of output.
      * @return the line prefix
      */
     private static final String printWakeLock(StringBuilder sb, Timer timer,
-            long batteryRealtime, String name, int which, String linePrefix) {
+            long elapsedRealtimeUs, String name, int which, String linePrefix) {
         
         if (timer != null) {
-            long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
+            long totalTimeMillis = computeWakeLock(timer, elapsedRealtimeUs, which);
             
             int count = timer.getCountLocked(which);
             if (totalTimeMillis != 0) {
@@ -1185,18 +1462,18 @@
      * 
      * @param sb a StringBuilder object.
      * @param timer a Timer object contining the wakelock times.
-     * @param now the current time in microseconds.
+     * @param elapsedRealtimeUs the current time in microseconds.
      * @param name the name of the wakelock.
      * @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
      * @param linePrefix a String to be prepended to each line of output.
      * @return the line prefix
      */
-    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer, long now,
-            String name, int which, String linePrefix) {
+    private static final String printWakeLockCheckin(StringBuilder sb, Timer timer,
+            long elapsedRealtimeUs, String name, int which, String linePrefix) {
         long totalTimeMicros = 0;
         int count = 0;
         if (timer != null) {
-            totalTimeMicros = timer.getTotalTimeLocked(now, which);
+            totalTimeMicros = timer.getTotalTimeLocked(elapsedRealtimeUs, which);
             count = timer.getCountLocked(which); 
         }
         sb.append(linePrefix);
@@ -1234,20 +1511,22 @@
      * 
      * NOTE: all times are expressed in 'ms'.
      */
-    public final void dumpCheckinLocked(PrintWriter pw, int which, int reqUid) {
+    public final void dumpCheckinLocked(Context context, PrintWriter pw, int which, int reqUid) {
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
-        final long batteryRealtime = getBatteryRealtime(rawRealtime);
         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
+        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
+        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
+                which);
         final long totalRealtime = computeRealtime(rawRealtime, which);
         final long totalUptime = computeUptime(rawUptime, which);
-        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
-        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
-        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
-        final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
-        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
+        final long screenOnTime = getScreenOnTime(rawRealtime, which);
+        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
+        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
+        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
+        final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
        
         StringBuilder sb = new StringBuilder(128);
         
@@ -1260,22 +1539,16 @@
         dumpLine(pw, 0 /* uid */, category, BATTERY_DATA, 
                 which == STATS_SINCE_CHARGED ? getStartCount() : "N/A",
                 whichBatteryRealtime / 1000, whichBatteryUptime / 1000,
-                totalRealtime / 1000, totalUptime / 1000); 
+                totalRealtime / 1000, totalUptime / 1000,
+                getStartClockTime(),
+                whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000);
         
-        // Calculate total network and wakelock times across all uids.
-        long mobileRxTotal = 0;
-        long mobileTxTotal = 0;
-        long wifiRxTotal = 0;
-        long wifiTxTotal = 0;
+        // Calculate wakelock times across all uids.
         long fullWakeLockTimeTotal = 0;
         long partialWakeLockTimeTotal = 0;
         
         for (int iu = 0; iu < NU; iu++) {
             Uid u = uidStats.valueAt(iu);
-            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) {
@@ -1285,59 +1558,97 @@
                     
                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
                     if (fullWakeTimer != null) {
-                        fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(batteryRealtime, which);
+                        fullWakeLockTimeTotal += fullWakeTimer.getTotalTimeLocked(rawRealtime,
+                                which);
                     }
 
                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
                     if (partialWakeTimer != null) {
                         partialWakeLockTimeTotal += partialWakeTimer.getTotalTimeLocked(
-                            batteryRealtime, which);
+                            rawRealtime, which);
                     }
                 }
             }
         }
         
+        long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+        long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+        long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+        long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+        long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+        long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+        long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+        long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+
+        // Dump network stats
+        dumpLine(pw, 0 /* uid */, category, GLOBAL_NETWORK_DATA,
+                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
+                mobileRxTotalPackets, mobileTxTotalPackets, wifiRxTotalPackets, wifiTxTotalPackets);
+
         // Dump misc stats
         dumpLine(pw, 0 /* uid */, category, MISC_DATA,
                 screenOnTime / 1000, phoneOnTime / 1000, wifiOnTime / 1000,
                 wifiRunningTime / 1000, bluetoothOnTime / 1000,
-                mobileRxTotal, mobileTxTotal, wifiRxTotal, wifiTxTotal,
+                mobileRxTotalBytes, mobileTxTotalBytes, wifiRxTotalBytes, wifiTxTotalBytes,
                 fullWakeLockTimeTotal, partialWakeLockTimeTotal,
-                getInputEventCount(which));
+                getInputEventCount(which), getMobileRadioActiveTime(rawRealtime, which),
+                getMobileRadioActiveAdjustedTime(which));
         
         // Dump screen brightness stats
         Object[] args = new Object[NUM_SCREEN_BRIGHTNESS_BINS];
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            args[i] = getScreenBrightnessTime(i, batteryRealtime, which) / 1000;
+            args[i] = getScreenBrightnessTime(i, rawRealtime, which) / 1000;
         }
         dumpLine(pw, 0 /* uid */, category, SCREEN_BRIGHTNESS_DATA, args);
         
         // Dump signal strength stats
         args = new Object[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
+            args[i] = getPhoneSignalStrengthTime(i, rawRealtime, which) / 1000;
         }
         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
         dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
-                getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
+                getPhoneSignalScanningTime(rawRealtime, which) / 1000);
         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
             args[i] = getPhoneSignalStrengthCount(i, which);
         }
         dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_COUNT_DATA, args);
-        
+
         // Dump network type stats
         args = new Object[NUM_DATA_CONNECTION_TYPES];
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
-            args[i] = getPhoneDataConnectionTime(i, batteryRealtime, which) / 1000;
+            args[i] = getPhoneDataConnectionTime(i, rawRealtime, which) / 1000;
         }
         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_TIME_DATA, args);
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
             args[i] = getPhoneDataConnectionCount(i, which);
         }
         dumpLine(pw, 0 /* uid */, category, DATA_CONNECTION_COUNT_DATA, args);
-        
+
+        // Dump wifi state stats
+        args = new Object[NUM_WIFI_STATES];
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            args[i] = getWifiStateTime(i, rawRealtime, which) / 1000;
+        }
+        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_TIME_DATA, args);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            args[i] = getWifiStateCount(i, which);
+        }
+        dumpLine(pw, 0 /* uid */, category, WIFI_STATE_COUNT_DATA, args);
+
+        // Dump bluetooth state stats
+        args = new Object[NUM_BLUETOOTH_STATES];
+        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
+            args[i] = getBluetoothStateTime(i, rawRealtime, which) / 1000;
+        }
+        dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_TIME_DATA, args);
+        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
+            args[i] = getBluetoothStateCount(i, which);
+        }
+        dumpLine(pw, 0 /* uid */, category, BLUETOOTH_STATE_COUNT_DATA, args);
+
         if (which == STATS_SINCE_UNPLUGGED) {
-            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(), 
+            dumpLine(pw, 0 /* uid */, category, BATTERY_LEVEL_DATA, getDischargeStartLevel(),
                     getDischargeCurrentLevel());
         }
         
@@ -1353,18 +1664,79 @@
         }
         
         if (reqUid < 0) {
-            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
+            Map<String, ? extends Timer> kernelWakelocks = getKernelWakelockStats();
             if (kernelWakelocks.size() > 0) {
-                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
+                for (Map.Entry<String, ? extends Timer> ent : kernelWakelocks.entrySet()) {
                     sb.setLength(0);
-                    printWakeLockCheckin(sb, ent.getValue(), batteryRealtime, null, which, "");
-    
-                    dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(), 
+                    printWakeLockCheckin(sb, ent.getValue(), rawRealtime, null, which, "");
+                    dumpLine(pw, 0 /* uid */, category, KERNEL_WAKELOCK_DATA, ent.getKey(),
                             sb.toString());
                 }
             }
+            Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats();
+            if (wakeupReasons.size() > 0) {
+                for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) {
+                    dumpLine(pw, 0 /* uid */, category, WAKEUP_REASON_DATA,
+                            "\"" + ent.getKey() + "\"", ent.getValue().getCountLocked(which));
+                }
+            }
         }
         
+        BatteryStatsHelper helper = new BatteryStatsHelper(context);
+        helper.create(this);
+        helper.refreshStats(which, UserHandle.USER_ALL);
+        List<BatterySipper> sippers = helper.getUsageList();
+        if (sippers != null && sippers.size() > 0) {
+            dumpLine(pw, 0 /* uid */, category, POWER_USE_SUMMARY_DATA,
+                    BatteryStatsHelper.makemAh(helper.getPowerProfile().getBatteryCapacity()),
+                    BatteryStatsHelper.makemAh(helper.getComputedPower()),
+                    BatteryStatsHelper.makemAh(helper.getMinDrainedPower()),
+                    BatteryStatsHelper.makemAh(helper.getMaxDrainedPower()));
+            for (int i=0; i<sippers.size(); i++) {
+                BatterySipper bs = sippers.get(i);
+                int uid = 0;
+                String label;
+                switch (bs.drainType) {
+                    case IDLE:
+                        label="idle";
+                        break;
+                    case CELL:
+                        label="cell";
+                        break;
+                    case PHONE:
+                        label="phone";
+                        break;
+                    case WIFI:
+                        label="wifi";
+                        break;
+                    case BLUETOOTH:
+                        label="blue";
+                        break;
+                    case SCREEN:
+                        label="scrn";
+                        break;
+                    case APP:
+                        uid = bs.uidObj.getUid();
+                        label = "uid";
+                        break;
+                    case USER:
+                        uid = UserHandle.getUid(bs.userId, 0);
+                        label = "user";
+                        break;
+                    case UNACCOUNTED:
+                        label = "unacc";
+                        break;
+                    case OVERCOUNTED:
+                        label = "over";
+                        break;
+                    default:
+                        label = "???";
+                }
+                dumpLine(pw, uid, category, POWER_USE_ITEM_DATA, label,
+                        BatteryStatsHelper.makemAh(bs.value));
+            }
+        }
+
         for (int iu = 0; iu < NU; iu++) {
             final int uid = uidStats.keyAt(iu);
             if (reqUid >= 0 && uid != reqUid) {
@@ -1372,16 +1744,28 @@
             }
             Uid u = uidStats.valueAt(iu);
             // Dump Network stats per uid, if any
-            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);
+            long mobileBytesRx = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+            long mobileBytesTx = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+            long wifiBytesRx = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+            long wifiBytesTx = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+            long mobilePacketsRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+            long mobilePacketsTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+            long mobileActiveTime = u.getMobileRadioActiveTime(which);
+            int mobileActiveCount = u.getMobileRadioActiveCount(which);
+            long wifiPacketsRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+            long wifiPacketsTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+            long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
+            long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
+            long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
 
-            if (mobileRx > 0 || mobileTx > 0 || wifiRx > 0 || wifiTx > 0) {
-                dumpLine(pw, uid, category, NETWORK_DATA, mobileRx, mobileTx, wifiRx, wifiTx);
+            if (mobileBytesRx > 0 || mobileBytesTx > 0 || wifiBytesRx > 0 || wifiBytesTx > 0
+                    || mobilePacketsRx > 0 || mobilePacketsTx > 0 || wifiPacketsRx > 0
+                    || wifiPacketsTx > 0 || mobileActiveTime > 0 || mobileActiveCount > 0) {
+                dumpLine(pw, uid, category, NETWORK_DATA, mobileBytesRx, mobileBytesTx,
+                        wifiBytesRx, wifiBytesTx,
+                        mobilePacketsRx, mobilePacketsTx,
+                        wifiPacketsRx, wifiPacketsTx,
+                        mobileActiveTime, mobileActiveCount);
             }
 
             if (fullWifiLockOnTime != 0 || wifiScanTime != 0
@@ -1411,11 +1795,11 @@
                     String linePrefix = "";
                     sb.setLength(0);
                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), 
-                            batteryRealtime, "f", which, linePrefix);
+                            rawRealtime, "f", which, linePrefix);
                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), 
-                            batteryRealtime, "p", which, linePrefix);
+                            rawRealtime, "p", which, linePrefix);
                     linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), 
-                            batteryRealtime, "w", which, linePrefix);
+                            rawRealtime, "w", which, linePrefix);
                     
                     // Only log if we had at lease one wakelock...
                     if (sb.length() > 0) {
@@ -1437,7 +1821,7 @@
                     Timer timer = se.getSensorTime();
                     if (timer != null) {
                         // Convert from microseconds to milliseconds with rounding
-                        long totalTime = (timer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+                        long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                         int count = timer.getCountLocked(which);
                         if (totalTime != 0) {
                             dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
@@ -1449,7 +1833,7 @@
             Timer vibTimer = u.getVibratorOnTimer();
             if (vibTimer != null) {
                 // Convert from microseconds to milliseconds with rounding
-                long totalTime = (vibTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+                long totalTime = (vibTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                 int count = vibTimer.getCountLocked(which);
                 if (totalTime != 0) {
                     dumpLine(pw, uid, category, VIBRATOR_DATA, totalTime, count);
@@ -1459,7 +1843,7 @@
             Timer fgTimer = u.getForegroundActivityTimer();
             if (fgTimer != null) {
                 // Convert from microseconds to milliseconds with rounding
-                long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+                long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                 int count = fgTimer.getCountLocked(which);
                 if (totalTime != 0) {
                     dumpLine(pw, uid, category, FOREGROUND_DATA, totalTime, count);
@@ -1527,18 +1911,25 @@
         }
     }
 
+    private void printmAh(PrintWriter printer, double power) {
+        printer.print(BatteryStatsHelper.makemAh(power));
+    }
+
     @SuppressWarnings("unused")
-    public final void dumpLocked(PrintWriter pw, String prefix, final int which, int reqUid) {
+    public final void dumpLocked(Context context, PrintWriter pw, String prefix, final int which,
+            int reqUid) {
         final long rawUptime = SystemClock.uptimeMillis() * 1000;
         final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
         final long batteryUptime = getBatteryUptime(rawUptime);
-        final long batteryRealtime = getBatteryRealtime(rawRealtime);
 
         final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
         final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
         final long totalRealtime = computeRealtime(rawRealtime, which);
         final long totalUptime = computeUptime(rawUptime, which);
-        
+        final long whichBatteryScreenOffUptime = computeBatteryScreenOffUptime(rawUptime, which);
+        final long whichBatteryScreenOffRealtime = computeBatteryScreenOffRealtime(rawRealtime,
+                which);
+
         StringBuilder sb = new StringBuilder(128);
         
         SparseArray<? extends Uid> uidStats = getUidStats();
@@ -1556,37 +1947,56 @@
         pw.println(sb.toString());
         sb.setLength(0);
         sb.append(prefix);
+                sb.append("  Time on battery screen off: ");
+                formatTimeMs(sb, whichBatteryScreenOffRealtime / 1000); sb.append("(");
+                sb.append(formatRatioLocked(whichBatteryScreenOffRealtime, totalRealtime));
+                sb.append(") realtime, ");
+                formatTimeMs(sb, whichBatteryScreenOffUptime / 1000);
+                sb.append("(");
+                sb.append(formatRatioLocked(whichBatteryScreenOffUptime, totalRealtime));
+                sb.append(") uptime");
+        pw.println(sb.toString());
+        sb.setLength(0);
+        sb.append(prefix);
                 sb.append("  Total run time: ");
                 formatTimeMs(sb, totalRealtime / 1000);
                 sb.append("realtime, ");
                 formatTimeMs(sb, totalUptime / 1000);
-                sb.append("uptime, ");
+                sb.append("uptime");
         pw.println(sb.toString());
-        
-        final long screenOnTime = getScreenOnTime(batteryRealtime, which);
-        final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
-        final long wifiRunningTime = getGlobalWifiRunningTime(batteryRealtime, which);
-        final long wifiOnTime = getWifiOnTime(batteryRealtime, which);
-        final long bluetoothOnTime = getBluetoothOnTime(batteryRealtime, which);
+        pw.print("  Start clock time: ");
+        pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss", getStartClockTime()).toString());
+
+        final long screenOnTime = getScreenOnTime(rawRealtime, which);
+        final long phoneOnTime = getPhoneOnTime(rawRealtime, which);
+        final long wifiRunningTime = getGlobalWifiRunningTime(rawRealtime, which);
+        final long wifiOnTime = getWifiOnTime(rawRealtime, which);
+        final long bluetoothOnTime = getBluetoothOnTime(rawRealtime, which);
         sb.setLength(0);
         sb.append(prefix);
                 sb.append("  Screen on: "); formatTimeMs(sb, screenOnTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(screenOnTime, whichBatteryRealtime));
-                sb.append("), Input events: "); sb.append(getInputEventCount(which));
-                sb.append(", Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
-                sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
-                sb.append(")");
+                sb.append(") "); sb.append(getScreenOnCount(which));
+                sb.append("x, Input events: "); sb.append(getInputEventCount(which));
         pw.println(sb.toString());
+        if (phoneOnTime != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("  Active phone call: "); formatTimeMs(sb, phoneOnTime / 1000);
+                    sb.append("("); sb.append(formatRatioLocked(phoneOnTime, whichBatteryRealtime));
+                    sb.append(") "); sb.append(getPhoneOnCount(which));
+        }
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Screen brightnesses: ");
+        sb.append("  Screen brightnesses:");
         boolean didOne = false;
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            final long time = getScreenBrightnessTime(i, batteryRealtime, which);
+            final long time = getScreenBrightnessTime(i, rawRealtime, which);
             if (time == 0) {
                 continue;
             }
-            if (didOne) sb.append(", ");
+            sb.append("\n    ");
+            sb.append(prefix);
             didOne = true;
             sb.append(SCREEN_BRIGHTNESS_NAMES[i]);
             sb.append(" ");
@@ -1595,70 +2005,17 @@
             sb.append(formatRatioLocked(time, screenOnTime));
             sb.append(")");
         }
-        if (!didOne) sb.append("No activity");
+        if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
         
-        // Calculate total network and wakelock times across all uids.
-        long mobileRxTotal = 0;
-        long mobileTxTotal = 0;
-        long wifiRxTotal = 0;
-        long wifiTxTotal = 0;
+        // Calculate wakelock times across all uids.
         long fullWakeLockTimeTotalMicros = 0;
         long partialWakeLockTimeTotalMicros = 0;
 
-        final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
-            @Override
-            public int compare(TimerEntry lhs, TimerEntry rhs) {
-                long lhsTime = lhs.mTime;
-                long rhsTime = rhs.mTime;
-                if (lhsTime < rhsTime) {
-                    return 1;
-                }
-                if (lhsTime > rhsTime) {
-                    return -1;
-                }
-                return 0;
-            }
-        };
-
-        if (reqUid < 0) {
-            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
-            if (kernelWakelocks.size() > 0) {
-                final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
-                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
-                    BatteryStats.Timer timer = ent.getValue();
-                    long totalTimeMillis = computeWakeLock(timer, batteryRealtime, which);
-                    if (totalTimeMillis > 0) {
-                        timers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
-                    }
-                }
-                Collections.sort(timers, timerComparator);
-                for (int i=0; i<timers.size(); i++) {
-                    TimerEntry timer = timers.get(i);
-                    String linePrefix = ": ";
-                    sb.setLength(0);
-                    sb.append(prefix);
-                    sb.append("  Kernel Wake lock ");
-                    sb.append(timer.mName);
-                    linePrefix = printWakeLock(sb, timer.mTimer, batteryRealtime, null,
-                            which, linePrefix);
-                    if (!linePrefix.equals(": ")) {
-                        sb.append(" realtime");
-                        // Only print out wake locks that were held
-                        pw.println(sb.toString());
-                    }
-                }
-            }
-        }
-
         final ArrayList<TimerEntry> timers = new ArrayList<TimerEntry>();
 
         for (int iu = 0; iu < NU; iu++) {
             Uid u = uidStats.valueAt(iu);
-            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) {
@@ -1669,13 +2026,13 @@
                     Timer fullWakeTimer = wl.getWakeTime(WAKE_TYPE_FULL);
                     if (fullWakeTimer != null) {
                         fullWakeLockTimeTotalMicros += fullWakeTimer.getTotalTimeLocked(
-                                batteryRealtime, which);
+                                rawRealtime, which);
                     }
 
                     Timer partialWakeTimer = wl.getWakeTime(WAKE_TYPE_PARTIAL);
                     if (partialWakeTimer != null) {
                         long totalTimeMicros = partialWakeTimer.getTotalTimeLocked(
-                                batteryRealtime, which);
+                                rawRealtime, which);
                         if (totalTimeMicros > 0) {
                             if (reqUid < 0) {
                                 // Only show the ordered list of all wake
@@ -1691,30 +2048,47 @@
             }
         }
         
+        long mobileRxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+        long mobileTxTotalBytes = getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+        long wifiRxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+        long wifiTxTotalBytes = getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+        long mobileRxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+        long mobileTxTotalPackets = getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+        long wifiRxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+        long wifiTxTotalPackets = getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+
+        if (fullWakeLockTimeTotalMicros != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("  Total full wakelock time: "); formatTimeMsNoSpace(sb,
+                            (fullWakeLockTimeTotalMicros + 500) / 1000);
+            pw.println(sb.toString());
+        }
+
+        if (partialWakeLockTimeTotalMicros != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("  Total partial wakelock time: "); formatTimeMsNoSpace(sb,
+                            (partialWakeLockTimeTotalMicros + 500) / 1000);
+            pw.println(sb.toString());
+        }
+
         pw.print(prefix);
-                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));
+                pw.print("  Mobile total received: "); pw.print(formatBytesLocked(mobileRxTotalBytes));
+                pw.print(", sent: "); pw.print(formatBytesLocked(mobileTxTotalBytes));
+                pw.print(" (packets received "); pw.print(mobileRxTotalPackets);
+                pw.print(", sent "); pw.print(mobileTxTotalPackets); pw.println(")");
         sb.setLength(0);
         sb.append(prefix);
-                sb.append("  Total full wakelock time: "); formatTimeMs(sb,
-                        (fullWakeLockTimeTotalMicros + 500) / 1000);
-                sb.append(", Total partial wakelock time: "); formatTimeMs(sb,
-                        (partialWakeLockTimeTotalMicros + 500) / 1000);
-        pw.println(sb.toString());
-        
-        sb.setLength(0);
-        sb.append(prefix);
-        sb.append("  Signal levels: ");
+        sb.append("  Signal levels:");
         didOne = false;
         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            final long time = getPhoneSignalStrengthTime(i, batteryRealtime, which);
+            final long time = getPhoneSignalStrengthTime(i, rawRealtime, which);
             if (time == 0) {
                 continue;
             }
-            if (didOne) sb.append(", ");
+            sb.append("\n    ");
+            sb.append(prefix);
             didOne = true;
             sb.append(SignalStrength.SIGNAL_STRENGTH_NAMES[i]);
             sb.append(" ");
@@ -1725,25 +2099,26 @@
             sb.append(getPhoneSignalStrengthCount(i, which));
             sb.append("x");
         }
-        if (!didOne) sb.append("No activity");
+        if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
         sb.append("  Signal scanning time: ");
-        formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
+        formatTimeMsNoSpace(sb, getPhoneSignalScanningTime(rawRealtime, which) / 1000);
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Radio types: ");
+        sb.append("  Radio types:");
         didOne = false;
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
-            final long time = getPhoneDataConnectionTime(i, batteryRealtime, which);
+            final long time = getPhoneDataConnectionTime(i, rawRealtime, which);
             if (time == 0) {
                 continue;
             }
-            if (didOne) sb.append(", ");
+            sb.append("\n    ");
+            sb.append(prefix);
             didOne = true;
             sb.append(DATA_CONNECTION_NAMES[i]);
             sb.append(" ");
@@ -1754,28 +2129,112 @@
             sb.append(getPhoneDataConnectionCount(i, which));
             sb.append("x");
         }
-        if (!didOne) sb.append("No activity");
+        if (!didOne) sb.append(" (no activity)");
         pw.println(sb.toString());
 
         sb.setLength(0);
         sb.append(prefix);
-        sb.append("  Radio data uptime when unplugged: ");
-        sb.append(getRadioDataUptime() / 1000);
-        sb.append(" ms");
+        sb.append("  Mobile radio active time: ");
+        final long mobileActiveTime = getMobileRadioActiveTime(rawRealtime, which);
+        formatTimeMs(sb, mobileActiveTime / 1000);
+        sb.append("("); sb.append(formatRatioLocked(mobileActiveTime, whichBatteryRealtime));
+        sb.append(") "); sb.append(getMobileRadioActiveCount(which));
+        sb.append("x");
         pw.println(sb.toString());
 
+        final long mobileActiveUnknownTime = getMobileRadioActiveUnknownTime(which);
+        if (mobileActiveUnknownTime != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("  Mobile radio active unknown time: ");
+            formatTimeMs(sb, mobileActiveUnknownTime / 1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(mobileActiveUnknownTime, whichBatteryRealtime));
+            sb.append(") "); sb.append(getMobileRadioActiveUnknownCount(which));
+            sb.append("x");
+            pw.println(sb.toString());
+        }
+
+        final long mobileActiveAdjustedTime = getMobileRadioActiveAdjustedTime(which);
+        if (mobileActiveAdjustedTime != 0) {
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("  Mobile radio active adjusted time: ");
+            formatTimeMs(sb, mobileActiveAdjustedTime / 1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(mobileActiveAdjustedTime, whichBatteryRealtime));
+            sb.append(")");
+            pw.println(sb.toString());
+        }
+
+        pw.print(prefix);
+                pw.print("  Wi-Fi total received: "); pw.print(formatBytesLocked(wifiRxTotalBytes));
+                pw.print(", sent: "); pw.print(formatBytesLocked(wifiTxTotalBytes));
+                pw.print(" (packets received "); pw.print(wifiRxTotalPackets);
+                pw.print(", sent "); pw.print(wifiTxTotalPackets); pw.println(")");
         sb.setLength(0);
         sb.append(prefix);
                 sb.append("  Wifi on: "); formatTimeMs(sb, wifiOnTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(wifiOnTime, whichBatteryRealtime));
                 sb.append("), Wifi running: "); formatTimeMs(sb, wifiRunningTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(wifiRunningTime, whichBatteryRealtime));
-                sb.append("), Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
+                sb.append(")");
+        pw.println(sb.toString());
+
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("  Wifi states:");
+        didOne = false;
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            final long time = getWifiStateTime(i, rawRealtime, which);
+            if (time == 0) {
+                continue;
+            }
+            sb.append("\n    ");
+            didOne = true;
+            sb.append(WIFI_STATE_NAMES[i]);
+            sb.append(" ");
+            formatTimeMs(sb, time/1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(time, whichBatteryRealtime));
+            sb.append(") ");
+            sb.append(getPhoneDataConnectionCount(i, which));
+            sb.append("x");
+        }
+        if (!didOne) sb.append(" (no activity)");
+        pw.println(sb.toString());
+
+        sb.setLength(0);
+        sb.append(prefix);
+                sb.append("  Bluetooth on: "); formatTimeMs(sb, bluetoothOnTime / 1000);
                 sb.append("("); sb.append(formatRatioLocked(bluetoothOnTime, whichBatteryRealtime));
                 sb.append(")");
         pw.println(sb.toString());
-        
-        pw.println(" ");
+
+        sb.setLength(0);
+        sb.append(prefix);
+        sb.append("  Bluetooth states:");
+        didOne = false;
+        for (int i=0; i<NUM_BLUETOOTH_STATES; i++) {
+            final long time = getBluetoothStateTime(i, rawRealtime, which);
+            if (time == 0) {
+                continue;
+            }
+            sb.append("\n    ");
+            didOne = true;
+            sb.append(BLUETOOTH_STATE_NAMES[i]);
+            sb.append(" ");
+            formatTimeMs(sb, time/1000);
+            sb.append("(");
+            sb.append(formatRatioLocked(time, whichBatteryRealtime));
+            sb.append(") ");
+            sb.append(getPhoneDataConnectionCount(i, which));
+            sb.append("x");
+        }
+        if (!didOne) sb.append(" (no activity)");
+        pw.println(sb.toString());
+
+        pw.println();
 
         if (which == STATS_SINCE_UNPLUGGED) {
             if (getIsOnBattery()) {
@@ -1809,24 +2268,185 @@
             pw.println();
         }
 
-        if (timers.size() > 0) {
-            Collections.sort(timers, timerComparator);
-            pw.print(prefix); pw.println("  All partial wake locks:");
-            for (int i=0; i<timers.size(); i++) {
-                TimerEntry timer = timers.get(i);
-                sb.setLength(0);
-                sb.append("  Wake lock ");
-                UserHandle.formatUid(sb, timer.mId);
-                sb.append(" ");
-                sb.append(timer.mName);
-                printWakeLock(sb, timer.mTimer, batteryRealtime, null, which, ": ");
-                sb.append(" realtime");
-                pw.println(sb.toString());
+        BatteryStatsHelper helper = new BatteryStatsHelper(context);
+        helper.create(this);
+        helper.refreshStats(which, UserHandle.USER_ALL);
+        List<BatterySipper> sippers = helper.getUsageList();
+        if (sippers != null && sippers.size() > 0) {
+            pw.print(prefix); pw.println("  Estimated power use (mAh):");
+            pw.print(prefix); pw.print("    Capacity: ");
+                    printmAh(pw, helper.getPowerProfile().getBatteryCapacity());
+                    pw.print(", Computed drain: "); printmAh(pw, helper.getComputedPower());
+                    pw.print(", Min drain: "); printmAh(pw, helper.getMinDrainedPower());
+                    pw.print(", Max drain: "); printmAh(pw, helper.getMaxDrainedPower());
+                    pw.println();
+            for (int i=0; i<sippers.size(); i++) {
+                BatterySipper bs = sippers.get(i);
+                switch (bs.drainType) {
+                    case IDLE:
+                        pw.print(prefix); pw.print("    Idle: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                    case CELL:
+                        pw.print(prefix); pw.print("    Cell standby: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                    case PHONE:
+                        pw.print(prefix); pw.print("    Phone calls: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                    case WIFI:
+                        pw.print(prefix); pw.print("    Wifi: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                    case BLUETOOTH:
+                        pw.print(prefix); pw.print("    Bluetooth: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                    case SCREEN:
+                        pw.print(prefix); pw.print("    Screen: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                    case APP:
+                        pw.print(prefix); pw.print("    Uid ");
+                        UserHandle.formatUid(pw, bs.uidObj.getUid());
+                        pw.print(": "); printmAh(pw, bs.value); pw.println();
+                        break;
+                    case USER:
+                        pw.print(prefix); pw.print("    User "); pw.print(bs.userId);
+                        pw.print(": "); printmAh(pw, bs.value); pw.println();
+                        break;
+                    case UNACCOUNTED:
+                        pw.print(prefix); pw.print("    Unaccounted: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                    case OVERCOUNTED:
+                        pw.print(prefix); pw.print("    Over-counted: "); printmAh(pw, bs.value);
+                        pw.println();
+                        break;
+                }
             }
-            timers.clear();
             pw.println();
         }
 
+        sippers = helper.getMobilemsppList();
+        if (sippers != null && sippers.size() > 0) {
+            pw.print(prefix); pw.println("  Per-app mobile ms per packet:");
+            long totalTime = 0;
+            for (int i=0; i<sippers.size(); i++) {
+                BatterySipper bs = sippers.get(i);
+                sb.setLength(0);
+                sb.append(prefix); sb.append("    Uid ");
+                UserHandle.formatUid(sb, bs.uidObj.getUid());
+                sb.append(": "); sb.append(BatteryStatsHelper.makemAh(bs.mobilemspp));
+                sb.append(" ("); sb.append(bs.mobileRxPackets+bs.mobileTxPackets);
+                sb.append(" packets over "); formatTimeMsNoSpace(sb, bs.mobileActive);
+                sb.append(") "); sb.append(bs.mobileActiveCount); sb.append("x");
+                pw.println(sb.toString());
+                totalTime += bs.mobileActive;
+            }
+            sb.setLength(0);
+            sb.append(prefix);
+            sb.append("    TOTAL TIME: ");
+            formatTimeMs(sb, totalTime);
+            sb.append("("); sb.append(formatRatioLocked(totalTime, whichBatteryRealtime));
+            sb.append(")");
+            pw.println(sb.toString());
+            pw.println();
+        }
+
+        final Comparator<TimerEntry> timerComparator = new Comparator<TimerEntry>() {
+            @Override
+            public int compare(TimerEntry lhs, TimerEntry rhs) {
+                long lhsTime = lhs.mTime;
+                long rhsTime = rhs.mTime;
+                if (lhsTime < rhsTime) {
+                    return 1;
+                }
+                if (lhsTime > rhsTime) {
+                    return -1;
+                }
+                return 0;
+            }
+        };
+
+        if (reqUid < 0) {
+            Map<String, ? extends BatteryStats.Timer> kernelWakelocks = getKernelWakelockStats();
+            if (kernelWakelocks.size() > 0) {
+                final ArrayList<TimerEntry> ktimers = new ArrayList<TimerEntry>();
+                for (Map.Entry<String, ? extends BatteryStats.Timer> ent : kernelWakelocks.entrySet()) {
+                    BatteryStats.Timer timer = ent.getValue();
+                    long totalTimeMillis = computeWakeLock(timer, rawRealtime, which);
+                    if (totalTimeMillis > 0) {
+                        ktimers.add(new TimerEntry(ent.getKey(), 0, timer, totalTimeMillis));
+                    }
+                }
+                if (ktimers.size() > 0) {
+                    Collections.sort(ktimers, timerComparator);
+                    pw.print(prefix); pw.println("  All kernel wake locks:");
+                    for (int i=0; i<ktimers.size(); i++) {
+                        TimerEntry timer = ktimers.get(i);
+                        String linePrefix = ": ";
+                        sb.setLength(0);
+                        sb.append(prefix);
+                        sb.append("  Kernel Wake lock ");
+                        sb.append(timer.mName);
+                        linePrefix = printWakeLock(sb, timer.mTimer, rawRealtime, null,
+                                which, linePrefix);
+                        if (!linePrefix.equals(": ")) {
+                            sb.append(" realtime");
+                            // Only print out wake locks that were held
+                            pw.println(sb.toString());
+                        }
+                    }
+                    pw.println();
+                }
+            }
+
+            if (timers.size() > 0) {
+                Collections.sort(timers, timerComparator);
+                pw.print(prefix); pw.println("  All partial wake locks:");
+                for (int i=0; i<timers.size(); i++) {
+                    TimerEntry timer = timers.get(i);
+                    sb.setLength(0);
+                    sb.append("  Wake lock ");
+                    UserHandle.formatUid(sb, timer.mId);
+                    sb.append(" ");
+                    sb.append(timer.mName);
+                    printWakeLock(sb, timer.mTimer, rawRealtime, null, which, ": ");
+                    sb.append(" realtime");
+                    pw.println(sb.toString());
+                }
+                timers.clear();
+                pw.println();
+            }
+
+            Map<String, ? extends LongCounter> wakeupReasons = getWakeupReasonStats();
+            if (wakeupReasons.size() > 0) {
+                pw.print(prefix); pw.println("  All wakeup reasons:");
+                final ArrayList<TimerEntry> reasons = new ArrayList<TimerEntry>();
+                for (Map.Entry<String, ? extends LongCounter> ent : wakeupReasons.entrySet()) {
+                    BatteryStats.LongCounter counter = ent.getValue();
+                    reasons.add(new TimerEntry(ent.getKey(), 0, null,
+                            ent.getValue().getCountLocked(which)));
+                }
+                Collections.sort(reasons, timerComparator);
+                for (int i=0; i<reasons.size(); i++) {
+                    TimerEntry timer = reasons.get(i);
+                    String linePrefix = ": ";
+                    sb.setLength(0);
+                    sb.append(prefix);
+                    sb.append("  Wakeup reason ");
+                    sb.append(timer.mName);
+                    sb.append(": ");
+                    formatTimeMs(sb, timer.mTime);
+                    sb.append("realtime");
+                    pw.println(sb.toString());
+                }
+                pw.println();
+            }
+        }
+
         for (int iu=0; iu<NU; iu++) {
             final int uid = uidStats.keyAt(iu);
             if (reqUid >= 0 && uid != reqUid && uid != Process.SYSTEM_UID) {
@@ -1840,24 +2460,70 @@
             UserHandle.formatUid(pw, uid);
             pw.println(":");
             boolean uidActivity = false;
-            
-            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 (mobileRxBytes > 0 || mobileTxBytes > 0) {
+            long mobileRxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, which);
+            long mobileTxBytes = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, which);
+            long wifiRxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, which);
+            long wifiTxBytes = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, which);
+            long mobileRxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, which);
+            long mobileTxPackets = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, which);
+            long uidMobileActiveTime = u.getMobileRadioActiveTime(which);
+            int uidMobileActiveCount = u.getMobileRadioActiveCount(which);
+            long wifiRxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, which);
+            long wifiTxPackets = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, which);
+            long fullWifiLockOnTime = u.getFullWifiLockTime(rawRealtime, which);
+            long wifiScanTime = u.getWifiScanTime(rawRealtime, which);
+            long uidWifiRunningTime = u.getWifiRunningTime(rawRealtime, which);
+
+            if (mobileRxBytes > 0 || mobileTxBytes > 0
+                    || mobileRxPackets > 0 || mobileTxPackets > 0) {
                 pw.print(prefix); pw.print("    Mobile network: ");
                         pw.print(formatBytesLocked(mobileRxBytes)); pw.print(" received, ");
-                        pw.print(formatBytesLocked(mobileTxBytes)); pw.println(" sent");
+                        pw.print(formatBytesLocked(mobileTxBytes));
+                        pw.print(" sent (packets "); pw.print(mobileRxPackets);
+                        pw.print(" received, "); pw.print(mobileTxPackets); pw.println(" sent)");
             }
-            if (wifiRxBytes > 0 || wifiTxBytes > 0) {
+            if (uidMobileActiveTime > 0 || uidMobileActiveCount > 0) {
+                sb.setLength(0);
+                sb.append(prefix); sb.append("    Mobile radio active: ");
+                formatTimeMs(sb, uidMobileActiveTime / 1000);
+                sb.append("(");
+                sb.append(formatRatioLocked(uidMobileActiveTime, mobileActiveTime));
+                sb.append(") "); sb.append(uidMobileActiveCount); sb.append("x");
+                long packets = mobileRxPackets + mobileTxPackets;
+                if (packets == 0) {
+                    packets = 1;
+                }
+                sb.append(" @ ");
+                sb.append(BatteryStatsHelper.makemAh(uidMobileActiveTime / 1000 / (double)packets));
+                sb.append(" mspp");
+                pw.println(sb.toString());
+            }
+
+            if (wifiRxBytes > 0 || wifiTxBytes > 0 || wifiRxPackets > 0 || wifiTxPackets > 0) {
                 pw.print(prefix); pw.print("    Wi-Fi network: ");
                         pw.print(formatBytesLocked(wifiRxBytes)); pw.print(" received, ");
-                        pw.print(formatBytesLocked(wifiTxBytes)); pw.println(" sent");
+                        pw.print(formatBytesLocked(wifiTxBytes));
+                        pw.print(" sent (packets "); pw.print(wifiRxPackets);
+                        pw.print(" received, "); pw.print(wifiTxPackets); pw.println(" sent)");
+            }
+
+            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
+                    || uidWifiRunningTime != 0) {
+                sb.setLength(0);
+                sb.append(prefix); sb.append("    Wifi Running: ");
+                        formatTimeMs(sb, uidWifiRunningTime / 1000);
+                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
+                                whichBatteryRealtime)); sb.append(")\n");
+                sb.append(prefix); sb.append("    Full Wifi Lock: "); 
+                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
+                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
+                                whichBatteryRealtime)); sb.append(")\n");
+                sb.append(prefix); sb.append("    Wifi Scan: ");
+                        formatTimeMs(sb, wifiScanTime / 1000);
+                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
+                                whichBatteryRealtime)); sb.append(")");
+                pw.println(sb.toString());
             }
 
             if (u.hasUserActivity()) {
@@ -1881,24 +2547,6 @@
                     pw.println(sb.toString());
                 }
             }
-            
-            if (fullWifiLockOnTime != 0 || wifiScanTime != 0
-                    || uidWifiRunningTime != 0) {
-                sb.setLength(0);
-                sb.append(prefix); sb.append("    Wifi Running: ");
-                        formatTimeMs(sb, uidWifiRunningTime / 1000);
-                        sb.append("("); sb.append(formatRatioLocked(uidWifiRunningTime,
-                                whichBatteryRealtime)); sb.append(")\n");
-                sb.append(prefix); sb.append("    Full Wifi Lock: "); 
-                        formatTimeMs(sb, fullWifiLockOnTime / 1000);
-                        sb.append("("); sb.append(formatRatioLocked(fullWifiLockOnTime,
-                                whichBatteryRealtime)); sb.append(")\n");
-                sb.append(prefix); sb.append("    Wifi Scan: ");
-                        formatTimeMs(sb, wifiScanTime / 1000);
-                        sb.append("("); sb.append(formatRatioLocked(wifiScanTime,
-                                whichBatteryRealtime)); sb.append(")");
-                pw.println(sb.toString());
-            }
 
             Map<String, ? extends BatteryStats.Uid.Wakelock> wakelocks = u.getWakelockStats();
             if (wakelocks.size() > 0) {
@@ -1912,11 +2560,11 @@
                     sb.append(prefix);
                     sb.append("    Wake lock ");
                     sb.append(ent.getKey());
-                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
+                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), rawRealtime,
                             "full", which, linePrefix);
-                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
+                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), rawRealtime,
                             "partial", which, linePrefix);
-                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
+                    linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), rawRealtime,
                             "window", which, linePrefix);
                     if (!linePrefix.equals(": ")) {
                         sb.append(" realtime");
@@ -1926,11 +2574,11 @@
                         count++;
                     }
                     totalFull += computeWakeLock(wl.getWakeTime(WAKE_TYPE_FULL),
-                            batteryRealtime, which);
+                            rawRealtime, which);
                     totalPartial += computeWakeLock(wl.getWakeTime(WAKE_TYPE_PARTIAL),
-                            batteryRealtime, which);
+                            rawRealtime, which);
                     totalWindow += computeWakeLock(wl.getWakeTime(WAKE_TYPE_WINDOW),
-                            batteryRealtime, which);
+                            rawRealtime, which);
                 }
                 if (count > 1) {
                     if (totalFull != 0 || totalPartial != 0 || totalWindow != 0) {
@@ -1986,7 +2634,7 @@
                     if (timer != null) {
                         // Convert from microseconds to milliseconds with rounding
                         long totalTime = (timer.getTotalTimeLocked(
-                                batteryRealtime, which) + 500) / 1000;
+                                rawRealtime, which) + 500) / 1000;
                         int count = timer.getCountLocked(which);
                         //timer.logState();
                         if (totalTime != 0) {
@@ -2010,7 +2658,7 @@
             if (vibTimer != null) {
                 // Convert from microseconds to milliseconds with rounding
                 long totalTime = (vibTimer.getTotalTimeLocked(
-                        batteryRealtime, which) + 500) / 1000;
+                        rawRealtime, which) + 500) / 1000;
                 int count = vibTimer.getCountLocked(which);
                 //timer.logState();
                 if (totalTime != 0) {
@@ -2029,7 +2677,7 @@
             Timer fgTimer = u.getForegroundActivityTimer();
             if (fgTimer != null) {
                 // Convert from microseconds to milliseconds with rounding
-                long totalTime = (fgTimer.getTotalTimeLocked(batteryRealtime, which) + 500) / 1000;
+                long totalTime = (fgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                 int count = fgTimer.getCountLocked(which);
                 if (totalTime != 0) {
                     sb.setLength(0);
@@ -2151,28 +2799,53 @@
         }
     }
 
-    static void printBitDescriptions(PrintWriter pw, int oldval, int newval, BitDescription[] descriptions) {
+    static void printBitDescriptions(PrintWriter pw, int oldval, int newval, HistoryTag wakelockTag,
+            BitDescription[] descriptions, boolean longNames) {
         int diff = oldval ^ newval;
         if (diff == 0) return;
+        boolean didWake = false;
         for (int i=0; i<descriptions.length; i++) {
             BitDescription bd = descriptions[i];
             if ((diff&bd.mask) != 0) {
+                pw.print(longNames ? " " : ",");
                 if (bd.shift < 0) {
-                    pw.print((newval&bd.mask) != 0 ? " +" : " -");
-                    pw.print(bd.name);
+                    pw.print((newval&bd.mask) != 0 ? "+" : "-");
+                    pw.print(longNames ? bd.name : bd.shortName);
+                    if (bd.mask == HistoryItem.STATE_WAKE_LOCK_FLAG && wakelockTag != null) {
+                        didWake = true;
+                        pw.print("=");
+                        if (longNames) {
+                            UserHandle.formatUid(pw, wakelockTag.uid);
+                            pw.print(":\"");
+                            pw.print(wakelockTag.string);
+                            pw.print("\"");
+                        } else {
+                            pw.print(wakelockTag.poolIdx);
+                        }
+                    }
                 } else {
-                    pw.print(" ");
-                    pw.print(bd.name);
+                    pw.print(longNames ? bd.name : bd.shortName);
                     pw.print("=");
                     int val = (newval&bd.mask)>>bd.shift;
                     if (bd.values != null && val >= 0 && val < bd.values.length) {
-                        pw.print(bd.values[val]);
+                        pw.print(longNames? bd.values[val] : bd.shortValues[val]);
                     } else {
                         pw.print(val);
                     }
                 }
             }
         }
+        if (!didWake && wakelockTag != null) {
+            pw.print(longNames ? "wake_lock=" : "w=");
+            if (longNames) {
+                UserHandle.formatUid(pw, wakelockTag.uid);
+                pw.print(":\"");
+                pw.print(wakelockTag.string);
+                pw.print("\"");
+            } else {
+                pw.print(wakelockTag.poolIdx);
+            }
+        }
     }
     
     public void prepareForDumpLocked() {
@@ -2180,51 +2853,103 @@
 
     public static class HistoryPrinter {
         int oldState = 0;
+        int oldState2 = 0;
+        int oldLevel = -1;
         int oldStatus = -1;
         int oldHealth = -1;
         int oldPlug = -1;
         int oldTemp = -1;
         int oldVolt = -1;
+        long lastTime = -1;
 
-        public void printNextItem(PrintWriter pw, HistoryItem rec, long now) {
-            pw.print("  ");
-            TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
-            pw.print(" ");
-            if (rec.cmd == HistoryItem.CMD_START) {
-                pw.println(" START");
-            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
-                pw.println(" *OVERFLOW*");
+        public void printNextItem(PrintWriter pw, HistoryItem rec, long now, boolean checkin,
+                boolean verbose) {
+            if (!checkin) {
+                pw.print("  ");
+                if (now >= 0) {
+                    TimeUtils.formatDuration(rec.time-now, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
+                } else {
+                    TimeUtils.formatDuration(rec.time, pw, TimeUtils.HUNDRED_DAY_FIELD_LEN);
+                }
+                pw.print(" (");
+                pw.print(rec.numReadInts);
+                pw.print(") ");
             } else {
-                if (rec.batteryLevel < 10) pw.print("00");
-                else if (rec.batteryLevel < 100) pw.print("0");
-                pw.print(rec.batteryLevel);
-                pw.print(" ");
-                if (rec.states < 0x10) pw.print("0000000");
-                else if (rec.states < 0x100) pw.print("000000");
-                else if (rec.states < 0x1000) pw.print("00000");
-                else if (rec.states < 0x10000) pw.print("0000");
-                else if (rec.states < 0x100000) pw.print("000");
-                else if (rec.states < 0x1000000) pw.print("00");
-                else if (rec.states < 0x10000000) pw.print("0");
-                pw.print(Integer.toHexString(rec.states));
+                if (lastTime < 0) {
+                    if (now >= 0) {
+                        pw.print("@");
+                        pw.print(rec.time-now);
+                    } else {
+                        pw.print(rec.time);
+                    }
+                } else {
+                    pw.print(rec.time-lastTime);
+                }
+                lastTime = rec.time;
+            }
+            if (rec.cmd == HistoryItem.CMD_START) {
+                if (checkin) {
+                    pw.print(":");
+                }
+                pw.println("START");
+            } else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
+                if (checkin) {
+                    pw.print(":");
+                }
+                pw.print("TIME:");
+                if (checkin) {
+                    pw.println(rec.currentTime);
+                } else {
+                    pw.print(" ");
+                    pw.println(DateFormat.format("yyyy-MM-dd-HH-mm-ss",
+                            rec.currentTime).toString());
+                }
+            } else if (rec.cmd == HistoryItem.CMD_OVERFLOW) {
+                if (checkin) {
+                    pw.print(":");
+                }
+                pw.println("*OVERFLOW*");
+            } else {
+                if (!checkin) {
+                    if (rec.batteryLevel < 10) pw.print("00");
+                    else if (rec.batteryLevel < 100) pw.print("0");
+                    pw.print(rec.batteryLevel);
+                    if (verbose) {
+                        pw.print(" ");
+                        if (rec.states < 0) ;
+                        else if (rec.states < 0x10) pw.print("0000000");
+                        else if (rec.states < 0x100) pw.print("000000");
+                        else if (rec.states < 0x1000) pw.print("00000");
+                        else if (rec.states < 0x10000) pw.print("0000");
+                        else if (rec.states < 0x100000) pw.print("000");
+                        else if (rec.states < 0x1000000) pw.print("00");
+                        else if (rec.states < 0x10000000) pw.print("0");
+                        pw.print(Integer.toHexString(rec.states));
+                    }
+                } else {
+                    if (oldLevel != rec.batteryLevel) {
+                        oldLevel = rec.batteryLevel;
+                        pw.print(",Bl="); pw.print(rec.batteryLevel);
+                    }
+                }
                 if (oldStatus != rec.batteryStatus) {
                     oldStatus = rec.batteryStatus;
-                    pw.print(" status=");
+                    pw.print(checkin ? ",Bs=" : " status=");
                     switch (oldStatus) {
                         case BatteryManager.BATTERY_STATUS_UNKNOWN:
-                            pw.print("unknown");
+                            pw.print(checkin ? "?" : "unknown");
                             break;
                         case BatteryManager.BATTERY_STATUS_CHARGING:
-                            pw.print("charging");
+                            pw.print(checkin ? "c" : "charging");
                             break;
                         case BatteryManager.BATTERY_STATUS_DISCHARGING:
-                            pw.print("discharging");
+                            pw.print(checkin ? "d" : "discharging");
                             break;
                         case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
-                            pw.print("not-charging");
+                            pw.print(checkin ? "n" : "not-charging");
                             break;
                         case BatteryManager.BATTERY_STATUS_FULL:
-                            pw.print("full");
+                            pw.print(checkin ? "f" : "full");
                             break;
                         default:
                             pw.print(oldStatus);
@@ -2233,25 +2958,28 @@
                 }
                 if (oldHealth != rec.batteryHealth) {
                     oldHealth = rec.batteryHealth;
-                    pw.print(" health=");
+                    pw.print(checkin ? ",Bh=" : " health=");
                     switch (oldHealth) {
                         case BatteryManager.BATTERY_HEALTH_UNKNOWN:
-                            pw.print("unknown");
+                            pw.print(checkin ? "?" : "unknown");
                             break;
                         case BatteryManager.BATTERY_HEALTH_GOOD:
-                            pw.print("good");
+                            pw.print(checkin ? "g" : "good");
                             break;
                         case BatteryManager.BATTERY_HEALTH_OVERHEAT:
-                            pw.print("overheat");
+                            pw.print(checkin ? "h" : "overheat");
                             break;
                         case BatteryManager.BATTERY_HEALTH_DEAD:
-                            pw.print("dead");
+                            pw.print(checkin ? "d" : "dead");
                             break;
                         case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
-                            pw.print("over-voltage");
+                            pw.print(checkin ? "v" : "over-voltage");
                             break;
                         case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
-                            pw.print("failure");
+                            pw.print(checkin ? "f" : "failure");
+                            break;
+                        case BatteryManager.BATTERY_HEALTH_COLD:
+                            pw.print(checkin ? "c" : "cold");
                             break;
                         default:
                             pw.print(oldHealth);
@@ -2260,19 +2988,19 @@
                 }
                 if (oldPlug != rec.batteryPlugType) {
                     oldPlug = rec.batteryPlugType;
-                    pw.print(" plug=");
+                    pw.print(checkin ? ",Bp=" : " plug=");
                     switch (oldPlug) {
                         case 0:
-                            pw.print("none");
+                            pw.print(checkin ? "n" : "none");
                             break;
                         case BatteryManager.BATTERY_PLUGGED_AC:
-                            pw.print("ac");
+                            pw.print(checkin ? "a" : "ac");
                             break;
                         case BatteryManager.BATTERY_PLUGGED_USB:
-                            pw.print("usb");
+                            pw.print(checkin ? "u" : "usb");
                             break;
                         case BatteryManager.BATTERY_PLUGGED_WIRELESS:
-                            pw.print("wireless");
+                            pw.print(checkin ? "w" : "wireless");
                             break;
                         default:
                             pw.print(oldPlug);
@@ -2281,139 +3009,252 @@
                 }
                 if (oldTemp != rec.batteryTemperature) {
                     oldTemp = rec.batteryTemperature;
-                    pw.print(" temp=");
+                    pw.print(checkin ? ",Bt=" : " temp=");
                     pw.print(oldTemp);
                 }
                 if (oldVolt != rec.batteryVoltage) {
                     oldVolt = rec.batteryVoltage;
-                    pw.print(" volt=");
+                    pw.print(checkin ? ",Bv=" : " volt=");
                     pw.print(oldVolt);
                 }
-                printBitDescriptions(pw, oldState, rec.states,
-                        HISTORY_STATE_DESCRIPTIONS);
+                printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
+                        HISTORY_STATE_DESCRIPTIONS, !checkin);
+                printBitDescriptions(pw, oldState2, rec.states2, null,
+                        HISTORY_STATE2_DESCRIPTIONS, !checkin);
+                if (rec.wakeReasonTag != null) {
+                    if (checkin) {
+                        pw.print(",Wr=");
+                        pw.print(rec.wakeReasonTag.poolIdx);
+                    } else {
+                        pw.print(" wake_reason=");
+                        pw.print(rec.wakeReasonTag.uid);
+                        pw.print(":\"");
+                        pw.print(rec.wakeReasonTag.string);
+                        pw.print("\"");
+                    }
+                }
+                if (rec.eventCode != HistoryItem.EVENT_NONE) {
+                    pw.print(checkin ? "," : " ");
+                    if ((rec.eventCode&HistoryItem.EVENT_FLAG_START) != 0) {
+                        pw.print("+");
+                    } else if ((rec.eventCode&HistoryItem.EVENT_FLAG_FINISH) != 0) {
+                        pw.print("-");
+                    }
+                    String[] eventNames = checkin ? HISTORY_EVENT_CHECKIN_NAMES
+                            : HISTORY_EVENT_NAMES;
+                    int idx = rec.eventCode & ~(HistoryItem.EVENT_FLAG_START
+                            | HistoryItem.EVENT_FLAG_FINISH);
+                    if (idx >= 0 && idx < eventNames.length) {
+                        pw.print(eventNames[idx]);
+                    } else {
+                        pw.print(checkin ? "Ev" : "event");
+                        pw.print(idx);
+                    }
+                    pw.print("=");
+                    if (checkin) {
+                        pw.print(rec.eventTag.poolIdx);
+                    } else {
+                        UserHandle.formatUid(pw, rec.eventTag.uid);
+                        pw.print(":\"");
+                        pw.print(rec.eventTag.string);
+                        pw.print("\"");
+                    }
+                }
                 pw.println();
-            }
-            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);
+                oldState = rec.states;
             }
         }
     }
 
+    private void printSizeValue(PrintWriter pw, long size) {
+        float result = size;
+        String suffix = "";
+        if (result >= 10*1024) {
+            suffix = "KB";
+            result = result / 1024;
+        }
+        if (result >= 10*1024) {
+            suffix = "MB";
+            result = result / 1024;
+        }
+        if (result >= 10*1024) {
+            suffix = "GB";
+            result = result / 1024;
+        }
+        if (result >= 10*1024) {
+            suffix = "TB";
+            result = result / 1024;
+        }
+        if (result >= 10*1024) {
+            suffix = "PB";
+            result = result / 1024;
+        }
+        pw.print((int)result);
+        pw.print(suffix);
+    }
+
+    public static final int DUMP_UNPLUGGED_ONLY = 1<<0;
+    public static final int DUMP_CHARGED_ONLY = 1<<1;
+    public static final int DUMP_HISTORY_ONLY = 1<<2;
+    public static final int DUMP_INCLUDE_HISTORY = 1<<3;
+    public static final int DUMP_VERBOSE = 1<<4;
+
     /**
      * Dumps a human-readable summary of the battery statistics to the given PrintWriter.
      *
      * @param pw a Printer to receive the dump output.
      */
     @SuppressWarnings("unused")
-    public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
+    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
         prepareForDumpLocked();
 
-        long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
+        final boolean filtering =
+                (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
 
-        final HistoryItem rec = new HistoryItem();
-        if (startIteratingHistoryLocked()) {
-            pw.println("Battery History:");
-            HistoryPrinter hprinter = new HistoryPrinter();
-            while (getNextHistoryLocked(rec)) {
-                hprinter.printNextItem(pw, rec, now);
-            }
-            finishIteratingHistoryLocked();
-            pw.println("");
-        }
+        if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
+            long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
 
-        if (startIteratingOldHistoryLocked()) {
-            pw.println("Old battery History:");
-            HistoryPrinter hprinter = new HistoryPrinter();
-            while (getNextOldHistoryLocked(rec)) {
-                hprinter.printNextItem(pw, rec, now);
-            }
-            finishIteratingOldHistoryLocked();
-            pw.println("");
-        }
-        
-        SparseArray<? extends Uid> uidStats = getUidStats();
-        final int NU = uidStats.size();
-        boolean didPid = false;
-        long nowRealtime = SystemClock.elapsedRealtime();
-        for (int i=0; i<NU; i++) {
-            Uid uid = uidStats.valueAt(i);
-            SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
-            if (pids != null) {
-                for (int j=0; j<pids.size(); j++) {
-                    Uid.Pid pid = pids.valueAt(j);
-                    if (!didPid) {
-                        pw.println("Per-PID Stats:");
-                        didPid = true;
+            final HistoryItem rec = new HistoryItem();
+            final long historyTotalSize = getHistoryTotalSize();
+            final long historyUsedSize = getHistoryUsedSize();
+            if (startIteratingHistoryLocked()) {
+                try {
+                    pw.print("Battery History (");
+                    pw.print((100*historyUsedSize)/historyTotalSize);
+                    pw.print("% used, ");
+                    printSizeValue(pw, historyUsedSize);
+                    pw.print(" used of ");
+                    printSizeValue(pw, historyTotalSize);
+                    pw.print(", ");
+                    pw.print(getHistoryStringPoolSize());
+                    pw.print(" strings using ");
+                    printSizeValue(pw, getHistoryStringPoolBytes());
+                    pw.println("):");
+                    HistoryPrinter hprinter = new HistoryPrinter();
+                    long lastTime = -1;
+                    while (getNextHistoryLocked(rec)) {
+                        lastTime = rec.time;
+                        if (rec.time >= histStart) {
+                            hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, false,
+                                    (flags&DUMP_VERBOSE) != 0);
+                        }
                     }
-                    long time = pid.mWakeSum + (pid.mWakeStart != 0
-                            ? (nowRealtime - pid.mWakeStart) : 0);
-                    pw.print("  PID "); pw.print(pids.keyAt(j));
-                            pw.print(" wake time: ");
-                            TimeUtils.formatDuration(time, pw);
-                            pw.println("");
+                    if (histStart >= 0) {
+                        pw.print("  NEXT: "); pw.println(lastTime+1);
+                    }
+                    pw.println();
+                } finally {
+                    finishIteratingHistoryLocked();
+                }
+            }
+
+            if (startIteratingOldHistoryLocked()) {
+                try {
+                    pw.println("Old battery History:");
+                    HistoryPrinter hprinter = new HistoryPrinter();
+                    while (getNextOldHistoryLocked(rec)) {
+                        hprinter.printNextItem(pw, rec, now, false, (flags&DUMP_VERBOSE) != 0);
+                    }
+                    pw.println();
+                } finally {
+                    finishIteratingOldHistoryLocked();
                 }
             }
         }
-        if (didPid) {
-            pw.println("");
+
+        if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
+            return;
         }
 
-        if (!isUnpluggedOnly) {
+        if (!filtering) {
+            SparseArray<? extends Uid> uidStats = getUidStats();
+            final int NU = uidStats.size();
+            boolean didPid = false;
+            long nowRealtime = SystemClock.elapsedRealtime();
+            for (int i=0; i<NU; i++) {
+                Uid uid = uidStats.valueAt(i);
+                SparseArray<? extends Uid.Pid> pids = uid.getPidStats();
+                if (pids != null) {
+                    for (int j=0; j<pids.size(); j++) {
+                        Uid.Pid pid = pids.valueAt(j);
+                        if (!didPid) {
+                            pw.println("Per-PID Stats:");
+                            didPid = true;
+                        }
+                        long time = pid.mWakeSumMs + (pid.mWakeNesting > 0
+                                ? (nowRealtime - pid.mWakeStartMs) : 0);
+                        pw.print("  PID "); pw.print(pids.keyAt(j));
+                                pw.print(" wake time: ");
+                                TimeUtils.formatDuration(time, pw);
+                                pw.println("");
+                    }
+                }
+            }
+            if (didPid) {
+                pw.println("");
+            }
+        }
+
+        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
             pw.println("Statistics since last charge:");
             pw.println("  System starts: " + getStartCount()
                     + ", currently on battery: " + getIsOnBattery());
-            dumpLocked(pw, "", STATS_SINCE_CHARGED, reqUid);
+            dumpLocked(context, pw, "", STATS_SINCE_CHARGED, reqUid);
             pw.println("");
         }
-        pw.println("Statistics since last unplugged:");
-        dumpLocked(pw, "", STATS_SINCE_UNPLUGGED, reqUid);
+        if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
+            pw.println("Statistics since last unplugged:");
+            dumpLocked(context, pw, "", STATS_SINCE_UNPLUGGED, reqUid);
+        }
     }
     
     @SuppressWarnings("unused")
-    public void dumpCheckinLocked(
-            PrintWriter pw, List<ApplicationInfo> apps, boolean isUnpluggedOnly,
-            boolean includeHistory) {
+    public void dumpCheckinLocked(Context context, PrintWriter pw,
+            List<ApplicationInfo> apps, int flags, long histStart) {
         prepareForDumpLocked();
         
         long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
 
-        if (includeHistory) {
+        final boolean filtering =
+                (flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
+
+        if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
             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();
+                try {
+                    for (int i=0; i<getHistoryStringPoolSize(); i++) {
+                        pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
+                        pw.print(HISTORY_STRING_POOL); pw.print(',');
+                        pw.print(i);
+                        pw.print(',');
+                        pw.print(getHistoryTagPoolString(i));
+                        pw.print(',');
+                        pw.print(getHistoryTagPoolUid(i));
+                        pw.println();
+                    }
+                    HistoryPrinter hprinter = new HistoryPrinter();
+                    long lastTime = -1;
+                    while (getNextHistoryLocked(rec)) {
+                        lastTime = rec.time;
+                        if (rec.time >= histStart) {
+                            pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
+                            pw.print(HISTORY_DATA); pw.print(',');
+                            hprinter.printNextItem(pw, rec, histStart >= 0 ? -1 : now, true, false);
+                        }
+                    }
+                    if (histStart >= 0) {
+                        pw.print("NEXT: "); pw.println(lastTime+1);
+                    }
+                } finally {
+                    finishIteratingHistoryLocked();
                 }
-                finishIteratingHistoryLocked();
             }
         }
 
+        if (filtering && (flags&(DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) == 0) {
+            return;
+        }
+
         if (apps != null) {
             SparseArray<ArrayList<String>> uids = new SparseArray<ArrayList<String>>();
             for (int i=0; i<apps.size(); i++) {
@@ -2441,12 +3282,11 @@
                 }
             }
         }
-        if (isUnpluggedOnly) {
-            dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
+        if (!filtering || (flags&DUMP_CHARGED_ONLY) != 0) {
+            dumpCheckinLocked(context, pw, STATS_SINCE_CHARGED, -1);
         }
-        else {
-            dumpCheckinLocked(pw, STATS_SINCE_CHARGED, -1);
-            dumpCheckinLocked(pw, STATS_SINCE_UNPLUGGED, -1);
+        if (!filtering || (flags&DUMP_UNPLUGGED_ONLY) != 0) {
+            dumpCheckinLocked(context, pw, STATS_SINCE_UNPLUGGED, -1);
         }
     }
 }
diff --git a/core/java/android/os/Broadcaster.java b/core/java/android/os/Broadcaster.java
index 96dc61a..70dcdd8 100644
--- a/core/java/android/os/Broadcaster.java
+++ b/core/java/android/os/Broadcaster.java
@@ -171,10 +171,10 @@
     public void broadcast(Message msg)
     {
         synchronized (this) {
-        	if (mReg == null) {
-        		return;
-        	}
-        	
+            if (mReg == null) {
+                return;
+            }
+            
             int senderWhat = msg.what;
             Registration start = mReg;
             Registration r = start;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 22e1476..c8051aa 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -467,6 +467,19 @@
          * </ul>
          */
         public static final int KITKAT = 19;
+
+        /**
+         * L!
+         *
+         * <p>Applications targeting this or a later release will get these
+         * new changes in behavior:</p>
+         * <ul>
+         * <li> {@link android.content.Context#bindService Context.bindService} now
+         * requires an explicit Intent, and will throw an exception if given an explicit
+         * Intent.</li>
+         * </ul>
+         */
+        public static final int L = CUR_DEVELOPMENT;
     }
     
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/os/CommonClock.java b/core/java/android/os/CommonClock.java
index 3a1da97..2ecf317 100644
--- a/core/java/android/os/CommonClock.java
+++ b/core/java/android/os/CommonClock.java
@@ -15,17 +15,8 @@
  */
 package android.os;
 
-import java.net.InetAddress;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
 import java.net.InetSocketAddress;
 import java.util.NoSuchElementException;
-import static libcore.io.OsConstants.*;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
 import android.os.Binder;
 import android.os.CommonTimeUtils;
 import android.os.IBinder;
diff --git a/core/java/android/os/CommonTimeConfig.java b/core/java/android/os/CommonTimeConfig.java
index 3355ee3..1f9fab5 100644
--- a/core/java/android/os/CommonTimeConfig.java
+++ b/core/java/android/os/CommonTimeConfig.java
@@ -15,7 +15,6 @@
  */
 package android.os;
 
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.NoSuchElementException;
 
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 2de1204..18730b6 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -26,7 +26,6 @@
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
-import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.io.Reader;
 import java.lang.reflect.Field;
@@ -41,7 +40,6 @@
 import org.apache.harmony.dalvik.ddmc.DdmServer;
 
 import dalvik.bytecode.OpcodeInfo;
-import dalvik.bytecode.Opcodes;
 import dalvik.system.VMDebug;
 
 
diff --git a/core/java/android/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java
index e1c1678..27001dc 100644
--- a/core/java/android/os/DropBoxManager.java
+++ b/core/java/android/os/DropBoxManager.java
@@ -16,14 +16,11 @@
 
 package android.os;
 
-import android.util.Log;
-
 import com.android.internal.os.IDropBoxManagerService;
 
 import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.zip.GZIPInputStream;
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index b5413db..e96398a 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -16,14 +16,13 @@
 
 package android.os;
 
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.os.storage.IMountService;
-import android.os.storage.StorageManager;
 import android.os.storage.StorageVolume;
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.internal.annotations.GuardedBy;
 import com.google.android.collect.Lists;
 
 import java.io.File;
@@ -42,6 +41,7 @@
     private static final String ENV_MEDIA_STORAGE = "MEDIA_STORAGE";
     private static final String ENV_SECONDARY_STORAGE = "SECONDARY_STORAGE";
     private static final String ENV_ANDROID_ROOT = "ANDROID_ROOT";
+    private static final String ENV_OEM_ROOT = "OEM_ROOT";
 
     /** {@hide} */
     public static final String DIR_ANDROID = "Android";
@@ -56,6 +56,7 @@
     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_OEM_ROOT = getDirectory(ENV_OEM_ROOT, "/oem");
     private static final File DIR_MEDIA_STORAGE = getDirectory(ENV_MEDIA_STORAGE, "/data/media");
 
     private static final String CANONCIAL_EMULATED_STORAGE_TARGET = getCanonicalPathOrNull(
@@ -66,33 +67,6 @@
     private static UserEnvironment sCurrentUser;
     private static boolean sUserRequired;
 
-    private static final Object sLock = new Object();
-
-    @GuardedBy("sLock")
-    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) {
-                    try {
-                        IMountService mountService = IMountService.Stub.asInterface(ServiceManager
-                                .getService("mount"));
-                        final StorageVolume[] volumes = mountService.getVolumeList();
-                        sPrimaryVolume = StorageManager.getPrimaryVolume(volumes);
-                    } catch (Exception e) {
-                        Log.e(TAG, "couldn't talk to MountService", e);
-                    }
-                }
-            }
-        }
-        return sPrimaryVolume;
-    }
-
     static {
         initForCurrentUser();
     }
@@ -101,10 +75,6 @@
     public static void initForCurrentUser() {
         final int userId = UserHandle.myUserId();
         sCurrentUser = new UserEnvironment(userId);
-
-        synchronized (sLock) {
-            sPrimaryVolume = null;
-        }
     }
 
     /** {@hide} */
@@ -237,13 +207,24 @@
     }
 
     /**
-     * Gets the Android root directory.
+     * Return root of the "system" partition holding the core Android OS.
+     * Always present and mounted read-only.
      */
     public static File getRootDirectory() {
         return DIR_ANDROID_ROOT;
     }
 
     /**
+     * Return root directory of the "oem" partition holding OEM customizations,
+     * if any. If present, the partition is mounted read-only.
+     *
+     * @hide
+     */
+    public static File getOemDirectory() {
+        return DIR_OEM_ROOT;
+    }
+
+    /**
      * Gets the system directory available for secure storage.
      * If Encrypted File system is enabled, it returns an encrypted directory (/data/secure/system).
      * Otherwise, it returns the unencrypted /data/system directory.
@@ -603,28 +584,28 @@
      * Unknown storage state, such as when a path isn't backed by known storage
      * media.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_UNKNOWN = "unknown";
 
     /**
      * Storage state if the media is not present.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_REMOVED = "removed";
 
     /**
      * Storage state if the media is present but not mounted.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_UNMOUNTED = "unmounted";
 
     /**
      * Storage state if the media is present and being disk-checked.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_CHECKING = "checking";
 
@@ -632,7 +613,7 @@
      * Storage state if the media is present but is blank or is using an
      * unsupported filesystem.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_NOFS = "nofs";
 
@@ -640,7 +621,7 @@
      * Storage state if the media is present and mounted at its mount point with
      * read/write access.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_MOUNTED = "mounted";
 
@@ -648,7 +629,7 @@
      * Storage state if the media is present and mounted at its mount point with
      * read-only access.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_MOUNTED_READ_ONLY = "mounted_ro";
 
@@ -656,14 +637,14 @@
      * Storage state if the media is present not mounted, and shared via USB
      * mass storage.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_SHARED = "shared";
 
     /**
      * Storage state if the media was removed before it was unmounted.
      *
-     * @see #getStorageState(File)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_BAD_REMOVAL = "bad_removal";
 
@@ -671,7 +652,7 @@
      * 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)
+     * @see #getExternalStorageState(File)
      */
     public static final String MEDIA_UNMOUNTABLE = "unmountable";
 
@@ -687,7 +668,15 @@
      */
     public static String getExternalStorageState() {
         final File externalDir = sCurrentUser.getExternalDirsForApp()[0];
-        return getStorageState(externalDir);
+        return getExternalStorageState(externalDir);
+    }
+
+    /**
+     * @deprecated use {@link #getExternalStorageState(File)}
+     */
+    @Deprecated
+    public static String getStorageState(File path) {
+        return getExternalStorageState(path);
     }
 
     /**
@@ -700,59 +689,81 @@
      *         {@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 {
-            rawPath = path.getCanonicalPath();
-        } catch (IOException e) {
-            Log.w(TAG, "Failed to resolve target path: " + e);
-            return Environment.MEDIA_UNKNOWN;
-        }
-
-        try {
+    public static String getExternalStorageState(File path) {
+        final StorageVolume volume = getStorageVolume(path);
+        if (volume != null) {
             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());
-                }
+            try {
+                return mountService.getVolumeState(volume.getPath());
+            } catch (RemoteException e) {
             }
-        } catch (RemoteException e) {
-            Log.w(TAG, "Failed to find external storage state: " + e);
         }
+
         return Environment.MEDIA_UNKNOWN;
     }
 
     /**
      * Returns whether the primary "external" storage device is removable.
-     * If true is returned, this device is for example an SD card that the
-     * user can remove.  If false is returned, the storage is built into
-     * the device and can not be physically removed.
      *
-     * <p>See {@link #getExternalStorageDirectory()} for more information.
+     * @return true if the storage device can be removed (such as an SD card),
+     *         or false if the storage device is built in and cannot be
+     *         physically removed.
      */
     public static boolean isExternalStorageRemovable() {
-        final StorageVolume primary = getPrimaryVolume();
-        return (primary != null && primary.isRemovable());
+        if (isStorageDisabled()) return false;
+        final File externalDir = sCurrentUser.getExternalDirsForApp()[0];
+        return isExternalStorageRemovable(externalDir);
     }
 
     /**
-     * Returns whether the device has an external storage device which is
-     * emulated. If true, the device does not have real external storage, and the directory
-     * returned by {@link #getExternalStorageDirectory()} will be allocated using a portion of
-     * the internal storage system.
+     * Returns whether the storage device that provides the given path is
+     * removable.
      *
-     * <p>Certain system services, such as the package manager, use this
-     * to determine where to install an application.
+     * @return true if the storage device can be removed (such as an SD card),
+     *         or false if the storage device is built in and cannot be
+     *         physically removed.
+     * @throws IllegalArgumentException if the path is not a valid storage
+     *             device.
+     */
+    public static boolean isExternalStorageRemovable(File path) {
+        final StorageVolume volume = getStorageVolume(path);
+        if (volume != null) {
+            return volume.isRemovable();
+        } else {
+            throw new IllegalArgumentException("Failed to find storage device at " + path);
+        }
+    }
+
+    /**
+     * Returns whether the primary "external" storage device is emulated. If
+     * true, data stored on this device will be stored on a portion of the
+     * internal storage system.
      *
-     * <p>Emulated external storage may also be encrypted - see
-     * {@link android.app.admin.DevicePolicyManager#setStorageEncryption(
-     * android.content.ComponentName, boolean)} for additional details.
+     * @see DevicePolicyManager#setStorageEncryption(android.content.ComponentName,
+     *      boolean)
      */
     public static boolean isExternalStorageEmulated() {
-        final StorageVolume primary = getPrimaryVolume();
-        return (primary != null && primary.isEmulated());
+        if (isStorageDisabled()) return false;
+        final File externalDir = sCurrentUser.getExternalDirsForApp()[0];
+        return isExternalStorageEmulated(externalDir);
+    }
+
+    /**
+     * Returns whether the storage device that provides the given path is
+     * emulated. If true, data stored on this device will be stored on a portion
+     * of the internal storage system.
+     *
+     * @throws IllegalArgumentException if the path is not a valid storage
+     *             device.
+     */
+    public static boolean isExternalStorageEmulated(File path) {
+        final StorageVolume volume = getStorageVolume(path);
+        if (volume != null) {
+            return volume.isEmulated();
+        } else {
+            throw new IllegalArgumentException("Failed to find storage device at " + path);
+        }
     }
 
     static File getDirectory(String variableName, String defaultPath) {
@@ -815,6 +826,32 @@
         return cur;
     }
 
+    private static boolean isStorageDisabled() {
+        return SystemProperties.getBoolean("config.disable_storage", false);
+    }
+
+    private static StorageVolume getStorageVolume(File path) {
+        try {
+            path = path.getCanonicalFile();
+        } catch (IOException e) {
+            return null;
+        }
+
+        try {
+            final IMountService mountService = IMountService.Stub.asInterface(
+                    ServiceManager.getService("mount"));
+            final StorageVolume[] volumes = mountService.getVolumeList();
+            for (StorageVolume volume : volumes) {
+                if (FileUtils.contains(volume.getPathFile(), path)) {
+                    return volume;
+                }
+            }
+        } catch (RemoteException e) {
+        }
+
+        return null;
+    }
+
     /**
      * If the given path exists on emulated external storage, return the
      * translated backing path hosted on internal storage. This bypasses any
diff --git a/core/java/android/os/FileObserver.java b/core/java/android/os/FileObserver.java
index d633486..4e705e0 100644
--- a/core/java/android/os/FileObserver.java
+++ b/core/java/android/os/FileObserver.java
@@ -18,10 +18,7 @@
 
 import android.util.Log;
 
-import com.android.internal.os.RuntimeInit;
-
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
 import java.util.HashMap;
 
 /**
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index ff3e277..dc18dee 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -20,9 +20,7 @@
 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;
@@ -328,14 +326,15 @@
      *
      * @param minCount Always keep at least this many files.
      * @param minAge Always keep files younger than this age.
+     * @return if any files were deleted.
      */
-    public static void deleteOlderFiles(File dir, int minCount, long minAge) {
+    public static boolean deleteOlderFiles(File dir, int minCount, long minAge) {
         if (minCount < 0 || minAge < 0) {
             throw new IllegalArgumentException("Constraints must be positive or 0");
         }
 
         final File[] files = dir.listFiles();
-        if (files == null) return;
+        if (files == null) return false;
 
         // Sort with newest files first
         Arrays.sort(files, new Comparator<File>() {
@@ -346,15 +345,41 @@
         });
 
         // Keep at least minCount files
+        boolean deleted = false;
         for (int i = minCount; i < files.length; i++) {
             final File file = files[i];
 
             // Keep files newer than minAge
             final long age = System.currentTimeMillis() - file.lastModified();
             if (age > minAge) {
-                Log.d(TAG, "Deleting old file " + file);
-                file.delete();
+                if (file.delete()) {
+                    Log.d(TAG, "Deleted old file " + file);
+                    deleted = true;
+                }
             }
         }
+        return deleted;
+    }
+
+    /**
+     * Test if a file lives under the given directory, either as a direct child
+     * or a distant grandchild.
+     * <p>
+     * Both files <em>must</em> have been resolved using
+     * {@link File#getCanonicalFile()} to avoid symlink or path traversal
+     * attacks.
+     */
+    public static boolean contains(File dir, File file) {
+        String dirPath = dir.getPath();
+        String filePath = file.getPath();
+
+        if (dirPath.equals(filePath)) {
+            return true;
+        }
+
+        if (!dirPath.endsWith("/")) {
+            dirPath += "/";
+        }
+        return filePath.startsWith(dirPath);
     }
 }
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index e6886c4..44367f3 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -330,6 +330,7 @@
      * Causes the Runnable r to be added to the message queue, to be run
      * at a specific time given by <var>uptimeMillis</var>.
      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
+     * Time spent in deep sleep will add an additional delay to execution.
      * The runnable will be run on the thread to which this handler is attached.
      *
      * @param r The Runnable that will be executed.
@@ -352,6 +353,7 @@
      * Causes the Runnable r to be added to the message queue, to be run
      * at a specific time given by <var>uptimeMillis</var>.
      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
+     * Time spent in deep sleep will add an additional delay to execution.
      * The runnable will be run on the thread to which this handler is attached.
      *
      * @param r The Runnable that will be executed.
@@ -377,6 +379,8 @@
      * after the specified amount of time elapses.
      * The runnable will be run on the thread to which this handler
      * is attached.
+     * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
+     * Time spent in deep sleep will add an additional delay to execution.
      *  
      * @param r The Runnable that will be executed.
      * @param delayMillis The delay (in milliseconds) until the Runnable
@@ -570,6 +574,7 @@
      * Enqueue a message into the message queue after all pending messages
      * before the absolute time (in milliseconds) <var>uptimeMillis</var>.
      * <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>
+     * Time spent in deep sleep will add an additional delay to execution.
      * You will receive it in {@link #handleMessage}, in the thread attached
      * to this handler.
      * 
diff --git a/core/java/android/os/IBatteryPropertiesRegistrar.aidl b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
index 376f6c9..fd01802 100644
--- a/core/java/android/os/IBatteryPropertiesRegistrar.aidl
+++ b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.os.IBatteryPropertiesListener;
+import android.os.BatteryProperty;
 
 /**
  * {@hide}
@@ -25,4 +26,5 @@
 interface IBatteryPropertiesRegistrar {
     void registerListener(IBatteryPropertiesListener listener);
     void unregisterListener(IBatteryPropertiesListener listener);
+    int getProperty(in int id, out BatteryProperty prop);
 }
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index a2432d6..73a0f65 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -17,7 +17,6 @@
 package android.os;
 
 import java.io.FileDescriptor;
-import java.io.PrintWriter;
 
 /**
  * Base interface for a remotable object, the core part of a lightweight
diff --git a/core/java/android/os/INetworkActivityListener.aidl b/core/java/android/os/INetworkActivityListener.aidl
new file mode 100644
index 0000000..24e6e55
--- /dev/null
+++ b/core/java/android/os/INetworkActivityListener.aidl
@@ -0,0 +1,24 @@
+/* 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;
+
+/**
+ * @hide
+ */
+oneway interface INetworkActivityListener
+{
+    void onNetworkActive();
+}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index f65b6ba..f5ff185 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -23,6 +23,7 @@
 import android.net.NetworkStats;
 import android.net.RouteInfo;
 import android.net.wifi.WifiConfiguration;
+import android.os.INetworkActivityListener;
 
 /**
  * @hide
@@ -306,14 +307,12 @@
      * reference-counting if an idletimer already exists for given
      * {@code iface}.
      *
-     * {@code label} usually represents the network type of {@code iface}.
-     * Caller should ensure that {@code label} for an {@code iface} remains the
-     * same for all calls to addIdleTimer.
+     * {@code type} is the type of the interface, such as TYPE_MOBILE.
      *
      * Every {@code addIdleTimer} should be paired with a
      * {@link removeIdleTimer} to cleanup when the network disconnects.
      */
-    void addIdleTimer(String iface, int timeout, String label);
+    void addIdleTimer(String iface, int timeout, int type);
 
     /**
      * Removes idletimer for an interface.
@@ -441,4 +440,19 @@
      * Determine whether the clatd (464xlat) service has been started
      */
     boolean isClatdStarted();
+
+    /**
+     * Start listening for mobile activity state changes.
+     */
+    void registerNetworkActivityListener(INetworkActivityListener listener);
+
+    /**
+     * Stop listening for mobile activity state changes.
+     */
+    void unregisterNetworkActivityListener(INetworkActivityListener listener);
+
+    /**
+     * Check whether the mobile radio is currently active.
+     */
+    boolean isNetworkActive();
 }
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index 56176a4..d03b0c5 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -25,12 +25,14 @@
 {
     // WARNING: The first four methods must remain the first three methods because their
     // transaction numbers must not change unless IPowerManager.cpp is also updated.
-    void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws);
-    void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName, int uidtoblame);
+    void acquireWakeLock(IBinder lock, int flags, String tag, String packageName, in WorkSource ws,
+            String historyTag);
+    void acquireWakeLockWithUid(IBinder lock, int flags, String tag, String packageName,
+            int uidtoblame);
     void releaseWakeLock(IBinder lock, int flags);
     void updateWakeLockUids(IBinder lock, in int[] uids);
 
-    void updateWakeLockWorkSource(IBinder lock, in WorkSource ws);
+    void updateWakeLockWorkSource(IBinder lock, in WorkSource ws, String historyTag);
     boolean isWakeLockLevelSupported(int level);
 
     void userActivity(long time, int event, int flags);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 3c9d0d9..6e6c06d 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -28,11 +28,13 @@
  */
 interface IUserManager {
     UserInfo createUser(in String name, int flags);
+    UserInfo createRelatedUser(in String name, int flags, int relatedUserId);
     boolean removeUser(int userHandle);
     void setUserName(int userHandle, String name);
     void setUserIcon(int userHandle, in Bitmap icon);
     Bitmap getUserIcon(int userHandle);
     List<UserInfo> getUsers(boolean excludeDying);
+    List<UserInfo> getRelatedUsers(int userHandle);
     UserInfo getUserInfo(int userHandle);
     boolean isRestricted();
     void setGuestEnabled(boolean enable);
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl
index 456ffb1..4854bc0 100644
--- a/core/java/android/os/IVibratorService.aidl
+++ b/core/java/android/os/IVibratorService.aidl
@@ -20,8 +20,8 @@
 interface IVibratorService
 {
     boolean hasVibrator();
-    void vibrate(int uid, String packageName, long milliseconds, IBinder token);
-    void vibratePattern(int uid, String packageName, in long[] pattern, int repeat, IBinder token);
+    void vibrate(int uid, String packageName, long milliseconds, int streamHint, IBinder token);
+    void vibratePattern(int uid, String packageName, in long[] pattern, int repeat, int streamHint, IBinder token);
     void cancelVibrate(IBinder token);
 }
 
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 21e9f6b..6d7c9cf 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 import android.util.Printer;
-import android.util.PrefixPrinter;
 
 /**
   * Class used to run a message loop for a thread.  Threads by default do
@@ -150,7 +149,7 @@
                         + msg.callback + " what=" + msg.what);
             }
 
-            msg.recycle();
+            msg.recycleUnchecked();
         }
     }
 
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index 51203a48..d30bbc1 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -71,7 +71,14 @@
      */
     public Messenger replyTo;
 
-    /** If set message is in use */
+    /** If set message is in use.
+     * This flag is set when the message is enqueued and remains set while it
+     * is delivered and afterwards when it is recycled.  The flag is only cleared
+     * when a new message is created or obtained since that is the only time that
+     * applications are allowed to modify the contents of the message.
+     *
+     * It is an error to attempt to enqueue or recycle a message that is already in use.
+     */
     /*package*/ static final int FLAG_IN_USE = 1 << 0;
 
     /** If set message is asynchronous */
@@ -86,9 +93,9 @@
     
     /*package*/ Bundle data;
     
-    /*package*/ Handler target;     
+    /*package*/ Handler target;
     
-    /*package*/ Runnable callback;   
+    /*package*/ Runnable callback;
     
     // sometimes we store linked lists of these things
     /*package*/ Message next;
@@ -109,6 +116,7 @@
                 Message m = sPool;
                 sPool = m.next;
                 m.next = null;
+                m.flags = 0; // clear in-use flag
                 sPoolSize--;
                 return m;
             }
@@ -241,12 +249,38 @@
     }
 
     /**
-     * Return a Message instance to the global pool.  You MUST NOT touch
-     * the Message after calling this function -- it has effectively been
-     * freed.
+     * Return a Message instance to the global pool.
+     * <p>
+     * You MUST NOT touch the Message after calling this function because it has
+     * effectively been freed.  It is an error to recycle a message that is currently
+     * enqueued or that is in the process of being delivered to a Handler.
+     * </p>
      */
     public void recycle() {
-        clearForRecycle();
+        if (isInUse()) {
+            throw new IllegalStateException("This message cannot be recycled because it "
+                    + "is still in use.");
+        }
+        recycleUnchecked();
+    }
+
+    /**
+     * Recycles a Message that may be in-use.
+     * Used internally by the MessageQueue and Looper when disposing of queued Messages.
+     */
+    void recycleUnchecked() {
+        // Mark the message as in use while it remains in the recycled object pool.
+        // Clear out all other details.
+        flags = FLAG_IN_USE;
+        what = 0;
+        arg1 = 0;
+        arg2 = 0;
+        obj = null;
+        replyTo = null;
+        when = 0;
+        target = null;
+        callback = null;
+        data = null;
 
         synchronized (sPoolSync) {
             if (sPoolSize < MAX_POOL_SIZE) {
@@ -402,19 +436,6 @@
         }
     }
 
-    /*package*/ void clearForRecycle() {
-        flags = 0;
-        what = 0;
-        arg1 = 0;
-        arg2 = 0;
-        obj = null;
-        replyTo = null;
-        when = 0;
-        target = null;
-        callback = null;
-        data = null;
-    }
-
     /*package*/ boolean isInUse() {
         return ((flags & FLAG_IN_USE) == FLAG_IN_USE);
     }
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 75f9813..01a23ce 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.util.AndroidRuntimeException;
 import android.util.Log;
 import android.util.Printer;
 
@@ -126,6 +125,14 @@
     }
 
     Message next() {
+        // Return here if the message loop has already quit and been disposed.
+        // This can happen if the application tries to restart a looper after quit
+        // which is not supported.
+        final long ptr = mPtr;
+        if (ptr == 0) {
+            return null;
+        }
+
         int pendingIdleHandlerCount = -1; // -1 only during first iteration
         int nextPollTimeoutMillis = 0;
         for (;;) {
@@ -133,9 +140,7 @@
                 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);
+            nativePollOnce(ptr, nextPollTimeoutMillis);
 
             synchronized (this) {
                 // Try to retrieve the next message.  Return if found.
@@ -163,7 +168,6 @@
                         }
                         msg.next = null;
                         if (false) Log.v("MessageQueue", "Returning message: " + msg);
-                        msg.markInUse();
                         return msg;
                     }
                 } else {
@@ -227,7 +231,7 @@
 
     void quit(boolean safe) {
         if (!mQuitAllowed) {
-            throw new RuntimeException("Main thread not allowed to quit.");
+            throw new IllegalStateException("Main thread not allowed to quit.");
         }
 
         synchronized (this) {
@@ -253,6 +257,7 @@
         synchronized (this) {
             final int token = mNextBarrierToken++;
             final Message msg = Message.obtain();
+            msg.markInUse();
             msg.when = when;
             msg.arg1 = token;
 
@@ -297,7 +302,7 @@
                 mMessages = p.next;
                 needWake = mMessages == null || mMessages.target != null;
             }
-            p.recycle();
+            p.recycleUnchecked();
 
             // If the loop is quitting then it is already awake.
             // We can assume mPtr != 0 when mQuitting is false.
@@ -308,21 +313,23 @@
     }
 
     boolean enqueueMessage(Message msg, long when) {
-        if (msg.isInUse()) {
-            throw new AndroidRuntimeException(msg + " This message is already in use.");
-        }
         if (msg.target == null) {
-            throw new AndroidRuntimeException("Message must have a target.");
+            throw new IllegalArgumentException("Message must have a target.");
+        }
+        if (msg.isInUse()) {
+            throw new IllegalStateException(msg + " This message is already in use.");
         }
 
         synchronized (this) {
             if (mQuitting) {
-                RuntimeException e = new RuntimeException(
+                IllegalStateException e = new IllegalStateException(
                         msg.target + " sending message to a Handler on a dead thread");
                 Log.w("MessageQueue", e.getMessage(), e);
+                msg.recycle();
                 return false;
             }
 
+            msg.markInUse();
             msg.when = when;
             Message p = mMessages;
             boolean needWake;
@@ -418,7 +425,7 @@
                    && (object == null || p.obj == object)) {
                 Message n = p.next;
                 mMessages = n;
-                p.recycle();
+                p.recycleUnchecked();
                 p = n;
             }
 
@@ -429,7 +436,7 @@
                     if (n.target == h && n.what == what
                         && (object == null || n.obj == object)) {
                         Message nn = n.next;
-                        n.recycle();
+                        n.recycleUnchecked();
                         p.next = nn;
                         continue;
                     }
@@ -452,7 +459,7 @@
                    && (object == null || p.obj == object)) {
                 Message n = p.next;
                 mMessages = n;
-                p.recycle();
+                p.recycleUnchecked();
                 p = n;
             }
 
@@ -463,7 +470,7 @@
                     if (n.target == h && n.callback == r
                         && (object == null || n.obj == object)) {
                         Message nn = n.next;
-                        n.recycle();
+                        n.recycleUnchecked();
                         p.next = nn;
                         continue;
                     }
@@ -486,7 +493,7 @@
                     && (object == null || p.obj == object)) {
                 Message n = p.next;
                 mMessages = n;
-                p.recycle();
+                p.recycleUnchecked();
                 p = n;
             }
 
@@ -496,7 +503,7 @@
                 if (n != null) {
                     if (n.target == h && (object == null || n.obj == object)) {
                         Message nn = n.next;
-                        n.recycle();
+                        n.recycleUnchecked();
                         p.next = nn;
                         continue;
                     }
@@ -510,7 +517,7 @@
         Message p = mMessages;
         while (p != null) {
             Message n = p.next;
-            p.recycle();
+            p.recycleUnchecked();
             p = n;
         }
         mMessages = null;
@@ -538,7 +545,7 @@
                 do {
                     p = n;
                     n = p.next;
-                    p.recycle();
+                    p.recycleUnchecked();
                 } while (n != null);
             }
         }
diff --git a/core/java/android/os/NullVibrator.java b/core/java/android/os/NullVibrator.java
index ac6027f..536da32 100644
--- a/core/java/android/os/NullVibrator.java
+++ b/core/java/android/os/NullVibrator.java
@@ -16,8 +16,6 @@
 
 package android.os;
 
-import android.util.Log;
-
 /**
  * Vibrator implementation that does nothing.
  *
@@ -38,22 +36,11 @@
         return false;
     }
 
-    @Override
-    public void vibrate(long milliseconds) {
-    }
-
-    @Override
-    public void vibrate(long[] pattern, int repeat) {
-        if (repeat >= pattern.length) {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-    }
-
     /**
      * @hide
      */
     @Override
-    public void vibrate(int owningUid, String owningPackage, long milliseconds) {
+    public void vibrate(int owningUid, String owningPackage, long milliseconds, int streamHint) {
         vibrate(milliseconds);
     }
 
@@ -61,8 +48,11 @@
      * @hide
      */
     @Override
-    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
-        vibrate(pattern, repeat);
+    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat,
+            int streamHint) {
+        if (repeat >= pattern.length) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
     }
 
     @Override
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 7425f67..8e0ff08 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -29,6 +29,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
 import java.io.Serializable;
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -2067,7 +2068,7 @@
             return readByte();
 
         case VAL_SERIALIZABLE:
-            return readSerializable();
+            return readSerializable(loader);
 
         case VAL_PARCELABLEARRAY:
             return readParcelableArray(loader);
@@ -2204,6 +2205,10 @@
      * wasn't found in the parcel.
      */
     public final Serializable readSerializable() {
+        return readSerializable(null);
+    }
+
+    private final Serializable readSerializable(final ClassLoader loader) {
         String name = readString();
         if (name == null) {
             // For some reason we were unable to read the name of the Serializable (either there
@@ -2215,14 +2220,27 @@
         byte[] serializedData = createByteArray();
         ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
         try {
-            ObjectInputStream ois = new ObjectInputStream(bais);
+            ObjectInputStream ois = new ObjectInputStream(bais) {
+                @Override
+                protected Class<?> resolveClass(ObjectStreamClass osClass)
+                        throws IOException, ClassNotFoundException {
+                    // try the custom classloader if provided
+                    if (loader != null) {
+                        Class<?> c = Class.forName(osClass.getName(), false, loader);
+                        if (c != null) {
+                            return c;
+                        }
+                    }
+                    return super.resolveClass(osClass);
+                }
+            };
             return (Serializable) ois.readObject();
         } catch (IOException ioe) {
             throw new RuntimeException("Parcelable encountered " +
                 "IOException reading a Serializable object (name = " + name +
                 ")", ioe);
         } catch (ClassNotFoundException cnfe) {
-            throw new RuntimeException("Parcelable encountered" +
+            throw new RuntimeException("Parcelable encountered " +
                 "ClassNotFoundException reading a Serializable object (name = "
                 + name + ")", cnfe);
         }
@@ -2234,6 +2252,7 @@
     private static final HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>
         mCreators = new HashMap<ClassLoader,HashMap<String,Parcelable.Creator>>();
 
+    /** @hide for internal use only. */
     static protected final Parcel obtain(int obj) {
         throw new UnsupportedOperationException();
     }
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 5273c20..86dc8b4 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -872,6 +872,8 @@
      */
     @Override
     public void writeToParcel(Parcel out, int flags) {
+        // WARNING: This must stay in sync with Parcel::readParcelFileDescriptor()
+        // in frameworks/native/libs/binder/Parcel.cpp
         if (mWrapped != null) {
             try {
                 mWrapped.writeToParcel(out, flags);
@@ -897,6 +899,8 @@
             = new Parcelable.Creator<ParcelFileDescriptor>() {
         @Override
         public ParcelFileDescriptor createFromParcel(Parcel in) {
+            // WARNING: This must stay in sync with Parcel::writeParcelFileDescriptor()
+            // in frameworks/native/libs/binder/Parcel.cpp
             final FileDescriptor fd = in.readRawFileDescriptor();
             FileDescriptor commChannel = null;
             if (in.readInt() != 0) {
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 86ef479..a195200 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -235,6 +235,13 @@
     public static final int ON_AFTER_RELEASE = 0x20000000;
 
     /**
+     * Wake lock flag: This wake lock is not important for logging events.  If a later
+     * wake lock is acquired that is important, it will be considered the one to log.
+     * @hide
+     */
+    public static final int UNIMPORTANT_FOR_LOGGING = 0x40000000;
+
+    /**
      * Flag for {@link WakeLock#release release(int)} to defer releasing a
      * {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor returns
      * a negative value.
@@ -302,6 +309,18 @@
      */
     public static final int GO_TO_SLEEP_REASON_TIMEOUT = 2;
 
+    /**
+     * The value to pass as the 'reason' argument to reboot() to
+     * reboot into recovery mode (for applying system updates, doing
+     * factory resets, etc.).
+     * <p>
+     * Requires the {@link android.Manifest.permission#RECOVERY}
+     * permission (in addition to
+     * {@link android.Manifest.permission#REBOOT}).
+     * </p>
+     */
+    public static final String REBOOT_RECOVERY = "recovery";
+    
     final Context mContext;
     final IPowerManager mService;
     final Handler mHandler;
@@ -635,14 +654,15 @@
      * </p>
      */
     public final class WakeLock {
-        private final int mFlags;
-        private final String mTag;
+        private int mFlags;
+        private String mTag;
         private final String mPackageName;
         private final IBinder mToken;
         private int mCount;
         private boolean mRefCounted = true;
         private boolean mHeld;
         private WorkSource mWorkSource;
+        private String mHistoryTag;
 
         private final Runnable mReleaser = new Runnable() {
             public void run() {
@@ -729,7 +749,8 @@
                 // been explicitly released by the keyguard.
                 mHandler.removeCallbacks(mReleaser);
                 try {
-                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource);
+                    mService.acquireWakeLock(mToken, mFlags, mTag, mPackageName, mWorkSource,
+                            mHistoryTag);
                 } catch (RemoteException e) {
                 }
                 mHeld = true;
@@ -823,13 +844,29 @@
 
                 if (changed && mHeld) {
                     try {
-                        mService.updateWakeLockWorkSource(mToken, mWorkSource);
+                        mService.updateWakeLockWorkSource(mToken, mWorkSource, mHistoryTag);
                     } catch (RemoteException e) {
                     }
                 }
             }
         }
 
+        /** @hide */
+        public void setTag(String tag) {
+            mTag = tag;
+        }
+
+        /** @hide */
+        public void setHistoryTag(String tag) {
+            mHistoryTag = tag;
+        }
+
+        /** @hide */
+        public void setUnimportantForLogging(boolean state) {
+            if (state) mFlags |= UNIMPORTANT_FOR_LOGGING;
+            else mFlags &= ~UNIMPORTANT_FOR_LOGGING;
+        }
+
         @Override
         public String toString() {
             synchronized (mToken) {
diff --git a/core/java/android/os/Registrant.java b/core/java/android/os/Registrant.java
index c1780b9..705cc5d 100644
--- a/core/java/android/os/Registrant.java
+++ b/core/java/android/os/Registrant.java
@@ -20,7 +20,6 @@
 import android.os.Message;
 
 import java.lang.ref.WeakReference;
-import java.util.HashMap;
 
 /** @hide */
 public class Registrant
diff --git a/core/java/android/os/RegistrantList.java b/core/java/android/os/RegistrantList.java
index 56b9e2b..9ab61f5 100644
--- a/core/java/android/os/RegistrantList.java
+++ b/core/java/android/os/RegistrantList.java
@@ -17,10 +17,8 @@
 package android.os;
 
 import android.os.Handler;         
-import android.os.Message;         
 
 import java.util.ArrayList;
-import java.util.HashMap;
 
 /** @hide */
 public class RegistrantList
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 156600e..1479035 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -18,8 +18,6 @@
 
 import java.util.ArrayList;
 
-import android.util.Log;
-
 
 /**
  * Gives access to the system properties store.  The system properties
diff --git a/core/java/android/os/SystemService.java b/core/java/android/os/SystemService.java
index f345271..41e7546 100644
--- a/core/java/android/os/SystemService.java
+++ b/core/java/android/os/SystemService.java
@@ -16,8 +16,6 @@
 
 package android.os;
 
-import android.util.Slog;
-
 import com.google.android.collect.Maps;
 
 import java.util.HashMap;
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 700f80d..13bc4f6 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -16,7 +16,6 @@
 
 package android.os;
 
-import android.app.ActivityThread;
 import android.content.Context;
 import android.util.Log;
 
@@ -28,18 +27,16 @@
 public class SystemVibrator extends Vibrator {
     private static final String TAG = "Vibrator";
 
-    private final String mPackageName;
     private final IVibratorService mService;
     private final Binder mToken = new Binder();
 
     public SystemVibrator() {
-        mPackageName = ActivityThread.currentPackageName();
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
     }
 
     public SystemVibrator(Context context) {
-        mPackageName = context.getOpPackageName();
+        super(context);
         mService = IVibratorService.Stub.asInterface(
                 ServiceManager.getService("vibrator"));
     }
@@ -57,27 +54,17 @@
         return false;
     }
 
-    @Override
-    public void vibrate(long milliseconds) {
-        vibrate(Process.myUid(), mPackageName, milliseconds);
-    }
-
-    @Override
-    public void vibrate(long[] pattern, int repeat) {
-        vibrate(Process.myUid(), mPackageName, pattern, repeat);
-    }
-
     /**
      * @hide
      */
     @Override
-    public void vibrate(int owningUid, String owningPackage, long milliseconds) {
+    public void vibrate(int owningUid, String owningPackage, long milliseconds, int streamHint) {
         if (mService == null) {
             Log.w(TAG, "Failed to vibrate; no vibrator service.");
             return;
         }
         try {
-            mService.vibrate(owningUid, owningPackage, milliseconds, mToken);
+            mService.vibrate(owningUid, owningPackage, milliseconds, streamHint, mToken);
         } catch (RemoteException e) {
             Log.w(TAG, "Failed to vibrate.", e);
         }
@@ -87,7 +74,8 @@
      * @hide
      */
     @Override
-    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat) {
+    public void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat,
+            int streamHint) {
         if (mService == null) {
             Log.w(TAG, "Failed to vibrate; no vibrator service.");
             return;
@@ -97,7 +85,8 @@
         // anyway
         if (repeat < pattern.length) {
             try {
-                mService.vibratePattern(owningUid, owningPackage, pattern, repeat, mToken);
+                mService.vibratePattern(owningUid, owningPackage, pattern, repeat, streamHint,
+                        mToken);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to vibrate.", e);
             }
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index 3249bcb..57ed979 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -16,8 +16,6 @@
 
 package android.os;
 
-import android.util.Log;
-
 /**
  * Writes trace events to the system trace buffer.  These trace events can be
  * collected and visualized using the Systrace tool.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a3752a1..1ec5cd5 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -17,7 +17,6 @@
 
 import android.app.ActivityManagerNative;
 import android.content.Context;
-import android.content.RestrictionEntry;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -165,11 +164,13 @@
 
     /**
      * Returns whether the system supports multiple users.
-     * @return true if multiple users can be created, false if it is a single user device.
+     * @return true if multiple users can be created by user, false if it is a single user device.
      * @hide
      */
     public static boolean supportsMultipleUsers() {
-        return getMaxSupportedUsers() > 1;
+        return getMaxSupportedUsers() > 1
+                && SystemProperties.getBoolean("fw.show_multiuserui",
+                Resources.getSystem().getBoolean(R.bool.config_enableMultiUserUI));
     }
 
     /**
@@ -409,6 +410,27 @@
     }
 
     /**
+     * Creates a user with the specified name and options.
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     *
+     * @param name the user's name
+     * @param flags flags that identify the type of user and other properties.
+     * @see UserInfo
+     * @param relatedUserId new user will be related to this user id.
+     *
+     * @return the UserInfo object for the created user, or null if the user could not be created.
+     * @hide
+     */
+    public UserInfo createRelatedUser(String name, int flags, int relatedUserId) {
+        try {
+            return mService.createRelatedUser(name, flags, relatedUserId);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not create a user", re);
+            return null;
+        }
+    }
+
+    /**
      * Return the number of users currently created on the device.
      */
     public int getUserCount() {
@@ -432,6 +454,22 @@
     }
 
     /**
+     * Returns information for all users related to userId
+     * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
+     * @param userHandle users related to this user id will be returned.
+     * @return the list of related users.
+     * @hide
+     */
+    public List<UserInfo> getRelatedUsers(int userHandle) {
+        try {
+            return mService.getRelatedUsers(userHandle);
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not get user list", re);
+            return null;
+        }
+    }
+
+    /**
      * Returns information for all users on this device.
      * Requires {@link android.Manifest.permission#MANAGE_USERS} permission.
      * @param excludeDying specify if the list should exclude users being removed.
@@ -565,6 +603,26 @@
     }
 
     /**
+     * Returns true if the user switcher should be shown, this will be if there
+     * are multiple users that aren't managed profiles.
+     * @hide
+     * @return true if user switcher should be shown.
+     */
+    public boolean isUserSwitcherEnabled() {
+        List<UserInfo> users = getUsers(true);
+        if (users == null) {
+           return false;
+        }
+        int switchableUserCount = 0;
+        for (UserInfo user : users) {
+            if (user.supportsSwitchTo()) {
+                ++switchableUserCount;
+            }
+        }
+        return switchableUserCount > 1;
+    }
+
+    /**
      * Returns a serial number on this device for a given userHandle. User handles can be recycled
      * when deleting and creating users, but serial numbers are not reused until the device is wiped.
      * @param userHandle
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index 5d55143..8845ba3 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -16,7 +16,9 @@
 
 package android.os;
 
+import android.app.ActivityThread;
 import android.content.Context;
+import android.media.AudioManager;
 
 /**
  * Class that operates the vibrator on the device.
@@ -28,10 +30,21 @@
  * {@link Context#getSystemService} with {@link Context#VIBRATOR_SERVICE} as the argument.
  */
 public abstract class Vibrator {
+
+    private final String mPackageName;
+
     /**
      * @hide to prevent subclassing from outside of the framework
      */
     public Vibrator() {
+        mPackageName = ActivityThread.currentPackageName();
+    }
+
+    /**
+     * @hide to prevent subclassing from outside of the framework
+     */
+    protected Vibrator(Context context) {
+        mPackageName = context.getOpPackageName();
     }
 
     /**
@@ -40,7 +53,7 @@
      * @return True if the hardware has a vibrator, else false.
      */
     public abstract boolean hasVibrator();
-    
+
     /**
      * Vibrate constantly for the specified period of time.
      * <p>This method requires the caller to hold the permission
@@ -48,7 +61,23 @@
      *
      * @param milliseconds The number of milliseconds to vibrate.
      */
-    public abstract void vibrate(long milliseconds);
+    public void vibrate(long milliseconds) {
+        vibrate(milliseconds, AudioManager.USE_DEFAULT_STREAM_TYPE);
+    }
+
+    /**
+     * Vibrate constantly for the specified period of time.
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#VIBRATE}.
+     *
+     * @param milliseconds The number of milliseconds to vibrate.
+     * @param streamHint An {@link AudioManager} stream type corresponding to the vibration type.
+     *        For example, specify {@link AudioManager#STREAM_ALARM} for alarm vibrations or
+     *        {@link AudioManager#STREAM_RING} for vibrations associated with incoming calls.
+     */
+    public void vibrate(long milliseconds, int streamHint) {
+        vibrate(Process.myUid(), mPackageName, milliseconds, streamHint);
+    }
 
     /**
      * Vibrate with a given pattern.
@@ -70,21 +99,52 @@
      * @param repeat the index into pattern at which to repeat, or -1 if
      *        you don't want to repeat.
      */
-    public abstract void vibrate(long[] pattern, int repeat);
+    public void vibrate(long[] pattern, int repeat) {
+        vibrate(pattern, repeat, AudioManager.USE_DEFAULT_STREAM_TYPE);
+    }
+
+    /**
+     * Vibrate with a given pattern.
+     *
+     * <p>
+     * Pass in an array of ints that are the durations for which to turn on or off
+     * the vibrator in milliseconds.  The first value indicates the number of milliseconds
+     * to wait before turning the vibrator on.  The next value indicates the number of milliseconds
+     * for which to keep the vibrator on before turning it off.  Subsequent values alternate
+     * between durations in milliseconds to turn the vibrator off or to turn the vibrator on.
+     * </p><p>
+     * To cause the pattern to repeat, pass the index into the pattern array at which
+     * to start the repeat, or -1 to disable repeating.
+     * </p>
+     * <p>This method requires the caller to hold the permission
+     * {@link android.Manifest.permission#VIBRATE}.
+     *
+     * @param pattern an array of longs of times for which to turn the vibrator on or off.
+     * @param repeat the index into pattern at which to repeat, or -1 if
+     *        you don't want to repeat.
+     * @param streamHint An {@link AudioManager} stream type corresponding to the vibration type.
+     *        For example, specify {@link AudioManager#STREAM_ALARM} for alarm vibrations or
+     *        {@link AudioManager#STREAM_RING} for vibrations associated with incoming calls.
+     */
+    public void vibrate(long[] pattern, int repeat, int streamHint) {
+        vibrate(Process.myUid(), mPackageName, pattern, repeat, streamHint);
+    }
 
     /**
      * @hide
-     * Like {@link #vibrate(long)}, but allowing the caller to specify that
+     * Like {@link #vibrate(long, int)}, but allowing the caller to specify that
      * the vibration is owned by someone else.
      */
-    public abstract void vibrate(int owningUid, String owningPackage, long milliseconds);
+    public abstract void vibrate(int owningUid, String owningPackage,
+            long milliseconds, int streamHint);
 
     /**
      * @hide
-     * Like {@link #vibrate(long[], int)}, but allowing the caller to specify that
+     * Like {@link #vibrate(long[], int, int)}, but allowing the caller to specify that
      * the vibration is owned by someone else.
      */
-    public abstract void vibrate(int owningUid, String owningPackage, long[] pattern, int repeat);
+    public abstract void vibrate(int owningUid, String owningPackage,
+            long[] pattern, int repeat, int streamHint);
 
     /**
      * Turn the vibrator off.
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
index 51ba2f6..4180860 100644
--- a/core/java/android/os/storage/IMountService.java
+++ b/core/java/android/os/storage/IMountService.java
@@ -642,12 +642,13 @@
                 return _result;
             }
 
-            public int changeEncryptionPassword(String password) throws RemoteException {
+            public int changeEncryptionPassword(int type, String password) throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
                 int _result;
                 try {
                     _data.writeInterfaceToken(DESCRIPTOR);
+                    _data.writeInt(type);
                     _data.writeString(password);
                     mRemote.transact(Stub.TRANSACTION_changeEncryptionPassword, _data, _reply, 0);
                     _reply.readException();
@@ -677,6 +678,52 @@
                 return _result;
             }
 
+            public int getPasswordType() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                int _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_getPasswordType, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readInt();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            public String getPassword() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                String _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_getPassword, _data, _reply, 0);
+                    _reply.readException();
+                    _result = _reply.readString();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+                return _result;
+            }
+
+            public void clearPassword() throws RemoteException {
+                Parcel _data = Parcel.obtain();
+                Parcel _reply = Parcel.obtain();
+                String _result;
+                try {
+                    _data.writeInterfaceToken(DESCRIPTOR);
+                    mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, 0);
+                    _reply.readException();
+                } finally {
+                    _reply.recycle();
+                    _data.recycle();
+                }
+            }
+
             public StorageVolume[] getVolumeList() throws RemoteException {
                 Parcel _data = Parcel.obtain();
                 Parcel _reply = Parcel.obtain();
@@ -829,6 +876,12 @@
 
         static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34;
 
+        static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 35;
+
+        static final int TRANSACTION_getPassword = IBinder.FIRST_CALL_TRANSACTION + 36;
+
+        static final int TRANSACTION_clearPassword = IBinder.FIRST_CALL_TRANSACTION + 37;
+
         /**
          * Cast an IBinder object into an IMountService interface, generating a
          * proxy if needed.
@@ -1130,8 +1183,9 @@
                 }
                 case TRANSACTION_changeEncryptionPassword: {
                     data.enforceInterface(DESCRIPTOR);
+                    int type = data.readInt();
                     String password = data.readString();
-                    int result = changeEncryptionPassword(password);
+                    int result = changeEncryptionPassword(type, password);
                     reply.writeNoException();
                     reply.writeInt(result);
                     return true;
@@ -1181,6 +1235,26 @@
                     reply.writeInt(result);
                     return true;
                 }
+                case TRANSACTION_getPasswordType: {
+                    data.enforceInterface(DESCRIPTOR);
+                    int result = getPasswordType();
+                    reply.writeNoException();
+                    reply.writeInt(result);
+                    return true;
+                }
+                case TRANSACTION_getPassword: {
+                    data.enforceInterface(DESCRIPTOR);
+                    String result = getPassword();
+                    reply.writeNoException();
+                    reply.writeString(result);
+                    return true;
+                }
+                case TRANSACTION_clearPassword: {
+                    data.enforceInterface(DESCRIPTOR);
+                    clearPassword();
+                    reply.writeNoException();
+                    return true;
+                }
             }
             return super.onTransact(code, data, reply, flags);
         }
@@ -1375,7 +1449,8 @@
     /**
      * Changes the encryption password.
      */
-    public int changeEncryptionPassword(String password) throws RemoteException;
+    public int changeEncryptionPassword(int type, String password)
+        throws RemoteException;
 
     /**
      * Verify the encryption password against the stored volume.  This method
@@ -1412,4 +1487,21 @@
      * external storage data or OBB directory belonging to calling app.
      */
     public int mkdirs(String callingPkg, String path) throws RemoteException;
+
+    /**
+     * Determines the type of the encryption password
+     * @return PasswordType
+     */
+    public int getPasswordType() throws RemoteException;
+
+    /**
+     * Get password from vold
+     * @return password or empty string
+     */
+    public String getPassword() throws RemoteException;
+
+    /**
+     * Securely clear password from vold
+     */
+    public void clearPassword() throws RemoteException;
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index f5e728d..4963991 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -58,6 +58,24 @@
  * argument of {@link android.content.Context#STORAGE_SERVICE}.
  */
 public class StorageManager {
+
+    /// Consts to match the password types in cryptfs.h
+    /** Master key is encrypted with a password.
+     */
+    public static final int CRYPT_TYPE_PASSWORD = 0;
+
+    /** Master key is encrypted with the default password.
+     */
+    public static final int CRYPT_TYPE_DEFAULT = 1;
+
+    /** Master key is encrypted with a pattern.
+     */
+    public static final int CRYPT_TYPE_PATTERN = 2;
+
+    /** Master key is encrypted with a pin.
+     */
+    public static final int CRYPT_TYPE_PIN = 3;
+
     private static final String TAG = "StorageManager";
 
     private final ContentResolver mResolver;
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index 1536760..1ce98b8 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -34,11 +34,16 @@
  */
 public class CheckBoxPreference extends TwoStatePreference {
 
-    public CheckBoxPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.CheckBoxPreference, defStyle, 0);
+    public CheckBoxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public CheckBoxPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.CheckBoxPreference, defStyleAttr, defStyleRes);
         setSummaryOn(a.getString(com.android.internal.R.styleable.CheckBoxPreference_summaryOn));
         setSummaryOff(a.getString(com.android.internal.R.styleable.CheckBoxPreference_summaryOff));
         setDisableDependentsState(a.getBoolean(
diff --git a/core/java/android/preference/DialogPreference.java b/core/java/android/preference/DialogPreference.java
index a643c8a..b65eac7 100644
--- a/core/java/android/preference/DialogPreference.java
+++ b/core/java/android/preference/DialogPreference.java
@@ -64,12 +64,13 @@
 
     /** Which button was clicked. */
     private int mWhichButtonClicked;
-    
-    public DialogPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.DialogPreference, defStyle, 0);
+
+    public DialogPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.DialogPreference, defStyleAttr, defStyleRes);
         mDialogTitle = a.getString(com.android.internal.R.styleable.DialogPreference_dialogTitle);
         if (mDialogTitle == null) {
             // Fallback on the regular title of the preference
@@ -83,13 +84,20 @@
         mDialogLayoutResId = a.getResourceId(com.android.internal.R.styleable.DialogPreference_dialogLayout,
                 mDialogLayoutResId);
         a.recycle();
-        
+    }
+
+    public DialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public DialogPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
     }
-    
+
+    public DialogPreference(Context context) {
+        this(context, null);
+    }
+
     /**
      * Sets the title of the dialog. This will be shown on subsequent dialogs.
      * 
@@ -161,7 +169,7 @@
      * @param dialogIconRes The icon, as a resource ID.
      */
     public void setDialogIcon(int dialogIconRes) {
-        mDialogIcon = getContext().getResources().getDrawable(dialogIconRes);
+        mDialogIcon = getContext().getDrawable(dialogIconRes);
     }
     
     /**
diff --git a/core/java/android/preference/EditTextPreference.java b/core/java/android/preference/EditTextPreference.java
index aa27627..ff37042 100644
--- a/core/java/android/preference/EditTextPreference.java
+++ b/core/java/android/preference/EditTextPreference.java
@@ -49,9 +49,9 @@
     private EditText mEditText;
     
     private String mText;
-    
-    public EditTextPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         
         mEditText = new EditText(context, attrs);
         
@@ -67,6 +67,10 @@
         mEditText.setEnabled(true);
     }
 
+    public EditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public EditTextPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.editTextPreferenceStyle);
     }
diff --git a/core/java/android/preference/GenericInflater.java b/core/java/android/preference/GenericInflater.java
index 3003290..7de7d1c 100644
--- a/core/java/android/preference/GenericInflater.java
+++ b/core/java/android/preference/GenericInflater.java
@@ -191,7 +191,7 @@
     public void setFactory(Factory<T> factory) {
         if (mFactorySet) {
             throw new IllegalStateException("" +
-            		"A factory has already been set on this inflater");
+                    "A factory has already been set on this inflater");
         }
         if (factory == null) {
             throw new NullPointerException("Given factory can not be null");
diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java
index 9edf112..8081a54 100644
--- a/core/java/android/preference/ListPreference.java
+++ b/core/java/android/preference/ListPreference.java
@@ -42,12 +42,12 @@
     private String mSummary;
     private int mClickedDialogEntryIndex;
     private boolean mValueSet;
-    
-    public ListPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ListPreference, 0, 0);
+
+    public ListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ListPreference, defStyleAttr, defStyleRes);
         mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
         mEntryValues = a.getTextArray(com.android.internal.R.styleable.ListPreference_entryValues);
         a.recycle();
@@ -56,11 +56,19 @@
          * in the Preference class.
          */
         a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Preference, 0, 0);
+                com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
         mSummary = a.getString(com.android.internal.R.styleable.Preference_summary);
         a.recycle();
     }
 
+    public ListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ListPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
+
     public ListPreference(Context context) {
         this(context, null);
     }
diff --git a/core/java/android/preference/MultiCheckPreference.java b/core/java/android/preference/MultiCheckPreference.java
index 6953075..57c906d 100644
--- a/core/java/android/preference/MultiCheckPreference.java
+++ b/core/java/android/preference/MultiCheckPreference.java
@@ -40,12 +40,13 @@
     private boolean[] mSetValues;
     private boolean[] mOrigValues;
     private String mSummary;
-    
-    public MultiCheckPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ListPreference, 0, 0);
+
+    public MultiCheckPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ListPreference, defStyleAttr, defStyleRes);
         mEntries = a.getTextArray(com.android.internal.R.styleable.ListPreference_entries);
         if (mEntries != null) {
             setEntries(mEntries);
@@ -63,6 +64,14 @@
         a.recycle();
     }
 
+    public MultiCheckPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MultiCheckPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
+
     public MultiCheckPreference(Context context) {
         this(context, null);
     }
diff --git a/core/java/android/preference/MultiSelectListPreference.java b/core/java/android/preference/MultiSelectListPreference.java
index 553ce80..6c4c20f 100644
--- a/core/java/android/preference/MultiSelectListPreference.java
+++ b/core/java/android/preference/MultiSelectListPreference.java
@@ -44,16 +44,26 @@
     private Set<String> mValues = new HashSet<String>();
     private Set<String> mNewValues = new HashSet<String>();
     private boolean mPreferenceChanged;
-    
-    public MultiSelectListPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.MultiSelectListPreference, 0, 0);
+
+    public MultiSelectListPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.MultiSelectListPreference, defStyleAttr,
+                defStyleRes);
         mEntries = a.getTextArray(com.android.internal.R.styleable.MultiSelectListPreference_entries);
         mEntryValues = a.getTextArray(com.android.internal.R.styleable.MultiSelectListPreference_entryValues);
         a.recycle();
     }
+
+    public MultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MultiSelectListPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
     
     public MultiSelectListPreference(Context context) {
         this(context, null);
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index f7d1eb7..144c909 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -188,30 +188,33 @@
 
     /**
      * Perform inflation from XML and apply a class-specific base style. This
-     * constructor of Preference allows subclasses to use their own base
-     * style when they are inflating. For example, a {@link CheckBoxPreference}
+     * constructor of Preference allows subclasses to use their own base style
+     * when they are inflating. For example, a {@link CheckBoxPreference}
      * constructor calls this version of the super class constructor and
-     * supplies {@code android.R.attr.checkBoxPreferenceStyle} for <var>defStyle</var>.
-     * This allows the theme's checkbox preference style to modify all of the base
-     * preference attributes as well as the {@link CheckBoxPreference} class's
-     * attributes.
-     * 
+     * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
+     * <var>defStyleAttr</var>. This allows the theme's checkbox preference
+     * style to modify all of the base preference attributes as well as the
+     * {@link CheckBoxPreference} class's attributes.
+     *
      * @param context The Context this is associated with, through which it can
-     *            access the current theme, resources, {@link SharedPreferences},
-     *            etc.
-     * @param attrs The attributes of the XML tag that is inflating the preference.
-     * @param defStyle The default style to apply to this preference. 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.
+     *            access the current theme, resources,
+     *            {@link SharedPreferences}, etc.
+     * @param attrs The attributes of the XML tag that is inflating the
+     *            preference.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *            reference to a style resource that supplies default values for
+     *            the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *            supplies default values for the view, used only if
+     *            defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *            to not look for defaults.
      * @see #Preference(Context, AttributeSet)
      */
-    public Preference(Context context, AttributeSet attrs, int defStyle) {
+    public Preference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         mContext = context;
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Preference, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
         for (int i = a.getIndexCount(); i >= 0; i--) {
             int attr = a.getIndex(i); 
             switch (attr) {
@@ -281,6 +284,30 @@
             mCanRecycleLayout = false;
         }
     }
+
+    /**
+     * Perform inflation from XML and apply a class-specific base style. This
+     * constructor of Preference allows subclasses to use their own base style
+     * when they are inflating. For example, a {@link CheckBoxPreference}
+     * constructor calls this version of the super class constructor and
+     * supplies {@code android.R.attr.checkBoxPreferenceStyle} for
+     * <var>defStyleAttr</var>. This allows the theme's checkbox preference
+     * style to modify all of the base preference attributes as well as the
+     * {@link CheckBoxPreference} class's attributes.
+     *
+     * @param context The Context this is associated with, through which it can
+     *            access the current theme, resources,
+     *            {@link SharedPreferences}, etc.
+     * @param attrs The attributes of the XML tag that is inflating the
+     *            preference.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *            reference to a style resource that supplies default values for
+     *            the view. Can be 0 to not look for defaults.
+     * @see #Preference(Context, AttributeSet)
+     */
+    public Preference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
     
     /**
      * Constructor that is called when inflating a Preference from XML. This is
@@ -534,7 +561,7 @@
         if (imageView != null) {
             if (mIconResId != 0 || mIcon != null) {
                 if (mIcon == null) {
-                    mIcon = getContext().getResources().getDrawable(mIconResId);
+                    mIcon = getContext().getDrawable(mIconResId);
                 }
                 if (mIcon != null) {
                     imageView.setImageDrawable(mIcon);
@@ -667,7 +694,7 @@
      */
     public void setIcon(int iconResId) {
         mIconResId = iconResId;
-        setIcon(mContext.getResources().getDrawable(iconResId));
+        setIcon(mContext.getDrawable(iconResId));
     }
 
     /**
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 2ab5a91..0418049 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -33,7 +33,6 @@
 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;
@@ -794,8 +793,8 @@
                 if ("header".equals(nodeName)) {
                     Header header = new Header();
 
-                    TypedArray sa = getResources().obtainAttributes(attrs,
-                            com.android.internal.R.styleable.PreferenceHeader);
+                    TypedArray sa = obtainStyledAttributes(
+                            attrs, com.android.internal.R.styleable.PreferenceHeader);
                     header.id = sa.getResourceId(
                             com.android.internal.R.styleable.PreferenceHeader_id,
                             (int)HEADER_ID_UNDEFINED);
@@ -1173,7 +1172,7 @@
         }
     }
 
-    private void switchToHeaderInner(String fragmentName, Bundle args, int direction) {
+    private void switchToHeaderInner(String fragmentName, Bundle args) {
         getFragmentManager().popBackStack(BACK_STACK_PREFS,
                 FragmentManager.POP_BACK_STACK_INCLUSIVE);
         if (!isValidFragment(fragmentName)) {
@@ -1196,7 +1195,7 @@
      */
     public void switchToHeader(String fragmentName, Bundle args) {
         setSelectedHeader(null);
-        switchToHeaderInner(fragmentName, args, 0);
+        switchToHeaderInner(fragmentName, args);
     }
 
     /**
@@ -1215,8 +1214,7 @@
             if (header.fragment == null) {
                 throw new IllegalStateException("can't switch to header that has no fragment");
             }
-            int direction = mHeaders.indexOf(header) - mHeaders.indexOf(mCurHeader);
-            switchToHeaderInner(header.fragment, header.fragmentArguments, direction);
+            switchToHeaderInner(header.fragment, header.fragmentArguments);
             setSelectedHeader(header);
         }
     }
diff --git a/core/java/android/preference/PreferenceCategory.java b/core/java/android/preference/PreferenceCategory.java
index 229a96a..253481b 100644
--- a/core/java/android/preference/PreferenceCategory.java
+++ b/core/java/android/preference/PreferenceCategory.java
@@ -16,8 +16,6 @@
 
 package android.preference;
 
-import java.util.Map;
-
 import android.content.Context;
 import android.util.AttributeSet;
 
@@ -34,9 +32,14 @@
  */
 public class PreferenceCategory extends PreferenceGroup {
     private static final String TAG = "PreferenceCategory";
-    
-    public PreferenceCategory(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public PreferenceCategory(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public PreferenceCategory(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public PreferenceCategory(Context context, AttributeSet attrs) {
diff --git a/core/java/android/preference/PreferenceFrameLayout.java b/core/java/android/preference/PreferenceFrameLayout.java
index 75372aa..886338f 100644
--- a/core/java/android/preference/PreferenceFrameLayout.java
+++ b/core/java/android/preference/PreferenceFrameLayout.java
@@ -16,7 +16,6 @@
 
 package android.preference;
 
-import android.app.FragmentBreadCrumbs;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -45,10 +44,15 @@
         this(context, attrs, com.android.internal.R.attr.preferenceFrameLayoutStyle);
     }
 
-    public PreferenceFrameLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.PreferenceFrameLayout, defStyle, 0);
+    public PreferenceFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PreferenceFrameLayout(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.PreferenceFrameLayout, defStyleAttr, defStyleRes);
 
         float density = context.getResources().getDisplayMetrics().density;
         int defaultBorderTop = (int) (density * DEFAULT_BORDER_TOP + 0.5f);
diff --git a/core/java/android/preference/PreferenceGroup.java b/core/java/android/preference/PreferenceGroup.java
index 5f8c78d..2d35b1b 100644
--- a/core/java/android/preference/PreferenceGroup.java
+++ b/core/java/android/preference/PreferenceGroup.java
@@ -55,19 +55,23 @@
     private int mCurrentPreferenceOrder = 0;
 
     private boolean mAttachedToActivity = false;
-    
-    public PreferenceGroup(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mPreferenceList = new ArrayList<Preference>();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.PreferenceGroup, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.PreferenceGroup, defStyleAttr, defStyleRes);
         mOrderingAsAdded = a.getBoolean(com.android.internal.R.styleable.PreferenceGroup_orderingFromXml,
                 mOrderingAsAdded);
         a.recycle();
     }
 
+    public PreferenceGroup(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public PreferenceGroup(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/android/preference/PreferenceInflater.java b/core/java/android/preference/PreferenceInflater.java
index c21aa18..727fbca 100644
--- a/core/java/android/preference/PreferenceInflater.java
+++ b/core/java/android/preference/PreferenceInflater.java
@@ -19,16 +19,13 @@
 import com.android.internal.util.XmlUtils;
 
 import java.io.IOException;
-import java.util.Map;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import android.app.AliasActivity;
 import android.content.Context;
 import android.content.Intent;
 import android.util.AttributeSet;
-import android.util.Log;
 
 /**
  * The {@link PreferenceInflater} is used to inflate preference hierarchies from
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 17f88f1..5c8c8e9 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -800,8 +800,10 @@
      * Interface definition for a callback to be invoked when a
      * {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is
      * clicked.
+     *
+     * @hide
      */
-    interface OnPreferenceTreeClickListener {
+    public interface OnPreferenceTreeClickListener {
         /**
          * Called when a preference in the tree rooted at this
          * {@link PreferenceScreen} has been clicked.
diff --git a/core/java/android/preference/PreferenceScreen.java b/core/java/android/preference/PreferenceScreen.java
index db80676..b1317e6 100644
--- a/core/java/android/preference/PreferenceScreen.java
+++ b/core/java/android/preference/PreferenceScreen.java
@@ -27,7 +27,6 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.Window;
-import android.widget.AbsListView;
 import android.widget.Adapter;
 import android.widget.AdapterView;
 import android.widget.ListAdapter;
diff --git a/core/java/android/preference/RingtonePreference.java b/core/java/android/preference/RingtonePreference.java
index 2ebf294..488a0c4 100644
--- a/core/java/android/preference/RingtonePreference.java
+++ b/core/java/android/preference/RingtonePreference.java
@@ -50,11 +50,11 @@
     
     private int mRequestCode;
 
-    public RingtonePreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.RingtonePreference, defStyle, 0);
+    public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.RingtonePreference, defStyleAttr, defStyleRes);
         mRingtoneType = a.getInt(com.android.internal.R.styleable.RingtonePreference_ringtoneType,
                 RingtoneManager.TYPE_RINGTONE);
         mShowDefault = a.getBoolean(com.android.internal.R.styleable.RingtonePreference_showDefault,
@@ -64,6 +64,10 @@
         a.recycle();
     }
 
+    public RingtonePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public RingtonePreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.ringtonePreferenceStyle);
     }
diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java
index 0e89b16..9a08827 100644
--- a/core/java/android/preference/SeekBarDialogPreference.java
+++ b/core/java/android/preference/SeekBarDialogPreference.java
@@ -32,8 +32,9 @@
 
     private Drawable mMyIcon;
 
-    public SeekBarDialogPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
+    public SeekBarDialogPreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog);
         createActionButtons();
@@ -43,6 +44,18 @@
         setDialogIcon(null);
     }
 
+    public SeekBarDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SeekBarDialogPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.dialogPreferenceStyle);
+    }
+
+    public SeekBarDialogPreference(Context context) {
+        this(context, null);
+    }
+
     // Allow subclasses to override the action buttons
     public void createActionButtons() {
         setPositiveButtonText(android.R.string.ok);
diff --git a/core/java/android/preference/SeekBarPreference.java b/core/java/android/preference/SeekBarPreference.java
index 7133d3a..e32890d 100644
--- a/core/java/android/preference/SeekBarPreference.java
+++ b/core/java/android/preference/SeekBarPreference.java
@@ -37,15 +37,20 @@
     private boolean mTrackingTouch;
 
     public SeekBarPreference(
-            Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ProgressBar, defStyle, 0);
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ProgressBar, defStyleAttr, defStyleRes);
         setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax));
         a.recycle();
         setLayoutResource(com.android.internal.R.layout.preference_widget_seekbar);
     }
 
+    public SeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public SeekBarPreference(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java
index 8bac6bd..76ef544 100644
--- a/core/java/android/preference/SwitchPreference.java
+++ b/core/java/android/preference/SwitchPreference.java
@@ -60,13 +60,19 @@
      *
      * @param context The Context that will style this preference
      * @param attrs Style attributes that differ from the default
-     * @param defStyle Theme attribute defining the default style options
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
      */
-    public SwitchPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.SwitchPreference, defStyle, 0);
+                com.android.internal.R.styleable.SwitchPreference, defStyleAttr, defStyleRes);
         setSummaryOn(a.getString(com.android.internal.R.styleable.SwitchPreference_summaryOn));
         setSummaryOff(a.getString(com.android.internal.R.styleable.SwitchPreference_summaryOff));
         setSwitchTextOn(a.getString(
@@ -83,6 +89,19 @@
      *
      * @param context The Context that will style this preference
      * @param attrs Style attributes that differ from the default
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     */
+    public SwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Construct a new SwitchPreference with the given style options.
+     *
+     * @param context The Context that will style this preference
+     * @param attrs Style attributes that differ from the default
      */
     public SwitchPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java
index af83953..6f8be1f 100644
--- a/core/java/android/preference/TwoStatePreference.java
+++ b/core/java/android/preference/TwoStatePreference.java
@@ -42,9 +42,13 @@
     private boolean mSendClickAccessibilityEvent;
     private boolean mDisableDependentsState;
 
+    public TwoStatePreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
 
-    public TwoStatePreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TwoStatePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public TwoStatePreference(Context context, AttributeSet attrs) {
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index dc683a6..29f2545 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -51,15 +51,24 @@
     /** May be null if the dialog isn't visible. */
     private SeekBarVolumizer mSeekBarVolumizer;
 
-    public VolumePreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
+    public VolumePreference(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.VolumePreference, 0, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.VolumePreference, defStyleAttr, defStyleRes);
         mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0);
         a.recycle();
     }
 
+    public VolumePreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public VolumePreference(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
     public void setStreamType(int streamType) {
         mStreamType = streamType;
     }
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index d1bb8fd..e4f73cb 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -359,6 +359,17 @@
      * selected the hinted options in the print dialog, given the current printer
      * supports them.
      * </p>
+     * <p>
+     * <strong>Note:</strong> Calling this method will bring the print dialog and
+     * the system will connect to the provided {@link PrintDocumentAdapter}. If a
+     * configuration change occurs that you application does not handle, for example
+     * a rotation change, the system will drop the connection to the adapter as the
+     * activity has to be recreated and the old adapter may be invalid in this context,
+     * hence a new adapter instance is required. As a consequence, if your activity
+     * does not handle configuration changes (default behavior), you have to save the
+     * state that you were printing and call this method again when your activity
+     * is recreated.
+     * </p>
      *
      * @param printJobName A name for the new print job which is shown to the user.
      * @param documentAdapter An adapter that emits the document to print.
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index a6f23a8..3b0d7ff 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -86,10 +86,8 @@
         public static final String ALLOW_VOICEMAILS_PARAM_KEY = "allow_voicemails";
 
         /**
-         * Content uri with {@link #ALLOW_VOICEMAILS_PARAM_KEY} set. This can directly be used to
-         * access call log entries that includes voicemail records.
-         *
-         * @hide
+         * Content uri used to access call log entries, including voicemail records. You must have
+         * the READ_CALL_LOG and WRITE_CALL_LOG permissions to read and write to the call log.
          */
         public static final Uri CONTENT_URI_WITH_VOICEMAIL = CONTENT_URI.buildUpon()
                 .appendQueryParameter(ALLOW_VOICEMAILS_PARAM_KEY, "true")
@@ -124,10 +122,7 @@
         public static final int OUTGOING_TYPE = 2;
         /** Call log type for missed calls. */
         public static final int MISSED_TYPE = 3;
-        /**
-         * Call log type for voicemails.
-         * @hide
-         */
+        /** Call log type for voicemails. */
         public static final int VOICEMAIL_TYPE = 4;
 
         /**
@@ -168,8 +163,6 @@
          * <P>
          * Type: TEXT
          * </P>
-         *
-         * @hide
          */
         public static final String COUNTRY_ISO = "countryiso";
 
@@ -220,7 +213,6 @@
         /**
          * URI of the voicemail entry. Populated only for {@link #VOICEMAIL_TYPE}.
          * <P>Type: TEXT</P>
-         * @hide
          */
         public static final String VOICEMAIL_URI = "voicemail_uri";
 
@@ -238,51 +230,48 @@
          * <p>
          * The string represents a city, state, or country associated with the number.
          * <P>Type: TEXT</P>
-         * @hide
          */
         public static final String GEOCODED_LOCATION = "geocoded_location";
 
         /**
          * The cached URI to look up the contact associated with the phone number, if it exists.
-         * This value is not guaranteed to be current, if the contact information
-         * associated with this number has changed.
+         * This value may not be current if the contact information associated with this number
+         * has changed.
          * <P>Type: TEXT</P>
-         * @hide
          */
         public static final String CACHED_LOOKUP_URI = "lookup_uri";
 
         /**
          * The cached phone number of the contact which matches this entry, if it exists.
-         * This value is not guaranteed to be current, if the contact information
-         * associated with this number has changed.
+         * This value may not be current if the contact information associated with this number
+         * has changed.
          * <P>Type: TEXT</P>
-         * @hide
          */
         public static final String CACHED_MATCHED_NUMBER = "matched_number";
 
         /**
-         * The cached normalized version of the phone number, if it exists.
-         * This value is not guaranteed to be current, if the contact information
-         * associated with this number has changed.
+         * The cached normalized(E164) version of the phone number, if it exists.
+         * This value may not be current if the contact information associated with this number
+         * has changed.
          * <P>Type: TEXT</P>
-         * @hide
          */
         public static final String CACHED_NORMALIZED_NUMBER = "normalized_number";
 
         /**
          * The cached photo id of the picture associated with the phone number, if it exists.
-         * This value is not guaranteed to be current, if the contact information
-         * associated with this number has changed.
+         * This value may not be current if the contact information associated with this number
+         * has changed.
          * <P>Type: INTEGER (long)</P>
-         * @hide
          */
         public static final String CACHED_PHOTO_ID = "photo_id";
 
         /**
-         * The cached formatted phone number.
-         * This value is not guaranteed to be present.
+         * The cached phone number, formatted with formatting rules based on the country the
+         * user was in when the call was made or received.
+         * This value is not guaranteed to be present, and may not be current if the contact
+         * information associated with this number
+         * has changed.
          * <P>Type: TEXT</P>
-         * @hide
          */
         public static final String CACHED_FORMATTED_NUMBER = "formatted_number";
 
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index c7e3c08..9e2aacd 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -26,7 +26,6 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
-import android.os.Build;
 import android.text.TextUtils;
 import android.util.Log;
 import android.widget.ImageView;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 0863368..11678a6 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -47,9 +47,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * <p>
@@ -167,8 +164,6 @@
      * {@link Contacts#CONTENT_STREQUENT_FILTER_URI}, which requires the ContactsProvider to
      * return only phone-related results. For example, frequently contacted person list should
      * include persons contacted via phone (not email, sms, etc.)
-     *
-     * @hide
      */
     public static final String STREQUENT_PHONE_ONLY = "strequent_phone_only";
 
@@ -193,8 +188,6 @@
      * {@link CommonDataKinds.Email#CONTENT_URI}, and
      * {@link CommonDataKinds.StructuredPostal#CONTENT_URI}.
      * This enables a content provider to remove duplicate entries in results.
-     *
-     * @hide
      */
     public static final String REMOVE_DUPLICATE_ENTRIES = "remove_duplicate_entries";
 
@@ -251,30 +244,21 @@
         public static final String KEY_AUTHORIZED_URI = "authorized_uri";
     }
 
-    /**
-     * @hide
-     */
     public static final class Preferences {
 
         /**
          * A key in the {@link android.provider.Settings android.provider.Settings} provider
          * that stores the preferred sorting order for contacts (by given name vs. by family name).
-         *
-         * @hide
          */
         public static final String SORT_ORDER = "android.contacts.SORT_ORDER";
 
         /**
          * The value for the SORT_ORDER key corresponding to sorting by given name first.
-         *
-         * @hide
          */
         public static final int SORT_ORDER_PRIMARY = 1;
 
         /**
          * The value for the SORT_ORDER key corresponding to sorting by family name first.
-         *
-         * @hide
          */
         public static final int SORT_ORDER_ALTERNATIVE = 2;
 
@@ -282,22 +266,16 @@
          * A key in the {@link android.provider.Settings android.provider.Settings} provider
          * that stores the preferred display order for contacts (given name first vs. family
          * name first).
-         *
-         * @hide
          */
         public static final String DISPLAY_ORDER = "android.contacts.DISPLAY_ORDER";
 
         /**
          * The value for the DISPLAY_ORDER key corresponding to showing the given name first.
-         *
-         * @hide
          */
         public static final int DISPLAY_ORDER_PRIMARY = 1;
 
         /**
          * The value for the DISPLAY_ORDER key corresponding to showing the family name first.
-         *
-         * @hide
          */
         public static final int DISPLAY_ORDER_ALTERNATIVE = 2;
     }
@@ -827,10 +805,9 @@
         public static final String STARRED = "starred";
 
         /**
-         * The position at which the contact is pinned. If {@link PinnedPositions.UNPINNED},
+         * 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";
 
@@ -924,6 +901,14 @@
         public static final String PHOTO_THUMBNAIL_URI = "photo_thumb_uri";
 
         /**
+         * Flag that reflects whether the contact exists inside the default directory.
+         * Ie, whether the contact is designed to only be visible outside search.
+         *
+         * @hide
+         */
+        public static final String IN_DEFAULT_DIRECTORY = "in_default_directory";
+
+        /**
          * Flag that reflects the {@link Groups#GROUP_VISIBLE} state of any
          * {@link CommonDataKinds.GroupMembership} for this contact.
          */
@@ -1470,17 +1455,43 @@
          * Base {@link Uri} for referencing multiple {@link Contacts} entry,
          * created by appending {@link #LOOKUP_KEY} using
          * {@link Uri#withAppendedPath(Uri, String)}. The lookup keys have to be
-         * encoded and joined with the colon (":") separator. The resulting string
-         * has to be encoded again. Provides
-         * {@link OpenableColumns} columns when queried, or returns the
+         * joined with the colon (":") separator, and the resulting string encoded.
+         *
+         * Provides {@link OpenableColumns} columns when queried, or returns the
          * referenced contact formatted as a vCard when opened through
          * {@link ContentResolver#openAssetFileDescriptor(Uri, String)}.
          *
-         * This is private API because we do not have a well-defined way to
-         * specify several entities yet. The format of this Uri might change in the future
-         * or the Uri might be completely removed.
+         * <p>
+         * Usage example:
+         * <dl>
+         * <dt>The following code snippet creates a multi-vcard URI that references all the
+         * contacts in a user's database.</dt>
+         * <dd>
          *
-         * @hide
+         * <pre>
+         * public Uri getAllContactsVcardUri() {
+         *     Cursor cursor = getActivity().getContentResolver().query(Contacts.CONTENT_URI,
+         *         new String[] {Contacts.LOOKUP_KEY}, null, null, null);
+         *     if (cursor == null) {
+         *         return null;
+         *     }
+         *     try {
+         *         StringBuilder uriListBuilder = new StringBuilder();
+         *         int index = 0;
+         *         while (cursor.moveToNext()) {
+         *             if (index != 0) uriListBuilder.append(':');
+         *             uriListBuilder.append(cursor.getString(0));
+         *             index++;
+         *         }
+         *         return Uri.withAppendedPath(Contacts.CONTENT_MULTI_VCARD_URI,
+         *                 Uri.encode(uriListBuilder.toString()));
+         *     } finally {
+         *         cursor.close();
+         *     }
+         * }
+         * </pre>
+         *
+         * </p>
          */
         public static final Uri CONTENT_MULTI_VCARD_URI = Uri.withAppendedPath(CONTENT_URI,
                 "as_multi_vcard");
@@ -4794,11 +4805,11 @@
          */
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone_lookup";
 
-       /**
-        * Boolean parameter that is used to look up a SIP address.
-        *
-        * @hide
-        */
+        /**
+         * If this boolean parameter is set to true, then the appended query is treated as a
+         * SIP address and the lookup will be performed against SIP addresses in the user's
+         * contacts.
+         */
         public static final String QUERY_PARAMETER_SIP_ADDRESS = "sip";
     }
 
@@ -5307,8 +5318,6 @@
             /**
              * The style used for combining given/middle/family name into a full name.
              * See {@link ContactsContract.FullNameStyle}.
-             *
-             * @hide
              */
             public static final String FULL_NAME_STYLE = DATA10;
 
@@ -6900,8 +6909,6 @@
          * each column. For example the meaning for {@link Phone}'s type is different than
          * {@link SipAddress}'s.
          * </p>
-         *
-         * @hide
          */
         public static final class Callable implements DataColumnsWithJoins, CommonColumns {
             /**
@@ -7759,7 +7766,6 @@
      * {@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 {
 
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index f69cad0..bd576af 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -169,6 +169,14 @@
      */
     public static final String EXTRA_MEDIA_TITLE = "android.intent.extra.title";
     /**
+     * The name of the Intent-extra used to define the genre.
+     */
+    public static final String EXTRA_MEDIA_GENRE = "android.intent.extra.genre";
+    /**
+     * The name of the Intent-extra used to define the radio channel.
+     */
+    public static final String EXTRA_MEDIA_RADIO_CHANNEL = "android.intent.extra.radio_channel";
+    /**
      * The name of the Intent-extra used to define the search focus. The search focus
      * indicates whether the search should be for things related to the artist, album
      * or song that is identified by the other extras.
@@ -1389,6 +1397,11 @@
             public static final String CONTENT_TYPE = "vnd.android.cursor.dir/audio";
 
             /**
+             * The MIME type for an audio track.
+             */
+            public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/audio";
+
+            /**
              * The default sort order for this table
              */
             public static final String DEFAULT_SORT_ORDER = TITLE_KEY;
@@ -1859,6 +1872,13 @@
              */
             public static final String DEFAULT_SORT_ORDER = ALBUM_KEY;
         }
+
+        public static final class Radio {
+            /**
+             * The MIME type for entries in this table.
+             */
+            public static final String ENTRY_CONTENT_TYPE = "vnd.android.cursor.item/radio";
+        }
     }
 
     public static final class Video {
diff --git a/core/java/android/provider/SearchIndexableData.java b/core/java/android/provider/SearchIndexableData.java
new file mode 100644
index 0000000..719dcea
--- /dev/null
+++ b/core/java/android/provider/SearchIndexableData.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider;
+
+import android.content.Context;
+
+import java.util.Locale;
+
+/**
+ * The Indexable data for Search.
+ *
+ * This abstract class defines the common parts for all search indexable data.
+ *
+ * @hide
+ */
+public abstract class SearchIndexableData {
+
+    /**
+     * The context for the data. Will usually allow retrieving some resources.
+     *
+     * @see Context
+     */
+    public Context context;
+
+    /**
+     * The locale for the data
+     */
+    public Locale locale;
+
+    /**
+     * Tells if the data will be included into the search results. This is application specific.
+     */
+    public boolean enabled;
+
+    /**
+     * The rank for the data. This is application specific.
+     */
+    public int rank;
+
+    /**
+     * The class name associated with the data. Generally this is a Fragment class name for
+     * referring where the data is coming from and for launching the associated Fragment for
+     * displaying the data. This is used only when the data is provided "locally".
+     *
+     * If the data is provided "externally", the relevant information come from the
+     * {@link SearchIndexableData#intentAction} and {@link SearchIndexableData#intentTargetPackage}
+     * and {@link SearchIndexableData#intentTargetClass}.
+     *
+     * @see SearchIndexableData#intentAction
+     * @see SearchIndexableData#intentTargetPackage
+     * @see SearchIndexableData#intentTargetClass
+     */
+    public String className;
+
+    /**
+     * The package name for retrieving the icon associated with the data.
+     *
+     * @see SearchIndexableData#iconResId
+     */
+    public String packageName;
+
+    /**
+     * The icon resource ID associated with the data.
+     *
+     * @see SearchIndexableData#packageName
+     */
+    public int iconResId;
+
+    /**
+     * The Intent action associated with the data. This is used when the
+     * {@link SearchIndexableData#className} is not relevant.
+     *
+     * @see SearchIndexableData#intentTargetPackage
+     * @see SearchIndexableData#intentTargetClass
+     */
+    public String intentAction;
+
+    /**
+     * The Intent target package associated with the data.
+     *
+     * @see SearchIndexableData#intentAction
+     * @see SearchIndexableData#intentTargetClass
+     */
+    public String intentTargetPackage;
+
+    /**
+     * The Intent target class associated with the data.
+     *
+     * @see SearchIndexableData#intentAction
+     * @see SearchIndexableData#intentTargetPackage
+     */
+    public String intentTargetClass;
+
+    /**
+     * Default constructor.
+     */
+    public SearchIndexableData() {
+        enabled = true;
+    }
+
+    /**
+     * Constructor with a {@link Context}.
+     *
+     * @param ctx the Context
+     */
+    public SearchIndexableData(Context ctx) {
+        context = ctx;
+        locale = Locale.getDefault();
+        enabled = true;
+    }
+}
diff --git a/core/java/android/provider/SearchIndexableResource.java b/core/java/android/provider/SearchIndexableResource.java
new file mode 100644
index 0000000..ba3bd4f
--- /dev/null
+++ b/core/java/android/provider/SearchIndexableResource.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider;
+
+import android.content.Context;
+
+/**
+ * Search Indexable Resource.
+ *
+ * This class wraps a set of reference information representing data that can be indexed from a
+ * resource which would typically be a {@link android.preference.PreferenceScreen}.
+ *
+ * xmlResId: the resource ID of a {@link android.preference.PreferenceScreen} XML file.
+ *
+ * @see SearchIndexableData
+ * @see android.preference.PreferenceScreen
+ *
+ * @hide
+ */
+public class SearchIndexableResource extends SearchIndexableData {
+
+    /**
+     * Resource ID of the associated {@link android.preference.PreferenceScreen} XML file.
+     */
+    public int xmlResId;
+
+    /**
+     * Constructor.
+     *
+     * @param rank the rank of the data.
+     * @param xmlResId the resource ID of a {@link android.preference.PreferenceScreen} XML file.
+     * @param className the class name associated with the data (generally a
+     *                  {@link android.app.Fragment}).
+     * @param iconResId the resource ID associated with the data.
+     */
+    public SearchIndexableResource(int rank, int xmlResId, String className, int iconResId) {
+        this.rank = rank;
+        this.xmlResId = xmlResId;
+        this.className = className;
+        this.iconResId = iconResId;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param context the Context associated with the data.
+     */
+    public SearchIndexableResource(Context context) {
+        super(context);
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/provider/SearchIndexablesContract.java b/core/java/android/provider/SearchIndexablesContract.java
new file mode 100644
index 0000000..b8635b8
--- /dev/null
+++ b/core/java/android/provider/SearchIndexablesContract.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider;
+
+import android.content.ContentResolver;
+
+/**
+ * Describe the contract for an Indexable data.
+ *
+ * @hide
+ */
+public class SearchIndexablesContract {
+
+    /**
+     * Intent action used to identify {@link SearchIndexablesProvider}
+     * instances. This is used in the {@code <intent-filter>} of a {@code <provider>}.
+     */
+    public static final String PROVIDER_INTERFACE =
+            "android.content.action.SEARCH_INDEXABLES_PROVIDER";
+
+    private static final String SETTINGS = "settings";
+
+    /**
+     * Indexable references name.
+     */
+    public static final String INDEXABLES_XML_RES = "indexables_xml_res";
+
+    /**
+     * ContentProvider path for indexable xml resources.
+     */
+    public static final String INDEXABLES_XML_RES_PATH = SETTINGS + "/" + INDEXABLES_XML_RES;
+
+    /**
+     * Indexable raw data name.
+     */
+    public static final String INDEXABLES_RAW = "indexables_raw";
+
+    /**
+     * ContentProvider path for indexable raw data.
+     */
+    public static final String INDEXABLES_RAW_PATH = SETTINGS + "/" + INDEXABLES_RAW;
+
+    /**
+     * Indexable xml resources colums.
+     */
+    public static final String[] INDEXABLES_XML_RES_COLUMNS = new String[] {
+            XmlResource.COLUMN_RANK,
+            XmlResource.COLUMN_XML_RESID,
+            XmlResource.COLUMN_CLASS_NAME,
+            XmlResource.COLUMN_ICON_RESID,
+            XmlResource.COLUMN_INTENT_ACTION,
+            XmlResource.COLUMN_INTENT_TARGET_PACKAGE,
+            XmlResource.COLUMN_INTENT_TARGET_CLASS
+    };
+
+    /**
+     * Indexable raw data colums.
+     */
+    public static final String[] INDEXABLES_RAW_COLUMNS = new String[] {
+            RawData.COLUMN_RANK,
+            RawData.COLUMN_TITLE,
+            RawData.COLUMN_SUMMARY,
+            RawData.COLUMN_KEYWORDS,
+            RawData.COLUMN_SCREEN_TITLE,
+            RawData.COLUMN_CLASS_NAME,
+            RawData.COLUMN_ICON_RESID,
+            RawData.COLUMN_INTENT_ACTION,
+            RawData.COLUMN_INTENT_TARGET_PACKAGE,
+            RawData.COLUMN_INTENT_TARGET_CLASS,
+    };
+
+    /**
+     * Constants related to a {@link SearchIndexableResource}.
+     *
+     * This is a description of
+     */
+    public static final class XmlResource extends BaseColumns {
+        private XmlResource() {
+        }
+
+        public static final String MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
+                "/" + INDEXABLES_XML_RES;
+
+        /**
+         * XML resource ID for the {@link android.preference.PreferenceScreen} to load and index.
+         */
+        public static final String COLUMN_XML_RESID = "xmlResId";
+    }
+
+    /**
+     * Constants related to a {@link SearchIndexableData}.
+     *
+     * This is the raw data that is stored into an Index. This is related to
+     * {@link android.preference.Preference} and its attributes like
+     * {@link android.preference.Preference#getTitle()},
+     * {@link android.preference.Preference#getSummary()}, etc.
+     *
+     */
+    public static final class RawData extends BaseColumns {
+        private RawData() {
+        }
+
+        public static final String MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +
+                "/" + INDEXABLES_RAW;
+
+        /**
+         * Title's raw data.
+         */
+        public static final String COLUMN_TITLE = "title";
+
+        /**
+         * Summary's raw data.
+         */
+        public static final String COLUMN_SUMMARY = "summary";
+
+        /**
+         * Keywords' raw data.
+         */
+        public static final String COLUMN_KEYWORDS = "keywords";
+
+        /**
+         * Fragment's title associated with the raw data.
+         */
+        public static final String COLUMN_SCREEN_TITLE = "screenTitle";
+    }
+
+    /**
+     * The base columns.
+     */
+    private static class BaseColumns {
+        private BaseColumns() {
+        }
+
+        /**
+         * Rank of the data. This is an integer used for ranking the search results. This is
+         * application specific.
+         */
+        public static final String COLUMN_RANK = "rank";
+
+        /**
+         * Class name associated with the data (usually a Fragment class name).
+         */
+        public static final String COLUMN_CLASS_NAME = "className";
+
+        /**
+         * Icon resource ID for the data.
+         */
+        public static final String COLUMN_ICON_RESID = "iconResId";
+
+        /**
+         * Intent action associated with the data.
+         */
+        public static final String COLUMN_INTENT_ACTION = "intentAction";
+
+        /**
+         * Intent target package associated with the data.
+         */
+        public static final String COLUMN_INTENT_TARGET_PACKAGE = "intentTargetPackage";
+
+        /**
+         * Intent target class associated with the data.
+         */
+        public static final String COLUMN_INTENT_TARGET_CLASS = "intentTargetClass";
+    }
+}
diff --git a/core/java/android/provider/SearchIndexablesProvider.java b/core/java/android/provider/SearchIndexablesProvider.java
new file mode 100644
index 0000000..2e358e4
--- /dev/null
+++ b/core/java/android/provider/SearchIndexablesProvider.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.provider;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.content.pm.ProviderInfo;
+import android.database.Cursor;
+import android.net.Uri;
+
+/**
+ * Base class for a search indexable provider. Such provider offers data to be indexed either
+ * as a reference to an XML file (like a {@link android.preference.PreferenceScreen}) or either
+ * as some raw data.
+ *
+ * @see SearchIndexableResource
+ * @see SearchIndexableData
+ * @see SearchIndexablesContract
+ *
+ * To create a search indexables provider, extend this class, then implement the abstract methods,
+ * and add it to your manifest like this:
+ *
+ * <pre class="prettyprint">&lt;manifest&gt;
+ *    ...
+ *    &lt;application&gt;
+ *        ...
+ *        &lt;provider
+ *            android:name="com.example.MyIndexablesProvider"
+ *            android:authorities="com.example.myindexablesprovider"
+ *            android:exported="true"
+ *            android:grantUriPermissions="true"
+ *            android:permission="android.permission.READ_SEARCH_INDEXABLES"
+ *            &lt;intent-filter&gt;
+ *                &lt;action android:name="android.content.action.SEARCH_INDEXABLES_PROVIDER" /&gt;
+ *            &lt;/intent-filter&gt;
+ *        &lt;/provider&gt;
+ *        ...
+ *    &lt;/application&gt;
+ *&lt;/manifest&gt;</pre>
+ * <p>
+ * When defining your provider, you must protect it with
+ * {@link android.Manifest.permission#READ_SEARCH_INDEXABLES}, which is a permission only the system
+ * can obtain.
+ * </p>
+ *
+ * @hide
+ */
+public abstract class SearchIndexablesProvider extends ContentProvider {
+    private static final String TAG = "IndexablesProvider";
+
+    private String mAuthority;
+    private UriMatcher mMatcher;
+
+    private static final int MATCH_RES_CODE = 1;
+    private static final int MATCH_RAW_CODE = 2;
+
+    /**
+     * 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, SearchIndexablesContract.INDEXABLES_XML_RES_PATH,
+                MATCH_RES_CODE);
+        mMatcher.addURI(mAuthority, SearchIndexablesContract.INDEXABLES_RAW_PATH,
+                MATCH_RAW_CODE);
+
+        // 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.READ_SEARCH_INDEXABLES.equals(info.readPermission)) {
+            throw new SecurityException("Provider must be protected by READ_SEARCH_INDEXABLES");
+        }
+
+        super.attachInfo(context, info);
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+                        String sortOrder) {
+        switch (mMatcher.match(uri)) {
+            case MATCH_RES_CODE:
+                return queryXmlResources(null);
+            case MATCH_RAW_CODE:
+                return queryRawData(null);
+            default:
+                throw new UnsupportedOperationException("Unknown Uri " + uri);
+        }
+    }
+
+    /**
+     * Returns all {@link android.provider.SearchIndexablesContract.XmlResource}.
+     *
+     * Those are usually xml resource ID to some {@link android.preference.PreferenceScreen}.
+     *
+     * @param projection list of {@link android.provider.SearchIndexablesContract.XmlResource}
+     *                   columns to put into the cursor. If {@code null} all supported columns
+     *                   should be included.
+     */
+    public abstract Cursor queryXmlResources(String[] projection);
+
+    /**
+     * Returns all {@link android.provider.SearchIndexablesContract.RawData}.
+     *
+     * Those are raw indexable data.
+     *
+     * @param projection list of {@link android.provider.SearchIndexablesContract.RawData} columns
+     *                   to put into the cursor. If {@code null} all supported columns should be
+     *                   included.
+     */
+    public abstract Cursor queryRawData(String[] projection);
+
+    @Override
+    public String getType(Uri uri) {
+        switch (mMatcher.match(uri)) {
+            case MATCH_RES_CODE:
+                return SearchIndexablesContract.XmlResource.MIME_TYPE;
+            case MATCH_RAW_CODE:
+                return SearchIndexablesContract.RawData.MIME_TYPE;
+            default:
+                throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+    }
+
+    /**
+     * Implementation is provided by the parent class. Throws by default, and
+     * cannot be overriden.
+     */
+    @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.
+     */
+    @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");
+    }
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3810eb3..7777334 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -749,6 +749,14 @@
     public static final String ACTION_PRINT_SETTINGS =
             "android.settings.ACTION_PRINT_SETTINGS";
 
+    /**
+     * Activity Action: Show Zen Mode configuration settings.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_ZEN_MODE_SETTINGS = "android.settings.ZEN_MODE_SETTINGS";
+
     // End of Intent actions for Settings
 
     /**
@@ -3352,21 +3360,29 @@
         public static final String INSTALL_NON_MARKET_APPS = Global.INSTALL_NON_MARKET_APPS;
 
         /**
-         * Comma-separated list of location providers that activities may access.
+         * Comma-separated list of location providers that activities may access. Do not rely on
+         * this value being present in settings.db or on ContentObserver notifications on the
+         * corresponding Uri.
          *
-         * @deprecated use {@link #LOCATION_MODE}
+         * @deprecated use {@link #LOCATION_MODE} and
+         * {@link LocationManager#MODE_CHANGED_ACTION} (or
+         * {@link LocationManager#PROVIDERS_CHANGED_ACTION})
          */
         @Deprecated
         public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
 
         /**
          * The degree of location access enabled by the user.
-         * <p/>
+         * <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.
+         * <p>
+         * Note: do not rely on this value being present in settings.db or on ContentObserver
+         * notifications for the corresponding Uri. Use {@link LocationManager#MODE_CHANGED_ACTION}
+         * to receive changes in this value.
          */
         public static final String LOCATION_MODE = "location_mode";
 
@@ -3407,6 +3423,11 @@
         public static final String LOCK_PATTERN_VISIBLE = "lock_pattern_visible_pattern";
 
         /**
+         * Whether the NFC unlock feature is enabled (0 = false, 1 = true)
+         */
+        public static final String NFC_UNLOCK_ENABLED = "nfc_unlock_enabled";
+
+        /**
          * Whether lock pattern will vibrate as user enters (0 = false, 1 =
          * true)
          *
@@ -3463,6 +3484,14 @@
             "lock_screen_owner_info_enabled";
 
         /**
+         * When set by a user, allows notifications to be shown atop a securely locked screen
+         * in their full "private" form (same as when the device is unlocked).
+         * @hide
+         */
+        public static final String LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS =
+                "lock_screen_allow_private_notifications";
+
+        /**
          * The Logging ID (a unique 64-bit value) as a hex string.
          * Used as a pseudonymous identifier for logging.
          * @deprecated This identifier is poorly initialized and has
@@ -3741,6 +3770,16 @@
                 "accessibility_captioning_edge_color";
 
         /**
+         * Integer property that specifes the window color for captions as a
+         * packed 32-bit color.
+         *
+         * @see android.graphics.Color#argb
+         * @hide
+         */
+        public static final String ACCESSIBILITY_CAPTIONING_WINDOW_COLOR =
+                "accessibility_captioning_window_color";
+
+        /**
          * String property that specifies the typeface for captions, one of:
          * <ul>
          * <li>DEFAULT
@@ -3764,6 +3803,97 @@
                 "accessibility_captioning_font_scale";
 
         /**
+         * Setting that specifies whether the quick setting tile for display
+         * color inversion is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED =
+                "accessibility_display_inversion_quick_setting_enabled";
+
+        /**
+         * Setting that specifies whether display color inversion is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_INVERSION_ENABLED =
+                "accessibility_display_inversion_enabled";
+
+        /**
+         * Integer property that specifies the type of color inversion to
+         * perform. Valid values are defined in AccessibilityManager.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_INVERSION =
+                "accessibility_display_inversion";
+
+        /**
+         * Setting that specifies whether the quick setting tile for display
+         * color space adjustment is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED =
+                "accessibility_display_daltonizer_quick_setting_enabled";
+
+        /**
+         * Setting that specifies whether display color space adjustment is
+         * enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED =
+                "accessibility_display_daltonizer_enabled";
+
+        /**
+         * Integer property that specifies the type of color space adjustment to
+         * perform. Valid values are defined in AccessibilityManager.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_DALTONIZER =
+                "accessibility_display_daltonizer";
+
+        /**
+         * Setting that specifies whether the quick setting tile for display
+         * contrast enhancement is enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED =
+                "accessibility_display_contrast_quick_setting_enabled";
+
+        /**
+         * Setting that specifies whether display contrast enhancement is
+         * enabled.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED =
+                "accessibility_display_contrast_enabled";
+
+        /**
+         * Floating point property that specifies display contrast adjustment.
+         * Valid range is [0, ...] where 0 is gray, 1 is normal, and higher
+         * values indicate enhanced contrast.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_CONTRAST =
+                "accessibility_display_contrast";
+
+        /**
+         * Floating point property that specifies display brightness adjustment.
+         * Valid range is [-1, 1] where -1 is black, 0 is default, and 1 is
+         * white.
+         *
+         * @hide
+         */
+        public static final String ACCESSIBILITY_DISPLAY_BRIGHTNESS =
+                "accessibility_display_brightness";
+
+        /**
          * The timout for considering a press to be a long press in milliseconds.
          * @hide
          */
@@ -5941,6 +6071,62 @@
         public static final String LOW_BATTERY_SOUND_TIMEOUT = "low_battery_sound_timeout";
 
         /**
+         * Milliseconds to wait before bouncing Wi-Fi after settings is restored. Note that after
+         * the caller is done with this, they should call {@link ContentResolver#delete(Uri)} to
+         * clean up any value that they may have written.
+         *
+         * @hide
+         */
+        public static final String WIFI_BOUNCE_DELAY_OVERRIDE_MS = "wifi_bounce_delay_override_ms";
+
+        /**
+         * Defines global runtime overrides to window policy.
+         *
+         * See {@link com.android.internal.policy.impl.PolicyControl} for value format.
+         *
+         * @hide
+         */
+        public static final String POLICY_CONTROL = "policy_control";
+
+
+        /**
+         * This preference enables notification display even over a securely
+         * locked screen.
+         * @hide
+         */
+        public static final String LOCK_SCREEN_SHOW_NOTIFICATIONS =
+                "lock_screen_show_notifications";
+
+        /**
+         * Defines global zen mode.  One of ZEN_MODE_OFF, ZEN_MODE_LIMITED, ZEN_MODE_FULL.
+         *
+         * @hide
+         */
+        public static final String ZEN_MODE = "zen_mode";
+
+        /** @hide */ public static final int ZEN_MODE_OFF = 0;
+        /** @hide */ public static final int ZEN_MODE_LIMITED = 1;
+        /** @hide */ public static final int ZEN_MODE_FULL = 2;
+
+        /** @hide */ public static String zenModeToString(int mode) {
+            if (mode == ZEN_MODE_OFF) return "ZEN_MODE_OFF";
+            if (mode == ZEN_MODE_LIMITED) return "ZEN_MODE_LIMITED";
+            if (mode == ZEN_MODE_FULL) return "ZEN_MODE_FULL";
+            throw new IllegalArgumentException("Invalid zen mode: " + mode);
+        }
+
+        /**
+         * Defines global heads up toggle.  One of HEADS_UP_OFF, HEADS_UP_ON.
+         *
+         * @hide
+         */
+        public static final String HEADS_UP_NOTIFICATIONS_ENABLED =
+                "heads_up_notifications_enabled";
+
+        /** @hide */ public static final int HEADS_UP_OFF = 0;
+        /** @hide */ public static final int HEADS_UP_ON = 1;
+
+        /**
          * 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/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
index 77b22ed..acfef82 100644
--- a/core/java/android/service/textservice/SpellCheckerService.java
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -32,7 +32,6 @@
 import android.view.textservice.SentenceSuggestionsInfo;
 import android.view.textservice.SuggestionsInfo;
 import android.view.textservice.TextInfo;
-import android.widget.SpellChecker;
 
 import java.lang.ref.WeakReference;
 import java.text.BreakIterator;
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 5db8168..03ce4e0 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -38,7 +38,6 @@
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.util.Log;
-import android.util.LogPrinter;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.IWindowSession;
diff --git a/core/java/android/speech/srec/Recognizer.java b/core/java/android/speech/srec/Recognizer.java
index 1396204..6c491a0 100644
--- a/core/java/android/speech/srec/Recognizer.java
+++ b/core/java/android/speech/srec/Recognizer.java
@@ -22,8 +22,6 @@
 
 package android.speech.srec;
 
-import android.util.Log;
-
 import java.io.File;
 import java.io.InputStream;
 import java.io.IOException;
diff --git a/core/java/android/speech/tts/AbstractEventLogger.java b/core/java/android/speech/tts/AbstractEventLogger.java
new file mode 100644
index 0000000..37f8656
--- /dev/null
+++ b/core/java/android/speech/tts/AbstractEventLogger.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 android.speech.tts;
+
+import android.os.SystemClock;
+
+/**
+ * Base class for storing data about a given speech synthesis request to the
+ * event logs. The data that is logged depends on actual implementation. Note
+ * that {@link AbstractEventLogger#onAudioDataWritten()} and
+ * {@link AbstractEventLogger#onEngineComplete()} must be called from a single
+ * thread (usually the audio playback thread}.
+ */
+abstract class AbstractEventLogger {
+    protected final String mServiceApp;
+    protected final int mCallerUid;
+    protected final int mCallerPid;
+    protected final long mReceivedTime;
+    protected long mPlaybackStartTime = -1;
+
+    private volatile long mRequestProcessingStartTime = -1;
+    private volatile long mEngineStartTime = -1;
+    private volatile long mEngineCompleteTime = -1;
+
+    private boolean mLogWritten = false;
+
+    AbstractEventLogger(int callerUid, int callerPid, String serviceApp) {
+        mCallerUid = callerUid;
+        mCallerPid = callerPid;
+        mServiceApp = serviceApp;
+        mReceivedTime = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Notifies the logger that this request has been selected from
+     * the processing queue for processing. Engine latency / total time
+     * is measured from this baseline.
+     */
+    public void onRequestProcessingStart() {
+        mRequestProcessingStartTime = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Notifies the logger that a chunk of data has been received from
+     * the engine. Might be called multiple times.
+     */
+    public void onEngineDataReceived() {
+        if (mEngineStartTime == -1) {
+            mEngineStartTime = SystemClock.elapsedRealtime();
+        }
+    }
+
+    /**
+     * Notifies the logger that the engine has finished processing data.
+     * Will be called exactly once.
+     */
+    public void onEngineComplete() {
+        mEngineCompleteTime = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Notifies the logger that audio playback has started for some section
+     * of the synthesis. This is normally some amount of time after the engine
+     * has synthesized data and varies depending on utterances and
+     * other audio currently in the queue.
+     */
+    public void onAudioDataWritten() {
+        // For now, keep track of only the first chunk of audio
+        // that was played.
+        if (mPlaybackStartTime == -1) {
+            mPlaybackStartTime = SystemClock.elapsedRealtime();
+        }
+    }
+
+    /**
+     * Notifies the logger that the current synthesis has completed.
+     * All available data is not logged.
+     */
+    public void onCompleted(int statusCode) {
+        if (mLogWritten) {
+            return;
+        } else {
+            mLogWritten = true;
+        }
+
+        long completionTime = SystemClock.elapsedRealtime();
+
+        // We don't report latency for stopped syntheses because their overall
+        // total time spent will be inaccurate (will not correlate with
+        // the length of the utterance).
+
+        // onAudioDataWritten() should normally always be called, and hence mPlaybackStartTime
+        // should be set, if an error does not occur.
+        if (statusCode != TextToSpeechClient.Status.SUCCESS
+                || mPlaybackStartTime == -1 || mEngineCompleteTime == -1) {
+            logFailure(statusCode);
+            return;
+        }
+
+        final long audioLatency = mPlaybackStartTime - mReceivedTime;
+        final long engineLatency = mEngineStartTime - mRequestProcessingStartTime;
+        final long engineTotal = mEngineCompleteTime - mRequestProcessingStartTime;
+        logSuccess(audioLatency, engineLatency, engineTotal);
+    }
+
+    protected abstract void logFailure(int statusCode);
+    protected abstract void logSuccess(long audioLatency, long engineLatency,
+            long engineTotal);
+
+
+}
diff --git a/core/java/android/speech/tts/AbstractSynthesisCallback.java b/core/java/android/speech/tts/AbstractSynthesisCallback.java
index c7a4af0..91e119b 100644
--- a/core/java/android/speech/tts/AbstractSynthesisCallback.java
+++ b/core/java/android/speech/tts/AbstractSynthesisCallback.java
@@ -15,15 +15,28 @@
  */
 package android.speech.tts;
 
+
 /**
  * Defines additional methods the synthesis callback must implement that
  * are private to the TTS service implementation.
+ *
+ * All of these class methods (with the exception of {@link #stop()}) can be only called on the
+ * synthesis thread, while inside
+ * {@link TextToSpeechService#onSynthesizeText} or {@link TextToSpeechService#onSynthesizeTextV2}.
+ * {@link #stop()} is the exception, it may be called from multiple threads.
  */
 abstract class AbstractSynthesisCallback implements SynthesisCallback {
+    /** If true, request comes from V2 TTS interface */
+    protected final boolean mClientIsUsingV2;
+
     /**
-     * Checks whether the synthesis request completed successfully.
+     * Constructor.
+     * @param clientIsUsingV2 If true, this callback will be used inside
+     *         {@link TextToSpeechService#onSynthesizeTextV2} method.
      */
-    abstract boolean isDone();
+    AbstractSynthesisCallback(boolean clientIsUsingV2) {
+        mClientIsUsingV2 = clientIsUsingV2;
+    }
 
     /**
      * Aborts the speech request.
@@ -31,4 +44,16 @@
      * Can be called from multiple threads.
      */
     abstract void stop();
+
+    /**
+     * Get status code for a "stop".
+     *
+     * V2 Clients will receive special status, V1 clients will receive standard error.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText}.
+     */
+    int errorCodeOnStop() {
+        return mClientIsUsingV2 ? TextToSpeechClient.Status.STOPPED : TextToSpeech.ERROR;
+    }
 }
diff --git a/core/java/android/speech/tts/AudioPlaybackHandler.java b/core/java/android/speech/tts/AudioPlaybackHandler.java
index d63f605..dcf49b0 100644
--- a/core/java/android/speech/tts/AudioPlaybackHandler.java
+++ b/core/java/android/speech/tts/AudioPlaybackHandler.java
@@ -43,7 +43,7 @@
             return;
         }
 
-        item.stop(false);
+        item.stop(TextToSpeechClient.Status.STOPPED);
     }
 
     public void enqueue(PlaybackQueueItem item) {
diff --git a/core/java/android/speech/tts/AudioPlaybackQueueItem.java b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
index 1a1fda81..c514639 100644
--- a/core/java/android/speech/tts/AudioPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
@@ -53,7 +53,7 @@
         dispatcher.dispatchOnStart();
         mPlayer = MediaPlayer.create(mContext, mUri);
         if (mPlayer == null) {
-            dispatcher.dispatchOnError();
+            dispatcher.dispatchOnError(TextToSpeechClient.Status.ERROR_OUTPUT);
             return;
         }
 
@@ -83,9 +83,9 @@
         }
 
         if (mFinished) {
-            dispatcher.dispatchOnDone();
+            dispatcher.dispatchOnSuccess();
         } else {
-            dispatcher.dispatchOnError();
+            dispatcher.dispatchOnStop();
         }
     }
 
@@ -99,7 +99,7 @@
     }
 
     @Override
-    void stop(boolean isError) {
+    void stop(int errorCode) {
         mDone.open();
     }
 }
diff --git a/core/java/android/speech/tts/EventLogTags.logtags b/core/java/android/speech/tts/EventLogTags.logtags
index f8654ad..e209a28 100644
--- a/core/java/android/speech/tts/EventLogTags.logtags
+++ b/core/java/android/speech/tts/EventLogTags.logtags
@@ -4,3 +4,6 @@
 
 76001 tts_speak_success (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(locale|3),(rate|1),(pitch|1),(engine_latency|2|3),(engine_total|2|3),(audio_latency|2|3)
 76002 tts_speak_failure (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(locale|3),(rate|1),(pitch|1)
+
+76003 tts_v2_speak_success (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(request_config|3),(engine_latency|2|3),(engine_total|2|3),(audio_latency|2|3)
+76004 tts_v2_speak_failure (engine|3),(caller_uid|1),(caller_pid|1),(length|1),(request_config|3), (statusCode|1)
diff --git a/core/java/android/speech/tts/EventLogger.java b/core/java/android/speech/tts/EventLogger.java
deleted file mode 100644
index 82ed4dd..0000000
--- a/core/java/android/speech/tts/EventLogger.java
+++ /dev/null
@@ -1,178 +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.speech.tts;
-
-import android.os.SystemClock;
-import android.text.TextUtils;
-import android.util.Log;
-
-/**
- * Writes data about a given speech synthesis request to the event logs.
- * The data that is logged includes the calling app, length of the utterance,
- * speech rate / pitch and the latency and overall time taken.
- *
- * Note that {@link EventLogger#onStopped()} and {@link EventLogger#onError()}
- * might be called from any thread, but on {@link EventLogger#onAudioDataWritten()} and
- * {@link EventLogger#onComplete()} must be called from a single thread
- * (usually the audio playback thread}
- */
-class EventLogger {
-    private final SynthesisRequest mRequest;
-    private final String mServiceApp;
-    private final int mCallerUid;
-    private final int mCallerPid;
-    private final long mReceivedTime;
-    private long mPlaybackStartTime = -1;
-    private volatile long mRequestProcessingStartTime = -1;
-    private volatile long mEngineStartTime = -1;
-    private volatile long mEngineCompleteTime = -1;
-
-    private volatile boolean mError = false;
-    private volatile boolean mStopped = false;
-    private boolean mLogWritten = false;
-
-    EventLogger(SynthesisRequest request, int callerUid, int callerPid, String serviceApp) {
-        mRequest = request;
-        mCallerUid = callerUid;
-        mCallerPid = callerPid;
-        mServiceApp = serviceApp;
-        mReceivedTime = SystemClock.elapsedRealtime();
-    }
-
-    /**
-     * Notifies the logger that this request has been selected from
-     * the processing queue for processing. Engine latency / total time
-     * is measured from this baseline.
-     */
-    public void onRequestProcessingStart() {
-        mRequestProcessingStartTime = SystemClock.elapsedRealtime();
-    }
-
-    /**
-     * Notifies the logger that a chunk of data has been received from
-     * the engine. Might be called multiple times.
-     */
-    public void onEngineDataReceived() {
-        if (mEngineStartTime == -1) {
-            mEngineStartTime = SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Notifies the logger that the engine has finished processing data.
-     * Will be called exactly once.
-     */
-    public void onEngineComplete() {
-        mEngineCompleteTime = SystemClock.elapsedRealtime();
-    }
-
-    /**
-     * Notifies the logger that audio playback has started for some section
-     * of the synthesis. This is normally some amount of time after the engine
-     * has synthesized data and varies depending on utterances and
-     * other audio currently in the queue.
-     */
-    public void onAudioDataWritten() {
-        // For now, keep track of only the first chunk of audio
-        // that was played.
-        if (mPlaybackStartTime == -1) {
-            mPlaybackStartTime = SystemClock.elapsedRealtime();
-        }
-    }
-
-    /**
-     * Notifies the logger that the current synthesis was stopped.
-     * Latency numbers are not reported for stopped syntheses.
-     */
-    public void onStopped() {
-        mStopped = false;
-    }
-
-    /**
-     * Notifies the logger that the current synthesis resulted in
-     * an error. This is logged using {@link EventLogTags#writeTtsSpeakFailure}.
-     */
-    public void onError() {
-        mError = true;
-    }
-
-    /**
-     * Notifies the logger that the current synthesis has completed.
-     * All available data is not logged.
-     */
-    public void onWriteData() {
-        if (mLogWritten) {
-            return;
-        } else {
-            mLogWritten = true;
-        }
-
-        long completionTime = SystemClock.elapsedRealtime();
-        // onAudioDataWritten() should normally always be called if an
-        // error does not occur.
-        if (mError || mPlaybackStartTime == -1 || mEngineCompleteTime == -1) {
-            EventLogTags.writeTtsSpeakFailure(mServiceApp, mCallerUid, mCallerPid,
-                    getUtteranceLength(), getLocaleString(),
-                    mRequest.getSpeechRate(), mRequest.getPitch());
-            return;
-        }
-
-        // We don't report stopped syntheses because their overall
-        // total time spent will be innacurate (will not correlate with
-        // the length of the utterance).
-        if (mStopped) {
-            return;
-        }
-
-        final long audioLatency = mPlaybackStartTime - mReceivedTime;
-        final long engineLatency = mEngineStartTime - mRequestProcessingStartTime;
-        final long engineTotal = mEngineCompleteTime - mRequestProcessingStartTime;
-
-        EventLogTags.writeTtsSpeakSuccess(mServiceApp, mCallerUid, mCallerPid,
-                getUtteranceLength(), getLocaleString(),
-                mRequest.getSpeechRate(), mRequest.getPitch(),
-                engineLatency, engineTotal, audioLatency);
-    }
-
-    /**
-     * @return the length of the utterance for the given synthesis, 0
-     *          if the utterance was {@code null}.
-     */
-    private int getUtteranceLength() {
-        final String utterance = mRequest.getText();
-        return utterance == null ? 0 : utterance.length();
-    }
-
-    /**
-     * Returns a formatted locale string from the synthesis params of the
-     * form lang-country-variant.
-     */
-    private String getLocaleString() {
-        StringBuilder sb = new StringBuilder(mRequest.getLanguage());
-        if (!TextUtils.isEmpty(mRequest.getCountry())) {
-            sb.append('-');
-            sb.append(mRequest.getCountry());
-
-            if (!TextUtils.isEmpty(mRequest.getVariant())) {
-                sb.append('-');
-                sb.append(mRequest.getVariant());
-            }
-        }
-
-        return sb.toString();
-    }
-
-}
diff --git a/core/java/android/speech/tts/EventLoggerV1.java b/core/java/android/speech/tts/EventLoggerV1.java
new file mode 100644
index 0000000..f484347
--- /dev/null
+++ b/core/java/android/speech/tts/EventLoggerV1.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 android.speech.tts;
+
+import android.text.TextUtils;
+
+/**
+ * Writes data about a given speech synthesis request for V1 API to the event
+ * logs. The data that is logged includes the calling app, length of the
+ * utterance, speech rate / pitch, the latency, and overall time taken.
+ */
+class EventLoggerV1 extends AbstractEventLogger {
+    private final SynthesisRequest mRequest;
+
+    EventLoggerV1(SynthesisRequest request, int callerUid, int callerPid, String serviceApp) {
+        super(callerUid, callerPid, serviceApp);
+        mRequest = request;
+    }
+
+    @Override
+    protected void logFailure(int statusCode) {
+        // We don't report stopped syntheses because their overall
+        // total time spent will be inaccurate (will not correlate with
+        // the length of the utterance).
+        if (statusCode != TextToSpeechClient.Status.STOPPED) {
+            EventLogTags.writeTtsSpeakFailure(mServiceApp, mCallerUid, mCallerPid,
+                    getUtteranceLength(), getLocaleString(),
+                    mRequest.getSpeechRate(), mRequest.getPitch());
+        }
+    }
+
+    @Override
+    protected void logSuccess(long audioLatency, long engineLatency, long engineTotal) {
+        EventLogTags.writeTtsSpeakSuccess(mServiceApp, mCallerUid, mCallerPid,
+                getUtteranceLength(), getLocaleString(),
+                mRequest.getSpeechRate(), mRequest.getPitch(),
+                engineLatency, engineTotal, audioLatency);
+    }
+
+    /**
+     * @return the length of the utterance for the given synthesis, 0
+     *          if the utterance was {@code null}.
+     */
+    private int getUtteranceLength() {
+        final String utterance = mRequest.getText();
+        return utterance == null ? 0 : utterance.length();
+    }
+
+    /**
+     * Returns a formatted locale string from the synthesis params of the
+     * form lang-country-variant.
+     */
+    private String getLocaleString() {
+        StringBuilder sb = new StringBuilder(mRequest.getLanguage());
+        if (!TextUtils.isEmpty(mRequest.getCountry())) {
+            sb.append('-');
+            sb.append(mRequest.getCountry());
+
+            if (!TextUtils.isEmpty(mRequest.getVariant())) {
+                sb.append('-');
+                sb.append(mRequest.getVariant());
+            }
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/core/java/android/speech/tts/EventLoggerV2.java b/core/java/android/speech/tts/EventLoggerV2.java
new file mode 100644
index 0000000..b8e4dae
--- /dev/null
+++ b/core/java/android/speech/tts/EventLoggerV2.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 android.speech.tts;
+
+
+
+/**
+ * Writes data about a given speech synthesis request for V2 API to the event logs.
+ * The data that is logged includes the calling app, length of the utterance,
+ * synthesis request configuration and the latency and overall time taken.
+ */
+class EventLoggerV2 extends AbstractEventLogger {
+    private final SynthesisRequestV2 mRequest;
+
+    EventLoggerV2(SynthesisRequestV2 request, int callerUid, int callerPid, String serviceApp) {
+        super(callerUid, callerPid, serviceApp);
+        mRequest = request;
+    }
+
+    @Override
+    protected void logFailure(int statusCode) {
+        // We don't report stopped syntheses because their overall
+        // total time spent will be inaccurate (will not correlate with
+        // the length of the utterance).
+        if (statusCode != TextToSpeechClient.Status.STOPPED) {
+            EventLogTags.writeTtsV2SpeakFailure(mServiceApp,
+                    mCallerUid, mCallerPid, getUtteranceLength(), getRequestConfigString(), statusCode);
+        }
+    }
+
+    @Override
+    protected void logSuccess(long audioLatency, long engineLatency, long engineTotal) {
+        EventLogTags.writeTtsV2SpeakSuccess(mServiceApp,
+                mCallerUid, mCallerPid, getUtteranceLength(), getRequestConfigString(),
+                engineLatency, engineTotal, audioLatency);
+    }
+
+    /**
+     * @return the length of the utterance for the given synthesis, 0
+     *          if the utterance was {@code null}.
+     */
+    private int getUtteranceLength() {
+        final String utterance = mRequest.getText();
+        return utterance == null ? 0 : utterance.length();
+    }
+
+    /**
+     * Returns a string representation of the synthesis request configuration.
+     */
+    private String getRequestConfigString() {
+        // Ensure the bundles are unparceled.
+        mRequest.getVoiceParams().size();
+        mRequest.getAudioParams().size();
+
+        return new StringBuilder(64).append("VoiceName: ").append(mRequest.getVoiceName())
+            .append(" ,VoiceParams: ").append(mRequest.getVoiceParams())
+            .append(" ,SystemParams: ").append(mRequest.getAudioParams())
+            .append("]").toString();
+    }
+}
diff --git a/core/java/android/speech/tts/FileSynthesisCallback.java b/core/java/android/speech/tts/FileSynthesisCallback.java
index ab8f82f..717aeb6 100644
--- a/core/java/android/speech/tts/FileSynthesisCallback.java
+++ b/core/java/android/speech/tts/FileSynthesisCallback.java
@@ -16,13 +16,10 @@
 package android.speech.tts;
 
 import android.media.AudioFormat;
-import android.os.FileUtils;
+import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
 import android.util.Log;
 
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.channels.FileChannel;
@@ -48,19 +45,39 @@
 
     private FileChannel mFileChannel;
 
+    private final UtteranceProgressDispatcher mDispatcher;
+    private final Object mCallerIdentity;
+
     private boolean mStarted = false;
-    private boolean mStopped = false;
     private boolean mDone = false;
 
-    FileSynthesisCallback(FileChannel fileChannel) {
+    /** Status code of synthesis */
+    protected int mStatusCode;
+
+    FileSynthesisCallback(FileChannel fileChannel, UtteranceProgressDispatcher dispatcher,
+            Object callerIdentity, boolean clientIsUsingV2) {
+        super(clientIsUsingV2);
         mFileChannel = fileChannel;
+        mDispatcher = dispatcher;
+        mCallerIdentity = callerIdentity;
+        mStatusCode = TextToSpeechClient.Status.SUCCESS;
     }
 
     @Override
     void stop() {
         synchronized (mStateLock) {
-            mStopped = true;
+            if (mDone) {
+                return;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+                return;
+            }
+
+            mStatusCode = TextToSpeechClient.Status.STOPPED;
             cleanUp();
+            if (mDispatcher != null) {
+                mDispatcher.dispatchOnStop();
+            }
         }
     }
 
@@ -75,14 +92,8 @@
      * Must be called while holding the monitor on {@link #mStateLock}.
      */
     private void closeFile() {
-        try {
-            if (mFileChannel != null) {
-                mFileChannel.close();
-                mFileChannel = null;
-            }
-        } catch (IOException ex) {
-            Log.e(TAG, "Failed to close output file descriptor", ex);
-        }
+        // File will be closed by the SpeechItem in the speech service.
+        mFileChannel = null;
     }
 
     @Override
@@ -91,38 +102,46 @@
     }
 
     @Override
-    boolean isDone() {
-        return mDone;
-    }
-
-    @Override
     public int start(int sampleRateInHz, int audioFormat, int channelCount) {
         if (DBG) {
             Log.d(TAG, "FileSynthesisRequest.start(" + sampleRateInHz + "," + audioFormat
                     + "," + channelCount + ")");
         }
+        FileChannel fileChannel = null;
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
                 return TextToSpeech.ERROR;
             }
             if (mStarted) {
-                cleanUp();
-                throw new IllegalArgumentException("FileSynthesisRequest.start() called twice");
+                Log.e(TAG, "Start called twice");
+                return TextToSpeech.ERROR;
             }
             mStarted = true;
             mSampleRateInHz = sampleRateInHz;
             mAudioFormat = audioFormat;
             mChannelCount = channelCount;
 
-            try {
-                mFileChannel.write(ByteBuffer.allocate(WAV_HEADER_LENGTH));
-                return TextToSpeech.SUCCESS;
-            } catch (IOException ex) {
-                Log.e(TAG, "Failed to write wav header to output file descriptor" + ex);
-                cleanUp();
-                return TextToSpeech.ERROR;
+            if (mDispatcher != null) {
+                mDispatcher.dispatchOnStart();
             }
+            fileChannel = mFileChannel;
+        }
+
+        try {
+            fileChannel.write(ByteBuffer.allocate(WAV_HEADER_LENGTH));
+                return TextToSpeech.SUCCESS;
+        } catch (IOException ex) {
+            Log.e(TAG, "Failed to write wav header to output file descriptor", ex);
+            synchronized (mStateLock) {
+                cleanUp();
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+            }
+            return TextToSpeech.ERROR;
         }
     }
 
@@ -132,66 +151,128 @@
             Log.d(TAG, "FileSynthesisRequest.audioAvailable(" + buffer + "," + offset
                     + "," + length + ")");
         }
+        FileChannel fileChannel = null;
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
                 return TextToSpeech.ERROR;
             }
             if (mFileChannel == null) {
                 Log.e(TAG, "File not open");
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
                 return TextToSpeech.ERROR;
             }
-            try {
-                mFileChannel.write(ByteBuffer.wrap(buffer,  offset,  length));
-                return TextToSpeech.SUCCESS;
-            } catch (IOException ex) {
-                Log.e(TAG, "Failed to write to output file descriptor", ex);
+            if (!mStarted) {
+                Log.e(TAG, "Start method was not called");
+                return TextToSpeech.ERROR;
+            }
+            fileChannel = mFileChannel;
+        }
+
+        try {
+            fileChannel.write(ByteBuffer.wrap(buffer,  offset,  length));
+            return TextToSpeech.SUCCESS;
+        } catch (IOException ex) {
+            Log.e(TAG, "Failed to write to output file descriptor", ex);
+            synchronized (mStateLock) {
                 cleanUp();
-                return TextToSpeech.ERROR;
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
             }
+            return TextToSpeech.ERROR;
         }
     }
 
     @Override
     public int done() {
         if (DBG) Log.d(TAG, "FileSynthesisRequest.done()");
+        FileChannel fileChannel = null;
+
+        int sampleRateInHz = 0;
+        int audioFormat = 0;
+        int channelCount = 0;
+
         synchronized (mStateLock) {
             if (mDone) {
-                if (DBG) Log.d(TAG, "Duplicate call to done()");
-                // This preserves existing behaviour. Earlier, if done was called twice
-                // we'd return ERROR because mFile == null and we'd add to logspam.
+                Log.w(TAG, "Duplicate call to done()");
+                // This is not an error that would prevent synthesis. Hence no
+                // setStatusCode is set.
                 return TextToSpeech.ERROR;
             }
-            if (mStopped) {
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
+            if (mDispatcher != null && mStatusCode != TextToSpeechClient.Status.SUCCESS &&
+                    mStatusCode != TextToSpeechClient.Status.STOPPED) {
+                mDispatcher.dispatchOnError(mStatusCode);
                 return TextToSpeech.ERROR;
             }
             if (mFileChannel == null) {
                 Log.e(TAG, "File not open");
                 return TextToSpeech.ERROR;
             }
-            try {
-                // Write WAV header at start of file
-                mFileChannel.position(0);
-                int dataLength = (int) (mFileChannel.size() - WAV_HEADER_LENGTH);
-                mFileChannel.write(
-                        makeWavHeader(mSampleRateInHz, mAudioFormat, mChannelCount, dataLength));
+            mDone = true;
+            fileChannel = mFileChannel;
+            sampleRateInHz = mSampleRateInHz;
+            audioFormat = mAudioFormat;
+            channelCount = mChannelCount;
+        }
+
+        try {
+            // Write WAV header at start of file
+            fileChannel.position(0);
+            int dataLength = (int) (fileChannel.size() - WAV_HEADER_LENGTH);
+            fileChannel.write(
+                    makeWavHeader(sampleRateInHz, audioFormat, channelCount, dataLength));
+
+            synchronized (mStateLock) {
                 closeFile();
-                mDone = true;
+                if (mDispatcher != null) {
+                    mDispatcher.dispatchOnSuccess();
+                }
                 return TextToSpeech.SUCCESS;
-            } catch (IOException ex) {
-                Log.e(TAG, "Failed to write to output file descriptor", ex);
-                cleanUp();
-                return TextToSpeech.ERROR;
             }
+        } catch (IOException ex) {
+            Log.e(TAG, "Failed to write to output file descriptor", ex);
+            synchronized (mStateLock) {
+                cleanUp();
+            }
+            return TextToSpeech.ERROR;
         }
     }
 
     @Override
     public void error() {
+        error(TextToSpeechClient.Status.ERROR_SYNTHESIS);
+    }
+
+    @Override
+    public void error(int errorCode) {
         if (DBG) Log.d(TAG, "FileSynthesisRequest.error()");
         synchronized (mStateLock) {
+            if (mDone) {
+                return;
+            }
             cleanUp();
+            mStatusCode = errorCode;
+        }
+    }
+
+    @Override
+    public boolean hasStarted() {
+        synchronized (mStateLock) {
+            return mStarted;
+        }
+    }
+
+    @Override
+    public boolean hasFinished() {
+        synchronized (mStateLock) {
+            return mDone;
         }
     }
 
@@ -225,4 +306,16 @@
         return header;
     }
 
+    @Override
+    public int fallback() {
+        synchronized (mStateLock) {
+            if (hasStarted() || hasFinished()) {
+                return TextToSpeech.ERROR;
+            }
+
+            mDispatcher.dispatchOnFallback();
+            mStatusCode = TextToSpeechClient.Status.SUCCESS;
+            return TextToSpeechClient.Status.SUCCESS;
+        }
+    }
 }
diff --git a/core/java/android/speech/tts/ITextToSpeechCallback.aidl b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
index f0287d4..3c808ff 100644
--- a/core/java/android/speech/tts/ITextToSpeechCallback.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechCallback.aidl
@@ -15,13 +15,53 @@
  */
 package android.speech.tts;
 
+import android.speech.tts.VoiceInfo;
+
 /**
  * Interface for callbacks from TextToSpeechService
  *
  * {@hide}
  */
 oneway interface ITextToSpeechCallback {
+    /**
+     * Tells the client that the synthesis has started.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
     void onStart(String utteranceId);
-    void onDone(String utteranceId);
-    void onError(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis has finished.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
+    void onSuccess(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis was stopped.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
+    void onStop(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis failed, and fallback synthesis will be attempted.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     */
+    void onFallback(String utteranceId);
+
+    /**
+     * Tells the client that the synthesis has failed.
+     *
+     * @param utteranceId Unique id identifying synthesis request.
+     * @param errorCode One of the values from
+     *        {@link android.speech.tts.v2.TextToSpeechClient.Status}.
+     */
+    void onError(String utteranceId, int errorCode);
+
+    /**
+     * Inform the client that set of available voices changed.
+     */
+    void onVoicesInfoChange(in List<VoiceInfo> voices);
 }
diff --git a/core/java/android/speech/tts/ITextToSpeechService.aidl b/core/java/android/speech/tts/ITextToSpeechService.aidl
index b7bc70c..9cf49ff 100644
--- a/core/java/android/speech/tts/ITextToSpeechService.aidl
+++ b/core/java/android/speech/tts/ITextToSpeechService.aidl
@@ -20,6 +20,8 @@
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 import android.speech.tts.ITextToSpeechCallback;
+import android.speech.tts.VoiceInfo;
+import android.speech.tts.SynthesisRequestV2;
 
 /**
  * Interface for TextToSpeech to talk to TextToSpeechService.
@@ -70,9 +72,10 @@
      *        TextToSpeech object.
      * @param duration Number of milliseconds of silence to play.
      * @param queueMode Determines what to do to requests already in the queue.
-     * @param param Request parameters.
+     * @param utteranceId Unique id used to identify this request in callbacks.
      */
-    int playSilence(in IBinder callingInstance, in long duration, in int queueMode, in Bundle params);
+    int playSilence(in IBinder callingInstance, in long duration, in int queueMode,
+        in String utteranceId);
 
     /**
      * Checks whether the service is currently playing some audio.
@@ -90,7 +93,6 @@
 
     /**
      * Returns the language, country and variant currently being used by the TTS engine.
-     *
      * Can be called from multiple threads.
      *
      * @return A 3-element array, containing language (ISO 3-letter code),
@@ -99,7 +101,7 @@
      *         be empty too.
      */
     String[] getLanguage();
-    
+
     /**
      * Returns a default TTS language, country and variant as set by the user.
      *
@@ -111,7 +113,7 @@
      *         be empty too.
      */
     String[] getClientDefaultLanguage();
-    
+
     /**
      * Checks whether the engine supports a given language.
      *
@@ -137,7 +139,7 @@
      * @param country ISO-3 country code. May be empty or null.
      * @param variant Language variant. May be empty or null.
      * @return An array of strings containing the set of features supported for
-     *         the supplied locale. The array of strings must not contain 
+     *         the supplied locale. The array of strings must not contain
      *         duplicates.
      */
     String[] getFeaturesForLanguage(in String lang, in String country, in String variant);
@@ -169,4 +171,44 @@
      */
     void setCallback(in IBinder caller, ITextToSpeechCallback cb);
 
+    /**
+     * Tells the engine to synthesize some speech and play it back.
+     *
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
+     * @param text The text to synthesize.
+     * @param queueMode Determines what to do to requests already in the queue.
+     * @param request Request parameters.
+     */
+    int speakV2(in IBinder callingInstance, in SynthesisRequestV2 request);
+
+    /**
+     * Tells the engine to synthesize some speech and write it to a file.
+     *
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
+     * @param text The text to synthesize.
+     * @param fileDescriptor The file descriptor to write the synthesized audio to. Has to be
+              writable.
+     * @param request Request parameters.
+     */
+    int synthesizeToFileDescriptorV2(in IBinder callingInstance,
+        in ParcelFileDescriptor fileDescriptor, in SynthesisRequestV2 request);
+
+    /**
+     * Plays an existing audio resource. V2 version
+     *
+     * @param callingInstance a binder representing the identity of the calling
+     *        TextToSpeech object.
+     * @param audioUri URI for the audio resource (a file or android.resource URI)
+     * @param utteranceId Unique identifier.
+     * @param audioParameters Parameters for audio playback (from {@link SynthesisRequestV2}).
+     */
+    int playAudioV2(in IBinder callingInstance, in Uri audioUri, in String utteranceId,
+        in Bundle audioParameters);
+
+    /**
+     * Request the list of available voices from the service.
+     */
+    List<VoiceInfo> getVoicesInfo();
 }
diff --git a/core/java/android/speech/tts/PlaybackQueueItem.java b/core/java/android/speech/tts/PlaybackQueueItem.java
index d0957ff..b2e323e 100644
--- a/core/java/android/speech/tts/PlaybackQueueItem.java
+++ b/core/java/android/speech/tts/PlaybackQueueItem.java
@@ -22,6 +22,16 @@
         return mDispatcher;
     }
 
+    @Override
     public abstract void run();
-    abstract void stop(boolean isError);
+
+    /**
+     * Stop the playback.
+     *
+     * @param errorCode Cause of the stop. Can be either one of the error codes from
+     *         {@link android.speech.tts.TextToSpeechClient.Status} or
+     *         {@link android.speech.tts.TextToSpeechClient.Status#STOPPED}
+     *         if stopped on a client request.
+     */
+    abstract void stop(int errorCode);
 }
diff --git a/core/java/android/speech/tts/PlaybackSynthesisCallback.java b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
index c99f201..e345e89 100644
--- a/core/java/android/speech/tts/PlaybackSynthesisCallback.java
+++ b/core/java/android/speech/tts/PlaybackSynthesisCallback.java
@@ -55,20 +55,20 @@
     private final AudioPlaybackHandler mAudioTrackHandler;
     // A request "token", which will be non null after start() has been called.
     private SynthesisPlaybackQueueItem mItem = null;
-    // Whether this request has been stopped. This is useful for keeping
-    // track whether stop() has been called before start(). In all other cases,
-    // a non-null value of mItem will provide the same information.
-    private boolean mStopped = false;
 
     private volatile boolean mDone = false;
 
+    /** Status code of synthesis */
+    protected int mStatusCode;
+
     private final UtteranceProgressDispatcher mDispatcher;
     private final Object mCallerIdentity;
-    private final EventLogger mLogger;
+    private final AbstractEventLogger mLogger;
 
     PlaybackSynthesisCallback(int streamType, float volume, float pan,
             AudioPlaybackHandler audioTrackHandler, UtteranceProgressDispatcher dispatcher,
-            Object callerIdentity, EventLogger logger) {
+            Object callerIdentity, AbstractEventLogger logger, boolean clientIsUsingV2) {
+        super(clientIsUsingV2);
         mStreamType = streamType;
         mVolume = volume;
         mPan = pan;
@@ -76,28 +76,25 @@
         mDispatcher = dispatcher;
         mCallerIdentity = callerIdentity;
         mLogger = logger;
+        mStatusCode = TextToSpeechClient.Status.SUCCESS;
     }
 
     @Override
     void stop() {
-        stopImpl(false);
-    }
-
-    void stopImpl(boolean wasError) {
         if (DBG) Log.d(TAG, "stop()");
 
-        // Note that mLogger.mError might be true too at this point.
-        mLogger.onStopped();
-
         SynthesisPlaybackQueueItem item;
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (mDone) {
+                return;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 Log.w(TAG, "stop() called twice");
                 return;
             }
 
             item = mItem;
-            mStopped = true;
+            mStatusCode = TextToSpeechClient.Status.STOPPED;
         }
 
         if (item != null) {
@@ -105,19 +102,15 @@
             // point it will write an additional buffer to the item - but we
             // won't worry about that because the audio playback queue will be cleared
             // soon after (see SynthHandler#stop(String).
-            item.stop(wasError);
+            item.stop(TextToSpeechClient.Status.STOPPED);
         } else {
             // This happens when stop() or error() were called before start() was.
 
             // In all other cases, mAudioTrackHandler.stop() will
             // result in onSynthesisDone being called, and we will
             // write data there.
-            mLogger.onWriteData();
-
-            if (wasError) {
-                // We have to dispatch the error ourselves.
-                mDispatcher.dispatchOnError();
-            }
+            mLogger.onCompleted(TextToSpeechClient.Status.STOPPED);
+            mDispatcher.dispatchOnStop();
         }
     }
 
@@ -129,26 +122,42 @@
     }
 
     @Override
-    boolean isDone() {
-        return mDone;
+    public boolean hasStarted() {
+        synchronized (mStateLock) {
+            return mItem != null;
+        }
+    }
+
+    @Override
+    public boolean hasFinished() {
+        synchronized (mStateLock) {
+            return mDone;
+        }
     }
 
     @Override
     public int start(int sampleRateInHz, int audioFormat, int channelCount) {
-        if (DBG) {
-            Log.d(TAG, "start(" + sampleRateInHz + "," + audioFormat
-                    + "," + channelCount + ")");
-        }
+        if (DBG) Log.d(TAG, "start(" + sampleRateInHz + "," + audioFormat + "," + channelCount
+                + ")");
 
         int channelConfig = BlockingAudioTrack.getChannelConfig(channelCount);
-        if (channelConfig == 0) {
-            Log.e(TAG, "Unsupported number of channels :" + channelCount);
-            return TextToSpeech.ERROR;
-        }
 
         synchronized (mStateLock) {
-            if (mStopped) {
+            if (channelConfig == 0) {
+                Log.e(TAG, "Unsupported number of channels :" + channelCount);
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+                return TextToSpeech.ERROR;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
                 if (DBG) Log.d(TAG, "stop() called before start(), returning.");
+                return errorCodeOnStop();
+            }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
+                return TextToSpeech.ERROR;
+            }
+            if (mItem != null) {
+                Log.e(TAG, "Start called twice");
                 return TextToSpeech.ERROR;
             }
             SynthesisPlaybackQueueItem item = new SynthesisPlaybackQueueItem(
@@ -161,13 +170,11 @@
         return TextToSpeech.SUCCESS;
     }
 
-
     @Override
     public int audioAvailable(byte[] buffer, int offset, int length) {
-        if (DBG) {
-            Log.d(TAG, "audioAvailable(byte[" + buffer.length + "],"
-                    + offset + "," + length + ")");
-        }
+        if (DBG) Log.d(TAG, "audioAvailable(byte[" + buffer.length + "]," + offset + "," + length
+                + ")");
+
         if (length > getMaxBufferSize() || length <= 0) {
             throw new IllegalArgumentException("buffer is too large or of zero length (" +
                     + length + " bytes)");
@@ -175,9 +182,17 @@
 
         SynthesisPlaybackQueueItem item = null;
         synchronized (mStateLock) {
-            if (mItem == null || mStopped) {
+            if (mItem == null) {
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
                 return TextToSpeech.ERROR;
             }
+            if (mStatusCode != TextToSpeechClient.Status.SUCCESS) {
+                if (DBG) Log.d(TAG, "Error was raised");
+                return TextToSpeech.ERROR;
+            }
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+                return errorCodeOnStop();
+            }
             item = mItem;
         }
 
@@ -190,11 +205,13 @@
         try {
             item.put(bufferCopy);
         } catch (InterruptedException ie) {
-            return TextToSpeech.ERROR;
+            synchronized (mStateLock) {
+                mStatusCode = TextToSpeechClient.Status.ERROR_OUTPUT;
+                return TextToSpeech.ERROR;
+            }
         }
 
         mLogger.onEngineDataReceived();
-
         return TextToSpeech.SUCCESS;
     }
 
@@ -202,35 +219,74 @@
     public int done() {
         if (DBG) Log.d(TAG, "done()");
 
+        int statusCode = 0;
         SynthesisPlaybackQueueItem item = null;
         synchronized (mStateLock) {
             if (mDone) {
                 Log.w(TAG, "Duplicate call to done()");
+                // Not an error that would prevent synthesis. Hence no
+                // setStatusCode
                 return TextToSpeech.ERROR;
             }
-
+            if (mStatusCode == TextToSpeechClient.Status.STOPPED) {
+                if (DBG) Log.d(TAG, "Request has been aborted.");
+                return errorCodeOnStop();
+            }
             mDone = true;
 
             if (mItem == null) {
+                // .done() was called before .start. Treat it as successful synthesis
+                // for a client, despite service bad implementation.
+                Log.w(TAG, "done() was called before start() call");
+                if (mStatusCode == TextToSpeechClient.Status.SUCCESS) {
+                    mDispatcher.dispatchOnSuccess();
+                } else {
+                    mDispatcher.dispatchOnError(mStatusCode);
+                }
+                mLogger.onEngineComplete();
                 return TextToSpeech.ERROR;
             }
 
             item = mItem;
+            statusCode = mStatusCode;
         }
 
-        item.done();
+        // Signal done or error to item
+        if (statusCode == TextToSpeechClient.Status.SUCCESS) {
+            item.done();
+        } else {
+            item.stop(statusCode);
+        }
         mLogger.onEngineComplete();
-
         return TextToSpeech.SUCCESS;
     }
 
     @Override
     public void error() {
-        if (DBG) Log.d(TAG, "error() [will call stop]");
-        // Currently, this call will not be logged if error( ) is called
-        // before start.
-        mLogger.onError();
-        stopImpl(true);
+        error(TextToSpeechClient.Status.ERROR_SYNTHESIS);
     }
 
+    @Override
+    public void error(int errorCode) {
+        if (DBG) Log.d(TAG, "error() [will call stop]");
+        synchronized (mStateLock) {
+            if (mDone) {
+                return;
+            }
+            mStatusCode = errorCode;
+        }
+    }
+
+    @Override
+    public int fallback() {
+        synchronized (mStateLock) {
+            if (hasStarted() || hasFinished()) {
+                return TextToSpeech.ERROR;
+            }
+
+            mDispatcher.dispatchOnFallback();
+            mStatusCode = TextToSpeechClient.Status.SUCCESS;
+            return TextToSpeechClient.Status.SUCCESS;
+        }
+    }
 }
diff --git a/core/java/android/speech/tts/RequestConfig.java b/core/java/android/speech/tts/RequestConfig.java
new file mode 100644
index 0000000..4b5385f
--- /dev/null
+++ b/core/java/android/speech/tts/RequestConfig.java
@@ -0,0 +1,213 @@
+package android.speech.tts;
+
+import android.media.AudioManager;
+import android.os.Bundle;
+
+/**
+ * Synthesis request configuration.
+ *
+ * This class is immutable, and can only be constructed using
+ * {@link RequestConfig.Builder}.
+ */
+public final class RequestConfig {
+
+    /** Builder for constructing RequestConfig objects. */
+    public static final class Builder {
+        private VoiceInfo mCurrentVoiceInfo;
+        private Bundle mVoiceParams;
+        private Bundle mAudioParams;
+
+        Builder(VoiceInfo currentVoiceInfo, Bundle voiceParams, Bundle audioParams) {
+            mCurrentVoiceInfo = currentVoiceInfo;
+            mVoiceParams = voiceParams;
+            mAudioParams = audioParams;
+        }
+
+        /**
+         * Create new RequestConfig builder.
+         */
+        public static Builder newBuilder() {
+            return new Builder(null, new Bundle(), new Bundle());
+        }
+
+        /**
+         * Create new RequestConfig builder.
+         * @param prototype
+         *            Prototype of new RequestConfig. Copies all fields of the
+         *            prototype to the constructed object.
+         */
+        public static Builder newBuilder(RequestConfig prototype) {
+            return new Builder(prototype.mCurrentVoiceInfo,
+                    (Bundle)prototype.mVoiceParams.clone(),
+                    (Bundle)prototype.mAudioParams.clone());
+        }
+
+        /** Set voice for request. Will reset voice parameters to the defaults. */
+        public Builder setVoice(VoiceInfo voice) {
+            mCurrentVoiceInfo = voice;
+            mVoiceParams = (Bundle)voice.getParamsWithDefaults().clone();
+            return this;
+        }
+
+        /**
+         * Set request voice parameter.
+         *
+         * @param paramName
+         *            The name of the parameter. It has to be one of the keys
+         *            from {@link VoiceInfo#getParamsWithDefaults()}
+         * @param value
+         *            Value of the parameter. Its type can be one of: Integer, Float,
+         *            Boolean, String, VoiceInfo (will be set as a String, result of a call to
+         *            the {@link VoiceInfo#getName()}) or byte[]. It has to be of the same type
+         *            as the default value from {@link VoiceInfo#getParamsWithDefaults()}
+         *            for that parameter.
+         * @throws IllegalArgumentException
+         *            If paramName is not a valid parameter name or its value is of a wrong
+         *            type.
+         * @throws IllegalStateException
+         *            If no voice is set.
+         */
+        public Builder setVoiceParam(String paramName, Object value){
+            if (mCurrentVoiceInfo == null) {
+                throw new IllegalStateException(
+                        "Couldn't set voice parameter, no voice is set");
+            }
+            Object defaultValue = mCurrentVoiceInfo.getParamsWithDefaults().get(paramName);
+            if (defaultValue == null) {
+                throw new IllegalArgumentException(
+                        "Parameter \"" + paramName + "\" is not available in set voice with " +
+                                "name: " + mCurrentVoiceInfo.getName());
+            }
+
+            // If it's VoiceInfo, get its name
+            if (value instanceof VoiceInfo) {
+                value = ((VoiceInfo)value).getName();
+            }
+
+            // Check type information
+            if (!defaultValue.getClass().equals(value.getClass())) {
+                throw new IllegalArgumentException(
+                        "Parameter \"" + paramName +"\" is of different type. Value passed has " +
+                                "type " + value.getClass().getSimpleName() + " but should have " +
+                                "type " + defaultValue.getClass().getSimpleName());
+            }
+
+            setParam(mVoiceParams, paramName, value);
+            return this;
+        }
+
+        /**
+         * Set request audio parameter.
+         *
+         * Doesn't requires a set voice.
+         *
+         * @param paramName
+         *            Name of parameter.
+         * @param value
+         *            Value of parameter. Its type can be one of: Integer, Float, Boolean, String
+         *            or byte[].
+         */
+        public Builder setAudioParam(String paramName, Object value) {
+            setParam(mAudioParams, paramName, value);
+            return this;
+        }
+
+        /**
+         * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_STREAM} audio parameter.
+         *
+         * @param streamId One of the STREAM_ constants defined in {@link AudioManager}.
+         */
+        public void setAudioParamStream(int streamId) {
+            setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_STREAM, streamId);
+        }
+
+        /**
+         * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_VOLUME} audio parameter.
+         *
+         * @param volume Float in range of 0.0 to 1.0.
+         */
+        public void setAudioParamVolume(float volume) {
+            setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_VOLUME, volume);
+        }
+
+        /**
+         * Set the {@link TextToSpeechClient.Params#AUDIO_PARAM_PAN} audio parameter.
+         *
+         * @param pan Float in range of -1.0 to +1.0.
+         */
+        public void setAudioParamPan(float pan) {
+            setAudioParam(TextToSpeechClient.Params.AUDIO_PARAM_PAN, pan);
+        }
+
+        private void setParam(Bundle bundle, String featureName, Object value) {
+            if (value instanceof String) {
+                bundle.putString(featureName, (String)value);
+            } else if(value instanceof byte[]) {
+                bundle.putByteArray(featureName, (byte[])value);
+            } else if(value instanceof Integer) {
+                bundle.putInt(featureName, (Integer)value);
+            } else if(value instanceof Float) {
+                bundle.putFloat(featureName, (Float)value);
+            } else if(value instanceof Double) {
+                bundle.putFloat(featureName, (Float)value);
+            } else if(value instanceof Boolean) {
+                bundle.putBoolean(featureName, (Boolean)value);
+            } else {
+                throw new IllegalArgumentException("Illegal type of object");
+            }
+            return;
+        }
+
+        /**
+         * Build new RequestConfig instance.
+         */
+        public RequestConfig build() {
+            RequestConfig config =
+                    new RequestConfig(mCurrentVoiceInfo, mVoiceParams, mAudioParams);
+            return config;
+        }
+    }
+
+    private RequestConfig(VoiceInfo voiceInfo, Bundle voiceParams, Bundle audioParams) {
+        mCurrentVoiceInfo = voiceInfo;
+        mVoiceParams = voiceParams;
+        mAudioParams = audioParams;
+    }
+
+    /**
+     * Currently set voice.
+     */
+    private final VoiceInfo mCurrentVoiceInfo;
+
+    /**
+     * Voice parameters bundle.
+     */
+    private final Bundle mVoiceParams;
+
+    /**
+     * Audio parameters bundle.
+     */
+    private final Bundle mAudioParams;
+
+    /**
+     * @return Currently set request voice.
+     */
+    public VoiceInfo getVoice() {
+        return mCurrentVoiceInfo;
+    }
+
+    /**
+     * @return Request audio parameters.
+     */
+    public Bundle getAudioParams() {
+        return mAudioParams;
+    }
+
+    /**
+     * @return Request voice parameters.
+     */
+    public Bundle getVoiceParams() {
+        return mVoiceParams;
+    }
+
+}
diff --git a/core/java/android/speech/tts/RequestConfigHelper.java b/core/java/android/speech/tts/RequestConfigHelper.java
new file mode 100644
index 0000000..b25c985
--- /dev/null
+++ b/core/java/android/speech/tts/RequestConfigHelper.java
@@ -0,0 +1,170 @@
+package android.speech.tts;
+
+import android.speech.tts.TextToSpeechClient.EngineStatus;
+
+import java.util.Locale;
+
+/**
+ * Set of common heuristics for selecting {@link VoiceInfo} from
+ * {@link TextToSpeechClient#getEngineStatus()} output.
+ */
+public final class RequestConfigHelper {
+    private RequestConfigHelper() {}
+
+    /**
+     * Interface for scoring VoiceInfo object.
+     */
+    public static interface VoiceScorer {
+        /**
+         * Score VoiceInfo. If the score is less than or equal to zero, that voice is discarded.
+         * If two voices have same desired primary characteristics (highest quality, lowest
+         * latency or others), the one with the higher score is selected.
+         */
+        public int scoreVoice(VoiceInfo voiceInfo);
+    }
+
+    /**
+     * Score positively voices that exactly match the locale supplied to the constructor.
+     */
+    public static final class ExactLocaleMatcher implements VoiceScorer {
+        private final Locale mLocale;
+
+        /**
+         * Score positively voices that exactly match the given locale
+         * @param locale Reference locale. If null, the default locale will be used.
+         */
+        public ExactLocaleMatcher(Locale locale) {
+            if (locale == null) {
+                mLocale = Locale.getDefault();
+            } else {
+                mLocale = locale;
+            }
+        }
+        @Override
+        public int scoreVoice(VoiceInfo voiceInfo) {
+            return mLocale.equals(voiceInfo.getLocale()) ? 1 : 0;
+        }
+    }
+
+    /**
+     * Score positively voices that match exactly the given locale (score 3)
+     * or that share same language and country (score 2), or that share just a language (score 1).
+     */
+    public static final class LanguageMatcher implements VoiceScorer {
+        private final Locale mLocale;
+
+        /**
+         * Score positively voices with similar locale.
+         * @param locale Reference locale. If null, default will be used.
+         */
+        public LanguageMatcher(Locale locale) {
+            if (locale == null) {
+                mLocale = Locale.getDefault();
+            } else {
+                mLocale = locale;
+            }
+        }
+
+        @Override
+        public int scoreVoice(VoiceInfo voiceInfo) {
+            final Locale voiceLocale = voiceInfo.getLocale();
+            if (mLocale.equals(voiceLocale)) {
+                return 3;
+            } else {
+                if (mLocale.getLanguage().equals(voiceLocale.getLanguage())) {
+                    if (mLocale.getCountry().equals(voiceLocale.getCountry())) {
+                        return 2;
+                    }
+                    return 1;
+                }
+                return 0;
+            }
+        }
+    }
+
+    /**
+     * Get the highest quality voice from voices that score more than zero from the passed scorer.
+     * If there is more than one voice with the same highest quality, then this method returns one
+     * with the highest score. If they share same score as well, one with the lower index in the
+     * voices list is returned.
+     *
+     * @param engineStatus
+     *            Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+     * @param voiceScorer
+     *            Used to discard unsuitable voices and help settle cases where more than
+     *            one voice has the desired characteristic.
+     * @param hasToBeEmbedded
+     *            If true, require the voice to be an embedded voice (no network
+     *            access will be required for synthesis).
+     */
+    private static VoiceInfo getHighestQualityVoice(EngineStatus engineStatus,
+            VoiceScorer voiceScorer, boolean hasToBeEmbedded) {
+        VoiceInfo bestVoice = null;
+        int bestScoreMatch = 1;
+        int bestVoiceQuality = 0;
+
+        for (VoiceInfo voice : engineStatus.getVoices()) {
+            int score = voiceScorer.scoreVoice(voice);
+            if (score <= 0 || hasToBeEmbedded && voice.getRequiresNetworkConnection()
+                    || voice.getQuality() < bestVoiceQuality) {
+                continue;
+            }
+
+            if (bestVoice == null ||
+                    voice.getQuality() > bestVoiceQuality ||
+                    score > bestScoreMatch) {
+                bestVoice = voice;
+                bestScoreMatch = score;
+                bestVoiceQuality = voice.getQuality();
+            }
+        }
+        return bestVoice;
+    }
+
+    /**
+     * Get highest quality voice.
+     *
+     * Highest quality voice is selected from voices that score more than zero from the passed
+     * scorer. If there is more than one voice with the same highest quality, then this method
+     * will return one with the highest score. If they share same score as well, one with the lower
+     * index in the voices list is returned.
+
+     * @param engineStatus
+     *            Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+     * @param hasToBeEmbedded
+     *            If true, require the voice to be an embedded voice (no network
+     *            access will be required for synthesis).
+     * @param voiceScorer
+     *            Scorer is used to discard unsuitable voices and help settle cases where more than
+     *            one voice has highest quality.
+     * @return RequestConfig with selected voice or null if suitable voice was not found.
+     */
+    public static RequestConfig highestQuality(EngineStatus engineStatus,
+            boolean hasToBeEmbedded, VoiceScorer voiceScorer) {
+        VoiceInfo voice = getHighestQualityVoice(engineStatus, voiceScorer, hasToBeEmbedded);
+        if (voice == null) {
+            return null;
+        }
+        return RequestConfig.Builder.newBuilder().setVoice(voice).build();
+    }
+
+    /**
+     * Get highest quality voice for the default locale.
+     *
+     * Call {@link #highestQuality(EngineStatus, boolean, VoiceScorer)} with
+     * {@link LanguageMatcher} set to device default locale.
+     *
+     * @param engineStatus
+     *            Voices status received from a {@link TextToSpeechClient#getEngineStatus()} call.
+     * @param hasToBeEmbedded
+     *            If true, require the voice to be an embedded voice (no network
+     *            access will be required for synthesis).
+     * @return RequestConfig with selected voice or null if suitable voice was not found.
+     */
+    public static RequestConfig highestQuality(EngineStatus engineStatus,
+            boolean hasToBeEmbedded) {
+        return highestQuality(engineStatus, hasToBeEmbedded,
+                new LanguageMatcher(Locale.getDefault()));
+    }
+
+}
diff --git a/core/java/android/speech/tts/SilencePlaybackQueueItem.java b/core/java/android/speech/tts/SilencePlaybackQueueItem.java
index a5e47ae..88b7c70 100644
--- a/core/java/android/speech/tts/SilencePlaybackQueueItem.java
+++ b/core/java/android/speech/tts/SilencePlaybackQueueItem.java
@@ -17,7 +17,6 @@
 
 import android.os.ConditionVariable;
 import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
-import android.util.Log;
 
 class SilencePlaybackQueueItem extends PlaybackQueueItem {
     private final ConditionVariable mCondVar = new ConditionVariable();
@@ -32,14 +31,20 @@
     @Override
     public void run() {
         getDispatcher().dispatchOnStart();
+        boolean wasStopped = false;
         if (mSilenceDurationMs > 0) {
-            mCondVar.block(mSilenceDurationMs);
+          wasStopped = mCondVar.block(mSilenceDurationMs);
         }
-        getDispatcher().dispatchOnDone();
+        if (wasStopped) {
+            getDispatcher().dispatchOnStop();
+        } else {
+            getDispatcher().dispatchOnSuccess();
+        }
+
     }
 
     @Override
-    void stop(boolean isError) {
+    void stop(int errorCode) {
         mCondVar.open();
     }
 }
diff --git a/core/java/android/speech/tts/SynthesisCallback.java b/core/java/android/speech/tts/SynthesisCallback.java
index f98bb09..bc2f239 100644
--- a/core/java/android/speech/tts/SynthesisCallback.java
+++ b/core/java/android/speech/tts/SynthesisCallback.java
@@ -26,7 +26,9 @@
  * indicate that an error has occurred, but if the call is made after a call
  * to {@link #done}, it might be discarded.
  *
- * After {@link #start} been called, {@link #done} must be called regardless of errors.
+ * {@link #done} must be called at the end of synthesis, regardless of errors.
+ *
+ * All methods can be only called on the synthesis thread.
  */
 public interface SynthesisCallback {
     /**
@@ -41,13 +43,16 @@
      * request.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText}.
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
      * @param sampleRateInHz Sample rate in HZ of the generated audio.
      * @param audioFormat Audio format of the generated audio. Must be one of
      *         the ENCODING_ constants defined in {@link android.media.AudioFormat}.
      * @param channelCount The number of channels. Must be {@code 1} or {@code 2}.
-     * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
+     * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR}.
+     *          {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
+     *          {@link TextToSpeechService#onSynthesizeTextV2}.
      */
     public int start(int sampleRateInHz, int audioFormat, int channelCount);
 
@@ -55,7 +60,8 @@
      * The service should call this method when synthesized audio is ready for consumption.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText}.
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
      * @param buffer The generated audio data. This method will not hold on to {@code buffer},
      *         so the caller is free to modify it after this method returns.
@@ -63,6 +69,8 @@
      * @param length The number of bytes of audio data in {@code buffer}. This must be
      *         less than or equal to the return value of {@link #getMaxBufferSize}.
      * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
+     *          {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
+     *          {@link TextToSpeechService#onSynthesizeTextV2}.
      */
     public int audioAvailable(byte[] buffer, int offset, int length);
 
@@ -71,11 +79,14 @@
      * been passed to {@link #audioAvailable}.
      *
      * This method should only be called on the synthesis thread,
-     * while in {@link TextToSpeechService#onSynthesizeText}.
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
      *
-     * This method has to be called if {@link #start} was called.
+     * This method has to be called if {@link #start} and/or {@link #error} was called.
      *
      * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
+     *          {@link TextToSpeechClient.Status#STOPPED} is also possible if called in context of
+     *          {@link TextToSpeechService#onSynthesizeTextV2}.
      */
     public int done();
 
@@ -87,4 +98,58 @@
      */
     public void error();
 
-}
\ No newline at end of file
+
+    /**
+     * The service should call this method if the speech synthesis fails.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * @param errorCode Error code to pass to the client. One of the ERROR_ values from
+     *      {@link TextToSpeechClient.Status}
+     */
+    public void error(int errorCode);
+
+    /**
+     * Communicate to client that the original request can't be done and client-requested
+     * fallback is happening.
+     *
+     * Fallback can be requested by the client by setting
+     * {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter with a id of
+     * the voice that is expected to be used for the fallback.
+     *
+     * This method will fail if user called {@link #start(int, int, int)} and/or
+     * {@link #done()}.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * @return {@link TextToSpeech#SUCCESS}, {@link TextToSpeech#ERROR} if client already
+     *          called {@link #start(int, int, int)}, {@link TextToSpeechClient.Status#STOPPED}
+     *          if stop was requested.
+     */
+    public int fallback();
+
+    /**
+     * Check if {@link #start} was called or not.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * Useful for checking if a fallback from network request is possible.
+     */
+    public boolean hasStarted();
+
+    /**
+     * Check if {@link #done} was called or not.
+     *
+     * This method should only be called on the synthesis thread,
+     * while in {@link TextToSpeechService#onSynthesizeText} or
+     * {@link TextToSpeechService#onSynthesizeTextV2}.
+     *
+     * Useful for checking if a fallback from network request is possible.
+     */
+    public boolean hasFinished();
+}
diff --git a/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
index e853c9e..b424356 100644
--- a/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/SynthesisPlaybackQueueItem.java
@@ -57,23 +57,22 @@
      */
     private volatile boolean mStopped;
     private volatile boolean mDone;
-    private volatile boolean mIsError;
+    private volatile int mStatusCode;
 
     private final BlockingAudioTrack mAudioTrack;
-    private final EventLogger mLogger;
-
+    private final AbstractEventLogger mLogger;
 
     SynthesisPlaybackQueueItem(int streamType, int sampleRate,
             int audioFormat, int channelCount,
             float volume, float pan, UtteranceProgressDispatcher dispatcher,
-            Object callerIdentity, EventLogger logger) {
+            Object callerIdentity, AbstractEventLogger logger) {
         super(dispatcher, callerIdentity);
 
         mUnconsumedBytes = 0;
 
         mStopped = false;
         mDone = false;
-        mIsError = false;
+        mStatusCode = TextToSpeechClient.Status.SUCCESS;
 
         mAudioTrack = new BlockingAudioTrack(streamType, sampleRate, audioFormat,
                 channelCount, volume, pan);
@@ -86,9 +85,8 @@
         final UtteranceProgressDispatcher dispatcher = getDispatcher();
         dispatcher.dispatchOnStart();
 
-
         if (!mAudioTrack.init()) {
-            dispatcher.dispatchOnError();
+            dispatcher.dispatchOnError(TextToSpeechClient.Status.ERROR_OUTPUT);
             return;
         }
 
@@ -112,23 +110,25 @@
 
         mAudioTrack.waitAndRelease();
 
-        if (mIsError) {
-            dispatcher.dispatchOnError();
+        if (mStatusCode == TextToSpeechClient.Status.SUCCESS) {
+            dispatcher.dispatchOnSuccess();
+        } else if(mStatusCode == TextToSpeechClient.Status.STOPPED) {
+            dispatcher.dispatchOnStop();
         } else {
-            dispatcher.dispatchOnDone();
+            dispatcher.dispatchOnError(mStatusCode);
         }
 
-        mLogger.onWriteData();
+        mLogger.onCompleted(mStatusCode);
     }
 
     @Override
-    void stop(boolean isError) {
+    void stop(int statusCode) {
         try {
             mListLock.lock();
 
             // Update our internal state.
             mStopped = true;
-            mIsError = isError;
+            mStatusCode = statusCode;
 
             // Wake up the audio playback thread if it was waiting on take().
             // take() will return null since mStopped was true, and will then
diff --git a/core/java/android/speech/tts/SynthesisRequestV2.aidl b/core/java/android/speech/tts/SynthesisRequestV2.aidl
new file mode 100644
index 0000000..2ac7da6
--- /dev/null
+++ b/core/java/android/speech/tts/SynthesisRequestV2.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** 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.speech.tts;
+
+parcelable SynthesisRequestV2;
\ No newline at end of file
diff --git a/core/java/android/speech/tts/SynthesisRequestV2.java b/core/java/android/speech/tts/SynthesisRequestV2.java
new file mode 100644
index 0000000..a1da49c
--- /dev/null
+++ b/core/java/android/speech/tts/SynthesisRequestV2.java
@@ -0,0 +1,144 @@
+package android.speech.tts;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.speech.tts.TextToSpeechClient.UtteranceId;
+
+/**
+ * Service-side representation of a synthesis request from a V2 API client. Contains:
+ * <ul>
+ *   <li>The utterance to synthesize</li>
+ *   <li>The id of the utterance (String, result of {@link UtteranceId#toUniqueString()}</li>
+ *   <li>The synthesis voice name (String, result of {@link VoiceInfo#getName()})</li>
+ *   <li>Voice parameters (Bundle of parameters)</li>
+ *   <li>Audio parameters (Bundle of parameters)</li>
+ * </ul>
+ */
+public final class SynthesisRequestV2 implements Parcelable {
+    /** Synthesis utterance. */
+    private final String mText;
+
+    /** Synthesis id. */
+    private final String mUtteranceId;
+
+    /** Voice ID. */
+    private final String mVoiceName;
+
+    /** Voice Parameters. */
+    private final Bundle mVoiceParams;
+
+    /** Audio Parameters. */
+    private final Bundle mAudioParams;
+
+    /**
+     * Constructor for test purposes.
+     */
+    public SynthesisRequestV2(String text, String utteranceId, String voiceName,
+            Bundle voiceParams, Bundle audioParams) {
+        this.mText = text;
+        this.mUtteranceId = utteranceId;
+        this.mVoiceName = voiceName;
+        this.mVoiceParams = voiceParams;
+        this.mAudioParams = audioParams;
+    }
+
+    /**
+     * Parcel based constructor.
+     *
+     * @hide
+     */
+    public SynthesisRequestV2(Parcel in) {
+        this.mText = in.readString();
+        this.mUtteranceId = in.readString();
+        this.mVoiceName = in.readString();
+        this.mVoiceParams = in.readBundle();
+        this.mAudioParams = in.readBundle();
+    }
+
+    SynthesisRequestV2(String text, String utteranceId, RequestConfig rconfig) {
+        this.mText = text;
+        this.mUtteranceId = utteranceId;
+        this.mVoiceName = rconfig.getVoice().getName();
+        this.mVoiceParams = rconfig.getVoiceParams();
+        this.mAudioParams = rconfig.getAudioParams();
+    }
+
+    /**
+     * Write to parcel.
+     *
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mText);
+        dest.writeString(mUtteranceId);
+        dest.writeString(mVoiceName);
+        dest.writeBundle(mVoiceParams);
+        dest.writeBundle(mAudioParams);
+    }
+
+    /**
+     * @return the text which should be synthesized.
+     */
+    public String getText() {
+        return mText;
+    }
+
+    /**
+     * @return the id of the synthesis request. It's an output of a call to the
+     * {@link UtteranceId#toUniqueString()} method of the {@link UtteranceId} associated with
+     * this request.
+     */
+    public String getUtteranceId() {
+        return mUtteranceId;
+    }
+
+    /**
+     * @return the name of the voice to use for this synthesis request. Result of a call to
+     * the {@link VoiceInfo#getName()} method.
+     */
+    public String getVoiceName() {
+        return mVoiceName;
+    }
+
+    /**
+     * @return bundle of voice parameters.
+     */
+    public Bundle getVoiceParams() {
+        return mVoiceParams;
+    }
+
+    /**
+     * @return bundle of audio parameters.
+     */
+    public Bundle getAudioParams() {
+        return mAudioParams;
+    }
+
+    /**
+     * Parcel creators.
+     *
+     * @hide
+     */
+    public static final Parcelable.Creator<SynthesisRequestV2> CREATOR =
+            new Parcelable.Creator<SynthesisRequestV2>() {
+        @Override
+        public SynthesisRequestV2 createFromParcel(Parcel source) {
+            return new SynthesisRequestV2(source);
+        }
+
+        @Override
+        public SynthesisRequestV2[] newArray(int size) {
+            return new SynthesisRequestV2[size];
+        }
+    };
+
+    /**
+     * @hide
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 2752085..327c59a 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -54,7 +54,9 @@
  * When you are done using the TextToSpeech instance, call the {@link #shutdown()} method
  * to release the native resources used by the TextToSpeech engine.
  *
+ * @deprecated Use {@link TextToSpeechClient} instead
  */
+@Deprecated
 public class TextToSpeech {
 
     private static final String TAG = "TextToSpeech";
@@ -970,7 +972,7 @@
             @Override
             public Integer run(ITextToSpeechService service) throws RemoteException {
                 return service.playSilence(getCallerIdentity(), durationInMs, queueMode,
-                        getParams(params));
+                        params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
             }
         }, ERROR, "playSilence");
     }
@@ -1443,8 +1445,17 @@
         private boolean mEstablished;
 
         private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
+            public void onStop(String utteranceId) throws RemoteException {
+                // do nothing
+            };
+
             @Override
-            public void onDone(String utteranceId) {
+            public void onFallback(String utteranceId) throws RemoteException {
+                // do nothing
+            }
+
+            @Override
+            public void onSuccess(String utteranceId) {
                 UtteranceProgressListener listener = mUtteranceProgressListener;
                 if (listener != null) {
                     listener.onDone(utteranceId);
@@ -1452,7 +1463,7 @@
             }
 
             @Override
-            public void onError(String utteranceId) {
+            public void onError(String utteranceId, int errorCode) {
                 UtteranceProgressListener listener = mUtteranceProgressListener;
                 if (listener != null) {
                     listener.onError(utteranceId);
@@ -1466,6 +1477,11 @@
                     listener.onStart(utteranceId);
                 }
             }
+
+            @Override
+            public void onVoicesInfoChange(List<VoiceInfo> voicesInfo) throws RemoteException {
+                // Ignore it
+            }
         };
 
         private class SetupConnectionAsyncTask extends AsyncTask<Void, Void, Integer> {
@@ -1484,11 +1500,13 @@
 
                     try {
                         mService.setCallback(getCallerIdentity(), mCallback);
-                        String[] defaultLanguage = mService.getClientDefaultLanguage();
 
-                        mParams.putString(Engine.KEY_PARAM_LANGUAGE, defaultLanguage[0]);
-                        mParams.putString(Engine.KEY_PARAM_COUNTRY, defaultLanguage[1]);
-                        mParams.putString(Engine.KEY_PARAM_VARIANT, defaultLanguage[2]);
+                        if (mParams.getString(Engine.KEY_PARAM_LANGUAGE) == null) {
+                            String[] defaultLanguage = mService.getClientDefaultLanguage();
+                            mParams.putString(Engine.KEY_PARAM_LANGUAGE, defaultLanguage[0]);
+                            mParams.putString(Engine.KEY_PARAM_COUNTRY, defaultLanguage[1]);
+                            mParams.putString(Engine.KEY_PARAM_VARIANT, defaultLanguage[2]);
+                        }
 
                         Log.i(TAG, "Set up connection to " + mName);
                         return SUCCESS;
diff --git a/core/java/android/speech/tts/TextToSpeechClient.java b/core/java/android/speech/tts/TextToSpeechClient.java
new file mode 100644
index 0000000..c6a14f2
--- /dev/null
+++ b/core/java/android/speech/tts/TextToSpeechClient.java
@@ -0,0 +1,1047 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.speech.tts;
+
+import android.app.Activity;
+import android.app.Application;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.speech.tts.ITextToSpeechCallback;
+import android.speech.tts.ITextToSpeechService;
+import android.util.Log;
+import android.util.Pair;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Synthesizes speech from text for immediate playback or to create a sound
+ * file.
+ * <p>
+ * This is an updated version of the speech synthesis client that supersedes
+ * {@link android.speech.tts.TextToSpeech}.
+ * <p>
+ * A TextToSpeechClient instance can only be used to synthesize text once it has
+ * connected to the service. The TextToSpeechClient instance will start establishing
+ * the connection after a call to the {@link #connect()} method. This is usually done in
+ * {@link Application#onCreate()} or {@link Activity#onCreate}. When the connection
+ * is established, the instance will call back using the
+ * {@link TextToSpeechClient.ConnectionCallbacks} interface. Only after a
+ * successful callback is the client usable.
+ * <p>
+ * After successful connection, the list of all available voices can be obtained
+ * by calling the {@link TextToSpeechClient#getEngineStatus() method. The client can
+ * choose a voice using some custom heuristic and build a {@link RequestConfig} object
+ * using {@link RequestConfig.Builder}, or can use one of the common heuristics found
+ * in ({@link RequestConfigHelper}.
+ * <p>
+ * When you are done using the TextToSpeechClient instance, call the
+ * {@link #disconnect()} method to release the connection.
+ * <p>
+ * In the rare case of a change to the set of available voices, the service will call to the
+ * {@link ConnectionCallbacks#onEngineStatusChange} with new set of available voices as argument.
+ * In response, the client HAVE to recreate all {@link RequestConfig} instances in use.
+ */
+public final class TextToSpeechClient {
+    private static final String TAG = TextToSpeechClient.class.getSimpleName();
+
+    private final Object mLock = new Object();
+    private final TtsEngines mEnginesHelper;
+    private final Context mContext;
+
+    // Guarded by mLock
+    private Connection mServiceConnection;
+    private final RequestCallbacks mDefaultRequestCallbacks;
+    private final ConnectionCallbacks mConnectionCallbacks;
+    private EngineStatus mEngineStatus;
+    private String mRequestedEngine;
+    private boolean mFallbackToDefault;
+    private HashMap<String, Pair<UtteranceId, RequestCallbacks>> mCallbacks;
+    // Guarded by mLock
+
+    /** Common voices parameters */
+    public static final class Params {
+        private Params() {}
+
+        /**
+         * Maximum allowed time for a single request attempt, in milliseconds, before synthesis
+         * fails (or fallback request starts, if requested using
+         * {@link #FALLBACK_VOICE_NAME}).
+         */
+        public static final String NETWORK_TIMEOUT_MS = "networkTimeoutMs";
+
+        /**
+         * Number of network request retries that are attempted in case of failure
+         */
+        public static final String NETWORK_RETRIES_COUNT = "networkRetriesCount";
+
+        /**
+         * Should synthesizer report sub-utterance progress on synthesis. Only applicable
+         * for the {@link TextToSpeechClient#queueSpeak} method.
+         */
+        public static final String TRACK_SUBUTTERANCE_PROGRESS = "trackSubutteranceProgress";
+
+        /**
+         * If a voice exposes this parameter then it supports the fallback request feature.
+         *
+         * If it is set to a valid name of some other voice ({@link VoiceInfo#getName()}) then
+         * in case of request failure (due to network problems or missing data), fallback request
+         * will be attempted. Request will be done using the voice referenced by this parameter.
+         * If it is the case, the client will be informed by a callback to the {@link
+         * RequestCallbacks#onSynthesisFallback(UtteranceId)}.
+         */
+        public static final String FALLBACK_VOICE_NAME = "fallbackVoiceName";
+
+        /**
+         * Audio parameter for specifying a linear multiplier to the speaking speed of the voice.
+         * The value is a float. Values below zero decrease speed of the synthesized speech
+         * values above one increase it. If the value of this parameter is equal to zero,
+         * then it will be replaced by a settings-configurable default before it reaches
+         * TTS service.
+         */
+        public static final String SPEECH_SPEED = "speechSpeed";
+
+        /**
+         * Audio parameter for controlling the pitch of the output. The Value is a positive float,
+         * with default of {@code 1.0}. The value is used to scale the primary frequency linearly.
+         * Lower values lower the tone of the synthesized voice, greater values increase it.
+         */
+        public static final String SPEECH_PITCH = "speechPitch";
+
+        /**
+         * Audio parameter for controlling output volume. Value is a float with scale of 0 to 1
+         */
+        public static final String AUDIO_PARAM_VOLUME = TextToSpeech.Engine.KEY_PARAM_VOLUME;
+
+        /**
+         * Audio parameter for controlling output pan.
+         * Value is a float ranging from -1 to +1 where -1 maps to a hard-left pan,
+         * 0 to center (the default behavior), and +1 to hard-right.
+         */
+        public static final String AUDIO_PARAM_PAN = TextToSpeech.Engine.KEY_PARAM_PAN;
+
+        /**
+         * Audio parameter for specifying the audio stream type to be used when speaking text
+         * or playing back a file. The value should be one of the STREAM_ constants
+         * defined in {@link AudioManager}.
+         */
+        public static final String AUDIO_PARAM_STREAM = TextToSpeech.Engine.KEY_PARAM_STREAM;
+    }
+
+    /**
+     * Result codes for TTS operations.
+     */
+    public static final class Status {
+        private Status() {}
+
+        /**
+         * Denotes a successful operation.
+         */
+        public static final int SUCCESS = 0;
+
+        /**
+         * Denotes a stop requested by a client. It's used only on the service side of the API,
+         * client should never expect to see this result code.
+         */
+        public static final int STOPPED = 100;
+
+        /**
+         * Denotes a generic failure.
+         */
+        public static final int ERROR_UNKNOWN = -1;
+
+        /**
+         * Denotes a failure of a TTS engine to synthesize the given input.
+         */
+        public static final int ERROR_SYNTHESIS = 10;
+
+        /**
+         * Denotes a failure of a TTS service.
+         */
+        public static final int ERROR_SERVICE = 11;
+
+        /**
+         * Denotes a failure related to the output (audio device or a file).
+         */
+        public static final int ERROR_OUTPUT = 12;
+
+        /**
+         * Denotes a failure caused by a network connectivity problems.
+         */
+        public static final int ERROR_NETWORK = 13;
+
+        /**
+         * Denotes a failure caused by network timeout.
+         */
+        public static final int ERROR_NETWORK_TIMEOUT = 14;
+
+        /**
+         * Denotes a failure caused by an invalid request.
+         */
+        public static final int ERROR_INVALID_REQUEST = 15;
+
+        /**
+         * Denotes a failure related to passing a non-unique utterance id.
+         */
+        public static final int ERROR_NON_UNIQUE_UTTERANCE_ID = 16;
+
+        /**
+         * Denotes a failure related to missing data. The TTS implementation may download
+         * the missing data, and if so, request will succeed in future. This error can only happen
+         * for voices with {@link VoiceInfo#FEATURE_MAY_AUTOINSTALL} feature.
+         * Note: the recommended way to avoid this error is to create a request with the fallback
+         * voice.
+         */
+        public static final int ERROR_DOWNLOADING_ADDITIONAL_DATA = 17;
+    }
+
+    /**
+     * Set of callbacks for the events related to the progress of a synthesis request
+     * through the synthesis queue. Each synthesis request is associated with a call to
+     * {@link #queueSpeak} or {@link #queueSynthesizeToFile}.
+     *
+     * The callbacks specified in this method will NOT be called on UI thread.
+     */
+    public static abstract class RequestCallbacks  {
+        /**
+         * Called after synthesis of utterance successfully starts.
+         */
+        public void onSynthesisStart(UtteranceId utteranceId) {}
+
+        /**
+         * Called after synthesis successfully finishes.
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         */
+        public void onSynthesisSuccess(UtteranceId utteranceId) {}
+
+        /**
+         * Called after synthesis was stopped in middle of synthesis process.
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         */
+        public void onSynthesisStop(UtteranceId utteranceId) {}
+
+        /**
+         * Called when requested synthesis failed and fallback synthesis is about to be attempted.
+         *
+         * Requires voice with available {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}
+         * parameter, and request with this parameter enabled.
+         *
+         * This callback will be followed by callback to the {@link #onSynthesisStart},
+         * {@link #onSynthesisFailure} or {@link #onSynthesisSuccess} that depends on the
+         * fallback outcome.
+         *
+         * For more fallback feature reference, look at the
+         * {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME}.
+         *
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         */
+        public void onSynthesisFallback(UtteranceId utteranceId) {}
+
+        /**
+         * Called after synthesis of utterance fails.
+         *
+         * It may be called instead or after a {@link #onSynthesisStart} callback.
+         *
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         * @param errorCode
+         *            One of the values from {@link Status}.
+         */
+        public void onSynthesisFailure(UtteranceId utteranceId, int errorCode) {}
+
+        /**
+         * Called during synthesis to mark synthesis progress.
+         *
+         * Requires voice with available
+         * {@link TextToSpeechClient.Params#TRACK_SUBUTTERANCE_PROGRESS} parameter, and
+         * request with this parameter enabled.
+         *
+         * @param utteranceId
+         *            Unique identifier of synthesized utterance.
+         * @param charIndex
+         *            String index (java char offset) of recently synthesized character.
+         * @param msFromStart
+         *            Miliseconds from the start of the synthesis.
+         */
+        public void onSynthesisProgress(UtteranceId utteranceId, int charIndex,
+                int msFromStart) {}
+    }
+
+    /**
+     * Interface definition of callbacks that are called when the client is
+     * connected or disconnected from the TTS service.
+     */
+    public static interface ConnectionCallbacks {
+        /**
+         * After calling {@link TextToSpeechClient#connect()}, this method will be invoked
+         * asynchronously when the connect request has successfully completed.
+         *
+         * Clients are strongly encouraged to call {@link TextToSpeechClient#getEngineStatus()}
+         * and create {@link RequestConfig} objects used in subsequent synthesis requests.
+         */
+        public void onConnectionSuccess();
+
+        /**
+         * After calling {@link TextToSpeechClient#connect()}, this method may be invoked
+         * asynchronously when the connect request has failed to complete.
+         *
+         * It may be also invoked synchronously, from the body of
+         * {@link TextToSpeechClient#connect()} method.
+         */
+        public void onConnectionFailure();
+
+        /**
+         * Called when the connection to the service is lost. This can happen if there is a problem
+         * with the speech service (e.g. a crash or resource problem causes it to be killed by the
+         * system). When called, all requests have been canceled and no outstanding listeners will
+         * be executed. Applications should disable UI components that require the service.
+         */
+        public void onServiceDisconnected();
+
+        /**
+         * After receiving {@link #onConnectionSuccess()} callback, this method may be invoked
+         * if engine status obtained from {@link TextToSpeechClient#getEngineStatus()}) changes.
+         * It usually means that some voices were removed, changed or added.
+         *
+         * Clients are required to recreate {@link RequestConfig} objects used in subsequent
+         * synthesis requests.
+         */
+        public void onEngineStatusChange(EngineStatus newEngineStatus);
+    }
+
+    /** State of voices as provided by engine and user. */
+    public static final class EngineStatus {
+        /** All available voices. */
+        private final List<VoiceInfo> mVoices;
+
+        /** Name of the TTS engine package */
+        private final String mPackageName;
+
+        private EngineStatus(String packageName, List<VoiceInfo> voices) {
+            this.mVoices =  Collections.unmodifiableList(voices);
+            this.mPackageName = packageName;
+        }
+
+        /**
+         * Get an immutable list of all Voices exposed by the TTS engine.
+         */
+        public List<VoiceInfo> getVoices() {
+            return mVoices;
+        }
+
+        /**
+         * Get name of the TTS engine package currently in use.
+         */
+        public String getEnginePackage() {
+            return mPackageName;
+        }
+    }
+
+    /** Unique synthesis request identifier. */
+    public static class UtteranceId {
+        /** Unique identifier */
+        private final int id;
+
+        /** Unique identifier generator */
+        private static final AtomicInteger ID_GENERATOR = new AtomicInteger();
+
+        /**
+         * Create new, unique UtteranceId instance.
+         */
+        public UtteranceId() {
+            id = ID_GENERATOR.getAndIncrement();
+        }
+
+        /**
+         * Returns a unique string associated with an instance of this object.
+         *
+         * This string will be used to identify the synthesis request/utterance inside the
+         * TTS service.
+         */
+        public final String toUniqueString() {
+            return "UID" + id;
+        }
+    }
+
+    /**
+     * Create TextToSpeech service client.
+     *
+     * Will connect to the default TTS service. In order to be usable, {@link #connect()} need
+     * to be called first and successful connection callback need to be received.
+     *
+     * @param context
+     *            The context this instance is running in.
+     * @param engine
+     *            Package name of requested TTS engine. If it's null, then default engine will
+     *            be selected regardless of {@code fallbackToDefaultEngine} parameter value.
+     * @param fallbackToDefaultEngine
+     *            If requested engine is not available, should we fallback to the default engine?
+     * @param defaultRequestCallbacks
+     *            Default request callbacks, it will be used for all synthesis requests without
+     *            supplied RequestCallbacks instance. Can't be null.
+     * @param connectionCallbacks
+     *            Callbacks for connecting and disconnecting from the service. Can't be null.
+     */
+    public TextToSpeechClient(Context context,
+            String engine, boolean fallbackToDefaultEngine,
+            RequestCallbacks defaultRequestCallbacks,
+            ConnectionCallbacks connectionCallbacks) {
+        if (context == null)
+            throw new IllegalArgumentException("context can't be null");
+        if (defaultRequestCallbacks == null)
+            throw new IllegalArgumentException("defaultRequestCallbacks can't be null");
+        if (connectionCallbacks == null)
+            throw new IllegalArgumentException("connectionCallbacks can't be null");
+        mContext = context;
+        mEnginesHelper = new TtsEngines(mContext);
+        mCallbacks = new HashMap<String, Pair<UtteranceId, RequestCallbacks>>();
+        mDefaultRequestCallbacks = defaultRequestCallbacks;
+        mConnectionCallbacks = connectionCallbacks;
+
+        mRequestedEngine = engine;
+        mFallbackToDefault = fallbackToDefaultEngine;
+    }
+
+    /**
+     * Create TextToSpeech service client. Will connect to the default TTS
+     * service. In order to be usable, {@link #connect()} need to be called
+     * first and successful connection callback need to be received.
+     *
+     * @param context Context this instance is running in.
+     * @param defaultRequestCallbacks Default request callbacks, it
+     *            will be used for all synthesis requests without supplied
+     *            RequestCallbacks instance. Can't be null.
+     * @param connectionCallbacks Callbacks for connecting and disconnecting
+     *            from the service. Can't be null.
+     */
+    public TextToSpeechClient(Context context, RequestCallbacks defaultRequestCallbacks,
+            ConnectionCallbacks connectionCallbacks) {
+        this(context, null, true, defaultRequestCallbacks, connectionCallbacks);
+    }
+
+
+    private boolean initTts(String requestedEngine, boolean fallbackToDefaultEngine) {
+        // Step 1: Try connecting to the engine that was requested.
+        if (requestedEngine != null) {
+            if (mEnginesHelper.isEngineInstalled(requestedEngine)) {
+                if ((mServiceConnection = connectToEngine(requestedEngine)) != null) {
+                    return true;
+                } else if (!fallbackToDefaultEngine) {
+                    Log.w(TAG, "Couldn't connect to requested engine: " + requestedEngine);
+                    return false;
+                }
+            } else if (!fallbackToDefaultEngine) {
+                Log.w(TAG, "Requested engine not installed: " + requestedEngine);
+                return false;
+            }
+        }
+
+        // Step 2: Try connecting to the user's default engine.
+        final String defaultEngine = mEnginesHelper.getDefaultEngine();
+        if (defaultEngine != null && !defaultEngine.equals(requestedEngine)) {
+            if ((mServiceConnection = connectToEngine(defaultEngine)) != null) {
+                return true;
+            }
+        }
+
+        // Step 3: Try connecting to the highest ranked engine in the
+        // system.
+        final String highestRanked = mEnginesHelper.getHighestRankedEngineName();
+        if (highestRanked != null && !highestRanked.equals(requestedEngine) &&
+                !highestRanked.equals(defaultEngine)) {
+            if ((mServiceConnection = connectToEngine(highestRanked)) != null) {
+                return true;
+            }
+        }
+
+        Log.w(TAG, "Couldn't find working TTS engine");
+        return false;
+    }
+
+    private Connection connectToEngine(String engine) {
+        Connection connection = new Connection(engine);
+        Intent intent = new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE);
+        intent.setPackage(engine);
+        boolean bound = mContext.bindService(intent, connection, Context.BIND_AUTO_CREATE);
+        if (!bound) {
+            Log.e(TAG, "Failed to bind to " + engine);
+            return null;
+        } else {
+            Log.i(TAG, "Successfully bound to " + engine);
+            return connection;
+        }
+    }
+
+
+    /**
+     * Connects the client to TTS service. This method returns immediately, and connects to the
+     * service in the background.
+     *
+     * After connection initializes successfully, {@link ConnectionCallbacks#onConnectionSuccess()}
+     * is called. On a failure {@link ConnectionCallbacks#onConnectionFailure} is called.
+     *
+     * Both of those callback may be called asynchronously on the main thread,
+     * {@link ConnectionCallbacks#onConnectionFailure} may be called synchronously, before
+     * this method returns.
+     */
+    public void connect() {
+        synchronized (mLock) {
+            if (mServiceConnection != null) {
+                return;
+            }
+            if(!initTts(mRequestedEngine, mFallbackToDefault)) {
+                mConnectionCallbacks.onConnectionFailure();
+            }
+        }
+    }
+
+    /**
+     * Checks if the client is currently connected to the service, so that
+     * requests to other methods will succeed.
+     */
+    public boolean isConnected() {
+        synchronized (mLock) {
+            return mServiceConnection != null && mServiceConnection.isEstablished();
+        }
+    }
+
+    /**
+     * Closes the connection to TextToSpeech service. No calls can be made on this object after
+     * calling this method.
+     * It is good practice to call this method in the onDestroy() method of an Activity
+     * so the TextToSpeech engine can be cleanly stopped.
+     */
+    public void disconnect() {
+        synchronized (mLock) {
+            if (mServiceConnection != null) {
+                mServiceConnection.disconnect();
+                mServiceConnection = null;
+                mCallbacks.clear();
+            }
+        }
+    }
+
+    /**
+     * Register callback.
+     *
+     * @param utteranceId Non-null UtteranceId instance.
+     * @param callback Non-null callbacks for the request
+     * @return Status.SUCCESS or error code in case of invalid arguments.
+     */
+    private int addCallback(UtteranceId utteranceId, RequestCallbacks callback) {
+        synchronized (mLock) {
+            if (utteranceId == null || callback == null) {
+                return Status.ERROR_INVALID_REQUEST;
+            }
+            if (mCallbacks.put(utteranceId.toUniqueString(),
+                    new Pair<UtteranceId, RequestCallbacks>(utteranceId, callback)) != null) {
+                return Status.ERROR_NON_UNIQUE_UTTERANCE_ID;
+            }
+            return Status.SUCCESS;
+        }
+    }
+
+    /**
+     * Remove and return callback.
+     *
+     * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+     */
+    private Pair<UtteranceId, RequestCallbacks> removeCallback(String utteranceIdStr) {
+        synchronized (mLock) {
+            return mCallbacks.remove(utteranceIdStr);
+        }
+    }
+
+    /**
+     * Get callback and utterance id.
+     *
+     * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+     */
+    private Pair<UtteranceId, RequestCallbacks> getCallback(String utteranceIdStr) {
+        synchronized (mLock) {
+            return mCallbacks.get(utteranceIdStr);
+        }
+    }
+
+    /**
+     * Remove callback and call {@link RequestCallbacks#onSynthesisFailure} with passed
+     * error code.
+     *
+     * @param utteranceIdStr Unique string obtained from {@link UtteranceId#toUniqueString}.
+     * @param errorCode argument to {@link RequestCallbacks#onSynthesisFailure} call.
+     */
+    private void removeCallbackAndErr(String utteranceIdStr, int errorCode) {
+        synchronized (mLock) {
+            Pair<UtteranceId, RequestCallbacks> c = mCallbacks.remove(utteranceIdStr);
+            c.second.onSynthesisFailure(c.first, errorCode);
+        }
+    }
+
+    /**
+     * Retrieve TTS engine status {@link EngineStatus}. Requires connected client.
+     */
+    public EngineStatus getEngineStatus() {
+        synchronized (mLock) {
+            return mEngineStatus;
+        }
+    }
+
+    /**
+     * Query TTS engine about available voices and defaults.
+     *
+     * @return EngineStatus is connected or null if client is disconnected.
+     */
+    private EngineStatus requestEngineStatus(ITextToSpeechService service)
+            throws RemoteException {
+        List<VoiceInfo> voices = service.getVoicesInfo();
+        if (voices == null) {
+            Log.e(TAG, "Requested engine doesn't support TTS V2 API");
+            return null;
+        }
+
+        return new EngineStatus(mServiceConnection.getEngineName(), voices);
+    }
+
+    private class Connection implements ServiceConnection {
+        private final String mEngineName;
+
+        private ITextToSpeechService mService;
+
+        private boolean mEstablished;
+
+        private PrepareConnectionAsyncTask mSetupConnectionAsyncTask;
+
+        public Connection(String engineName) {
+            this.mEngineName = engineName;
+        }
+
+        private final ITextToSpeechCallback.Stub mCallback = new ITextToSpeechCallback.Stub() {
+
+            @Override
+            public void onStart(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = getCallback(utteranceIdStr);
+                    callbacks.second.onSynthesisStart(callbacks.first);
+                }
+            }
+
+            public void onStop(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = removeCallback(utteranceIdStr);
+                    callbacks.second.onSynthesisStop(callbacks.first);
+                }
+            }
+
+            @Override
+            public void onSuccess(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = removeCallback(utteranceIdStr);
+                    callbacks.second.onSynthesisSuccess(callbacks.first);
+                }
+            }
+
+            public void onFallback(String utteranceIdStr) {
+                synchronized (mLock) {
+                    Pair<UtteranceId, RequestCallbacks> callbacks = getCallback(
+                            utteranceIdStr);
+                    callbacks.second.onSynthesisFallback(callbacks.first);
+                }
+            };
+
+            @Override
+            public void onError(String utteranceIdStr, int errorCode) {
+                removeCallbackAndErr(utteranceIdStr, errorCode);
+            }
+
+            @Override
+            public void onVoicesInfoChange(List<VoiceInfo> voicesInfo) {
+                synchronized (mLock) {
+                    mEngineStatus = new EngineStatus(mServiceConnection.getEngineName(),
+                            voicesInfo);
+                    mConnectionCallbacks.onEngineStatusChange(mEngineStatus);
+                }
+            }
+        };
+
+        private class PrepareConnectionAsyncTask extends AsyncTask<Void, Void, EngineStatus> {
+
+            private final ComponentName mName;
+
+            public PrepareConnectionAsyncTask(ComponentName name) {
+                mName = name;
+            }
+
+            @Override
+            protected EngineStatus doInBackground(Void... params) {
+                synchronized(mLock) {
+                    if (isCancelled()) {
+                        return null;
+                    }
+                    try {
+                        mService.setCallback(getCallerIdentity(), mCallback);
+                        return requestEngineStatus(mService);
+                    } catch (RemoteException re) {
+                        Log.e(TAG, "Error setting up the TTS service");
+                        return null;
+                    }
+                }
+            }
+
+            @Override
+            protected void onPostExecute(EngineStatus result) {
+                synchronized(mLock) {
+                    if (mSetupConnectionAsyncTask == this) {
+                        mSetupConnectionAsyncTask = null;
+                    }
+                    if (result == null) {
+                        Log.e(TAG, "Setup task failed");
+                        disconnect();
+                        mConnectionCallbacks.onConnectionFailure();
+                        return;
+                    }
+
+                    mEngineStatus = result;
+                    mEstablished = true;
+                }
+                mConnectionCallbacks.onConnectionSuccess();
+            }
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            Log.i(TAG, "Connected to " + name);
+
+            synchronized(mLock) {
+                mEstablished = false;
+                mService = ITextToSpeechService.Stub.asInterface(service);
+                startSetupConnectionTask(name);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            Log.i(TAG, "Asked to disconnect from " + name);
+
+            synchronized(mLock) {
+                stopSetupConnectionTask();
+            }
+            mConnectionCallbacks.onServiceDisconnected();
+        }
+
+        private void startSetupConnectionTask(ComponentName name) {
+            stopSetupConnectionTask();
+            mSetupConnectionAsyncTask = new PrepareConnectionAsyncTask(name);
+            mSetupConnectionAsyncTask.execute();
+        }
+
+        private boolean stopSetupConnectionTask() {
+            boolean result = false;
+            if (mSetupConnectionAsyncTask != null) {
+                result = mSetupConnectionAsyncTask.cancel(false);
+                mSetupConnectionAsyncTask = null;
+            }
+            return result;
+        }
+
+        IBinder getCallerIdentity() {
+            return mCallback;
+        }
+
+        boolean isEstablished() {
+            return mService != null && mEstablished;
+        }
+
+        boolean runAction(Action action) {
+            synchronized (mLock) {
+                try {
+                    action.run(mService);
+                    return true;
+                } catch (Exception ex) {
+                    Log.e(TAG, action.getName() + " failed", ex);
+                    disconnect();
+                    return false;
+                }
+            }
+        }
+
+        void disconnect() {
+            mContext.unbindService(this);
+            stopSetupConnectionTask();
+            mService = null;
+            mEstablished = false;
+            if (mServiceConnection == this) {
+                mServiceConnection = null;
+            }
+        }
+
+        String getEngineName() {
+            return mEngineName;
+        }
+    }
+
+    private abstract class Action {
+        private final String mName;
+
+        public Action(String name) {
+            mName = name;
+        }
+
+        public String getName() {return mName;}
+        abstract void run(ITextToSpeechService service) throws RemoteException;
+    }
+
+    private IBinder getCallerIdentity() {
+        if (mServiceConnection != null) {
+            return mServiceConnection.getCallerIdentity();
+        }
+        return null;
+    }
+
+    private boolean runAction(Action action) {
+        synchronized (mLock) {
+            if (mServiceConnection == null) {
+                return false;
+            }
+            if (!mServiceConnection.isEstablished()) {
+                return false;
+            }
+            mServiceConnection.runAction(action);
+            return true;
+        }
+    }
+
+    private static final String ACTION_STOP_NAME = "stop";
+
+    /**
+     * Interrupts the current utterance spoken (whether played or rendered to file) and discards
+     * other utterances in the queue.
+     */
+    public void stop() {
+        runAction(new Action(ACTION_STOP_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+               if (service.stop(getCallerIdentity()) != Status.SUCCESS) {
+                   Log.e(TAG, "Stop failed");
+               }
+               mCallbacks.clear();
+            }
+        });
+    }
+
+    private static final String ACTION_QUEUE_SPEAK_NAME = "queueSpeak";
+
+    /**
+     * Speaks the string using the specified queuing strategy using current
+     * voice. This method is asynchronous, i.e. the method just adds the request
+     * to the queue of TTS requests and then returns. The synthesis might not
+     * have finished (or even started!) at the time when this method returns.
+     *
+     * @param utterance The string of text to be spoken. No longer than
+     *            1000 characters.
+     * @param utteranceId Unique identificator used to track the synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param config Synthesis request configuration. Can't be null. Has to contain a
+     *            voice.
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueSpeak(final String utterance, final UtteranceId utteranceId,
+            final RequestConfig config,
+            final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_SPEAK_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                    return;
+                }
+
+                int queueResult = service.speakV2(
+                        getCallerIdentity(),
+                        new SynthesisRequestV2(utterance, utteranceId.toUniqueString(), config));
+                if (queueResult != Status.SUCCESS) {
+                    removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                }
+            }
+        });
+    }
+
+    private static final String ACTION_QUEUE_SYNTHESIZE_TO_FILE = "queueSynthesizeToFile";
+
+    /**
+     * Synthesizes the given text to a file using the specified parameters. This
+     * method is asynchronous, i.e. the method just adds the request to the
+     * queue of TTS requests and then returns. The synthesis might not have
+     * finished (or even started!) at the time when this method returns.
+     *
+     * @param utterance The text that should be synthesized. No longer than
+     *            1000 characters.
+     * @param utteranceId Unique identificator used to track the synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param outputFile File to write the generated audio data to.
+     * @param config Synthesis request configuration. Can't be null. Have to contain a
+     *            voice.
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueSynthesizeToFile(final String utterance, final UtteranceId utteranceId,
+            final File outputFile, final RequestConfig config,
+            final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_SYNTHESIZE_TO_FILE) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                    return;
+                }
+
+                ParcelFileDescriptor fileDescriptor = null;
+                try {
+                    if (outputFile.exists() && !outputFile.canWrite()) {
+                        Log.e(TAG, "No permissions to write to " + outputFile);
+                        removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
+                        return;
+                    }
+                    fileDescriptor = ParcelFileDescriptor.open(outputFile,
+                            ParcelFileDescriptor.MODE_WRITE_ONLY |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+                    int queueResult = service.synthesizeToFileDescriptorV2(getCallerIdentity(),
+                            fileDescriptor,
+                            new SynthesisRequestV2(utterance, utteranceId.toUniqueString(),
+                                    config));
+                    fileDescriptor.close();
+                    if (queueResult != Status.SUCCESS) {
+                        removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                    }
+                } catch (FileNotFoundException e) {
+                    Log.e(TAG, "Opening file " + outputFile + " failed", e);
+                    removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
+                } catch (IOException e) {
+                    Log.e(TAG, "Closing file " + outputFile + " failed", e);
+                    removeCallbackAndErr(utteranceId.toUniqueString(), Status.ERROR_OUTPUT);
+                }
+            }
+        });
+    }
+
+    private static final String ACTION_QUEUE_SILENCE_NAME = "queueSilence";
+
+    /**
+     * Plays silence for the specified amount of time. This method is asynchronous,
+     * i.e. the method just adds the request to the queue of TTS requests and then
+     * returns. The synthesis might not have finished (or even started!) at the time
+     * when this method returns.
+     *
+     * @param durationInMs The duration of the silence in milliseconds.
+     * @param utteranceId Unique identificator used to track the synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueSilence(final long durationInMs, final UtteranceId utteranceId,
+            final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_SILENCE_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                }
+
+                int queueResult = service.playSilence(getCallerIdentity(), durationInMs,
+                        TextToSpeech.QUEUE_ADD, utteranceId.toUniqueString());
+
+                if (queueResult != Status.SUCCESS) {
+                    removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                }
+            }
+        });
+    }
+
+
+    private static final String ACTION_QUEUE_AUDIO_NAME = "queueAudio";
+
+    /**
+     * Plays the audio resource using the specified parameters.
+     * This method is asynchronous, i.e. the method just adds the request to the queue of TTS
+     * requests and then returns. The synthesis might not have finished (or even started!) at the
+     * time when this method returns.
+     *
+     * @param audioUrl The audio resource that should be played
+     * @param utteranceId Unique identificator used to track synthesis progress
+     *            in {@link RequestCallbacks}.
+     * @param config Synthesis request configuration. Can't be null. Doesn't have to contain a
+     *            voice (only system parameters are used).
+     * @param callbacks Synthesis request callbacks. If null, default request
+     *            callbacks object will be used.
+     */
+    public void queueAudio(final Uri audioUrl, final UtteranceId utteranceId,
+            final RequestConfig config, final RequestCallbacks callbacks) {
+        runAction(new Action(ACTION_QUEUE_AUDIO_NAME) {
+            @Override
+            public void run(ITextToSpeechService service) throws RemoteException {
+                RequestCallbacks c = mDefaultRequestCallbacks;
+                if (callbacks != null) {
+                    c = callbacks;
+                }
+                int addCallbackStatus = addCallback(utteranceId, c);
+                if (addCallbackStatus != Status.SUCCESS) {
+                    c.onSynthesisFailure(utteranceId, Status.ERROR_INVALID_REQUEST);
+                }
+
+                int queueResult = service.playAudioV2(getCallerIdentity(), audioUrl,
+                        utteranceId.toUniqueString(), config.getVoiceParams());
+
+                if (queueResult != Status.SUCCESS) {
+                    removeCallbackAndErr(utteranceId.toUniqueString(), queueResult);
+                }
+            }
+        });
+    }
+}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 575855c..d7c51fc 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -34,26 +34,27 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.MissingResourceException;
 import java.util.Set;
 
 
 /**
  * Abstract base class for TTS engine implementations. The following methods
- * need to be implemented.
- *
+ * need to be implemented for V1 API ({@link TextToSpeech}) implementation.
  * <ul>
- *   <li>{@link #onIsLanguageAvailable}</li>
- *   <li>{@link #onLoadLanguage}</li>
- *   <li>{@link #onGetLanguage}</li>
- *   <li>{@link #onSynthesizeText}</li>
- *   <li>{@link #onStop}</li>
+ * <li>{@link #onIsLanguageAvailable}</li>
+ * <li>{@link #onLoadLanguage}</li>
+ * <li>{@link #onGetLanguage}</li>
+ * <li>{@link #onSynthesizeText}</li>
+ * <li>{@link #onStop}</li>
  * </ul>
- *
  * The first three deal primarily with language management, and are used to
  * query the engine for it's support for a given language and indicate to it
  * that requests in a given language are imminent.
@@ -61,22 +62,44 @@
  * {@link #onSynthesizeText} is central to the engine implementation. The
  * implementation should synthesize text as per the request parameters and
  * return synthesized data via the supplied callback. This class and its helpers
- * will then consume that data, which might mean queueing it for playback or writing
- * it to a file or similar. All calls to this method will be on a single
- * thread, which will be different from the main thread of the service. Synthesis
- * must be synchronous which means the engine must NOT hold on the callback or call
- * any methods on it after the method returns
+ * will then consume that data, which might mean queuing it for playback or writing
+ * it to a file or similar. All calls to this method will be on a single thread,
+ * which will be different from the main thread of the service. Synthesis must be
+ * synchronous which means the engine must NOT hold on to the callback or call any
+ * methods on it after the method returns.
  *
- * {@link #onStop} tells the engine that it should stop all ongoing synthesis, if
- * any. Any pending data from the current synthesis will be discarded.
+ * {@link #onStop} tells the engine that it should stop
+ * all ongoing synthesis, if any. Any pending data from the current synthesis
+ * will be discarded.
  *
+ * {@link #onGetLanguage} is not required as of JELLYBEAN_MR2 (API 18) and later, it is only
+ * called on earlier versions of Android.
+ * <p>
+ * In order to fully support the V2 API ({@link TextToSpeechClient}),
+ * these methods must be implemented:
+ * <ul>
+ * <li>{@link #onSynthesizeTextV2}</li>
+ * <li>{@link #checkVoicesInfo}</li>
+ * <li>{@link #onVoicesInfoChange}</li>
+ * <li>{@link #implementsV2API}</li>
+ * </ul>
+ * In addition {@link #implementsV2API} has to return true.
+ * <p>
+ * If the service does not implement these methods and {@link #implementsV2API} returns false,
+ * then the V2 API will be provided by converting V2 requests ({@link #onSynthesizeTextV2})
+ * to V1 requests ({@link #onSynthesizeText}). On service setup, all of the available device
+ * locales will be fed to {@link #onIsLanguageAvailable} to check if they are supported.
+ * If they are, embedded and/or network voices will be created depending on the result of
+ * {@link #onGetFeaturesForLanguage}.
+ * <p>
+ * Note that a V2 service will still receive requests from V1 clients and has to implement all
+ * of the V1 API methods.
  */
 public abstract class TextToSpeechService extends Service {
 
     private static final boolean DBG = false;
     private static final String TAG = "TextToSpeechService";
 
-
     private static final String SYNTH_THREAD_NAME = "SynthThread";
 
     private SynthHandler mSynthHandler;
@@ -89,6 +112,11 @@
     private CallbackMap mCallbacks;
     private String mPackageName;
 
+    private final Object mVoicesInfoLock = new Object();
+
+    private List<VoiceInfo> mVoicesInfoList;
+    private Map<String, VoiceInfo> mVoicesInfoLookup;
+
     @Override
     public void onCreate() {
         if (DBG) Log.d(TAG, "onCreate()");
@@ -108,6 +136,7 @@
         mPackageName = getApplicationInfo().packageName;
 
         String[] defaultLocale = getSettingsLocale();
+
         // Load default language
         onLoadLanguage(defaultLocale[0], defaultLocale[1], defaultLocale[2]);
     }
@@ -148,6 +177,9 @@
     /**
      * Returns the language, country and variant currently being used by the TTS engine.
      *
+     * This method will be called only on Android 4.2 and before (API <= 17). In later versions
+     * this method is not called by the Android TTS framework.
+     *
      * Can be called on multiple threads.
      *
      * @return A 3-element array, containing language (ISO 3-letter code),
@@ -191,21 +223,159 @@
     protected abstract void onStop();
 
     /**
-     * Tells the service to synthesize speech from the given text. This method should
-     * block until the synthesis is finished.
-     *
-     * Called on the synthesis thread.
+     * Tells the service to synthesize speech from the given text. This method
+     * should block until the synthesis is finished. Used for requests from V1
+     * clients ({@link android.speech.tts.TextToSpeech}). Called on the synthesis
+     * thread.
      *
      * @param request The synthesis request.
-     * @param callback The callback the the engine must use to make data available for
-     *         playback or for writing to a file.
+     * @param callback The callback that the engine must use to make data
+     *            available for playback or for writing to a file.
      */
     protected abstract void onSynthesizeText(SynthesisRequest request,
             SynthesisCallback callback);
 
     /**
+     * Check the available voices data and return an immutable list of the available voices.
+     * The output of this method will be passed to clients to allow them to configure synthesis
+     * requests.
+     *
+     * Can be called on multiple threads.
+     *
+     * The result of this method will be saved and served to all TTS clients. If a TTS service wants
+     * to update the set of available voices, it should call the {@link #forceVoicesInfoCheck()}
+     * method.
+     */
+    protected List<VoiceInfo> checkVoicesInfo() {
+        if (implementsV2API()) {
+            throw new IllegalStateException("For proper V2 API implementation this method has to" +
+                    "  be implemented");
+        }
+
+        // V2 to V1 interface adapter. This allows using V2 client interface on V1-only services.
+        Bundle defaultParams = new Bundle();
+        defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_PITCH, 1.0f);
+        defaultParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED, -1.0f);
+
+        // Enumerate all locales and check if they are available
+        ArrayList<VoiceInfo> voicesInfo = new ArrayList<VoiceInfo>();
+        int id = 0;
+        for (Locale locale : Locale.getAvailableLocales()) {
+            int expectedStatus = TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE;
+            if (locale.getVariant().isEmpty()) {
+                if (locale.getCountry().isEmpty()) {
+                    expectedStatus = TextToSpeech.LANG_AVAILABLE;
+                } else {
+                    expectedStatus = TextToSpeech.LANG_COUNTRY_AVAILABLE;
+                }
+            }
+            try {
+                int localeStatus = onIsLanguageAvailable(locale.getISO3Language(),
+                        locale.getISO3Country(), locale.getVariant());
+                if (localeStatus != expectedStatus) {
+                    continue;
+                }
+            } catch (MissingResourceException e) {
+                // Ignore locale without iso 3 codes
+                continue;
+            }
+
+            Set<String> features = onGetFeaturesForLanguage(locale.getISO3Language(),
+                        locale.getISO3Country(), locale.getVariant());
+
+            VoiceInfo.Builder builder = new VoiceInfo.Builder();
+            builder.setLatency(VoiceInfo.LATENCY_NORMAL);
+            builder.setQuality(VoiceInfo.QUALITY_NORMAL);
+            builder.setLocale(locale);
+            builder.setParamsWithDefaults(defaultParams);
+
+            if (features == null || features.contains(
+                    TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS)) {
+                builder.setName(locale.toString() + "-embedded");
+                builder.setRequiresNetworkConnection(false);
+                voicesInfo.add(builder.build());
+            }
+
+            if (features != null && features.contains(
+                    TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS)) {
+                builder.setName(locale.toString() + "-network");
+                builder.setRequiresNetworkConnection(true);
+                voicesInfo.add(builder.build());
+            }
+        }
+
+        return voicesInfo;
+    }
+
+    /**
+     * Tells the synthesis thread that it should reload voice data.
+     * There's a high probability that the underlying set of available voice data has changed.
+     * Called only on the synthesis thread.
+     */
+    protected void onVoicesInfoChange() {
+
+    }
+
+    /**
+     * Tells the service to synthesize speech from the given text. This method
+     * should block until the synthesis is finished. Used for requests from V2
+     * client {@link android.speech.tts.TextToSpeechClient}. Called on the
+     * synthesis thread.
+     *
+     * @param request The synthesis request.
+     * @param callback The callback the the engine must use to make data
+     *            available for playback or for writing to a file.
+     */
+    protected void onSynthesizeTextV2(SynthesisRequestV2 request,
+            VoiceInfo selectedVoice,
+            SynthesisCallback callback) {
+        if (implementsV2API()) {
+            throw new IllegalStateException("For proper V2 API implementation this method has to" +
+                    "  be implemented");
+        }
+
+        // Convert to V1 params
+        int speechRate = (int) (request.getVoiceParams().getFloat(
+                TextToSpeechClient.Params.SPEECH_SPEED, 1.0f) * 100);
+        int speechPitch = (int) (request.getVoiceParams().getFloat(
+                TextToSpeechClient.Params.SPEECH_PITCH, 1.0f) * 100);
+
+        // Provide adapter to V1 API
+        Bundle params = new Bundle();
+        params.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, request.getUtteranceId());
+        params.putInt(TextToSpeech.Engine.KEY_PARAM_PITCH, speechPitch);
+        params.putInt(TextToSpeech.Engine.KEY_PARAM_RATE, speechRate);
+        if (selectedVoice.getRequiresNetworkConnection()) {
+            params.putString(TextToSpeech.Engine.KEY_FEATURE_NETWORK_SYNTHESIS, "true");
+        } else {
+            params.putString(TextToSpeech.Engine.KEY_FEATURE_EMBEDDED_SYNTHESIS, "true");
+        }
+
+        // Build V1 request
+        SynthesisRequest requestV1 = new SynthesisRequest(request.getText(), params);
+        Locale locale = selectedVoice.getLocale();
+        requestV1.setLanguage(locale.getISO3Language(), locale.getISO3Country(),
+                locale.getVariant());
+        requestV1.setSpeechRate(speechRate);
+        requestV1.setPitch(speechPitch);
+
+        // Synthesize using V1 interface
+        onSynthesizeText(requestV1, callback);
+    }
+
+    /**
+     * If true, this service implements proper V2 TTS API service. If it's false,
+     * V2 API will be provided through adapter.
+     */
+    protected boolean implementsV2API() {
+        return false;
+    }
+
+    /**
      * Queries the service for a set of features supported for a given language.
      *
+     * Can be called on multiple threads.
+     *
      * @param lang ISO-3 language code.
      * @param country ISO-3 country code. May be empty or null.
      * @param variant Language variant. May be empty or null.
@@ -215,6 +385,69 @@
         return null;
     }
 
+    private List<VoiceInfo> getVoicesInfo() {
+        synchronized (mVoicesInfoLock) {
+            if (mVoicesInfoList == null) {
+                // Get voices. Defensive copy to make sure TTS engine won't alter the list.
+                mVoicesInfoList = new ArrayList<VoiceInfo>(checkVoicesInfo());
+                // Build lookup map
+                mVoicesInfoLookup = new HashMap<String, VoiceInfo>((int) (
+                        mVoicesInfoList.size()*1.5f));
+                for (VoiceInfo voiceInfo : mVoicesInfoList) {
+                    VoiceInfo prev = mVoicesInfoLookup.put(voiceInfo.getName(), voiceInfo);
+                    if (prev != null) {
+                        Log.e(TAG, "Duplicate name (" + voiceInfo.getName() + ") of the voice ");
+                    }
+                }
+            }
+            return mVoicesInfoList;
+        }
+    }
+
+    public VoiceInfo getVoicesInfoWithName(String name) {
+        synchronized (mVoicesInfoLock) {
+            if (mVoicesInfoLookup != null) {
+                return mVoicesInfoLookup.get(name);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Force TTS service to reevaluate the set of available languages. Will result in
+     * a call to {@link #checkVoicesInfo()} on the same thread, {@link #onVoicesInfoChange}
+     * on the synthesizer thread and callback to
+     * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange} of all connected
+     * TTS clients.
+     *
+     * Use this method only if you know that set of available languages changed.
+     *
+     * Can be called on multiple threads.
+     */
+    public void forceVoicesInfoCheck() {
+        synchronized (mVoicesInfoLock) {
+            List<VoiceInfo> old = mVoicesInfoList;
+
+            mVoicesInfoList = null; // Force recreation of voices info list
+            getVoicesInfo();
+
+            if (mVoicesInfoList == null) {
+                throw new IllegalStateException("This method applies only to services " +
+                        "supporting V2 TTS API. This services doesn't support V2 TTS API.");
+            }
+
+            if (old != null) {
+                // Flush all existing items, and inform synthesis thread about the change.
+                mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_FLUSH,
+                        new VoicesInfoChangeItem());
+                // TODO: Handle items that may be added to queue after SynthesizerRestartItem
+                // but before client reconnection
+                // Disconnect all of them
+                mCallbacks.dispatchVoicesInfoChange(mVoicesInfoList);
+            }
+        }
+    }
+
     private int getDefaultSpeechRate() {
         return getSecureSettingInt(Settings.Secure.TTS_DEFAULT_RATE, Engine.DEFAULT_RATE);
     }
@@ -317,7 +550,8 @@
 
             if (!speechItem.isValid()) {
                 if (utterenceProgress != null) {
-                    utterenceProgress.dispatchOnError();
+                    utterenceProgress.dispatchOnError(
+                            TextToSpeechClient.Status.ERROR_INVALID_REQUEST);
                 }
                 return TextToSpeech.ERROR;
             }
@@ -342,12 +576,13 @@
             //
             // Note that this string is interned, so the == comparison works.
             msg.obj = speechItem.getCallerIdentity();
+
             if (sendMessage(msg)) {
                 return TextToSpeech.SUCCESS;
             } else {
                 Log.w(TAG, "SynthThread has quit");
                 if (utterenceProgress != null) {
-                    utterenceProgress.dispatchOnError();
+                    utterenceProgress.dispatchOnError(TextToSpeechClient.Status.ERROR_SERVICE);
                 }
                 return TextToSpeech.ERROR;
             }
@@ -399,9 +634,11 @@
     }
 
     interface UtteranceProgressDispatcher {
-        public void dispatchOnDone();
+        public void dispatchOnFallback();
+        public void dispatchOnStop();
+        public void dispatchOnSuccess();
         public void dispatchOnStart();
-        public void dispatchOnError();
+        public void dispatchOnError(int errorCode);
     }
 
     /**
@@ -409,15 +646,13 @@
      */
     private abstract class SpeechItem {
         private final Object mCallerIdentity;
-        protected final Bundle mParams;
         private final int mCallerUid;
         private final int mCallerPid;
         private boolean mStarted = false;
         private boolean mStopped = false;
 
-        public SpeechItem(Object caller, int callerUid, int callerPid, Bundle params) {
+        public SpeechItem(Object caller, int callerUid, int callerPid) {
             mCallerIdentity = caller;
-            mParams = params;
             mCallerUid = callerUid;
             mCallerPid = callerPid;
         }
@@ -446,20 +681,18 @@
          * Must not be called more than once.
          *
          * Only called on the synthesis thread.
-         *
-         * @return {@link TextToSpeech#SUCCESS} or {@link TextToSpeech#ERROR}.
          */
-        public int play() {
+        public void play() {
             synchronized (this) {
                 if (mStarted) {
                     throw new IllegalStateException("play() called twice");
                 }
                 mStarted = true;
             }
-            return playImpl();
+            playImpl();
         }
 
-        protected abstract int playImpl();
+        protected abstract void playImpl();
 
         /**
          * Stops the speech item.
@@ -485,20 +718,37 @@
     }
 
     /**
-     * An item in the synth thread queue that process utterance.
+     * An item in the synth thread queue that process utterance (and call back to client about
+     * progress).
      */
     private abstract class UtteranceSpeechItem extends SpeechItem
         implements UtteranceProgressDispatcher  {
 
-        public UtteranceSpeechItem(Object caller, int callerUid, int callerPid, Bundle params) {
-            super(caller, callerUid, callerPid, params);
+        public UtteranceSpeechItem(Object caller, int callerUid, int callerPid) {
+            super(caller, callerUid, callerPid);
         }
 
         @Override
-        public void dispatchOnDone() {
+        public void dispatchOnSuccess() {
             final String utteranceId = getUtteranceId();
             if (utteranceId != null) {
-                mCallbacks.dispatchOnDone(getCallerIdentity(), utteranceId);
+                mCallbacks.dispatchOnSuccess(getCallerIdentity(), utteranceId);
+            }
+        }
+
+        @Override
+        public void dispatchOnStop() {
+            final String utteranceId = getUtteranceId();
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnStop(getCallerIdentity(), utteranceId);
+            }
+        }
+
+        @Override
+        public void dispatchOnFallback() {
+            final String utteranceId = getUtteranceId();
+            if (utteranceId != null) {
+                mCallbacks.dispatchOnFallback(getCallerIdentity(), utteranceId);
             }
         }
 
@@ -511,44 +761,260 @@
         }
 
         @Override
-        public void dispatchOnError() {
+        public void dispatchOnError(int errorCode) {
             final String utteranceId = getUtteranceId();
             if (utteranceId != null) {
-                mCallbacks.dispatchOnError(getCallerIdentity(), utteranceId);
+                mCallbacks.dispatchOnError(getCallerIdentity(), utteranceId, errorCode);
             }
         }
 
-        public int getStreamType() {
-            return getIntParam(Engine.KEY_PARAM_STREAM, Engine.DEFAULT_STREAM);
+        abstract public String getUtteranceId();
+
+        String getStringParam(Bundle params, String key, String defaultValue) {
+            return params == null ? defaultValue : params.getString(key, defaultValue);
         }
 
-        public float getVolume() {
-            return getFloatParam(Engine.KEY_PARAM_VOLUME, Engine.DEFAULT_VOLUME);
+        int getIntParam(Bundle params, String key, int defaultValue) {
+            return params == null ? defaultValue : params.getInt(key, defaultValue);
         }
 
-        public float getPan() {
-            return getFloatParam(Engine.KEY_PARAM_PAN, Engine.DEFAULT_PAN);
+        float getFloatParam(Bundle params, String key, float defaultValue) {
+            return params == null ? defaultValue : params.getFloat(key, defaultValue);
+        }
+    }
+
+    /**
+     * UtteranceSpeechItem for V1 API speech items. V1 API speech items keep
+     * synthesis parameters in a single Bundle passed as parameter. This class
+     * allow subclasses to access them conveniently.
+     */
+    private abstract class SpeechItemV1 extends UtteranceSpeechItem {
+        protected final Bundle mParams;
+
+        SpeechItemV1(Object callerIdentity, int callerUid, int callerPid,
+                Bundle params) {
+            super(callerIdentity, callerUid, callerPid);
+            mParams = params;
+        }
+
+        boolean hasLanguage() {
+            return !TextUtils.isEmpty(getStringParam(mParams, Engine.KEY_PARAM_LANGUAGE, null));
+        }
+
+        int getSpeechRate() {
+            return getIntParam(mParams, Engine.KEY_PARAM_RATE, getDefaultSpeechRate());
+        }
+
+        int getPitch() {
+            return getIntParam(mParams, Engine.KEY_PARAM_PITCH, Engine.DEFAULT_PITCH);
+        }
+
+        @Override
+        public String getUtteranceId() {
+            return getStringParam(mParams, Engine.KEY_PARAM_UTTERANCE_ID, null);
+        }
+
+        int getStreamType() {
+            return getIntParam(mParams, Engine.KEY_PARAM_STREAM, Engine.DEFAULT_STREAM);
+        }
+
+        float getVolume() {
+            return getFloatParam(mParams, Engine.KEY_PARAM_VOLUME, Engine.DEFAULT_VOLUME);
+        }
+
+        float getPan() {
+            return getFloatParam(mParams, Engine.KEY_PARAM_PAN, Engine.DEFAULT_PAN);
+        }
+    }
+
+    class SynthesisSpeechItemV2 extends UtteranceSpeechItem {
+        private final SynthesisRequestV2 mSynthesisRequest;
+        private AbstractSynthesisCallback mSynthesisCallback;
+        private final EventLoggerV2 mEventLogger;
+
+        public SynthesisSpeechItemV2(Object callerIdentity, int callerUid, int callerPid,
+                SynthesisRequestV2 synthesisRequest) {
+            super(callerIdentity, callerUid, callerPid);
+
+            mSynthesisRequest = synthesisRequest;
+            mEventLogger = new EventLoggerV2(synthesisRequest, callerUid, callerPid,
+                    mPackageName);
+
+            updateSpeechSpeedParam(synthesisRequest);
+        }
+
+        private void updateSpeechSpeedParam(SynthesisRequestV2 synthesisRequest) {
+            Bundle voiceParams = mSynthesisRequest.getVoiceParams();
+
+            // Inject default speech speed if needed
+            if (voiceParams.containsKey(TextToSpeechClient.Params.SPEECH_SPEED)) {
+                if (voiceParams.getFloat(TextToSpeechClient.Params.SPEECH_SPEED) <= 0) {
+                    voiceParams.putFloat(TextToSpeechClient.Params.SPEECH_SPEED,
+                            getDefaultSpeechRate() / 100.0f);
+                }
+            }
+        }
+
+        @Override
+        public boolean isValid() {
+            if (mSynthesisRequest.getText() == null) {
+                Log.e(TAG, "null synthesis text");
+                return false;
+            }
+            if (mSynthesisRequest.getText().length() >= TextToSpeech.getMaxSpeechInputLength()) {
+                Log.w(TAG, "Text too long: " + mSynthesisRequest.getText().length() + " chars");
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        protected void playImpl() {
+            AbstractSynthesisCallback synthesisCallback;
+            if (mEventLogger != null) {
+                mEventLogger.onRequestProcessingStart();
+            }
+            synchronized (this) {
+                // stop() might have been called before we enter this
+                // synchronized block.
+                if (isStopped()) {
+                    return;
+                }
+                mSynthesisCallback = createSynthesisCallback();
+                synthesisCallback = mSynthesisCallback;
+            }
+
+            // Get voice info
+            VoiceInfo voiceInfo = getVoicesInfoWithName(mSynthesisRequest.getVoiceName());
+            if (voiceInfo != null) {
+                // Primary voice
+                TextToSpeechService.this.onSynthesizeTextV2(mSynthesisRequest, voiceInfo,
+                        synthesisCallback);
+            } else {
+                Log.e(TAG, "Unknown voice name:" + mSynthesisRequest.getVoiceName());
+                synthesisCallback.error(TextToSpeechClient.Status.ERROR_INVALID_REQUEST);
+            }
+
+            // Fix for case where client called .start() & .error(), but did not called .done()
+            if (!synthesisCallback.hasFinished()) {
+                synthesisCallback.done();
+            }
+        }
+
+        @Override
+        protected void stopImpl() {
+            AbstractSynthesisCallback synthesisCallback;
+            synchronized (this) {
+                synthesisCallback = mSynthesisCallback;
+            }
+            if (synthesisCallback != null) {
+                // If the synthesis callback is null, it implies that we haven't
+                // entered the synchronized(this) block in playImpl which in
+                // turn implies that synthesis would not have started.
+                synthesisCallback.stop();
+                TextToSpeechService.this.onStop();
+            }
+        }
+
+        protected AbstractSynthesisCallback createSynthesisCallback() {
+            return new PlaybackSynthesisCallback(getStreamType(), getVolume(), getPan(),
+                    mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger,
+                    implementsV2API());
+        }
+
+        private int getStreamType() {
+            return getIntParam(mSynthesisRequest.getAudioParams(),
+                    TextToSpeechClient.Params.AUDIO_PARAM_STREAM,
+                    Engine.DEFAULT_STREAM);
+        }
+
+        private float getVolume() {
+            return getFloatParam(mSynthesisRequest.getAudioParams(),
+                    TextToSpeechClient.Params.AUDIO_PARAM_VOLUME,
+                    Engine.DEFAULT_VOLUME);
+        }
+
+        private float getPan() {
+            return getFloatParam(mSynthesisRequest.getAudioParams(),
+                    TextToSpeechClient.Params.AUDIO_PARAM_PAN,
+                    Engine.DEFAULT_PAN);
+        }
+
+        @Override
+        public String getUtteranceId() {
+            return mSynthesisRequest.getUtteranceId();
+        }
+    }
+
+    private class SynthesisToFileOutputStreamSpeechItemV2 extends SynthesisSpeechItemV2 {
+        private final FileOutputStream mFileOutputStream;
+
+        public SynthesisToFileOutputStreamSpeechItemV2(Object callerIdentity, int callerUid,
+                int callerPid,
+                SynthesisRequestV2 synthesisRequest,
+                FileOutputStream fileOutputStream) {
+            super(callerIdentity, callerUid, callerPid, synthesisRequest);
+            mFileOutputStream = fileOutputStream;
+        }
+
+        @Override
+        protected AbstractSynthesisCallback createSynthesisCallback() {
+            return new FileSynthesisCallback(mFileOutputStream.getChannel(),
+                    this, getCallerIdentity(), implementsV2API());
+        }
+
+        @Override
+        protected void playImpl() {
+            super.playImpl();
+            try {
+              mFileOutputStream.close();
+            } catch(IOException e) {
+              Log.w(TAG, "Failed to close output file", e);
+            }
+        }
+    }
+
+    private class AudioSpeechItemV2 extends UtteranceSpeechItem {
+        private final AudioPlaybackQueueItem mItem;
+        private final Bundle mAudioParams;
+        private final String mUtteranceId;
+
+        public AudioSpeechItemV2(Object callerIdentity, int callerUid, int callerPid,
+                String utteranceId, Bundle audioParams, Uri uri) {
+            super(callerIdentity, callerUid, callerPid);
+            mUtteranceId = utteranceId;
+            mAudioParams = audioParams;
+            mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
+                    TextToSpeechService.this, uri, getStreamType());
+        }
+
+        @Override
+        public boolean isValid() {
+            return true;
+        }
+
+        @Override
+        protected void playImpl() {
+            mAudioPlaybackHandler.enqueue(mItem);
+        }
+
+        @Override
+        protected void stopImpl() {
+            // Do nothing.
+        }
+
+        protected int getStreamType() {
+            return mAudioParams.getInt(TextToSpeechClient.Params.AUDIO_PARAM_STREAM);
         }
 
         public String getUtteranceId() {
-            return getStringParam(Engine.KEY_PARAM_UTTERANCE_ID, null);
+            return mUtteranceId;
         }
-
-        protected String getStringParam(String key, String defaultValue) {
-            return mParams == null ? defaultValue : mParams.getString(key, defaultValue);
-        }
-
-        protected int getIntParam(String key, int defaultValue) {
-            return mParams == null ? defaultValue : mParams.getInt(key, defaultValue);
-        }
-
-        protected float getFloatParam(String key, float defaultValue) {
-            return mParams == null ? defaultValue : mParams.getFloat(key, defaultValue);
-        }
-
     }
 
-    class SynthesisSpeechItem extends UtteranceSpeechItem {
+
+    class SynthesisSpeechItemV1 extends SpeechItemV1 {
         // Never null.
         private final String mText;
         private final SynthesisRequest mSynthesisRequest;
@@ -556,10 +1022,10 @@
         // Non null after synthesis has started, and all accesses
         // guarded by 'this'.
         private AbstractSynthesisCallback mSynthesisCallback;
-        private final EventLogger mEventLogger;
+        private final EventLoggerV1 mEventLogger;
         private final int mCallerUid;
 
-        public SynthesisSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+        public SynthesisSpeechItemV1(Object callerIdentity, int callerUid, int callerPid,
                 Bundle params, String text) {
             super(callerIdentity, callerUid, callerPid, params);
             mText = text;
@@ -567,7 +1033,7 @@
             mSynthesisRequest = new SynthesisRequest(mText, mParams);
             mDefaultLocale = getSettingsLocale();
             setRequestParams(mSynthesisRequest);
-            mEventLogger = new EventLogger(mSynthesisRequest, callerUid, callerPid,
+            mEventLogger = new EventLoggerV1(mSynthesisRequest, callerUid, callerPid,
                     mPackageName);
         }
 
@@ -589,25 +1055,30 @@
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             AbstractSynthesisCallback synthesisCallback;
             mEventLogger.onRequestProcessingStart();
             synchronized (this) {
                 // stop() might have been called before we enter this
                 // synchronized block.
                 if (isStopped()) {
-                    return TextToSpeech.ERROR;
+                    return;
                 }
                 mSynthesisCallback = createSynthesisCallback();
                 synthesisCallback = mSynthesisCallback;
             }
+
             TextToSpeechService.this.onSynthesizeText(mSynthesisRequest, synthesisCallback);
-            return synthesisCallback.isDone() ? TextToSpeech.SUCCESS : TextToSpeech.ERROR;
+
+            // Fix for case where client called .start() & .error(), but did not called .done()
+            if (synthesisCallback.hasStarted() && !synthesisCallback.hasFinished()) {
+                synthesisCallback.done();
+            }
         }
 
         protected AbstractSynthesisCallback createSynthesisCallback() {
             return new PlaybackSynthesisCallback(getStreamType(), getVolume(), getPan(),
-                    mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger);
+                    mAudioPlaybackHandler, this, getCallerIdentity(), mEventLogger, false);
         }
 
         private void setRequestParams(SynthesisRequest request) {
@@ -632,37 +1103,25 @@
             }
         }
 
-        public String getLanguage() {
-            return getStringParam(Engine.KEY_PARAM_LANGUAGE, mDefaultLocale[0]);
-        }
-
-        private boolean hasLanguage() {
-            return !TextUtils.isEmpty(getStringParam(Engine.KEY_PARAM_LANGUAGE, null));
-        }
-
         private String getCountry() {
             if (!hasLanguage()) return mDefaultLocale[1];
-            return getStringParam(Engine.KEY_PARAM_COUNTRY, "");
+            return getStringParam(mParams, Engine.KEY_PARAM_COUNTRY, "");
         }
 
         private String getVariant() {
             if (!hasLanguage()) return mDefaultLocale[2];
-            return getStringParam(Engine.KEY_PARAM_VARIANT, "");
+            return getStringParam(mParams, Engine.KEY_PARAM_VARIANT, "");
         }
 
-        private int getSpeechRate() {
-            return getIntParam(Engine.KEY_PARAM_RATE, getDefaultSpeechRate());
-        }
-
-        private int getPitch() {
-            return getIntParam(Engine.KEY_PARAM_PITCH, Engine.DEFAULT_PITCH);
+        public String getLanguage() {
+            return getStringParam(mParams, Engine.KEY_PARAM_LANGUAGE, mDefaultLocale[0]);
         }
     }
 
-    private class SynthesisToFileOutputStreamSpeechItem extends SynthesisSpeechItem {
+    private class SynthesisToFileOutputStreamSpeechItemV1 extends SynthesisSpeechItemV1 {
         private final FileOutputStream mFileOutputStream;
 
-        public SynthesisToFileOutputStreamSpeechItem(Object callerIdentity, int callerUid,
+        public SynthesisToFileOutputStreamSpeechItemV1(Object callerIdentity, int callerUid,
                 int callerPid, Bundle params, String text, FileOutputStream fileOutputStream) {
             super(callerIdentity, callerUid, callerPid, params, text);
             mFileOutputStream = fileOutputStream;
@@ -670,30 +1129,26 @@
 
         @Override
         protected AbstractSynthesisCallback createSynthesisCallback() {
-            return new FileSynthesisCallback(mFileOutputStream.getChannel());
+            return new FileSynthesisCallback(mFileOutputStream.getChannel(),
+                    this, getCallerIdentity(), false);
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             dispatchOnStart();
-            int status = super.playImpl();
-            if (status == TextToSpeech.SUCCESS) {
-                dispatchOnDone();
-            } else {
-                dispatchOnError();
-            }
+            super.playImpl();
             try {
               mFileOutputStream.close();
             } catch(IOException e) {
               Log.w(TAG, "Failed to close output file", e);
             }
-            return status;
         }
     }
 
-    private class AudioSpeechItem extends UtteranceSpeechItem {
+    private class AudioSpeechItemV1 extends SpeechItemV1 {
         private final AudioPlaybackQueueItem mItem;
-        public AudioSpeechItem(Object callerIdentity, int callerUid, int callerPid,
+
+        public AudioSpeechItemV1(Object callerIdentity, int callerUid, int callerPid,
                 Bundle params, Uri uri) {
             super(callerIdentity, callerUid, callerPid, params);
             mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
@@ -706,23 +1161,29 @@
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             mAudioPlaybackHandler.enqueue(mItem);
-            return TextToSpeech.SUCCESS;
         }
 
         @Override
         protected void stopImpl() {
             // Do nothing.
         }
+
+        @Override
+        public String getUtteranceId() {
+            return getStringParam(mParams, Engine.KEY_PARAM_UTTERANCE_ID, null);
+        }
     }
 
     private class SilenceSpeechItem extends UtteranceSpeechItem {
         private final long mDuration;
+        private final String mUtteranceId;
 
         public SilenceSpeechItem(Object callerIdentity, int callerUid, int callerPid,
-                Bundle params, long duration) {
-            super(callerIdentity, callerUid, callerPid, params);
+                String utteranceId, long duration) {
+            super(callerIdentity, callerUid, callerPid);
+            mUtteranceId = utteranceId;
             mDuration = duration;
         }
 
@@ -732,26 +1193,57 @@
         }
 
         @Override
-        protected int playImpl() {
+        protected void playImpl() {
             mAudioPlaybackHandler.enqueue(new SilencePlaybackQueueItem(
                     this, getCallerIdentity(), mDuration));
-            return TextToSpeech.SUCCESS;
         }
 
         @Override
         protected void stopImpl() {
-            // Do nothing, handled by AudioPlaybackHandler#stopForApp
+
+        }
+
+        @Override
+        public String getUtteranceId() {
+            return mUtteranceId;
         }
     }
 
+    /**
+     * Call {@link TextToSpeechService#onVoicesInfoChange} on synthesis thread.
+     */
+    private class VoicesInfoChangeItem extends SpeechItem {
+        public VoicesInfoChangeItem() {
+            super(null, 0, 0); // It's never initiated by an user
+        }
+
+        @Override
+        public boolean isValid() {
+            return true;
+        }
+
+        @Override
+        protected void playImpl() {
+            TextToSpeechService.this.onVoicesInfoChange();
+        }
+
+        @Override
+        protected void stopImpl() {
+            // No-op
+        }
+    }
+
+    /**
+     * Call {@link TextToSpeechService#onLoadLanguage} on synth thread.
+     */
     private class LoadLanguageItem extends SpeechItem {
         private final String mLanguage;
         private final String mCountry;
         private final String mVariant;
 
         public LoadLanguageItem(Object callerIdentity, int callerUid, int callerPid,
-                Bundle params, String language, String country, String variant) {
-            super(callerIdentity, callerUid, callerPid, params);
+                String language, String country, String variant) {
+            super(callerIdentity, callerUid, callerPid);
             mLanguage = language;
             mCountry = country;
             mVariant = variant;
@@ -763,14 +1255,8 @@
         }
 
         @Override
-        protected int playImpl() {
-            int result = TextToSpeechService.this.onLoadLanguage(mLanguage, mCountry, mVariant);
-            if (result == TextToSpeech.LANG_AVAILABLE ||
-                    result == TextToSpeech.LANG_COUNTRY_AVAILABLE ||
-                    result == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE) {
-                return TextToSpeech.SUCCESS;
-            }
-            return TextToSpeech.ERROR;
+        protected void playImpl() {
+            TextToSpeechService.this.onLoadLanguage(mLanguage, mCountry, mVariant);
         }
 
         @Override
@@ -800,7 +1286,7 @@
                 return TextToSpeech.ERROR;
             }
 
-            SpeechItem item = new SynthesisSpeechItem(caller,
+            SpeechItem item = new SynthesisSpeechItemV1(caller,
                     Binder.getCallingUid(), Binder.getCallingPid(), params, text);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
@@ -818,7 +1304,7 @@
             final ParcelFileDescriptor sameFileDescriptor = ParcelFileDescriptor.adoptFd(
                     fileDescriptor.detachFd());
 
-            SpeechItem item = new SynthesisToFileOutputStreamSpeechItem(caller,
+            SpeechItem item = new SynthesisToFileOutputStreamSpeechItemV1(caller,
                     Binder.getCallingUid(), Binder.getCallingPid(), params, text,
                     new ParcelFileDescriptor.AutoCloseOutputStream(sameFileDescriptor));
             return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
@@ -830,19 +1316,19 @@
                 return TextToSpeech.ERROR;
             }
 
-            SpeechItem item = new AudioSpeechItem(caller,
+            SpeechItem item = new AudioSpeechItemV1(caller,
                     Binder.getCallingUid(), Binder.getCallingPid(), params, audioUri);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
 
         @Override
-        public int playSilence(IBinder caller, long duration, int queueMode, Bundle params) {
-            if (!checkNonNull(caller, params)) {
+        public int playSilence(IBinder caller, long duration, int queueMode, String utteranceId) {
+            if (!checkNonNull(caller)) {
                 return TextToSpeech.ERROR;
             }
 
             SpeechItem item = new SilenceSpeechItem(caller,
-                    Binder.getCallingUid(), Binder.getCallingPid(), params, duration);
+                    Binder.getCallingUid(), Binder.getCallingPid(), utteranceId, duration);
             return mSynthHandler.enqueueSpeechItem(queueMode, item);
         }
 
@@ -912,7 +1398,7 @@
                     retVal == TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE) {
 
                 SpeechItem item = new LoadLanguageItem(caller, Binder.getCallingUid(),
-                    Binder.getCallingPid(), null, lang, country, variant);
+                        Binder.getCallingPid(), lang, country, variant);
 
                 if (mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item) !=
                         TextToSpeech.SUCCESS) {
@@ -943,6 +1429,58 @@
             }
             return true;
         }
+
+        @Override
+        public List<VoiceInfo> getVoicesInfo() {
+            return TextToSpeechService.this.getVoicesInfo();
+        }
+
+        @Override
+        public int speakV2(IBinder callingInstance,
+                SynthesisRequestV2 request) {
+            if (!checkNonNull(callingInstance, request)) {
+                return TextToSpeech.ERROR;
+            }
+
+            SpeechItem item = new SynthesisSpeechItemV2(callingInstance,
+                    Binder.getCallingUid(), Binder.getCallingPid(), request);
+            return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
+        }
+
+        @Override
+        public int synthesizeToFileDescriptorV2(IBinder callingInstance,
+                ParcelFileDescriptor fileDescriptor,
+                SynthesisRequestV2 request) {
+            if (!checkNonNull(callingInstance, request, fileDescriptor)) {
+                return TextToSpeech.ERROR;
+            }
+
+            // In test env, ParcelFileDescriptor instance may be EXACTLY the same
+            // one that is used by client. And it will be closed by a client, thus
+            // preventing us from writing anything to it.
+            final ParcelFileDescriptor sameFileDescriptor = ParcelFileDescriptor.adoptFd(
+                    fileDescriptor.detachFd());
+
+            SpeechItem item = new SynthesisToFileOutputStreamSpeechItemV2(callingInstance,
+                    Binder.getCallingUid(), Binder.getCallingPid(), request,
+                    new ParcelFileDescriptor.AutoCloseOutputStream(sameFileDescriptor));
+            return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
+
+        }
+
+        @Override
+        public int playAudioV2(
+                IBinder callingInstance, Uri audioUri, String utteranceId,
+                Bundle systemParameters) {
+            if (!checkNonNull(callingInstance, audioUri, systemParameters)) {
+                return TextToSpeech.ERROR;
+            }
+
+            SpeechItem item = new AudioSpeechItemV2(callingInstance,
+                    Binder.getCallingUid(), Binder.getCallingPid(), utteranceId, systemParameters,
+                    audioUri);
+            return mSynthHandler.enqueueSpeechItem(TextToSpeech.QUEUE_ADD, item);
+        }
     };
 
     private class CallbackMap extends RemoteCallbackList<ITextToSpeechCallback> {
@@ -964,11 +1502,31 @@
             }
         }
 
-        public void dispatchOnDone(Object callerIdentity, String utteranceId) {
+        public void dispatchOnFallback(Object callerIdentity, String utteranceId) {
             ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
             if (cb == null) return;
             try {
-                cb.onDone(utteranceId);
+                cb.onFallback(utteranceId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Callback onFallback failed: " + e);
+            }
+        }
+
+        public void dispatchOnStop(Object callerIdentity, String utteranceId) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
+            if (cb == null) return;
+            try {
+                cb.onStop(utteranceId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Callback onStop failed: " + e);
+            }
+        }
+
+        public void dispatchOnSuccess(Object callerIdentity, String utteranceId) {
+            ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
+            if (cb == null) return;
+            try {
+                cb.onSuccess(utteranceId);
             } catch (RemoteException e) {
                 Log.e(TAG, "Callback onDone failed: " + e);
             }
@@ -985,11 +1543,12 @@
 
         }
 
-        public void dispatchOnError(Object callerIdentity, String utteranceId) {
+        public void dispatchOnError(Object callerIdentity, String utteranceId,
+                int errorCode) {
             ITextToSpeechCallback cb = getCallbackFor(callerIdentity);
             if (cb == null) return;
             try {
-                cb.onError(utteranceId);
+                cb.onError(utteranceId, errorCode);
             } catch (RemoteException e) {
                 Log.e(TAG, "Callback onError failed: " + e);
             }
@@ -1001,7 +1560,7 @@
             synchronized (mCallerToCallback) {
                 mCallerToCallback.remove(caller);
             }
-            mSynthHandler.stopForApp(caller);
+            //mSynthHandler.stopForApp(caller);
         }
 
         @Override
@@ -1012,6 +1571,18 @@
             }
         }
 
+        public void dispatchVoicesInfoChange(List<VoiceInfo> voicesInfo) {
+            synchronized (mCallerToCallback) {
+                for (ITextToSpeechCallback callback : mCallerToCallback.values()) {
+                    try {
+                        callback.onVoicesInfoChange(voicesInfo);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Failed to request reconnect", e);
+                    }
+                }
+            }
+        }
+
         private ITextToSpeechCallback getCallbackFor(Object caller) {
             ITextToSpeechCallback cb;
             IBinder asBinder = (IBinder) caller;
@@ -1021,7 +1592,5 @@
 
             return cb;
         }
-
     }
-
 }
diff --git a/core/java/android/speech/tts/VoiceInfo.aidl b/core/java/android/speech/tts/VoiceInfo.aidl
new file mode 100644
index 0000000..4005f8b
--- /dev/null
+++ b/core/java/android/speech/tts/VoiceInfo.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** 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.speech.tts;
+
+parcelable VoiceInfo;
\ No newline at end of file
diff --git a/core/java/android/speech/tts/VoiceInfo.java b/core/java/android/speech/tts/VoiceInfo.java
new file mode 100644
index 0000000..16b9a97
--- /dev/null
+++ b/core/java/android/speech/tts/VoiceInfo.java
@@ -0,0 +1,325 @@
+package android.speech.tts;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Locale;
+
+/**
+ * Characteristics and features of a Text-To-Speech Voice. Each TTS Engine can expose
+ * multiple voices for multiple locales, with different set of features.
+ *
+ * Each VoiceInfo has an unique name. This name can be obtained using the {@link #getName()} method
+ * and will persist until the client is asked to re-evaluate the list of available voices in the
+ * {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
+ * callback. The name can be used to reference a VoiceInfo in an instance of {@link RequestConfig};
+ * the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter is an example of this.
+ * It is recommended that the voice name never change during the TTS service lifetime.
+ */
+public final class VoiceInfo implements Parcelable {
+    /** Very low, but still intelligible quality of speech synthesis */
+    public static final int QUALITY_VERY_LOW = 100;
+
+    /** Low, not human-like quality of speech synthesis */
+    public static final int QUALITY_LOW = 200;
+
+    /** Normal quality of speech synthesis */
+    public static final int QUALITY_NORMAL = 300;
+
+    /** High, human-like quality of speech synthesis */
+    public static final int QUALITY_HIGH = 400;
+
+    /** Very high, almost human-indistinguishable quality of speech synthesis */
+    public static final int QUALITY_VERY_HIGH = 500;
+
+    /** Very low expected synthesizer latency (< 20ms) */
+    public static final int LATENCY_VERY_LOW = 100;
+
+    /** Low expected synthesizer latency (~20ms) */
+    public static final int LATENCY_LOW = 200;
+
+    /** Normal expected synthesizer latency (~50ms) */
+    public static final int LATENCY_NORMAL = 300;
+
+    /** Network based expected synthesizer latency (~200ms) */
+    public static final int LATENCY_HIGH = 400;
+
+    /** Very slow network based expected synthesizer latency (> 200ms) */
+    public static final int LATENCY_VERY_HIGH = 500;
+
+    /** Additional feature key, with string value, gender of the speaker */
+    public static final String FEATURE_SPEAKER_GENDER = "speakerGender";
+
+    /** Additional feature key, with integer value, speaking speed in words per minute
+     * when {@link TextToSpeechClient.Params#SPEECH_SPEED} parameter is set to {@code 1.0} */
+    public static final String FEATURE_WORDS_PER_MINUTE = "wordsPerMinute";
+
+    /**
+     * Additional feature key, with boolean value, that indicates that voice may need to
+     * download additional data if used for synthesis.
+     *
+     * Making a request with a voice that has this feature may result in a
+     * {@link TextToSpeechClient.Status#ERROR_DOWNLOADING_ADDITIONAL_DATA} error. It's recommended
+     * to set the {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} voice parameter to reference
+     * a fully installed voice (or network voice) that can serve as replacement.
+     *
+     * Note: It's a good practice for a TTS engine to provide a sensible fallback voice as the
+     * default value for {@link TextToSpeechClient.Params#FALLBACK_VOICE_NAME} parameter if this
+     * feature is present.
+     */
+    public static final String FEATURE_MAY_AUTOINSTALL = "mayAutoInstall";
+
+    private final String mName;
+    private final Locale mLocale;
+    private final int mQuality;
+    private final int mLatency;
+    private final boolean mRequiresNetworkConnection;
+    private final Bundle mParams;
+    private final Bundle mAdditionalFeatures;
+
+    private VoiceInfo(Parcel in) {
+        this.mName = in.readString();
+        String[] localesData = new String[3];
+        in.readStringArray(localesData);
+        this.mLocale = new Locale(localesData[0], localesData[1], localesData[2]);
+
+        this.mQuality = in.readInt();
+        this.mLatency = in.readInt();
+        this.mRequiresNetworkConnection = (in.readByte() == 1);
+
+        this.mParams = in.readBundle();
+        this.mAdditionalFeatures = in.readBundle();
+    }
+
+    private VoiceInfo(String name,
+            Locale locale,
+            int quality,
+            int latency,
+            boolean requiresNetworkConnection,
+            Bundle params,
+            Bundle additionalFeatures) {
+        this.mName = name;
+        this.mLocale = locale;
+        this.mQuality = quality;
+        this.mLatency = latency;
+        this.mRequiresNetworkConnection = requiresNetworkConnection;
+        this.mParams = params;
+        this.mAdditionalFeatures = additionalFeatures;
+    }
+
+    /** Builder, allows TTS engines to create VoiceInfo instances. */
+    public static final class Builder {
+        private String name;
+        private Locale locale;
+        private int quality = VoiceInfo.QUALITY_NORMAL;
+        private int latency = VoiceInfo.LATENCY_NORMAL;
+        private boolean requiresNetworkConnection;
+        private Bundle params;
+        private Bundle additionalFeatures;
+
+        public Builder() {
+
+        }
+
+        /**
+         * Copy fields from given VoiceInfo instance.
+         */
+        public Builder(VoiceInfo voiceInfo) {
+            this.name = voiceInfo.mName;
+            this.locale = voiceInfo.mLocale;
+            this.quality = voiceInfo.mQuality;
+            this.latency = voiceInfo.mLatency;
+            this.requiresNetworkConnection = voiceInfo.mRequiresNetworkConnection;
+            this.params = (Bundle)voiceInfo.mParams.clone();
+            this.additionalFeatures = (Bundle) voiceInfo.mAdditionalFeatures.clone();
+        }
+
+        /**
+         * Sets the voice's unique name. It will be used by clients to reference the voice used by a
+         * request.
+         *
+         * It's recommended that each voice use the same consistent name during the TTS service
+         * lifetime.
+         */
+        public Builder setName(String name) {
+            this.name = name;
+            return this;
+        }
+
+        /**
+         * Sets voice locale. This has to be a valid locale, built from ISO 639-1 and ISO 3166-1
+         * two letter codes.
+         */
+        public Builder setLocale(Locale locale) {
+            this.locale = locale;
+            return this;
+        }
+
+        /**
+         * Sets map of all available request parameters with their default values.
+         * Some common parameter names can be found in {@link TextToSpeechClient.Params} static
+         * members.
+         */
+        public Builder setParamsWithDefaults(Bundle params) {
+            this.params = params;
+            return this;
+        }
+
+        /**
+         * Sets map of additional voice features. Some common feature names can be found in
+         * {@link VoiceInfo} static members.
+         */
+        public Builder setAdditionalFeatures(Bundle additionalFeatures) {
+            this.additionalFeatures = additionalFeatures;
+            return this;
+        }
+
+        /**
+         * Sets the voice quality (higher is better).
+         */
+        public Builder setQuality(int quality) {
+            this.quality = quality;
+            return this;
+        }
+
+        /**
+         * Sets the voice latency (lower is better).
+         */
+        public Builder setLatency(int latency) {
+            this.latency = latency;
+            return this;
+        }
+
+        /**
+         * Sets whether the voice requires network connection to work properly.
+         */
+        public Builder setRequiresNetworkConnection(boolean requiresNetworkConnection) {
+            this.requiresNetworkConnection = requiresNetworkConnection;
+            return this;
+        }
+
+        /**
+         * @return The built VoiceInfo instance.
+         */
+        public VoiceInfo build() {
+            if (name == null || name.isEmpty()) {
+                throw new IllegalStateException("Name can't be null or empty");
+            }
+            if (locale == null) {
+                throw new IllegalStateException("Locale can't be null");
+            }
+
+            return new VoiceInfo(name, locale, quality, latency,
+                        requiresNetworkConnection,
+                        ((params == null) ? new Bundle() :
+                            (Bundle)params.clone()),
+                        ((additionalFeatures == null) ? new Bundle() :
+                            (Bundle)additionalFeatures.clone()));
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mName);
+        String[] localesData = new String[]{mLocale.getLanguage(), mLocale.getCountry(), mLocale.getVariant()};
+        dest.writeStringArray(localesData);
+        dest.writeInt(mQuality);
+        dest.writeInt(mLatency);
+        dest.writeByte((byte) (mRequiresNetworkConnection ? 1 : 0));
+        dest.writeBundle(mParams);
+        dest.writeBundle(mAdditionalFeatures);
+    }
+
+    /**
+     * @hide
+     */
+    public static final Parcelable.Creator<VoiceInfo> CREATOR = new Parcelable.Creator<VoiceInfo>() {
+        @Override
+        public VoiceInfo createFromParcel(Parcel in) {
+            return new VoiceInfo(in);
+        }
+
+        @Override
+        public VoiceInfo[] newArray(int size) {
+            return new VoiceInfo[size];
+        }
+    };
+
+    /**
+     * @return The voice's locale
+     */
+    public Locale getLocale() {
+        return mLocale;
+    }
+
+    /**
+     * @return The voice's quality (higher is better)
+     */
+    public int getQuality() {
+        return mQuality;
+    }
+
+    /**
+     * @return The voice's latency (lower is better)
+     */
+    public int getLatency() {
+        return mLatency;
+    }
+
+    /**
+     * @return Does the Voice require a network connection to work.
+     */
+    public boolean getRequiresNetworkConnection() {
+        return mRequiresNetworkConnection;
+    }
+
+    /**
+     * @return Bundle of all available parameters with their default values.
+     */
+    public Bundle getParamsWithDefaults() {
+        return mParams;
+    }
+
+    /**
+     * @return Unique voice name.
+     *
+     * Each VoiceInfo has an unique name, that persists until client is asked to re-evaluate the
+     * set of the available languages in the {@link TextToSpeechClient.ConnectionCallbacks#onEngineStatusChange(android.speech.tts.TextToSpeechClient.EngineStatus)}
+     * callback (Voice may disappear from the set if voice was removed by the user).
+     */
+    public String getName() {
+        return mName;
+    }
+
+    /**
+     * @return Additional features of the voice.
+     */
+    public Bundle getAdditionalFeatures() {
+        return mAdditionalFeatures;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder(64);
+        return builder.append("VoiceInfo[Name: ").append(mName)
+                .append(" ,locale: ").append(mLocale)
+                .append(" ,quality: ").append(mQuality)
+                .append(" ,latency: ").append(mLatency)
+                .append(" ,requiresNetwork: ").append(mRequiresNetworkConnection)
+                .append(" ,paramsWithDefaults: ").append(mParams.toString())
+                .append(" ,additionalFeatures: ").append(mAdditionalFeatures.toString())
+                .append("]").toString();
+    }
+}
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index f839d52..c80321c 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -48,11 +48,8 @@
 import android.text.style.URLSpan;
 import android.text.style.UnderlineSpan;
 
-import com.android.internal.util.XmlUtils;
-
 import java.io.IOException;
 import java.io.StringReader;
-import java.util.HashMap;
 
 /**
  * This class processes HTML strings into displayable styled text.
diff --git a/core/java/android/text/SpannableStringBuilder.java b/core/java/android/text/SpannableStringBuilder.java
index 34274a6..b55cd6a 100644
--- a/core/java/android/text/SpannableStringBuilder.java
+++ b/core/java/android/text/SpannableStringBuilder.java
@@ -29,6 +29,7 @@
  */
 public class SpannableStringBuilder implements CharSequence, GetChars, Spannable, Editable,
         Appendable, GraphicsOperations {
+    private final static String TAG = "SpannableStringBuilder";
     /**
      * Create a new SpannableStringBuilder with empty contents
      */
@@ -436,10 +437,26 @@
     }
 
     // Documentation from interface
-    public SpannableStringBuilder replace(final int start, final int end,
+    public SpannableStringBuilder replace(int start, int end,
             CharSequence tb, int tbstart, int tbend) {
         checkRange("replace", start, end);
 
+        // Sanity check
+        if (start > end) {
+            Log.w(TAG, "Bad arguments to #replace : "
+                    + "start = " + start + ", end = " + end);
+            final int tmp = start;
+            start = end;
+            end = tmp;
+        }
+        if (tbstart > tbend) {
+            Log.w(TAG, "Bad arguments to #replace : "
+                    + "tbstart = " + tbstart + ", tbend = " + tbend);
+            final int tmp = tbstart;
+            tbstart = tbend;
+            tbend = tmp;
+        }
+
         int filtercount = mFilters.length;
         for (int i = 0; i < filtercount; i++) {
             CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
@@ -613,8 +630,9 @@
 
         // 0-length Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
         if (flagsStart == POINT && flagsEnd == MARK && start == end) {
-            if (send) Log.e("SpannableStringBuilder",
-                    "SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length");
+            if (send) {
+                Log.e(TAG, "SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length");
+            }
             // Silently ignore invalid spans when they are created from this class.
             // This avoids the duplication of the above test code before all the
             // calls to setSpan that are done in this class
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 22675b4..d0ed871 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -28,7 +28,6 @@
 import java.util.Formatter;
 import java.util.GregorianCalendar;
 import java.util.Locale;
-import java.util.TimeZone;
 
 import libcore.icu.DateIntervalFormat;
 import libcore.icu.LocaleData;
diff --git a/core/java/android/text/method/HideReturnsTransformationMethod.java b/core/java/android/text/method/HideReturnsTransformationMethod.java
index ce18692..c6a90ca 100644
--- a/core/java/android/text/method/HideReturnsTransformationMethod.java
+++ b/core/java/android/text/method/HideReturnsTransformationMethod.java
@@ -16,13 +16,6 @@
 
 package android.text.method;
 
-import android.graphics.Rect;
-import android.text.GetChars;
-import android.text.Spanned;
-import android.text.SpannedString;
-import android.text.TextUtils;
-import android.view.View; 
-
 /**
  * This transformation method causes any carriage return characters (\r)
  * to be hidden by displaying them as zero-width non-breaking space
diff --git a/core/java/android/text/method/PasswordTransformationMethod.java b/core/java/android/text/method/PasswordTransformationMethod.java
index b769b76..88a69b9 100644
--- a/core/java/android/text/method/PasswordTransformationMethod.java
+++ b/core/java/android/text/method/PasswordTransformationMethod.java
@@ -25,7 +25,6 @@
 import android.text.NoCopySpan;
 import android.text.TextUtils;
 import android.text.TextWatcher;
-import android.text.Selection;
 import android.text.Spanned;
 import android.text.Spannable;
 import android.text.style.UpdateLayout;
diff --git a/core/java/android/text/method/SingleLineTransformationMethod.java b/core/java/android/text/method/SingleLineTransformationMethod.java
index 6a05fe4..818526a 100644
--- a/core/java/android/text/method/SingleLineTransformationMethod.java
+++ b/core/java/android/text/method/SingleLineTransformationMethod.java
@@ -16,15 +16,6 @@
 
 package android.text.method;
 
-import android.graphics.Rect;
-import android.text.Editable;
-import android.text.GetChars;
-import android.text.Spannable;
-import android.text.Spanned;
-import android.text.SpannedString;
-import android.text.TextUtils;
-import android.view.View;
-
 /**
  * This transformation method causes any newline characters (\n) to be
  * displayed as spaces instead of causing line breaks, and causes
diff --git a/core/java/android/text/style/BackgroundColorSpan.java b/core/java/android/text/style/BackgroundColorSpan.java
index 580a369..cda8015 100644
--- a/core/java/android/text/style/BackgroundColorSpan.java
+++ b/core/java/android/text/style/BackgroundColorSpan.java
@@ -26,9 +26,9 @@
 
     private final int mColor;
 
-	public BackgroundColorSpan(int color) {
-		mColor = color;
-	}
+    public BackgroundColorSpan(int color) {
+        mColor = color;
+    }
 
     public BackgroundColorSpan(Parcel src) {
         mColor = src.readInt();
@@ -46,12 +46,12 @@
         dest.writeInt(mColor);
     }
 
-	public int getBackgroundColor() {
-		return mColor;
-	}
+    public int getBackgroundColor() {
+        return mColor;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.bgColor = mColor;
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.bgColor = mColor;
+    }
 }
diff --git a/core/java/android/text/style/CharacterStyle.java b/core/java/android/text/style/CharacterStyle.java
index 14dfddd..5b95f1a 100644
--- a/core/java/android/text/style/CharacterStyle.java
+++ b/core/java/android/text/style/CharacterStyle.java
@@ -24,7 +24,7 @@
  * ones may just implement {@link UpdateAppearance}.
  */
 public abstract class CharacterStyle {
-	public abstract void updateDrawState(TextPaint tp);
+    public abstract void updateDrawState(TextPaint tp);
 
     /**
      * A given CharacterStyle can only applied to a single region of a given
diff --git a/core/java/android/text/style/DrawableMarginSpan.java b/core/java/android/text/style/DrawableMarginSpan.java
index c2564d5..20b6886 100644
--- a/core/java/android/text/style/DrawableMarginSpan.java
+++ b/core/java/android/text/style/DrawableMarginSpan.java
@@ -19,7 +19,6 @@
 import android.graphics.drawable.Drawable;
 import android.graphics.Paint;
 import android.graphics.Canvas;
-import android.graphics.RectF;
 import android.text.Spanned;
 import android.text.Layout;
 
diff --git a/core/java/android/text/style/DynamicDrawableSpan.java b/core/java/android/text/style/DynamicDrawableSpan.java
index 89dc45b..5b8a6dd 100644
--- a/core/java/android/text/style/DynamicDrawableSpan.java
+++ b/core/java/android/text/style/DynamicDrawableSpan.java
@@ -17,12 +17,9 @@
 package android.text.style;
 
 import android.graphics.Canvas;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
-import android.graphics.Paint.Style;
 import android.graphics.drawable.Drawable;
-import android.util.Log;
 
 import java.lang.ref.WeakReference;
 
diff --git a/core/java/android/text/style/ForegroundColorSpan.java b/core/java/android/text/style/ForegroundColorSpan.java
index 476124d..c9e09bd 100644
--- a/core/java/android/text/style/ForegroundColorSpan.java
+++ b/core/java/android/text/style/ForegroundColorSpan.java
@@ -26,9 +26,9 @@
 
     private final int mColor;
 
-	public ForegroundColorSpan(int color) {
-		mColor = color;
-	}
+    public ForegroundColorSpan(int color) {
+        mColor = color;
+    }
 
     public ForegroundColorSpan(Parcel src) {
         mColor = src.readInt();
@@ -46,12 +46,12 @@
         dest.writeInt(mColor);
     }
 
-	public int getForegroundColor() {
-		return mColor;
-	}
+    public int getForegroundColor() {
+        return mColor;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setColor(mColor);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setColor(mColor);
+    }
 }
diff --git a/core/java/android/text/style/IconMarginSpan.java b/core/java/android/text/style/IconMarginSpan.java
index c786a17..cf9a705 100644
--- a/core/java/android/text/style/IconMarginSpan.java
+++ b/core/java/android/text/style/IconMarginSpan.java
@@ -19,7 +19,6 @@
 import android.graphics.Paint;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.RectF;
 import android.text.Spanned;
 import android.text.Layout;
 
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index 74b9463..3d6f8e6 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -145,7 +145,7 @@
             }
         } else {
             try {
-                drawable = mContext.getResources().getDrawable(mResourceId);
+                drawable = mContext.getDrawable(mResourceId);
                 drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                         drawable.getIntrinsicHeight());
             } catch (Exception e) {
diff --git a/core/java/android/text/style/LineHeightSpan.java b/core/java/android/text/style/LineHeightSpan.java
index 44a1706..1ebee82 100644
--- a/core/java/android/text/style/LineHeightSpan.java
+++ b/core/java/android/text/style/LineHeightSpan.java
@@ -17,8 +17,6 @@
 package android.text.style;
 
 import android.graphics.Paint;
-import android.graphics.Canvas;
-import android.text.Layout;
 import android.text.TextPaint;
 
 public interface LineHeightSpan
diff --git a/core/java/android/text/style/MaskFilterSpan.java b/core/java/android/text/style/MaskFilterSpan.java
index 64ab0d8..2ff52a8f 100644
--- a/core/java/android/text/style/MaskFilterSpan.java
+++ b/core/java/android/text/style/MaskFilterSpan.java
@@ -21,18 +21,18 @@
 
 public class MaskFilterSpan extends CharacterStyle implements UpdateAppearance {
 
-	private MaskFilter mFilter;
+    private MaskFilter mFilter;
 
-	public MaskFilterSpan(MaskFilter filter) {
-		mFilter = filter;
-	}
+    public MaskFilterSpan(MaskFilter filter) {
+        mFilter = filter;
+    }
 
-	public MaskFilter getMaskFilter() {
-		return mFilter;
-	}
+    public MaskFilter getMaskFilter() {
+        return mFilter;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setMaskFilter(mFilter);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setMaskFilter(mFilter);
+    }
 }
diff --git a/core/java/android/text/style/MetricAffectingSpan.java b/core/java/android/text/style/MetricAffectingSpan.java
index 92558eb..853ecc6 100644
--- a/core/java/android/text/style/MetricAffectingSpan.java
+++ b/core/java/android/text/style/MetricAffectingSpan.java
@@ -16,7 +16,6 @@
 
 package android.text.style;
 
-import android.graphics.Paint;
 import android.text.TextPaint;
 
 /**
@@ -27,7 +26,7 @@
 extends CharacterStyle
 implements UpdateLayout {
 
-	public abstract void updateMeasureState(TextPaint p);
+    public abstract void updateMeasureState(TextPaint p);
 
     /**
      * Returns "this" for most MetricAffectingSpans, but for 
diff --git a/core/java/android/text/style/RasterizerSpan.java b/core/java/android/text/style/RasterizerSpan.java
index 75b5bcc..cae9640 100644
--- a/core/java/android/text/style/RasterizerSpan.java
+++ b/core/java/android/text/style/RasterizerSpan.java
@@ -21,18 +21,18 @@
 
 public class RasterizerSpan extends CharacterStyle implements UpdateAppearance {
 
-	private Rasterizer mRasterizer;
+    private Rasterizer mRasterizer;
 
-	public RasterizerSpan(Rasterizer r) {
-		mRasterizer = r;
-	}
+    public RasterizerSpan(Rasterizer r) {
+        mRasterizer = r;
+    }
 
-	public Rasterizer getRasterizer() {
-		return mRasterizer;
-	}
+    public Rasterizer getRasterizer() {
+        return mRasterizer;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setRasterizer(mRasterizer);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setRasterizer(mRasterizer);
+    }
 }
diff --git a/core/java/android/text/style/RelativeSizeSpan.java b/core/java/android/text/style/RelativeSizeSpan.java
index 9717362..632dbd4 100644
--- a/core/java/android/text/style/RelativeSizeSpan.java
+++ b/core/java/android/text/style/RelativeSizeSpan.java
@@ -23,11 +23,11 @@
 
 public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final float mProportion;
+    private final float mProportion;
 
-	public RelativeSizeSpan(float proportion) {
-		mProportion = proportion;
-	}
+    public RelativeSizeSpan(float proportion) {
+        mProportion = proportion;
+    }
 
     public RelativeSizeSpan(Parcel src) {
         mProportion = src.readFloat();
@@ -45,17 +45,17 @@
         dest.writeFloat(mProportion);
     }
 
-	public float getSizeChange() {
-		return mProportion;
-	}
+    public float getSizeChange() {
+        return mProportion;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setTextSize(ds.getTextSize() * mProportion);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setTextSize(ds.getTextSize() * mProportion);
+    }
 
-	@Override
-	public void updateMeasureState(TextPaint ds) {
-		ds.setTextSize(ds.getTextSize() * mProportion);
-	}
+    @Override
+    public void updateMeasureState(TextPaint ds) {
+        ds.setTextSize(ds.getTextSize() * mProportion);
+    }
 }
diff --git a/core/java/android/text/style/ScaleXSpan.java b/core/java/android/text/style/ScaleXSpan.java
index 655064b..a22a5a1 100644
--- a/core/java/android/text/style/ScaleXSpan.java
+++ b/core/java/android/text/style/ScaleXSpan.java
@@ -23,11 +23,11 @@
 
 public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final float mProportion;
+    private final float mProportion;
 
-	public ScaleXSpan(float proportion) {
-		mProportion = proportion;
-	}
+    public ScaleXSpan(float proportion) {
+        mProportion = proportion;
+    }
 
     public ScaleXSpan(Parcel src) {
         mProportion = src.readFloat();
@@ -45,17 +45,17 @@
         dest.writeFloat(mProportion);
     }
 
-	public float getScaleX() {
-		return mProportion;
-	}
+    public float getScaleX() {
+        return mProportion;
+    }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setTextScaleX(ds.getTextScaleX() * mProportion);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+    }
 
-	@Override
-	public void updateMeasureState(TextPaint ds) {
-		ds.setTextScaleX(ds.getTextScaleX() * mProportion);
-	}
+    @Override
+    public void updateMeasureState(TextPaint ds) {
+        ds.setTextScaleX(ds.getTextScaleX() * mProportion);
+    }
 }
diff --git a/core/java/android/text/style/StrikethroughSpan.java b/core/java/android/text/style/StrikethroughSpan.java
index b51363a..303e41574 100644
--- a/core/java/android/text/style/StrikethroughSpan.java
+++ b/core/java/android/text/style/StrikethroughSpan.java
@@ -40,8 +40,8 @@
     public void writeToParcel(Parcel dest, int flags) {
     }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setStrikeThruText(true);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setStrikeThruText(true);
+    }
 }
diff --git a/core/java/android/text/style/StyleSpan.java b/core/java/android/text/style/StyleSpan.java
index 8e6147c..b08f70e 100644
--- a/core/java/android/text/style/StyleSpan.java
+++ b/core/java/android/text/style/StyleSpan.java
@@ -33,17 +33,17 @@
  */
 public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan {
 
-	private final int mStyle;
+    private final int mStyle;
 
-	/**
-	 * 
-	 * @param style An integer constant describing the style for this span. Examples
-	 * include bold, italic, and normal. Values are constants defined 
-	 * in {@link android.graphics.Typeface}.
-	 */
-	public StyleSpan(int style) {
-		mStyle = style;
-	}
+    /**
+     * 
+     * @param style An integer constant describing the style for this span. Examples
+     * include bold, italic, and normal. Values are constants defined 
+     * in {@link android.graphics.Typeface}.
+     */
+    public StyleSpan(int style) {
+        mStyle = style;
+    }
 
     public StyleSpan(Parcel src) {
         mStyle = src.readInt();
@@ -61,19 +61,19 @@
         dest.writeInt(mStyle);
     }
 
-	/**
-	 * Returns the style constant defined in {@link android.graphics.Typeface}. 
-	 */
-	public int getStyle() {
-		return mStyle;
-	}
+    /**
+     * Returns the style constant defined in {@link android.graphics.Typeface}. 
+     */
+    public int getStyle() {
+        return mStyle;
+    }
 
-	@Override
+    @Override
     public void updateDrawState(TextPaint ds) {
         apply(ds, mStyle);
     }
 
-	@Override
+    @Override
     public void updateMeasureState(TextPaint paint) {
         apply(paint, mStyle);
     }
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index 0ec7e84..8b40953 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -166,25 +166,25 @@
             return;
         }
 
-        int defStyle = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
+        int defStyleAttr = com.android.internal.R.attr.textAppearanceMisspelledSuggestion;
         TypedArray typedArray = context.obtainStyledAttributes(
-                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
         mMisspelledUnderlineThickness = typedArray.getDimension(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
         mMisspelledUnderlineColor = typedArray.getColor(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
 
-        defStyle = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
+        defStyleAttr = com.android.internal.R.attr.textAppearanceEasyCorrectSuggestion;
         typedArray = context.obtainStyledAttributes(
-                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
         mEasyCorrectUnderlineThickness = typedArray.getDimension(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
         mEasyCorrectUnderlineColor = typedArray.getColor(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineColor, Color.BLACK);
 
-        defStyle = com.android.internal.R.attr.textAppearanceAutoCorrectionSuggestion;
+        defStyleAttr = com.android.internal.R.attr.textAppearanceAutoCorrectionSuggestion;
         typedArray = context.obtainStyledAttributes(
-                null, com.android.internal.R.styleable.SuggestionSpan, defStyle, 0);
+                null, com.android.internal.R.styleable.SuggestionSpan, defStyleAttr, 0);
         mAutoCorrectionUnderlineThickness = typedArray.getDimension(
                 com.android.internal.R.styleable.SuggestionSpan_textUnderlineThickness, 0);
         mAutoCorrectionUnderlineColor = typedArray.getColor(
diff --git a/core/java/android/text/style/UnderlineSpan.java b/core/java/android/text/style/UnderlineSpan.java
index b0cb0e8..80b2427 100644
--- a/core/java/android/text/style/UnderlineSpan.java
+++ b/core/java/android/text/style/UnderlineSpan.java
@@ -40,8 +40,8 @@
     public void writeToParcel(Parcel dest, int flags) {
     }
 
-	@Override
-	public void updateDrawState(TextPaint ds) {
-		ds.setUnderlineText(true);
-	}
+    @Override
+    public void updateDrawState(TextPaint ds) {
+        ds.setUnderlineText(true);
+    }
 }
diff --git a/core/java/android/transition/Recolor.java b/core/java/android/transition/Recolor.java
index 70111d1..1638f67 100644
--- a/core/java/android/transition/Recolor.java
+++ b/core/java/android/transition/Recolor.java
@@ -17,7 +17,6 @@
 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;
@@ -75,8 +74,8 @@
             if (startColor.getColor() != endColor.getColor()) {
                 endColor.setColor(startColor.getColor());
                 changed = true;
-                return ObjectAnimator.ofObject(endBackground, "color",
-                        new ArgbEvaluator(), startColor.getColor(), endColor.getColor());
+                return ObjectAnimator.ofArgb(endBackground, "color", startColor.getColor(),
+                        endColor.getColor());
             }
         }
         if (view instanceof TextView) {
@@ -86,8 +85,7 @@
             if (start != end) {
                 textView.setTextColor(end);
                 changed = true;
-                return ObjectAnimator.ofObject(textView, "textColor",
-                        new ArgbEvaluator(), start, end);
+                return ObjectAnimator.ofArgb(textView, "textColor", start, end);
             }
         }
         return null;
diff --git a/core/java/android/transition/Scene.java b/core/java/android/transition/Scene.java
index e1f1896..4267a65 100644
--- a/core/java/android/transition/Scene.java
+++ b/core/java/android/transition/Scene.java
@@ -34,7 +34,7 @@
     private Context mContext;
     private int mLayoutId = -1;
     private ViewGroup mSceneRoot;
-    private ViewGroup mLayout; // alternative to layoutId
+    private View mLayout; // alternative to layoutId
     Runnable mEnterAction, mExitAction;
 
     /**
@@ -114,6 +114,15 @@
      * @param layout The view hierarchy of this scene, added as a child
      * of sceneRoot when this scene is entered.
      */
+    public Scene(ViewGroup sceneRoot, View layout) {
+        mSceneRoot = sceneRoot;
+        mLayout = layout;
+    }
+
+    /**
+     * @deprecated use {@link #Scene(ViewGroup, View)}.
+     */
+    @Deprecated
     public Scene(ViewGroup sceneRoot, ViewGroup layout) {
         mSceneRoot = sceneRoot;
         mLayout = layout;
diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java
index da9ba5a..c88b4c0 100644
--- a/core/java/android/transition/Transition.java
+++ b/core/java/android/transition/Transition.java
@@ -28,6 +28,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewOverlay;
+import android.view.WindowId;
 import android.widget.ListView;
 import android.widget.Spinner;
 
@@ -496,7 +497,8 @@
                             view = (start != null) ? start.view : null;
                         }
                         if (animator != null) {
-                            AnimationInfo info = new AnimationInfo(view, getName(), infoValues);
+                            AnimationInfo info = new AnimationInfo(view, getName(),
+                                    sceneRoot.getWindowId(), infoValues);
                             runningAnimators.put(animator, info);
                             mAnimators.add(animator);
                         }
@@ -1077,6 +1079,9 @@
         if (view == null) {
             return;
         }
+        if (!isValidTarget(view, view.getId())) {
+            return;
+        }
         boolean isListViewItem = false;
         if (view.getParent() instanceof ListView) {
             isListViewItem = true;
@@ -1109,30 +1114,32 @@
                 }
             }
         }
-        TransitionValues values = new TransitionValues();
-        values.view = view;
-        if (start) {
-            captureStartValues(values);
-        } else {
-            captureEndValues(values);
-        }
-        if (start) {
-            if (!isListViewItem) {
-                mStartValues.viewValues.put(view, values);
-                if (id >= 0) {
-                    mStartValues.idValues.put((int) id, values);
-                }
+        if (view.getParent() instanceof ViewGroup) {
+            TransitionValues values = new TransitionValues();
+            values.view = view;
+            if (start) {
+                captureStartValues(values);
             } else {
-                mStartValues.itemIdValues.put(itemId, values);
+                captureEndValues(values);
             }
-        } else {
-            if (!isListViewItem) {
-                mEndValues.viewValues.put(view, values);
-                if (id >= 0) {
-                    mEndValues.idValues.put((int) id, 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 {
-                mEndValues.itemIdValues.put(itemId, values);
+                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) {
@@ -1194,13 +1201,17 @@
      *
      * @hide
      */
-    public void pause() {
+    public void pause(View sceneRoot) {
         if (!mEnded) {
             ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
             int numOldAnims = runningAnimators.size();
+            WindowId windowId = sceneRoot.getWindowId();
             for (int i = numOldAnims - 1; i >= 0; i--) {
-                Animator anim = runningAnimators.keyAt(i);
-                anim.pause();
+                AnimationInfo info = runningAnimators.valueAt(i);
+                if (info.view != null && windowId.equals(info.windowId)) {
+                    Animator anim = runningAnimators.keyAt(i);
+                    anim.pause();
+                }
             }
             if (mListeners != null && mListeners.size() > 0) {
                 ArrayList<TransitionListener> tmpListeners =
@@ -1221,14 +1232,18 @@
      *
      * @hide
      */
-    public void resume() {
+    public void resume(View sceneRoot) {
         if (mPaused) {
             if (!mEnded) {
                 ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
                 int numOldAnims = runningAnimators.size();
+                WindowId windowId = sceneRoot.getWindowId();
                 for (int i = numOldAnims - 1; i >= 0; i--) {
-                    Animator anim = runningAnimators.keyAt(i);
-                    anim.resume();
+                    AnimationInfo info = runningAnimators.valueAt(i);
+                    if (info.view != null && windowId.equals(info.windowId)) {
+                        Animator anim = runningAnimators.keyAt(i);
+                        anim.resume();
+                    }
                 }
                 if (mListeners != null && mListeners.size() > 0) {
                     ArrayList<TransitionListener> tmpListeners =
@@ -1467,6 +1482,10 @@
         mCanRemoveViews = canRemoveViews;
     }
 
+    public boolean canRemoveViews() {
+        return mCanRemoveViews;
+    }
+
     @Override
     public String toString() {
         return toString("");
@@ -1629,16 +1648,19 @@
      * 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.
+     * @hide
      */
-    private static class AnimationInfo {
-        View view;
+    public static class AnimationInfo {
+        public View view;
         String name;
         TransitionValues values;
+        WindowId windowId;
 
-        AnimationInfo(View view, String name, TransitionValues values) {
+        AnimationInfo(View view, String name, WindowId windowId, TransitionValues values) {
             this.view = view;
             this.name = name;
             this.values = values;
+            this.windowId = windowId;
         }
     }
 
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 9f77d5e..912f2ed 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -20,6 +20,7 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Xml;
 import android.view.InflateException;
@@ -284,25 +285,27 @@
                 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);
+        Scene fromScene = (fromId < 0) ? null: 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);
+        Scene toScene = (toId < 0) ? null : 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 " +
+                if (fromScene == null) {
+                    if (toScene == null) {
+                        throw new RuntimeException("No matching fromScene or toScene " +
                                 "for transition ID " + transitionId);
                     } else {
-                        transitionManager.setTransition(fromScene, toScene, transition);
+                        transitionManager.setTransition(toScene, transition);
                     }
-                } else if (toId >= 0) {
-                    transitionManager.setTransition(toScene, transition);
+                } else if (toScene == null) {
+                    transitionManager.setExitTransition(fromScene, transition);
+                } else {
+                    transitionManager.setTransition(fromScene, toScene, transition);
                 }
             }
         }
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 3bf6790..1614d34 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -67,7 +67,10 @@
 
     private static Transition sDefaultTransition = new AutoTransition();
 
+    private static final String[] EMPTY_STRINGS = new String[0];
+
     ArrayMap<Scene, Transition> mSceneTransitions = new ArrayMap<Scene, Transition>();
+    ArrayMap<Scene, Transition> mExitSceneTransitions = new ArrayMap<Scene, Transition>();
     ArrayMap<Scene, ArrayMap<Scene, Transition>> mScenePairTransitions =
             new ArrayMap<Scene, ArrayMap<Scene, Transition>>();
     private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<Transition>>>>
@@ -116,6 +119,21 @@
     }
 
     /**
+     * Sets a specific transition to occur when the given scene is exited. This
+     * has the lowest priority -- if a Scene-to-Scene transition or
+     * Scene enter transition can be applied, it will.
+     *
+     * @param scene The scene which, when exited, will cause the given
+     * transition to run.
+     * @param transition The transition that will play when the given scene is
+     * exited. A value of null will result in the default behavior of
+     * using the default transition instead.
+     */
+    public void setExitTransition(Scene scene, Transition transition) {
+        mExitSceneTransitions.put(scene, transition);
+    }
+
+    /**
      * Sets a specific transition to occur when the given pair of scenes is
      * exited/entered.
      *
@@ -163,6 +181,9 @@
             }
         }
         transition = mSceneTransitions.get(scene);
+        if (transition == null && sceneRoot != null) {
+            transition = mExitSceneTransitions.get(Scene.getCurrentScene(sceneRoot));
+        }
         return (transition != null) ? transition : sDefaultTransition;
     }
 
@@ -218,6 +239,34 @@
     }
 
     /**
+     * Retrieve the transition to a target defined scene if one has been
+     * associated with this TransitionManager.
+     *
+     * @param toScene Target scene that this transition will move to
+     * @return Transition corresponding to the given toScene or null
+     *         if no association exists in this TransitionManager
+     *
+     * @see #setTransition(Scene, Transition)
+     * @hide
+     */
+    public Transition getEnterTransition(Scene toScene) {
+        return mSceneTransitions.get(toScene);
+    }
+
+    /**
+     * Retrieve the transition from a defined scene to a target named scene if one has been
+     * associated with this TransitionManager.
+     *
+     * @param fromScene Scene that this transition starts from
+     * @return Transition corresponding to the given fromScene or null
+     *         if no association exists in this TransitionManager
+     * @hide
+     */
+    public Transition getExitTransition(Scene fromScene) {
+        return mExitSceneTransitions.get(fromScene);
+    }
+
+    /**
      * This private utility class is used to listen for both OnPreDraw and
      * OnAttachStateChange events. OnPreDraw events are the main ones we care
      * about since that's what triggers the transition to take place.
@@ -253,7 +302,7 @@
             ArrayList<Transition> runningTransitions = getRunningTransitions().get(mSceneRoot);
             if (runningTransitions != null && runningTransitions.size() > 0) {
                 for (Transition runningTransition : runningTransitions) {
-                    runningTransition.resume();
+                    runningTransition.resume(mSceneRoot);
                 }
             }
             mTransition.clearValues(true);
@@ -286,7 +335,7 @@
             mTransition.captureValues(mSceneRoot, false);
             if (previousRunningTransitions != null) {
                 for (Transition runningTransition : previousRunningTransitions) {
-                    runningTransition.resume();
+                    runningTransition.resume(mSceneRoot);
                 }
             }
             mTransition.playTransition(mSceneRoot);
@@ -302,7 +351,7 @@
 
         if (runningTransitions != null && runningTransitions.size() > 0) {
             for (Transition runningTransition : runningTransitions) {
-                runningTransition.pause();
+                runningTransition.pause(sceneRoot);
             }
         }
 
@@ -329,7 +378,6 @@
         // Auto transition if there is no transition declared for the Scene, but there is
         // a root or parent view
         changeScene(scene, getTransition(scene));
-
     }
 
     /**
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 4545e3b..19d6b3d 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -317,21 +317,21 @@
 
     /** @hide */
     @Override
-    public void pause() {
-        super.pause();
+    public void pause(View sceneRoot) {
+        super.pause(sceneRoot);
         int numTransitions = mTransitions.size();
         for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).pause();
+            mTransitions.get(i).pause(sceneRoot);
         }
     }
 
     /** @hide */
     @Override
-    public void resume() {
-        super.resume();
+    public void resume(View sceneRoot) {
+        super.resume(sceneRoot);
         int numTransitions = mTransitions.size();
         for (int i = 0; i < numTransitions; ++i) {
-            mTransitions.get(i).resume();
+            mTransitions.get(i).resume(sceneRoot);
         }
     }
 
diff --git a/core/java/android/util/EventLogTags.java b/core/java/android/util/EventLogTags.java
index 8c18417..f4ce4fd 100644
--- a/core/java/android/util/EventLogTags.java
+++ b/core/java/android/util/EventLogTags.java
@@ -16,14 +16,8 @@
 
 package android.util;
 
-import android.util.Log;
-
 import java.io.BufferedReader;
-import java.io.FileReader;
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * @deprecated This class is no longer functional.
diff --git a/core/java/android/util/LocalLog.java b/core/java/android/util/LocalLog.java
index 641d1b4..eeb6d58 100644
--- a/core/java/android/util/LocalLog.java
+++ b/core/java/android/util/LocalLog.java
@@ -20,7 +20,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.Iterator;
 import java.util.LinkedList;
 
diff --git a/core/java/android/util/LongArray.java b/core/java/android/util/LongArray.java
new file mode 100644
index 0000000..d5f15f0
--- /dev/null
+++ b/core/java/android/util/LongArray.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 android.util;
+
+import com.android.internal.util.ArrayUtils;
+
+/**
+ * Implements a growing array of long primitives.
+ *
+ * @hide
+ */
+public class LongArray implements Cloneable {
+    private static final int MIN_CAPACITY_INCREMENT = 12;
+
+    private long[] mValues;
+    private int mSize;
+
+    /**
+     * Creates an empty LongArray with the default initial capacity.
+     */
+    public LongArray() {
+        this(10);
+    }
+
+    /**
+     * Creates an empty LongArray with the specified initial capacity.
+     */
+    public LongArray(int initialCapacity) {
+        if (initialCapacity == 0) {
+            mValues = ContainerHelpers.EMPTY_LONGS;
+        } else {
+            initialCapacity = ArrayUtils.idealLongArraySize(initialCapacity);
+            mValues = new long[initialCapacity];
+        }
+        mSize = 0;
+    }
+
+    /**
+     * Appends the specified value to the end of this array.
+     */
+    public void add(long value) {
+        add(mSize, value);
+    }
+
+    /**
+     * Inserts a value at the specified position in this array.
+     *
+     * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt; size()
+     */
+    public void add(int index, long value) {
+        if (index < 0 || index > mSize) {
+            throw new IndexOutOfBoundsException();
+        }
+
+        ensureCapacity(1);
+
+        if (mSize - index != 0) {
+            System.arraycopy(mValues, index, mValues, index + 1, mSize - index);
+        }
+
+        mValues[index] = value;
+        mSize++;
+    }
+
+    /**
+     * Adds the values in the specified array to this array.
+     */
+    public void addAll(LongArray values) {
+        final int count = values.mSize;
+        ensureCapacity(count);
+
+        System.arraycopy(values.mValues, 0, mValues, mSize, count);
+        mSize += count;
+    }
+
+    /**
+     * Ensures capacity to append at least <code>count</code> values.
+     */
+    private void ensureCapacity(int count) {
+        final int currentSize = mSize;
+        final int minCapacity = currentSize + count;
+        if (minCapacity >= mValues.length) {
+            final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ?
+                    MIN_CAPACITY_INCREMENT : currentSize >> 1);
+            final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity;
+            final long[] newValues = new long[ArrayUtils.idealLongArraySize(newCapacity)];
+            System.arraycopy(mValues, 0, newValues, 0, currentSize);
+            mValues = newValues;
+        }
+    }
+
+    /**
+     * Removes all values from this array.
+     */
+    public void clear() {
+        mSize = 0;
+    }
+
+    @Override
+    public LongArray clone() {
+        LongArray clone = null;
+        try {
+            clone = (LongArray) super.clone();
+            clone.mValues = mValues.clone();
+        } catch (CloneNotSupportedException cnse) {
+            /* ignore */
+        }
+        return clone;
+    }
+
+    /**
+     * Returns the value at the specified position in this array.
+     */
+    public long get(int index) {
+        if (index >= mSize) {
+            throw new ArrayIndexOutOfBoundsException(mSize, index);
+        }
+        return mValues[index];
+    }
+
+    /**
+     * Returns the index of the first occurrence of the specified value in this
+     * array, or -1 if this array does not contain the value.
+     */
+    public int indexOf(long value) {
+        final int n = mSize;
+        for (int i = 0; i < n; i++) {
+            if (mValues[i] == value) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Removes the value at the specified index from this array.
+     */
+    public void remove(int index) {
+        if (index >= mSize) {
+            throw new ArrayIndexOutOfBoundsException(mSize, index);
+        }
+        System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1);
+        mSize--;
+    }
+
+    /**
+     * Returns the number of values in this array.
+     */
+    public int size() {
+        return mSize;
+    }
+}
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 6654899..b8073dd 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -18,8 +18,6 @@
 
 import com.android.internal.util.ArrayUtils;
 
-import java.util.Arrays;
-
 /**
  * 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 memory efficient than using a
diff --git a/core/java/android/util/LruCache.java b/core/java/android/util/LruCache.java
index dd504c1..4015488 100644
--- a/core/java/android/util/LruCache.java
+++ b/core/java/android/util/LruCache.java
@@ -87,9 +87,8 @@
 
     /**
      * Sets the size of the cache.
-     * @param maxSize The new maximum size.
      *
-     * @hide
+     * @param maxSize The new maximum size.
      */
     public void resize(int maxSize) {
         if (maxSize <= 0) {
diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java
index 70795bb..b25d80f 100644
--- a/core/java/android/util/Slog.java
+++ b/core/java/android/util/Slog.java
@@ -16,11 +16,6 @@
 
 package android.util;
 
-import com.android.internal.os.RuntimeInit;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
 /**
  * @hide
  */
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index 905dcb0..f59ef0f6d 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -115,6 +115,13 @@
         }
     }
 
+    /** @hide */
+    public void removeAt(int index) {
+        System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+        System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1));
+        mSize--;
+    }
+
     /**
      * Adds a mapping from the specified key to the specified value,
      * replacing the previous mapping from the specified key if there
@@ -191,6 +198,11 @@
         return mValues[index];
     }
 
+    /** @hide */
+    public void setValueAt(int index, boolean value) {
+        mValues[index] = value;
+    }
+
     /**
      * Returns the index for which {@link #keyAt} would return the
      * specified key, or a negative number if the specified
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 41d3700..abae068 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -18,13 +18,14 @@
 
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
-import android.util.SparseLongArray;
+import android.util.LongSparseArray;
 import android.view.View.AttachInfo;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -36,8 +37,11 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Queue;
 
 /**
  * Class for managing accessibility interactions initiated from the system
@@ -48,6 +52,8 @@
  */
 final class AccessibilityInteractionController {
 
+    private static final boolean ENFORCE_NODE_TREE_CONSISTENT = Build.IS_DEBUGGABLE;
+
     private final ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
         new ArrayList<AccessibilityNodeInfo>();
 
@@ -138,7 +144,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId == AccessibilityNodeInfo.UNDEFINED) {
+            if (accessibilityViewId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                 root = mViewRootImpl.mView;
             } else {
                 root = findViewByAccessibilityId(accessibilityViewId);
@@ -210,7 +216,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
+            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -290,7 +296,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
+            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -298,9 +304,14 @@
             if (root != null && isShown(root)) {
                 AccessibilityNodeProvider provider = root.getAccessibilityNodeProvider();
                 if (provider != null) {
-                    infos = provider.findAccessibilityNodeInfosByText(text,
-                            virtualDescendantId);
-                } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED) {
+                    if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                        infos = provider.findAccessibilityNodeInfosByText(text,
+                                virtualDescendantId);
+                    } else {
+                        infos = provider.findAccessibilityNodeInfosByText(text,
+                                AccessibilityNodeProvider.HOST_VIEW_ID);
+                    }
+                } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                     ArrayList<View> foundViews = mTempArrayList;
                     foundViews.clear();
                     root.findViewsWithText(foundViews, text, View.FIND_VIEWS_WITH_TEXT
@@ -317,7 +328,7 @@
                                 if (provider != null) {
                                     List<AccessibilityNodeInfo> infosFromProvider =
                                         provider.findAccessibilityNodeInfosByText(text,
-                                                AccessibilityNodeInfo.UNDEFINED);
+                                                AccessibilityNodeProvider.HOST_VIEW_ID);
                                     if (infosFromProvider != null) {
                                         infos.addAll(infosFromProvider);
                                     }
@@ -392,7 +403,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
+            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -418,7 +429,7 @@
                                 focused = AccessibilityNodeInfo.obtain(
                                         mViewRootImpl.mAccessibilityFocusedVirtualView);
                             }
-                        } else if (virtualDescendantId == View.NO_ID) {
+                        } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                             focused = host.createAccessibilityNodeInfo();
                         }
                     } break;
@@ -501,7 +512,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View root = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
+            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                 root = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 root = mViewRootImpl.mView;
@@ -577,7 +588,7 @@
             }
             mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
             View target = null;
-            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
+            if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                 target = findViewByAccessibilityId(accessibilityViewId);
             } else {
                 target = mViewRootImpl.mView;
@@ -585,9 +596,14 @@
             if (target != null && isShown(target)) {
                 AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
                 if (provider != null) {
-                    succeeded = provider.performAction(virtualDescendantId, action,
-                            arguments);
-                } else if (virtualDescendantId == View.NO_ID) {
+                    if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                        succeeded = provider.performAction(virtualDescendantId, action,
+                                arguments);
+                    } else {
+                        succeeded = provider.performAction(AccessibilityNodeProvider.HOST_VIEW_ID,
+                                action, arguments);
+                    }
+                } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                     succeeded = target.performAccessibilityAction(action, arguments);
                 }
             }
@@ -735,6 +751,85 @@
                     }
                 }
             }
+            if (ENFORCE_NODE_TREE_CONSISTENT) {
+                enforceNodeTreeConsistent(outInfos);
+            }
+        }
+
+        private void enforceNodeTreeConsistent(List<AccessibilityNodeInfo> nodes) {
+            LongSparseArray<AccessibilityNodeInfo> nodeMap =
+                    new LongSparseArray<AccessibilityNodeInfo>();
+            final int nodeCount = nodes.size();
+            for (int i = 0; i < nodeCount; i++) {
+                AccessibilityNodeInfo node = nodes.get(i);
+                nodeMap.put(node.getSourceNodeId(), node);
+            }
+
+            // If the nodes are a tree it does not matter from
+            // which node we start to search for the root.
+            AccessibilityNodeInfo root = nodeMap.valueAt(0);
+            AccessibilityNodeInfo parent = root;
+            while (parent != null) {
+                root = parent;
+                parent = nodeMap.get(parent.getParentNodeId());
+            }
+
+            // Traverse the tree and do some checks.
+            AccessibilityNodeInfo accessFocus = null;
+            AccessibilityNodeInfo inputFocus = null;
+            HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>();
+            Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
+            fringe.add(root);
+
+            while (!fringe.isEmpty()) {
+                AccessibilityNodeInfo current = fringe.poll();
+
+                // Check for duplicates
+                if (!seen.add(current)) {
+                    throw new IllegalStateException("Duplicate node: "
+                            + current + " in window:"
+                            + mViewRootImpl.mAttachInfo.mAccessibilityWindowId);
+                }
+
+                // Check for one accessibility focus.
+                if (current.isAccessibilityFocused()) {
+                    if (accessFocus != null) {
+                        throw new IllegalStateException("Duplicate accessibility focus:"
+                                + current
+                                + " in window:" + mViewRootImpl.mAttachInfo.mAccessibilityWindowId);
+                    } else {
+                        accessFocus = current;
+                    }
+                }
+
+                // Check for one input focus.
+                if (current.isFocused()) {
+                    if (inputFocus != null) {
+                        throw new IllegalStateException("Duplicate input focus: "
+                            + current + " in window:"
+                            + mViewRootImpl.mAttachInfo.mAccessibilityWindowId);
+                    } else {
+                        inputFocus = current;
+                    }
+                }
+
+                final int childCount = current.getChildCount();
+                for (int j = 0; j < childCount; j++) {
+                    final long childId = current.getChildId(j);
+                    final AccessibilityNodeInfo child = nodeMap.get(childId);
+                    if (child != null) {
+                        fringe.add(child);
+                    }
+                }
+            }
+
+            // Check for disconnected nodes.
+            for (int j = nodeMap.size() - 1; j >= 0; j--) {
+                AccessibilityNodeInfo info = nodeMap.valueAt(j);
+                if (!seen.contains(info)) {
+                    throw new IllegalStateException("Disconnected node: " + info);
+                }
+            }
         }
 
         private void prefetchPredecessorsOfRealNode(View view,
@@ -775,7 +870,7 @@
                                 info = child.createAccessibilityNodeInfo();
                             } else {
                                 info = provider.createAccessibilityNodeInfo(
-                                        AccessibilityNodeInfo.UNDEFINED);
+                                        AccessibilityNodeProvider.HOST_VIEW_ID);
                             }
                             if (info != null) {
                                 outInfos.add(info);
@@ -815,7 +910,7 @@
                             }
                         } else {
                             AccessibilityNodeInfo info = provider.createAccessibilityNodeInfo(
-                                   AccessibilityNodeInfo.UNDEFINED);
+                                   AccessibilityNodeProvider.HOST_VIEW_ID);
                             if (info != null) {
                                 outInfos.add(info);
                                 addedChildren.put(child, info);
@@ -846,16 +941,22 @@
                 List<AccessibilityNodeInfo> outInfos) {
             long parentNodeId = root.getParentNodeId();
             int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
-            while (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
+            while (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
                 if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                     return;
                 }
                 final int virtualDescendantId =
                     AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
-                if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED
+                if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
                         || accessibilityViewId == providerHost.getAccessibilityViewId()) {
-                    AccessibilityNodeInfo parent = provider.createAccessibilityNodeInfo(
-                            virtualDescendantId);
+                    final AccessibilityNodeInfo parent;
+                    if (virtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                        parent = provider.createAccessibilityNodeInfo(
+                                virtualDescendantId);
+                    } else {
+                        parent= provider.createAccessibilityNodeInfo(
+                                AccessibilityNodeProvider.HOST_VIEW_ID);
+                    }
                     if (parent != null) {
                         outInfos.add(parent);
                     }
@@ -876,18 +977,22 @@
                 AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
             final int parentVirtualDescendantId =
                 AccessibilityNodeInfo.getVirtualDescendantId(parentNodeId);
-            if (parentVirtualDescendantId != AccessibilityNodeInfo.UNDEFINED
+            if (parentVirtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
                     || parentAccessibilityViewId == providerHost.getAccessibilityViewId()) {
-                AccessibilityNodeInfo parent =
-                    provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
+                final AccessibilityNodeInfo parent;
+                if (parentAccessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                    parent = provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
+                } else {
+                    parent = provider.createAccessibilityNodeInfo(
+                            AccessibilityNodeProvider.HOST_VIEW_ID);
+                }
                 if (parent != null) {
-                    SparseLongArray childNodeIds = parent.getChildNodeIds();
-                    final int childCount = childNodeIds.size();
+                    final int childCount = parent.getChildCount();
                     for (int i = 0; i < childCount; i++) {
                         if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                             return;
                         }
-                        final long childNodeId = childNodeIds.get(i);
+                        final long childNodeId = parent.getChildId(i);
                         if (childNodeId != current.getSourceNodeId()) {
                             final int childVirtualDescendantId =
                                 AccessibilityNodeInfo.getVirtualDescendantId(childNodeId);
@@ -906,14 +1011,13 @@
 
         private void prefetchDescendantsOfVirtualNode(AccessibilityNodeInfo root,
                 AccessibilityNodeProvider provider, List<AccessibilityNodeInfo> outInfos) {
-            SparseLongArray childNodeIds = root.getChildNodeIds();
             final int initialOutInfosSize = outInfos.size();
-            final int childCount = childNodeIds.size();
+            final int childCount = root.getChildCount();
             for (int i = 0; i < childCount; i++) {
                 if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
                     return;
                 }
-                final long childNodeId = childNodeIds.get(i);
+                final long childNodeId = root.getChildId(i);
                 AccessibilityNodeInfo child = provider.createAccessibilityNodeInfo(
                         AccessibilityNodeInfo.getVirtualDescendantId(childNodeId));
                 if (child != null) {
diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java
index 17ce4f6..e59937d 100644
--- a/core/java/android/view/AccessibilityIterators.java
+++ b/core/java/android/view/AccessibilityIterators.java
@@ -17,8 +17,6 @@
 package android.view;
 
 import android.content.ComponentCallbacks;
-import android.content.Context;
-import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 
 import java.text.BreakIterator;
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index 6c733f9..0afbde9 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -20,14 +20,12 @@
 import android.content.ContextWrapper;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.os.Build;
 
 /**
  * A ContextWrapper that allows you to modify the theme from what is in the 
  * wrapped context. 
  */
 public class ContextThemeWrapper extends ContextWrapper {
-    private Context mBase;
     private int mThemeResource;
     private Resources.Theme mTheme;
     private LayoutInflater mInflater;
@@ -40,13 +38,11 @@
     
     public ContextThemeWrapper(Context base, int themeres) {
         super(base);
-        mBase = base;
         mThemeResource = themeres;
     }
 
     @Override protected void attachBaseContext(Context newBase) {
         super.attachBaseContext(newBase);
-        mBase = newBase;
     }
 
     /**
@@ -110,11 +106,11 @@
     @Override public Object getSystemService(String name) {
         if (LAYOUT_INFLATER_SERVICE.equals(name)) {
             if (mInflater == null) {
-                mInflater = LayoutInflater.from(mBase).cloneInContext(this);
+                mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this);
             }
             return mInflater;
         }
-        return mBase.getSystemService(name);
+        return getBaseContext().getSystemService(name);
     }
     
     /**
@@ -136,7 +132,7 @@
         final boolean first = mTheme == null;
         if (first) {
             mTheme = getResources().newTheme();
-            Resources.Theme theme = mBase.getTheme();
+            Resources.Theme theme = getBaseContext().getTheme();
             if (theme != null) {
                 mTheme.setTo(theme);
             }
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 7d310a2..d3f63b4 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -528,6 +528,7 @@
      * 90 degrees clockwise and thus the returned value here will be
      * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
      */
+    @Surface.Rotation
     public int getRotation() {
         synchronized (this) {
             updateDisplayInfoLocked();
@@ -540,6 +541,7 @@
      * @return orientation of this display.
      */
     @Deprecated
+    @Surface.Rotation
     public int getOrientation() {
         return getRotation();
     }
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 8944207..7fd7b83 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -20,7 +20,6 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Process;
 import android.util.DisplayMetrics;
 
 import libcore.util.Objects;
@@ -144,6 +143,7 @@
      * more than one physical display.
      * </p>
      */
+    @Surface.Rotation
     public int rotation;
 
     /**
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index 43fd628..ed52803 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,671 +16,10 @@
 
 package android.view;
 
-import android.graphics.Matrix;
-
-/**
- * <p>A display list records a series of graphics related operations and can replay
- * them later. Display lists are usually built by recording operations on a
- * {@link HardwareCanvas}. Replaying the operations from a display list avoids
- * executing application code on every frame, and is thus much more efficient.</p>
- *
- * <p>Display lists are used internally for all views by default, and are not
- * typically used directly. One reason to consider using a display is a custom
- * {@link View} implementation that needs to issue a large number of drawing commands.
- * When the view invalidates, all the drawing commands must be reissued, even if
- * large portions of the drawing command stream stay the same frame to frame, which
- * can become a performance bottleneck. To solve this issue, a custom View might split
- * its content into several display lists. A display list is updated only when its
- * content, and only its content, needs to be updated.</p>
- *
- * <p>A text editor might for instance store each paragraph into its own display list.
- * Thus when the user inserts or removes characters, only the display list of the
- * affected paragraph needs to be recorded again.</p>
- *
- * <h3>Hardware acceleration</h3>
- * <p>Display lists can only be replayed using a {@link HardwareCanvas}. They are not
- * supported in software. Always make sure that the {@link android.graphics.Canvas}
- * you are using to render a display list is hardware accelerated using
- * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
- *
- * <h3>Creating a display list</h3>
- * <pre class="prettyprint">
- *     HardwareRenderer renderer = myView.getHardwareRenderer();
- *     if (renderer != null) {
- *         DisplayList displayList = renderer.createDisplayList();
- *         HardwareCanvas canvas = displayList.start(width, height);
- *         try {
- *             // Draw onto the canvas
- *             // For instance: canvas.drawBitmap(...);
- *         } finally {
- *             displayList.end();
- *         }
- *     }
- * </pre>
- *
- * <h3>Rendering a display list on a View</h3>
- * <pre class="prettyprint">
- *     protected void onDraw(Canvas canvas) {
- *         if (canvas.isHardwareAccelerated()) {
- *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
- *             hardwareCanvas.drawDisplayList(mDisplayList);
- *         }
- *     }
- * </pre>
- *
- * <h3>Releasing resources</h3>
- * <p>This step is not mandatory but recommended if you want to release resources
- * held by a display list as soon as possible.</p>
- * <pre class="prettyprint">
- *     // Mark this display list invalid, it cannot be used for drawing anymore,
- *     // and release resources held by this display list
- *     displayList.clear();
- * </pre>
- *
- * <h3>Properties</h3>
- * <p>In addition, a display list offers several properties, such as
- * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all
- * the drawing commands recorded within. For instance, these properties can be used
- * to move around a large number of images without re-issuing all the individual
- * <code>drawBitmap()</code> calls.</p>
- *
- * <pre class="prettyprint">
- *     private void createDisplayList() {
- *         HardwareRenderer renderer = getHardwareRenderer();
- *         if (renderer != null) {
- *             mDisplayList = renderer.createDisplayList();
- *             HardwareCanvas canvas = mDisplayList.start(width, height);
- *             try {
- *                 for (Bitmap b : mBitmaps) {
- *                     canvas.drawBitmap(b, 0.0f, 0.0f, null);
- *                     canvas.translate(0.0f, b.getHeight());
- *                 }
- *             } finally {
- *                 displayList.end();
- *             }
- *         }
- *     }
- *
- *     protected void onDraw(Canvas canvas) {
- *         if (canvas.isHardwareAccelerated()) {
- *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
- *             hardwareCanvas.drawDisplayList(mDisplayList);
- *         }
- *     }
- *
- *     private void moveContentBy(int x) {
- *          // This will move all the bitmaps recorded inside the display list
- *          // by x pixels to the right and redraw this view. All the commands
- *          // recorded in createDisplayList() won't be re-issued, only onDraw()
- *          // will be invoked and will execute very quickly
- *          mDisplayList.offsetLeftAndRight(x);
- *          invalidate();
- *     }
- * </pre>
- *
- * <h3>Threading</h3>
- * <p>Display lists must be created on and manipulated from the UI thread only.</p>
- *
- * @hide
+/** TODO: Remove once frameworks/webview is updated
+ *  @hide
  */
-public abstract class DisplayList {
-    private boolean mDirty;
-
-    /**
-     * Flag used when calling
-     * {@link HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)} 
-     * When this flag is set, draw operations lying outside of the bounds of the
-     * display list will be culled early. It is recommeneded to always set this
-     * flag.
-     *
-     * @hide
-     */
-    public static final int FLAG_CLIP_CHILDREN = 0x1;
-
-    // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h
-
-    /**
-     * Indicates that the display list is done drawing.
-     * 
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
-     *
-     * @hide
-     */
+public class DisplayList {
+    /** @hide */
     public static final int STATUS_DONE = 0x0;
-
-    /**
-     * Indicates that the display list needs another drawing pass.
-     * 
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
-     *
-     * @hide
-     */
-    public static final int STATUS_DRAW = 0x1;
-
-    /**
-     * Indicates that the display list needs to re-execute its GL functors.
-     * 
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int) 
-     * @see HardwareCanvas#callDrawGLFunction(int)
-     *
-     * @hide
-     */
-    public static final int STATUS_INVOKE = 0x2;
-
-    /**
-     * Indicates that the display list performed GL drawing operations.
-     *
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
-     *
-     * @hide
-     */
-    public static final int STATUS_DREW = 0x4;
-
-    /**
-     * Starts recording the display list. All operations performed on the
-     * returned canvas are recorded and stored in this display list.
-     *
-     * Calling this method will mark the display list invalid until
-     * {@link #end()} is called. Only valid display lists can be replayed.
-     *
-     * @param width The width of the display list's viewport
-     * @param height The height of the display list's viewport
-     *
-     * @return A canvas to record drawing operations.
-     *
-     * @see #end()
-     * @see #isValid()
-     */
-    public abstract HardwareCanvas start(int width, int height);
-
-    /**
-     * Ends the recording for this display list. A display list cannot be
-     * replayed if recording is not finished. Calling this method marks
-     * the display list valid and {@link #isValid()} will return true.
-     *
-     * @see #start(int, int)
-     * @see #isValid()
-     */
-    public abstract void end();
-
-    /**
-     * Clears resources held onto by this display list. After calling this method
-     * {@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.
-     *
-     * @see #isDirty()
-     * @see #clear()
-     *
-     * @hide
-     */
-    public void markDirty() {
-        mDirty = true;
-    }
-
-    /**
-     * Removes the dirty flag. This method can be used to cancel a cleanup
-     * previously scheduled by setting the dirty flag.
-     *
-     * @see #isDirty()
-     * @see #clear()
-     *
-     * @hide
-     */
-    protected void clearDirty() {
-        mDirty = false;
-    }
-
-    /**
-     * Indicates whether the display list is dirty.
-     *
-     * @see #markDirty()
-     * @see #clear()
-     *
-     * @hide
-     */
-    public boolean isDirty() {
-        return mDirty;
-    }
-
-    /**
-     * Returns whether the display list is currently usable. If this returns false,
-     * the display list should be re-recorded prior to replaying it.
-     *
-     * @return boolean true if the display list is able to be replayed, false otherwise.
-     */
-    public abstract boolean isValid();
-
-    /**
-     * Return the amount of memory used by this display list.
-     * 
-     * @return The size of this display list in bytes
-     *
-     * @hide
-     */
-    public abstract int getSize();
-
-    ///////////////////////////////////////////////////////////////////////////
-    // DisplayList Property Setters
-    ///////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Set the caching property on the display list, which indicates whether the display list
-     * holds a layer. Layer display lists should avoid creating an alpha layer, since alpha is
-     * handled in the drawLayer operation directly (and more efficiently).
-     *
-     * @param caching true if the display list represents a hardware layer, false otherwise.
-     *
-     * @hide
-     */
-    public abstract void setCaching(boolean caching);
-
-    /**
-     * Set whether the display list should clip itself to its bounds. This property is controlled by
-     * the view's parent.
-     *
-     * @param clipToBounds true if the display list should clip to its bounds
-     */
-    public abstract void setClipToBounds(boolean clipToBounds);
-
-    /**
-     * Set the static matrix on the display list. The specified matrix is combined with other
-     * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
-     *
-     * @param matrix A transform matrix to apply to this display list
-     *
-     * @see #getMatrix(android.graphics.Matrix)
-     * @see #getMatrix()
-     */
-    public abstract void setMatrix(Matrix matrix);
-
-    /**
-     * Returns the static matrix set on this display list.
-     *
-     * @return A new {@link Matrix} instance populated with this display list's static
-     *         matrix
-     *
-     * @see #getMatrix(android.graphics.Matrix)
-     * @see #setMatrix(android.graphics.Matrix)
-     */
-    public Matrix getMatrix() {
-        return getMatrix(new Matrix());
-    }
-
-    /**
-     * Copies this display list's static matrix into the specified matrix.
-     *
-     * @param matrix The {@link Matrix} instance in which to copy this display
-     *               list's static matrix. Cannot be null
-     *
-     * @return The <code>matrix</code> parameter, for convenience
-     *
-     * @see #getMatrix()
-     * @see #setMatrix(android.graphics.Matrix)
-     */
-    public abstract Matrix getMatrix(Matrix matrix);
-
-    /**
-     * Set the Animation matrix on the display list. This matrix exists if an Animation is
-     * currently playing on a View, and is set on the display list during at draw() time. When
-     * the Animation finishes, the matrix should be cleared by sending <code>null</code>
-     * for the matrix parameter.
-     *
-     * @param matrix The matrix, null indicates that the matrix should be cleared.
-     *
-     * @hide
-     */
-    public abstract void setAnimationMatrix(Matrix matrix);
-
-    /**
-     * Sets the translucency level for the display list.
-     *
-     * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
-     *
-     * @see View#setAlpha(float)
-     * @see #getAlpha()
-     */
-    public abstract void setAlpha(float alpha);
-
-    /**
-     * Returns the translucency level of this display list.
-     *
-     * @return A value between 0.0f and 1.0f
-     *
-     * @see #setAlpha(float)
-     */
-    public abstract float getAlpha();
-
-    /**
-     * Sets whether the display list renders content which overlaps. Non-overlapping rendering
-     * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
-     * display lists consider they do not have overlapping content.
-     *
-     * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
-     *                                true otherwise.
-     *
-     * @see android.view.View#hasOverlappingRendering()
-     * @see #hasOverlappingRendering()
-     */
-    public abstract void setHasOverlappingRendering(boolean hasOverlappingRendering);
-
-    /**
-     * Indicates whether the content of this display list overlaps.
-     *
-     * @return True if this display list renders content which overlaps, false otherwise.
-     *
-     * @see #setHasOverlappingRendering(boolean)
-     */
-    public abstract boolean hasOverlappingRendering();
-
-    /**
-     * Sets the translation value for the display list on the X axis
-     *
-     * @param translationX The X axis translation value of the display list, in pixels
-     *
-     * @see View#setTranslationX(float)
-     * @see #getTranslationX()
-     */
-    public abstract void setTranslationX(float translationX);
-
-    /**
-     * Returns the translation value for this display list on the X axis, in pixels.
-     *
-     * @see #setTranslationX(float)
-     */
-    public abstract float getTranslationX();
-
-    /**
-     * Sets the translation value for the display list on the Y axis
-     *
-     * @param translationY The Y axis translation value of the display list, in pixels
-     *
-     * @see View#setTranslationY(float)
-     * @see #getTranslationY()
-     */
-    public abstract void setTranslationY(float translationY);
-
-    /**
-     * Returns the translation value for this display list on the Y axis, in pixels.
-     *
-     * @see #setTranslationY(float)
-     */
-    public abstract float getTranslationY();
-
-    /**
-     * Sets the rotation value for the display list around the Z axis
-     *
-     * @param rotation The rotation value of the display list, in degrees
-     *
-     * @see View#setRotation(float)
-     * @see #getRotation()
-     */
-    public abstract void setRotation(float rotation);
-
-    /**
-     * Returns the rotation value for this display list around the Z axis, in degrees.
-     *
-     * @see #setRotation(float)
-     */
-    public abstract float getRotation();
-
-    /**
-     * Sets the rotation value for the display list around the X axis
-     *
-     * @param rotationX The rotation value of the display list, in degrees
-     *
-     * @see View#setRotationX(float)
-     * @see #getRotationX()
-     */
-    public abstract void setRotationX(float rotationX);
-
-    /**
-     * Returns the rotation value for this display list around the X axis, in degrees.
-     *
-     * @see #setRotationX(float)
-     */
-    public abstract float getRotationX();
-
-    /**
-     * Sets the rotation value for the display list around the Y axis
-     *
-     * @param rotationY The rotation value of the display list, in degrees
-     *
-     * @see View#setRotationY(float)
-     * @see #getRotationY()
-     */
-    public abstract void setRotationY(float rotationY);
-
-    /**
-     * Returns the rotation value for this display list around the Y axis, in degrees.
-     *
-     * @see #setRotationY(float)
-     */
-    public abstract float getRotationY();
-
-    /**
-     * Sets the scale value for the display list on the X axis
-     *
-     * @param scaleX The scale value of the display list
-     *
-     * @see View#setScaleX(float)
-     * @see #getScaleX()
-     */
-    public abstract void setScaleX(float scaleX);
-
-    /**
-     * Returns the scale value for this display list on the X axis.
-     *
-     * @see #setScaleX(float)
-     */
-    public abstract float getScaleX();
-
-    /**
-     * Sets the scale value for the display list on the Y axis
-     *
-     * @param scaleY The scale value of the display list
-     *
-     * @see View#setScaleY(float)
-     * @see #getScaleY()
-     */
-    public abstract void setScaleY(float scaleY);
-
-    /**
-     * Returns the scale value for this display list on the Y axis.
-     *
-     * @see #setScaleY(float)
-     */
-    public abstract float getScaleY();
-
-    /**
-     * Sets all of the transform-related values of the display list
-     *
-     * @param alpha The alpha value of the display list
-     * @param translationX The translationX value of the display list
-     * @param translationY The translationY value of the display list
-     * @param rotation The rotation value of the display list
-     * @param rotationX The rotationX value of the display list
-     * @param rotationY The rotationY value of the display list
-     * @param scaleX The scaleX value of the display list
-     * @param scaleY The scaleY value of the display list
-     *
-     * @hide
-     */
-    public abstract void setTransformationInfo(float alpha, float translationX, float translationY,
-            float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
-
-    /**
-     * Sets the pivot value for the display list on the X axis
-     *
-     * @param pivotX The pivot value of the display list on the X axis, in pixels
-     *
-     * @see View#setPivotX(float)
-     * @see #getPivotX()
-     */
-    public abstract void setPivotX(float pivotX);
-
-    /**
-     * Returns the pivot value for this display list on the X axis, in pixels.
-     *
-     * @see #setPivotX(float)
-     */
-    public abstract float getPivotX();
-
-    /**
-     * Sets the pivot value for the display list on the Y axis
-     *
-     * @param pivotY The pivot value of the display list on the Y axis, in pixels
-     *
-     * @see View#setPivotY(float)
-     * @see #getPivotY()
-     */
-    public abstract void setPivotY(float pivotY);
-
-    /**
-     * Returns the pivot value for this display list on the Y axis, in pixels.
-     *
-     * @see #setPivotY(float)
-     */
-    public abstract float getPivotY();
-
-    /**
-     * Sets the camera distance for the display list. Refer to
-     * {@link View#setCameraDistance(float)} for more information on how to
-     * use this property.
-     *
-     * @param distance The distance in Z of the camera of the display list
-     *
-     * @see View#setCameraDistance(float)
-     * @see #getCameraDistance()
-     */
-    public abstract void setCameraDistance(float distance);
-
-    /**
-     * Returns the distance in Z of the camera of the display list.
-     *
-     * @see #setCameraDistance(float)
-     */
-    public abstract float getCameraDistance();
-
-    /**
-     * Sets the left position for the display list.
-     *
-     * @param left The left position, in pixels, of the display list
-     *
-     * @see View#setLeft(int)
-     * @see #getLeft()
-     */
-    public abstract void setLeft(int left);
-
-    /**
-     * Returns the left position for the display list in pixels.
-     *
-     * @see #setLeft(int)
-     */
-    public abstract float getLeft();
-
-    /**
-     * Sets the top position for the display list.
-     *
-     * @param top The top position, in pixels, of the display list
-     *
-     * @see View#setTop(int)
-     * @see #getTop()
-     */
-    public abstract void setTop(int top);
-
-    /**
-     * Returns the top position for the display list in pixels.
-     *
-     * @see #setTop(int)
-     */
-    public abstract float getTop();
-
-    /**
-     * Sets the right position for the display list.
-     *
-     * @param right The right position, in pixels, of the display list
-     *
-     * @see View#setRight(int)
-     * @see #getRight()
-     */
-    public abstract void setRight(int right);
-
-    /**
-     * Returns the right position for the display list in pixels.
-     *
-     * @see #setRight(int)
-     */
-    public abstract float getRight();
-
-    /**
-     * Sets the bottom position for the display list.
-     *
-     * @param bottom The bottom position, in pixels, of the display list
-     *
-     * @see View#setBottom(int)
-     * @see #getBottom()
-     */
-    public abstract void setBottom(int bottom);
-
-    /**
-     * Returns the bottom position for the display list in pixels.
-     *
-     * @see #setBottom(int)
-     */
-    public abstract float getBottom();
-
-    /**
-     * Sets the left and top positions for the display list
-     *
-     * @param left The left position of the display list, in pixels
-     * @param top The top position of the display list, in pixels
-     * @param right The right position of the display list, in pixels
-     * @param bottom The bottom position of the display list, in pixels
-     *
-     * @see View#setLeft(int)
-     * @see View#setTop(int)
-     * @see View#setRight(int)
-     * @see View#setBottom(int)
-     */
-    public abstract void setLeftTopRightBottom(int left, int top, int right, int bottom);
-
-    /**
-     * Offsets the left and right positions for the display list
-     *
-     * @param offset The amount that the left and right positions of the display
-     *               list are offset, in pixels
-     *
-     * @see View#offsetLeftAndRight(int)
-     */
-    public abstract void offsetLeftAndRight(float offset);
-
-    /**
-     * Offsets the top and bottom values for the display list
-     *
-     * @param offset The amount that the top and bottom positions of the display
-     *               list are offset, in pixels
-     *
-     * @see View#offsetTopAndBottom(int)
-     */
-    public abstract void offsetTopAndBottom(float offset);
 }
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index d533060..c274fc4 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.ColorFilter;
 import android.graphics.DrawFilter;
 import android.graphics.Matrix;
 import android.graphics.NinePatch;
@@ -31,7 +30,6 @@
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.graphics.Shader;
-import android.graphics.SurfaceTexture;
 import android.graphics.TemporaryBuffer;
 import android.text.GraphicsOperations;
 import android.text.SpannableString;
@@ -46,10 +44,9 @@
     private static final int MODIFIER_NONE = 0;
     private static final int MODIFIER_SHADOW = 1;
     private static final int MODIFIER_SHADER = 2;
-    private static final int MODIFIER_COLOR_FILTER = 4;
 
     private final boolean mOpaque;
-    private long mRenderer;
+    protected long mRenderer;
 
     // The native renderer will be destroyed when this object dies.
     // DO NOT overwrite this reference once it is set.
@@ -88,15 +85,6 @@
     GLES20Canvas(boolean translucent) {
         this(false, translucent);
     }
-
-    /**
-     * Creates a canvas to render into an FBO.
-     */
-    GLES20Canvas(long layer, boolean translucent) {
-        mOpaque = !translucent;
-        mRenderer = nCreateLayerRenderer(layer);
-        setupFinalizer();
-    }
     
     protected GLES20Canvas(boolean record, boolean translucent) {
         mOpaque = !translucent;
@@ -118,12 +106,7 @@
         }
     }
 
-    protected void resetDisplayListRenderer() {
-        nResetDisplayListRenderer(mRenderer);
-    }
-
     private static native long nCreateRenderer();
-    private static native long nCreateLayerRenderer(long layer);
     private static native long nCreateDisplayListRenderer();
     private static native void nResetDisplayListRenderer(long renderer);
     private static native void nDestroyRenderer(long renderer);
@@ -145,13 +128,11 @@
         }
     }
 
-    @Override
-    public void setName(String name) {
-        super.setName(name);
-        nSetName(mRenderer, name);
+    public static void setProperty(String name, String value) {
+        nSetProperty(name, value);
     }
 
-    private static native void nSetName(long renderer, String name);
+    private static native void nSetProperty(String name, String value);
 
     ///////////////////////////////////////////////////////////////////////////
     // Hardware layers
@@ -159,12 +140,12 @@
 
     @Override
     void pushLayerUpdate(HardwareLayer layer) {
-        nPushLayerUpdate(mRenderer, ((GLES20RenderLayer) layer).mLayer);
+        nPushLayerUpdate(mRenderer, layer.getLayer());
     }
 
     @Override
     void cancelLayerUpdate(HardwareLayer layer) {
-        nCancelLayerUpdate(mRenderer, ((GLES20RenderLayer) layer).mLayer);
+        nCancelLayerUpdate(mRenderer, layer.getLayer());
     }
 
     @Override
@@ -177,22 +158,7 @@
         nClearLayerUpdates(mRenderer);
     }
 
-    static native long nCreateTextureLayer(boolean opaque, int[] layerInfo);
-    static native long nCreateLayer(int width, int height, boolean isOpaque, int[] layerInfo);
-    static native boolean nResizeLayer(long layerId, int width, int height, int[] layerInfo);
-    static native void nSetOpaqueLayer(long layerId, boolean isOpaque);
-    static native void nSetLayerPaint(long layerId, long nativePaint);
-    static native void nSetLayerColorFilter(long layerId, long nativeColorFilter);
-    static native void nUpdateTextureLayer(long layerId, int width, int height, boolean opaque,
-            SurfaceTexture surface);
-    static native void nClearLayerTexture(long layerId);
-    static native void nSetTextureLayerTransform(long layerId, long matrix);
-    static native void nDestroyLayer(long layerId);
-    static native void nDestroyLayerDeferred(long layerId);
-    static native void nUpdateRenderLayer(long layerId, long renderer, long displayList,
-            int left, int top, int right, int bottom);
     static native boolean nCopyLayer(long layerId, long bitmap);
-
     private static native void nClearLayerUpdates(long renderer);
     private static native void nFlushLayerUpdates(long renderer);
     private static native void nPushLayerUpdate(long renderer, long layer);
@@ -286,18 +252,6 @@
 
     private static native int nGetStencilSize();
 
-    void setCountOverdrawEnabled(boolean enabled) {
-        nSetCountOverdrawEnabled(mRenderer, enabled);
-    }
-
-    static native void nSetCountOverdrawEnabled(long renderer, boolean enabled);
-
-    float getOverdraw() {
-        return nGetOverdraw(mRenderer);
-    }
-
-    static native float nGetOverdraw(long renderer);
-
     ///////////////////////////////////////////////////////////////////////////
     // Functor
     ///////////////////////////////////////////////////////////////////////////
@@ -402,22 +356,11 @@
     // Display list
     ///////////////////////////////////////////////////////////////////////////
 
-    long getDisplayList(long displayList) {
-        return nGetDisplayList(mRenderer, displayList);
-    }
-
-    private static native long nGetDisplayList(long renderer, long displayList);
+    protected static native long nFinishRecording(long renderer);
 
     @Override
-    void outputDisplayList(DisplayList displayList) {
-        nOutputDisplayList(mRenderer, ((GLES20DisplayList) displayList).getNativeDisplayList());
-    }
-
-    private static native void nOutputDisplayList(long renderer, long displayList);
-
-    @Override
-    public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
-        return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).getNativeDisplayList(),
+    public int drawDisplayList(RenderNode displayList, Rect dirty, int flags) {
+        return nDrawDisplayList(mRenderer, displayList.getNativeDisplayList(),
                 dirty, flags);
     }
 
@@ -430,9 +373,7 @@
     
     void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
         layer.setLayerPaint(paint);
-
-        final GLES20Layer glLayer = (GLES20Layer) layer;
-        nDrawLayer(mRenderer, glLayer.getLayer(), x, y);
+        nDrawLayer(mRenderer, layer.getLayer(), x, y);
     }
 
     private static native void nDrawLayer(long renderer, long layer, float x, float y);
@@ -648,15 +589,8 @@
             return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
         }
 
-        int count;
-        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
-        try {
-            final long nativePaint = paint == null ? 0 : paint.mNativePaint;
-            count = nSaveLayer(mRenderer, nativePaint, saveFlags);
-        } finally {
-            if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
-        }
-        return count;
+        final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+        return nSaveLayer(mRenderer, nativePaint, saveFlags);
     }
 
     private static native int nSaveLayer(long renderer, long paint, int saveFlags);
@@ -665,15 +599,8 @@
     public int saveLayer(float left, float top, float right, float bottom, Paint paint,
             int saveFlags) {
         if (left < right && top < bottom) {
-            int count;
-            int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
-            try {
-                final long nativePaint = paint == null ? 0 : paint.mNativePaint;
-                count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
-            } finally {
-                if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
-            }
-            return count;
+            final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+            return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
         }
         return save(saveFlags);
     }
@@ -755,7 +682,7 @@
     @Override
     public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
             Paint paint) {
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom,
                     startAngle, sweepAngle, useCenter, paint.mNativePaint);
@@ -778,14 +705,9 @@
         Bitmap bitmap = patch.getBitmap();
         throwIfCannotDraw(bitmap);
         // Shaders are ignored when drawing patches
-        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
-        try {
-            final long 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);
-        }
+        final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+        nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
+                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
     }
 
     @Override
@@ -793,14 +715,9 @@
         Bitmap bitmap = patch.getBitmap();
         throwIfCannotDraw(bitmap);
         // Shaders are ignored when drawing patches
-        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
-        try {
-            final long 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);
-        }
+        final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+        nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, patch.mNativeChunk,
+                dst.left, dst.top, dst.right, dst.bottom, nativePaint);
     }
 
     private static native void nDrawPatch(long renderer, long bitmap, byte[] buffer, long chunk,
@@ -921,14 +838,9 @@
         }
 
         // Shaders are ignored when drawing bitmaps
-        int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
-        try {
-            final long nativePaint = paint == null ? 0 : paint.mNativePaint;
-            nDrawBitmap(mRenderer, colors, offset, stride, x, y,
-                    width, height, hasAlpha, nativePaint);
-        } finally {
-            if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
-        }
+        final long nativePaint = paint == null ? 0 : paint.mNativePaint;
+        nDrawBitmap(mRenderer, colors, offset, stride, x, y,
+                width, height, hasAlpha, nativePaint);
     }
 
     private static native void nDrawBitmap(long renderer, int[] colors, int offset, int stride,
@@ -976,7 +888,7 @@
 
     @Override
     public void drawCircle(float cx, float cy, float radius, Paint paint) {
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
         } finally {
@@ -1016,7 +928,7 @@
         if ((offset | count) < 0 || offset + count > pts.length) {
             throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
         }
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
         } finally {
@@ -1034,7 +946,7 @@
 
     @Override
     public void drawOval(RectF oval, Paint paint) {
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
         } finally {
@@ -1054,7 +966,7 @@
 
     @Override
     public void drawPath(Path path, Paint paint) {
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             if (path.isSimplePath) {
                 if (path.rects != null) {
@@ -1072,7 +984,7 @@
     private static native void nDrawRects(long renderer, long region, long paint);
 
     void drawRects(float[] rects, int count, Paint paint) {
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawRects(mRenderer, rects, count, paint.mNativePaint);
         } finally {
@@ -1139,7 +1051,7 @@
     public void drawPoints(float[] pts, int offset, int count, Paint paint) {
         if (count < 2) return;
 
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
         } finally {
@@ -1189,7 +1101,7 @@
     @Override
     public void drawRect(float left, float top, float right, float bottom, Paint paint) {
         if (left == right || top == bottom) return;
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
         } finally {
@@ -1217,7 +1129,7 @@
 
     @Override
     public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
-        int modifiers = setupModifiers(paint, MODIFIER_COLOR_FILTER | MODIFIER_SHADER);
+        int modifiers = setupModifiers(paint, MODIFIER_SHADER);
         try {
             nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
                     rx, ry, paint.mNativePaint);
@@ -1397,12 +1309,6 @@
 
     private int setupModifiers(Bitmap b, Paint paint) {
         if (b.getConfig() != Bitmap.Config.ALPHA_8) {
-            final ColorFilter filter = paint.getColorFilter();
-            if (filter != null) {
-                nSetupColorFilter(mRenderer, filter.nativeColorFilter);
-                return MODIFIER_COLOR_FILTER;
-            }
-
             return MODIFIER_NONE;
         } else {
             return setupModifiers(paint);
@@ -1424,12 +1330,6 @@
             modifiers |= MODIFIER_SHADER;
         }
 
-        final ColorFilter filter = paint.getColorFilter();
-        if (filter != null) {
-            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
-            modifiers |= MODIFIER_COLOR_FILTER;
-        }
-
         return modifiers;
     }
 
@@ -1448,26 +1348,10 @@
             modifiers |= MODIFIER_SHADER;
         }
 
-        final ColorFilter filter = paint.getColorFilter();
-        if (filter != null && (flags & MODIFIER_COLOR_FILTER) != 0) {
-            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
-            modifiers |= MODIFIER_COLOR_FILTER;
-        }
-
         return modifiers;
     }
 
-    private int setupColorFilter(Paint paint) {
-        final ColorFilter filter = paint.getColorFilter();
-        if (filter != null) {
-            nSetupColorFilter(mRenderer, filter.nativeColorFilter);
-            return MODIFIER_COLOR_FILTER;
-        }
-        return MODIFIER_NONE;
-    }
-
     private static native void nSetupShader(long renderer, long shader);
-    private static native void nSetupColorFilter(long renderer, long colorFilter);
     private static native void nSetupShadow(long renderer, float radius,
             float dx, float dy, int color);
 
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
deleted file mode 100644
index 7f8b3bd..0000000
--- a/core/java/android/view/GLES20DisplayList.java
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-import android.graphics.Matrix;
-
-import java.util.ArrayList;
-
-/**
- * An implementation of display list for OpenGL ES 2.0.
- */
-class GLES20DisplayList extends DisplayList {
-    private ArrayList<DisplayList> mChildDisplayLists;
-
-    private GLES20RecordingCanvas mCanvas;
-    private boolean mValid;
-
-    // Used for debugging
-    private final String mName;
-
-    // The native display list will be destroyed when this object dies.
-    // DO NOT overwrite this reference once it is set.
-    private DisplayListFinalizer mFinalizer;
-
-    GLES20DisplayList(String name) {
-        mName = name;
-    }
-
-    boolean hasNativeDisplayList() {
-        return mValid && mFinalizer != null;
-    }
-
-    long getNativeDisplayList() {
-        if (!mValid || mFinalizer == null) {
-            throw new IllegalStateException("The display list is not valid.");
-        }
-        return mFinalizer.mNativeDisplayList;
-    }
-
-    @Override
-    public HardwareCanvas start(int width, int height) {
-        if (mCanvas != null) {
-            throw new IllegalStateException("Recording has already started");
-        }
-
-        mValid = false;
-        mCanvas = GLES20RecordingCanvas.obtain(this);
-        mCanvas.start();
-
-        mCanvas.setViewport(width, height);
-        // The dirty rect should always be null for a display list
-        mCanvas.onPreDraw(null);
-
-        return mCanvas;
-    }
-    @Override
-    public void clear() {
-        clearDirty();
-
-        if (mCanvas != null) {
-            mCanvas.recycle();
-            mCanvas = null;
-        }
-        mValid = false;
-
-        clearReferences();
-    }
-
-    void clearReferences() {
-        if (mChildDisplayLists != null) mChildDisplayLists.clear();
-    }
-
-    ArrayList<DisplayList> getChildDisplayLists() {
-        if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>();
-        return mChildDisplayLists;
-    }
-
-    @Override
-    public void reset() {
-        if (hasNativeDisplayList()) {
-            nReset(mFinalizer.mNativeDisplayList);
-        }
-        clear();
-    }
-
-    @Override
-    public boolean isValid() {
-        return mValid;
-    }
-
-    @Override
-    public void end() {
-        if (mCanvas != null) {
-            mCanvas.onPostDraw();
-            if (mFinalizer != null) {
-                mCanvas.end(mFinalizer.mNativeDisplayList);
-            } else {
-                mFinalizer = new DisplayListFinalizer(mCanvas.end(0));
-                nSetDisplayListName(mFinalizer.mNativeDisplayList, mName);
-            }
-            mCanvas.recycle();
-            mCanvas = null;
-            mValid = true;
-        }
-    }
-
-    @Override
-    public int getSize() {
-        if (mFinalizer == null) return 0;
-        return nGetDisplayListSize(mFinalizer.mNativeDisplayList);
-    }
-
-    private static native void nDestroyDisplayList(long displayList);
-    private static native int nGetDisplayListSize(long displayList);
-    private static native void nSetDisplayListName(long displayList, String name);
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Native View Properties
-    ///////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void setCaching(boolean caching) {
-        if (hasNativeDisplayList()) {
-            nSetCaching(mFinalizer.mNativeDisplayList, caching);
-        }
-    }
-
-    @Override
-    public void setClipToBounds(boolean clipToBounds) {
-        if (hasNativeDisplayList()) {
-            nSetClipToBounds(mFinalizer.mNativeDisplayList, clipToBounds);
-        }
-    }
-
-    @Override
-    public void setMatrix(Matrix matrix) {
-        if (hasNativeDisplayList()) {
-            nSetStaticMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance);
-        }
-    }
-
-    @Override
-    public Matrix getMatrix(Matrix matrix) {
-        if (hasNativeDisplayList()) {
-            nGetMatrix(mFinalizer.mNativeDisplayList, matrix.native_instance);
-        }
-        return matrix;
-    }
-
-    @Override
-    public void setAnimationMatrix(Matrix matrix) {
-        if (hasNativeDisplayList()) {
-            nSetAnimationMatrix(mFinalizer.mNativeDisplayList,
-                    (matrix != null) ? matrix.native_instance : 0);
-        }
-    }
-
-    @Override
-    public void setAlpha(float alpha) {
-        if (hasNativeDisplayList()) {
-            nSetAlpha(mFinalizer.mNativeDisplayList, alpha);
-        }
-    }
-
-    @Override
-    public float getAlpha() {
-        if (hasNativeDisplayList()) {
-            return nGetAlpha(mFinalizer.mNativeDisplayList);
-        }
-        return 1.0f;
-    }
-
-    @Override
-    public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
-        if (hasNativeDisplayList()) {
-            nSetHasOverlappingRendering(mFinalizer.mNativeDisplayList, hasOverlappingRendering);
-        }
-    }
-
-    @Override
-    public boolean hasOverlappingRendering() {
-        //noinspection SimplifiableIfStatement
-        if (hasNativeDisplayList()) {
-            return nHasOverlappingRendering(mFinalizer.mNativeDisplayList);
-        }
-        return true;
-    }
-
-    @Override
-    public void setTranslationX(float translationX) {
-        if (hasNativeDisplayList()) {
-            nSetTranslationX(mFinalizer.mNativeDisplayList, translationX);
-        }
-    }
-
-    @Override
-    public float getTranslationX() {
-        if (hasNativeDisplayList()) {
-            return nGetTranslationX(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setTranslationY(float translationY) {
-        if (hasNativeDisplayList()) {
-            nSetTranslationY(mFinalizer.mNativeDisplayList, translationY);
-        }
-    }
-
-    @Override
-    public float getTranslationY() {
-        if (hasNativeDisplayList()) {
-            return nGetTranslationY(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setRotation(float rotation) {
-        if (hasNativeDisplayList()) {
-            nSetRotation(mFinalizer.mNativeDisplayList, rotation);
-        }
-    }
-
-    @Override
-    public float getRotation() {
-        if (hasNativeDisplayList()) {
-            return nGetRotation(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setRotationX(float rotationX) {
-        if (hasNativeDisplayList()) {
-            nSetRotationX(mFinalizer.mNativeDisplayList, rotationX);
-        }
-    }
-
-    @Override
-    public float getRotationX() {
-        if (hasNativeDisplayList()) {
-            return nGetRotationX(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setRotationY(float rotationY) {
-        if (hasNativeDisplayList()) {
-            nSetRotationY(mFinalizer.mNativeDisplayList, rotationY);
-        }
-    }
-
-    @Override
-    public float getRotationY() {
-        if (hasNativeDisplayList()) {
-            return nGetRotationY(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setScaleX(float scaleX) {
-        if (hasNativeDisplayList()) {
-            nSetScaleX(mFinalizer.mNativeDisplayList, scaleX);
-        }
-    }
-
-    @Override
-    public float getScaleX() {
-        if (hasNativeDisplayList()) {
-            return nGetScaleX(mFinalizer.mNativeDisplayList);
-        }
-        return 1.0f;
-    }
-
-    @Override
-    public void setScaleY(float scaleY) {
-        if (hasNativeDisplayList()) {
-            nSetScaleY(mFinalizer.mNativeDisplayList, scaleY);
-        }
-    }
-
-    @Override
-    public float getScaleY() {
-        if (hasNativeDisplayList()) {
-            return nGetScaleY(mFinalizer.mNativeDisplayList);
-        }
-        return 1.0f;
-    }
-
-    @Override
-    public void setTransformationInfo(float alpha, float translationX, float translationY,
-            float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
-        if (hasNativeDisplayList()) {
-            nSetTransformationInfo(mFinalizer.mNativeDisplayList, alpha, translationX, translationY,
-                    rotation, rotationX, rotationY, scaleX, scaleY);
-        }
-    }
-
-    @Override
-    public void setPivotX(float pivotX) {
-        if (hasNativeDisplayList()) {
-            nSetPivotX(mFinalizer.mNativeDisplayList, pivotX);
-        }
-    }
-
-    @Override
-    public float getPivotX() {
-        if (hasNativeDisplayList()) {
-            return nGetPivotX(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setPivotY(float pivotY) {
-        if (hasNativeDisplayList()) {
-            nSetPivotY(mFinalizer.mNativeDisplayList, pivotY);
-        }
-    }
-
-    @Override
-    public float getPivotY() {
-        if (hasNativeDisplayList()) {
-            return nGetPivotY(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setCameraDistance(float distance) {
-        if (hasNativeDisplayList()) {
-            nSetCameraDistance(mFinalizer.mNativeDisplayList, distance);
-        }
-    }
-
-    @Override
-    public float getCameraDistance() {
-        if (hasNativeDisplayList()) {
-            return nGetCameraDistance(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setLeft(int left) {
-        if (hasNativeDisplayList()) {
-            nSetLeft(mFinalizer.mNativeDisplayList, left);
-        }
-    }
-
-    @Override
-    public float getLeft() {
-        if (hasNativeDisplayList()) {
-            return nGetLeft(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setTop(int top) {
-        if (hasNativeDisplayList()) {
-            nSetTop(mFinalizer.mNativeDisplayList, top);
-        }
-    }
-
-    @Override
-    public float getTop() {
-        if (hasNativeDisplayList()) {
-            return nGetTop(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setRight(int right) {
-        if (hasNativeDisplayList()) {
-            nSetRight(mFinalizer.mNativeDisplayList, right);
-        }
-    }
-
-    @Override
-    public float getRight() {
-        if (hasNativeDisplayList()) {
-            return nGetRight(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setBottom(int bottom) {
-        if (hasNativeDisplayList()) {
-            nSetBottom(mFinalizer.mNativeDisplayList, bottom);
-        }
-    }
-
-    @Override
-    public float getBottom() {
-        if (hasNativeDisplayList()) {
-            return nGetBottom(mFinalizer.mNativeDisplayList);
-        }
-        return 0.0f;
-    }
-
-    @Override
-    public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
-        if (hasNativeDisplayList()) {
-            nSetLeftTopRightBottom(mFinalizer.mNativeDisplayList, left, top, right, bottom);
-        }
-    }
-
-    @Override
-    public void offsetLeftAndRight(float offset) {
-        if (hasNativeDisplayList()) {
-            nOffsetLeftAndRight(mFinalizer.mNativeDisplayList, offset);
-        }
-    }
-
-    @Override
-    public void offsetTopAndBottom(float offset) {
-        if (hasNativeDisplayList()) {
-            nOffsetTopAndBottom(mFinalizer.mNativeDisplayList, offset);
-        }
-    }
-
-    private static native void nReset(long displayList);
-    private static native void nOffsetTopAndBottom(long displayList, float offset);
-    private static native void nOffsetLeftAndRight(long displayList, float offset);
-    private static native void nSetLeftTopRightBottom(long displayList, int left, int top,
-            int right, int bottom);
-    private static native void nSetBottom(long displayList, int bottom);
-    private static native void nSetRight(long displayList, int right);
-    private static native void nSetTop(long displayList, int top);
-    private static native void nSetLeft(long displayList, int left);
-    private static native void nSetCameraDistance(long displayList, float distance);
-    private static native void nSetPivotY(long displayList, float pivotY);
-    private static native void nSetPivotX(long displayList, float pivotX);
-    private static native void nSetCaching(long displayList, boolean caching);
-    private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
-    private static native void nSetAlpha(long displayList, float alpha);
-    private static native void nSetHasOverlappingRendering(long displayList,
-            boolean hasOverlappingRendering);
-    private static native void nSetTranslationX(long displayList, float translationX);
-    private static native void nSetTranslationY(long displayList, float translationY);
-    private static native void nSetRotation(long displayList, float rotation);
-    private static native void nSetRotationX(long displayList, float rotationX);
-    private static native void nSetRotationY(long displayList, float rotationY);
-    private static native void nSetScaleX(long displayList, float scaleX);
-    private static native void nSetScaleY(long displayList, float scaleY);
-    private static native void nSetTransformationInfo(long displayList, float alpha,
-            float translationX, float translationY, float rotation, float rotationX,
-            float rotationY, float scaleX, float scaleY);
-    private static native void nSetStaticMatrix(long displayList, long nativeMatrix);
-    private static native void nSetAnimationMatrix(long displayList, long animationMatrix);
-
-    private static native boolean nHasOverlappingRendering(long displayList);
-    private static native void nGetMatrix(long displayList, long matrix);
-    private static native float nGetAlpha(long displayList);
-    private static native float nGetLeft(long displayList);
-    private static native float nGetTop(long displayList);
-    private static native float nGetRight(long displayList);
-    private static native float nGetBottom(long displayList);
-    private static native float nGetCameraDistance(long displayList);
-    private static native float nGetScaleX(long displayList);
-    private static native float nGetScaleY(long displayList);
-    private static native float nGetTranslationX(long displayList);
-    private static native float nGetTranslationY(long displayList);
-    private static native float nGetRotation(long displayList);
-    private static native float nGetRotationX(long displayList);
-    private static native float nGetRotationY(long displayList);
-    private static native float nGetPivotX(long displayList);
-    private static native float nGetPivotY(long displayList);
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Finalization
-    ///////////////////////////////////////////////////////////////////////////
-
-    private static class DisplayListFinalizer {
-        final long mNativeDisplayList;
-
-        public DisplayListFinalizer(long nativeDisplayList) {
-            mNativeDisplayList = nativeDisplayList;
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                nDestroyDisplayList(mNativeDisplayList);
-            } finally {
-                super.finalize();
-            }
-        }
-    }
-}
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
deleted file mode 100644
index 37154eb..0000000
--- a/core/java/android/view/GLES20Layer.java
+++ /dev/null
@@ -1,100 +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.graphics.Bitmap;
-import android.graphics.Paint;
-
-/**
- * An OpenGL ES 2.0 implementation of {@link HardwareLayer}.
- */
-abstract class GLES20Layer extends HardwareLayer {
-    long mLayer;
-    Finalizer mFinalizer;
-
-    GLES20Layer() {
-    }
-
-    GLES20Layer(int width, int height, boolean opaque) {
-        super(width, height, opaque);
-    }
-
-    /**
-     * Returns the native layer object used to render this layer.
-     * 
-     * @return A pointer to the native layer object, or 0 if the object is NULL
-     */
-    public long getLayer() {
-        return mLayer;
-    }
-
-    @Override
-    void setLayerPaint(Paint paint) {
-        if (paint != null) {
-            GLES20Canvas.nSetLayerPaint(mLayer, paint.mNativePaint);
-            GLES20Canvas.nSetLayerColorFilter(mLayer, paint.getColorFilter() != null ?
-                    paint.getColorFilter().nativeColorFilter : 0);
-        }
-    }
-
-    @Override
-    public boolean copyInto(Bitmap bitmap) {
-        return GLES20Canvas.nCopyLayer(mLayer, bitmap.mNativeBitmap);
-    }
-
-    @Override
-    public void destroy() {
-        if (mDisplayList != null) {
-            mDisplayList.reset();
-        }
-        if (mFinalizer != null) {
-            mFinalizer.destroy();
-            mFinalizer = null;
-        }
-        mLayer = 0;
-    }
-
-    @Override
-    void clearStorage() {
-        if (mLayer != 0) GLES20Canvas.nClearLayerTexture(mLayer);
-    }
-
-    static class Finalizer {
-        private long mLayerId;
-
-        public Finalizer(long layerId) {
-            mLayerId = layerId;
-        }
-
-        @Override
-        protected void finalize() throws Throwable {
-            try {
-                if (mLayerId != 0) {
-                    GLES20Canvas.nDestroyLayerDeferred(mLayerId);
-                }
-            } finally {
-                super.finalize();
-            }
-        }
-
-        void destroy() {
-            GLES20Canvas.nDestroyLayer(mLayerId);
-            mLayerId = 0;
-        }
-    }
-}
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index e3e1c76..2b29e5c 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -16,7 +16,6 @@
 
 package android.view;
 
-import android.graphics.Rect;
 import android.util.Pools.SynchronizedPool;
 
 /**
@@ -33,39 +32,23 @@
     private static final SynchronizedPool<GLES20RecordingCanvas> sPool =
             new SynchronizedPool<GLES20RecordingCanvas>(POOL_LIMIT);
 
-    private GLES20DisplayList mDisplayList;
-
     private GLES20RecordingCanvas() {
         super(true, true);
     }
 
-    static GLES20RecordingCanvas obtain(GLES20DisplayList displayList) {
+    static GLES20RecordingCanvas obtain() {
         GLES20RecordingCanvas canvas = sPool.acquire();
         if (canvas == null) {
             canvas = new GLES20RecordingCanvas();
         }
-        canvas.mDisplayList = displayList;
         return canvas;
     }
 
     void recycle() {
-        mDisplayList = null;
-        resetDisplayListRenderer();
         sPool.release(this);
     }
 
-    void start() {
-        mDisplayList.clearReferences();
-    }
-
-    long end(long nativeDisplayList) {
-        return getDisplayList(nativeDisplayList);
-    }
-
-    @Override
-    public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
-        int status = super.drawDisplayList(displayList, dirty, flags);
-        mDisplayList.getChildDisplayLists().add(displayList);
-        return status;
+    long finishRecording() {
+        return nFinishRecording(mRenderer);
     }
 }
diff --git a/core/java/android/view/GLES20RenderLayer.java b/core/java/android/view/GLES20RenderLayer.java
deleted file mode 100644
index 68ba77c..0000000
--- a/core/java/android/view/GLES20RenderLayer.java
+++ /dev/null
@@ -1,130 +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.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-
-/**
- * An OpenGL ES 2.0 implementation of {@link HardwareLayer}. This
- * implementation can be used a rendering target. It generates a
- * {@link Canvas} that can be used to render into an FBO using OpenGL.
- */
-class GLES20RenderLayer extends GLES20Layer {
-    private int mLayerWidth;
-    private int mLayerHeight;
-
-    private final GLES20Canvas mCanvas;
-
-    GLES20RenderLayer(int width, int height, boolean isOpaque) {
-        super(width, height, isOpaque);
-
-        int[] layerInfo = new int[2];
-        mLayer = GLES20Canvas.nCreateLayer(width, height, isOpaque, layerInfo);
-        if (mLayer != 0) {
-            mLayerWidth = layerInfo[0];
-            mLayerHeight = layerInfo[1];
-
-            mCanvas = new GLES20Canvas(mLayer, !isOpaque);
-            mFinalizer = new Finalizer(mLayer);
-        } else {
-            mCanvas = null;
-            mFinalizer = null;
-        }
-    }
-
-    @Override
-    boolean isValid() {
-        return mLayer != 0 && mLayerWidth > 0 && mLayerHeight > 0;
-    }
-
-    @Override
-    boolean resize(int width, int height) {
-        if (!isValid() || width <= 0 || height <= 0) return false;
-
-        mWidth = width;
-        mHeight = height;
-        
-        if (width != mLayerWidth || height != mLayerHeight) {
-            int[] layerInfo = new int[2];
-
-            if (GLES20Canvas.nResizeLayer(mLayer, width, height, layerInfo)) {
-                mLayerWidth = layerInfo[0];
-                mLayerHeight = layerInfo[1];
-            } else {
-                // Failure: not enough GPU resources for requested size
-                mLayer = 0;
-                mLayerWidth = 0;
-                mLayerHeight = 0;
-            }
-        }
-        return isValid();
-    }
-
-    @Override
-    void setOpaque(boolean isOpaque) {
-        mOpaque = isOpaque;
-        GLES20Canvas.nSetOpaqueLayer(mLayer, isOpaque);
-    }
-
-    @Override
-    HardwareCanvas getCanvas() {
-        return mCanvas;
-    }
-
-    @Override
-    void end(Canvas currentCanvas) {
-        HardwareCanvas canvas = getCanvas();
-        if (canvas != null) {
-            canvas.onPostDraw();
-        }
-        if (currentCanvas instanceof GLES20Canvas) {
-            ((GLES20Canvas) currentCanvas).resume();
-        }
-    }
-
-    @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(dirty);
-        return canvas;
-    }
-
-    /**
-     * Ignored
-     */
-    @Override
-    void setTransform(Matrix matrix) {
-    }
-
-    @Override
-    void redrawLater(DisplayList displayList, Rect dirtyRect) {
-        GLES20Canvas.nUpdateRenderLayer(mLayer, mCanvas.getRenderer(),
-                ((GLES20DisplayList) displayList).getNativeDisplayList(),
-                dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
-    }
-}
diff --git a/core/java/android/view/GLES20TextureLayer.java b/core/java/android/view/GLES20TextureLayer.java
deleted file mode 100644
index bb5a6eb..0000000
--- a/core/java/android/view/GLES20TextureLayer.java
+++ /dev/null
@@ -1,108 +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.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-
-/**
- * An OpenGL ES 2.0 implementation of {@link HardwareLayer}. This
- * implementation can be used as a texture. Rendering into this
- * layer is not controlled by a {@link HardwareCanvas}.
- */
-class GLES20TextureLayer extends GLES20Layer {
-    private int mTexture;
-    private SurfaceTexture mSurface;
-
-    GLES20TextureLayer(boolean isOpaque) {
-        int[] layerInfo = new int[2];
-        mLayer = GLES20Canvas.nCreateTextureLayer(isOpaque, layerInfo);
-
-        if (mLayer != 0) {
-            mTexture = layerInfo[0];
-            mFinalizer = new Finalizer(mLayer);
-        } else {
-            mFinalizer = null;
-        }
-    }
-
-    @Override
-    boolean isValid() {
-        return mLayer != 0 && mTexture != 0;
-    }
-
-    @Override
-    boolean resize(int width, int height) {
-        return isValid();
-    }
-
-    @Override
-    HardwareCanvas getCanvas() {
-        return null;
-    }
-
-    @Override
-    HardwareCanvas start(Canvas currentCanvas) {
-        return null;
-    }
-
-    @Override
-    HardwareCanvas start(Canvas currentCanvas, Rect dirty) {
-        return null;
-    }
-
-    @Override
-    void end(Canvas currentCanvas) {
-    }
-
-    SurfaceTexture getSurfaceTexture() {
-        if (mSurface == null) {
-            mSurface = new SurfaceTexture(mTexture);
-        }
-        return mSurface;
-    }
-
-    void setSurfaceTexture(SurfaceTexture surfaceTexture) {
-        if (mSurface != null) {
-            mSurface.release();
-        }
-        mSurface = surfaceTexture;
-        mSurface.attachToGLContext(mTexture);
-    }
-
-    @Override
-    void update(int width, int height, boolean isOpaque) {
-        super.update(width, height, isOpaque);
-        GLES20Canvas.nUpdateTextureLayer(mLayer, width, height, isOpaque, mSurface);
-    }
-
-    @Override
-    void setOpaque(boolean isOpaque) {
-        throw new UnsupportedOperationException("Use update(int, int, boolean) instead");
-    }
-
-    @Override
-    void setTransform(Matrix matrix) {
-        GLES20Canvas.nSetTextureLayerTransform(mLayer, matrix.native_instance);
-    }
-
-    @Override
-    void redrawLater(DisplayList displayList, Rect dirtyRect) {
-    }
-}
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
new file mode 100644
index 0000000..4d42c5d
--- /dev/null
+++ b/core/java/android/view/GLRenderer.java
@@ -0,0 +1,1554 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import static javax.microedition.khronos.egl.EGL10.EGL_ALPHA_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_BAD_NATIVE_WINDOW;
+import static javax.microedition.khronos.egl.EGL10.EGL_BLUE_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_CONFIG_CAVEAT;
+import static javax.microedition.khronos.egl.EGL10.EGL_DEFAULT_DISPLAY;
+import static javax.microedition.khronos.egl.EGL10.EGL_DEPTH_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_DRAW;
+import static javax.microedition.khronos.egl.EGL10.EGL_GREEN_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_HEIGHT;
+import static javax.microedition.khronos.egl.EGL10.EGL_NONE;
+import static javax.microedition.khronos.egl.EGL10.EGL_NO_CONTEXT;
+import static javax.microedition.khronos.egl.EGL10.EGL_NO_DISPLAY;
+import static javax.microedition.khronos.egl.EGL10.EGL_NO_SURFACE;
+import static javax.microedition.khronos.egl.EGL10.EGL_RED_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_RENDERABLE_TYPE;
+import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLES;
+import static javax.microedition.khronos.egl.EGL10.EGL_SAMPLE_BUFFERS;
+import static javax.microedition.khronos.egl.EGL10.EGL_STENCIL_SIZE;
+import static javax.microedition.khronos.egl.EGL10.EGL_SUCCESS;
+import static javax.microedition.khronos.egl.EGL10.EGL_SURFACE_TYPE;
+import static javax.microedition.khronos.egl.EGL10.EGL_WIDTH;
+import static javax.microedition.khronos.egl.EGL10.EGL_WINDOW_BIT;
+
+import android.content.ComponentCallbacks2;
+import android.graphics.Bitmap;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.opengl.EGL14;
+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 java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGL11;
+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.GL;
+
+/**
+ * Hardware renderer using OpenGL
+ *
+ * @hide
+ */
+public class GLRenderer extends HardwareRenderer {
+    static final int SURFACE_STATE_ERROR = 0;
+    static final int SURFACE_STATE_SUCCESS = 1;
+    static final int SURFACE_STATE_UPDATED = 2;
+
+    static final int FUNCTOR_PROCESS_DELAY = 4;
+
+    /**
+     * Number of frames to profile.
+     */
+    private static final int PROFILE_MAX_FRAMES = 128;
+
+    /**
+     * Number of floats per profiled frame.
+     */
+    private static final int PROFILE_FRAME_DATA_COUNT = 3;
+
+    private static final int PROFILE_DRAW_MARGIN = 0;
+    private static final int PROFILE_DRAW_WIDTH = 3;
+    private static final int[] PROFILE_DRAW_COLORS = { 0xcf3e66cc, 0xcfdc3912, 0xcfe69800 };
+    private static final int PROFILE_DRAW_CURRENT_FRAME_COLOR = 0xcf5faa4d;
+    private static final int PROFILE_DRAW_THRESHOLD_COLOR = 0xff5faa4d;
+    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,
+    };
+    private static final int GL_VERSION = 2;
+
+    static EGL10 sEgl;
+    static EGLDisplay sEglDisplay;
+    static EGLConfig sEglConfig;
+    static final Object[] sEglLock = new Object[0];
+    int mWidth = -1, mHeight = -1;
+
+    static final ThreadLocal<ManagedEGLContext> sEglContextStorage
+            = new ThreadLocal<ManagedEGLContext>();
+
+    EGLContext mEglContext;
+    Thread mEglThread;
+
+    EGLSurface mEglSurface;
+
+    GL mGl;
+    HardwareCanvas mCanvas;
+
+    String mName;
+
+    long mFrameCount;
+    Paint mDebugPaint;
+
+    static boolean sDirtyRegions;
+    static final boolean sDirtyRegionsRequested;
+    static {
+        String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        sDirtyRegions = "true".equalsIgnoreCase(dirtyProperty);
+        sDirtyRegionsRequested = sDirtyRegions;
+    }
+
+    boolean mDirtyRegionsEnabled;
+    boolean mUpdateDirtyRegions;
+
+    boolean mProfileEnabled;
+    int mProfileVisualizerType = -1;
+    float[] mProfileData;
+    ReentrantLock mProfileLock;
+    int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
+
+    GraphDataProvider mDebugDataProvider;
+    float[][] mProfileShapes;
+    Paint mProfilePaint;
+
+    boolean mDebugDirtyRegions;
+    int mDebugOverdraw = -1;
+
+    final boolean mTranslucent;
+
+    private boolean mDestroyed;
+
+    private final Rect mRedrawClip = new Rect();
+
+    private final int[] mSurfaceSize = new int[2];
+    private final FunctorsRunnable mFunctorsRunnable = new FunctorsRunnable();
+
+    private long mDrawDelta = Long.MAX_VALUE;
+
+    private GLES20Canvas mGlCanvas;
+
+    private DisplayMetrics mDisplayMetrics;
+
+    private static EGLSurface sPbuffer;
+    private static final Object[] sPbufferLock = new Object[0];
+
+    private List<HardwareLayer> mAttachedLayers = new ArrayList<HardwareLayer>();
+
+    private static class GLRendererEglContext extends ManagedEGLContext {
+        final Handler mHandler = new Handler();
+
+        public GLRendererEglContext(EGLContext context) {
+            super(context);
+        }
+
+        @Override
+        public void onTerminate(final EGLContext eglContext) {
+            // Make sure we do this on the correct thread.
+            if (mHandler.getLooper() != Looper.myLooper()) {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        onTerminate(eglContext);
+                    }
+                });
+                return;
+            }
+
+            synchronized (sEglLock) {
+                if (sEgl == null) return;
+
+                if (EGLImpl.getInitCount(sEglDisplay) == 1) {
+                    usePbufferSurface(eglContext);
+                    GLES20Canvas.terminateCaches();
+
+                    sEgl.eglDestroyContext(sEglDisplay, eglContext);
+                    sEglContextStorage.set(null);
+                    sEglContextStorage.remove();
+
+                    sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
+                    sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
+                            EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+                    sEgl.eglReleaseThread();
+                    sEgl.eglTerminate(sEglDisplay);
+
+                    sEgl = null;
+                    sEglDisplay = null;
+                    sEglConfig = null;
+                    sPbuffer = null;
+                }
+            }
+        }
+    }
+
+    HardwareCanvas createCanvas() {
+        return mGlCanvas = new GLES20Canvas(mTranslucent);
+    }
+
+    ManagedEGLContext createManagedContext(EGLContext eglContext) {
+        return new GLRendererEglContext(mEglContext);
+    }
+
+    int[] getConfig(boolean dirtyRegions) {
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        final int stencilSize = GLES20Canvas.getStencilSize();
+        final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
+
+        return new int[] {
+                EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
+                EGL_RED_SIZE, 8,
+                EGL_GREEN_SIZE, 8,
+                EGL_BLUE_SIZE, 8,
+                EGL_ALPHA_SIZE, 8,
+                EGL_DEPTH_SIZE, 0,
+                EGL_CONFIG_CAVEAT, EGL_NONE,
+                EGL_STENCIL_SIZE, stencilSize,
+                EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
+                EGL_NONE
+        };
+    }
+
+    void initCaches() {
+        if (GLES20Canvas.initCaches()) {
+            // Caches were (re)initialized, rebind atlas
+            initAtlas();
+        }
+    }
+
+    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) {
+                    long[] 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);
+        }
+    }
+
+    boolean canDraw() {
+        return mGl != null && mCanvas != null && mGlCanvas != null;
+    }
+
+    int onPreDraw(Rect dirty) {
+        return mGlCanvas.onPreDraw(dirty);
+    }
+
+    void onPostDraw() {
+        mGlCanvas.onPostDraw();
+    }
+
+    void drawProfileData(View.AttachInfo attachInfo) {
+        if (mDebugDataProvider != null) {
+            final GraphDataProvider provider = mDebugDataProvider;
+            initProfileDrawData(attachInfo, provider);
+
+            final int height = provider.getVerticalUnitSize();
+            final int margin = provider.getHorizontaUnitMargin();
+            final int width = provider.getHorizontalUnitSize();
+
+            int x = 0;
+            int count = 0;
+            int current = 0;
+
+            final float[] data = provider.getData();
+            final int elementCount = provider.getElementCount();
+            final int graphType = provider.getGraphType();
+
+            int totalCount = provider.getFrameCount() * elementCount;
+            if (graphType == GraphDataProvider.GRAPH_TYPE_LINES) {
+                totalCount -= elementCount;
+            }
+
+            for (int i = 0; i < totalCount; i += elementCount) {
+                if (data[i] < 0.0f) break;
+
+                int index = count * 4;
+                if (i == provider.getCurrentFrame() * elementCount) current = index;
+
+                x += margin;
+                int x2 = x + width;
+
+                int y2 = mHeight;
+                int y1 = (int) (y2 - data[i] * height);
+
+                switch (graphType) {
+                    case GraphDataProvider.GRAPH_TYPE_BARS: {
+                        for (int j = 0; j < elementCount; j++) {
+                            //noinspection MismatchedReadAndWriteOfArray
+                            final float[] r = mProfileShapes[j];
+                            r[index] = x;
+                            r[index + 1] = y1;
+                            r[index + 2] = x2;
+                            r[index + 3] = y2;
+
+                            y2 = y1;
+                            if (j < elementCount - 1) {
+                                y1 = (int) (y2 - data[i + j + 1] * height);
+                            }
+                        }
+                    } break;
+                    case GraphDataProvider.GRAPH_TYPE_LINES: {
+                        for (int j = 0; j < elementCount; j++) {
+                            //noinspection MismatchedReadAndWriteOfArray
+                            final float[] r = mProfileShapes[j];
+                            r[index] = (x + x2) * 0.5f;
+                            r[index + 1] = index == 0 ? y1 : r[index - 1];
+                            r[index + 2] = r[index] + width;
+                            r[index + 3] = y1;
+
+                            y2 = y1;
+                            if (j < elementCount - 1) {
+                                y1 = (int) (y2 - data[i + j + 1] * height);
+                            }
+                        }
+                    } break;
+                }
+
+
+                x += width;
+                count++;
+            }
+
+            x += margin;
+
+            drawGraph(graphType, count);
+            drawCurrentFrame(graphType, current);
+            drawThreshold(x, height);
+        }
+    }
+
+    private void drawGraph(int graphType, int count) {
+        for (int i = 0; i < mProfileShapes.length; i++) {
+            mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
+            switch (graphType) {
+                case GraphDataProvider.GRAPH_TYPE_BARS:
+                    mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
+                    break;
+                case GraphDataProvider.GRAPH_TYPE_LINES:
+                    mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
+                    break;
+            }
+        }
+    }
+
+    private void drawCurrentFrame(int graphType, int index) {
+        if (index >= 0) {
+            mDebugDataProvider.setupCurrentFramePaint(mProfilePaint);
+            switch (graphType) {
+                case GraphDataProvider.GRAPH_TYPE_BARS:
+                    mGlCanvas.drawRect(mProfileShapes[2][index], mProfileShapes[2][index + 1],
+                            mProfileShapes[2][index + 2], mProfileShapes[0][index + 3],
+                            mProfilePaint);
+                    break;
+                case GraphDataProvider.GRAPH_TYPE_LINES:
+                    mGlCanvas.drawLine(mProfileShapes[2][index], mProfileShapes[2][index + 1],
+                            mProfileShapes[2][index], mHeight, mProfilePaint);
+                    break;
+            }
+        }
+    }
+
+    private void drawThreshold(int x, int height) {
+        float threshold = mDebugDataProvider.getThreshold();
+        if (threshold > 0.0f) {
+            mDebugDataProvider.setupThresholdPaint(mProfilePaint);
+            int y = (int) (mHeight - threshold * height);
+            mGlCanvas.drawLine(0.0f, y, x, y, mProfilePaint);
+        }
+    }
+
+    private void initProfileDrawData(View.AttachInfo attachInfo, GraphDataProvider provider) {
+        if (mProfileShapes == null) {
+            final int elementCount = provider.getElementCount();
+            final int frameCount = provider.getFrameCount();
+
+            mProfileShapes = new float[elementCount][];
+            for (int i = 0; i < elementCount; i++) {
+                mProfileShapes[i] = new float[frameCount * 4];
+            }
+
+            mProfilePaint = new Paint();
+        }
+
+        mProfilePaint.reset();
+        if (provider.getGraphType() == GraphDataProvider.GRAPH_TYPE_LINES) {
+            mProfilePaint.setAntiAlias(true);
+        }
+
+        if (mDisplayMetrics == null) {
+            mDisplayMetrics = new DisplayMetrics();
+        }
+
+        attachInfo.mDisplay.getMetrics(mDisplayMetrics);
+        provider.prepare(mDisplayMetrics);
+    }
+
+    @Override
+    void destroy(boolean full) {
+        try {
+            if (full && mCanvas != null) {
+                mCanvas = null;
+            }
+
+            if (!isEnabled() || mDestroyed) {
+                setEnabled(false);
+                return;
+            }
+
+            destroySurface();
+            setEnabled(false);
+
+            mDestroyed = true;
+            mGl = null;
+        } finally {
+            if (full && mGlCanvas != null) {
+                mGlCanvas = null;
+            }
+        }
+    }
+
+    @Override
+    void pushLayerUpdate(HardwareLayer layer) {
+        mGlCanvas.pushLayerUpdate(layer);
+    }
+
+    @Override
+    void flushLayerUpdates() {
+        if (validate()) {
+            flushLayerChanges();
+            mGlCanvas.flushLayerUpdates();
+        }
+    }
+
+    @Override
+    HardwareLayer createTextureLayer() {
+        validate();
+        return HardwareLayer.createTextureLayer(this);
+    }
+
+    @Override
+    public HardwareLayer createDisplayListLayer(int width, int height) {
+        validate();
+        return HardwareLayer.createDisplayListLayer(this, width, height);
+    }
+
+    @Override
+    void onLayerCreated(HardwareLayer hardwareLayer) {
+        mAttachedLayers.add(hardwareLayer);
+    }
+
+    boolean hasContext() {
+        return sEgl != null && mEglContext != null
+                && mEglContext.equals(sEgl.eglGetCurrentContext());
+    }
+
+    @Override
+    void onLayerDestroyed(HardwareLayer layer) {
+        if (mGlCanvas != null) {
+            mGlCanvas.cancelLayerUpdate(layer);
+        }
+        if (hasContext()) {
+            long backingLayer = layer.detachBackingLayer();
+            nDestroyLayer(backingLayer);
+        }
+        mAttachedLayers.remove(layer);
+    }
+
+    @Override
+    public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
+        return layer.createSurfaceTexture();
+    }
+
+    @Override
+    boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap) {
+        if (!validate()) {
+            throw new IllegalStateException("Could not acquire hardware rendering context");
+        }
+        layer.flushChanges();
+        return GLES20Canvas.nCopyLayer(layer.getLayer(), bitmap.mNativeBitmap);
+    }
+
+    @Override
+    boolean safelyRun(Runnable action) {
+        boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
+
+        if (needsContext) {
+            GLRendererEglContext managedContext =
+                    (GLRendererEglContext) sEglContextStorage.get();
+            if (managedContext == null) return false;
+            usePbufferSurface(managedContext.getContext());
+        }
+
+        try {
+            action.run();
+        } finally {
+            if (needsContext) {
+                sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
+                        EGL_NO_SURFACE, EGL_NO_CONTEXT);
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    void destroyHardwareResources(final View view) {
+        if (view != null) {
+            safelyRun(new Runnable() {
+                @Override
+                public void run() {
+                    if (mCanvas != null) {
+                        mCanvas.clearLayerUpdates();
+                    }
+                    destroyResources(view);
+                    GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+                }
+            });
+        }
+    }
+
+    private static void destroyResources(View view) {
+        view.destroyHardwareResources();
+
+        if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) view;
+
+            int count = group.getChildCount();
+            for (int i = 0; i < count; i++) {
+                destroyResources(group.getChildAt(i));
+            }
+        }
+    }
+
+    static void startTrimMemory(int level) {
+        if (sEgl == null || sEglConfig == null) return;
+
+        GLRendererEglContext managedContext =
+                (GLRendererEglContext) sEglContextStorage.get();
+        // We do not have OpenGL objects
+        if (managedContext == null) {
+            return;
+        } else {
+            usePbufferSurface(managedContext.getContext());
+        }
+
+        if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
+            GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
+        } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+            GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
+        }
+    }
+
+    static void endTrimMemory() {
+        if (sEgl != null && sEglDisplay != null) {
+            sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        }
+    }
+
+    private static void usePbufferSurface(EGLContext eglContext) {
+        synchronized (sPbufferLock) {
+            // Create a temporary 1x1 pbuffer so we have a context
+            // to clear our OpenGL objects
+            if (sPbuffer == null) {
+                sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] {
+                        EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE
+                });
+            }
+        }
+        sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
+    }
+
+    GLRenderer(boolean translucent) {
+        mTranslucent = translucent;
+
+        loadSystemProperties();
+    }
+
+    @Override
+    boolean loadSystemProperties() {
+        boolean value;
+        boolean changed = false;
+
+        String profiling = SystemProperties.get(PROFILE_PROPERTY);
+        int graphType = search(VISUALIZERS, profiling);
+        value = graphType >= 0;
+
+        if (graphType != mProfileVisualizerType) {
+            changed = true;
+            mProfileVisualizerType = graphType;
+
+            mProfileShapes = null;
+            mProfilePaint = null;
+
+            if (value) {
+                mDebugDataProvider = new DrawPerformanceDataProvider(graphType);
+            } else {
+                mDebugDataProvider = null;
+            }
+        }
+
+        // If on-screen profiling is not enabled, we need to check whether
+        // console profiling only is enabled
+        if (!value) {
+            value = Boolean.parseBoolean(profiling);
+        }
+
+        if (value != mProfileEnabled) {
+            changed = true;
+            mProfileEnabled = value;
+
+            if (mProfileEnabled) {
+                Log.d(LOG_TAG, "Profiling hardware renderer");
+
+                int maxProfileFrames = SystemProperties.getInt(PROFILE_MAXFRAMES_PROPERTY,
+                        PROFILE_MAX_FRAMES);
+                mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT];
+                for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
+                    mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
+                }
+
+                mProfileLock = new ReentrantLock();
+            } else {
+                mProfileData = null;
+                mProfileLock = null;
+                mProfileVisualizerType = -1;
+            }
+
+            mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
+        }
+
+        value = SystemProperties.getBoolean(DEBUG_DIRTY_REGIONS_PROPERTY, false);
+        if (value != mDebugDirtyRegions) {
+            changed = true;
+            mDebugDirtyRegions = value;
+
+            if (mDebugDirtyRegions) {
+                Log.d(LOG_TAG, "Debugging dirty regions");
+            }
+        }
+
+        String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
+        int debugOverdraw = search(OVERDRAW, overdraw);
+        if (debugOverdraw != mDebugOverdraw) {
+            changed = true;
+            mDebugOverdraw = debugOverdraw;
+        }
+
+        if (loadProperties()) {
+            changed = true;
+        }
+
+        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) {
+            pw.printf("\n\tDraw\tProcess\tExecute\n");
+
+            mProfileLock.lock();
+            try {
+                for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
+                    if (mProfileData[i] < 0) {
+                        break;
+                    }
+                    pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
+                            mProfileData[i + 2]);
+                    mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
+                }
+                mProfileCurrentFrame = mProfileData.length;
+            } finally {
+                mProfileLock.unlock();
+            }
+        }
+    }
+
+    @Override
+    long getFrameCount() {
+        return mFrameCount;
+    }
+
+    /**
+     * Indicates whether this renderer instance can track and update dirty regions.
+     */
+    boolean hasDirtyRegions() {
+        return mDirtyRegionsEnabled;
+    }
+
+    /**
+     * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
+     * is invoked and the requested flag is turned off. The error code is
+     * also logged as a warning.
+     */
+    void checkEglErrors() {
+        if (isEnabled()) {
+            checkEglErrorsForced();
+        }
+    }
+
+    private void checkEglErrorsForced() {
+        int error = sEgl.eglGetError();
+        if (error != EGL_SUCCESS) {
+            // something bad has happened revert to
+            // normal rendering.
+            Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
+            fallback(error != EGL11.EGL_CONTEXT_LOST);
+        }
+    }
+
+    private void fallback(boolean fallback) {
+        destroy(true);
+        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. "
+                    + "Switching back to software rendering.");
+        }
+    }
+
+    @Override
+    boolean initialize(Surface surface) throws OutOfResourcesException {
+        if (isRequested() && !isEnabled()) {
+            boolean contextCreated = initializeEgl();
+            mGl = createEglSurface(surface);
+            mDestroyed = false;
+
+            if (mGl != null) {
+                int err = sEgl.eglGetError();
+                if (err != EGL_SUCCESS) {
+                    destroy(true);
+                    setRequested(false);
+                } else {
+                    if (mCanvas == null) {
+                        mCanvas = createCanvas();
+                    }
+                    setEnabled(true);
+
+                    if (contextCreated) {
+                        initAtlas();
+                    }
+                }
+
+                return mCanvas != null;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    void updateSurface(Surface surface) throws OutOfResourcesException {
+        if (isRequested() && isEnabled()) {
+            createEglSurface(surface);
+        }
+    }
+
+    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)) {
+                    throw new RuntimeException("eglInitialize failed " +
+                            GLUtils.getEGLErrorString(sEgl.eglGetError()));
+                }
+
+                checkEglErrorsForced();
+
+                sEglConfig = loadEglConfig();
+            }
+        }
+
+        ManagedEGLContext managedContext = sEglContextStorage.get();
+        mEglContext = managedContext != null ? managedContext.getContext() : null;
+        mEglThread = Thread.currentThread();
+
+        if (mEglContext == null) {
+            mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
+            sEglContextStorage.set(createManagedContext(mEglContext));
+            return true;
+        }
+
+        return false;
+    }
+
+    private EGLConfig loadEglConfig() {
+        EGLConfig eglConfig = chooseEglConfig();
+        if (eglConfig == null) {
+            // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
+            if (sDirtyRegions) {
+                sDirtyRegions = false;
+                eglConfig = chooseEglConfig();
+                if (eglConfig == null) {
+                    throw new RuntimeException("eglConfig not initialized");
+                }
+            } else {
+                throw new RuntimeException("eglConfig not initialized");
+            }
+        }
+        return eglConfig;
+    }
+
+    private EGLConfig chooseEglConfig() {
+        EGLConfig[] configs = new EGLConfig[1];
+        int[] configsCount = new int[1];
+        int[] configSpec = getConfig(sDirtyRegions);
+
+        // Debug
+        final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, "");
+        if ("all".equalsIgnoreCase(debug)) {
+            sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount);
+
+            EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]];
+            sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs,
+                    configsCount[0], configsCount);
+
+            for (EGLConfig config : debugConfigs) {
+                printConfig(config);
+            }
+        }
+
+        if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
+            throw new IllegalArgumentException("eglChooseConfig failed " +
+                    GLUtils.getEGLErrorString(sEgl.eglGetError()));
+        } else if (configsCount[0] > 0) {
+            if ("choice".equalsIgnoreCase(debug)) {
+                printConfig(configs[0]);
+            }
+            return configs[0];
+        }
+
+        return null;
+    }
+
+    private static void printConfig(EGLConfig config) {
+        int[] value = new int[1];
+
+        Log.d(LOG_TAG, "EGL configuration " + config + ":");
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value);
+        Log.d(LOG_TAG, "  RED_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value);
+        Log.d(LOG_TAG, "  GREEN_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value);
+        Log.d(LOG_TAG, "  BLUE_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value);
+        Log.d(LOG_TAG, "  ALPHA_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value);
+        Log.d(LOG_TAG, "  DEPTH_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
+        Log.d(LOG_TAG, "  STENCIL_SIZE = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
+        Log.d(LOG_TAG, "  SAMPLE_BUFFERS = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
+        Log.d(LOG_TAG, "  SAMPLES = " + value[0]);
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
+        Log.d(LOG_TAG, "  SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
+
+        sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
+        Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
+    }
+
+    GL createEglSurface(Surface surface) throws OutOfResourcesException {
+        // Check preconditions.
+        if (sEgl == null) {
+            throw new RuntimeException("egl not initialized");
+        }
+        if (sEglDisplay == null) {
+            throw new RuntimeException("eglDisplay not initialized");
+        }
+        if (sEglConfig == null) {
+            throw new RuntimeException("eglConfig not initialized");
+        }
+        if (Thread.currentThread() != mEglThread) {
+            throw new IllegalStateException("HardwareRenderer cannot be used "
+                    + "from multiple threads");
+        }
+
+        // In case we need to destroy an existing surface
+        destroySurface();
+
+        // Create an EGL surface we can render into.
+        if (!createSurface(surface)) {
+            return null;
+        }
+
+        initCaches();
+
+        return mEglContext.getGL();
+    }
+
+    private void enableDirtyRegions() {
+        // If mDirtyRegions is set, this means we have an EGL configuration
+        // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
+        if (sDirtyRegions) {
+            if (!(mDirtyRegionsEnabled = preserveBackBuffer())) {
+                Log.w(LOG_TAG, "Backbuffer cannot be preserved");
+            }
+        } else if (sDirtyRegionsRequested) {
+            // If mDirtyRegions is not set, our EGL configuration does not
+            // have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default
+            // swap behavior might be EGL_BUFFER_PRESERVED, which means we
+            // want to set mDirtyRegions. We try to do this only if dirty
+            // regions were initially requested as part of the device
+            // configuration (see RENDER_DIRTY_REGIONS)
+            mDirtyRegionsEnabled = isBackBufferPreserved();
+        }
+    }
+
+    EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
+        final int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, GL_VERSION, EGL_NONE };
+
+        EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT,
+                attribs);
+        if (context == null || context == EGL_NO_CONTEXT) {
+            //noinspection ConstantConditions
+            throw new IllegalStateException(
+                    "Could not create an EGL context. eglCreateContext failed with error: " +
+                    GLUtils.getEGLErrorString(sEgl.eglGetError()));
+        }
+
+        return context;
+    }
+
+    void destroySurface() {
+        if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
+            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;
+        }
+    }
+
+    @Override
+    void invalidate(Surface surface) {
+        // Cancels any existing buffer to ensure we'll get a buffer
+        // of the right size before we call eglSwapBuffers
+        sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+        if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
+            sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+            mEglSurface = null;
+            setEnabled(false);
+        }
+
+        if (surface.isValid()) {
+            if (!createSurface(surface)) {
+                return;
+            }
+
+            mUpdateDirtyRegions = true;
+
+            if (mCanvas != null) {
+                setEnabled(true);
+            }
+        }
+    }
+
+    private boolean createSurface(Surface surface) {
+        mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, surface, null);
+
+        if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
+            int error = sEgl.eglGetError();
+            if (error == EGL_BAD_NATIVE_WINDOW) {
+                Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
+                return false;
+            }
+            throw new RuntimeException("createWindowSurface failed "
+                    + GLUtils.getEGLErrorString(error));
+        }
+
+        if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+            throw new IllegalStateException("eglMakeCurrent failed " +
+                    GLUtils.getEGLErrorString(sEgl.eglGetError()));
+        }
+
+        enableDirtyRegions();
+
+        return true;
+    }
+
+    boolean validate() {
+        return checkRenderContext() != SURFACE_STATE_ERROR;
+    }
+
+    @Override
+    void setup(int width, int height) {
+        if (validate()) {
+            mCanvas.setViewport(width, height);
+            mWidth = width;
+            mHeight = height;
+        }
+    }
+
+    @Override
+    int getWidth() {
+        return mWidth;
+    }
+
+    @Override
+    int getHeight() {
+        return mHeight;
+    }
+
+    @Override
+    void setName(String name) {
+        mName = name;
+    }
+
+    class FunctorsRunnable implements Runnable {
+        View.AttachInfo attachInfo;
+
+        @Override
+        public void run() {
+            final HardwareRenderer renderer = attachInfo.mHardwareRenderer;
+            if (renderer == null || !renderer.isEnabled() || renderer != GLRenderer.this) {
+                return;
+            }
+
+            if (checkRenderContext() != SURFACE_STATE_ERROR) {
+                int status = mCanvas.invokeFunctors(mRedrawClip);
+                handleFunctorStatus(attachInfo, status);
+            }
+        }
+    }
+
+    @Override
+    void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+            Rect dirty) {
+        if (canDraw()) {
+            if (!hasDirtyRegions()) {
+                dirty = null;
+            }
+            attachInfo.mIgnoreDirtyState = true;
+            attachInfo.mDrawingTime = SystemClock.uptimeMillis();
+
+            view.mPrivateFlags |= View.PFLAG_DRAWN;
+
+            // We are already on the correct thread
+            final int surfaceState = checkRenderContextUnsafe();
+            if (surfaceState != SURFACE_STATE_ERROR) {
+                HardwareCanvas canvas = mCanvas;
+
+                if (mProfileEnabled) {
+                    mProfileLock.lock();
+                }
+
+                dirty = beginFrame(canvas, dirty, surfaceState);
+
+                RenderNode displayList = buildDisplayList(view, canvas);
+
+                flushLayerChanges();
+
+                // 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 = RenderNode.STATUS_DONE;
+
+                long start = getSystemTime();
+                try {
+                    status = prepareFrame(dirty);
+
+                    saveCount = canvas.save();
+                    callbacks.onHardwarePreDraw(canvas);
+
+                    if (displayList != null) {
+                        status |= drawDisplayList(attachInfo, canvas, displayList, status);
+                    } else {
+                        // Shouldn't reach here
+                        view.draw(canvas);
+                    }
+                } catch (Exception e) {
+                    Log.e(LOG_TAG, "An error has occurred while drawing:", e);
+                } finally {
+                    callbacks.onHardwarePostDraw(canvas);
+                    canvas.restoreToCount(saveCount);
+                    view.mRecreateDisplayList = false;
+
+                    mDrawDelta = getSystemTime() - start;
+
+                    if (mDrawDelta > 0) {
+                        mFrameCount++;
+
+                        debugDirtyRegions(dirty, canvas);
+                        drawProfileData(attachInfo);
+                    }
+                }
+
+                onPostDraw();
+
+                swapBuffers(status);
+
+                if (mProfileEnabled) {
+                    mProfileLock.unlock();
+                }
+
+                attachInfo.mIgnoreDirtyState = false;
+            }
+        }
+    }
+
+    private void flushLayerChanges() {
+        // Loop through and apply any pending layer changes
+        for (int i = 0; i < mAttachedLayers.size(); i++) {
+            HardwareLayer layer = mAttachedLayers.get(i);
+            layer.flushChanges();
+            if (!layer.isValid()) {
+                // The layer was removed from mAttachedLayers, rewind i by 1
+                // Note that this shouldn't actually happen as View.getHardwareLayer()
+                // is already flushing for error checking reasons
+                i--;
+            }
+        }
+    }
+
+    void setDisplayListData(long displayList, long newData) {
+        nSetDisplayListData(displayList, newData);
+    }
+    private static native void nSetDisplayListData(long displayList, long newData);
+
+    private RenderNode 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;
+
+        long buildDisplayListStartTime = startBuildDisplayListProfiling();
+        canvas.clearLayerUpdates();
+
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
+        RenderNode displayList = view.getDisplayList();
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+
+        endBuildDisplayListProfiling(buildDisplayListStartTime);
+
+        return displayList;
+    }
+
+    private Rect beginFrame(HardwareCanvas canvas, Rect dirty, int surfaceState) {
+        // We had to change the current surface and/or context, redraw everything
+        if (surfaceState == SURFACE_STATE_UPDATED) {
+            dirty = null;
+            beginFrame(null);
+        } else {
+            int[] size = mSurfaceSize;
+            beginFrame(size);
+
+            if (size[1] != mHeight || size[0] != mWidth) {
+                mWidth = size[0];
+                mHeight = size[1];
+
+                canvas.setViewport(mWidth, mHeight);
+
+                dirty = null;
+            }
+        }
+
+        if (mDebugDataProvider != null) dirty = null;
+
+        return dirty;
+    }
+
+    private long startBuildDisplayListProfiling() {
+        if (mProfileEnabled) {
+            mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT;
+            if (mProfileCurrentFrame >= mProfileData.length) {
+                mProfileCurrentFrame = 0;
+            }
+
+            return System.nanoTime();
+        }
+        return 0;
+    }
+
+    private void endBuildDisplayListProfiling(long getDisplayListStartTime) {
+        if (mProfileEnabled) {
+            long now = System.nanoTime();
+            float total = (now - getDisplayListStartTime) * 0.000001f;
+            //noinspection PointlessArithmeticExpression
+            mProfileData[mProfileCurrentFrame] = total;
+        }
+    }
+
+    private int prepareFrame(Rect dirty) {
+        int status;
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame");
+        try {
+            status = onPreDraw(dirty);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+        }
+        return status;
+    }
+
+    private int drawDisplayList(View.AttachInfo attachInfo, HardwareCanvas canvas,
+            RenderNode displayList, int status) {
+
+        long drawDisplayListStartTime = 0;
+        if (mProfileEnabled) {
+            drawDisplayListStartTime = System.nanoTime();
+        }
+
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
+        try {
+            status |= canvas.drawDisplayList(displayList, mRedrawClip,
+                    RenderNode.FLAG_CLIP_CHILDREN);
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+        }
+
+        if (mProfileEnabled) {
+            long now = System.nanoTime();
+            float total = (now - drawDisplayListStartTime) * 0.000001f;
+            mProfileData[mProfileCurrentFrame + 1] = total;
+        }
+
+        handleFunctorStatus(attachInfo, status);
+        return status;
+    }
+
+    private void swapBuffers(int status) {
+        if ((status & RenderNode.STATUS_DREW) == RenderNode.STATUS_DREW) {
+            long eglSwapBuffersStartTime = 0;
+            if (mProfileEnabled) {
+                eglSwapBuffersStartTime = System.nanoTime();
+            }
+
+            sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
+
+            if (mProfileEnabled) {
+                long now = System.nanoTime();
+                float total = (now - eglSwapBuffersStartTime) * 0.000001f;
+                mProfileData[mProfileCurrentFrame + 2] = total;
+            }
+
+            checkEglErrors();
+        }
+    }
+
+    private void debugDirtyRegions(Rect dirty, HardwareCanvas canvas) {
+        if (mDebugDirtyRegions) {
+            if (mDebugPaint == null) {
+                mDebugPaint = new Paint();
+                mDebugPaint.setColor(0x7fff0000);
+            }
+
+            if (dirty != null && (mFrameCount & 1) == 0) {
+                canvas.drawRect(dirty, mDebugPaint);
+            }
+        }
+    }
+
+    private void handleFunctorStatus(View.AttachInfo attachInfo, int status) {
+        // If the draw flag is set, functors will be invoked while executing
+        // the tree of display lists
+        if ((status & RenderNode.STATUS_DRAW) != 0) {
+            if (mRedrawClip.isEmpty()) {
+                attachInfo.mViewRootImpl.invalidate();
+            } else {
+                attachInfo.mViewRootImpl.invalidateChildInParent(null, mRedrawClip);
+                mRedrawClip.setEmpty();
+            }
+        }
+
+        if ((status & RenderNode.STATUS_INVOKE) != 0 ||
+                attachInfo.mHandler.hasCallbacks(mFunctorsRunnable)) {
+            attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
+            mFunctorsRunnable.attachInfo = attachInfo;
+            attachInfo.mHandler.postDelayed(mFunctorsRunnable, FUNCTOR_PROCESS_DELAY);
+        }
+    }
+
+    @Override
+    void detachFunctor(long functor) {
+        if (mCanvas != null) {
+            mCanvas.detachFunctor(functor);
+        }
+    }
+
+    @Override
+    void attachFunctor(View.AttachInfo attachInfo, long functor) {
+        if (mCanvas != null) {
+            mCanvas.attachFunctor(functor);
+            mFunctorsRunnable.attachInfo = attachInfo;
+            attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
+            attachInfo.mHandler.postDelayed(mFunctorsRunnable,  0);
+        }
+    }
+
+    /**
+     * 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 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());
+        }
+
+        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()));
+                fallback(true);
+                return SURFACE_STATE_ERROR;
+            } else {
+                if (mUpdateDirtyRegions) {
+                    enableDirtyRegions();
+                    mUpdateDirtyRegions = false;
+                }
+                return SURFACE_STATE_UPDATED;
+            }
+        }
+        return SURFACE_STATE_SUCCESS;
+    }
+
+    private static int dpToPx(int dp, float density) {
+        return (int) (dp * density + 0.5f);
+    }
+
+    static native boolean loadProperties();
+
+    static native void setupShadersDiskCache(String cacheFile);
+
+    /**
+     * Notifies EGL that the frame is about to be rendered.
+     * @param size
+     */
+    static native void beginFrame(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 native long getSystemTime();
+
+    /**
+     * 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
+     * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
+     *
+     * @return True if the swap behavior was successfully changed,
+     *         false otherwise.
+     */
+    static native boolean preserveBackBuffer();
+
+    /**
+     * Indicates whether the current surface preserves its back buffer
+     * after a buffer swap.
+     *
+     * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
+     *         false otherwise
+     */
+    static native boolean isBackBufferPreserved();
+
+    static native void nDestroyLayer(long layerPtr);
+
+    class DrawPerformanceDataProvider extends GraphDataProvider {
+        private final int mGraphType;
+
+        private int mVerticalUnit;
+        private int mHorizontalUnit;
+        private int mHorizontalMargin;
+        private int mThresholdStroke;
+
+        DrawPerformanceDataProvider(int graphType) {
+            mGraphType = graphType;
+        }
+
+        @Override
+        void prepare(DisplayMetrics metrics) {
+            final float density = metrics.density;
+
+            mVerticalUnit = dpToPx(PROFILE_DRAW_DP_PER_MS, density);
+            mHorizontalUnit = dpToPx(PROFILE_DRAW_WIDTH, density);
+            mHorizontalMargin = dpToPx(PROFILE_DRAW_MARGIN, density);
+            mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
+        }
+
+        @Override
+        int getGraphType() {
+            return mGraphType;
+        }
+
+        @Override
+        int getVerticalUnitSize() {
+            return mVerticalUnit;
+        }
+
+        @Override
+        int getHorizontalUnitSize() {
+            return mHorizontalUnit;
+        }
+
+        @Override
+        int getHorizontaUnitMargin() {
+            return mHorizontalMargin;
+        }
+
+        @Override
+        float[] getData() {
+            return mProfileData;
+        }
+
+        @Override
+        float getThreshold() {
+            return 16;
+        }
+
+        @Override
+        int getFrameCount() {
+            return mProfileData.length / PROFILE_FRAME_DATA_COUNT;
+        }
+
+        @Override
+        int getElementCount() {
+            return PROFILE_FRAME_DATA_COUNT;
+        }
+
+        @Override
+        int getCurrentFrame() {
+            return mProfileCurrentFrame / PROFILE_FRAME_DATA_COUNT;
+        }
+
+        @Override
+        void setupGraphPaint(Paint paint, int elementIndex) {
+            paint.setColor(PROFILE_DRAW_COLORS[elementIndex]);
+            if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
+        }
+
+        @Override
+        void setupThresholdPaint(Paint paint) {
+            paint.setColor(PROFILE_DRAW_THRESHOLD_COLOR);
+            paint.setStrokeWidth(mThresholdStroke);
+        }
+
+        @Override
+        void setupCurrentFramePaint(Paint paint) {
+            paint.setColor(PROFILE_DRAW_CURRENT_FRAME_COLOR);
+            if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
+        }
+    }
+}
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index 8f40260..26f47f9 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -41,6 +41,11 @@
     public static final int KEYBOARD_TAP = 3;
 
     /**
+     * The user has pressed either an hour or minute tick of a Clock.
+     */
+    public static final int CLOCK_TICK = 4;
+
+    /**
      * This is a private constant.  Feel free to renumber as desired.
      * @hide
      */
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index 10f700c..f695b20 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -27,7 +27,6 @@
  * @hide
  */
 public abstract class HardwareCanvas extends Canvas {
-    private String mName;
 
     @Override
     public boolean isHardwareAccelerated() {
@@ -40,37 +39,10 @@
     }
 
     /**
-     * Specifies the name of this canvas. Naming the canvas is entirely
-     * optional but can be useful for debugging purposes.
-     *
-     * @param name The name of the canvas, can be null
-     *
-     * @see #getName()
-     *
-     * @hide
-     */
-    public void setName(String name) {
-        mName = name;
-    }
-
-    /**
-     * Returns the name of this canvas.
-     *
-     * @return The name of the canvas or null
-     *
-     * @see #setName(String)
-     *
-     * @hide
-     */
-    public String getName() {
-        return mName;
-    }
-
-    /**
      * Invoked before any drawing operation is performed in this canvas.
      * 
      * @param dirty The dirty rectangle to update, can be null.
-     * @return {@link DisplayList#STATUS_DREW} if anything was drawn (such as a call to clear
+     * @return {@link RenderNode#STATUS_DREW} if anything was drawn (such as a call to clear
      *         the canvas).
      *
      * @hide
@@ -86,12 +58,12 @@
 
     /**
      * Draws the specified display list onto this canvas. The display list can only
-     * be drawn if {@link android.view.DisplayList#isValid()} returns true.
+     * be drawn if {@link android.view.RenderNode#isValid()} returns true.
      *
      * @param displayList The display list to replay.
      */
-    public void drawDisplayList(DisplayList displayList) {
-        drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
+    public void drawDisplayList(RenderNode displayList) {
+        drawDisplayList(displayList, null, RenderNode.FLAG_CLIP_CHILDREN);
     }
 
     /**
@@ -99,27 +71,17 @@
      *
      * @param displayList The display list to replay.
      * @param dirty The dirty region to redraw in the next pass, matters only
-     *        if this method returns {@link DisplayList#STATUS_DRAW}, can be null.
-     * @param flags Optional flags about drawing, see {@link DisplayList} for
+     *        if this method returns {@link RenderNode#STATUS_DRAW}, can be null.
+     * @param flags Optional flags about drawing, see {@link RenderNode} for
      *              the possible flags.
      *
-     * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW}, or
-     *         {@link DisplayList#STATUS_INVOKE}, or'd with {@link DisplayList#STATUS_DREW}
+     * @return One of {@link RenderNode#STATUS_DONE}, {@link RenderNode#STATUS_DRAW}, or
+     *         {@link RenderNode#STATUS_INVOKE}, or'd with {@link RenderNode#STATUS_DREW}
      *         if anything was drawn.
      *
      * @hide
      */
-    public abstract int drawDisplayList(DisplayList displayList, Rect dirty, int flags);
-
-    /**
-     * Outputs the specified display list to the log. This method exists for use by
-     * tools to output display lists for selected nodes to the log.
-     *
-     * @param displayList The display list to be logged.
-     *
-     * @hide
-     */
-    abstract void outputDisplayList(DisplayList displayList);
+    public abstract int drawDisplayList(RenderNode displayList, Rect dirty, int flags);
 
     /**
      * Draws the specified layer onto this canvas.
@@ -140,28 +102,28 @@
      *
      * @param drawGLFunction A native function pointer
      *                       
-     * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW} or
-     *         {@link DisplayList#STATUS_INVOKE}
+     * @return One of {@link RenderNode#STATUS_DONE}, {@link RenderNode#STATUS_DRAW} or
+     *         {@link RenderNode#STATUS_INVOKE}
      *
      * @hide
      */
     public int callDrawGLFunction(long drawGLFunction) {
         // Noop - this is done in the display list recorder subclass
-        return DisplayList.STATUS_DONE;
+        return RenderNode.STATUS_DONE;
     }
 
     /**
      * Invoke all the functors who requested to be invoked during the previous frame.
      * 
-     * @param dirty The region to redraw when the functors return {@link DisplayList#STATUS_DRAW}
+     * @param dirty The region to redraw when the functors return {@link RenderNode#STATUS_DRAW}
      *              
-     * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW} or
-     *         {@link DisplayList#STATUS_INVOKE}
+     * @return One of {@link RenderNode#STATUS_DONE}, {@link RenderNode#STATUS_DRAW} or
+     *         {@link RenderNode#STATUS_INVOKE}
      *
      * @hide
      */
     public int invokeFunctors(Rect dirty) {
-        return DisplayList.STATUS_DONE;
+        return RenderNode.STATUS_DONE;
     }
 
     /**
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 23383d9..4d78733 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -17,10 +17,10 @@
 package android.view;
 
 import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
 
 /**
  * A hardware layer can be used to render graphics operations into a hardware
@@ -28,38 +28,35 @@
  * would use a Frame Buffer Object (FBO.) The hardware layer can be used as
  * a drawing cache when a complex set of graphics operations needs to be
  * drawn several times.
+ *
+ * @hide
  */
-abstract class HardwareLayer {
-    /**
-     * Indicates an unknown dimension (width or height.)
-     */
-    static final int DIMENSION_UNDEFINED = -1;
-    
-    int mWidth;
-    int mHeight;
-    DisplayList mDisplayList;
+final class HardwareLayer {
+    private static final int LAYER_TYPE_TEXTURE = 1;
+    private static final int LAYER_TYPE_DISPLAY_LIST = 2;
 
-    boolean mOpaque;
+    private HardwareRenderer mRenderer;
+    private Finalizer mFinalizer;
+    private RenderNode mDisplayList;
+    private final int mLayerType;
 
-    /**
-     * Creates a new hardware layer with undefined dimensions.
-     */
-    HardwareLayer() {
-        this(DIMENSION_UNDEFINED, DIMENSION_UNDEFINED, false);
+    private HardwareLayer(HardwareRenderer renderer, long deferredUpdater, int type) {
+        if (renderer == null || deferredUpdater == 0) {
+            throw new IllegalArgumentException("Either hardware renderer: " + renderer
+                    + " or deferredUpdater: " + deferredUpdater + " is invalid");
+        }
+        mRenderer = renderer;
+        mLayerType = type;
+        mFinalizer = new Finalizer(deferredUpdater);
+
+        // Layer is considered initialized at this point, notify the HardwareRenderer
+        mRenderer.onLayerCreated(this);
     }
 
-    /**
-     * Creates a new hardware layer at least as large as the supplied
-     * dimensions.
-     * 
-     * @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
-     */
-    HardwareLayer(int width, int height, boolean isOpaque) {
-        mWidth = width;
-        mHeight = height;
-        mOpaque = isOpaque;
+    private void assertType(int type) {
+        if (mLayerType != type) {
+            throw new IllegalAccessError("Method not appropriate for this layer type! " + mLayerType);
+        }
     }
 
     /**
@@ -68,158 +65,244 @@
      * @param paint The paint used when the layer is drawn into the destination canvas.
      * @see View#setLayerPaint(android.graphics.Paint)
      */
-    void setLayerPaint(Paint paint) { }
-
-    /**
-     * Returns the minimum width of the layer.
-     * 
-     * @return The minimum desired width of the hardware layer 
-     */
-    int getWidth() {
-        return mWidth;
+    public void setLayerPaint(Paint paint) {
+        nSetLayerPaint(mFinalizer.mDeferredUpdater, paint.mNativePaint);
     }
 
     /**
-     * Returns the minimum height of the layer.
-     * 
-     * @return The minimum desired height of the hardware layer 
-     */
-    int getHeight() {
-        return mHeight;
-    }
-
-    /**
-     * Returns the DisplayList for the layer.
-     *
-     * @return The DisplayList of the hardware layer
-     */
-    DisplayList getDisplayList() {
-        return mDisplayList;
-    }
-
-    /**
-     * Sets the DisplayList for the layer.
-     *
-     * @param displayList The new DisplayList for this layer
-     */
-    void setDisplayList(DisplayList displayList) {
-        mDisplayList = displayList;
-    }
-
-    /**
-     * Returns whether or not this layer is opaque.
-     * 
-     * @return True if the layer is opaque, false otherwise
-     */
-    boolean isOpaque() {
-        return mOpaque;
-    }
-
-    /**
-     * Sets whether or not this layer should be considered opaque.
-     * 
-     * @param isOpaque True if the layer is opaque, false otherwise
-     */
-    abstract void setOpaque(boolean isOpaque);
-
-    /**
      * Indicates whether this layer can be rendered.
-     * 
+     *
      * @return True if the layer can be rendered into, false otherwise
      */
-    abstract boolean isValid();
+    public boolean isValid() {
+        return mFinalizer != null && mFinalizer.mDeferredUpdater != 0;
+    }
 
     /**
-     * Resize the layer, if necessary, to be at least as large
-     * as the supplied dimensions.
-     * 
-     * @param width The new desired minimum width for this layer
-     * @param height The new desired minimum height for this layer
-     * @return True if the resulting layer is valid, false otherwise
+     * Destroys resources without waiting for a GC.
      */
-    abstract boolean resize(int width, int height);
+    public void destroy() {
+        if (!isValid()) {
+            // Already destroyed
+            return;
+        }
+
+        if (mDisplayList != null) {
+            mDisplayList.destroyDisplayListData();
+            mDisplayList = null;
+        }
+        if (mRenderer != null) {
+            mRenderer.onLayerDestroyed(this);
+            mRenderer = null;
+        }
+        doDestroyLayerUpdater();
+    }
+
+    public long getDeferredLayerUpdater() {
+        return mFinalizer.mDeferredUpdater;
+    }
 
     /**
-     * Returns a hardware canvas that can be used to render onto
-     * this layer.
-     * 
-     * @return A hardware canvas, or null if a canvas cannot be created
+     * Destroys the deferred layer updater but not the backing layer. The
+     * backing layer is instead returned and is the caller's responsibility
+     * to destroy/recycle as appropriate.
      *
-     * @see #start(android.graphics.Canvas)
-     * @see #end(android.graphics.Canvas)
+     * It is safe to call this in onLayerDestroyed only
      */
-    abstract HardwareCanvas getCanvas();
+    public long detachBackingLayer() {
+        long backingLayer = nDetachBackingLayer(mFinalizer.mDeferredUpdater);
+        doDestroyLayerUpdater();
+        return backingLayer;
+    }
 
-    /**
-     * Destroys resources without waiting for a GC. 
-     */
-    abstract void destroy();
+    private void doDestroyLayerUpdater() {
+        if (mFinalizer != null) {
+            mFinalizer.destroy();
+            mFinalizer = null;
+        }
+    }
 
-    /**
-     * This must be invoked before drawing onto this layer.
-     *
-     * @param currentCanvas The canvas whose rendering needs to be interrupted
-     */
-    abstract HardwareCanvas start(Canvas currentCanvas);
+    public RenderNode startRecording() {
+        assertType(LAYER_TYPE_DISPLAY_LIST);
 
-    /**
-     * 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);
+        if (mDisplayList == null) {
+            mDisplayList = RenderNode.create("HardwareLayer");
+        }
+        return mDisplayList;
+    }
 
-    /**
-     * This must be invoked after drawing onto this layer.
-     *
-     * @param currentCanvas The canvas whose rendering needs to be resumed
-     */
-    abstract void end(Canvas currentCanvas);
+    public void endRecording(Rect dirtyRect) {
+        nUpdateRenderLayer(mFinalizer.mDeferredUpdater, mDisplayList.getNativeDisplayList(),
+                dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
+        mRenderer.pushLayerUpdate(this);
+    }
 
     /**
      * Copies this layer into the specified bitmap.
-     * 
+     *
      * @param bitmap The bitmap to copy they layer into
-     * 
+     *
      * @return True if the copy was successful, false otherwise
      */
-    abstract boolean copyInto(Bitmap bitmap);
+    public boolean copyInto(Bitmap bitmap) {
+        return mRenderer.copyLayerInto(this, bitmap);
+    }
 
     /**
-     * Update the layer's properties. This method should be used
-     * when the underlying storage is modified by an external entity.
-     * To change the underlying storage, use the {@link #resize(int, int)}
-     * method instead.
-     * 
+     * Update the layer's properties. Note that after calling this isValid() may
+     * return false if the requested width/height cannot be satisfied
+     *
      * @param width The new width of this layer
      * @param height The new height of this layer
      * @param isOpaque Whether this layer is opaque
+     *
+     * @return true if the layer's properties will change, false if they already
+     *         match the desired values.
      */
-    void update(int width, int height, boolean isOpaque) {
-        mWidth = width;
-        mHeight = height;
-        mOpaque = isOpaque;
+    public boolean prepare(int width, int height, boolean isOpaque) {
+        return nPrepare(mFinalizer.mDeferredUpdater, width, height, isOpaque);
     }
 
     /**
      * Sets an optional transform on this layer.
-     * 
+     *
      * @param matrix The transform to apply to the layer.
      */
-    abstract void setTransform(Matrix matrix);
+    public void setTransform(Matrix matrix) {
+        nSetTransform(mFinalizer.mDeferredUpdater, matrix.native_instance);
+    }
 
     /**
-     * Specifies the display list to use to refresh the layer.
-     *
-     * @param displayList The display list containing the drawing commands to
-     *                    execute in this layer
-     * @param dirtyRect The dirty region of the layer that needs to be redrawn
+     * Indicates that this layer has lost its texture.
      */
-    abstract void redrawLater(DisplayList displayList, Rect dirtyRect);
+    public void detachSurfaceTexture(final SurfaceTexture surface) {
+        assertType(LAYER_TYPE_TEXTURE);
+        mRenderer.safelyRun(new Runnable() {
+            @Override
+            public void run() {
+                surface.detachFromGLContext();
+                // SurfaceTexture owns the texture name and detachFromGLContext
+                // should have deleted it
+                nOnTextureDestroyed(mFinalizer.mDeferredUpdater);
+            }
+        });
+    }
 
     /**
-     * Indicates that this layer has lost its underlying storage.
+     * This exists to minimize impact into the current HardwareLayer paths as
+     * some of the specifics of how to handle error cases in the fully
+     * deferred model will work
      */
-    abstract void clearStorage();
+    @Deprecated
+    public void flushChanges() {
+        if (HardwareRenderer.sUseRenderThread) {
+            // Not supported, don't try.
+            return;
+        }
+
+        boolean success = nFlushChanges(mFinalizer.mDeferredUpdater);
+        if (!success) {
+            destroy();
+        }
+    }
+
+    public long getLayer() {
+        return nGetLayer(mFinalizer.mDeferredUpdater);
+    }
+
+    public void setSurfaceTexture(SurfaceTexture surface) {
+        assertType(LAYER_TYPE_TEXTURE);
+        nSetSurfaceTexture(mFinalizer.mDeferredUpdater, surface, false);
+    }
+
+    public void updateSurfaceTexture() {
+        assertType(LAYER_TYPE_TEXTURE);
+        nUpdateSurfaceTexture(mFinalizer.mDeferredUpdater);
+    }
+
+    /**
+     * This should only be used by HardwareRenderer! Do not call directly
+     */
+    SurfaceTexture createSurfaceTexture() {
+        assertType(LAYER_TYPE_TEXTURE);
+        SurfaceTexture st = new SurfaceTexture(nGetTexName(mFinalizer.mDeferredUpdater));
+        nSetSurfaceTexture(mFinalizer.mDeferredUpdater, st, true);
+        return st;
+    }
+
+    /**
+     * This should only be used by HardwareRenderer! Do not call directly
+     */
+    static HardwareLayer createTextureLayer(HardwareRenderer renderer) {
+        return new HardwareLayer(renderer, nCreateTextureLayer(), LAYER_TYPE_TEXTURE);
+    }
+
+    static HardwareLayer adoptTextureLayer(HardwareRenderer renderer, long layer) {
+        return new HardwareLayer(renderer, layer, LAYER_TYPE_TEXTURE);
+    }
+
+    /**
+     * This should only be used by HardwareRenderer! Do not call directly
+     */
+    static HardwareLayer createDisplayListLayer(HardwareRenderer renderer,
+            int width, int height) {
+        return new HardwareLayer(renderer, nCreateRenderLayer(width, height), LAYER_TYPE_DISPLAY_LIST);
+    }
+
+    static HardwareLayer adoptDisplayListLayer(HardwareRenderer renderer, long layer) {
+        return new HardwareLayer(renderer, layer, LAYER_TYPE_DISPLAY_LIST);
+    }
+
+    /** This also creates the underlying layer */
+    private static native long nCreateTextureLayer();
+    private static native long nCreateRenderLayer(int width, int height);
+
+    private static native void nOnTextureDestroyed(long layerUpdater);
+    private static native long nDetachBackingLayer(long layerUpdater);
+
+    /** This also destroys the underlying layer if it is still attached.
+     *  Note it does not recycle the underlying layer, but instead queues it
+     *  for deferred deletion.
+     *  The HardwareRenderer should use detachBackingLayer() in the
+     *  onLayerDestroyed() callback to do recycling if desired.
+     */
+    private static native void nDestroyLayerUpdater(long layerUpdater);
+
+    private static native boolean nPrepare(long layerUpdater, int width, int height, boolean isOpaque);
+    private static native void nSetLayerPaint(long layerUpdater, long paint);
+    private static native void nSetTransform(long layerUpdater, long matrix);
+    private static native void nSetSurfaceTexture(long layerUpdater,
+            SurfaceTexture surface, boolean isAlreadyAttached);
+    private static native void nUpdateSurfaceTexture(long layerUpdater);
+    private static native void nUpdateRenderLayer(long layerUpdater, long displayList,
+            int left, int top, int right, int bottom);
+
+    private static native boolean nFlushChanges(long layerUpdater);
+
+    private static native long nGetLayer(long layerUpdater);
+    private static native int nGetTexName(long layerUpdater);
+
+    private static class Finalizer {
+        private long mDeferredUpdater;
+
+        public Finalizer(long deferredUpdater) {
+            mDeferredUpdater = deferredUpdater;
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            try {
+                destroy();
+            } finally {
+                super.finalize();
+            }
+        }
+
+        void destroy() {
+            if (mDeferredUpdater != 0) {
+                nDestroyLayerUpdater(mDeferredUpdater);
+                mDeferredUpdater = 0;
+            }
+        }
+    }
 }
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index f09a111..34efcf5 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -16,41 +16,15 @@
 
 package android.view;
 
-import android.content.ComponentCallbacks2;
-import android.graphics.Color;
+import android.graphics.Bitmap;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
-import android.opengl.EGL14;
-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;
-import javax.microedition.khronos.egl.EGL11;
-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.GL;
-
 import java.io.File;
 import java.io.PrintWriter;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static javax.microedition.khronos.egl.EGL10.*;
 
 /**
  * Interface for rendering a view hierarchy using hardware acceleration.
@@ -66,13 +40,6 @@
     private static final String CACHE_PATH_SHADERS = "com.android.opengl.shaders_cache";
 
     /**
-     * Turn on to only refresh the parts of the screen that need updating.
-     * When turned on the property defined by {@link #RENDER_DIRTY_REGIONS_PROPERTY}
-     * must also have the value "true".
-     */
-    static final boolean RENDER_DIRTY_REGIONS = true;
-
-    /**
      * 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.
@@ -187,14 +154,6 @@
     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.
      *
      * Possible values:
@@ -222,15 +181,8 @@
      */
     public static boolean sSystemRendererDisabled = false;
 
-    /**
-     * Number of frames to profile.
-     */
-    private static final int PROFILE_MAX_FRAMES = 128;
-
-    /**
-     * Number of floats per profiled frame.
-     */
-    private static final int PROFILE_FRAME_DATA_COUNT = 3;
+    /** @hide */
+    public static boolean sUseRenderThread = false;
 
     private boolean mEnabled;
     private boolean mRequested = true;
@@ -282,13 +234,6 @@
     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);
-
-    /**
      * Destroys all hardware rendering resources associated with the specified
      * view hierarchy.
      *
@@ -305,15 +250,6 @@
     abstract void invalidate(Surface surface);
 
     /**
-     * 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();
-
-    /**
      * This method ensures the hardware renderer is in a valid state
      * before executing the specified action.
      *
@@ -350,13 +286,6 @@
     abstract int getHeight();
 
     /**
-     * Gets the current canvas associated with this HardwareRenderer.
-     *
-     * @return the current HardwareCanvas
-     */
-    abstract HardwareCanvas getCanvas();
-
-    /**
      * Outputs extra debugging information in the specified file descriptor.
      * @param pw
      */
@@ -379,9 +308,7 @@
      *
      * @return True if a property has changed.
      */
-    abstract boolean loadSystemProperties(Surface surface);
-
-    private static native boolean nLoadProperties();
+    abstract boolean loadSystemProperties();
 
     /**
      * Sets the directory to use as a persistent storage for hardware rendering
@@ -392,60 +319,9 @@
      * @hide
      */
     public static void setupDiskCache(File cacheDir) {
-        nSetupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
+        GLRenderer.setupShadersDiskCache(new File(cacheDir, CACHE_PATH_SHADERS).getAbsolutePath());
     }
 
-    private static native void nSetupShadersDiskCache(String cacheFile);
-
-    /**
-     * Notifies EGL that the frame is about to be rendered.
-     * @param size
-     */
-    static void beginFrame(int[] size) {
-        nBeginFrame(size);
-    }
-
-    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
-     * config that supports EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
-     *
-     * @return True if the swap behavior was successfully changed,
-     *         false otherwise.
-     */
-    static boolean preserveBackBuffer() {
-        return nPreserveBackBuffer();
-    }
-
-    private static native boolean nPreserveBackBuffer();
-
-    /**
-     * Indicates whether the current surface preserves its back buffer
-     * after a buffer swap.
-     *
-     * @return True, if the surface's EGL_SWAP_BEHAVIOR is EGL_BUFFER_PRESERVED,
-     *         false otherwise
-     */
-    static boolean isBackBufferPreserved() {
-        return nIsBackBufferPreserved();
-    }
-
-    private static native boolean nIsBackBufferPreserved();
-
     /**
      * Indicates that the specified hardware layer needs to be updated
      * as soon as possible.
@@ -453,19 +329,20 @@
      * @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)
+     * Tells the HardwareRenderer that a layer was created. The renderer should
+     * make sure to apply any pending layer changes at the start of a new frame
      */
-    abstract void cancelLayerUpdate(HardwareLayer layer);
+    abstract void onLayerCreated(HardwareLayer hardwareLayer);
+
+    /**
+     * Tells the HardwareRenderer that the layer is destroyed. The renderer
+     * should remove the layer from any update queues.
+     */
+    abstract void onLayerDestroyed(HardwareLayer layer);
 
     /**
      * Forces all enqueued layer updates to be executed immediately.
@@ -509,37 +386,22 @@
             Rect dirty);
 
     /**
-     * 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
-     */
-    public abstract DisplayList createDisplayList(String name);
-
-    /**
      * 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);
+    abstract HardwareLayer createTextureLayer();
 
     /**
      * 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);
+    abstract HardwareLayer createDisplayListLayer(int width, int height);
 
     /**
      * Creates a new {@link SurfaceTexture} that can be used to render into the
@@ -551,14 +413,7 @@
      */
     abstract SurfaceTexture createSurfaceTexture(HardwareLayer layer);
 
-    /**
-     * Sets the {@link android.graphics.SurfaceTexture} that will be used to
-     * render into the specified hardware layer.
-     *
-     * @param layer The layer to render into using a {@link android.graphics.SurfaceTexture}
-     * @param surfaceTexture The {@link android.graphics.SurfaceTexture} to use for the layer
-     */
-    abstract void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture);
+    abstract boolean copyLayerInto(HardwareLayer layer, Bitmap bitmap);
 
     /**
      * Detaches the specified functor from the current functor execution queue.
@@ -566,7 +421,7 @@
      * @param functor The native functor to remove from the execution queue.
      *
      * @see HardwareCanvas#callDrawGLFunction(int)
-     * @see #attachFunctor(android.view.View.AttachInfo, int)
+     * @see #attachFunctor(android.view.View.AttachInfo, long)
      */
     abstract void detachFunctor(long functor);
 
@@ -577,11 +432,10 @@
      * @param functor The native functor to insert in the execution queue.
      *
      * @see HardwareCanvas#callDrawGLFunction(int)
-     * @see #detachFunctor(int)
+     * @see #detachFunctor(long)
      *
-     * @return true if the functor was attached successfully
      */
-    abstract boolean attachFunctor(View.AttachInfo attachInfo, long functor);
+    abstract void attachFunctor(View.AttachInfo attachInfo, long functor);
 
     /**
      * Initializes the hardware renderer for the specified surface and setup the
@@ -621,17 +475,20 @@
     /**
      * 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) {
-        switch (glVersion) {
-            case 2:
-                return Gl20Renderer.create(translucent);
+    static HardwareRenderer create(boolean translucent) {
+        HardwareRenderer renderer = null;
+        if (GLES20Canvas.isAvailable()) {
+            if (sUseRenderThread) {
+                renderer = new ThreadedRenderer(translucent);
+            } else {
+                renderer = new GLRenderer(translucent);
+            }
         }
-        throw new IllegalArgumentException("Unknown GL version: " + glVersion);
+        return renderer;
     }
 
     /**
@@ -656,7 +513,7 @@
      *              see {@link android.content.ComponentCallbacks}
      */
     static void startTrimMemory(int level) {
-        Gl20Renderer.startTrimMemory(level);
+        GLRenderer.startTrimMemory(level);
     }
 
     /**
@@ -664,7 +521,7 @@
      * cleanup special resources used by the memory trimming process.
      */
     static void endTrimMemory() {
-        Gl20Renderer.endTrimMemory();
+        GLRenderer.endTrimMemory();
     }
 
     /**
@@ -705,6 +562,8 @@
         mRequested = requested;
     }
 
+    abstract void setDisplayListData(long displayList, long newData);
+
     /**
      * Describes a series of frames that should be drawn on screen as a graph.
      * Each frame is composed of 1 or more elements.
@@ -798,1553 +657,4 @@
          */
         abstract void setupCurrentFramePaint(Paint paint);
     }
-
-    @SuppressWarnings({"deprecation"})
-    static abstract class GlRenderer extends HardwareRenderer {
-        static final int SURFACE_STATE_ERROR = 0;
-        static final int SURFACE_STATE_SUCCESS = 1;
-        static final int SURFACE_STATE_UPDATED = 2;
-
-        static final int FUNCTOR_PROCESS_DELAY = 4;
-
-        private static final int PROFILE_DRAW_MARGIN = 0;
-        private static final int PROFILE_DRAW_WIDTH = 3;
-        private static final int[] PROFILE_DRAW_COLORS = { 0xcf3e66cc, 0xcfdc3912, 0xcfe69800 };
-        private static final int PROFILE_DRAW_CURRENT_FRAME_COLOR = 0xcf5faa4d;
-        private static final int PROFILE_DRAW_THRESHOLD_COLOR = 0xff5faa4d;
-        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;
-        static final Object[] sEglLock = new Object[0];
-        int mWidth = -1, mHeight = -1;
-
-        static final ThreadLocal<ManagedEGLContext> sEglContextStorage
-                = new ThreadLocal<ManagedEGLContext>();
-
-        EGLContext mEglContext;
-        Thread mEglThread;
-
-        EGLSurface mEglSurface;
-
-        GL mGl;
-        HardwareCanvas mCanvas;
-
-        String mName;
-
-        long mFrameCount;
-        Paint mDebugPaint;
-
-        static boolean sDirtyRegions;
-        static final boolean sDirtyRegionsRequested;
-        static {
-            String dirtyProperty = SystemProperties.get(RENDER_DIRTY_REGIONS_PROPERTY, "true");
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            sDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty);
-            sDirtyRegionsRequested = sDirtyRegions;
-        }
-
-        boolean mDirtyRegionsEnabled;
-        boolean mUpdateDirtyRegions;
-
-        boolean mProfileEnabled;
-        int mProfileVisualizerType = -1;
-        float[] mProfileData;
-        ReentrantLock mProfileLock;
-        int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
-
-        GraphDataProvider mDebugDataProvider;
-        float[][] mProfileShapes;
-        Paint mProfilePaint;
-
-        boolean mDebugDirtyRegions;
-        int mDebugOverdraw = -1;
-        HardwareLayer mDebugOverdrawLayer;
-        Paint mDebugOverdrawPaint;
-
-        final int mGlVersion;
-        final boolean mTranslucent;
-
-        private boolean mDestroyed;
-
-        private final Rect mRedrawClip = new Rect();
-
-        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;
-
-            loadSystemProperties(null);
-        }
-
-        @Override
-        boolean loadSystemProperties(Surface surface) {
-            boolean value;
-            boolean changed = false;
-
-            String profiling = SystemProperties.get(PROFILE_PROPERTY);
-            int graphType = search(VISUALIZERS, profiling);
-            value = graphType >= 0;
-
-            if (graphType != mProfileVisualizerType) {
-                changed = true;
-                mProfileVisualizerType = graphType;
-
-                mProfileShapes = null;
-                mProfilePaint = null;
-
-                if (value) {
-                    mDebugDataProvider = new DrawPerformanceDataProvider(graphType);
-                } else {
-                    mDebugDataProvider = null;
-                }
-            }
-
-            // If on-screen profiling is not enabled, we need to check whether
-            // console profiling only is enabled
-            if (!value) {
-                value = Boolean.parseBoolean(profiling);
-            }
-
-            if (value != mProfileEnabled) {
-                changed = true;
-                mProfileEnabled = value;
-
-                if (mProfileEnabled) {
-                    Log.d(LOG_TAG, "Profiling hardware renderer");
-
-                    int maxProfileFrames = SystemProperties.getInt(PROFILE_MAXFRAMES_PROPERTY,
-                            PROFILE_MAX_FRAMES);
-                    mProfileData = new float[maxProfileFrames * PROFILE_FRAME_DATA_COUNT];
-                    for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
-                        mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
-                    }
-
-                    mProfileLock = new ReentrantLock();
-                } else {
-                    mProfileData = null;
-                    mProfileLock = null;
-                    mProfileVisualizerType = -1;
-                }
-
-                mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
-            }
-
-            value = SystemProperties.getBoolean(DEBUG_DIRTY_REGIONS_PROPERTY, false);
-            if (value != mDebugDirtyRegions) {
-                changed = true;
-                mDebugDirtyRegions = value;
-
-                if (mDebugDirtyRegions) {
-                    Log.d(LOG_TAG, "Debugging dirty regions");
-                }
-            }
-
-            String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
-            int debugOverdraw = search(OVERDRAW, overdraw);
-            if (debugOverdraw != mDebugOverdraw) {
-                changed = true;
-                mDebugOverdraw = debugOverdraw;
-
-                if (mDebugOverdraw != OVERDRAW_TYPE_COUNT) {
-                    if (mDebugOverdrawLayer != null) {
-                        mDebugOverdrawLayer.destroy();
-                        mDebugOverdrawLayer = null;
-                        mDebugOverdrawPaint = null;
-                    }
-                }
-            }
-
-            if (nLoadProperties()) {
-                changed = true;
-            }
-
-            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) {
-                pw.printf("\n\tDraw\tProcess\tExecute\n");
-
-                mProfileLock.lock();
-                try {
-                    for (int i = 0; i < mProfileData.length; i += PROFILE_FRAME_DATA_COUNT) {
-                        if (mProfileData[i] < 0) {
-                            break;
-                        }
-                        pw.printf("\t%3.2f\t%3.2f\t%3.2f\n", mProfileData[i], mProfileData[i + 1],
-                                mProfileData[i + 2]);
-                        mProfileData[i] = mProfileData[i + 1] = mProfileData[i + 2] = -1;
-                    }
-                    mProfileCurrentFrame = mProfileData.length;
-                } finally {
-                    mProfileLock.unlock();
-                }
-            }
-        }
-
-        @Override
-        long getFrameCount() {
-            return mFrameCount;
-        }
-
-        /**
-         * Indicates whether this renderer instance can track and update dirty regions.
-         */
-        boolean hasDirtyRegions() {
-            return mDirtyRegionsEnabled;
-        }
-
-        /**
-         * Checks for OpenGL errors. If an error has occured, {@link #destroy(boolean)}
-         * is invoked and the requested flag is turned off. The error code is
-         * also logged as a warning.
-         */
-        void checkEglErrors() {
-            if (isEnabled()) {
-                checkEglErrorsForced();
-            }
-        }
-
-        private void checkEglErrorsForced() {
-            int error = sEgl.eglGetError();
-            if (error != EGL_SUCCESS) {
-                // something bad has happened revert to
-                // normal rendering.
-                Log.w(LOG_TAG, "EGL error: " + GLUtils.getEGLErrorString(error));
-                fallback(error != EGL11.EGL_CONTEXT_LOST);
-            }
-        }
-
-        private void fallback(boolean fallback) {
-            destroy(true);
-            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. "
-                        + "Switching back to software rendering.");
-            }
-        }
-
-        @Override
-        boolean initialize(Surface surface) throws OutOfResourcesException {
-            if (isRequested() && !isEnabled()) {
-                boolean contextCreated = initializeEgl();
-                mGl = createEglSurface(surface);
-                mDestroyed = false;
-
-                if (mGl != null) {
-                    int err = sEgl.eglGetError();
-                    if (err != EGL_SUCCESS) {
-                        destroy(true);
-                        setRequested(false);
-                    } else {
-                        if (mCanvas == null) {
-                            mCanvas = createCanvas();
-                            mCanvas.setName(mName);
-                        }
-                        setEnabled(true);
-
-                        if (contextCreated) {
-                            initAtlas();
-                        }
-                    }
-
-                    return mCanvas != null;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        void updateSurface(Surface surface) throws OutOfResourcesException {
-            if (isRequested() && isEnabled()) {
-                createEglSurface(surface);
-            }
-        }
-
-        abstract HardwareCanvas createCanvas();
-
-        abstract int[] getConfig(boolean dirtyRegions);
-
-        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)) {
-                        throw new RuntimeException("eglInitialize failed " +
-                                GLUtils.getEGLErrorString(sEgl.eglGetError()));
-                    }
-
-                    checkEglErrorsForced();
-
-                    sEglConfig = loadEglConfig();
-                }
-            }
-
-            ManagedEGLContext managedContext = sEglContextStorage.get();
-            mEglContext = managedContext != null ? managedContext.getContext() : null;
-            mEglThread = Thread.currentThread();
-
-            if (mEglContext == null) {
-                mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
-                sEglContextStorage.set(createManagedContext(mEglContext));
-                return true;
-            }
-
-            return false;
-        }
-
-        private EGLConfig loadEglConfig() {
-            EGLConfig eglConfig = chooseEglConfig();
-            if (eglConfig == null) {
-                // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
-                if (sDirtyRegions) {
-                    sDirtyRegions = false;
-                    eglConfig = chooseEglConfig();
-                    if (eglConfig == null) {
-                        throw new RuntimeException("eglConfig not initialized");
-                    }
-                } else {
-                    throw new RuntimeException("eglConfig not initialized");
-                }
-            }
-            return eglConfig;
-        }
-
-        abstract ManagedEGLContext createManagedContext(EGLContext eglContext);
-
-        private EGLConfig chooseEglConfig() {
-            EGLConfig[] configs = new EGLConfig[1];
-            int[] configsCount = new int[1];
-            int[] configSpec = getConfig(sDirtyRegions);
-
-            // Debug
-            final String debug = SystemProperties.get(PRINT_CONFIG_PROPERTY, "");
-            if ("all".equalsIgnoreCase(debug)) {
-                sEgl.eglChooseConfig(sEglDisplay, configSpec, null, 0, configsCount);
-
-                EGLConfig[] debugConfigs = new EGLConfig[configsCount[0]];
-                sEgl.eglChooseConfig(sEglDisplay, configSpec, debugConfigs,
-                        configsCount[0], configsCount);
-
-                for (EGLConfig config : debugConfigs) {
-                    printConfig(config);
-                }
-            }
-
-            if (!sEgl.eglChooseConfig(sEglDisplay, configSpec, configs, 1, configsCount)) {
-                throw new IllegalArgumentException("eglChooseConfig failed " +
-                        GLUtils.getEGLErrorString(sEgl.eglGetError()));
-            } else if (configsCount[0] > 0) {
-                if ("choice".equalsIgnoreCase(debug)) {
-                    printConfig(configs[0]);
-                }
-                return configs[0];
-            }
-
-            return null;
-        }
-
-        private static void printConfig(EGLConfig config) {
-            int[] value = new int[1];
-
-            Log.d(LOG_TAG, "EGL configuration " + config + ":");
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_RED_SIZE, value);
-            Log.d(LOG_TAG, "  RED_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_GREEN_SIZE, value);
-            Log.d(LOG_TAG, "  GREEN_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_BLUE_SIZE, value);
-            Log.d(LOG_TAG, "  BLUE_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_ALPHA_SIZE, value);
-            Log.d(LOG_TAG, "  ALPHA_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_DEPTH_SIZE, value);
-            Log.d(LOG_TAG, "  DEPTH_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_STENCIL_SIZE, value);
-            Log.d(LOG_TAG, "  STENCIL_SIZE = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLE_BUFFERS, value);
-            Log.d(LOG_TAG, "  SAMPLE_BUFFERS = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SAMPLES, value);
-            Log.d(LOG_TAG, "  SAMPLES = " + value[0]);
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_SURFACE_TYPE, value);
-            Log.d(LOG_TAG, "  SURFACE_TYPE = 0x" + Integer.toHexString(value[0]));
-
-            sEgl.eglGetConfigAttrib(sEglDisplay, config, EGL_CONFIG_CAVEAT, value);
-            Log.d(LOG_TAG, "  CONFIG_CAVEAT = 0x" + Integer.toHexString(value[0]));
-        }
-
-        GL createEglSurface(Surface surface) throws OutOfResourcesException {
-            // Check preconditions.
-            if (sEgl == null) {
-                throw new RuntimeException("egl not initialized");
-            }
-            if (sEglDisplay == null) {
-                throw new RuntimeException("eglDisplay not initialized");
-            }
-            if (sEglConfig == null) {
-                throw new RuntimeException("eglConfig not initialized");
-            }
-            if (Thread.currentThread() != mEglThread) {
-                throw new IllegalStateException("HardwareRenderer cannot be used "
-                        + "from multiple threads");
-            }
-
-            // In case we need to destroy an existing surface
-            destroySurface();
-
-            // Create an EGL surface we can render into.
-            if (!createSurface(surface)) {
-                return null;
-            }
-
-            initCaches();
-
-            return mEglContext.getGL();
-        }
-
-        private void enableDirtyRegions() {
-            // If mDirtyRegions is set, this means we have an EGL configuration
-            // with EGL_SWAP_BEHAVIOR_PRESERVED_BIT set
-            if (sDirtyRegions) {
-                if (!(mDirtyRegionsEnabled = preserveBackBuffer())) {
-                    Log.w(LOG_TAG, "Backbuffer cannot be preserved");
-                }
-            } else if (sDirtyRegionsRequested) {
-                // If mDirtyRegions is not set, our EGL configuration does not
-                // have EGL_SWAP_BEHAVIOR_PRESERVED_BIT; however, the default
-                // swap behavior might be EGL_BUFFER_PRESERVED, which means we
-                // want to set mDirtyRegions. We try to do this only if dirty
-                // regions were initially requested as part of the device
-                // configuration (see RENDER_DIRTY_REGIONS)
-                mDirtyRegionsEnabled = isBackBufferPreserved();
-            }
-        }
-
-        abstract void initCaches();
-        abstract void initAtlas();
-
-        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
-            int[] attribs = { EGL14.EGL_CONTEXT_CLIENT_VERSION, mGlVersion, EGL_NONE };
-
-            EGLContext context = egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT,
-                    mGlVersion != 0 ? attribs : null);
-            if (context == null || context == EGL_NO_CONTEXT) {
-                //noinspection ConstantConditions
-                throw new IllegalStateException(
-                        "Could not create an EGL context. eglCreateContext failed with error: " +
-                        GLUtils.getEGLErrorString(sEgl.eglGetError()));
-            }
-
-            return context;
-        }
-
-        @Override
-        void destroy(boolean full) {
-            if (full && mCanvas != null) {
-                mCanvas = null;
-            }
-
-            if (!isEnabled() || mDestroyed) {
-                setEnabled(false);
-                return;
-            }
-
-            destroySurface();
-            setEnabled(false);
-
-            mDestroyed = true;
-            mGl = null;
-        }
-
-        void destroySurface() {
-            if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
-                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;
-            }
-        }
-
-        @Override
-        void invalidate(Surface surface) {
-            // Cancels any existing buffer to ensure we'll get a buffer
-            // of the right size before we call eglSwapBuffers
-            sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-            if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
-                sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
-                mEglSurface = null;
-                setEnabled(false);
-            }
-
-            if (surface.isValid()) {
-                if (!createSurface(surface)) {
-                    return;
-                }
-
-                mUpdateDirtyRegions = true;
-
-                if (mCanvas != null) {
-                    setEnabled(true);
-                }
-            }
-        }
-
-        private boolean createSurface(Surface surface) {
-            mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, surface, null);
-
-            if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
-                int error = sEgl.eglGetError();
-                if (error == EGL_BAD_NATIVE_WINDOW) {
-                    Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
-                    return false;
-                }
-                throw new RuntimeException("createWindowSurface failed "
-                        + GLUtils.getEGLErrorString(error));
-            }
-
-            if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
-                throw new IllegalStateException("eglMakeCurrent failed " +
-                        GLUtils.getEGLErrorString(sEgl.eglGetError()));
-            }
-
-            enableDirtyRegions();
-
-            return true;
-        }
-
-        @Override
-        boolean validate() {
-            return checkRenderContext() != SURFACE_STATE_ERROR;
-        }
-
-        @Override
-        void setup(int width, int height) {
-            if (validate()) {
-                mCanvas.setViewport(width, height);
-                mWidth = width;
-                mHeight = height;
-            }
-        }
-
-        @Override
-        int getWidth() {
-            return mWidth;
-        }
-
-        @Override
-        int getHeight() {
-            return mHeight;
-        }
-
-        @Override
-        HardwareCanvas getCanvas() {
-            return mCanvas;
-        }
-
-        @Override
-        void setName(String name) {
-            mName = name;
-        }
-
-        boolean canDraw() {
-            return mGl != null && mCanvas != null;
-        }
-
-        int onPreDraw(Rect dirty) {
-            return DisplayList.STATUS_DONE;
-        }
-
-        void onPostDraw() {
-        }
-
-        class FunctorsRunnable implements Runnable {
-            View.AttachInfo attachInfo;
-
-            @Override
-            public void run() {
-                final HardwareRenderer renderer = attachInfo.mHardwareRenderer;
-                if (renderer == null || !renderer.isEnabled() || renderer != GlRenderer.this) {
-                    return;
-                }
-
-                if (checkRenderContext() != SURFACE_STATE_ERROR) {
-                    int status = mCanvas.invokeFunctors(mRedrawClip);
-                    handleFunctorStatus(attachInfo, status);
-                }
-            }
-        }
-
-        @Override
-        void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
-                Rect dirty) {
-            if (canDraw()) {
-                if (!hasDirtyRegions()) {
-                    dirty = null;
-                }
-                attachInfo.mIgnoreDirtyState = true;
-                attachInfo.mDrawingTime = SystemClock.uptimeMillis();
-
-                view.mPrivateFlags |= View.PFLAG_DRAWN;
-
-                // We are already on the correct thread
-                final int surfaceState = checkRenderContextUnsafe();
-                if (surfaceState != SURFACE_STATE_ERROR) {
-                    HardwareCanvas canvas = mCanvas;
-                    attachInfo.mHardwareCanvas = canvas;
-
-                    if (mProfileEnabled) {
-                        mProfileLock.lock();
-                    }
-
-                    dirty = beginFrame(canvas, dirty, surfaceState);
-
-                    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);
-
-                        saveCount = canvas.save();
-                        callbacks.onHardwarePreDraw(canvas);
-
-                        if (displayList != null) {
-                            status |= drawDisplayList(attachInfo, canvas, displayList, status);
-                        } else {
-                            // Shouldn't reach here
-                            view.draw(canvas);
-                        }
-                    } catch (Exception e) {
-                        Log.e(LOG_TAG, "An error has occurred while drawing:", e);
-                    } finally {
-                        callbacks.onHardwarePostDraw(canvas);
-                        canvas.restoreToCount(saveCount);
-                        view.mRecreateDisplayList = false;
-
-                        mDrawDelta = getSystemTime() - start;
-
-                        if (mDrawDelta > 0) {
-                            mFrameCount++;
-
-                            debugOverdraw(attachInfo, dirty, canvas, displayList);
-                            debugDirtyRegions(dirty, canvas);
-                            drawProfileData(attachInfo);
-                        }
-                    }
-
-                    onPostDraw();
-
-                    swapBuffers(status);
-
-                    if (mProfileEnabled) {
-                        mProfileLock.unlock();
-                    }
-
-                    attachInfo.mIgnoreDirtyState = false;
-                }
-            }
-        }
-
-        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;
-
-            long buildDisplayListStartTime = startBuildDisplayListProfiling();
-            canvas.clearLayerUpdates();
-
-            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
-            DisplayList displayList = view.getDisplayList();
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-
-            endBuildDisplayListProfiling(buildDisplayListStartTime);
-
-            return displayList;
-        }
-
-        abstract void drawProfileData(View.AttachInfo attachInfo);
-
-        private Rect beginFrame(HardwareCanvas canvas, Rect dirty, int surfaceState) {
-            // We had to change the current surface and/or context, redraw everything
-            if (surfaceState == SURFACE_STATE_UPDATED) {
-                dirty = null;
-                beginFrame(null);
-            } else {
-                int[] size = mSurfaceSize;
-                beginFrame(size);
-
-                if (size[1] != mHeight || size[0] != mWidth) {
-                    mWidth = size[0];
-                    mHeight = size[1];
-
-                    canvas.setViewport(mWidth, mHeight);
-
-                    dirty = null;
-                }
-            }
-
-            if (mDebugDataProvider != null) dirty = null;
-
-            return dirty;
-        }
-
-        private long startBuildDisplayListProfiling() {
-            if (mProfileEnabled) {
-                mProfileCurrentFrame += PROFILE_FRAME_DATA_COUNT;
-                if (mProfileCurrentFrame >= mProfileData.length) {
-                    mProfileCurrentFrame = 0;
-                }
-
-                return System.nanoTime();
-            }
-            return 0;
-        }
-
-        private void endBuildDisplayListProfiling(long getDisplayListStartTime) {
-            if (mProfileEnabled) {
-                long now = System.nanoTime();
-                float total = (now - getDisplayListStartTime) * 0.000001f;
-                //noinspection PointlessArithmeticExpression
-                mProfileData[mProfileCurrentFrame] = total;
-            }
-        }
-
-        private int prepareFrame(Rect dirty) {
-            int status;
-            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "prepareFrame");
-            try {
-                status = onPreDraw(dirty);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-            }
-            return status;
-        }
-
-        private int drawDisplayList(View.AttachInfo attachInfo, HardwareCanvas canvas,
-                DisplayList displayList, int status) {
-
-            long drawDisplayListStartTime = 0;
-            if (mProfileEnabled) {
-                drawDisplayListStartTime = System.nanoTime();
-            }
-
-            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
-            try {
-                status |= canvas.drawDisplayList(displayList, mRedrawClip,
-                        DisplayList.FLAG_CLIP_CHILDREN);
-            } finally {
-                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
-            }
-
-            if (mProfileEnabled) {
-                long now = System.nanoTime();
-                float total = (now - drawDisplayListStartTime) * 0.000001f;
-                mProfileData[mProfileCurrentFrame + 1] = total;
-            }
-
-            handleFunctorStatus(attachInfo, status);
-            return status;
-        }
-
-        private void swapBuffers(int status) {
-            if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) {
-                long eglSwapBuffersStartTime = 0;
-                if (mProfileEnabled) {
-                    eglSwapBuffersStartTime = System.nanoTime();
-                }
-
-                sEgl.eglSwapBuffers(sEglDisplay, mEglSurface);
-
-                if (mProfileEnabled) {
-                    long now = System.nanoTime();
-                    float total = (now - eglSwapBuffersStartTime) * 0.000001f;
-                    mProfileData[mProfileCurrentFrame + 2] = total;
-                }
-
-                checkEglErrors();
-            }
-        }
-
-        private void debugDirtyRegions(Rect dirty, HardwareCanvas canvas) {
-            if (mDebugDirtyRegions) {
-                if (mDebugPaint == null) {
-                    mDebugPaint = new Paint();
-                    mDebugPaint.setColor(0x7fff0000);
-                }
-
-                if (dirty != null && (mFrameCount & 1) == 0) {
-                    canvas.drawRect(dirty, mDebugPaint);
-                }
-            }
-        }
-
-        private void handleFunctorStatus(View.AttachInfo attachInfo, int status) {
-            // If the draw flag is set, functors will be invoked while executing
-            // the tree of display lists
-            if ((status & DisplayList.STATUS_DRAW) != 0) {
-                if (mRedrawClip.isEmpty()) {
-                    attachInfo.mViewRootImpl.invalidate();
-                } else {
-                    attachInfo.mViewRootImpl.invalidateChildInParent(null, mRedrawClip);
-                    mRedrawClip.setEmpty();
-                }
-            }
-
-            if ((status & DisplayList.STATUS_INVOKE) != 0 ||
-                    attachInfo.mHandler.hasCallbacks(mFunctorsRunnable)) {
-                attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
-                mFunctorsRunnable.attachInfo = attachInfo;
-                attachInfo.mHandler.postDelayed(mFunctorsRunnable, FUNCTOR_PROCESS_DELAY);
-            }
-        }
-
-        @Override
-        void detachFunctor(long functor) {
-            if (mCanvas != null) {
-                mCanvas.detachFunctor(functor);
-            }
-        }
-
-        @Override
-        boolean attachFunctor(View.AttachInfo attachInfo, long functor) {
-            if (mCanvas != null) {
-                mCanvas.attachFunctor(functor);
-                mFunctorsRunnable.attachInfo = attachInfo;
-                attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
-                attachInfo.mHandler.postDelayed(mFunctorsRunnable,  0);
-                return true;
-            }
-            return false;
-        }
-
-        /**
-         * 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 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());
-            }
-
-            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()));
-                    fallback(true);
-                    return SURFACE_STATE_ERROR;
-                } else {
-                    if (mUpdateDirtyRegions) {
-                        enableDirtyRegions();
-                        mUpdateDirtyRegions = false;
-                    }
-                    return SURFACE_STATE_UPDATED;
-                }
-            }
-            return SURFACE_STATE_SUCCESS;
-        }
-
-        private static int dpToPx(int dp, float density) {
-            return (int) (dp * density + 0.5f);
-        }
-
-        class DrawPerformanceDataProvider extends GraphDataProvider {
-            private final int mGraphType;
-
-            private int mVerticalUnit;
-            private int mHorizontalUnit;
-            private int mHorizontalMargin;
-            private int mThresholdStroke;
-
-            DrawPerformanceDataProvider(int graphType) {
-                mGraphType = graphType;
-            }
-
-            @Override
-            void prepare(DisplayMetrics metrics) {
-                final float density = metrics.density;
-
-                mVerticalUnit = dpToPx(PROFILE_DRAW_DP_PER_MS, density);
-                mHorizontalUnit = dpToPx(PROFILE_DRAW_WIDTH, density);
-                mHorizontalMargin = dpToPx(PROFILE_DRAW_MARGIN, density);
-                mThresholdStroke = dpToPx(PROFILE_DRAW_THRESHOLD_STROKE_WIDTH, density);
-            }
-
-            @Override
-            int getGraphType() {
-                return mGraphType;
-            }
-
-            @Override
-            int getVerticalUnitSize() {
-                return mVerticalUnit;
-            }
-
-            @Override
-            int getHorizontalUnitSize() {
-                return mHorizontalUnit;
-            }
-
-            @Override
-            int getHorizontaUnitMargin() {
-                return mHorizontalMargin;
-            }
-
-            @Override
-            float[] getData() {
-                return mProfileData;
-            }
-
-            @Override
-            float getThreshold() {
-                return 16;
-            }
-
-            @Override
-            int getFrameCount() {
-                return mProfileData.length / PROFILE_FRAME_DATA_COUNT;
-            }
-
-            @Override
-            int getElementCount() {
-                return PROFILE_FRAME_DATA_COUNT;
-            }
-
-            @Override
-            int getCurrentFrame() {
-                return mProfileCurrentFrame / PROFILE_FRAME_DATA_COUNT;
-            }
-
-            @Override
-            void setupGraphPaint(Paint paint, int elementIndex) {
-                paint.setColor(PROFILE_DRAW_COLORS[elementIndex]);
-                if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
-            }
-
-            @Override
-            void setupThresholdPaint(Paint paint) {
-                paint.setColor(PROFILE_DRAW_THRESHOLD_COLOR);
-                paint.setStrokeWidth(mThresholdStroke);
-            }
-
-            @Override
-            void setupCurrentFramePaint(Paint paint) {
-                paint.setColor(PROFILE_DRAW_CURRENT_FRAME_COLOR);
-                if (mGraphType == GRAPH_TYPE_LINES) paint.setStrokeWidth(mThresholdStroke);
-            }
-        }
-    }
-
-    /**
-     * Hardware renderer using OpenGL ES 2.0.
-     */
-    static class Gl20Renderer extends GlRenderer {
-        private GLES20Canvas mGlCanvas;
-
-        private DisplayMetrics mDisplayMetrics;
-
-        private static EGLSurface sPbuffer;
-        private static final Object[] sPbufferLock = new Object[0];
-
-        static class Gl20RendererEglContext extends ManagedEGLContext {
-            final Handler mHandler = new Handler();
-
-            public Gl20RendererEglContext(EGLContext context) {
-                super(context);
-            }
-
-            @Override
-            public void onTerminate(final EGLContext eglContext) {
-                // Make sure we do this on the correct thread.
-                if (mHandler.getLooper() != Looper.myLooper()) {
-                    mHandler.post(new Runnable() {
-                        @Override
-                        public void run() {
-                            onTerminate(eglContext);
-                        }
-                    });
-                    return;
-                }
-
-                synchronized (sEglLock) {
-                    if (sEgl == null) return;
-
-                    if (EGLImpl.getInitCount(sEglDisplay) == 1) {
-                        usePbufferSurface(eglContext);
-                        GLES20Canvas.terminateCaches();
-
-                        sEgl.eglDestroyContext(sEglDisplay, eglContext);
-                        sEglContextStorage.set(null);
-                        sEglContextStorage.remove();
-
-                        sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
-                        sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
-                                EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-                        sEgl.eglReleaseThread();
-                        sEgl.eglTerminate(sEglDisplay);
-
-                        sEgl = null;
-                        sEglDisplay = null;
-                        sEglConfig = null;
-                        sPbuffer = null;
-                    }
-                }
-            }
-        }
-
-        Gl20Renderer(boolean translucent) {
-            super(2, translucent);
-        }
-
-        @Override
-        HardwareCanvas createCanvas() {
-            return mGlCanvas = new GLES20Canvas(mTranslucent);
-        }
-
-        @Override
-        ManagedEGLContext createManagedContext(EGLContext eglContext) {
-            return new Gl20Renderer.Gl20RendererEglContext(mEglContext);
-        }
-
-        @Override
-        int[] getConfig(boolean dirtyRegions) {
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            final int stencilSize = GLES20Canvas.getStencilSize();
-            final int swapBehavior = dirtyRegions ? EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
-
-            return new int[] {
-                    EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
-                    EGL_RED_SIZE, 8,
-                    EGL_GREEN_SIZE, 8,
-                    EGL_BLUE_SIZE, 8,
-                    EGL_ALPHA_SIZE, 8,
-                    EGL_DEPTH_SIZE, 0,
-                    EGL_CONFIG_CAVEAT, EGL_NONE,
-                    EGL_STENCIL_SIZE, stencilSize,
-                    EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
-                    EGL_NONE
-            };
-        }
-
-        @Override
-        void 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) {
-                        long[] 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) {
-            return mGlCanvas.onPreDraw(dirty);
-        }
-
-        @Override
-        void onPostDraw() {
-            mGlCanvas.onPostDraw();
-        }
-
-        @Override
-        void drawProfileData(View.AttachInfo attachInfo) {
-            if (mDebugDataProvider != null) {
-                final GraphDataProvider provider = mDebugDataProvider;
-                initProfileDrawData(attachInfo, provider);
-
-                final int height = provider.getVerticalUnitSize();
-                final int margin = provider.getHorizontaUnitMargin();
-                final int width = provider.getHorizontalUnitSize();
-
-                int x = 0;
-                int count = 0;
-                int current = 0;
-
-                final float[] data = provider.getData();
-                final int elementCount = provider.getElementCount();
-                final int graphType = provider.getGraphType();
-
-                int totalCount = provider.getFrameCount() * elementCount;
-                if (graphType == GraphDataProvider.GRAPH_TYPE_LINES) {
-                    totalCount -= elementCount;
-                }
-
-                for (int i = 0; i < totalCount; i += elementCount) {
-                    if (data[i] < 0.0f) break;
-
-                    int index = count * 4;
-                    if (i == provider.getCurrentFrame() * elementCount) current = index;
-
-                    x += margin;
-                    int x2 = x + width;
-
-                    int y2 = mHeight;
-                    int y1 = (int) (y2 - data[i] * height);
-
-                    switch (graphType) {
-                        case GraphDataProvider.GRAPH_TYPE_BARS: {
-                            for (int j = 0; j < elementCount; j++) {
-                                //noinspection MismatchedReadAndWriteOfArray
-                                final float[] r = mProfileShapes[j];
-                                r[index] = x;
-                                r[index + 1] = y1;
-                                r[index + 2] = x2;
-                                r[index + 3] = y2;
-
-                                y2 = y1;
-                                if (j < elementCount - 1) {
-                                    y1 = (int) (y2 - data[i + j + 1] * height);
-                                }
-                            }
-                        } break;
-                        case GraphDataProvider.GRAPH_TYPE_LINES: {
-                            for (int j = 0; j < elementCount; j++) {
-                                //noinspection MismatchedReadAndWriteOfArray
-                                final float[] r = mProfileShapes[j];
-                                r[index] = (x + x2) * 0.5f;
-                                r[index + 1] = index == 0 ? y1 : r[index - 1];
-                                r[index + 2] = r[index] + width;
-                                r[index + 3] = y1;
-
-                                y2 = y1;
-                                if (j < elementCount - 1) {
-                                    y1 = (int) (y2 - data[i + j + 1] * height);
-                                }
-                            }
-                        } break;
-                    }
-
-
-                    x += width;
-                    count++;
-                }
-
-                x += margin;
-
-                drawGraph(graphType, count);
-                drawCurrentFrame(graphType, current);
-                drawThreshold(x, height);
-            }
-        }
-
-        private void drawGraph(int graphType, int count) {
-            for (int i = 0; i < mProfileShapes.length; i++) {
-                mDebugDataProvider.setupGraphPaint(mProfilePaint, i);
-                switch (graphType) {
-                    case GraphDataProvider.GRAPH_TYPE_BARS:
-                        mGlCanvas.drawRects(mProfileShapes[i], count * 4, mProfilePaint);
-                        break;
-                    case GraphDataProvider.GRAPH_TYPE_LINES:
-                        mGlCanvas.drawLines(mProfileShapes[i], 0, count * 4, mProfilePaint);
-                        break;
-                }
-            }
-        }
-
-        private void drawCurrentFrame(int graphType, int index) {
-            if (index >= 0) {
-                mDebugDataProvider.setupCurrentFramePaint(mProfilePaint);
-                switch (graphType) {
-                    case GraphDataProvider.GRAPH_TYPE_BARS:
-                        mGlCanvas.drawRect(mProfileShapes[2][index], mProfileShapes[2][index + 1],
-                                mProfileShapes[2][index + 2], mProfileShapes[0][index + 3],
-                                mProfilePaint);
-                        break;
-                    case GraphDataProvider.GRAPH_TYPE_LINES:
-                        mGlCanvas.drawLine(mProfileShapes[2][index], mProfileShapes[2][index + 1],
-                                mProfileShapes[2][index], mHeight, mProfilePaint);
-                        break;
-                }
-            }
-        }
-
-        private void drawThreshold(int x, int height) {
-            float threshold = mDebugDataProvider.getThreshold();
-            if (threshold > 0.0f) {
-                mDebugDataProvider.setupThresholdPaint(mProfilePaint);
-                int y = (int) (mHeight - threshold * height);
-                mGlCanvas.drawLine(0.0f, y, x, y, mProfilePaint);
-            }
-        }
-
-        private void initProfileDrawData(View.AttachInfo attachInfo, GraphDataProvider provider) {
-            if (mProfileShapes == null) {
-                final int elementCount = provider.getElementCount();
-                final int frameCount = provider.getFrameCount();
-
-                mProfileShapes = new float[elementCount][];
-                for (int i = 0; i < elementCount; i++) {
-                    mProfileShapes[i] = new float[frameCount * 4];
-                }
-
-                mProfilePaint = new Paint();
-            }
-
-            mProfilePaint.reset();
-            if (provider.getGraphType() == GraphDataProvider.GRAPH_TYPE_LINES) {
-                mProfilePaint.setAntiAlias(true);
-            }
-
-            if (mDisplayMetrics == null) {
-                mDisplayMetrics = new DisplayMetrics();
-            }
-
-            attachInfo.mDisplay.getMetrics(mDisplayMetrics);
-            provider.prepare(mDisplayMetrics);
-        }
-
-        @Override
-        void destroy(boolean full) {
-            try {
-                super.destroy(full);
-            } finally {
-                if (full && mGlCanvas != null) {
-                    mGlCanvas = null;
-                }
-            }
-        }
-
-        @Override
-        void pushLayerUpdate(HardwareLayer layer) {
-            mGlCanvas.pushLayerUpdate(layer);
-        }
-
-        @Override
-        void cancelLayerUpdate(HardwareLayer layer) {
-            mGlCanvas.cancelLayerUpdate(layer);
-        }
-
-        @Override
-        void flushLayerUpdates() {
-            mGlCanvas.flushLayerUpdates();
-        }
-
-        @Override
-        public DisplayList createDisplayList(String name) {
-            return new GLES20DisplayList(name);
-        }
-
-        @Override
-        HardwareLayer createHardwareLayer(boolean isOpaque) {
-            return new GLES20TextureLayer(isOpaque);
-        }
-
-        @Override
-        public HardwareLayer createHardwareLayer(int width, int height, boolean isOpaque) {
-            return new GLES20RenderLayer(width, height, isOpaque);
-        }
-
-        @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();
-        }
-
-        @Override
-        void setSurfaceTexture(HardwareLayer layer, SurfaceTexture surfaceTexture) {
-            ((GLES20TextureLayer) layer).setSurfaceTexture(surfaceTexture);
-        }
-
-        @Override
-        boolean safelyRun(Runnable action) {
-            boolean needsContext = !isEnabled() || checkRenderContext() == SURFACE_STATE_ERROR;
-
-            if (needsContext) {
-                Gl20RendererEglContext managedContext =
-                        (Gl20RendererEglContext) sEglContextStorage.get();
-                if (managedContext == null) return false;
-                usePbufferSurface(managedContext.getContext());
-            }
-
-            try {
-                action.run();
-            } finally {
-                if (needsContext) {
-                    sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE,
-                            EGL_NO_SURFACE, EGL_NO_CONTEXT);
-                }
-            }
-
-            return true;
-        }
-
-        @Override
-        void destroyLayers(final View view) {
-            if (view != null) {
-                safelyRun(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCanvas != null) {
-                            mCanvas.clearLayerUpdates();
-                        }
-                        destroyHardwareLayer(view);
-                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
-                    }
-                });
-            }
-        }
-
-        private static void destroyHardwareLayer(View view) {
-            view.destroyLayer(true);
-
-            if (view instanceof ViewGroup) {
-                ViewGroup group = (ViewGroup) view;
-
-                int count = group.getChildCount();
-                for (int i = 0; i < count; i++) {
-                    destroyHardwareLayer(group.getChildAt(i));
-                }
-            }
-        }
-
-        @Override
-        void destroyHardwareResources(final View view) {
-            if (view != null) {
-                safelyRun(new Runnable() {
-                    @Override
-                    public void run() {
-                        if (mCanvas != null) {
-                            mCanvas.clearLayerUpdates();
-                        }
-                        destroyResources(view);
-                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
-                    }
-                });
-            }
-        }
-
-        private static void destroyResources(View view) {
-            view.destroyHardwareResources();
-
-            if (view instanceof ViewGroup) {
-                ViewGroup group = (ViewGroup) view;
-
-                int count = group.getChildCount();
-                for (int i = 0; i < count; i++) {
-                    destroyResources(group.getChildAt(i));
-                }
-            }
-        }
-
-        static HardwareRenderer create(boolean translucent) {
-            if (GLES20Canvas.isAvailable()) {
-                return new Gl20Renderer(translucent);
-            }
-            return null;
-        }
-
-        static void startTrimMemory(int level) {
-            if (sEgl == null || sEglConfig == null) return;
-
-            Gl20RendererEglContext managedContext =
-                    (Gl20RendererEglContext) sEglContextStorage.get();
-            // We do not have OpenGL objects
-            if (managedContext == null) {
-                return;
-            } else {
-                usePbufferSurface(managedContext.getContext());
-            }
-
-            if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
-                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
-            } else if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
-                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
-            }
-        }
-
-        static void endTrimMemory() {
-            if (sEgl != null && sEglDisplay != null) {
-                sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-            }
-        }
-
-        private static void usePbufferSurface(EGLContext eglContext) {
-            synchronized (sPbufferLock) {
-                // Create a temporary 1x1 pbuffer so we have a context
-                // to clear our OpenGL objects
-                if (sPbuffer == null) {
-                    sPbuffer = sEgl.eglCreatePbufferSurface(sEglDisplay, sEglConfig, new int[] {
-                            EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE
-                    });
-                }
-            }
-            sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
-        }
-    }
 }
diff --git a/core/java/android/view/IMagnificationCallbacks.aidl b/core/java/android/view/IMagnificationCallbacks.aidl
deleted file mode 100644
index 032d073..0000000
--- a/core/java/android/view/IMagnificationCallbacks.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-** 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.
-*/
-
-package android.view;
-
-import android.graphics.Region;
-
-/**
- * {@hide}
- */
-oneway interface IMagnificationCallbacks {
-    void onMagnifedBoundsChanged(in Region bounds);
-    void onRectangleOnScreenRequested(int left, int top, int right, int bottom);
-    void onRotationChanged(int rotation);
-    void onUserContextChanged();
-}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index c92a104..8f542bb 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -27,7 +27,6 @@
 import android.os.Bundle;
 import android.os.IRemoteCallback;
 import android.view.IApplicationToken;
-import android.view.IMagnificationCallbacks;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
 import android.view.IWindowSession;
@@ -197,7 +196,7 @@
     void thawRotation();
 
     /**
-     * Gets whether the rotation is frozen. 
+     * Gets whether the rotation is frozen.
      *
      * @return Whether the rotation is frozen.
      */
@@ -231,55 +230,7 @@
     void lockNow(in Bundle options);
 
     /**
-     * Gets the token for the focused window.
-     */
-    IBinder getFocusedWindowToken();
-
-    /**
-     * Sets an input filter for manipulating the input event stream.
-     */
-    void setInputFilter(in IInputFilter filter);
-
-    /**
-     * Gets the frame of a window given its token.
-     */
-    void getWindowFrame(IBinder token, out Rect outFrame);
-
-    /**
      * Device is in safe mode.
      */
     boolean isSafeModeEnabled();
-
-    /**
-     * Sets the display magnification callbacks. These callbacks notify
-     * the client for contextual changes related to display magnification.
-     *
-     * @param callbacks The magnification callbacks.
-     */
-    void setMagnificationCallbacks(IMagnificationCallbacks callbacks);
-
-    /**
-     * Sets the magnification spec to be applied to all windows that can be
-     * magnified.
-     *
-     * @param spec The current magnification spec.
-     */
-    void setMagnificationSpec(in MagnificationSpec spec);
-
-    /**
-     * Gets the magnification spec for a window given its token. If the
-     * window has a compatibility scale it is also folded in the returned
-     * magnification spec.
-     *
-     * @param windowToken The unique window token.
-     * @return The magnification spec if such or null.
-     */
-    MagnificationSpec getCompatibleMagnificationSpecForWindow(in IBinder windowToken);
-
-    /**
-     * Sets the current touch exploration state.
-     *
-     * @param enabled Whether touch exploration is enabled.
-     */
-    void setTouchExplorationEnabled(boolean enabled);
 }
diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java
index d5cec49..aebc601 100644
--- a/core/java/android/view/InputQueue.java
+++ b/core/java/android/view/InputQueue.java
@@ -18,7 +18,6 @@
 
 import dalvik.system.CloseGuard;
 
-import android.os.Handler;
 import android.os.Looper;
 import android.os.MessageQueue;
 import android.util.Pools.Pool;
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 6a6c127..c183f08 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -20,7 +20,6 @@
 import android.os.Parcelable;
 import android.text.method.MetaKeyKeyListener;
 import android.util.Log;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.view.KeyCharacterMap;
@@ -1169,25 +1168,25 @@
      * This mask is set if the device woke because of this key event.
      */
     public static final int FLAG_WOKE_HERE = 0x1;
-    
+
     /**
      * This mask is set if the key event was generated by a software keyboard.
      */
     public static final int FLAG_SOFT_KEYBOARD = 0x2;
-    
+
     /**
      * This mask is set if we don't want the key event to cause us to leave
      * touch mode.
      */
     public static final int FLAG_KEEP_TOUCH_MODE = 0x4;
-    
+
     /**
      * This mask is set if an event was known to come from a trusted part
      * of the system.  That is, the event is known to come from the user,
      * and could not have been spoofed by a third party component.
      */
     public static final int FLAG_FROM_SYSTEM = 0x8;
-    
+
     /**
      * This mask is used for compatibility, to identify enter keys that are
      * coming from an IME whose enter key has been auto-labelled "next" or
@@ -1196,7 +1195,7 @@
      * receiving them.
      */
     public static final int FLAG_EDITOR_ACTION = 0x10;
-    
+
     /**
      * When associated with up key events, this indicates that the key press
      * has been canceled.  Typically this is used with virtual touch screen
@@ -1205,29 +1204,29 @@
      * event and should not perform the action normally associated with the
      * key.  Note that for this to work, the application can not perform an
      * action for a key until it receives an up or the long press timeout has
-     * expired. 
+     * expired.
      */
     public static final int FLAG_CANCELED = 0x20;
-    
+
     /**
      * This key event was generated by a virtual (on-screen) hard key area.
      * Typically this is an area of the touchscreen, outside of the regular
      * display, dedicated to "hardware" buttons.
      */
     public static final int FLAG_VIRTUAL_HARD_KEY = 0x40;
-    
+
     /**
      * This flag is set for the first key repeat that occurs after the
      * long press timeout.
      */
     public static final int FLAG_LONG_PRESS = 0x80;
-    
+
     /**
      * Set when a key event has {@link #FLAG_CANCELED} set because a long
-     * press action was executed while it was down. 
+     * press action was executed while it was down.
      */
     public static final int FLAG_CANCELED_LONG_PRESS = 0x100;
-    
+
     /**
      * Set for {@link #ACTION_UP} when this event's key code is still being
      * tracked from its initial down.  That is, somebody requested that tracking
@@ -1284,7 +1283,7 @@
     public static int getDeadChar(int accent, int c) {
         return KeyCharacterMap.getDeadChar(accent, c);
     }
-    
+
     static final boolean DEBUG = false;
     static final String TAG = "KeyEvent";
 
@@ -1314,10 +1313,10 @@
          * KeyEvent.startTracking()} to have the framework track the event
          * through its {@link #onKeyUp(int, KeyEvent)} and also call your
          * {@link #onKeyLongPress(int, KeyEvent)} if it occurs.
-         * 
+         *
          * @param keyCode The value in event.getKeyCode().
          * @param event Description of the key event.
-         * 
+         *
          * @return If you handled the event, return true.  If you want to allow
          *         the event to be handled by the next receiver, return false.
          */
@@ -1330,10 +1329,10 @@
          * order to receive this callback, someone in the event change
          * <em>must</em> return true from {@link #onKeyDown} <em>and</em>
          * call {@link KeyEvent#startTracking()} on the event.
-         * 
+         *
          * @param keyCode The value in event.getKeyCode().
          * @param event Description of the key event.
-         * 
+         *
          * @return If you handled the event, return true.  If you want to allow
          *         the event to be handled by the next receiver, return false.
          */
@@ -1341,10 +1340,10 @@
 
         /**
          * Called when a key up event has occurred.
-         * 
+         *
          * @param keyCode The value in event.getKeyCode().
          * @param event Description of the key event.
-         * 
+         *
          * @return If you handled the event, return true.  If you want to allow
          *         the event to be handled by the next receiver, return false.
          */
@@ -1353,11 +1352,11 @@
         /**
          * Called when multiple down/up pairs of the same key have occurred
          * in a row.
-         * 
+         *
          * @param keyCode The value in event.getKeyCode().
          * @param count Number of pairs as returned by event.getRepeatCount().
          * @param event Description of the key event.
-         * 
+         *
          * @return If you handled the event, return true.  If you want to allow
          *         the event to be handled by the next receiver, return false.
          */
@@ -1373,7 +1372,7 @@
 
     /**
      * Create a new key event.
-     * 
+     *
      * @param action Action code: either {@link #ACTION_DOWN},
      * {@link #ACTION_UP}, or {@link #ACTION_MULTIPLE}.
      * @param code The key code.
@@ -1387,7 +1386,7 @@
 
     /**
      * Create a new key event.
-     * 
+     *
      * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
      * at which this key code originally went down.
      * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
@@ -1410,7 +1409,7 @@
 
     /**
      * Create a new key event.
-     * 
+     *
      * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
      * at which this key code originally went down.
      * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
@@ -1435,7 +1434,7 @@
 
     /**
      * Create a new key event.
-     * 
+     *
      * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
      * at which this key code originally went down.
      * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
@@ -1464,7 +1463,7 @@
 
     /**
      * Create a new key event.
-     * 
+     *
      * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
      * at which this key code originally went down.
      * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
@@ -1495,7 +1494,7 @@
 
     /**
      * Create a new key event.
-     * 
+     *
      * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
      * at which this key code originally went down.
      * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
@@ -1531,7 +1530,7 @@
      * action, repeat count and source will automatically be set to
      * {@link #KEYCODE_UNKNOWN}, {@link #ACTION_MULTIPLE}, 0, and
      * {@link InputDevice#SOURCE_KEYBOARD} for you.
-     * 
+     *
      * @param time The time (in {@link android.os.SystemClock#uptimeMillis})
      * at which this event occured.
      * @param characters The string of characters.
@@ -1569,10 +1568,10 @@
 
     /**
      * Copy an existing key event, modifying its time and repeat count.
-     * 
+     *
      * @deprecated Use {@link #changeTimeRepeat(KeyEvent, long, int)}
      * instead.
-     * 
+     *
      * @param origEvent The existing event to be copied.
      * @param eventTime The new event time
      * (in {@link android.os.SystemClock#uptimeMillis}) of the event.
@@ -1688,7 +1687,7 @@
     /**
      * Create a new key event that is the same as the given one, but whose
      * event time and repeat count are replaced with the given value.
-     * 
+     *
      * @param event The existing event to be copied.  This is not modified.
      * @param eventTime The new event time
      * (in {@link android.os.SystemClock#uptimeMillis}) of the event.
@@ -1698,11 +1697,11 @@
             int newRepeat) {
         return new KeyEvent(event, eventTime, newRepeat);
     }
-    
+
     /**
      * Create a new key event that is the same as the given one, but whose
      * event time and repeat count are replaced with the given value.
-     * 
+     *
      * @param event The existing event to be copied.  This is not modified.
      * @param eventTime The new event time
      * (in {@link android.os.SystemClock#uptimeMillis}) of the event.
@@ -1718,10 +1717,10 @@
         ret.mFlags = newFlags;
         return ret;
     }
-    
+
     /**
      * Copy an existing key event, modifying its action.
-     * 
+     *
      * @param origEvent The existing event to be copied.
      * @param action The new action code of the event.
      */
@@ -1743,18 +1742,18 @@
     /**
      * Create a new key event that is the same as the given one, but whose
      * action is replaced with the given value.
-     * 
+     *
      * @param event The existing event to be copied.  This is not modified.
      * @param action The new action code of the event.
      */
     public static KeyEvent changeAction(KeyEvent event, int action) {
         return new KeyEvent(event, action);
     }
-    
+
     /**
      * Create a new key event that is the same as the given one, but whose
      * flags are replaced with the given value.
-     * 
+     *
      * @param event The existing event to be copied.  This is not modified.
      * @param flags The new flags constant.
      */
@@ -1779,7 +1778,7 @@
     /**
      * Don't use in new code, instead explicitly check
      * {@link #getAction()}.
-     * 
+     *
      * @return If the action is ACTION_DOWN, returns true; else false.
      *
      * @deprecated
@@ -1791,7 +1790,7 @@
 
     /**
      * Is this a system key?  System keys can not be used for menu shortcuts.
-     * 
+     *
      * TODO: this information should come from a table somewhere.
      * TODO: should the dpad keys be here?  arguably, because they also shouldn't be menu shortcuts
      */
@@ -1860,6 +1859,30 @@
         }
     }
 
+    /**
+     * Whether this key is a media key, which can be send to apps that are
+     * interested in media key events.
+     *
+     * @hide
+     */
+    public static final boolean isMediaKey(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_MEDIA_PLAY:
+            case KeyEvent.KEYCODE_MEDIA_PAUSE:
+            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+            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:
+                return true;
+        }
+        return false;
+    }
+
     /** {@inheritDoc} */
     @Override
     public final int getDeviceId() {
@@ -2329,7 +2352,7 @@
     /**
      * Retrieve the action of this key event.  May be either
      * {@link #ACTION_DOWN}, {@link #ACTION_UP}, or {@link #ACTION_MULTIPLE}.
-     * 
+     *
      * @return The event action: ACTION_DOWN, ACTION_UP, or ACTION_MULTIPLE.
      */
     public final int getAction() {
@@ -2343,7 +2366,7 @@
     public final boolean isCanceled() {
         return (mFlags&FLAG_CANCELED) != 0;
     }
-    
+
     /**
      * Call this during {@link Callback#onKeyDown} to have the system track
      * the key through its final up (possibly including a long press).  Note
@@ -2354,7 +2377,7 @@
     public final void startTracking() {
         mFlags |= FLAG_START_TRACKING;
     }
-    
+
     /**
      * For {@link #ACTION_UP} events, indicates that the event is still being
      * tracked from its initial down event as per
@@ -2363,7 +2386,7 @@
     public final boolean isTracking() {
         return (mFlags&FLAG_TRACKING) != 0;
     }
-    
+
     /**
      * For {@link #ACTION_DOWN} events, indicates that the event has been
      * canceled as per {@link #FLAG_LONG_PRESS}.
@@ -2371,11 +2394,11 @@
     public final boolean isLongPress() {
         return (mFlags&FLAG_LONG_PRESS) != 0;
     }
-    
+
     /**
      * Retrieve the key code of the key event.  This is the physical key that
      * was pressed, <em>not</em> the Unicode character.
-     * 
+     *
      * @return The key code of the event.
      */
     public final int getKeyCode() {
@@ -2386,14 +2409,14 @@
      * For the special case of a {@link #ACTION_MULTIPLE} event with key
      * code of {@link #KEYCODE_UNKNOWN}, this is a raw string of characters
      * associated with the event.  In all other cases it is null.
-     * 
+     *
      * @return Returns a String of 1 or more characters associated with
      * the event.
      */
     public final String getCharacters() {
         return mCharacters;
     }
-    
+
     /**
      * Retrieve the hardware key id of this key event.  These values are not
      * reliable and vary from device to device.
@@ -2410,7 +2433,7 @@
      * events, this is the number of times the key has repeated with the first
      * down starting at 0 and counting up from there.  For multiple key
      * events, this is the number of down/up pairs that have occurred.
-     * 
+     *
      * @return The number of times the key has repeated.
      */
     public final int getRepeatCount() {
@@ -2424,7 +2447,7 @@
      * Note that when chording keys, this value is the down time of the
      * most recently pressed key, which may <em>not</em> be the same physical
      * key of this event.
-     * 
+     *
      * @return Returns the most recent key down time, in the
      * {@link android.os.SystemClock#uptimeMillis} time base
      */
@@ -2436,7 +2459,7 @@
      * Retrieve the time this event occurred,
      * in the {@link android.os.SystemClock#uptimeMillis} time base.
      *
-     * @return Returns the time this event occurred, 
+     * @return Returns the time this event occurred,
      * in the {@link android.os.SystemClock#uptimeMillis} time base.
      */
     @Override
@@ -2465,7 +2488,7 @@
 
     /**
      * Renamed to {@link #getDeviceId}.
-     * 
+     *
      * @hide
      * @deprecated use {@link #getDeviceId()} instead.
      */
@@ -2497,7 +2520,7 @@
     public char getDisplayLabel() {
         return getKeyCharacterMap().getDisplayLabel(mKeyCode);
     }
-    
+
     /**
      * Gets the Unicode character generated by the specified key and meta
      * key state combination.
@@ -2520,7 +2543,7 @@
     public int getUnicodeChar() {
         return getUnicodeChar(mMetaState);
     }
-    
+
     /**
      * Gets the Unicode character generated by the specified key and meta
      * key state combination.
@@ -2544,7 +2567,7 @@
     public int getUnicodeChar(int metaState) {
         return getKeyCharacterMap().get(mKeyCode, metaState);
     }
-    
+
     /**
      * Get the character conversion data for a given key code.
      *
@@ -2559,7 +2582,7 @@
     public boolean getKeyData(KeyData results) {
         return getKeyCharacterMap().getKeyData(mKeyCode, results);
     }
-    
+
     /**
      * Gets the first character in the character array that can be generated
      * by the specified key code.
@@ -2574,7 +2597,7 @@
     public char getMatch(char[] chars) {
         return getMatch(chars, 0);
     }
-    
+
     /**
      * Gets the first character in the character array that can be generated
      * by the specified key code.  If there are multiple choices, prefers
@@ -2587,7 +2610,7 @@
     public char getMatch(char[] chars, int metaState) {
         return getKeyCharacterMap().getMatch(mKeyCode, chars, metaState);
     }
-    
+
     /**
      * Gets the number or symbol associated with the key.
      * <p>
@@ -2611,7 +2634,7 @@
     public char getNumber() {
         return getKeyCharacterMap().getNumber(mKeyCode);
     }
-    
+
     /**
      * Returns true if this key produces a glyph.
      *
@@ -2620,7 +2643,7 @@
     public boolean isPrintingKey() {
         return getKeyCharacterMap().isPrintingKey(mKeyCode);
     }
-    
+
     /**
      * @deprecated Use {@link #dispatch(Callback, DispatcherState, Object)} instead.
      */
@@ -2628,16 +2651,16 @@
     public final boolean dispatch(Callback receiver) {
         return dispatch(receiver, null, null);
     }
-    
+
     /**
      * Deliver this key event to a {@link Callback} interface.  If this is
      * an ACTION_MULTIPLE event and it is not handled, then an attempt will
      * be made to deliver a single normal event.
-     * 
+     *
      * @param receiver The Callback that will be given the event.
      * @param state State information retained across events.
      * @param target The target of the dispatch, for use in tracking.
-     * 
+     *
      * @return The return value from the Callback method that was called.
      */
     public final boolean dispatch(Callback receiver, DispatcherState state,
@@ -2703,7 +2726,7 @@
         int mDownKeyCode;
         Object mDownTarget;
         SparseIntArray mActiveLongPresses = new SparseIntArray();
-        
+
         /**
          * Reset back to initial state.
          */
@@ -2713,7 +2736,7 @@
             mDownTarget = null;
             mActiveLongPresses.clear();
         }
-        
+
         /**
          * Stop any tracking associated with this target.
          */
@@ -2724,14 +2747,14 @@
                 mDownTarget = null;
             }
         }
-        
+
         /**
          * Start tracking the key code associated with the given event.  This
          * can only be called on a key down.  It will allow you to see any
          * long press associated with the key, and will result in
          * {@link KeyEvent#isTracking} return true on the long press and up
          * events.
-         * 
+         *
          * <p>This is only needed if you are directly dispatching events, rather
          * than handling them in {@link Callback#onKeyDown}.
          */
@@ -2744,7 +2767,7 @@
             mDownKeyCode = event.getKeyCode();
             mDownTarget = target;
         }
-        
+
         /**
          * Return true if the key event is for a key code that is currently
          * being tracked by the dispatcher.
@@ -2752,7 +2775,7 @@
         public boolean isTracking(KeyEvent event) {
             return mDownKeyCode == event.getKeyCode();
         }
-        
+
         /**
          * Keep track of the given event's key code as having performed an
          * action with a long press, so no action should occur on the up.
@@ -2762,7 +2785,7 @@
         public void performedLongPress(KeyEvent event) {
             mActiveLongPresses.put(event.getKeyCode(), 1);
         }
-        
+
         /**
          * Handle key up event to stop tracking.  This resets the dispatcher state,
          * and updates the key event state based on it.
@@ -2917,12 +2940,12 @@
             return new KeyEvent[size];
         }
     };
-    
+
     /** @hide */
     public static KeyEvent createFromParcelBody(Parcel in) {
         return new KeyEvent(in);
     }
-    
+
     private KeyEvent(Parcel in) {
         mDeviceId = in.readInt();
         mSource = in.readInt();
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index aa43bad..c4fac46 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -90,6 +90,10 @@
     private static final String TAG_INCLUDE = "include";
     private static final String TAG_1995 = "blink";
     private static final String TAG_REQUEST_FOCUS = "requestFocus";
+    private static final String TAG_TAG = "tag";
+
+    private static final int[] ATTRS_THEME = new int[] {
+            com.android.internal.R.attr.theme };
 
     /**
      * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed
@@ -459,15 +463,10 @@
                                 + "ViewGroup root and attachToRoot=true");
                     }
 
-                    rInflate(parser, root, attrs, false);
+                    rInflate(parser, root, attrs, false, false);
                 } else {
                     // Temp is the root view that was found in the xml
-                    View temp;
-                    if (TAG_1995.equals(name)) {
-                        temp = new BlinkLayout(mContext, attrs);
-                    } else {
-                        temp = createViewFromTag(root, name, attrs);
-                    }
+                    final View temp = createViewFromTag(root, name, attrs, false);
 
                     ViewGroup.LayoutParams params = null;
 
@@ -489,7 +488,7 @@
                         System.out.println("-----> start inflating children");
                     }
                     // Inflate all children under temp
-                    rInflate(parser, temp, attrs, true);
+                    rInflate(parser, temp, attrs, true, true);
                     if (DEBUG) {
                         System.out.println("-----> done inflating children");
                     }
@@ -669,31 +668,68 @@
         return onCreateView(name, attrs);
     }
 
-    /*
-     * default visibility so the BridgeInflater can override it.
+    /**
+     * Creates a view from a tag name using the supplied attribute set.
+     * <p>
+     * If {@code inheritContext} is true and the parent is non-null, the view
+     * will be inflated in parent view's context. If the view specifies a
+     * &lt;theme&gt; attribute, the inflation context will be wrapped with the
+     * specified theme.
+     * <p>
+     * Note: Default visibility so the BridgeInflater can override it.
      */
-    View createViewFromTag(View parent, String name, AttributeSet attrs) {
+    View createViewFromTag(View parent, String name, AttributeSet attrs, boolean inheritContext) {
         if (name.equals("view")) {
             name = attrs.getAttributeValue(null, "class");
         }
 
+        Context viewContext;
+        if (parent != null && inheritContext) {
+            viewContext = parent.getContext();
+        } else {
+            viewContext = mContext;
+        }
+
+        // Apply a theme wrapper, if requested.
+        final TypedArray ta = viewContext.obtainStyledAttributes(attrs, ATTRS_THEME);
+        final int themeResId = ta.getResourceId(0, 0);
+        if (themeResId != 0) {
+            viewContext = new ContextThemeWrapper(viewContext, themeResId);
+        }
+        ta.recycle();
+
+        if (name.equals(TAG_1995)) {
+            // Let's party like it's 1995!
+            return new BlinkLayout(viewContext, attrs);
+        }
+
         if (DEBUG) System.out.println("******** Creating view: " + name);
 
         try {
             View view;
-            if (mFactory2 != null) view = mFactory2.onCreateView(parent, name, mContext, attrs);
-            else if (mFactory != null) view = mFactory.onCreateView(name, mContext, attrs);
-            else view = null;
+            if (mFactory2 != null) {
+                view = mFactory2.onCreateView(parent, name, viewContext, attrs);
+            } else if (mFactory != null) {
+                view = mFactory.onCreateView(name, viewContext, attrs);
+            } else {
+                view = null;
+            }
 
             if (view == null && mPrivateFactory != null) {
-                view = mPrivateFactory.onCreateView(parent, name, mContext, attrs);
+                view = mPrivateFactory.onCreateView(parent, name, viewContext, attrs);
             }
-            
+
             if (view == null) {
-                if (-1 == name.indexOf('.')) {
-                    view = onCreateView(parent, name, attrs);
-                } else {
-                    view = createView(name, null, attrs);
+                final Object lastContext = mConstructorArgs[0];
+                mConstructorArgs[0] = viewContext;
+                try {
+                    if (-1 == name.indexOf('.')) {
+                        view = onCreateView(parent, name, attrs);
+                    } else {
+                        view = createView(name, null, attrs);
+                    }
+                } finally {
+                    mConstructorArgs[0] = lastContext;
                 }
             }
 
@@ -720,9 +756,14 @@
     /**
      * Recursive method used to descend down the xml hierarchy and instantiate
      * views, instantiate their children, and then call onFinishInflate().
+     *
+     * @param inheritContext Whether the root view should be inflated in its
+     *            parent's context. This should be true when called inflating
+     *            child views recursively, or false otherwise.
      */
     void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs,
-            boolean finishInflate) throws XmlPullParserException, IOException {
+            boolean finishInflate, boolean inheritContext) throws XmlPullParserException,
+            IOException {
 
         final int depth = parser.getDepth();
         int type;
@@ -738,24 +779,20 @@
             
             if (TAG_REQUEST_FOCUS.equals(name)) {
                 parseRequestFocus(parser, parent);
+            } else if (TAG_TAG.equals(name)) {
+                parseViewTag(parser, parent, attrs);
             } else if (TAG_INCLUDE.equals(name)) {
                 if (parser.getDepth() == 0) {
                     throw new InflateException("<include /> cannot be the root element");
                 }
-                parseInclude(parser, parent, attrs);
+                parseInclude(parser, parent, attrs, inheritContext);
             } else if (TAG_MERGE.equals(name)) {
                 throw new InflateException("<merge /> must be the root element");
-            } else if (TAG_1995.equals(name)) {
-                final View view = new BlinkLayout(mContext, attrs);
-                final ViewGroup viewGroup = (ViewGroup) parent;
-                final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
-                rInflate(parser, view, attrs, true);
-                viewGroup.addView(view, params);                
             } else {
-                final View view = createViewFromTag(parent, name, attrs);
+                final View view = createViewFromTag(parent, name, attrs, inheritContext);
                 final ViewGroup viewGroup = (ViewGroup) parent;
                 final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
-                rInflate(parser, view, attrs, true);
+                rInflate(parser, view, attrs, true, true);
                 viewGroup.addView(view, params);
             }
         }
@@ -763,10 +800,14 @@
         if (finishInflate) parent.onFinishInflate();
     }
 
-    private void parseRequestFocus(XmlPullParser parser, View parent)
+    /**
+     * Parses a <code>&lt;request-focus&gt;</code> element and requests focus on
+     * the containing View.
+     */
+    private void parseRequestFocus(XmlPullParser parser, View view)
             throws XmlPullParserException, IOException {
         int type;
-        parent.requestFocus();
+        view.requestFocus();
         final int currentDepth = parser.getDepth();
         while (((type = parser.next()) != XmlPullParser.END_TAG ||
                 parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
@@ -774,9 +815,30 @@
         }
     }
 
-    private void parseInclude(XmlPullParser parser, View parent, AttributeSet attrs)
+    /**
+     * Parses a <code>&lt;tag&gt;</code> element and sets a keyed tag on the
+     * containing View.
+     */
+    private void parseViewTag(XmlPullParser parser, View view, AttributeSet attrs)
             throws XmlPullParserException, IOException {
+        int type;
 
+        final TypedArray ta = mContext.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ViewTag);
+        final int key = ta.getResourceId(com.android.internal.R.styleable.ViewTag_id, 0);
+        final CharSequence value = ta.getText(com.android.internal.R.styleable.ViewTag_value);
+        view.setTag(key, value);
+        ta.recycle();
+
+        final int currentDepth = parser.getDepth();
+        while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) {
+            // Empty
+        }
+    }
+
+    private void parseInclude(XmlPullParser parser, View parent, AttributeSet attrs,
+            boolean inheritContext) throws XmlPullParserException, IOException {
         int type;
 
         if (parent instanceof ViewGroup) {
@@ -811,9 +873,10 @@
 
                     if (TAG_MERGE.equals(childName)) {
                         // Inflate all children.
-                        rInflate(childParser, parent, childAttrs, false);
+                        rInflate(childParser, parent, childAttrs, false, inheritContext);
                     } else {
-                        final View view = createViewFromTag(parent, childName, childAttrs);
+                        final View view = createViewFromTag(parent, childName, childAttrs,
+                                inheritContext);
                         final ViewGroup group = (ViewGroup) parent;
 
                         // We try to load the layout params set in the <include /> tag. If
@@ -836,7 +899,7 @@
                         }
 
                         // Inflate all children.
-                        rInflate(childParser, view, childAttrs, true);
+                        rInflate(childParser, view, childAttrs, true, true);
 
                         // Attempt to override the included layout's android:id with the
                         // one set on the <include /> tag itself.
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index bb7ed41..063a08d 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -140,7 +140,7 @@
         if ((resourceId & 0xff000000) == 0x01000000) {
             icon.mSystemIconResourceId = resourceId;
         } else {
-            icon.loadResource(context.getResources(), resourceId);
+            icon.loadResource(context, context.getResources(), resourceId);
         }
         return icon;
     }
@@ -198,7 +198,7 @@
         }
 
         PointerIcon icon = new PointerIcon(STYLE_CUSTOM);
-        icon.loadResource(resources, resourceId);
+        icon.loadResource(null, resources, resourceId);
         return icon;
     }
 
@@ -224,7 +224,7 @@
 
         PointerIcon result = new PointerIcon(mStyle);
         result.mSystemIconResourceId = mSystemIconResourceId;
-        result.loadResource(context.getResources(), mSystemIconResourceId);
+        result.loadResource(context, context.getResources(), mSystemIconResourceId);
         return result;
     }
 
@@ -373,7 +373,7 @@
         return true;
     }
 
-    private void loadResource(Resources resources, int resourceId) {
+    private void loadResource(Context context, Resources resources, int resourceId) {
         XmlResourceParser parser = resources.getXml(resourceId);
         final int bitmapRes;
         final float hotSpotX;
@@ -397,7 +397,12 @@
             throw new IllegalArgumentException("<pointer-icon> is missing bitmap attribute.");
         }
 
-        Drawable drawable = resources.getDrawable(bitmapRes);
+        Drawable drawable;
+        if (context == null) {
+            drawable = resources.getDrawable(bitmapRes);
+        } else {
+            drawable = context.getDrawable(bitmapRes);
+        }
         if (!(drawable instanceof BitmapDrawable)) {
             throw new IllegalArgumentException("<pointer-icon> bitmap attribute must "
                     + "refer to a bitmap drawable.");
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
new file mode 100644
index 0000000..60fb7ac
--- /dev/null
+++ b/core/java/android/view/RenderNode.java
@@ -0,0 +1,908 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.graphics.Matrix;
+import android.graphics.Outline;
+
+/**
+ * <p>A display list records a series of graphics related operations and can replay
+ * them later. Display lists are usually built by recording operations on a
+ * {@link HardwareCanvas}. Replaying the operations from a display list avoids
+ * executing application code on every frame, and is thus much more efficient.</p>
+ *
+ * <p>Display lists are used internally for all views by default, and are not
+ * typically used directly. One reason to consider using a display is a custom
+ * {@link View} implementation that needs to issue a large number of drawing commands.
+ * When the view invalidates, all the drawing commands must be reissued, even if
+ * large portions of the drawing command stream stay the same frame to frame, which
+ * can become a performance bottleneck. To solve this issue, a custom View might split
+ * its content into several display lists. A display list is updated only when its
+ * content, and only its content, needs to be updated.</p>
+ *
+ * <p>A text editor might for instance store each paragraph into its own display list.
+ * Thus when the user inserts or removes characters, only the display list of the
+ * affected paragraph needs to be recorded again.</p>
+ *
+ * <h3>Hardware acceleration</h3>
+ * <p>Display lists can only be replayed using a {@link HardwareCanvas}. They are not
+ * supported in software. Always make sure that the {@link android.graphics.Canvas}
+ * you are using to render a display list is hardware accelerated using
+ * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
+ *
+ * <h3>Creating a display list</h3>
+ * <pre class="prettyprint">
+ *     HardwareRenderer renderer = myView.getHardwareRenderer();
+ *     if (renderer != null) {
+ *         DisplayList displayList = renderer.createDisplayList();
+ *         HardwareCanvas canvas = displayList.start(width, height);
+ *         try {
+ *             // Draw onto the canvas
+ *             // For instance: canvas.drawBitmap(...);
+ *         } finally {
+ *             displayList.end();
+ *         }
+ *     }
+ * </pre>
+ *
+ * <h3>Rendering a display list on a View</h3>
+ * <pre class="prettyprint">
+ *     protected void onDraw(Canvas canvas) {
+ *         if (canvas.isHardwareAccelerated()) {
+ *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
+ *             hardwareCanvas.drawDisplayList(mDisplayList);
+ *         }
+ *     }
+ * </pre>
+ *
+ * <h3>Releasing resources</h3>
+ * <p>This step is not mandatory but recommended if you want to release resources
+ * held by a display list as soon as possible.</p>
+ * <pre class="prettyprint">
+ *     // Mark this display list invalid, it cannot be used for drawing anymore,
+ *     // and release resources held by this display list
+ *     displayList.clear();
+ * </pre>
+ *
+ * <h3>Properties</h3>
+ * <p>In addition, a display list offers several properties, such as
+ * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all
+ * the drawing commands recorded within. For instance, these properties can be used
+ * to move around a large number of images without re-issuing all the individual
+ * <code>drawBitmap()</code> calls.</p>
+ *
+ * <pre class="prettyprint">
+ *     private void createDisplayList() {
+ *         mDisplayList = DisplayList.create("MyDisplayList");
+ *         HardwareCanvas canvas = mDisplayList.start(width, height);
+ *         try {
+ *             for (Bitmap b : mBitmaps) {
+ *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
+ *                 canvas.translate(0.0f, b.getHeight());
+ *             }
+ *         } finally {
+ *             displayList.end();
+ *         }
+ *     }
+ *
+ *     protected void onDraw(Canvas canvas) {
+ *         if (canvas.isHardwareAccelerated()) {
+ *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
+ *             hardwareCanvas.drawDisplayList(mDisplayList);
+ *         }
+ *     }
+ *
+ *     private void moveContentBy(int x) {
+ *          // This will move all the bitmaps recorded inside the display list
+ *          // by x pixels to the right and redraw this view. All the commands
+ *          // recorded in createDisplayList() won't be re-issued, only onDraw()
+ *          // will be invoked and will execute very quickly
+ *          mDisplayList.offsetLeftAndRight(x);
+ *          invalidate();
+ *     }
+ * </pre>
+ *
+ * <h3>Threading</h3>
+ * <p>Display lists must be created on and manipulated from the UI thread only.</p>
+ *
+ * @hide
+ */
+public class RenderNode {
+    /**
+     * Flag used when calling
+     * {@link HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)}
+     * When this flag is set, draw operations lying outside of the bounds of the
+     * display list will be culled early. It is recommeneded to always set this
+     * flag.
+     *
+     * @hide
+     */
+    public static final int FLAG_CLIP_CHILDREN = 0x1;
+
+    // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h
+
+    /**
+     * Indicates that the display list is done drawing.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     *
+     * @hide
+     */
+    public static final int STATUS_DONE = 0x0;
+
+    /**
+     * Indicates that the display list needs another drawing pass.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     *
+     * @hide
+     */
+    public static final int STATUS_DRAW = 0x1;
+
+    /**
+     * Indicates that the display list needs to re-execute its GL functors.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     * @see HardwareCanvas#callDrawGLFunction(long)
+     *
+     * @hide
+     */
+    public static final int STATUS_INVOKE = 0x2;
+
+    /**
+     * Indicates that the display list performed GL drawing operations.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     *
+     * @hide
+     */
+    public static final int STATUS_DREW = 0x4;
+
+    private boolean mValid;
+    private final long mNativeDisplayList;
+    private HardwareRenderer mRenderer;
+
+    private RenderNode(String name) {
+        mNativeDisplayList = nCreate();
+        nSetDisplayListName(mNativeDisplayList, name);
+    }
+
+    /**
+     * 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
+     */
+    public static RenderNode create(String name) {
+        return new RenderNode(name);
+    }
+
+    /**
+     * Starts recording the display list. All operations performed on the
+     * returned canvas are recorded and stored in this display list.
+     *
+     * Calling this method will mark the display list invalid until
+     * {@link #end()} is called. Only valid display lists can be replayed.
+     *
+     * @param width The width of the display list's viewport
+     * @param height The height of the display list's viewport
+     *
+     * @return A canvas to record drawing operations.
+     *
+     * @see #end()
+     * @see #isValid()
+     */
+    public HardwareCanvas start(int width, int height) {
+        HardwareCanvas canvas = GLES20RecordingCanvas.obtain();
+        canvas.setViewport(width, height);
+        // The dirty rect should always be null for a display list
+        canvas.onPreDraw(null);
+        return canvas;
+    }
+
+    /**
+     * Ends the recording for this display list. A display list cannot be
+     * replayed if recording is not finished. Calling this method marks
+     * the display list valid and {@link #isValid()} will return true.
+     *
+     * @see #start(int, int)
+     * @see #isValid()
+     */
+    public void end(HardwareRenderer renderer, HardwareCanvas endCanvas) {
+        if (!(endCanvas instanceof GLES20RecordingCanvas)) {
+            throw new IllegalArgumentException("Passed an invalid canvas to end!");
+        }
+
+        GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas;
+        canvas.onPostDraw();
+        long displayListData = canvas.finishRecording();
+        if (renderer != mRenderer) {
+            // If we are changing renderers first destroy with the old
+            // renderer, then set with the new one
+            destroyDisplayListData();
+        }
+        mRenderer = renderer;
+        setDisplayListData(displayListData);
+        canvas.recycle();
+        mValid = true;
+    }
+
+    /**
+     * 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 void destroyDisplayListData() {
+        if (!mValid) return;
+
+        setDisplayListData(0);
+        mRenderer = null;
+        mValid = false;
+    }
+
+    private void setDisplayListData(long newData) {
+        if (mRenderer != null) {
+            mRenderer.setDisplayListData(mNativeDisplayList, newData);
+        } else {
+            throw new IllegalStateException("Trying to set data without a renderer! data=" + newData);
+        }
+    }
+
+    /**
+     * Returns whether the display list is currently usable. If this returns false,
+     * the display list should be re-recorded prior to replaying it.
+     *
+     * @return boolean true if the display list is able to be replayed, false otherwise.
+     */
+    public boolean isValid() { return mValid; }
+
+    long getNativeDisplayList() {
+        if (!mValid) {
+            throw new IllegalStateException("The display list is not valid.");
+        }
+        return mNativeDisplayList;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // DisplayList Property Setters
+    ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Set the caching property on the display list, which indicates whether the display list
+     * holds a layer. Layer display lists should avoid creating an alpha layer, since alpha is
+     * handled in the drawLayer operation directly (and more efficiently).
+     *
+     * @param caching true if the display list represents a hardware layer, false otherwise.
+     *
+     * @hide
+     */
+    public void setCaching(boolean caching) {
+        nSetCaching(mNativeDisplayList, caching);
+    }
+
+    /**
+     * Set whether the display list should clip itself to its bounds. This property is controlled by
+     * the view's parent.
+     *
+     * @param clipToBounds true if the display list should clip to its bounds
+     */
+    public void setClipToBounds(boolean clipToBounds) {
+        nSetClipToBounds(mNativeDisplayList, clipToBounds);
+    }
+
+    /**
+     * Sets whether the display list should be drawn immediately after the
+     * closest ancestor display list where isolateZVolume is true. If the
+     * display list itself satisfies this constraint, changing this attribute
+     * has no effect on drawing order.
+     *
+     * @param shouldProject true if the display list should be projected onto a
+     *            containing volume.
+     */
+    public void setProjectBackwards(boolean shouldProject) {
+        nSetProjectBackwards(mNativeDisplayList, shouldProject);
+    }
+
+    /**
+     * Sets whether the display list is a projection receiver - that its parent
+     * DisplayList should draw any descendent DisplayLists with
+     * ProjectBackwards=true directly on top of it. Default value is false.
+     */
+    public void setProjectionReceiver(boolean shouldRecieve) {
+        nSetProjectionReceiver(mNativeDisplayList, shouldRecieve);
+    }
+
+    /**
+     * Sets the outline, defining the shape that casts a shadow, and the path to
+     * be clipped if setClipToOutline is set.
+     *
+     * Deep copies the data into native to simplify reference ownership.
+     */
+    public void setOutline(Outline outline) {
+        if (outline == null) {
+            nSetOutlineEmpty(mNativeDisplayList);
+        } else if (!outline.isValid()) {
+            throw new IllegalArgumentException("Outline must be valid");
+        } else if (outline.mRect != null) {
+            nSetOutlineRoundRect(mNativeDisplayList, outline.mRect.left, outline.mRect.top,
+                    outline.mRect.right, outline.mRect.bottom, outline.mRadius);
+        } else if (outline.mPath != null) {
+            nSetOutlineConvexPath(mNativeDisplayList, outline.mPath.mNativePath);
+        }
+    }
+
+    /**
+     * Enables or disables clipping to the outline.
+     *
+     * @param clipToOutline true if clipping to the outline.
+     */
+    public void setClipToOutline(boolean clipToOutline) {
+        nSetClipToOutline(mNativeDisplayList, clipToOutline);
+    }
+
+    /**
+     * Set the static matrix on the display list. The specified matrix is combined with other
+     * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
+     *
+     * @param matrix A transform matrix to apply to this display list
+     *
+     * @see #getMatrix(android.graphics.Matrix)
+     * @see #getMatrix()
+     */
+    public void setStaticMatrix(Matrix matrix) {
+        nSetStaticMatrix(mNativeDisplayList, matrix.native_instance);
+    }
+
+    /**
+     * Set the Animation matrix on the display list. This matrix exists if an Animation is
+     * currently playing on a View, and is set on the display list during at draw() time. When
+     * the Animation finishes, the matrix should be cleared by sending <code>null</code>
+     * for the matrix parameter.
+     *
+     * @param matrix The matrix, null indicates that the matrix should be cleared.
+     *
+     * @hide
+     */
+    public void setAnimationMatrix(Matrix matrix) {
+        nSetAnimationMatrix(mNativeDisplayList,
+                (matrix != null) ? matrix.native_instance : 0);
+    }
+
+    /**
+     * Sets the translucency level for the display list.
+     *
+     * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
+     *
+     * @see View#setAlpha(float)
+     * @see #getAlpha()
+     */
+    public void setAlpha(float alpha) {
+        nSetAlpha(mNativeDisplayList, alpha);
+    }
+
+    /**
+     * Returns the translucency level of this display list.
+     *
+     * @return A value between 0.0f and 1.0f
+     *
+     * @see #setAlpha(float)
+     */
+    public float getAlpha() {
+        return nGetAlpha(mNativeDisplayList);
+    }
+
+    /**
+     * Sets whether the display list renders content which overlaps. Non-overlapping rendering
+     * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
+     * display lists consider they do not have overlapping content.
+     *
+     * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
+     *                                true otherwise.
+     *
+     * @see android.view.View#hasOverlappingRendering()
+     * @see #hasOverlappingRendering()
+     */
+    public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
+        nSetHasOverlappingRendering(mNativeDisplayList, hasOverlappingRendering);
+    }
+
+    /**
+     * Indicates whether the content of this display list overlaps.
+     *
+     * @return True if this display list renders content which overlaps, false otherwise.
+     *
+     * @see #setHasOverlappingRendering(boolean)
+     */
+    public boolean hasOverlappingRendering() {
+        //noinspection SimplifiableIfStatement
+        return nHasOverlappingRendering(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the translation value for the display list on the X axis.
+     *
+     * @param translationX The X axis translation value of the display list, in pixels
+     *
+     * @see View#setTranslationX(float)
+     * @see #getTranslationX()
+     */
+    public void setTranslationX(float translationX) {
+        nSetTranslationX(mNativeDisplayList, translationX);
+    }
+
+    /**
+     * Returns the translation value for this display list on the X axis, in pixels.
+     *
+     * @see #setTranslationX(float)
+     */
+    public float getTranslationX() {
+        return nGetTranslationX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the translation value for the display list on the Y axis.
+     *
+     * @param translationY The Y axis translation value of the display list, in pixels
+     *
+     * @see View#setTranslationY(float)
+     * @see #getTranslationY()
+     */
+    public void setTranslationY(float translationY) {
+        nSetTranslationY(mNativeDisplayList, translationY);
+    }
+
+    /**
+     * Returns the translation value for this display list on the Y axis, in pixels.
+     *
+     * @see #setTranslationY(float)
+     */
+    public float getTranslationY() {
+        return nGetTranslationY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the translation value for the display list on the Z axis.
+     *
+     * @see View#setTranslationZ(float)
+     * @see #getTranslationZ()
+     */
+    public void setTranslationZ(float translationZ) {
+        nSetTranslationZ(mNativeDisplayList, translationZ);
+    }
+
+    /**
+     * Returns the translation value for this display list on the Z axis.
+     *
+     * @see #setTranslationZ(float)
+     */
+    public float getTranslationZ() {
+        return nGetTranslationZ(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the rotation value for the display list around the Z axis.
+     *
+     * @param rotation The rotation value of the display list, in degrees
+     *
+     * @see View#setRotation(float)
+     * @see #getRotation()
+     */
+    public void setRotation(float rotation) {
+        nSetRotation(mNativeDisplayList, rotation);
+    }
+
+    /**
+     * Returns the rotation value for this display list around the Z axis, in degrees.
+     *
+     * @see #setRotation(float)
+     */
+    public float getRotation() {
+        return nGetRotation(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the rotation value for the display list around the X axis.
+     *
+     * @param rotationX The rotation value of the display list, in degrees
+     *
+     * @see View#setRotationX(float)
+     * @see #getRotationX()
+     */
+    public void setRotationX(float rotationX) {
+        nSetRotationX(mNativeDisplayList, rotationX);
+    }
+
+    /**
+     * Returns the rotation value for this display list around the X axis, in degrees.
+     *
+     * @see #setRotationX(float)
+     */
+    public float getRotationX() {
+        return nGetRotationX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the rotation value for the display list around the Y axis.
+     *
+     * @param rotationY The rotation value of the display list, in degrees
+     *
+     * @see View#setRotationY(float)
+     * @see #getRotationY()
+     */
+    public void setRotationY(float rotationY) {
+        nSetRotationY(mNativeDisplayList, rotationY);
+    }
+
+    /**
+     * Returns the rotation value for this display list around the Y axis, in degrees.
+     *
+     * @see #setRotationY(float)
+     */
+    public float getRotationY() {
+        return nGetRotationY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the scale value for the display list on the X axis.
+     *
+     * @param scaleX The scale value of the display list
+     *
+     * @see View#setScaleX(float)
+     * @see #getScaleX()
+     */
+    public void setScaleX(float scaleX) {
+        nSetScaleX(mNativeDisplayList, scaleX);
+    }
+
+    /**
+     * Returns the scale value for this display list on the X axis.
+     *
+     * @see #setScaleX(float)
+     */
+    public float getScaleX() {
+        return nGetScaleX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the scale value for the display list on the Y axis.
+     *
+     * @param scaleY The scale value of the display list
+     *
+     * @see View#setScaleY(float)
+     * @see #getScaleY()
+     */
+    public void setScaleY(float scaleY) {
+        nSetScaleY(mNativeDisplayList, scaleY);
+    }
+
+    /**
+     * Returns the scale value for this display list on the Y axis.
+     *
+     * @see #setScaleY(float)
+     */
+    public float getScaleY() {
+        return nGetScaleY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets all of the transform-related values of the display list
+     *
+     * @param alpha The alpha value of the display list
+     * @param translationX The translationX value of the display list
+     * @param translationY The translationY value of the display list
+     * @param rotation The rotation value of the display list
+     * @param rotationX The rotationX value of the display list
+     * @param rotationY The rotationY value of the display list
+     * @param scaleX The scaleX value of the display list
+     * @param scaleY The scaleY value of the display list
+     *
+     * @hide
+     */
+    public void setTransformationInfo(float alpha,
+            float translationX, float translationY, float translationZ,
+            float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
+        nSetTransformationInfo(mNativeDisplayList, alpha,
+                translationX, translationY, translationZ,
+                rotation, rotationX, rotationY, scaleX, scaleY);
+    }
+
+    /**
+     * Sets the pivot value for the display list on the X axis
+     *
+     * @param pivotX The pivot value of the display list on the X axis, in pixels
+     *
+     * @see View#setPivotX(float)
+     * @see #getPivotX()
+     */
+    public void setPivotX(float pivotX) {
+        nSetPivotX(mNativeDisplayList, pivotX);
+    }
+
+    /**
+     * Returns the pivot value for this display list on the X axis, in pixels.
+     *
+     * @see #setPivotX(float)
+     */
+    public float getPivotX() {
+        return nGetPivotX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the pivot value for the display list on the Y axis
+     *
+     * @param pivotY The pivot value of the display list on the Y axis, in pixels
+     *
+     * @see View#setPivotY(float)
+     * @see #getPivotY()
+     */
+    public void setPivotY(float pivotY) {
+        nSetPivotY(mNativeDisplayList, pivotY);
+    }
+
+    /**
+     * Returns the pivot value for this display list on the Y axis, in pixels.
+     *
+     * @see #setPivotY(float)
+     */
+    public float getPivotY() {
+        return nGetPivotY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the camera distance for the display list. Refer to
+     * {@link View#setCameraDistance(float)} for more information on how to
+     * use this property.
+     *
+     * @param distance The distance in Z of the camera of the display list
+     *
+     * @see View#setCameraDistance(float)
+     * @see #getCameraDistance()
+     */
+    public void setCameraDistance(float distance) {
+        nSetCameraDistance(mNativeDisplayList, distance);
+    }
+
+    /**
+     * Returns the distance in Z of the camera of the display list.
+     *
+     * @see #setCameraDistance(float)
+     */
+    public float getCameraDistance() {
+        return nGetCameraDistance(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the left position for the display list.
+     *
+     * @param left The left position, in pixels, of the display list
+     *
+     * @see View#setLeft(int)
+     * @see #getLeft()
+     */
+    public void setLeft(int left) {
+        nSetLeft(mNativeDisplayList, left);
+    }
+
+    /**
+     * Returns the left position for the display list in pixels.
+     *
+     * @see #setLeft(int)
+     */
+    public float getLeft() {
+        return nGetLeft(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the top position for the display list.
+     *
+     * @param top The top position, in pixels, of the display list
+     *
+     * @see View#setTop(int)
+     * @see #getTop()
+     */
+    public void setTop(int top) {
+        nSetTop(mNativeDisplayList, top);
+    }
+
+    /**
+     * Returns the top position for the display list in pixels.
+     *
+     * @see #setTop(int)
+     */
+    public float getTop() {
+        return nGetTop(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the right position for the display list.
+     *
+     * @param right The right position, in pixels, of the display list
+     *
+     * @see View#setRight(int)
+     * @see #getRight()
+     */
+    public void setRight(int right) {
+        nSetRight(mNativeDisplayList, right);
+    }
+
+    /**
+     * Returns the right position for the display list in pixels.
+     *
+     * @see #setRight(int)
+     */
+    public float getRight() {
+        return nGetRight(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the bottom position for the display list.
+     *
+     * @param bottom The bottom position, in pixels, of the display list
+     *
+     * @see View#setBottom(int)
+     * @see #getBottom()
+     */
+    public void setBottom(int bottom) {
+        nSetBottom(mNativeDisplayList, bottom);
+    }
+
+    /**
+     * Returns the bottom position for the display list in pixels.
+     *
+     * @see #setBottom(int)
+     */
+    public float getBottom() {
+        return nGetBottom(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the left and top positions for the display list
+     *
+     * @param left The left position of the display list, in pixels
+     * @param top The top position of the display list, in pixels
+     * @param right The right position of the display list, in pixels
+     * @param bottom The bottom position of the display list, in pixels
+     *
+     * @see View#setLeft(int)
+     * @see View#setTop(int)
+     * @see View#setRight(int)
+     * @see View#setBottom(int)
+     */
+    public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+        nSetLeftTopRightBottom(mNativeDisplayList, left, top, right, bottom);
+    }
+
+    /**
+     * Offsets the left and right positions for the display list
+     *
+     * @param offset The amount that the left and right positions of the display
+     *               list are offset, in pixels
+     *
+     * @see View#offsetLeftAndRight(int)
+     */
+    public void offsetLeftAndRight(float offset) {
+        nOffsetLeftAndRight(mNativeDisplayList, offset);
+    }
+
+    /**
+     * Offsets the top and bottom values for the display list
+     *
+     * @param offset The amount that the top and bottom positions of the display
+     *               list are offset, in pixels
+     *
+     * @see View#offsetTopAndBottom(int)
+     */
+    public void offsetTopAndBottom(float offset) {
+        nOffsetTopAndBottom(mNativeDisplayList, offset);
+    }
+
+    /**
+     * Outputs the display list to the log. This method exists for use by
+     * tools to output display lists for selected nodes to the log.
+     *
+     * @hide
+     */
+    public void output() {
+        nOutput(mNativeDisplayList);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Native methods
+    ///////////////////////////////////////////////////////////////////////////
+
+    private static native long nCreate();
+    private static native void nDestroyDisplayList(long displayList);
+    private static native void nSetDisplayListName(long displayList, String name);
+
+    // Properties
+
+    private static native void nOffsetTopAndBottom(long displayList, float offset);
+    private static native void nOffsetLeftAndRight(long displayList, float offset);
+    private static native void nSetLeftTopRightBottom(long displayList, int left, int top,
+            int right, int bottom);
+    private static native void nSetBottom(long displayList, int bottom);
+    private static native void nSetRight(long displayList, int right);
+    private static native void nSetTop(long displayList, int top);
+    private static native void nSetLeft(long displayList, int left);
+    private static native void nSetCameraDistance(long displayList, float distance);
+    private static native void nSetPivotY(long displayList, float pivotY);
+    private static native void nSetPivotX(long displayList, float pivotX);
+    private static native void nSetCaching(long displayList, boolean caching);
+    private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
+    private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
+    private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
+    private static native void nSetOutlineRoundRect(long displayList, int left, int top,
+            int right, int bottom, float radius);
+    private static native void nSetOutlineConvexPath(long displayList, long nativePath);
+    private static native void nSetOutlineEmpty(long displayList);
+    private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
+    private static native void nSetAlpha(long displayList, float alpha);
+    private static native void nSetHasOverlappingRendering(long displayList,
+            boolean hasOverlappingRendering);
+    private static native void nSetTranslationX(long displayList, float translationX);
+    private static native void nSetTranslationY(long displayList, float translationY);
+    private static native void nSetTranslationZ(long displayList, float translationZ);
+    private static native void nSetRotation(long displayList, float rotation);
+    private static native void nSetRotationX(long displayList, float rotationX);
+    private static native void nSetRotationY(long displayList, float rotationY);
+    private static native void nSetScaleX(long displayList, float scaleX);
+    private static native void nSetScaleY(long displayList, float scaleY);
+    private static native void nSetTransformationInfo(long displayList, float alpha,
+            float translationX, float translationY, float translationZ,
+            float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
+    private static native void nSetStaticMatrix(long displayList, long nativeMatrix);
+    private static native void nSetAnimationMatrix(long displayList, long animationMatrix);
+
+    private static native boolean nHasOverlappingRendering(long displayList);
+    private static native float nGetAlpha(long displayList);
+    private static native float nGetLeft(long displayList);
+    private static native float nGetTop(long displayList);
+    private static native float nGetRight(long displayList);
+    private static native float nGetBottom(long displayList);
+    private static native float nGetCameraDistance(long displayList);
+    private static native float nGetScaleX(long displayList);
+    private static native float nGetScaleY(long displayList);
+    private static native float nGetTranslationX(long displayList);
+    private static native float nGetTranslationY(long displayList);
+    private static native float nGetTranslationZ(long displayList);
+    private static native float nGetRotation(long displayList);
+    private static native float nGetRotationX(long displayList);
+    private static native float nGetRotationY(long displayList);
+    private static native float nGetPivotX(long displayList);
+    private static native float nGetPivotY(long displayList);
+    private static native void nOutput(long displayList);
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Finalization
+    ///////////////////////////////////////////////////////////////////////////
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroyDisplayListData();
+            nDestroyDisplayList(mNativeDisplayList);
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 91645e7..fdaae01 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.annotation.IntDef;
 import android.content.res.CompatibilityInfo.Translator;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
@@ -24,6 +25,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 import dalvik.system.CloseGuard;
 
 /**
@@ -80,6 +85,11 @@
     // non compatibility mode.
     private Matrix mCompatibleMatrix;
 
+    /** @hide */
+    @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Rotation {}
+
     /**
      * Rotation constant: 0 degree rotation (natural orientation)
      */
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index eea5884..5a8d2c8 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -22,7 +22,6 @@
 import android.graphics.Region;
 import android.view.Surface;
 import android.os.IBinder;
-import android.os.SystemProperties;
 import android.util.Log;
 import android.view.Surface.OutOfResourcesException;
 
@@ -40,9 +39,11 @@
     private static native void nativeDestroy(long nativeObject);
 
     private static native Bitmap nativeScreenshot(IBinder displayToken,
-            int width, int height, int minLayer, int maxLayer, boolean allLayers);
+            int width, int height, int minLayer, int maxLayer, boolean allLayers,
+            boolean useIdentityTransform);
     private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
-            int width, int height, int minLayer, int maxLayer, boolean allLayers);
+            int width, int height, int minLayer, int maxLayer, boolean allLayers,
+            boolean useIdentityTransform);
 
     private static native void nativeOpenTransaction();
     private static native void nativeCloseTransaction();
@@ -178,13 +179,13 @@
      * Equivalent to calling hide().
      * Updates the value set during Surface creation (see {@link #HIDDEN}).
      */
-    public static final int SURFACE_HIDDEN = 0x01;
+    private static final int SURFACE_HIDDEN = 0x01;
 
     /**
      * Surface flag: composite without blending when possible.
      * Updates the value set during Surface creation (see {@link #OPAQUE}).
      */
-    public static final int SURFACE_OPAQUE = 0x02;
+    private static final int SURFACE_OPAQUE = 0x02;
 
 
     /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
@@ -192,13 +193,13 @@
 
     /**
      * Built-in physical display id: Main display.
-     * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+     * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
      */
     public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
 
     /**
      * Built-in physical display id: Attached HDMI display.
-     * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+     * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.
      */
     public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
 
@@ -370,18 +371,6 @@
         nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
     }
 
-    /**
-     * Sets and clears flags, such as {@link #SURFACE_HIDDEN}.  The new value will be:
-     * <p>
-     *   <code>newFlags = (oldFlags & ~mask) | (flags & mask)</code>
-     * <p>
-     * Note this does not take the same set of flags as the constructor.
-     */
-    public void setFlags(int flags, int mask) {
-        checkNotReleased();
-        nativeSetFlags(mNativeObject, flags, mask);
-    }
-
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
         if (crop != null) {
@@ -567,10 +556,15 @@
      * include in the screenshot.
      * @param maxLayer The highest (top-most Z order) surface layer to
      * include in the screenshot.
+     * @param useIdentityTransform Replace whatever transformation (rotation,
+     * scaling, translation) the surface layers are currently using with the
+     * identity transformation while taking the screenshot.
      */
     public static void screenshot(IBinder display, Surface consumer,
-            int width, int height, int minLayer, int maxLayer) {
-        screenshot(display, consumer, width, height, minLayer, maxLayer, false);
+            int width, int height, int minLayer, int maxLayer,
+            boolean useIdentityTransform) {
+        screenshot(display, consumer, width, height, minLayer, maxLayer, false,
+                useIdentityTransform);
     }
 
     /**
@@ -585,7 +579,7 @@
      */
     public static void screenshot(IBinder display, Surface consumer,
             int width, int height) {
-        screenshot(display, consumer, width, height, 0, 0, true);
+        screenshot(display, consumer, width, height, 0, 0, true, false);
     }
 
     /**
@@ -595,7 +589,7 @@
      * @param consumer The {@link Surface} to take the screenshot into.
      */
     public static void screenshot(IBinder display, Surface consumer) {
-        screenshot(display, consumer, 0, 0, 0, 0, true);
+        screenshot(display, consumer, 0, 0, 0, 0, true, false);
     }
 
 
@@ -615,15 +609,20 @@
      * include in the screenshot.
      * @param maxLayer The highest (top-most Z order) surface layer to
      * include in the screenshot.
+     * @param useIdentityTransform Replace whatever transformation (rotation,
+     * scaling, translation) the surface layers are currently using with the
+     * identity transformation while taking the screenshot.
      * @return Returns a Bitmap containing the screen contents, or null
      * if an error occurs. Make sure to call Bitmap.recycle() as soon as
      * possible, once its content is not needed anymore.
      */
-    public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) {
+    public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer,
+            boolean useIdentityTransform) {
         // TODO: should take the display as a parameter
         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
-        return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false);
+        return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false,
+                useIdentityTransform);
     }
 
     /**
@@ -642,17 +641,19 @@
         // TODO: should take the display as a parameter
         IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                 SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
-        return nativeScreenshot(displayToken, width, height, 0, 0, true);
+        return nativeScreenshot(displayToken, width, height, 0, 0, true, false);
     }
 
     private static void screenshot(IBinder display, Surface consumer,
-            int width, int height, int minLayer, int maxLayer, boolean allLayers) {
+            int width, int height, int minLayer, int maxLayer, boolean allLayers,
+            boolean useIdentityTransform) {
         if (display == null) {
             throw new IllegalArgumentException("displayToken must not be null");
         }
         if (consumer == null) {
             throw new IllegalArgumentException("consumer must not be null");
         }
-        nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers);
+        nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers,
+                useIdentityTransform);
     }
 }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 22d4c9b..23123dd 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -188,8 +188,13 @@
         init();
     }
 
-    public SurfaceView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    public SurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         init();
     }
 
@@ -250,8 +255,9 @@
         updateWindow(false, false);
     }
 
+    /** @hide */
     @Override
-    protected void onDetachedFromWindow() {
+    protected void onDetachedFromWindowInternal() {
         if (mGlobalListenersAdded) {
             ViewTreeObserver observer = getViewTreeObserver();
             observer.removeOnScrollChangedListener(mScrollChangedListener);
@@ -273,7 +279,7 @@
         mSession = null;
         mLayout.token = null;
 
-        super.onDetachedFromWindow();
+        super.onDetachedFromWindowInternal();
     }
 
     @Override
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index b78af2e..3cfe5e9 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -156,14 +156,32 @@
      * 
      * @param context The context to associate this view with.
      * @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 that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
     @SuppressWarnings({"UnusedDeclaration"})
-    public TextureView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextureView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        init();
+    }
+
+    /**
+     * Creates a new TextureView.
+     *
+     * @param context The context to associate this view with.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    @SuppressWarnings({"UnusedDeclaration"})
+    public TextureView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         init();
     }
 
@@ -210,29 +228,16 @@
         }
     }
 
+    /** @hide */
     @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        if (mLayer != null) {
-            boolean success = executeHardwareAction(new Runnable() {
-                @Override
-                public void run() {
-                    destroySurface();
-                }
-            });
-
-            if (!success) {
-                Log.w(LOG_TAG, "TextureView was not able to destroy its surface: " + this);
-            }
-        }
+    protected void onDetachedFromWindowInternal() {
+        destroySurface();
+        super.onDetachedFromWindowInternal();
     }
 
     private void destroySurface() {
         if (mLayer != null) {
-            mSurface.detachFromGLContext();
-            // SurfaceTexture owns the texture name and detachFromGLContext
-            // should have deleted it
-            mLayer.clearStorage();
+            mLayer.detachSurfaceTexture(mSurface);
 
             boolean shouldRelease = true;
             if (mListener != null) {
@@ -357,7 +362,7 @@
                 return null;
             }
 
-            mLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(mOpaque);
+            mLayer = mAttachInfo.mHardwareRenderer.createTextureLayer();
             if (!mUpdateSurface) {
                 // Create a new SurfaceTexture for the layer.
                 mSurface = mAttachInfo.mHardwareRenderer.createSurfaceTexture(mLayer);
@@ -398,7 +403,7 @@
             updateLayer();
             mMatrixChanged = true;
 
-            mAttachInfo.mHardwareRenderer.setSurfaceTexture(mLayer, mSurface);
+            mLayer.setSurfaceTexture(mSurface);
             mSurface.setDefaultBufferSize(getWidth(), getHeight());
         }
 
@@ -451,7 +456,8 @@
             }
         }
         
-        mLayer.update(getWidth(), getHeight(), mOpaque);
+        mLayer.prepare(getWidth(), getHeight(), mOpaque);
+        mLayer.updateSurfaceTexture();
 
         if (mListener != null) {
             mListener.onSurfaceTextureUpdated(mSurface);
@@ -589,14 +595,6 @@
      */
     public Bitmap getBitmap(Bitmap bitmap) {
         if (bitmap != null && isAvailable()) {
-            AttachInfo info = mAttachInfo;
-            if (info != null && info.mHardwareRenderer != null &&
-                    info.mHardwareRenderer.isEnabled()) {
-                if (!info.mHardwareRenderer.validate()) {
-                    throw new IllegalStateException("Could not acquire hardware rendering context");
-                }
-            }
-
             applyUpdate();
             applyTransformMatrix();
 
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
new file mode 100644
index 0000000..2a488a0
--- /dev/null
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Bitmap;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.view.Surface.OutOfResourcesException;
+import android.view.View.AttachInfo;
+
+import java.io.PrintWriter;
+
+/**
+ * Hardware renderer that proxies the rendering to a render thread. Most calls
+ * are currently synchronous.
+ * TODO: Make draw() async.
+ * TODO: Figure out how to share the DisplayList between two threads (global lock?)
+ *
+ * The UI thread can block on the RenderThread, but RenderThread must never
+ * block on the UI thread.
+ *
+ * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
+ * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
+ * by the lifecycle of the RenderProxy.
+ *
+ * Note that although currently the EGL context & surfaces are created & managed
+ * by the render thread, the goal is to move that into a shared structure that can
+ * be managed by both threads. EGLSurface creation & deletion should ideally be
+ * done on the UI thread and not the RenderThread to avoid stalling the
+ * RenderThread with surface buffer allocation.
+ *
+ * @hide
+ */
+public class ThreadedRenderer extends HardwareRenderer {
+    private static final String LOGTAG = "ThreadedRenderer";
+
+    private static final Rect NULL_RECT = new Rect(-1, -1, -1, -1);
+
+    private int mWidth, mHeight;
+    private long mNativeProxy;
+
+    ThreadedRenderer(boolean translucent) {
+        mNativeProxy = nCreateProxy(translucent);
+        setEnabled(mNativeProxy != 0);
+    }
+
+    @Override
+    void destroy(boolean full) {
+        nDestroyCanvas(mNativeProxy);
+    }
+
+    @Override
+    boolean initialize(Surface surface) throws OutOfResourcesException {
+        return nInitialize(mNativeProxy, surface);
+    }
+
+    @Override
+    void updateSurface(Surface surface) throws OutOfResourcesException {
+        nUpdateSurface(mNativeProxy, surface);
+    }
+
+    @Override
+    void destroyHardwareResources(View view) {
+        destroyResources(view);
+        // TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+    }
+
+    private static void destroyResources(View view) {
+        view.destroyHardwareResources();
+
+        if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) view;
+
+            int count = group.getChildCount();
+            for (int i = 0; i < count; i++) {
+                destroyResources(group.getChildAt(i));
+            }
+        }
+    }
+
+    @Override
+    void invalidate(Surface surface) {
+        updateSurface(surface);
+    }
+
+    @Override
+    boolean safelyRun(Runnable action) {
+        nRunWithGlContext(mNativeProxy, action);
+        return true;
+    }
+
+    @Override
+    void setup(int width, int height) {
+        mWidth = width;
+        mHeight = height;
+        nSetup(mNativeProxy, width, height);
+    }
+
+    @Override
+    int getWidth() {
+        return mWidth;
+    }
+
+    @Override
+    int getHeight() {
+        return mHeight;
+    }
+
+    @Override
+    void dumpGfxInfo(PrintWriter pw) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    long getFrameCount() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    boolean loadSystemProperties() {
+        return false;
+    }
+
+    /**
+     * TODO: Remove
+     * Temporary hack to allow RenderThreadTest prototype app to trigger
+     * replaying a DisplayList after modifying the displaylist properties
+     *
+     *  @hide */
+    public void repeatLastDraw() {
+    }
+
+    @Override
+    void setDisplayListData(long displayList, long newData) {
+        nSetDisplayListData(mNativeProxy, displayList, newData);
+    }
+
+    @Override
+    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
+        attachInfo.mIgnoreDirtyState = true;
+        attachInfo.mDrawingTime = SystemClock.uptimeMillis();
+        view.mPrivateFlags |= View.PFLAG_DRAWN;
+
+        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
+                == View.PFLAG_INVALIDATED;
+        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
+
+        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
+        RenderNode displayList = view.getDisplayList();
+        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+
+        view.mRecreateDisplayList = false;
+
+        if (dirty == null) {
+            dirty = NULL_RECT;
+        }
+        nDrawDisplayList(mNativeProxy, displayList.getNativeDisplayList(),
+                dirty.left, dirty.top, dirty.right, dirty.bottom);
+    }
+
+    @Override
+    void detachFunctor(long functor) {
+        nDetachFunctor(mNativeProxy, functor);
+    }
+
+    @Override
+    void attachFunctor(AttachInfo attachInfo, long functor) {
+        nAttachFunctor(mNativeProxy, functor);
+    }
+
+    @Override
+    HardwareLayer createDisplayListLayer(int width, int height) {
+        long layer = nCreateDisplayListLayer(mNativeProxy, width, height);
+        return HardwareLayer.adoptDisplayListLayer(this, layer);
+    }
+
+    @Override
+    HardwareLayer createTextureLayer() {
+        long layer = nCreateTextureLayer(mNativeProxy);
+        return HardwareLayer.adoptTextureLayer(this, layer);
+    }
+
+    @Override
+    SurfaceTexture createSurfaceTexture(final HardwareLayer layer) {
+        final SurfaceTexture[] ret = new SurfaceTexture[1];
+        nRunWithGlContext(mNativeProxy, new Runnable() {
+            @Override
+            public void run() {
+                ret[0] = layer.createSurfaceTexture();
+            }
+        });
+        return ret[0];
+    }
+
+    @Override
+    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
+        return nCopyLayerInto(mNativeProxy,
+                layer.getDeferredLayerUpdater(), bitmap.mNativeBitmap);
+    }
+
+    @Override
+    void pushLayerUpdate(HardwareLayer layer) {
+        // TODO: Remove this, it's not needed outside of GLRenderer
+    }
+
+    @Override
+    void onLayerCreated(HardwareLayer layer) {
+        // TODO: Is this actually useful?
+    }
+
+    @Override
+    void flushLayerUpdates() {
+        // TODO: Figure out what this should do or remove it
+    }
+
+    @Override
+    void onLayerDestroyed(HardwareLayer layer) {
+        nDestroyLayer(mNativeProxy, layer.getDeferredLayerUpdater());
+    }
+
+    @Override
+    void setName(String name) {
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            nDeleteProxy(mNativeProxy);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /** @hide */
+    public static native void postToRenderThread(Runnable runnable);
+
+    private static native long nCreateProxy(boolean translucent);
+    private static native void nDeleteProxy(long nativeProxy);
+
+    private static native boolean nInitialize(long nativeProxy, Surface window);
+    private static native void nUpdateSurface(long nativeProxy, Surface window);
+    private static native void nSetup(long nativeProxy, int width, int height);
+    private static native void nSetDisplayListData(long nativeProxy, long displayList,
+            long newData);
+    private static native void nDrawDisplayList(long nativeProxy, long displayList,
+            int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
+    private static native void nRunWithGlContext(long nativeProxy, Runnable runnable);
+    private static native void nDestroyCanvas(long nativeProxy);
+
+    private static native void nAttachFunctor(long nativeProxy, long functor);
+    private static native void nDetachFunctor(long nativeProxy, long functor);
+
+    private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
+    private static native long nCreateTextureLayer(long nativeProxy);
+    private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
+    private static native void nDestroyLayer(long nativeProxy, long layer);
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4c6aed7..4992960 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16,6 +16,9 @@
 
 package android.view;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.ClipData;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -28,7 +31,9 @@
 import android.graphics.Interpolator;
 import android.graphics.LinearGradient;
 import android.graphics.Matrix;
+import android.graphics.Outline;
 import android.graphics.Paint;
+import android.graphics.Path;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
@@ -86,6 +91,8 @@
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
@@ -95,7 +102,9 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -658,6 +667,7 @@
  * @attr ref android.R.styleable#View_scrollbarTrackVertical
  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
  * @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
+ * @attr ref android.R.styleable#View_sharedElementName
  * @attr ref android.R.styleable#View_soundEffectsEnabled
  * @attr ref android.R.styleable#View_tag
  * @attr ref android.R.styleable#View_textAlignment
@@ -666,6 +676,7 @@
  * @attr ref android.R.styleable#View_transformPivotY
  * @attr ref android.R.styleable#View_translationX
  * @attr ref android.R.styleable#View_translationY
+ * @attr ref android.R.styleable#View_translationZ
  * @attr ref android.R.styleable#View_visibility
  *
  * @see android.view.ViewGroup
@@ -729,6 +740,11 @@
      */
     private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
 
+    /** @hide */
+    @IntDef({VISIBLE, INVISIBLE, GONE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Visibility {}
+
     /**
      * This view is visible.
      * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
@@ -896,6 +912,11 @@
      */
     static final int FOCUSABLE_IN_TOUCH_MODE = 0x00040000;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({DRAWING_CACHE_QUALITY_LOW, DRAWING_CACHE_QUALITY_HIGH, DRAWING_CACHE_QUALITY_AUTO})
+    public @interface DrawingCacheQuality {}
+
     /**
      * <p>Enables low quality mode for the drawing cache.</p>
      */
@@ -940,6 +961,16 @@
      */
     static final int DUPLICATE_PARENT_STATE = 0x00400000;
 
+    /** @hide */
+    @IntDef({
+        SCROLLBARS_INSIDE_OVERLAY,
+        SCROLLBARS_INSIDE_INSET,
+        SCROLLBARS_OUTSIDE_OVERLAY,
+        SCROLLBARS_OUTSIDE_INSET
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScrollBarStyle {}
+
     /**
      * The scrollbar style to display the scrollbars inside the content area,
      * without increasing the padding. The scrollbars will be overlaid with
@@ -1020,6 +1051,15 @@
      */
     static final int PARENT_SAVE_DISABLED_MASK = 0x20000000;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                FOCUSABLES_ALL,
+                FOCUSABLES_TOUCH_MODE
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FocusableMode {}
+
     /**
      * View flag indicating whether {@link #addFocusables(ArrayList, int, int)}
      * should add all focusable Views regardless if they are focusable in touch mode.
@@ -1032,6 +1072,28 @@
      */
     public static final int FOCUSABLES_TOUCH_MODE = 0x00000001;
 
+    /** @hide */
+    @IntDef({
+            FOCUS_BACKWARD,
+            FOCUS_FORWARD,
+            FOCUS_LEFT,
+            FOCUS_UP,
+            FOCUS_RIGHT,
+            FOCUS_DOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FocusDirection {}
+
+    /** @hide */
+    @IntDef({
+            FOCUS_LEFT,
+            FOCUS_UP,
+            FOCUS_RIGHT,
+            FOCUS_DOWN
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FocusRealDirection {} // Like @FocusDirection, but without forward/backward
+
     /**
      * Use with {@link #focusSearch(int)}. Move focus to the previous selectable
      * item.
@@ -1587,7 +1649,7 @@
      * @see #setTag(Object)
      * @see #getTag()
      */
-    protected Object mTag;
+    protected Object mTag = null;
 
     // for mPrivateFlags:
     /** {@hide} */
@@ -1804,6 +1866,25 @@
      */
     static final int PFLAG2_DRAG_HOVERED               = 0x00000002;
 
+    /** @hide */
+    @IntDef({
+        LAYOUT_DIRECTION_LTR,
+        LAYOUT_DIRECTION_RTL,
+        LAYOUT_DIRECTION_INHERIT,
+        LAYOUT_DIRECTION_LOCALE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    // Not called LayoutDirection to avoid conflict with android.util.LayoutDirection
+    public @interface LayoutDir {}
+
+    /** @hide */
+    @IntDef({
+        LAYOUT_DIRECTION_LTR,
+        LAYOUT_DIRECTION_RTL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ResolvedLayoutDir {}
+
     /**
      * Horizontal layout direction of this view is from Left to Right.
      * Use with {@link #setLayoutDirection}.
@@ -1982,7 +2063,20 @@
     static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
             TEXT_DIRECTION_RESOLVED_DEFAULT << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
 
-    /*
+    /** @hide */
+    @IntDef({
+        TEXT_ALIGNMENT_INHERIT,
+        TEXT_ALIGNMENT_GRAVITY,
+        TEXT_ALIGNMENT_CENTER,
+        TEXT_ALIGNMENT_TEXT_START,
+        TEXT_ALIGNMENT_TEXT_END,
+        TEXT_ALIGNMENT_VIEW_START,
+        TEXT_ALIGNMENT_VIEW_END
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TextAlignment {}
+
+    /**
      * Default text alignment. The text alignment of this View is inherited from its parent.
      * Use with {@link #setTextAlignment(int)}
      */
@@ -2234,7 +2328,17 @@
 
     /* End of masks for mPrivateFlags2 */
 
-    /* Masks for mPrivateFlags3 */
+    /**
+     * Masks for mPrivateFlags3, as generated by dumpFlags():
+     *
+     * |-------|-------|-------|-------|
+     *                                 1 PFLAG3_VIEW_IS_ANIMATING_TRANSFORM
+     *                                1  PFLAG3_VIEW_IS_ANIMATING_ALPHA
+     *                               1   PFLAG3_IS_LAID_OUT
+     *                              1    PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT
+     *                             1     PFLAG3_CALLED_SUPER
+     * |-------|-------|-------|-------|
+     */
 
     /**
      * Flag indicating that view has a transform animation set on it. This is used to track whether
@@ -2268,6 +2372,25 @@
      */
     static final int PFLAG3_CALLED_SUPER = 0x10;
 
+    /**
+     * Flag indicating that an view will be clipped to its outline.
+     */
+    static final int PFLAG3_CLIP_TO_OUTLINE = 0x20;
+
+    /**
+     * Flag indicating that a view's outline has been specifically defined.
+     */
+    static final int PFLAG3_OUTLINE_DEFINED = 0x40;
+
+    /**
+     * Flag indicating that we're in the process of applying window insets.
+     */
+    static final int PFLAG3_APPLYING_INSETS = 0x80;
+
+    /**
+     * Flag indicating that we're in the process of fitting system windows using the old method.
+     */
+    static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x100;
 
     /* End of masks for mPrivateFlags3 */
 
@@ -2664,6 +2787,12 @@
             SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
             | SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = { FIND_VIEWS_WITH_TEXT, FIND_VIEWS_WITH_CONTENT_DESCRIPTION })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FindViewFlags {}
+
     /**
      * Find views that render the specified text.
      *
@@ -2685,7 +2814,7 @@
      * added and it is a responsibility of the client to call the APIs of
      * the provider to determine whether the virtual tree rooted at this View
      * contains the text, i.e. getting the list of {@link AccessibilityNodeInfo}s
-     * represeting the virtual views with this text.
+     * representing the virtual views with this text.
      *
      * @see #findViewsWithText(ArrayList, CharSequence, int)
      *
@@ -2887,6 +3016,9 @@
         @ViewDebug.ExportedProperty
         float mTranslationY = 0f;
 
+        @ViewDebug.ExportedProperty
+        float mTranslationZ = 0f;
+
         /**
          * The amount of scale in the x direction around the pivot point. A
          * value of 1 means no scaling is applied.
@@ -3125,6 +3257,15 @@
     @ViewDebug.ExportedProperty(deepExport = true, prefix = "bg_")
     private Drawable mBackground;
 
+    /**
+     * Display list used for backgrounds.
+     * <p>
+     * When non-null and valid, this is expected to contain an up-to-date copy
+     * of the background drawable. It is cleared on temporary detach and reset
+     * on cleanup.
+     */
+    private RenderNode mBackgroundDisplayList;
+
     private int mBackgroundResource;
     private boolean mBackgroundSizeChanged;
 
@@ -3178,6 +3319,8 @@
         private OnDragListener mOnDragListener;
 
         private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;
+
+        OnApplyWindowInsetsListener mOnApplyWindowInsetsListener;
     }
 
     ListenerInfo mListenerInfo;
@@ -3196,6 +3339,14 @@
     private int[] mDrawableState = null;
 
     /**
+     * Stores the outline of the view, passed down to the DisplayList level for
+     * defining shadow shape and clipping.
+     *
+     * TODO: once RenderNode is long-lived, remove this and rely on native copy.
+     */
+    private Outline mOutline;
+
+    /**
      * When this view has focus and the next focus is {@link #FOCUS_LEFT},
      * the user may specify which view to go to next.
      */
@@ -3398,7 +3549,14 @@
     private Bitmap mDrawingCache;
     private Bitmap mUnscaledDrawingCache;
 
-    DisplayList mDisplayList;
+    /**
+     * Display list used for the View content.
+     * <p>
+     * When non-null and valid, this is expected to contain an up-to-date copy
+     * of the View content. It is cleared on temporary detach and reset on
+     * cleanup.
+     */
+    RenderNode mDisplayList;
 
     /**
      * Set to true when the view is sending hover accessibility events because it
@@ -3485,27 +3643,64 @@
     }
 
     /**
-     * Perform inflation from XML and apply a class-specific base style. This
-     * constructor of View allows subclasses to use their own base style when
-     * they are inflating. For example, a Button class's constructor would call
-     * this version of the super class constructor and supply
-     * <code>R.attr.buttonStyle</code> for <var>defStyle</var>; this allows
-     * the theme's button style to modify all of the base view attributes (in
-     * particular its background) as well as the Button class's attributes.
+     * Perform inflation from XML and apply a class-specific base style from a
+     * theme attribute. This constructor of View allows subclasses to use their
+     * own base style when they are inflating. For example, a Button class's
+     * constructor would call this version of the super class constructor and
+     * supply <code>R.attr.buttonStyle</code> for <var>defStyleAttr</var>; this
+     * allows the theme's button style to modify all of the base view attributes
+     * (in particular its background) as well as the Button class's attributes.
      *
      * @param context The Context the view is running in, through which it can
      *        access the current theme, resources, etc.
      * @param attrs The attributes of the XML tag that is inflating the view.
      * @param defStyleAttr An attribute in the current theme that contains a
-     *        reference to a style resource to apply to this view. If 0, no
-     *        default style will be applied.
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @see #View(Context, AttributeSet)
      */
     public View(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Perform inflation from XML and apply a class-specific base style from a
+     * theme attribute or style resource. This constructor of View allows
+     * subclasses to use their own base style when they are inflating.
+     * <p>
+     * When determining the final value of a particular attribute, there are
+     * four inputs that come into play:
+     * <ol>
+     * <li>Any attribute values in the given AttributeSet.
+     * <li>The style resource specified in the AttributeSet (named "style").
+     * <li>The default style specified by <var>defStyleAttr</var>.
+     * <li>The default style specified by <var>defStyleRes</var>.
+     * <li>The base values in this theme.
+     * </ol>
+     * <p>
+     * Each of these inputs is considered in-order, with the first listed taking
+     * precedence over the following ones. In other words, if in the
+     * AttributeSet you have supplied <code>&lt;Button * textColor="#ff000000"&gt;</code>
+     * , then the button's text will <em>always</em> be black, regardless of
+     * what is specified in any of the styles.
+     *
+     * @param context The Context the view is running in, through which it can
+     *        access the current theme, resources, etc.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     * @see #View(Context, AttributeSet, int)
+     */
+    public View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         this(context);
 
-        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View,
-                defStyleAttr, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
 
         Drawable background = null;
 
@@ -3528,6 +3723,7 @@
 
         float tx = 0;
         float ty = 0;
+        float tz = 0;
         float rotation = 0;
         float rotationX = 0;
         float rotationY = 0;
@@ -3607,6 +3803,10 @@
                     ty = a.getDimensionPixelOffset(attr, 0);
                     transformSet = true;
                     break;
+                case com.android.internal.R.styleable.View_translationZ:
+                    tz = a.getDimensionPixelOffset(attr, 0);
+                    transformSet = true;
+                    break;
                 case com.android.internal.R.styleable.View_rotation:
                     rotation = a.getFloat(attr, 0);
                     transformSet = true;
@@ -3859,6 +4059,9 @@
                 case R.styleable.View_accessibilityLiveRegion:
                     setAccessibilityLiveRegion(a.getInt(attr, ACCESSIBILITY_LIVE_REGION_DEFAULT));
                     break;
+                case R.styleable.View_sharedElementName:
+                    setSharedElementName(a.getString(attr));
+                    break;
             }
         }
 
@@ -3948,6 +4151,7 @@
         if (transformSet) {
             setTranslationX(tx);
             setTranslationY(ty);
+            setTranslationZ(tz);
             setRotation(rotation);
             setRotationX(rotationX);
             setRotationY(rotationY);
@@ -4014,7 +4218,7 @@
             out.append(" #");
             out.append(Integer.toHexString(id));
             final Resources r = mResources;
-            if (id != 0 && r != null) {
+            if (Resources.resourceHasPackage(id) && r != null) {
                 try {
                     String pkgname;
                     switch (id&0xff000000) {
@@ -4596,7 +4800,7 @@
      * @param previouslyFocusedRect The rectangle of the view that had focus
      *        prior in this View's coordinate system.
      */
-    void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) {
+    void handleFocusGainInternal(@FocusRealDirection int direction, Rect previouslyFocusedRect) {
         if (DBG) {
             System.out.println(this + " requestFocus()");
         }
@@ -4614,12 +4818,43 @@
                 mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, this);
             }
 
+            manageFocusHotspot(true, oldFocus);
             onFocusChanged(true, direction, previouslyFocusedRect);
             refreshDrawableState();
         }
     }
 
     /**
+     * Forwards focus information to the background drawable, if necessary. When
+     * the view is gaining focus, <code>v</code> is the previous focus holder.
+     * When the view is losing focus, <code>v</code> is the next focus holder.
+     *
+     * @param focused whether this view is focused
+     * @param v previous or the next focus holder, or null if none
+     */
+    private void manageFocusHotspot(boolean focused, View v) {
+        if (mBackground != null && mBackground.supportsHotspots()) {
+            final Rect r = new Rect();
+            if (v != null) {
+                v.getBoundsOnScreen(r);
+                final int[] location = new int[2];
+                getLocationOnScreen(location);
+                r.offset(-location[0], -location[1]);
+            } else {
+                r.set(mLeft, mTop, mRight, mBottom);
+            }
+
+            final float x = r.exactCenterX();
+            final float y = r.exactCenterY();
+            mBackground.setHotspot(Drawable.HOTSPOT_FOCUS, x, y);
+
+            if (!focused) {
+                mBackground.removeHotspot(Drawable.HOTSPOT_FOCUS);
+            }
+        }
+    }
+
+    /**
      * Request that a rectangle of this view be visible on the screen,
      * scrolling if necessary just enough.
      *
@@ -4705,7 +4940,7 @@
             System.out.println(this + " clearFocus()");
         }
 
-        clearFocusInternal(true, true);
+        clearFocusInternal(null, true, true);
     }
 
     /**
@@ -4717,10 +4952,14 @@
      * @param refocus when propagate is true, specifies whether to request the
      *            root view place new focus
      */
-    void clearFocusInternal(boolean propagate, boolean refocus) {
+    void clearFocusInternal(View focused, boolean propagate, boolean refocus) {
         if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
             mPrivateFlags &= ~PFLAG_FOCUSED;
 
+            if (hasFocus()) {
+                manageFocusHotspot(false, focused);
+            }
+
             if (propagate && mParent != null) {
                 mParent.clearChildFocus(this);
             }
@@ -4754,12 +4993,12 @@
      * after calling this method. Otherwise, the view hierarchy may be left in
      * an inconstent state.
      */
-    void unFocus() {
+    void unFocus(View focused) {
         if (DBG) {
             System.out.println(this + " unFocus()");
         }
 
-        clearFocusInternal(false, false);
+        clearFocusInternal(focused, false, false);
     }
 
     /**
@@ -4807,7 +5046,8 @@
      *        passed in as finer grained information about where the focus is coming
      *        from (in addition to direction).  Will be <code>null</code> otherwise.
      */
-    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
+    protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
+            @Nullable Rect previouslyFocusedRect) {
         if (gainFocus) {
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
         } else {
@@ -4869,10 +5109,6 @@
      * @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 {
@@ -5667,6 +5903,7 @@
      *
      * @attr ref android.R.styleable#View_drawingCacheQuality
      */
+    @DrawingCacheQuality
     public int getDrawingCacheQuality() {
         return mViewFlags & DRAWING_CACHE_QUALITY_MASK;
     }
@@ -5684,7 +5921,7 @@
      *
      * @attr ref android.R.styleable#View_drawingCacheQuality
      */
-    public void setDrawingCacheQuality(int quality) {
+    public void setDrawingCacheQuality(@DrawingCacheQuality int quality) {
         setFlags(quality, DRAWING_CACHE_QUALITY_MASK);
     }
 
@@ -5901,10 +6138,33 @@
      * @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 #setFitsSystemWindows(boolean)
      * @see #setSystemUiVisibility(int)
+     *
+     * @deprecated As of API XX use {@link #dispatchApplyWindowInsets(WindowInsets)} to apply
+     * insets to views. Views should override {@link #onApplyWindowInsets(WindowInsets)} or use
+     * {@link #setOnApplyWindowInsetsListener(android.view.View.OnApplyWindowInsetsListener)}
+     * to implement handling their own insets.
      */
     protected boolean fitSystemWindows(Rect insets) {
+        if ((mPrivateFlags3 & PFLAG3_APPLYING_INSETS) == 0) {
+            // If we're not in the process of dispatching the newer apply insets call,
+            // that means we're not in the compatibility path. Dispatch into the newer
+            // apply insets path and take things from there.
+            try {
+                mPrivateFlags3 |= PFLAG3_FITTING_SYSTEM_WINDOWS;
+                return !dispatchApplyWindowInsets(new WindowInsets(insets)).hasInsets();
+            } finally {
+                mPrivateFlags3 &= ~PFLAG3_FITTING_SYSTEM_WINDOWS;
+            }
+        } else {
+            // We're being called from the newer apply insets path.
+            // Perform the standard fallback behavior.
+            return fitSystemWindowsInt(insets);
+        }
+    }
+
+    private boolean fitSystemWindowsInt(Rect insets) {
         if ((mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS) {
             mUserPaddingStart = UNDEFINED_PADDING;
             mUserPaddingEnd = UNDEFINED_PADDING;
@@ -5924,6 +6184,97 @@
     }
 
     /**
+     * Called when the view should apply {@link WindowInsets} according to its internal policy.
+     *
+     * <p>This method should be overridden by views that wish to apply a policy different from or
+     * in addition to the default behavior. Clients that wish to force a view subtree
+     * to apply insets should call {@link #dispatchApplyWindowInsets(WindowInsets)}.</p>
+     *
+     * <p>Clients may supply an {@link OnApplyWindowInsetsListener} to a view. If one is set
+     * it will be called during dispatch instead of this method. The listener may optionally
+     * call this method from its own implementation if it wishes to apply the view's default
+     * insets policy in addition to its own.</p>
+     *
+     * <p>Implementations of this method should either return the insets parameter unchanged
+     * or a new {@link WindowInsets} cloned from the supplied insets with any insets consumed
+     * that this view applied itself. This allows new inset types added in future platform
+     * versions to pass through existing implementations unchanged without being erroneously
+     * consumed.</p>
+     *
+     * <p>By default if a view's {@link #setFitsSystemWindows(boolean) fitsSystemWindows}
+     * property is set then the view will consume the system window insets and apply them
+     * as padding for the view.</p>
+     *
+     * @param insets Insets to apply
+     * @return The supplied insets with any applied insets consumed
+     */
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        if ((mPrivateFlags3 & PFLAG3_FITTING_SYSTEM_WINDOWS) == 0) {
+            // We weren't called from within a direct call to fitSystemWindows,
+            // call into it as a fallback in case we're in a class that overrides it
+            // and has logic to perform.
+            if (fitSystemWindows(insets.getSystemWindowInsets())) {
+                return insets.cloneWithSystemWindowInsetsConsumed();
+            }
+        } else {
+            // We were called from within a direct call to fitSystemWindows.
+            if (fitSystemWindowsInt(insets.getSystemWindowInsets())) {
+                return insets.cloneWithSystemWindowInsetsConsumed();
+            }
+        }
+        return insets;
+    }
+
+    /**
+     * Set an {@link OnApplyWindowInsetsListener} to take over the policy for applying
+     * window insets to this view. The listener's
+     * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
+     * method will be called instead of the view's
+     * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
+     *
+     * @param listener Listener to set
+     *
+     * @see #onApplyWindowInsets(WindowInsets)
+     */
+    public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
+        getListenerInfo().mOnApplyWindowInsetsListener = listener;
+    }
+
+    /**
+     * Request to apply the given window insets to this view or another view in its subtree.
+     *
+     * <p>This method should be called by clients wishing to apply insets corresponding to areas
+     * obscured by window decorations or overlays. This can include the status and navigation bars,
+     * action bars, input methods and more. New inset categories may be added in the future.
+     * The method returns the insets provided minus any that were applied by this view or its
+     * children.</p>
+     *
+     * <p>Clients wishing to provide custom behavior should override the
+     * {@link #onApplyWindowInsets(WindowInsets)} method or alternatively provide a
+     * {@link OnApplyWindowInsetsListener} via the
+     * {@link #setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) setOnApplyWindowInsetsListener}
+     * method.</p>
+     *
+     * <p>This method replaces the older {@link #fitSystemWindows(Rect) fitSystemWindows} method.
+     * </p>
+     *
+     * @param insets Insets to apply
+     * @return The provided insets minus the insets that were consumed
+     */
+    public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
+        try {
+            mPrivateFlags3 |= PFLAG3_APPLYING_INSETS;
+            if (mListenerInfo != null && mListenerInfo.mOnApplyWindowInsetsListener != null) {
+                return mListenerInfo.mOnApplyWindowInsetsListener.onApplyWindowInsets(this, insets);
+            } else {
+                return onApplyWindowInsets(insets);
+            }
+        } finally {
+            mPrivateFlags3 &= ~PFLAG3_APPLYING_INSETS;
+        }
+    }
+
+    /**
      * @hide Compute the insets that should be consumed by this view and the ones
      * that should propagate to those under it.
      */
@@ -5995,6 +6346,7 @@
 
     /**
      * Ask that a new dispatch of {@link #fitSystemWindows(Rect)} be performed.
+     * @deprecated Use {@link #requestApplyInsets()} for newer platform versions.
      */
     public void requestFitSystemWindows() {
         if (mParent != null) {
@@ -6003,6 +6355,13 @@
     }
 
     /**
+     * Ask that a new dispatch of {@link #onApplyWindowInsets(WindowInsets)} be performed.
+     */
+    public void requestApplyInsets() {
+        requestFitSystemWindows();
+    }
+
+    /**
      * For use by PhoneWindow to make its own system window fitting optional.
      * @hide
      */
@@ -6021,6 +6380,7 @@
         @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"),
         @ViewDebug.IntToString(from = GONE,      to = "GONE")
     })
+    @Visibility
     public int getVisibility() {
         return mViewFlags & VISIBILITY_MASK;
     }
@@ -6032,7 +6392,7 @@
      * @attr ref android.R.styleable#View_visibility
      */
     @RemotableViewMethod
-    public void setVisibility(int visibility) {
+    public void setVisibility(@Visibility int visibility) {
         setFlags(visibility, VISIBILITY_MASK);
         if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
     }
@@ -6191,6 +6551,7 @@
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_INHERIT, to = "INHERIT"),
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE,  to = "LOCALE")
     })
+    @LayoutDir
     public int getRawLayoutDirection() {
         return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
     }
@@ -6213,7 +6574,7 @@
      * @attr ref android.R.styleable#View_layoutDirection
      */
     @RemotableViewMethod
-    public void setLayoutDirection(int layoutDirection) {
+    public void setLayoutDirection(@LayoutDir int layoutDirection) {
         if (getRawLayoutDirection() != layoutDirection) {
             // Reset the current layout direction and the resolved one
             mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK;
@@ -6243,6 +6604,7 @@
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_LTR, to = "RESOLVED_DIRECTION_LTR"),
         @ViewDebug.IntToString(from = LAYOUT_DIRECTION_RTL, to = "RESOLVED_DIRECTION_RTL")
     })
+    @ResolvedLayoutDir
     public int getLayoutDirection() {
         final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
         if (targetSdkVersion < JELLY_BEAN_MR1) {
@@ -6612,7 +6974,7 @@
      * @return The nearest focusable in the specified direction, or null if none
      *         can be found.
      */
-    public View focusSearch(int direction) {
+    public View focusSearch(@FocusRealDirection int direction) {
         if (mParent != null) {
             return mParent.focusSearch(this, direction);
         } else {
@@ -6631,7 +6993,7 @@
      *        FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT.
      * @return True if the this view consumed this unhandled move.
      */
-    public boolean dispatchUnhandledMove(View focused, int direction) {
+    public boolean dispatchUnhandledMove(View focused, @FocusRealDirection int direction) {
         return false;
     }
 
@@ -6643,7 +7005,7 @@
      * or FOCUS_BACKWARD.
      * @return The user specified next view, or null if there is none.
      */
-    View findUserSetNextFocus(View root, int direction) {
+    View findUserSetNextFocus(View root, @FocusDirection int direction) {
         switch (direction) {
             case FOCUS_LEFT:
                 if (mNextFocusLeftId == View.NO_ID) return null;
@@ -6693,7 +7055,7 @@
      * @param direction The direction of the focus
      * @return A list of focusable views
      */
-    public ArrayList<View> getFocusables(int direction) {
+    public ArrayList<View> getFocusables(@FocusDirection int direction) {
         ArrayList<View> result = new ArrayList<View>(24);
         addFocusables(result, direction);
         return result;
@@ -6707,7 +7069,7 @@
      * @param views Focusable views found so far
      * @param direction The direction of the focus
      */
-    public void addFocusables(ArrayList<View> views, int direction) {
+    public void addFocusables(ArrayList<View> views, @FocusDirection int direction) {
         addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
     }
 
@@ -6727,7 +7089,8 @@
      * @see #FOCUSABLES_ALL
      * @see #FOCUSABLES_TOUCH_MODE
      */
-    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+    public void addFocusables(ArrayList<View> views, @FocusDirection int direction,
+            @FocusableMode int focusableMode) {
         if (views == null) {
             return;
         }
@@ -6756,7 +7119,8 @@
      * @see #FIND_VIEWS_WITH_CONTENT_DESCRIPTION
      * @see #setContentDescription(CharSequence)
      */
-    public void findViewsWithText(ArrayList<View> outViews, CharSequence searched, int flags) {
+    public void findViewsWithText(ArrayList<View> outViews, CharSequence searched,
+            @FindViewFlags int flags) {
         if (getAccessibilityNodeProvider() != null) {
             if ((flags & FIND_VIEWS_WITH_ACCESSIBILITY_NODE_PROVIDERS) != 0) {
                 outViews.add(this);
@@ -6803,7 +7167,6 @@
      * Returns whether this View is accessibility focused.
      *
      * @return True if this View is accessibility focused.
-     * @hide
      */
     public boolean isAccessibilityFocused() {
         return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0;
@@ -7151,11 +7514,38 @@
     }
 
     /**
-     * Gets whether this view should be exposed for accessibility.
+     * Computes whether this view should be exposed for accessibility. In
+     * general, views that are interactive or provide information are exposed
+     * while views that serve only as containers are hidden.
+     * <p>
+     * If an ancestor of this view has importance
+     * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, this method
+     * returns <code>false</code>.
+     * <p>
+     * Otherwise, the value is computed according to the view's
+     * {@link #getImportantForAccessibility()} value:
+     * <ol>
+     * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_NO} or
+     * {@link #IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS}, return <code>false
+     * </code>
+     * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_YES}, return <code>true</code>
+     * <li>{@link #IMPORTANT_FOR_ACCESSIBILITY_AUTO}, return <code>true</code> if
+     * view satisfies any of the following:
+     * <ul>
+     * <li>Is actionable, e.g. {@link #isClickable()},
+     * {@link #isLongClickable()}, or {@link #isFocusable()}
+     * <li>Has an {@link AccessibilityDelegate}
+     * <li>Has an interaction listener, e.g. {@link OnTouchListener},
+     * {@link OnKeyListener}, etc.
+     * <li>Is an accessibility live region, e.g.
+     * {@link #getAccessibilityLiveRegion()} is not
+     * {@link #ACCESSIBILITY_LIVE_REGION_NONE}.
+     * </ul>
+     * </ol>
      *
      * @return Whether the view is exposed for accessibility.
-     *
-     * @hide
+     * @see #setImportantForAccessibility(int)
+     * @see #getImportantForAccessibility()
      */
     public boolean isImportantForAccessibility() {
         final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
@@ -7208,9 +7598,7 @@
      * @param children The list of children for accessibility.
      */
     public void addChildrenForAccessibility(ArrayList<View> children) {
-        if (includeForAccessibility()) {
-            children.add(this);
-        }
+
     }
 
     /**
@@ -7224,7 +7612,6 @@
      * @hide
      */
     public boolean includeForAccessibility() {
-        //noinspection SimplifiableIfStatement
         if (mAttachInfo != null) {
             return (mAttachInfo.mAccessibilityFetchFlags
                     & AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS) != 0
@@ -7247,7 +7634,7 @@
     }
 
     /**
-     * Returns whether the View has registered callbacks wich makes it
+     * Returns whether the View has registered callbacks which makes it
      * important for accessibility.
      *
      * @return True if the view is actionable for accessibility.
@@ -7266,7 +7653,7 @@
      * 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.
+     * notification this method is a NOP until the notification has been sent.
      *
      * @hide
      */
@@ -7584,8 +7971,6 @@
      * @hide
      */
     public void dispatchStartTemporaryDetach() {
-        clearDisplayList();
-
         onStartTemporaryDetach();
     }
 
@@ -7946,7 +8331,8 @@
      * @param visibility The new visibility of changedView: {@link #VISIBLE},
      * {@link #INVISIBLE} or {@link #GONE}.
      */
-    protected void dispatchVisibilityChanged(View changedView, int visibility) {
+    protected void dispatchVisibilityChanged(@NonNull View changedView,
+            @Visibility int visibility) {
         onVisibilityChanged(changedView, visibility);
     }
 
@@ -7957,7 +8343,7 @@
      * @param visibility The new visibility of changedView: {@link #VISIBLE},
      * {@link #INVISIBLE} or {@link #GONE}.
      */
-    protected void onVisibilityChanged(View changedView, int visibility) {
+    protected void onVisibilityChanged(@NonNull View changedView, @Visibility int visibility) {
         if (visibility == VISIBLE) {
             if (mAttachInfo != null) {
                 initialAwakenScrollBars();
@@ -7976,7 +8362,7 @@
      * @param hint A hint about whether or not this view is displayed:
      * {@link #VISIBLE} or {@link #INVISIBLE}.
      */
-    public void dispatchDisplayHint(int hint) {
+    public void dispatchDisplayHint(@Visibility int hint) {
         onDisplayHint(hint);
     }
 
@@ -7989,7 +8375,7 @@
      * @param hint A hint about whether or not this view is displayed:
      * {@link #VISIBLE} or {@link #INVISIBLE}.
      */
-    protected void onDisplayHint(int hint) {
+    protected void onDisplayHint(@Visibility int hint) {
     }
 
     /**
@@ -8000,7 +8386,7 @@
      *
      * @see #onWindowVisibilityChanged(int)
      */
-    public void dispatchWindowVisibilityChanged(int visibility) {
+    public void dispatchWindowVisibilityChanged(@Visibility int visibility) {
         onWindowVisibilityChanged(visibility);
     }
 
@@ -8014,7 +8400,7 @@
      *
      * @param visibility The new visibility of the window.
      */
-    protected void onWindowVisibilityChanged(int visibility) {
+    protected void onWindowVisibilityChanged(@Visibility int visibility) {
         if (visibility == VISIBLE) {
             initialAwakenScrollBars();
         }
@@ -8026,6 +8412,7 @@
      *
      * @return Returns the current visibility of the view's window.
      */
+    @Visibility
     public int getWindowVisibility() {
         return mAttachInfo != null ? mAttachInfo.mWindowVisibility : GONE;
     }
@@ -8306,7 +8693,14 @@
      *
      * <p>When implementing this, you probably also want to implement
      * {@link #onCheckIsTextEditor()} to indicate you will return a
-     * non-null InputConnection.
+     * non-null InputConnection.</p>
+     *
+     * <p>Also, take good care to fill in the {@link android.view.inputmethod.EditorInfo}
+     * object correctly and in its entirety, so that the connected IME can rely
+     * on its values. For example, {@link android.view.inputmethod.EditorInfo#initialSelStart}
+     * and  {@link android.view.inputmethod.EditorInfo#initialSelEnd} members
+     * must be filled in with the correct cursor position for IMEs to work correctly
+     * with your application.</p>
      *
      * @param outAttrs Fill in with attribute information about the connection.
      */
@@ -8742,12 +9136,49 @@
                     }
                     break;
             }
+
+            if (mBackground != null && mBackground.supportsHotspots()) {
+                manageTouchHotspot(event);
+            }
+
             return true;
         }
 
         return false;
     }
 
+    private void manageTouchHotspot(MotionEvent event) {
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_POINTER_DOWN: {
+                final int index = event.getActionIndex();
+                setPointerHotspot(event, index);
+            } break;
+            case MotionEvent.ACTION_MOVE: {
+                final int count = event.getPointerCount();
+                for (int index = 0; index < count; index++) {
+                    setPointerHotspot(event, index);
+                }
+            } break;
+            case MotionEvent.ACTION_POINTER_UP: {
+                final int actionIndex = event.getActionIndex();
+                final int pointerId = event.getPointerId(actionIndex);
+                mBackground.removeHotspot(pointerId);
+            } break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mBackground.clearHotspots();
+                break;
+        }
+    }
+
+    private void setPointerHotspot(MotionEvent event, int index) {
+        final int id = event.getPointerId(index);
+        final float x = event.getX(index);
+        final float y = event.getY(index);
+        mBackground.setHotspot(id, x, y);
+    }
+
     /**
      * @hide
      */
@@ -8947,7 +9378,7 @@
 
         if ((changed & VISIBILITY_MASK) != 0) {
             // If the view is invisible, cleanup its display list to free up resources
-            if (newVisibility != VISIBLE) {
+            if (newVisibility != VISIBLE && mAttachInfo != null) {
                 cleanupDraw();
             }
 
@@ -8959,6 +9390,8 @@
                 mParent.invalidateChild(this, null);
             }
             dispatchVisibilityChanged(this, newVisibility);
+
+            notifySubtreeAccessibilityStateChangedIfNeeded();
         }
 
         if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
@@ -10344,6 +10777,111 @@
     }
 
     /**
+     * The depth location of this view relative to its parent.
+     *
+     * @return The depth of this view relative to its parent.
+     */
+    @ViewDebug.ExportedProperty(category = "drawing")
+    public float getTranslationZ() {
+        return mTransformationInfo != null ? mTransformationInfo.mTranslationZ : 0;
+    }
+
+    /**
+     * Sets the depth location of this view relative to its parent.
+     *
+     * @attr ref android.R.styleable#View_translationZ
+     */
+    public void setTranslationZ(float translationZ) {
+        ensureTransformationInfo();
+        final TransformationInfo info = mTransformationInfo;
+        if (info.mTranslationZ != translationZ) {
+            invalidateViewProperty(true, false);
+            info.mTranslationZ = translationZ;
+            info.mMatrixDirty = true;
+            invalidateViewProperty(false, true);
+            if (mDisplayList != null) {
+                mDisplayList.setTranslationZ(translationZ);
+            }
+            if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
+                // View was rejected last time it was drawn by its parent; this may have changed
+                invalidateParentIfNeeded();
+            }
+        }
+    }
+
+    /**
+     * Sets the outline of the view, which defines the shape of the shadow it
+     * casts, and can used for clipping.
+     * <p>
+     * If the outline is not set or is null, shadows will be cast from the
+     * bounds of the View, and clipToOutline will be ignored.
+     *
+     * @param outline The new outline of the view.
+     *         Must be {@link android.view.Outline#isValid() valid.}
+     *
+     * @see #getClipToOutline()
+     * @see #setClipToOutline(boolean)
+     */
+    public void setOutline(@Nullable Outline outline) {
+        if (outline != null && !outline.isValid()) {
+            throw new IllegalArgumentException("Outline must not be invalid");
+        }
+
+        mPrivateFlags3 |= PFLAG3_OUTLINE_DEFINED;
+
+        if (outline == null) {
+            mOutline = null;
+        } else {
+            // always copy the path since caller may reuse
+            if (mOutline == null) {
+                mOutline = new Outline();
+            }
+            mOutline.set(outline);
+        }
+
+        if (mDisplayList != null) {
+            mDisplayList.setOutline(mOutline);
+        }
+    }
+
+    /**
+     * Returns whether the outline of the View will be used for clipping.
+     *
+     * @see #setOutline(Outline)
+     */
+    public final boolean getClipToOutline() {
+        return ((mPrivateFlags3 & PFLAG3_CLIP_TO_OUTLINE) != 0);
+    }
+
+    /**
+     * Sets whether the outline of the View will be used for clipping.
+     * <p>
+     * The current implementation of outline clipping uses Canvas#clipPath(),
+     * and thus does not support anti-aliasing, and is expensive in terms of
+     * graphics performance. Therefore, it is strongly recommended that this
+     * property only be set temporarily, as in an animation. For the same
+     * reasons, there is no parallel XML attribute for this property.
+     * <p>
+     * If the outline of the view is not set or is empty, no clipping will be
+     * performed.
+     *
+     * @see #setOutline(Outline)
+     */
+    public void setClipToOutline(boolean clipToOutline) {
+        // TODO : Add a fast invalidation here.
+        if (getClipToOutline() != clipToOutline) {
+            if (clipToOutline) {
+                mPrivateFlags3 |= PFLAG3_CLIP_TO_OUTLINE;
+            } else {
+                mPrivateFlags3 &= ~PFLAG3_CLIP_TO_OUTLINE;
+            }
+            if (mDisplayList != null) {
+                mDisplayList.setClipToOutline(clipToOutline);
+            }
+        }
+    }
+
+    /**
      * Hit rectangle in parent's coordinates
      *
      * @param outRect The hit rectangle of the view.
@@ -10797,94 +11335,54 @@
                 (!(mParent instanceof ViewGroup) ||
                         !((ViewGroup) mParent).isViewTransitioning(this));
     }
+
     /**
      * Mark the area defined by dirty as needing to be drawn. If the view is
-     * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some point
-     * in the future. This must be called from a UI thread. To call from a non-UI
-     * thread, call {@link #postInvalidate()}.
+     * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
+     * point in the future.
+     * <p>
+     * This must be called from a UI thread. To call from a non-UI thread, call
+     * {@link #postInvalidate()}.
+     * <p>
+     * <b>WARNING:</b> In API 19 and below, this method may be destructive to
+     * {@code dirty}.
      *
-     * WARNING: This method is destructive to dirty.
      * @param dirty the rectangle representing the bounds of the dirty region
      */
     public void invalidate(Rect dirty) {
-        if (skipInvalidate()) {
-            return;
-        }
-        if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
-                (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID ||
-                (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED) {
-            mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
-            mPrivateFlags |= PFLAG_INVALIDATED;
-            mPrivateFlags |= PFLAG_DIRTY;
-            final ViewParent p = mParent;
-            final AttachInfo ai = mAttachInfo;
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
-                if (p != null && ai != null && ai.mHardwareAccelerated) {
-                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                    // with a null dirty rect, which tells the ViewAncestor to redraw everything
-                    p.invalidateChild(this, null);
-                    return;
-                }
-            }
-            if (p != null && ai != null) {
-                final int scrollX = mScrollX;
-                final int scrollY = mScrollY;
-                final Rect r = ai.mTmpInvalRect;
-                r.set(dirty.left - scrollX, dirty.top - scrollY,
-                        dirty.right - scrollX, dirty.bottom - scrollY);
-                mParent.invalidateChild(this, r);
-            }
-        }
+        final int scrollX = mScrollX;
+        final int scrollY = mScrollY;
+        invalidateInternal(dirty.left - scrollX, dirty.top - scrollY,
+                dirty.right - scrollX, dirty.bottom - scrollY, true, false);
     }
 
     /**
-     * Mark the area defined by the rect (l,t,r,b) as needing to be drawn.
-     * The coordinates of the dirty rect are relative to the view.
-     * If the view is visible, {@link #onDraw(android.graphics.Canvas)}
-     * will be called at some point in the future. This must be called from
-     * a UI thread. To call from a non-UI thread, call {@link #postInvalidate()}.
+     * Mark the area defined by the rect (l,t,r,b) as needing to be drawn. The
+     * coordinates of the dirty rect are relative to the view. If the view is
+     * visible, {@link #onDraw(android.graphics.Canvas)} will be called at some
+     * point in the future.
+     * <p>
+     * This must be called from a UI thread. To call from a non-UI thread, call
+     * {@link #postInvalidate()}.
+     *
      * @param l the left position of the dirty region
      * @param t the top position of the dirty region
      * @param r the right position of the dirty region
      * @param b the bottom position of the dirty region
      */
     public void invalidate(int l, int t, int r, int b) {
-        if (skipInvalidate()) {
-            return;
-        }
-        if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
-                (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID ||
-                (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED) {
-            mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
-            mPrivateFlags |= PFLAG_INVALIDATED;
-            mPrivateFlags |= PFLAG_DIRTY;
-            final ViewParent p = mParent;
-            final AttachInfo ai = mAttachInfo;
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
-                if (p != null && ai != null && ai.mHardwareAccelerated) {
-                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                    // with a null dirty rect, which tells the ViewAncestor to redraw everything
-                    p.invalidateChild(this, null);
-                    return;
-                }
-            }
-            if (p != null && ai != null && l < r && t < b) {
-                final int scrollX = mScrollX;
-                final int scrollY = mScrollY;
-                final Rect tmpr = ai.mTmpInvalRect;
-                tmpr.set(l - scrollX, t - scrollY, r - scrollX, b - scrollY);
-                p.invalidateChild(this, tmpr);
-            }
-        }
+        final int scrollX = mScrollX;
+        final int scrollY = mScrollY;
+        invalidateInternal(l - scrollX, t - scrollY, r - scrollX, b - scrollY, true, false);
     }
 
     /**
      * Invalidate the whole view. If the view is visible,
      * {@link #onDraw(android.graphics.Canvas)} will be called at some point in
-     * the future. This must be called from a UI thread. To call from a non-UI thread,
-     * call {@link #postInvalidate()}.
+     * the future.
+     * <p>
+     * This must be called from a UI thread. To call from a non-UI thread, call
+     * {@link #postInvalidate()}.
      */
     public void invalidate() {
         invalidate(true);
@@ -10892,47 +11390,102 @@
 
     /**
      * This is where the invalidate() work actually happens. A full invalidate()
-     * causes the drawing cache to be invalidated, but this function can be called with
-     * invalidateCache set to false to skip that invalidation step for cases that do not
-     * need it (for example, a component that remains at the same dimensions with the same
-     * content).
+     * causes the drawing cache to be invalidated, but this function can be
+     * called with invalidateCache set to false to skip that invalidation step
+     * for cases that do not need it (for example, a component that remains at
+     * the same dimensions with the same content).
      *
-     * @param invalidateCache Whether the drawing cache for this view should be invalidated as
-     * well. This is usually true for a full invalidate, but may be set to false if the
-     * View's contents or dimensions have not changed.
+     * @param invalidateCache Whether the drawing cache for this view should be
+     *            invalidated as well. This is usually true for a full
+     *            invalidate, but may be set to false if the View's contents or
+     *            dimensions have not changed.
      */
     void invalidate(boolean invalidateCache) {
+        invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true);
+    }
+
+    void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
+            boolean fullInvalidate) {
         if (skipInvalidate()) {
             return;
         }
-        if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
-                (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) ||
-                (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || isOpaque() != mLastIsOpaque) {
-            mLastIsOpaque = isOpaque();
-            mPrivateFlags &= ~PFLAG_DRAWN;
+
+        if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
+                || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID)
+                || (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED
+                || (fullInvalidate && isOpaque() != mLastIsOpaque)) {
+            if (fullInvalidate) {
+                mLastIsOpaque = isOpaque();
+                mPrivateFlags &= ~PFLAG_DRAWN;
+            }
+
             mPrivateFlags |= PFLAG_DIRTY;
+
             if (invalidateCache) {
                 mPrivateFlags |= PFLAG_INVALIDATED;
                 mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
             }
+
+            // Propagate the damage rectangle to the parent view.
             final AttachInfo ai = mAttachInfo;
             final ViewParent p = mParent;
-            //noinspection PointlessBooleanExpression,ConstantConditions
-            if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
-                if (p != null && ai != null && ai.mHardwareAccelerated) {
-                    // fast-track for GL-enabled applications; just invalidate the whole hierarchy
-                    // with a null dirty rect, which tells the ViewAncestor to redraw everything
-                    p.invalidateChild(this, null);
-                    return;
+            if (p != null && ai != null && l < r && t < b) {
+                final Rect damage = ai.mTmpInvalRect;
+                damage.set(l, t, r, b);
+                p.invalidateChild(this, damage);
+            }
+
+            // Damage the entire projection receiver, if necessary.
+            if (mBackground != null && mBackground.isProjected()) {
+                final View receiver = getProjectionReceiver();
+                if (receiver != null) {
+                    receiver.damageInParent();
                 }
             }
 
-            if (p != null && ai != null) {
-                final Rect r = ai.mTmpInvalRect;
-                r.set(0, 0, mRight - mLeft, mBottom - mTop);
-                // Don't call invalidate -- we don't want to internally scroll
-                // our own bounds
-                p.invalidateChild(this, r);
+            // Damage the entire IsolatedZVolume recieving this view's shadow.
+            if (getTranslationZ() != 0) {
+                damageShadowReceiver();
+            }
+        }
+    }
+
+    /**
+     * @return this view's projection receiver, or {@code null} if none exists
+     */
+    private View getProjectionReceiver() {
+        ViewParent p = getParent();
+        while (p != null && p instanceof View) {
+            final View v = (View) p;
+            if (v.isProjectionReceiver()) {
+                return v;
+            }
+            p = p.getParent();
+        }
+
+        return null;
+    }
+
+    /**
+     * @return whether the view is a projection receiver
+     */
+    private boolean isProjectionReceiver() {
+        return mBackground != null;
+    }
+
+    /**
+     * Damage area of the screen that can be covered by this View's shadow.
+     *
+     * This method will guarantee that any changes to shadows cast by a View
+     * are damaged on the screen for future redraw.
+     */
+    private void damageShadowReceiver() {
+        final AttachInfo ai = mAttachInfo;
+        if (ai != null) {
+            ViewParent p = getParent();
+            if (p != null && p instanceof ViewGroup) {
+                final ViewGroup vg = (ViewGroup) p;
+                vg.damageInParent();
             }
         }
     }
@@ -10963,16 +11516,28 @@
             }
             invalidate(false);
         } else {
-            final AttachInfo ai = mAttachInfo;
-            final ViewParent p = mParent;
-            if (p != null && ai != null) {
-                final Rect r = ai.mTmpInvalRect;
-                r.set(0, 0, mRight - mLeft, mBottom - mTop);
-                if (mParent instanceof ViewGroup) {
-                    ((ViewGroup) mParent).invalidateChildFast(this, r);
-                } else {
-                    mParent.invalidateChild(this, r);
-                }
+            damageInParent();
+        }
+        if (invalidateParent && getTranslationZ() != 0) {
+            damageShadowReceiver();
+        }
+    }
+
+    /**
+     * Tells the parent view to damage this view's bounds.
+     *
+     * @hide
+     */
+    protected void damageInParent() {
+        final AttachInfo ai = mAttachInfo;
+        final ViewParent p = mParent;
+        if (p != null && ai != null) {
+            final Rect r = ai.mTmpInvalRect;
+            r.set(0, 0, mRight - mLeft, mBottom - mTop);
+            if (mParent instanceof ViewGroup) {
+                ((ViewGroup) mParent).invalidateChildFast(this, r);
+            } else {
+                mParent.invalidateChild(this, r);
             }
         }
     }
@@ -11096,6 +11661,13 @@
     }
 
     /**
+     * @hide
+     */
+    public HardwareRenderer getHardwareRenderer() {
+        return mAttachInfo != null ? mAttachInfo.mHardwareRenderer : null;
+    }
+
+    /**
      * <p>Causes the Runnable to be added to the message queue.
      * The runnable will be run on the user interface thread.</p>
      *
@@ -11212,10 +11784,9 @@
                 attachInfo.mHandler.removeCallbacks(action);
                 attachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
                         Choreographer.CALLBACK_ANIMATION, action, null);
-            } else {
-                // Assume that post will succeed later
-                ViewRootImpl.getRunQueue().removeCallbacks(action);
             }
+            // Assume that post will succeed later
+            ViewRootImpl.getRunQueue().removeCallbacks(action);
         }
         return true;
     }
@@ -11706,7 +12277,7 @@
      *
      * @attr ref android.R.styleable#View_scrollbarStyle
      */
-    public void setScrollBarStyle(int style) {
+    public void setScrollBarStyle(@ScrollBarStyle int style) {
         if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
             mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
             computeOpaqueFlags();
@@ -11730,6 +12301,7 @@
             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_OVERLAY, to = "OUTSIDE_OVERLAY"),
             @ViewDebug.IntToString(from = SCROLLBARS_OUTSIDE_INSET, to = "OUTSIDE_INSET")
     })
+    @ScrollBarStyle
     public int getScrollBarStyle() {
         return mViewFlags & SCROLLBARS_STYLE_MASK;
     }
@@ -12121,10 +12693,6 @@
             InputMethodManager imm = InputMethodManager.peekInstance();
             imm.focusIn(this);
         }
-
-        if (mDisplayList != null) {
-            mDisplayList.clearDirty();
-        }
     }
 
     /**
@@ -12231,7 +12799,7 @@
      * @see #LAYOUT_DIRECTION_LTR
      * @see #LAYOUT_DIRECTION_RTL
      */
-    public void onRtlPropertiesChanged(int layoutDirection) {
+    public void onRtlPropertiesChanged(@ResolvedLayoutDir int layoutDirection) {
     }
 
     /**
@@ -12425,6 +12993,19 @@
      * @see #onAttachedToWindow()
      */
     protected void onDetachedFromWindow() {
+    }
+
+    /**
+     * This is a framework-internal mirror of onDetachedFromWindow() that's called
+     * after onDetachedFromWindow().
+     *
+     * If you override this you *MUST* call super.onDetachedFromWindowInternal()!
+     * The super method should be called at the end of the overriden method to ensure
+     * subclasses are destroyed first
+     *
+     * @hide
+     */
+    protected void onDetachedFromWindowInternal() {
         mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
         mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT;
 
@@ -12442,15 +13023,9 @@
     }
 
     private void cleanupDraw() {
+        resetDisplayList();
         if (mAttachInfo != null) {
-            if (mDisplayList != null) {
-                mDisplayList.markDirty();
-                mAttachInfo.mViewRootImpl.enqueueDisplayList(mDisplayList);
-            }
             mAttachInfo.mViewRootImpl.cancelInvalidate(this);
-        } else {
-            // Should never happen
-            resetDisplayList();
         }
     }
 
@@ -12618,6 +13193,7 @@
         }
 
         onDetachedFromWindow();
+        onDetachedFromWindowInternal();
 
         ListenerInfo li = mListenerInfo;
         final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
@@ -12919,11 +13495,7 @@
         }
 
         if (layerType == mLayerType) {
-            if (layerType != LAYER_TYPE_NONE && paint != mLayerPaint) {
-                mLayerPaint = paint == null ? new Paint() : paint;
-                invalidateParentCaches();
-                invalidate(true);
-            }
+            setLayerPaint(paint);
             return;
         }
 
@@ -12980,7 +13552,7 @@
             if (layerType == LAYER_TYPE_HARDWARE) {
                 HardwareLayer layer = getHardwareLayer();
                 if (layer != null) {
-                    layer.setLayerPaint(paint);
+                    layer.setLayerPaint(mLayerPaint);
                 }
                 invalidateViewProperty(false, false);
             } else {
@@ -13040,19 +13612,15 @@
 
         switch (mLayerType) {
             case LAYER_TYPE_HARDWARE:
-                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();
-                    }
+                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:
@@ -13073,8 +13641,6 @@
             return null;
         }
 
-        if (!mAttachInfo.mHardwareRenderer.validate()) return null;
-
         final int width = mRight - mLeft;
         final int height = mBottom - mTop;
 
@@ -13084,16 +13650,10 @@
 
         if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || mHardwareLayer == null) {
             if (mHardwareLayer == null) {
-                mHardwareLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
-                        width, height, isOpaque());
+                mHardwareLayer = mAttachInfo.mHardwareRenderer.createDisplayListLayer(
+                        width, height);
                 mLocalDirtyRect.set(0, 0, width, height);
-            } else {
-                if (mHardwareLayer.getWidth() != width || mHardwareLayer.getHeight() != height) {
-                    if (mHardwareLayer.resize(width, height)) {
-                        mLocalDirtyRect.set(0, 0, width, height);
-                    }
-                }
-
+            } else if (mHardwareLayer.isValid()) {
                 // This should not be necessary but applications that change
                 // the parameters of their background drawable without calling
                 // this.setBackground(Drawable) can leave the view in a bad state
@@ -13101,23 +13661,24 @@
                 // not opaque.)
                 computeOpaqueFlags();
 
-                final boolean opaque = isOpaque();
-                if (mHardwareLayer.isValid() && mHardwareLayer.isOpaque() != opaque) {
-                    mHardwareLayer.setOpaque(opaque);
+                if (mHardwareLayer.prepare(width, height, isOpaque())) {
                     mLocalDirtyRect.set(0, 0, width, height);
                 }
             }
 
             // The layer is not valid if the underlying GPU resources cannot be allocated
+            mHardwareLayer.flushChanges();
             if (!mHardwareLayer.isValid()) {
                 return null;
             }
 
             mHardwareLayer.setLayerPaint(mLayerPaint);
-            mHardwareLayer.redrawLater(getHardwareLayerDisplayList(mHardwareLayer), mLocalDirtyRect);
-            ViewRootImpl viewRoot = getViewRootImpl();
-            if (viewRoot != null) viewRoot.pushHardwareLayerUpdate(mHardwareLayer);
-
+            RenderNode displayList = mHardwareLayer.startRecording();
+            if (getDisplayList(displayList, true) != displayList) {
+                throw new IllegalStateException("getDisplayList() didn't return"
+                        + " the input displaylist for a hardware layer!");
+            }
+            mHardwareLayer.endRecording(mLocalDirtyRect);
             mLocalDirtyRect.setEmpty();
         }
 
@@ -13134,18 +13695,11 @@
      */
     boolean destroyLayer(boolean valid) {
         if (mHardwareLayer != null) {
-            AttachInfo info = mAttachInfo;
-            if (info != null && info.mHardwareRenderer != null &&
-                    info.mHardwareRenderer.isEnabled() &&
-                    (valid || info.mHardwareRenderer.validate())) {
+            mHardwareLayer.destroy();
+            mHardwareLayer = null;
 
-                info.mHardwareRenderer.cancelLayerUpdate(mHardwareLayer);
-                mHardwareLayer.destroy();
-                mHardwareLayer = null;
-
-                invalidate(true);
-                invalidateParentCaches();
-            }
+            invalidate(true);
+            invalidateParentCaches();
             return true;
         }
         return false;
@@ -13260,20 +13814,6 @@
     }
 
     /**
-     * @return The {@link HardwareRenderer} associated with that view or null if
-     *         hardware rendering is not supported or this view is not attached
-     *         to a window.
-     *
-     * @hide
-     */
-    public HardwareRenderer getHardwareRenderer() {
-        if (mAttachInfo != null) {
-            return mAttachInfo.mHardwareRenderer;
-        }
-        return null;
-    }
-
-    /**
      * Returns a DisplayList. If the incoming displayList is null, one will be created.
      * Otherwise, the same display list will be returned (after having been rendered into
      * along the way, depending on the invalidation state of the view).
@@ -13283,8 +13823,9 @@
      * the view will avoid creating a layer inside the resulting display list.
      * @return A new or reused DisplayList object.
      */
-    private DisplayList getDisplayList(DisplayList displayList, boolean isLayer) {
-        if (!canHaveDisplayList()) {
+    private RenderNode getDisplayList(RenderNode displayList, boolean isLayer) {
+        final HardwareRenderer renderer = getHardwareRenderer();
+        if (renderer == null || !canHaveDisplayList()) {
             return null;
         }
 
@@ -13308,7 +13849,7 @@
                 mRecreateDisplayList = true;
             }
             if (displayList == null) {
-                displayList = mAttachInfo.mHardwareRenderer.createDisplayList(getClass().getName());
+                displayList = RenderNode.create(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.
@@ -13363,13 +13904,21 @@
                     }
                 }
             } finally {
-                displayList.end();
+                displayList.end(renderer, canvas);
                 displayList.setCaching(caching);
                 if (isLayer) {
                     displayList.setLeftTopRightBottom(0, 0, width, height);
                 } else {
                     setDisplayListProperties(displayList);
                 }
+
+                if (renderer != getHardwareRenderer()) {
+                    Log.w(VIEW_LOG_TAG, "View was detached during a draw() call!");
+                    // TODO: Should this be elevated to a crash?
+                    // For now have it behaves the same as it previously did, it
+                    // will result in the DisplayListData being destroyed later
+                    // than it could be but oh well...
+                }
             }
         } else if (!isLayer) {
             mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
@@ -13380,19 +13929,6 @@
     }
 
     /**
-     * Get the DisplayList for the HardwareLayer
-     *
-     * @param layer The HardwareLayer whose DisplayList we want
-     * @return A DisplayList fopr the specified HardwareLayer
-     */
-    private DisplayList getHardwareLayerDisplayList(HardwareLayer layer) {
-        DisplayList displayList = getDisplayList(layer.getDisplayList(), true);
-        layer.setDisplayList(displayList);
-        return displayList;
-    }
-
-
-    /**
      * <p>Returns a display list that can be used to draw this view again
      * without executing its draw method.</p>
      *
@@ -13400,20 +13936,18 @@
      *
      * @hide
      */
-    public DisplayList getDisplayList() {
+    public RenderNode getDisplayList() {
         mDisplayList = getDisplayList(mDisplayList, false);
         return mDisplayList;
     }
 
-    private void clearDisplayList() {
-        if (mDisplayList != null) {
-            mDisplayList.clear();
-        }
-    }
-
     private void resetDisplayList() {
-        if (mDisplayList != null) {
-            mDisplayList.reset();
+        if (mDisplayList != null && mDisplayList.isValid()) {
+            mDisplayList.destroyDisplayListData();
+        }
+
+        if (mBackgroundDisplayList != null && mBackgroundDisplayList.isValid()) {
+            mBackgroundDisplayList.destroyDisplayListData();
         }
     }
 
@@ -14008,7 +14542,7 @@
      * necessary when a display list is being re-created, because we need to make sure that
      * previously-set transform values
      */
-    void setDisplayListProperties(DisplayList displayList) {
+    void setDisplayListProperties(RenderNode displayList) {
         if (displayList != null) {
             displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
             displayList.setHasOverlappingRendering(hasOverlappingRendering());
@@ -14016,6 +14550,8 @@
                 displayList.setClipToBounds(
                         (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
             }
+            displayList.setOutline(mOutline);
+            displayList.setClipToOutline(getClipToOutline());
             float alpha = 1;
             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
@@ -14028,7 +14564,7 @@
                             alpha = t.getAlpha();
                         }
                         if ((transformType & Transformation.TYPE_MATRIX) != 0) {
-                            displayList.setMatrix(t.getMatrix());
+                            displayList.setStaticMatrix(t.getMatrix());
                         }
                     }
                 }
@@ -14043,6 +14579,7 @@
                 }
                 displayList.setTransformationInfo(alpha,
                         mTransformationInfo.mTranslationX, mTransformationInfo.mTranslationY,
+                        mTransformationInfo.mTranslationZ,
                         mTransformationInfo.mRotation, mTransformationInfo.mRotationX,
                         mTransformationInfo.mRotationY, mTransformationInfo.mScaleX,
                         mTransformationInfo.mScaleY);
@@ -14144,7 +14681,7 @@
             mPrivateFlags &= ~PFLAG_INVALIDATED;
         }
 
-        DisplayList displayList = null;
+        RenderNode displayList = null;
         Bitmap cache = null;
         boolean hasDisplayList = false;
         if (caching) {
@@ -14436,24 +14973,7 @@
         int saveCount;
 
         if (!dirtyOpaque) {
-            final Drawable background = mBackground;
-            if (background != null) {
-                final int scrollX = mScrollX;
-                final int scrollY = mScrollY;
-
-                if (mBackgroundSizeChanged) {
-                    background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
-                    mBackgroundSizeChanged = false;
-                }
-
-                if ((scrollX | scrollY) == 0) {
-                    background.draw(canvas);
-                } else {
-                    canvas.translate(scrollX, scrollY);
-                    background.draw(canvas);
-                    canvas.translate(-scrollX, -scrollY);
-                }
-            }
+            drawBackground(canvas);
         }
 
         // skip step 2 & 5 if possible (common case)
@@ -14620,6 +15140,91 @@
     }
 
     /**
+     * Draws the background onto the specified canvas.
+     *
+     * @param canvas Canvas on which to draw the background
+     */
+    private void drawBackground(Canvas canvas) {
+        final Drawable background = mBackground;
+        if (background == null) {
+            return;
+        }
+
+        if (mBackgroundSizeChanged) {
+            background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);
+            mBackgroundSizeChanged = false;
+            if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) {
+                // Outline not currently define, query from background
+                mOutline = background.getOutline();
+                if (mDisplayList != null) {
+                    mDisplayList.setOutline(mOutline);
+                }
+            }
+        }
+
+        // Attempt to use a display list if requested.
+        if (canvas.isHardwareAccelerated() && mAttachInfo != null
+                && mAttachInfo.mHardwareRenderer != null) {
+            mBackgroundDisplayList = getDrawableDisplayList(background, mBackgroundDisplayList);
+
+            final RenderNode displayList = mBackgroundDisplayList;
+            if (displayList != null && displayList.isValid()) {
+                setBackgroundDisplayListProperties(displayList);
+                ((HardwareCanvas) canvas).drawDisplayList(displayList);
+                return;
+            }
+        }
+
+        final int scrollX = mScrollX;
+        final int scrollY = mScrollY;
+        if ((scrollX | scrollY) == 0) {
+            background.draw(canvas);
+        } else {
+            canvas.translate(scrollX, scrollY);
+            background.draw(canvas);
+            canvas.translate(-scrollX, -scrollY);
+        }
+    }
+
+    /**
+     * Set up background drawable display list properties.
+     *
+     * @param displayList Valid display list for the background drawable
+     */
+    private void setBackgroundDisplayListProperties(RenderNode displayList) {
+        displayList.setTranslationX(mScrollX);
+        displayList.setTranslationY(mScrollY);
+    }
+
+    /**
+     * Creates a new display list or updates the existing display list for the
+     * specified Drawable.
+     *
+     * @param drawable Drawable for which to create a display list
+     * @param displayList Existing display list, or {@code null}
+     * @return A valid display list for the specified drawable
+     */
+    private RenderNode getDrawableDisplayList(Drawable drawable, RenderNode displayList) {
+        if (displayList == null) {
+            displayList = RenderNode.create(drawable.getClass().getName());
+        }
+
+        final Rect bounds = drawable.getBounds();
+        final int width = bounds.width();
+        final int height = bounds.height();
+        final HardwareCanvas canvas = displayList.start(width, height);
+        drawable.draw(canvas);
+        displayList.end(getHardwareRenderer(), canvas);
+
+        // Set up drawable properties that are view-independent.
+        displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
+        displayList.setProjectBackwards(drawable.isProjected());
+        displayList.setProjectionReceiver(true);
+        displayList.setClipToBounds(false);
+        return displayList;
+    }
+
+    /**
      * Returns the overlay for this view, creating it if it does not yet exist.
      * Adding drawables to the overlay will cause them to be displayed whenever
      * the view itself is redrawn. Objects in the overlay should be actively
@@ -14960,9 +15565,10 @@
      *
      * @param drawable the drawable to invalidate
      */
+    @Override
     public void invalidateDrawable(Drawable drawable) {
         if (verifyDrawable(drawable)) {
-            final Rect dirty = drawable.getBounds();
+            final Rect dirty = drawable.getDirtyBounds();
             final int scrollX = mScrollX;
             final int scrollY = mScrollY;
 
@@ -14979,6 +15585,7 @@
      * @param when the time at which the action must occur. Uses the
      *        {@link SystemClock#uptimeMillis} timebase.
      */
+    @Override
     public void scheduleDrawable(Drawable who, Runnable what, long when) {
         if (verifyDrawable(who) && what != null) {
             final long delay = when - SystemClock.uptimeMillis();
@@ -14998,14 +15605,14 @@
      * @param who the recipient of the action
      * @param what the action to cancel
      */
+    @Override
     public void unscheduleDrawable(Drawable who, Runnable what) {
         if (verifyDrawable(who) && what != null) {
             if (mAttachInfo != null) {
                 mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks(
                         Choreographer.CALLBACK_ANIMATION, what, who);
-            } else {
-                ViewRootImpl.getRunQueue().removeCallbacks(what);
             }
+            ViewRootImpl.getRunQueue().removeCallbacks(what);
         }
     }
 
@@ -15068,7 +15675,7 @@
      *
      * @hide
      */
-    public void onResolveDrawables(int layoutDirection) {
+    public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) {
     }
 
     /**
@@ -15115,7 +15722,7 @@
      * @see Drawable#setState(int[])
      */
     protected void drawableStateChanged() {
-        Drawable d = mBackground;
+        final Drawable d = mBackground;
         if (d != null && d.isStateful()) {
             d.setState(getDrawableState());
         }
@@ -15300,7 +15907,7 @@
 
         Drawable d= null;
         if (resid != 0) {
-            d = mResources.getDrawable(resid);
+            d = mContext.getDrawable(resid);
         }
         setBackground(d);
 
@@ -15835,8 +16442,10 @@
             return false;
         }
 
-        transformMotionEventToGlobal(ev);
-        ev.offsetLocation(info.mWindowLeft, info.mWindowTop);
+        final Matrix m = info.mTmpMatrix;
+        m.set(Matrix.IDENTITY_MATRIX);
+        transformMatrixToGlobal(m);
+        ev.transform(m);
         return true;
     }
 
@@ -15854,54 +16463,60 @@
             return false;
         }
 
-        ev.offsetLocation(-info.mWindowLeft, -info.mWindowTop);
-        transformMotionEventToLocal(ev);
+        final Matrix m = info.mTmpMatrix;
+        m.set(Matrix.IDENTITY_MATRIX);
+        transformMatrixToLocal(m);
+        ev.transform(m);
         return true;
     }
 
     /**
-     * Recursive helper method that applies transformations in post-order.
+     * Modifies the input matrix such that it maps view-local coordinates to
+     * on-screen coordinates.
      *
-     * @param ev the on-screen motion event
+     * @param m input matrix to modify
      */
-    private void transformMotionEventToLocal(MotionEvent ev) {
+    void transformMatrixToGlobal(Matrix m) {
         final ViewParent parent = mParent;
         if (parent instanceof View) {
             final View vp = (View) parent;
-            vp.transformMotionEventToLocal(ev);
-            ev.offsetLocation(vp.mScrollX, vp.mScrollY);
+            vp.transformMatrixToGlobal(m);
+            m.postTranslate(-vp.mScrollX, -vp.mScrollY);
         } else if (parent instanceof ViewRootImpl) {
             final ViewRootImpl vr = (ViewRootImpl) parent;
-            ev.offsetLocation(0, vr.mCurScrollY);
+            vr.transformMatrixToGlobal(m);
+            m.postTranslate(0, -vr.mCurScrollY);
         }
 
-        ev.offsetLocation(-mLeft, -mTop);
+        m.postTranslate(mLeft, mTop);
 
         if (!hasIdentityMatrix()) {
-            ev.transform(getInverseMatrix());
+            m.postConcat(getMatrix());
         }
     }
 
     /**
-     * Recursive helper method that applies transformations in pre-order.
+     * Modifies the input matrix such that it maps on-screen coordinates to
+     * view-local coordinates.
      *
-     * @param ev the on-screen motion event
+     * @param m input matrix to modify
      */
-    private void transformMotionEventToGlobal(MotionEvent ev) {
-        if (!hasIdentityMatrix()) {
-            ev.transform(getMatrix());
-        }
-
-        ev.offsetLocation(mLeft, mTop);
-
+    void transformMatrixToLocal(Matrix m) {
         final ViewParent parent = mParent;
         if (parent instanceof View) {
             final View vp = (View) parent;
-            ev.offsetLocation(-vp.mScrollX, -vp.mScrollY);
-            vp.transformMotionEventToGlobal(ev);
+            vp.transformMatrixToLocal(m);
+            m.preTranslate(vp.mScrollX, vp.mScrollY);
         } else if (parent instanceof ViewRootImpl) {
             final ViewRootImpl vr = (ViewRootImpl) parent;
-            ev.offsetLocation(0, -vr.mCurScrollY);
+            vr.transformMatrixToLocal(m);
+            m.preTranslate(0, vr.mCurScrollY);
+        }
+
+        m.preTranslate(-mLeft, -mTop);
+
+        if (!hasIdentityMatrix()) {
+            m.preConcat(getInverseMatrix());
         }
     }
 
@@ -16184,7 +16799,8 @@
     /**
      * Returns this view's tag.
      *
-     * @return the Object stored in this view as a tag
+     * @return the Object stored in this view as a tag, or {@code null} if not
+     *         set
      *
      * @see #setTag(Object)
      * @see #getTag(int)
@@ -16214,7 +16830,8 @@
      *
      * @param key The key identifying the tag
      *
-     * @return the Object stored in this view as a tag
+     * @return the Object stored in this view as a tag, or {@code null} if not
+     *         set
      *
      * @see #setTag(int, Object)
      * @see #getTag()
@@ -17886,6 +18503,7 @@
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
     })
+    @TextAlignment
     public int getRawTextAlignment() {
         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
     }
@@ -17909,7 +18527,7 @@
      *
      * @attr ref android.R.styleable#View_textAlignment
      */
-    public void setTextAlignment(int textAlignment) {
+    public void setTextAlignment(@TextAlignment int textAlignment) {
         if (textAlignment != getRawTextAlignment()) {
             // Reset the current and resolved text alignment
             mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
@@ -17950,6 +18568,7 @@
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_START, to = "VIEW_START"),
             @ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
     })
+    @TextAlignment
     public int getTextAlignment() {
         return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >>
                 PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
@@ -18112,6 +18731,33 @@
         }
     }
 
+    /**
+     * Gets the Views in the hierarchy affected by entering and exiting Activity Scene transitions.
+     * @param transitioningViews This View will be added to transitioningViews if it is VISIBLE and
+     *                           a normal View or a ViewGroup with
+     *                           {@link android.view.ViewGroup#isTransitionGroup()} true.
+     * @hide
+     */
+    public void captureTransitioningViews(List<View> transitioningViews) {
+        if (getVisibility() == View.VISIBLE) {
+            transitioningViews.add(this);
+        }
+    }
+
+    /**
+     * Adds all Views that have {@link #getSharedElementName()} non-null to sharedElements.
+     * @param sharedElements Will contain all Views in the hierarchy having a shared element name.
+     * @hide
+     */
+    public void findSharedElements(Map<String, View> sharedElements) {
+        if (getVisibility() == VISIBLE) {
+            String sharedElementName = getSharedElementName();
+            if (sharedElementName != null) {
+                sharedElements.put(sharedElementName, this);
+            }
+        }
+    }
+
     //
     // Properties
     //
@@ -18164,6 +18810,22 @@
     };
 
     /**
+     * A Property wrapper around the <code>translationZ</code> functionality handled by the
+     * {@link View#setTranslationZ(float)} and {@link View#getTranslationZ()} methods.
+     */
+    public static final Property<View, Float> TRANSLATION_Z = new FloatProperty<View>("translationZ") {
+        @Override
+        public void setValue(View object, float value) {
+            object.setTranslationZ(value);
+        }
+
+        @Override
+        public Float get(View object) {
+            return object.getTranslationZ();
+        }
+    };
+
+    /**
      * A Property wrapper around the <code>x</code> functionality handled by the
      * {@link View#setX(float)} and {@link View#getX()} methods.
      */
@@ -18469,6 +19131,35 @@
     }
 
     /**
+     * Specifies that the shared name of the View to be shared with another Activity.
+     * When transitioning between Activities, the name links a UI element in the starting
+     * Activity to UI element in the called Activity. Names should be unique in the
+     * View hierarchy.
+     *
+     * @param sharedElementName The cross-Activity View identifier. The called Activity will use
+     *                 the name to match the location with a View in its layout.
+     * @see android.app.ActivityOptions#makeSceneTransitionAnimation(android.os.Bundle)
+     */
+    public void setSharedElementName(String sharedElementName) {
+        setTagInternal(com.android.internal.R.id.shared_element_name, sharedElementName);
+    }
+
+    /**
+     * Returns the shared name of the View to be shared with another Activity.
+     * When transitioning between Activities, the name links a UI element in the starting
+     * Activity to UI element in the called Activity. Names should be unique in the
+     * View hierarchy.
+     *
+     * <p>This returns null if the View is not a shared element or the name if it is.</p>
+     *
+     * @return The name used for this View for cross-Activity transitions or null if
+     * this View has not been identified as shared.
+     */
+    public String getSharedElementName() {
+        return (String) getTag(com.android.internal.R.id.shared_element_name);
+    }
+
+    /**
      * Interface definition for a callback to be invoked when a hardware key event is
      * dispatched to this view. The callback will be invoked before the key event is
      * given to the view. This is only useful for hardware keyboards; a software input
@@ -18668,6 +19359,31 @@
         public void onViewDetachedFromWindow(View v);
     }
 
+    /**
+     * Listener for applying window insets on a view in a custom way.
+     *
+     * <p>Apps may choose to implement this interface if they want to apply custom policy
+     * to the way that window insets are treated for a view. If an OnApplyWindowInsetsListener
+     * is set, its
+     * {@link OnApplyWindowInsetsListener#onApplyWindowInsets(View, WindowInsets) onApplyWindowInsets}
+     * method will be called instead of the View's own
+     * {@link #onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method. The listener
+     * may optionally call the parameter View's <code>onApplyWindowInsets</code> method to apply
+     * the View's normal behavior as part of its own.</p>
+     */
+    public interface OnApplyWindowInsetsListener {
+        /**
+         * When {@link View#setOnApplyWindowInsetsListener(View.OnApplyWindowInsetsListener) set}
+         * on a View, this listener method will be called instead of the view's own
+         * {@link View#onApplyWindowInsets(WindowInsets) onApplyWindowInsets} method.
+         *
+         * @param v The view applying window insets
+         * @param insets The insets to apply
+         * @return The insets supplied, minus any insets that were consumed
+         */
+        public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);
+    }
+
     private final class UnsetPressedState implements Runnable {
         public void run() {
             setPressed(false);
@@ -18762,8 +19478,6 @@
 
         final Callbacks mRootCallbacks;
 
-        HardwareCanvas mHardwareCanvas;
-
         IWindowId mIWindowId;
         WindowId mWindowId;
 
@@ -18773,7 +19487,6 @@
         View mRootView;
 
         IBinder mPanelParentWindowToken;
-        Surface mSurface;
 
         boolean mHardwareAccelerated;
         boolean mHardwareAccelerationRequested;
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index e67659c..5112b9a 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -80,7 +80,7 @@
      * is a tap or a scroll. If the user does not move within this interval, it is
      * considered to be a tap.
      */
-    private static final int TAP_TIMEOUT = 180;
+    private static final int TAP_TIMEOUT = 100;
 
     /**
      * Defines the duration in milliseconds we will wait to see if a touch event
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5763e72..aadaa7f 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -31,6 +31,7 @@
 import android.graphics.RectF;
 import android.graphics.Region;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.util.AttributeSet;
@@ -38,7 +39,6 @@
 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;
@@ -51,6 +51,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
 
@@ -355,6 +357,10 @@
      */
     private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;
 
+    static final int FLAG_IS_TRANSITION_GROUP = 0x1000000;
+
+    static final int FLAG_IS_TRANSITION_GROUP_SET = 0x2000000;
+
     /**
      * 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.
@@ -456,20 +462,21 @@
     private int mChildCountWithTransientState = 0;
 
     public ViewGroup(Context context) {
-        super(context);
-        initViewGroup();
+        this(context, null);
     }
 
     public ViewGroup(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initViewGroup();
-        initFromAttributes(context, attrs, 0);
+        this(context, attrs, 0);
     }
 
-    public ViewGroup(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initViewGroup();
-        initFromAttributes(context, attrs, defStyle);
+        initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
     }
 
     private boolean debugDraw() {
@@ -499,8 +506,10 @@
         mPersistentDrawingCache = PERSISTENT_SCROLLING_CACHE;
     }
 
-    private void initFromAttributes(Context context, AttributeSet attrs, int defStyle) {
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewGroup, defStyle, 0);
+    private void initFromAttributes(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewGroup, defStyleAttr,
+                defStyleRes);
 
         final int N = a.getIndexCount();
         for (int i = 0; i < N; i++) {
@@ -545,6 +554,9 @@
                 case R.styleable.ViewGroup_layoutMode:
                     setLayoutMode(a.getInt(attr, LAYOUT_MODE_UNDEFINED));
                     break;
+                case R.styleable.ViewGroup_transitionGroup:
+                    setTransitionGroup(a.getBoolean(attr, false));
+                    break;
             }
         }
 
@@ -597,7 +609,7 @@
     @Override
     void handleFocusGainInternal(int direction, Rect previouslyFocusedRect) {
         if (mFocused != null) {
-            mFocused.unFocus();
+            mFocused.unFocus(this);
             mFocused = null;
         }
         super.handleFocusGainInternal(direction, previouslyFocusedRect);
@@ -615,12 +627,12 @@
         }
 
         // Unfocus us, if necessary
-        super.unFocus();
+        super.unFocus(focused);
 
         // We had a previous notion of who had focus. Clear it.
         if (mFocused != child) {
             if (mFocused != null) {
-                mFocused.unFocus();
+                mFocused.unFocus(focused);
             }
 
             mFocused = child;
@@ -811,14 +823,14 @@
      * {@inheritDoc}
      */
     @Override
-    void unFocus() {
+    void unFocus(View focused) {
         if (DBG) {
             System.out.println(this + " unFocus()");
         }
         if (mFocused == null) {
-            super.unFocus();
+            super.unFocus(focused);
         } else {
-            mFocused.unFocus();
+            mFocused.unFocus(focused);
             mFocused = null;
         }
     }
@@ -2277,6 +2289,39 @@
     }
 
     /**
+     * Returns true if this ViewGroup should be considered as a single entity for removal
+     * when executing an Activity transition. If this is false, child elements will move
+     * individually during the transition.
+     * @return True if the ViewGroup should be acted on together during an Activity transition.
+     * The default value is false when the background is null and true when the background
+     * is not null or if {@link #getSharedElementName()} is not null.
+     */
+    public boolean isTransitionGroup() {
+        if ((mGroupFlags & FLAG_IS_TRANSITION_GROUP_SET) != 0) {
+            return ((mGroupFlags & FLAG_IS_TRANSITION_GROUP) != 0);
+        } else {
+            return getBackground() != null || getSharedElementName() != null;
+        }
+    }
+
+    /**
+     * Changes whether or not this ViewGroup should be treated as a single entity during
+     * ActivityTransitions.
+     * @param isTransitionGroup Whether or not the ViewGroup should be treated as a unit
+     *                          in Activity transitions. If false, the ViewGroup won't transition,
+     *                          only its children. If true, the entire ViewGroup will transition
+     *                          together.
+     */
+    public void setTransitionGroup(boolean isTransitionGroup) {
+        mGroupFlags |= FLAG_IS_TRANSITION_GROUP_SET;
+        if (isTransitionGroup) {
+            mGroupFlags |= FLAG_IS_TRANSITION_GROUP;
+        } else {
+            mGroupFlags &= ~FLAG_IS_TRANSITION_GROUP;
+        }
+    }
+
+    /**
      * {@inheritDoc}
      */
     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
@@ -2509,13 +2554,13 @@
     void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfoInternal(info);
         if (mAttachInfo != null) {
-            ArrayList<View> childrenForAccessibility = mAttachInfo.mTempArrayList;
+            final ArrayList<View> childrenForAccessibility = mAttachInfo.mTempArrayList;
             childrenForAccessibility.clear();
             addChildrenForAccessibility(childrenForAccessibility);
             final int childrenForAccessibilityCount = childrenForAccessibility.size();
             for (int i = 0; i < childrenForAccessibilityCount; i++) {
-                View child = childrenForAccessibility.get(i);
-                info.addChild(child);
+                final View child = childrenForAccessibility.get(i);
+                info.addChildUnchecked(child);
             }
             childrenForAccessibility.clear();
         }
@@ -2583,6 +2628,7 @@
         for (int i = 0; i < count; i++) {
             children[i].dispatchDetachedFromWindow();
         }
+        clearDisappearingChildren();
         super.dispatchDetachedFromWindow();
     }
 
@@ -3103,7 +3149,7 @@
     }
 
     /**
-     * Returns whether ths group's children are clipped to their bounds before drawing.
+     * Returns whether this group's children are clipped to their bounds before drawing.
      * The default value is true.
      * @see #setClipChildren(boolean)
      *
@@ -3618,7 +3664,7 @@
             childHasTransientStateChanged(child, true);
         }
 
-        if (child.isImportantForAccessibility() && child.getVisibility() != View.GONE) {
+        if (child.getVisibility() != View.GONE) {
             notifySubtreeAccessibilityStateChangedIfNeeded();
         }
     }
@@ -3826,7 +3872,7 @@
 
         boolean clearChildFocus = false;
         if (view == mFocused) {
-            view.unFocus();
+            view.unFocus(null);
             clearChildFocus = true;
         }
 
@@ -3861,7 +3907,7 @@
 
         onViewRemoved(view);
 
-        if (view.isImportantForAccessibility() && view.getVisibility() != View.GONE) {
+        if (view.getVisibility() != View.GONE) {
             notifySubtreeAccessibilityStateChangedIfNeeded();
         }
     }
@@ -3921,7 +3967,7 @@
             }
 
             if (view == focused) {
-                view.unFocus();
+                view.unFocus(null);
                 clearChildFocus = true;
             }
 
@@ -4008,7 +4054,7 @@
             }
 
             if (view == focused) {
-                view.unFocus();
+                view.unFocus(null);
                 clearChildFocus = true;
             }
 
@@ -5217,8 +5263,17 @@
      * this if you don't want animations for exiting views to stack up.
      */
     public void clearDisappearingChildren() {
-        if (mDisappearingChildren != null) {
-            mDisappearingChildren.clear();
+        final ArrayList<View> disappearingChildren = mDisappearingChildren;
+        if (disappearingChildren != null) {
+            final int count = disappearingChildren.size();
+            for (int i = 0; i < count; i++) {
+                final View view = disappearingChildren.get(i);
+                if (view.mAttachInfo != null) {
+                    view.dispatchDetachedFromWindow();
+                }
+                view.clearAnimation();
+            }
+            disappearingChildren.clear();
             invalidate();
         }
     }
@@ -5429,21 +5484,19 @@
         }
     }
 
-
     @Override
-    protected boolean fitSystemWindows(Rect insets) {
-        boolean done = super.fitSystemWindows(insets);
-        if (!done) {
-            final int count = mChildrenCount;
-            final View[] children = mChildren;
+    public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
+        insets = super.dispatchApplyWindowInsets(insets);
+        if (insets.hasInsets()) {
+            final int count = getChildCount();
             for (int i = 0; i < count; i++) {
-                done = children[i].fitSystemWindows(insets);
-                if (done) {
+                insets = getChildAt(i).dispatchApplyWindowInsets(insets);
+                if (!insets.hasInsets()) {
                     break;
                 }
             }
         }
-        return done;
+        return insets;
     }
 
     /**
@@ -5796,6 +5849,37 @@
     protected void onSetLayoutParams(View child, LayoutParams layoutParams) {
     }
 
+    /** @hide */
+    @Override
+    public void captureTransitioningViews(List<View> transitioningViews) {
+        if (getVisibility() != View.VISIBLE) {
+            return;
+        }
+        if (isTransitionGroup()) {
+            transitioningViews.add(this);
+        } else {
+            int count = getChildCount();
+            for (int i = 0; i < count; i++) {
+                View child = getChildAt(i);
+                child.captureTransitioningViews(transitioningViews);
+            }
+        }
+    }
+
+    /** @hide */
+    @Override
+    public void findSharedElements(Map<String, View> sharedElements) {
+        if (getVisibility() != VISIBLE) {
+            return;
+        }
+        super.findSharedElements(sharedElements);
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            child.findSharedElements(sharedElements);
+        }
+    }
+
     /**
      * LayoutParams are used by views to tell their parents how they want to be
      * laid out. See
diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java
index 975931a..47de780 100644
--- a/core/java/android/view/ViewOverlay.java
+++ b/core/java/android/view/ViewOverlay.java
@@ -155,6 +155,11 @@
             }
         }
 
+        @Override
+        protected boolean verifyDrawable(Drawable who) {
+            return super.verifyDrawable(who) || (mDrawables != null && mDrawables.contains(who));
+        }
+
         public void add(View child) {
             if (child.getParent() instanceof ViewGroup) {
                 ViewGroup parent = (ViewGroup) child.getParent();
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 67a94be..563ffb7 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -136,17 +136,18 @@
     private static final int NONE           = 0x0000;
     private static final int TRANSLATION_X  = 0x0001;
     private static final int TRANSLATION_Y  = 0x0002;
-    private static final int SCALE_X        = 0x0004;
-    private static final int SCALE_Y        = 0x0008;
-    private static final int ROTATION       = 0x0010;
-    private static final int ROTATION_X     = 0x0020;
-    private static final int ROTATION_Y     = 0x0040;
-    private static final int X              = 0x0080;
-    private static final int Y              = 0x0100;
-    private static final int ALPHA          = 0x0200;
+    private static final int TRANSLATION_Z  = 0x0004;
+    private static final int SCALE_X        = 0x0008;
+    private static final int SCALE_Y        = 0x0010;
+    private static final int ROTATION       = 0x0020;
+    private static final int ROTATION_X     = 0x0040;
+    private static final int ROTATION_Y     = 0x0080;
+    private static final int X              = 0x0100;
+    private static final int Y              = 0x0200;
+    private static final int ALPHA          = 0x0400;
 
-    private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | SCALE_X | SCALE_Y |
-            ROTATION | ROTATION_X | ROTATION_Y | X | Y;
+    private static final int TRANSFORM_MASK = TRANSLATION_X | TRANSLATION_Y | TRANSLATION_Z |
+            SCALE_X | SCALE_Y | ROTATION | ROTATION_X | ROTATION_Y | X | Y;
 
     /**
      * The mechanism by which the user can request several properties that are then animated
@@ -599,6 +600,31 @@
     }
 
     /**
+     * This method will cause the View's <code>translationZ</code> property to be animated to the
+     * specified value. Animations already running on the property will be canceled.
+     *
+     * @param value The value to be animated to.
+     * @see View#setTranslationZ(float)
+     * @return This object, allowing calls to methods in this class to be chained.
+     */
+    public ViewPropertyAnimator translationZ(float value) {
+        animateProperty(TRANSLATION_Z, value);
+        return this;
+    }
+
+    /**
+     * This method will cause the View's <code>translationZ</code> property to be animated by the
+     * specified value. Animations already running on the property will be canceled.
+     *
+     * @param value The amount to be animated by, as an offset from the current value.
+     * @see View#setTranslationZ(float)
+     * @return This object, allowing calls to methods in this class to be chained.
+     */
+    public ViewPropertyAnimator translationZBy(float value) {
+        animatePropertyBy(TRANSLATION_Z, value);
+        return this;
+    }
+    /**
      * This method will cause the View's <code>scaleX</code> property to be animated to the
      * specified value. Animations already running on the property will be canceled.
      *
@@ -899,7 +925,7 @@
      */
     private void setValue(int propertyConstant, float value) {
         final View.TransformationInfo info = mView.mTransformationInfo;
-        final DisplayList displayList = mView.mDisplayList;
+        final RenderNode displayList = mView.mDisplayList;
         switch (propertyConstant) {
             case TRANSLATION_X:
                 info.mTranslationX = value;
@@ -909,6 +935,10 @@
                 info.mTranslationY = value;
                 if (displayList != null) displayList.setTranslationY(value);
                 break;
+            case TRANSLATION_Z:
+                info.mTranslationZ = value;
+                if (displayList != null) displayList.setTranslationZ(value);
+                break;
             case ROTATION:
                 info.mRotation = value;
                 if (displayList != null) displayList.setRotation(value);
@@ -957,6 +987,8 @@
                 return info.mTranslationX;
             case TRANSLATION_Y:
                 return info.mTranslationY;
+            case TRANSLATION_Z:
+                return info.mTranslationZ;
             case ROTATION:
                 return info.mRotation;
             case ROTATION_X:
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index d779628..a94a671 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -28,6 +28,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
@@ -55,6 +56,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.TypedValue;
+import android.view.Surface.OutOfResourcesException;
 import android.view.View.AttachInfo;
 import android.view.View.MeasureSpec;
 import android.view.accessibility.AccessibilityEvent;
@@ -68,7 +70,6 @@
 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;
@@ -108,7 +109,6 @@
     private static final boolean DEBUG_IMF = false || LOCAL_LOGV;
     private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV;
     private static final boolean DEBUG_FPS = false;
-    private static final boolean DEBUG_INPUT_PROCESSING = false || LOCAL_LOGV;
 
     /**
      * Set this system property to true to force the view hierarchy to render
@@ -267,6 +267,10 @@
     HardwareLayer mResizeBuffer;
     long mResizeBufferStartTime;
     int mResizeBufferDuration;
+    // Used to block the creation of the ResizeBuffer due to invalidations in
+    // the previous DisplayList tree that must prevent re-execution.
+    // Currently this means a functor was detached.
+    boolean mBlockResizeBuffer;
     static final Interpolator mResizeInterpolator = new AccelerateDecelerateInterpolator();
     private ArrayList<LayoutTransition> mPendingTransitions;
 
@@ -290,8 +294,6 @@
     private long mFpsPrevTime = -1;
     private int mFpsNumFrames;
 
-    private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>();
-
     /**
      * see {@link #playSoundEffect(int)}
      */
@@ -616,7 +618,6 @@
     }
 
     void destroyHardwareResources() {
-        invalidateDisplayLists();
         if (mAttachInfo.mHardwareRenderer != null) {
             mAttachInfo.mHardwareRenderer.destroyHardwareResources(mView);
             mAttachInfo.mHardwareRenderer.destroy(false);
@@ -630,23 +631,25 @@
                 HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
             }
         } else {
-            invalidateDisplayLists();
-            if (mAttachInfo.mHardwareRenderer != null &&
-                    mAttachInfo.mHardwareRenderer.isEnabled()) {
-                mAttachInfo.mHardwareRenderer.destroyLayers(mView);
+            destroyHardwareLayer(mView);
+        }
+    }
+
+    private static void destroyHardwareLayer(View view) {
+        view.destroyLayer(true);
+
+        if (view instanceof ViewGroup) {
+            ViewGroup group = (ViewGroup) view;
+
+            int count = group.getChildCount();
+            for (int i = 0; i < count; i++) {
+                destroyHardwareLayer(group.getChildAt(i));
             }
         }
     }
 
-    void pushHardwareLayerUpdate(HardwareLayer layer) {
-        if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
-            mAttachInfo.mHardwareRenderer.pushLayerUpdate(layer);
-        }
-    }
-
     void flushHardwareLayerUpdates() {
-        if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled() &&
-                mAttachInfo.mHardwareRenderer.validate()) {
+        if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
             mAttachInfo.mHardwareRenderer.flushLayerUpdates();
         }
     }
@@ -656,15 +659,15 @@
         mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(MSG_FLUSH_LAYER_UPDATES));
     }
 
-    public boolean attachFunctor(int functor) {
+    public void attachFunctor(long functor) {
         //noinspection SimplifiableIfStatement
         if (mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled()) {
-            return mAttachInfo.mHardwareRenderer.attachFunctor(mAttachInfo, functor);
+            mAttachInfo.mHardwareRenderer.attachFunctor(mAttachInfo, functor);
         }
-        return false;
     }
 
-    public void detachFunctor(int functor) {
+    public void detachFunctor(long functor) {
+        mBlockResizeBuffer = true;
         if (mAttachInfo.mHardwareRenderer != null) {
             mAttachInfo.mHardwareRenderer.detachFunctor(functor);
         }
@@ -715,7 +718,7 @@
                 }
 
                 final boolean translucent = attrs.format != PixelFormat.OPAQUE;
-                mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
+                mAttachInfo.mHardwareRenderer = HardwareRenderer.create(translucent);
                 if (mAttachInfo.mHardwareRenderer != null) {
                     mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString());
                     mAttachInfo.mHardwareAccelerated =
@@ -930,14 +933,9 @@
     }
 
     void disposeResizeBuffer() {
-        if (mResizeBuffer != null && mAttachInfo.mHardwareRenderer != null) {
-            mAttachInfo.mHardwareRenderer.safelyRun(new Runnable() {
-                @Override
-                public void run() {
-                    mResizeBuffer.destroy();
-                    mResizeBuffer = null;
-                }
-            });
+        if (mResizeBuffer != null) {
+            mResizeBuffer.destroy();
+            mResizeBuffer = null;
         }
     }
 
@@ -1121,6 +1119,28 @@
         return windowSizeMayChange;
     }
 
+    /**
+     * Modifies the input matrix such that it maps view-local coordinates to
+     * on-screen coordinates.
+     *
+     * @param m input matrix to modify
+     */
+    void transformMatrixToGlobal(Matrix m) {
+        final View.AttachInfo attachInfo = mAttachInfo;
+        m.postTranslate(attachInfo.mWindowLeft, attachInfo.mWindowTop);
+    }
+
+    /**
+     * Modifies the input matrix such that it maps on-screen coordinates to
+     * view-local coordinates.
+     *
+     * @param m input matrix to modify
+     */
+    void transformMatrixToLocal(Matrix m) {
+        final View.AttachInfo attachInfo = mAttachInfo;
+        m.preTranslate(-attachInfo.mWindowLeft, -attachInfo.mWindowTop);
+    }
+
     private void performTraversals() {
         // cache mView since it is used so much below...
         final View host = mView;
@@ -1191,11 +1211,6 @@
                 desiredWindowHeight = packageMetrics.heightPixels;
             }
 
-            // For the very first time, tell the view hierarchy that it
-            // is attached to the window.  Note that at this point the surface
-            // object is not initialized to its backing store, but soon it
-            // will be (assuming the window is visible).
-            attachInfo.mSurface = mSurface;
             // We used to use the following condition to choose 32 bits drawing caches:
             // PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
             // However, windows are now always 32 bits by default, so choose 32 bits
@@ -1440,67 +1455,56 @@
                             !mAttachInfo.mTurnOffWindowResizeAnim &&
                             mAttachInfo.mHardwareRenderer != null &&
                             mAttachInfo.mHardwareRenderer.isEnabled() &&
-                            mAttachInfo.mHardwareRenderer.validate() &&
-                            lp != null && !PixelFormat.formatHasAlpha(lp.format)) {
+                            lp != null && !PixelFormat.formatHasAlpha(lp.format)
+                            && !mBlockResizeBuffer) {
 
                         disposeResizeBuffer();
 
-                        boolean completed = false;
-                        HardwareCanvas hwRendererCanvas = mAttachInfo.mHardwareRenderer.getCanvas();
-                        HardwareCanvas layerCanvas = null;
-                        try {
-                            if (mResizeBuffer == null) {
-                                mResizeBuffer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
-                                        mWidth, mHeight, false);
-                            } else if (mResizeBuffer.getWidth() != mWidth ||
-                                    mResizeBuffer.getHeight() != mHeight) {
-                                mResizeBuffer.resize(mWidth, mHeight);
-                            }
-                            // TODO: should handle create/resize failure
-                            layerCanvas = mResizeBuffer.start(hwRendererCanvas);
-                            final int restoreCount = layerCanvas.save();
-
-                            int yoff;
-                            final boolean scrolling = mScroller != null
-                                    && mScroller.computeScrollOffset();
-                            if (scrolling) {
-                                yoff = mScroller.getCurrY();
-                                mScroller.abortAnimation();
-                            } else {
-                                yoff = mScrollY;
-                            }
-
-                            layerCanvas.translate(0, -yoff);
-                            if (mTranslator != null) {
-                                mTranslator.translateCanvas(layerCanvas);
-                            }
-
-                            DisplayList displayList = mView.mDisplayList;
-                            if (displayList != null && displayList.isValid()) {
-                                layerCanvas.drawDisplayList(displayList, null,
-                                        DisplayList.FLAG_CLIP_CHILDREN);
-                            } else {
-                                mView.draw(layerCanvas);
-                            }
-
-                            drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
-
-                            mResizeBufferStartTime = SystemClock.uptimeMillis();
-                            mResizeBufferDuration = mView.getResources().getInteger(
-                                    com.android.internal.R.integer.config_mediumAnimTime);
-                            completed = true;
-
-                            layerCanvas.restoreToCount(restoreCount);
-                        } catch (OutOfMemoryError e) {
-                            Log.w(TAG, "Not enough memory for content change anim buffer", e);
-                        } finally {
-                            if (mResizeBuffer != null) {
-                                mResizeBuffer.end(hwRendererCanvas);
-                                if (!completed) {
-                                    disposeResizeBuffer();
-                                }
-                            }
+                        if (mResizeBuffer == null) {
+                            mResizeBuffer = mAttachInfo.mHardwareRenderer.createDisplayListLayer(
+                                    mWidth, mHeight);
                         }
+                        mResizeBuffer.prepare(mWidth, mHeight, false);
+                        RenderNode layerDisplayList = mResizeBuffer.startRecording();
+                        HardwareCanvas layerCanvas = layerDisplayList.start(mWidth, mHeight);
+                        final int restoreCount = layerCanvas.save();
+
+                        int yoff;
+                        final boolean scrolling = mScroller != null
+                                && mScroller.computeScrollOffset();
+                        if (scrolling) {
+                            yoff = mScroller.getCurrY();
+                            mScroller.abortAnimation();
+                        } else {
+                            yoff = mScrollY;
+                        }
+
+                        layerCanvas.translate(0, -yoff);
+                        if (mTranslator != null) {
+                            mTranslator.translateCanvas(layerCanvas);
+                        }
+
+                        RenderNode displayList = mView.mDisplayList;
+                        if (displayList != null && displayList.isValid()) {
+                            layerCanvas.drawDisplayList(displayList, null,
+                                    RenderNode.FLAG_CLIP_CHILDREN);
+                        } else {
+                            mView.draw(layerCanvas);
+                        }
+
+                        drawAccessibilityFocusedDrawableIfNeeded(layerCanvas);
+
+                        mResizeBufferStartTime = SystemClock.uptimeMillis();
+                        mResizeBufferDuration = mView.getResources().getInteger(
+                                com.android.internal.R.integer.config_mediumAnimTime);
+
+                        layerCanvas.restoreToCount(restoreCount);
+                        layerDisplayList.end(mAttachInfo.mHardwareRenderer, layerCanvas);
+                        layerDisplayList.setCaching(true);
+                        layerDisplayList.setLeftTopRightBottom(0, 0, mWidth, mHeight);
+                        mTempRect.set(0, 0, mWidth, mHeight);
+                        mResizeBuffer.endRecording(mTempRect);
+                        mAttachInfo.mHardwareRenderer.flushLayerUpdates();
                     }
                     mAttachInfo.mContentInsets.set(mPendingContentInsets);
                     if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: "
@@ -1544,7 +1548,7 @@
                         if (mAttachInfo.mHardwareRenderer != null) {
                             try {
                                 hwInitialized = mAttachInfo.mHardwareRenderer.initialize(
-                                        mHolder.getSurface());
+                                        mSurface);
                             } catch (OutOfResourcesException e) {
                                 handleOutOfResourcesException(e);
                                 return;
@@ -1571,7 +1575,7 @@
                         mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
                     mFullRedrawNeeded = true;
                     try {
-                        mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface());
+                        mAttachInfo.mHardwareRenderer.updateSurface(mSurface);
                     } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
@@ -1654,7 +1658,7 @@
                         mHeight != mAttachInfo.mHardwareRenderer.getHeight()) {
                     mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
                     if (!hwInitialized) {
-                        mAttachInfo.mHardwareRenderer.invalidate(mHolder.getSurface());
+                        mAttachInfo.mHardwareRenderer.invalidate(mSurface);
                         mFullRedrawNeeded = true;
                     }
                 }
@@ -2164,18 +2168,19 @@
             mResizePaint.setAlpha(mResizeAlpha);
             canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
         }
-        drawAccessibilityFocusedDrawableIfNeeded(canvas);
+        // TODO: this
+        if (!HardwareRenderer.sUseRenderThread) {
+            drawAccessibilityFocusedDrawableIfNeeded(canvas);
+        }
     }
 
     /**
      * @hide
      */
     void outputDisplayList(View view) {
-        if (mAttachInfo != null && mAttachInfo.mHardwareCanvas != null) {
-            DisplayList displayList = view.getDisplayList();
-            if (displayList != null) {
-                mAttachInfo.mHardwareCanvas.outputDisplayList(displayList);
-            }
+        RenderNode displayList = view.getDisplayList();
+        if (displayList != null) {
+            displayList.output();
         }
     }
 
@@ -2360,8 +2365,6 @@
                     appScale + ", width=" + mWidth + ", height=" + mHeight);
         }
 
-        invalidateDisplayLists();
-
         attachInfo.mTreeObserver.dispatchOnDraw();
 
         if (!dirty.isEmpty() || mIsAnimating) {
@@ -2374,6 +2377,7 @@
                 mCurrentDirty.set(dirty);
                 dirty.setEmpty();
 
+                mBlockResizeBuffer = false;
                 attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
                         animating ? null : mCurrentDirty);
             } else {
@@ -2391,7 +2395,7 @@
 
                     try {
                         attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
-                                mHolder.getSurface());
+                                mSurface);
                     } catch (OutOfResourcesException e) {
                         handleOutOfResourcesException(e);
                         return;
@@ -2526,28 +2530,35 @@
      * @param canvas The canvas on which to draw.
      */
     private void drawAccessibilityFocusedDrawableIfNeeded(Canvas canvas) {
-        AccessibilityManager manager = AccessibilityManager.getInstance(mView.mContext);
+        if (!mAttachInfo.mHasWindowFocus) {
+            return;
+        }
+
+        final AccessibilityManager manager = AccessibilityManager.getInstance(mView.mContext);
         if (!manager.isEnabled() || !manager.isTouchExplorationEnabled()) {
             return;
         }
-        if (mAccessibilityFocusedHost == null || mAccessibilityFocusedHost.mAttachInfo == null) {
+
+        final View host = mAccessibilityFocusedHost;
+        if (host == null || host.mAttachInfo == null) {
             return;
         }
-        Drawable drawable = getAccessibilityFocusedDrawable();
+
+        final Drawable drawable = getAccessibilityFocusedDrawable();
         if (drawable == null) {
             return;
         }
-        AccessibilityNodeProvider provider =
-            mAccessibilityFocusedHost.getAccessibilityNodeProvider();
-        Rect bounds = mView.mAttachInfo.mTmpInvalRect;
+
+        final AccessibilityNodeProvider provider = host.getAccessibilityNodeProvider();
+        final Rect bounds = mView.mAttachInfo.mTmpInvalRect;
         if (provider == null) {
-            mAccessibilityFocusedHost.getBoundsOnScreen(bounds);
-        } else {
-            if (mAccessibilityFocusedVirtualView == null) {
-                return;
-            }
+            host.getBoundsOnScreen(bounds);
+        } else if (mAccessibilityFocusedVirtualView != null) {
             mAccessibilityFocusedVirtualView.getBoundsInScreen(bounds);
+        } else {
+            return;
         }
+
         bounds.offset(-mAttachInfo.mWindowLeft, -mAttachInfo.mWindowTop);
         bounds.intersect(0, 0, mAttachInfo.mViewRootImpl.mWidth, mAttachInfo.mViewRootImpl.mHeight);
         drawable.setBounds(bounds);
@@ -2563,7 +2574,7 @@
                         R.attr.accessibilityFocusedDrawable, value, true);
                 if (resolved) {
                     mAttachInfo.mAccessibilityFocusDrawable =
-                        mView.mContext.getResources().getDrawable(value.resourceId);
+                        mView.mContext.getDrawable(value.resourceId);
                 }
             }
             return mAttachInfo.mAccessibilityFocusDrawable;
@@ -2571,20 +2582,6 @@
         return null;
     }
 
-    void invalidateDisplayLists() {
-        final ArrayList<DisplayList> displayLists = mDisplayLists;
-        final int count = displayLists.size();
-
-        for (int i = 0; i < count; i++) {
-            final DisplayList displayList = displayLists.get(i);
-            if (displayList.isDirty()) {
-                displayList.reset();
-            }
-        }
-
-        displayLists.clear();
-    }
-
     /**
      * @hide
      */
@@ -2826,10 +2823,6 @@
 
     void dispatchDetachedFromWindow() {
         if (mView != null && mView.mAttachInfo != null) {
-            if (mAttachInfo.mHardwareRenderer != null &&
-                    mAttachInfo.mHardwareRenderer.isEnabled()) {
-                mAttachInfo.mHardwareRenderer.validate();
-            }
             mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(false);
             mView.dispatchDetachedFromWindow();
         }
@@ -2846,7 +2839,6 @@
         mView.assignParent(null);
         mView = null;
         mAttachInfo.mRootView = null;
-        mAttachInfo.mSurface = null;
 
         mSurface.release();
 
@@ -3103,7 +3095,7 @@
                             mFullRedrawNeeded = true;
                             try {
                                 mAttachInfo.mHardwareRenderer.initializeIfNeeded(
-                                        mWidth, mHeight, mHolder.getSurface());
+                                        mWidth, mHeight, mSurface);
                             } catch (OutOfResourcesException e) {
                                 Log.e(TAG, "OutOfResourcesException locking surface", e);
                                 try {
@@ -3152,8 +3144,6 @@
                         mHasHadWindowFocus = true;
                     }
 
-                    setAccessibilityFocus(null, null);
-
                     if (mView != null && mAccessibilityManager.isEnabled()) {
                         if (hasWindowFocus) {
                             mView.sendAccessibilityEvent(
@@ -3301,7 +3291,7 @@
                 } else {
                     // There's nothing to focus. Clear and propagate through the
                     // hierarchy, but don't attempt to place new focus.
-                    focused.clearFocusInternal(true, false);
+                    focused.clearFocusInternal(null, true, false);
                     return true;
                 }
             }
@@ -4493,8 +4483,7 @@
         // The active pointer id, or -1 if none.
         private int mActivePointerId = -1;
 
-        // Time and location where tracking started.
-        private long mStartTime;
+        // Location where tracking started.
         private float mStartX;
         private float mStartY;
 
@@ -4522,9 +4511,6 @@
         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);
         }
@@ -4591,7 +4577,6 @@
                     mActivePointerId = event.getPointerId(0);
                     mVelocityTracker = VelocityTracker.obtain();
                     mVelocityTracker.addMovement(event);
-                    mStartTime = time;
                     mStartX = event.getX();
                     mStartY = event.getY();
                     mLastX = mStartX;
@@ -5221,10 +5206,10 @@
     }
 
     private static void getGfxInfo(View view, int[] info) {
-        DisplayList displayList = view.mDisplayList;
+        RenderNode displayList = view.mDisplayList;
         info[0]++;
         if (displayList != null) {
-            info[1] += displayList.getSize();
+            info[1] += 0; /* TODO: Memory used by display lists */
         }
 
         if (view instanceof ViewGroup) {
@@ -5272,7 +5257,6 @@
             }
 
             if (mAdded && !mFirst) {
-                invalidateDisplayLists();
                 destroyHardwareRenderer();
 
                 if (mView != null) {
@@ -5318,7 +5302,7 @@
 
                 // Hardware rendering
                 if (mAttachInfo.mHardwareRenderer != null) {
-                    if (mAttachInfo.mHardwareRenderer.loadSystemProperties(mHolder.getSurface())) {
+                    if (mAttachInfo.mHardwareRenderer.loadSystemProperties()) {
                         invalidate();
                     }
                 }
@@ -5521,24 +5505,23 @@
     }
 
     private void deliverInputEvent(QueuedInputEvent q) {
-        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "deliverInputEvent");
-        try {
-            if (mInputEventConsistencyVerifier != null) {
-                mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
-            }
+        Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "deliverInputEvent",
+                q.mEvent.getSequenceNumber());
+        if (mInputEventConsistencyVerifier != null) {
+            mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);
+        }
 
-            InputStage stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
-            if (stage != null) {
-                stage.deliver(q);
-            } else {
-                finishInputEvent(q);
-            }
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+        InputStage stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
+        if (stage != null) {
+            stage.deliver(q);
+        } else {
+            finishInputEvent(q);
         }
     }
 
     private void finishInputEvent(QueuedInputEvent q) {
+        Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, "deliverInputEvent",
+                q.mEvent.getSequenceNumber());
         if (q.mReceiver != null) {
             boolean handled = (q.mFlags & QueuedInputEvent.FLAG_FINISHED_HANDLED) != 0;
             q.mReceiver.finishInputEvent(q.mEvent, handled);
@@ -5739,10 +5722,6 @@
         mInvalidateOnAnimationRunnable.addViewRect(info);
     }
 
-    public void enqueueDisplayList(DisplayList displayList) {
-        mDisplayLists.add(displayList);
-    }
-
     public void cancelInvalidate(View view) {
         mHandler.removeMessages(MSG_INVALIDATE, view);
         // fixme: might leak the AttachInfo.InvalidateInfo objects instead of returning
@@ -5765,6 +5744,9 @@
 
     public void dispatchUnhandledKey(KeyEvent event) {
         if ((event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
+            // Some fallback keys are decided by the ViewRoot as they might have special
+            // properties (e.g. are locale aware). These take precedence over fallbacks defined by
+            // the kcm.
             final KeyCharacterMap kcm = event.getKeyCharacterMap();
             final int keyCode = event.getKeyCode();
             final int metaState = event.getMetaState();
@@ -5781,7 +5763,6 @@
                         event.getDeviceId(), event.getScanCode(),
                         flags, event.getSource(), null);
                 fallbackAction.recycle();
-
                 dispatchInputEvent(fallbackEvent);
             }
         }
@@ -6265,68 +6246,6 @@
         }
     }
 
-    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;
-        }
-    };
-
     static RunQueue getRunQueue() {
         RunQueue rq = sRunQueues.get();
         if (rq != null) {
@@ -6436,7 +6355,7 @@
         public void ensureConnection() {
             if (mAttachInfo != null) {
                 final boolean registered =
-                    mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED;
+                    mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
                 if (!registered) {
                     mAttachInfo.mAccessibilityWindowId =
                         mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
@@ -6447,9 +6366,9 @@
 
         public void ensureNoConnection() {
             final boolean registered =
-                mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED;
+                mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
             if (registered) {
-                mAttachInfo.mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED;
+                mAttachInfo.mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
                 mAccessibilityManager.removeAccessibilityInteractionConnection(mWindow);
             }
         }
diff --git a/core/java/android/view/ViewStub.java b/core/java/android/view/ViewStub.java
index a5dc3ae..d68a860 100644
--- a/core/java/android/view/ViewStub.java
+++ b/core/java/android/view/ViewStub.java
@@ -97,16 +97,21 @@
     }
 
     @SuppressWarnings({"UnusedDeclaration"})
-    public ViewStub(Context context, AttributeSet attrs, int defStyle) {
-        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ViewStub,
-                defStyle, 0);
+    public ViewStub(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ViewStub, defStyleAttr, defStyleRes);
 
         mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
         mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
 
         a.recycle();
 
-        a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.View, defStyle, 0);
+        a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
         mID = a.getResourceId(R.styleable.View_id, NO_ID);
         a.recycle();
 
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 52f9c0b..b05225b 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -787,7 +787,7 @@
             return;
         }
 
-        mVibrator.vibrate(VIBRATE_DURATION);
+        mVibrator.vibrate(VIBRATE_DURATION, AudioManager.STREAM_SYSTEM);
     }
 
     protected void onRemoteVolumeChanged(int streamType, int flags) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index c450f3c..0cd6325 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -16,6 +16,9 @@
 
 package android.view;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityOptions;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
@@ -25,8 +28,13 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.SystemProperties;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionManager;
 import android.view.accessibility.AccessibilityEvent;
 
+import java.util.Map;
+
 /**
  * Abstract base class for a top-level window look and behavior policy.  An
  * instance of this class should be used as the top-level view added to the
@@ -89,17 +97,25 @@
      * If overlay is enabled, the action mode UI will be allowed to cover existing window content.
      */
     public static final int FEATURE_ACTION_MODE_OVERLAY = 10;
-
     /**
      * Flag for requesting a decoration-free window that is dismissed by swiping from the left.
      */
     public static final int FEATURE_SWIPE_TO_DISMISS = 11;
+    /**
+     * Flag for requesting that window content changes should be represented
+     * with scenes and transitions.
+     *
+     * TODO Add docs
+     *
+     * @see #setContentView
+     */
+    public static final int FEATURE_CONTENT_TRANSITIONS = 12;
 
     /**
      * Max value used as a feature ID
      * @hide
      */
-    public static final int FEATURE_MAX = FEATURE_SWIPE_TO_DISMISS;
+    public static final int FEATURE_MAX = FEATURE_CONTENT_TRANSITIONS;
 
     /** Flag for setting the progress bar's visibility to VISIBLE */
     public static final int PROGRESS_VISIBILITY_ON = -1;
@@ -245,6 +261,7 @@
          *
          * @see #onPreparePanel
          */
+        @Nullable
         public View onCreatePanelView(int featureId);
 
         /**
@@ -373,6 +390,7 @@
          * @param callback Callback to control the lifecycle of this action mode
          * @return The ActionMode that was started, or null if the system should present it
          */
+        @Nullable
         public ActionMode onWindowStartingActionMode(ActionMode.Callback callback);
 
         /**
@@ -980,6 +998,7 @@
      *
      * @return View The current View with focus or null.
      */
+    @Nullable
     public abstract View getCurrentFocus();
 
     /**
@@ -988,10 +1007,12 @@
      *
      * @return LayoutInflater The shared LayoutInflater.
      */
+    @NonNull
     public abstract LayoutInflater getLayoutInflater();
 
     public abstract void setTitle(CharSequence title);
 
+    @Deprecated
     public abstract void setTitleColor(int textColor);
 
     public abstract void openPanel(int featureId, KeyEvent event);
@@ -1032,7 +1053,7 @@
      */
     public void setBackgroundDrawableResource(int resid)
     {
-        setBackgroundDrawable(mContext.getResources().getDrawable(resid));
+        setBackgroundDrawable(mContext.getDrawable(resid));
     }
 
     /**
@@ -1328,4 +1349,93 @@
      * @param event A key or touch event to inject to this window.
      */
     public void injectInputEvent(InputEvent event) { }
+
+    /**
+     * Retrieve the {@link TransitionManager} responsible for  for default transitions
+     * in this window. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return non-null after content has been initialized (e.g. by using
+     * {@link #setContentView}) if {@link #FEATURE_CONTENT_TRANSITIONS} has been granted.</p>
+     *
+     * @return This window's content TransitionManager or null if none is set.
+     */
+    public TransitionManager getTransitionManager() {
+        return null;
+    }
+
+    /**
+     * Set the {@link TransitionManager} to use for default transitions in this window.
+     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * @param tm The TransitionManager to use for scene changes.
+     */
+    public void setTransitionManager(TransitionManager tm) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Retrieve the {@link Scene} representing this window's current content.
+     * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+     *
+     * <p>This method will return null if the current content is not represented by a Scene.</p>
+     *
+     * @return Current Scene being shown or null
+     */
+    public Scene getContentScene() {
+        return null;
+    }
+
+    /**
+     * Set options that can affect the transition behavior within this window.
+     * @param options Options to set or null for none
+     * @hide
+     */
+    public void setTransitionOptions(ActivityOptions options, SceneTransitionListener listener) {
+    }
+
+    /**
+     * A callback for Activity transitions to be told when the shared element is ready to be shown
+     * and start the transition to its target location.
+     * @hide
+     */
+    public interface SceneTransitionListener {
+        void nullPendingTransition();
+        void convertFromTranslucent();
+        void convertToTranslucent();
+        void sharedElementStart(Transition transition);
+        void sharedElementEnd();
+    }
+
+    /**
+     * Controls when the Activity enter scene is triggered and the background is faded in. If
+     * triggerEarly is true, the enter scene will begin as soon as possible and the background
+     * will fade in when all shared elements are ready to begin transitioning. If triggerEarly is
+     * false, the Activity enter scene and background fade will be triggered when the calling
+     * Activity's exit transition completes.
+     *
+     * @param triggerEarly Set to true to have the Activity enter scene transition in as early as
+     *                     possible or set to false to wait for the calling Activity to exit first.
+     */
+    public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
+    }
+
+    /**
+     * Start the exit transition.
+     * @hide
+     */
+    public Bundle startExitTransition(ActivityOptions options) {
+        return null;
+    }
+
+    /**
+     * On entering Activity Scene transitions, shared element names may be mapped from a
+     * source Activity's specified name to a unique shared element name in the View hierarchy.
+     * Under most circumstances, mapping is not necessary - a single View will have the
+     * shared element name given by the calling Activity. However, if there are several similar
+     * Views (e.g. in a ListView), the correct shared element must be mapped.
+     * @param sharedElementNames A mapping from the calling Activity's assigned shared element
+     *                           name to a unique shared element name in the View hierarchy.
+     */
+    public void mapTransitionTargets(Map<String, String> sharedElementNames) {
+    }
 }
diff --git a/core/java/android/view/WindowInfo.aidl b/core/java/android/view/WindowInfo.aidl
new file mode 100644
index 0000000..75b8fd2
--- /dev/null
+++ b/core/java/android/view/WindowInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+parcelable WindowInfo;
diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java
new file mode 100644
index 0000000..7f89044
--- /dev/null
+++ b/core/java/android/view/WindowInfo.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.graphics.Rect;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Pools;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class represents information about a window from the
+ * window manager to another part of the system.
+ *
+ * @hide
+ */
+public class WindowInfo implements Parcelable {
+    private static final int MAX_POOL_SIZE = 10;
+
+    private static final Pools.SynchronizedPool<WindowInfo> sPool =
+            new Pools.SynchronizedPool<WindowInfo>(MAX_POOL_SIZE);
+
+    public int type;
+    public int layer;
+    public IBinder token;
+    public IBinder parentToken;
+    public boolean focused;
+    public final Rect boundsInScreen = new Rect();
+    public List<IBinder> childTokens;
+
+    private WindowInfo() {
+        /* do nothing - hide constructor */
+    }
+
+    public static WindowInfo obtain() {
+        WindowInfo window = sPool.acquire();
+        if (window == null) {
+            window = new WindowInfo();
+        }
+        return window;
+    }
+
+    public static WindowInfo obtain(WindowInfo other) {
+        WindowInfo window = obtain();
+        window.type = other.type;
+        window.layer = other.layer;
+        window.token = other.token;
+        window.parentToken = other.parentToken;
+        window.focused = other.focused;
+        window.boundsInScreen.set(other.boundsInScreen);
+
+        if (other.childTokens != null && !other.childTokens.isEmpty()) {
+            if (window.childTokens == null) {
+                window.childTokens = new ArrayList<IBinder>(other.childTokens);
+            } else {
+                window.childTokens.addAll(other.childTokens);
+            }
+        }
+
+        return window;
+    }
+
+    public void recycle() {
+        clear();
+        sPool.release(this);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(type);
+        parcel.writeInt(layer);
+        parcel.writeStrongBinder(token);
+        parcel.writeStrongBinder(parentToken);
+        parcel.writeInt(focused ? 1 : 0);
+        boundsInScreen.writeToParcel(parcel, flags);
+
+        if (childTokens != null && !childTokens.isEmpty()) {
+            parcel.writeInt(1);
+            parcel.writeBinderList(childTokens);
+        } else {
+            parcel.writeInt(0);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("WindowInfo[");
+        builder.append("type=").append(type);
+        builder.append(", layer=").append(layer);
+        builder.append(", token=").append(token);
+        builder.append(", parent=").append(parentToken);
+        builder.append(", focused=").append(focused);
+        builder.append(", children=").append(childTokens);
+        builder.append(']');
+        return builder.toString();
+    }
+
+    private void initFromParcel(Parcel parcel) {
+        type = parcel.readInt();
+        layer = parcel.readInt();
+        token = parcel.readStrongBinder();
+        parentToken = parcel.readStrongBinder();
+        focused = (parcel.readInt() == 1);
+        boundsInScreen.readFromParcel(parcel);
+
+        final boolean hasChildren = (parcel.readInt() == 1);
+        if (hasChildren) {
+            if (childTokens == null) {
+                childTokens = new ArrayList<IBinder>();
+            }
+            parcel.readBinderList(childTokens);
+        }
+    }
+
+    private void clear() {
+        type = 0;
+        layer = 0;
+        token = null;
+        parentToken = null;
+        focused = false;
+        boundsInScreen.setEmpty();
+        if (childTokens != null) {
+            childTokens.clear();
+        }
+    }
+
+    public static final Parcelable.Creator<WindowInfo> CREATOR =
+            new Creator<WindowInfo>() {
+        @Override
+        public WindowInfo createFromParcel(Parcel parcel) {
+            WindowInfo window = obtain();
+            window.initFromParcel(parcel);
+            return window;
+        }
+
+        @Override
+        public WindowInfo[] newArray(int size) {
+            return new WindowInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
new file mode 100644
index 0000000..cdfcb43
--- /dev/null
+++ b/core/java/android/view/WindowInsets.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.view;
+
+import android.graphics.Rect;
+
+/**
+ * Describes a set of insets for window content.
+ *
+ * <p>WindowInsets are immutable and may be expanded to include more inset types in the future.
+ * To adjust insets, use one of the supplied clone methods to obtain a new WindowInsets instance
+ * with the adjusted properties.</p>
+ *
+ * @see View.OnApplyWindowInsetsListener
+ * @see View#onApplyWindowInsets(WindowInsets)
+ */
+public class WindowInsets {
+    private Rect mSystemWindowInsets;
+    private Rect mWindowDecorInsets;
+    private Rect mTempRect;
+
+    private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
+
+    /**
+     * Since new insets may be added in the future that existing apps couldn't
+     * know about, this fully empty constant shouldn't be made available to apps
+     * since it would allow them to inadvertently consume unknown insets by returning it.
+     * @hide
+     */
+    public static final WindowInsets EMPTY = new WindowInsets(EMPTY_RECT, EMPTY_RECT);
+
+    /** @hide */
+    public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets) {
+        mSystemWindowInsets = systemWindowInsets;
+        mWindowDecorInsets = windowDecorInsets;
+    }
+
+    /**
+     * Construct a new WindowInsets, copying all values from a source WindowInsets.
+     *
+     * @param src Source to copy insets from
+     */
+    public WindowInsets(WindowInsets src) {
+        mSystemWindowInsets = src.mSystemWindowInsets;
+        mWindowDecorInsets = src.mWindowDecorInsets;
+    }
+
+    /** @hide */
+    public WindowInsets(Rect systemWindowInsets) {
+        mSystemWindowInsets = systemWindowInsets;
+        mWindowDecorInsets = EMPTY_RECT;
+    }
+
+    /**
+     * Used to provide a safe copy of the system window insets to pass through
+     * to the existing fitSystemWindows method and other similar internals.
+     * @hide
+     */
+    public Rect getSystemWindowInsets() {
+        if (mTempRect == null) {
+            mTempRect = new Rect();
+        }
+        mTempRect.set(mSystemWindowInsets);
+        return mTempRect;
+    }
+
+    /**
+     * Returns the left system window inset in pixels.
+     *
+     * <p>The system window inset represents the area of a full-screen window that is
+     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
+     * </p>
+     *
+     * @return The left system window inset
+     */
+    public int getSystemWindowInsetLeft() {
+        return mSystemWindowInsets.left;
+    }
+
+    /**
+     * Returns the top system window inset in pixels.
+     *
+     * <p>The system window inset represents the area of a full-screen window that is
+     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
+     * </p>
+     *
+     * @return The top system window inset
+     */
+    public int getSystemWindowInsetTop() {
+        return mSystemWindowInsets.top;
+    }
+
+    /**
+     * Returns the right system window inset in pixels.
+     *
+     * <p>The system window inset represents the area of a full-screen window that is
+     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
+     * </p>
+     *
+     * @return The right system window inset
+     */
+    public int getSystemWindowInsetRight() {
+        return mSystemWindowInsets.right;
+    }
+
+    /**
+     * Returns the bottom system window inset in pixels.
+     *
+     * <p>The system window inset represents the area of a full-screen window that is
+     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
+     * </p>
+     *
+     * @return The bottom system window inset
+     */
+    public int getSystemWindowInsetBottom() {
+        return mSystemWindowInsets.bottom;
+    }
+
+    /**
+     * Returns the left window decor inset in pixels.
+     *
+     * <p>The window decor inset represents the area of the window content area that is
+     * partially or fully obscured by decorations within the window provided by the framework.
+     * This can include action bars, title bars, toolbars, etc.</p>
+     *
+     * @return The left window decor inset
+     */
+    public int getWindowDecorInsetLeft() {
+        return mWindowDecorInsets.left;
+    }
+
+    /**
+     * Returns the top window decor inset in pixels.
+     *
+     * <p>The window decor inset represents the area of the window content area that is
+     * partially or fully obscured by decorations within the window provided by the framework.
+     * This can include action bars, title bars, toolbars, etc.</p>
+     *
+     * @return The top window decor inset
+     */
+    public int getWindowDecorInsetTop() {
+        return mWindowDecorInsets.top;
+    }
+
+    /**
+     * Returns the right window decor inset in pixels.
+     *
+     * <p>The window decor inset represents the area of the window content area that is
+     * partially or fully obscured by decorations within the window provided by the framework.
+     * This can include action bars, title bars, toolbars, etc.</p>
+     *
+     * @return The right window decor inset
+     */
+    public int getWindowDecorInsetRight() {
+        return mWindowDecorInsets.right;
+    }
+
+    /**
+     * Returns the bottom window decor inset in pixels.
+     *
+     * <p>The window decor inset represents the area of the window content area that is
+     * partially or fully obscured by decorations within the window provided by the framework.
+     * This can include action bars, title bars, toolbars, etc.</p>
+     *
+     * @return The bottom window decor inset
+     */
+    public int getWindowDecorInsetBottom() {
+        return mWindowDecorInsets.bottom;
+    }
+
+    /**
+     * Returns true if this WindowInsets has nonzero system window insets.
+     *
+     * <p>The system window inset represents the area of a full-screen window that is
+     * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
+     * </p>
+     *
+     * @return true if any of the system window inset values are nonzero
+     */
+    public boolean hasSystemWindowInsets() {
+        return mSystemWindowInsets.left != 0 || mSystemWindowInsets.top != 0 ||
+                mSystemWindowInsets.right != 0 || mSystemWindowInsets.bottom != 0;
+    }
+
+    /**
+     * Returns true if this WindowInsets has nonzero window decor insets.
+     *
+     * <p>The window decor inset represents the area of the window content area that is
+     * partially or fully obscured by decorations within the window provided by the framework.
+     * This can include action bars, title bars, toolbars, etc.</p>
+     *
+     * @return true if any of the window decor inset values are nonzero
+     */
+    public boolean hasWindowDecorInsets() {
+        return mWindowDecorInsets.left != 0 || mWindowDecorInsets.top != 0 ||
+                mWindowDecorInsets.right != 0 || mWindowDecorInsets.bottom != 0;
+    }
+
+    /**
+     * Returns true if this WindowInsets has any nonzero insets.
+     *
+     * @return true if any inset values are nonzero
+     */
+    public boolean hasInsets() {
+        return hasSystemWindowInsets() || hasWindowDecorInsets();
+    }
+
+    public WindowInsets cloneWithSystemWindowInsetsConsumed() {
+        final WindowInsets result = new WindowInsets(this);
+        result.mSystemWindowInsets = new Rect(0, 0, 0, 0);
+        return result;
+    }
+
+    public WindowInsets cloneWithSystemWindowInsetsConsumed(boolean left, boolean top,
+            boolean right, boolean bottom) {
+        if (left || top || right || bottom) {
+            final WindowInsets result = new WindowInsets(this);
+            result.mSystemWindowInsets = new Rect(left ? 0 : mSystemWindowInsets.left,
+                    top ? 0 : mSystemWindowInsets.top,
+                    right ? 0 : mSystemWindowInsets.right,
+                    bottom ? 0 : mSystemWindowInsets.bottom);
+            return result;
+        }
+        return this;
+    }
+
+    public WindowInsets cloneWithSystemWindowInsets(int left, int top, int right, int bottom) {
+        final WindowInsets result = new WindowInsets(this);
+        result.mSystemWindowInsets = new Rect(left, top, right, bottom);
+        return result;
+    }
+
+    public WindowInsets cloneWithWindowDecorInsetsConsumed() {
+        final WindowInsets result = new WindowInsets(this);
+        result.mWindowDecorInsets.set(0, 0, 0, 0);
+        return result;
+    }
+
+    public WindowInsets cloneWithWindowDecorInsetsConsumed(boolean left, boolean top,
+            boolean right, boolean bottom) {
+        if (left || top || right || bottom) {
+            final WindowInsets result = new WindowInsets(this);
+            result.mWindowDecorInsets = new Rect(left ? 0 : mWindowDecorInsets.left,
+                    top ? 0 : mWindowDecorInsets.top,
+                    right ? 0 : mWindowDecorInsets.right,
+                    bottom ? 0 : mWindowDecorInsets.bottom);
+            return result;
+        }
+        return this;
+    }
+
+    public WindowInsets cloneWithWindowDecorInsets(int left, int top, int right, int bottom) {
+        final WindowInsets result = new WindowInsets(this);
+        result.mWindowDecorInsets = new Rect(left, top, right, bottom);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "WindowInsets{systemWindowInsets=" + mSystemWindowInsets + " windowDecorInsets=" +
+                mWindowDecorInsets + "}";
+    }
+}
diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java
index a1bd4bd..14dc356 100644
--- a/core/java/android/view/WindowManagerInternal.java
+++ b/core/java/android/view/WindowManagerInternal.java
@@ -16,7 +16,12 @@
 
 package android.view;
 
+import android.graphics.Rect;
+import android.graphics.Region;
 import android.hardware.display.DisplayManagerInternal;
+import android.os.IBinder;
+
+import java.util.List;
 
 /**
  * Window manager local system service interface.
@@ -24,10 +29,136 @@
  * @hide Only for use within the system server.
  */
 public abstract class WindowManagerInternal {
+
+    /**
+     * Interface to receive a callback when the windows reported for
+     * accessibility changed.
+     */
+    public interface WindowsForAccessibilityCallback {
+
+        /**
+         * Called when the windows for accessibility changed.
+         *
+         * @param windows The windows for accessibility.
+         */
+        public void onWindowsForAccessibilityChanged(List<WindowInfo> windows);
+    }
+
+    /**
+     * Callbacks for contextual changes that affect the screen magnification
+     * feature.
+     */
+    public interface MagnificationCallbacks {
+
+        /**
+         * Called when the bounds of the screen content that is magnified changed.
+         * Note that not the entire screen is magnified.
+         *
+         * @param bounds The bounds.
+         */
+        public void onMagnifedBoundsChanged(Region bounds);
+
+        /**
+         * Called when an application requests a rectangle on the screen to allow
+         * the client to apply the appropriate pan and scale.
+         *
+         * @param left The rectangle left.
+         * @param top The rectangle top.
+         * @param right The rectangle right.
+         * @param bottom The rectangle bottom.
+         */
+        public void onRectangleOnScreenRequested(int left, int top, int right, int bottom);
+
+        /**
+         * Notifies that the rotation changed.
+         *
+         * @param rotation The current rotation.
+         */
+        public void onRotationChanged(int rotation);
+
+        /**
+         * Notifies that the context of the user changed. For example, an application
+         * was started.
+         */
+        public void onUserContextChanged();
+    }
+
     /**
      * Request that the window manager call
      * {@link DisplayManagerInternal#performTraversalInTransactionFromWindowManager}
      * within a surface transaction at a later time.
      */
     public abstract void requestTraversalFromDisplayManager();
-}
\ No newline at end of file
+
+    /**
+     * Set by the accessibility layer to observe changes in the magnified region,
+     * rotation, and other window transformations related to display magnification
+     * as the window manager is responsible for doing the actual magnification
+     * and has access to the raw window data while the accessibility layer serves
+     * as a controller.
+     *
+     * @param callbacks The callbacks to invoke.
+     */
+    public abstract void setMagnificationCallbacks(MagnificationCallbacks callbacks);
+
+    /**
+     * Set by the accessibility layer to specify the magnification and panning to
+     * be applied to all windows that should be magnified.
+     *
+     * @param callbacks The callbacks to invoke.
+     *
+     * @see #setMagnificationCallbacks(MagnificationCallbacks)
+     */
+    public abstract void setMagnificationSpec(MagnificationSpec spec);
+
+    /**
+     * Gets the magnification and translation applied to a window given its token.
+     * Not all windows are magnified and the window manager policy determines which
+     * windows are magnified. The returned result also takes into account the compat
+     * scale if necessary.
+     *
+     * @param windowToken The window's token.
+     *
+     * @return The magnification spec for the window.
+     *
+     * @see #setMagnificationCallbacks(MagnificationCallbacks)
+     */
+    public abstract MagnificationSpec getCompatibleMagnificationSpecForWindow(
+            IBinder windowToken);
+
+    /**
+     * Sets a callback for observing which windows are touchable for the purposes
+     * of accessibility.
+     *
+     * @param callback The callback.
+     */
+    public abstract void setWindowsForAccessibilityCallback(
+            WindowsForAccessibilityCallback callback);
+
+    /**
+     * Sets a filter for manipulating the input event stream.
+     *
+     * @param filter The filter implementation.
+     */
+    public abstract void setInputFilter(IInputFilter filter);
+
+    /**
+     * Gets the token of the window that has input focus.
+     *
+     * @return The token.
+     */
+    public abstract IBinder getFocusedWindowToken();
+
+    /**
+     * @return Whether the keyguard is engaged.
+     */
+    public abstract boolean isKeyguardLocked();
+
+    /**
+     * Gets the frame of a window given its token.
+     *
+     * @param token The token.
+     * @param outBounds The frame to populate.
+     */
+    public abstract void getWindowFrame(IBinder token, Rect outBounds);
+}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 74dda77..bd203c8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -16,7 +16,9 @@
 
 package android.view;
 
+import android.annotation.IntDef;
 import android.content.Context;
+import android.content.pm.ActivityInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -27,6 +29,8 @@
 import android.view.animation.Animation;
 
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
  * This interface supplies all UI-specific behavior of the window manager.  An
@@ -450,6 +454,11 @@
     /** Screen turned off because of proximity sensor */
     public final int OFF_BECAUSE_OF_PROX_SENSOR = 4;
 
+    /** @hide */
+    @IntDef({USER_ROTATION_FREE, USER_ROTATION_LOCKED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UserRotationMode {}
+
     /** When not otherwise specified by the activity's screenOrientation, rotation should be
      * determined by the system (that is, using sensors). */
     public final int USER_ROTATION_FREE = 0;
@@ -1006,7 +1015,8 @@
      * @param lastRotation The most recently used rotation.
      * @return The surface rotation to use.
      */
-    public int rotationForOrientationLw(int orientation, int lastRotation);
+    public int rotationForOrientationLw(@ActivityInfo.ScreenOrientation int orientation,
+            int lastRotation);
 
     /**
      * Given an orientation constant and a rotation, returns true if the rotation
@@ -1021,7 +1031,8 @@
      * @param rotation The rotation to check.
      * @return True if the rotation is compatible with the requested orientation.
      */
-    public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation);
+    public boolean rotationHasCompatibleMetricsLw(@ActivityInfo.ScreenOrientation int orientation,
+            int rotation);
 
     /**
      * Called by the window manager when the rotation changes.
@@ -1070,7 +1081,7 @@
      */
     public void enableScreenAfterBoot();
     
-    public void setCurrentOrientationLw(int newOrientation);
+    public void setCurrentOrientationLw(@ActivityInfo.ScreenOrientation int newOrientation);
     
     /**
      * Call from application to perform haptic feedback on its window.
@@ -1097,6 +1108,7 @@
      * @see WindowManagerPolicy#USER_ROTATION_LOCKED
      * @see WindowManagerPolicy#USER_ROTATION_FREE 
      */
+    @UserRotationMode
     public int getUserRotationMode();
 
     /**
@@ -1107,12 +1119,12 @@
      * @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
      *                 {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
      */
-    public void setUserRotationMode(int mode, int rotation);
+    public void setUserRotationMode(@UserRotationMode int mode, @Surface.Rotation int rotation);
 
     /**
      * Called when a new system UI visibility is being reported, allowing
      * the policy to adjust what is actually reported.
-     * @param visibility The raw visiblity reported by the status bar.
+     * @param visibility The raw visibility reported by the status bar.
      * @return The new desired visibility.
      */
     public int adjustSystemUiVisibilityLw(int visibility);
@@ -1135,6 +1147,11 @@
     public void setLastInputMethodWindowLw(WindowState ime, WindowState target);
 
     /**
+     * @return The current height of the input method window.
+     */
+    public int getInputMethodWindowVisibleHeightLw();
+
+    /**
      * Called when the current user changes. Guaranteed to be called before the broadcast
      * of the new user id is made to all listeners.
      *
@@ -1170,11 +1187,4 @@
      * @return True if the window is a top level one.
      */
     public boolean isTopLevelWindow(int windowType);
-
-    /**
-     * Sets the current touch exploration state.
-     *
-     * @param enabled Whether touch exploration is enabled.
-     */
-    public void setTouchExplorationEnabled(boolean enabled);
 }
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
new file mode 100644
index 0000000..77d48e2
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import android.os.Build;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.LongArray;
+import android.util.LongSparseArray;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Cache for AccessibilityWindowInfos and AccessibilityNodeInfos.
+ * It is updated when windows change or nodes change.
+ */
+final class AccessibilityCache {
+
+    private static final String LOG_TAG = "AccessibilityCache";
+
+    private static final boolean DEBUG = false;
+
+    private static final boolean CHECK_INTEGRITY = Build.IS_DEBUGGABLE;
+
+    private final Object mLock = new Object();
+
+    private final LongArray mTempLongArray = new LongArray();
+
+    private final SparseArray<AccessibilityWindowInfo> mWindowCache =
+            new SparseArray<AccessibilityWindowInfo>();
+
+    private final SparseArray<LongSparseArray<AccessibilityNodeInfo>> mNodeCache =
+            new SparseArray<LongSparseArray<AccessibilityNodeInfo>>();
+
+    private final SparseArray<AccessibilityWindowInfo> mTempWindowArray =
+            new SparseArray<AccessibilityWindowInfo>();
+
+    public void addWindow(AccessibilityWindowInfo window) {
+        synchronized (mLock) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Caching window: " + window.getId());
+            }
+            mWindowCache.put(window.getId(), window);
+        }
+    }
+
+    public void removeWindows(int[] windowIds) {
+        synchronized (mLock) {
+            final int windowCount = windowIds.length;
+            for (int i = 0; i < windowCount; i++) {
+                final int windowId = windowIds[i];
+                AccessibilityWindowInfo window = mWindowCache.get(windowId);
+                if (window != null) {
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "Removing window: " + windowId);
+                    }
+                    window.recycle();
+                    mWindowCache.remove(windowId);
+                }
+                clearNodesForWindowLocked(windowIds[i]);
+            }
+        }
+    }
+
+    /**
+     * Notifies the cache that the something in the UI changed. As a result
+     * the cache will either refresh some nodes or evict some nodes.
+     *
+     * @param event An event.
+     */
+    public void onAccessibilityEvent(AccessibilityEvent event) {
+        synchronized (mLock) {
+            final int eventType = event.getEventType();
+            switch (eventType) {
+                case AccessibilityEvent.TYPE_VIEW_FOCUSED:
+                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
+                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
+                case AccessibilityEvent.TYPE_VIEW_SELECTED:
+                case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
+                case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
+                    refreshCachedNodeLocked(event.getWindowId(), event.getSourceNodeId());
+                } break;
+
+                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: {
+                    synchronized (mLock) {
+                        final int windowId = event.getWindowId();
+                        final long sourceId = event.getSourceNodeId();
+                        if ((event.getContentChangeTypes()
+                                & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0) {
+                            clearSubTreeLocked(windowId, sourceId);
+                        } else {
+                            refreshCachedNodeLocked(windowId, sourceId);
+                        }
+                    }
+                } break;
+
+                case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
+                    clearSubTreeLocked(event.getWindowId(), event.getSourceNodeId());
+                } break;
+            }
+        }
+
+        if (CHECK_INTEGRITY) {
+            checkIntegrity();
+        }
+    }
+
+    private void refreshCachedNodeLocked(int windowId, long sourceId) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "Refreshing cached node.");
+        }
+
+        LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
+        if (nodes == null) {
+            return;
+        }
+        AccessibilityNodeInfo cachedInfo = nodes.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(windowId, sourceId);
+    }
+
+    /**
+     * Gets a cached {@link AccessibilityNodeInfo} given the id of the hosting
+     * window and the accessibility id of the node.
+     *
+     * @param windowId The id of the window hosting the node.
+     * @param accessibilityNodeId The info accessibility node id.
+     * @return The cached {@link AccessibilityNodeInfo} or null if such not found.
+     */
+    public AccessibilityNodeInfo getNode(int windowId, long accessibilityNodeId) {
+        synchronized(mLock) {
+            LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
+            if (nodes == null) {
+                return null;
+            }
+            AccessibilityNodeInfo info = nodes.get(accessibilityNodeId);
+            if (info != null) {
+                // Return a copy since the client calls to AccessibilityNodeInfo#recycle()
+                // will wipe the data of the cached info.
+                info = AccessibilityNodeInfo.obtain(info);
+            }
+            if (DEBUG) {
+                Log.i(LOG_TAG, "get(" + accessibilityNodeId + ") = " + info);
+            }
+            return info;
+        }
+    }
+
+    public List<AccessibilityWindowInfo> getWindows() {
+        synchronized (mLock) {
+            final int windowCount = mWindowCache.size();
+            if (windowCount > 0) {
+                // Careful to return the windows in a decreasing layer order.
+                SparseArray<AccessibilityWindowInfo> sortedWindows = mTempWindowArray;
+                sortedWindows.clear();
+
+                for (int i = 0; i < windowCount; i++) {
+                    AccessibilityWindowInfo window = mWindowCache.valueAt(i);
+                    sortedWindows.put(window.getLayer(), window);
+                }
+
+                List<AccessibilityWindowInfo> windows = new ArrayList<AccessibilityWindowInfo>();
+                for (int i = windowCount - 1; i >= 0; i--) {
+                    AccessibilityWindowInfo window = sortedWindows.valueAt(i);
+                    windows.add(AccessibilityWindowInfo.obtain(window));
+                }
+
+                sortedWindows.clear();
+
+                return windows;
+            }
+            return null;
+        }
+    }
+
+    public AccessibilityWindowInfo getWindow(int windowId) {
+        synchronized (mLock) {
+            AccessibilityWindowInfo window = mWindowCache.get(windowId);
+            if (window != null) {
+               return AccessibilityWindowInfo.obtain(window);
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Caches an {@link AccessibilityNodeInfo}.
+     *
+     * @param info The node to cache.
+     */
+    public void add(AccessibilityNodeInfo info) {
+        synchronized(mLock) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "add(" + info + ")");
+            }
+
+            final int windowId = info.getWindowId();
+            LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
+            if (nodes == null) {
+                nodes = new LongSparseArray<AccessibilityNodeInfo>();
+                mNodeCache.put(windowId, nodes);
+            }
+
+            final long sourceId = info.getSourceNodeId();
+            AccessibilityNodeInfo oldInfo = nodes.get(sourceId);
+            if (oldInfo != null) {
+                // If the added node is in the cache we have to be careful if
+                // the new one represents a source state where some of the
+                // children have been removed to remove the descendants that
+                // are no longer present.
+                final LongArray newChildrenIds = info.getChildNodeIds();
+                if (newChildrenIds != null) {
+                    // Cache the new ids as we will do some lookups.
+                    LongArray newChildNodeIds = mTempLongArray;
+                    final int newChildCount = newChildNodeIds.size();
+                    for (int i = 0; i < newChildCount; i++) {
+                        newChildNodeIds.add(newChildrenIds.get(i));
+                    }
+
+                    final int oldChildCount = oldInfo.getChildCount();
+                    for (int i = 0; i < oldChildCount; i++) {
+                        final long oldChildId = oldInfo.getChildId(i);
+                        if (newChildNodeIds.indexOf(oldChildId) < 0) {
+                            clearSubTreeLocked(windowId, oldChildId);
+                        }
+                    }
+
+                    newChildNodeIds.clear();
+                }
+
+                // Also be careful if the parent has changed since the new
+                // parent may be a predecessor of the old parent which will
+                // add cyclse to the cache.
+                final long oldParentId = oldInfo.getParentNodeId();
+                if (info.getParentNodeId() != oldParentId) {
+                    clearSubTreeLocked(windowId, oldParentId);
+                }
+           }
+
+            // Cache a copy since the client calls to AccessibilityNodeInfo#recycle()
+            // will wipe the data of the cached info.
+            AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info);
+            nodes.put(sourceId, clone);
+        }
+    }
+
+    /**
+     * Clears the cache.
+     */
+    public void clear() {
+        synchronized(mLock) {
+            if (DEBUG) {
+                Log.i(LOG_TAG, "clear()");
+            }
+            final int windowCount = mWindowCache.size();
+            for (int i = windowCount - 1; i >= 0; i--) {
+                AccessibilityWindowInfo window = mWindowCache.valueAt(i);
+                window.recycle();
+                mWindowCache.removeAt(i);
+            }
+            final int nodesForWindowCount = mNodeCache.size();
+            for (int i = 0; i < nodesForWindowCount; i++) {
+                final int windowId = mNodeCache.keyAt(i);
+                clearNodesForWindowLocked(windowId);
+            }
+        }
+    }
+
+    private void clearNodesForWindowLocked(int windowId) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "clearWindowLocked(" + windowId + ")");
+        }
+        LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
+        if (nodes == null) {
+            return;
+        }
+        // Recycle the nodes before clearing the cache.
+        final int nodeCount = nodes.size();
+        for (int i = nodeCount - 1; i >= 0; i--) {
+            AccessibilityNodeInfo info = nodes.valueAt(i);
+            nodes.removeAt(i);
+            info.recycle();
+        }
+        mNodeCache.remove(windowId);
+    }
+
+    /**
+     * Clears a subtree rooted at the node with the given id that is
+     * hosted in a given window.
+     *
+     * @param windowId The id of the hosting window.
+     * @param rootNodeId The root id.
+     */
+    private void clearSubTreeLocked(int windowId, long rootNodeId) {
+        if (DEBUG) {
+            Log.i(LOG_TAG, "Clearing cached subtree.");
+        }
+        LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.get(windowId);
+        if (nodes != null) {
+            clearSubTreeRecursiveLocked(nodes, rootNodeId);
+        }
+    }
+
+    /**
+     * Clears a subtree given a pointer to the root id and the nodes
+     * in the hosting window.
+     *
+     * @param nodes The nodes in the hosting window.
+     * @param rootNodeId The id of the root to evict.
+     */
+    private void clearSubTreeRecursiveLocked(LongSparseArray<AccessibilityNodeInfo> nodes,
+            long rootNodeId) {
+        AccessibilityNodeInfo current = nodes.get(rootNodeId);
+        if (current == null) {
+            return;
+        }
+        nodes.remove(rootNodeId);
+        final int childCount = current.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final long childNodeId = current.getChildId(i);
+            clearSubTreeRecursiveLocked(nodes, childNodeId);
+        }
+    }
+
+    /**
+     * Check the integrity of the cache which is nodes from different windows
+     * are not mixed, there is a single active window, there is a single focused
+     * window, for every window there are no duplicates nodes, all nodes for a
+     * window are connected, for every window there is a single input focused
+     * node, and for every window there is a single accessibility focused node.
+     */
+    public void checkIntegrity() {
+        synchronized (mLock) {
+            // Get the root.
+            if (mWindowCache.size() <= 0 && mNodeCache.size() == 0) {
+                return;
+            }
+
+            AccessibilityWindowInfo focusedWindow = null;
+            AccessibilityWindowInfo activeWindow = null;
+
+            final int windowCount = mWindowCache.size();
+            for (int i = 0; i < windowCount; i++) {
+                AccessibilityWindowInfo window = mWindowCache.valueAt(i);
+
+                // Check for one active window.
+                if (window.isActive()) {
+                    if (activeWindow != null) {
+                        Log.e(LOG_TAG, "Duplicate active window:" + window);
+                    } else {
+                        activeWindow = window;
+                    }
+                }
+
+                // Check for one focused window.
+                if (window.isFocused()) {
+                    if (focusedWindow != null) {
+                        Log.e(LOG_TAG, "Duplicate focused window:" + window);
+                    } else {
+                        focusedWindow = window;
+                    }
+                }
+            }
+
+            // Traverse the tree and do some checks.
+            AccessibilityNodeInfo accessFocus = null;
+            AccessibilityNodeInfo inputFocus = null;
+
+            final int nodesForWindowCount = mNodeCache.size();
+            for (int i = 0; i < nodesForWindowCount; i++) {
+                LongSparseArray<AccessibilityNodeInfo> nodes = mNodeCache.valueAt(i);
+                if (nodes.size() <= 0) {
+                    continue;
+                }
+
+                ArraySet<AccessibilityNodeInfo> seen = new ArraySet<AccessibilityNodeInfo>();
+                final int windowId = mNodeCache.keyAt(i);
+
+                final int nodeCount = nodes.size();
+                for (int j = 0; j < nodeCount; j++) {
+                    AccessibilityNodeInfo node = nodes.valueAt(j);
+
+                    // Check for duplicates
+                    if (!seen.add(node)) {
+                        Log.e(LOG_TAG, "Duplicate node: " + node
+                                + " in window:" + windowId);
+                    }
+
+                    // Check for one accessibility focus.
+                    if (node.isAccessibilityFocused()) {
+                        if (accessFocus != null) {
+                            Log.e(LOG_TAG, "Duplicate accessibility focus:" + node
+                                    + " in window:" + windowId);
+                        } else {
+                            accessFocus = node;
+                        }
+                    }
+
+                    // Check for one input focus.
+                    if (node.isFocused()) {
+                        if (inputFocus != null) {
+                            Log.e(LOG_TAG, "Duplicate input focus: " + node
+                                    + " in window:" + windowId);
+                        } else {
+                            inputFocus = node;
+                        }
+                    }
+
+                    // The node should be a child of its parent if we have the parent.
+                    AccessibilityNodeInfo nodeParent = nodes.get(node.getParentNodeId());
+                    if (nodeParent != null) {
+                        boolean childOfItsParent = false;
+                        final int childCount = nodeParent.getChildCount();
+                        for (int k = 0; k < childCount; k++) {
+                            AccessibilityNodeInfo child = nodes.get(nodeParent.getChildId(k));
+                            if (child == node) {
+                                childOfItsParent = true;
+                                break;
+                            }
+                        }
+                        if (!childOfItsParent) {
+                            Log.e(LOG_TAG, "Invalid parent-child ralation between parent: "
+                                    + nodeParent + " and child: " + node);
+                        }
+                    }
+
+                    // The node should be the parent of its child if we have the child.
+                    final int childCount = node.getChildCount();
+                    for (int k = 0; k < childCount; k++) {
+                        AccessibilityNodeInfo child = nodes.get(node.getChildId(k));
+                        if (child != null) {
+                            AccessibilityNodeInfo parent = nodes.get(child.getParentNodeId());
+                            if (parent != node) {
+                                Log.e(LOG_TAG, "Invalid child-parent ralation between child: "
+                                        + node + " and parent: " + nodeParent);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index f635eee..417e22c 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -343,6 +343,23 @@
  * view.</br>
  * </p>
  * <p>
+ * <b>Windows changed</b> - represents the event of changes in the windows shown on
+ * the screen such as a window appeared, a window disappeared, a window size changed,
+ * a window layer changed, etc.</br>
+ * <em>Type:</em> {@link #TYPE_WINDOWS_CHANGED}</br>
+ * <em>Properties:</em></br>
+ * <ul>
+ *   <li>{@link #getEventType()} - The type of the event.</li>
+ *   <li>{@link #getEventTime()} - The event time.</li>
+ * </ul>
+ * <em>Note:</em> You can retrieve the {@link AccessibilityWindowInfo} for the window
+ * source of the event via {@link AccessibilityEvent#getSource()} to get the source
+ * node on which then call {@link AccessibilityNodeInfo#getWindow()
+ * AccessibilityNodeInfo.getWindow()} to get the window. Also all windows on the screen can
+ * be retrieved by a call to {@link android.accessibilityservice.AccessibilityService#getWindows()
+ * android.accessibilityservice.AccessibilityService.getWindows()}.
+ * </p>
+ * <p>
  * <b>NOTIFICATION TYPES</b></br>
  * </p>
  * <p>
@@ -662,6 +679,11 @@
     public static final int TYPE_TOUCH_INTERACTION_END = 0x00200000;
 
     /**
+     * Represents the event change in the windows shown on the screen.
+     */
+    public static final int TYPE_WINDOWS_CHANGED = 0x00400000;
+
+    /**
      * Change type for {@link #TYPE_WINDOW_CONTENT_CHANGED} event:
      * The type of change is not defined.
      */
@@ -708,6 +730,7 @@
      * @see #TYPE_GESTURE_DETECTION_END
      * @see #TYPE_TOUCH_INTERACTION_START
      * @see #TYPE_TOUCH_INTERACTION_END
+     * @see #TYPE_WINDOWS_CHANGED
      */
     public static final int TYPES_ALL_MASK = 0xFFFFFFFF;
 
@@ -722,7 +745,7 @@
     int mAction;
     int mContentChangeTypes;
 
-    private final ArrayList<AccessibilityRecord> mRecords = new ArrayList<AccessibilityRecord>();
+    private ArrayList<AccessibilityRecord> mRecords;
 
     /*
      * Hide constructor from clients.
@@ -755,11 +778,13 @@
     @Override
     public void setSealed(boolean sealed) {
         super.setSealed(sealed);
-        List<AccessibilityRecord> records = mRecords;
-        final int recordCount = records.size();
-        for (int i = 0; i < recordCount; i++) {
-            AccessibilityRecord record = records.get(i);
-            record.setSealed(sealed);
+        final List<AccessibilityRecord> records = mRecords;
+        if (records != null) {
+            final int recordCount = records.size();
+            for (int i = 0; i < recordCount; i++) {
+                AccessibilityRecord record = records.get(i);
+                record.setSealed(sealed);
+            }
         }
     }
 
@@ -769,7 +794,7 @@
      * @return The number of records.
      */
     public int getRecordCount() {
-        return mRecords.size();
+        return mRecords == null ? 0 : mRecords.size();
     }
 
     /**
@@ -781,6 +806,9 @@
      */
     public void appendRecord(AccessibilityRecord record) {
         enforceNotSealed();
+        if (mRecords == null) {
+            mRecords = new ArrayList<AccessibilityRecord>();
+        }
         mRecords.add(record);
     }
 
@@ -791,6 +819,9 @@
      * @return The record at the specified index.
      */
     public AccessibilityRecord getRecord(int index) {
+        if (mRecords == null) {
+            throw new IndexOutOfBoundsException("Invalid index " + index + ", size is 0");
+        }
         return mRecords.get(index);
     }
 
@@ -964,11 +995,14 @@
         AccessibilityEvent eventClone = AccessibilityEvent.obtain();
         eventClone.init(event);
 
-        final int recordCount = event.mRecords.size();
-        for (int i = 0; i < recordCount; i++) {
-            AccessibilityRecord record = event.mRecords.get(i);
-            AccessibilityRecord recordClone = AccessibilityRecord.obtain(record);
-            eventClone.mRecords.add(recordClone);
+        if (event.mRecords != null) {
+            final int recordCount = event.mRecords.size();
+            eventClone.mRecords = new ArrayList<AccessibilityRecord>(recordCount);
+            for (int i = 0; i < recordCount; i++) {
+                final AccessibilityRecord record = event.mRecords.get(i);
+                final AccessibilityRecord recordClone = AccessibilityRecord.obtain(record);
+                eventClone.mRecords.add(recordClone);
+            }
         }
 
         return eventClone;
@@ -1013,9 +1047,11 @@
         mContentChangeTypes = 0;
         mPackageName = null;
         mEventTime = 0;
-        while (!mRecords.isEmpty()) {
-            AccessibilityRecord record = mRecords.remove(0);
-            record.recycle();
+        if (mRecords != null) {
+            while (!mRecords.isEmpty()) {
+                AccessibilityRecord record = mRecords.remove(0);
+                record.recycle();
+            }
         }
     }
 
@@ -1037,11 +1073,14 @@
 
         // Read the records.
         final int recordCount = parcel.readInt();
-        for (int i = 0; i < recordCount; i++) {
-            AccessibilityRecord record = AccessibilityRecord.obtain();
-            readAccessibilityRecordFromParcel(record, parcel);
-            record.mConnectionId = mConnectionId;
-            mRecords.add(record);
+        if (recordCount > 0) {
+            mRecords = new ArrayList<AccessibilityRecord>(recordCount);
+            for (int i = 0; i < recordCount; i++) {
+                AccessibilityRecord record = AccessibilityRecord.obtain();
+                readAccessibilityRecordFromParcel(record, parcel);
+                record.mConnectionId = mConnectionId;
+                mRecords.add(record);
+            }
         }
     }
 
@@ -1147,8 +1186,8 @@
             builder.append("; ContentChangeTypes: ").append(mContentChangeTypes);
             builder.append("; sourceWindowId: ").append(mSourceWindowId);
             builder.append("; mSourceNodeId: ").append(mSourceNodeId);
-            for (int i = 0; i < mRecords.size(); i++) {
-                AccessibilityRecord record = mRecords.get(i);
+            for (int i = 0; i < getRecordCount(); i++) {
+                final AccessibilityRecord record = getRecord(i);
                 builder.append("  Record ");
                 builder.append(i);
                 builder.append(":");
@@ -1350,6 +1389,13 @@
                     builder.append("TYPE_TOUCH_INTERACTION_END");
                     eventTypeCount++;
                 } break;
+                case TYPE_WINDOWS_CHANGED: {
+                    if (eventTypeCount > 0) {
+                        builder.append(", ");
+                    }
+                    builder.append("TYPE_WINDOWS_CHANGED");
+                    eventTypeCount++;
+                } break;
             }
         }
         if (eventTypeCount > 1) {
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 139df3e..4dd8dcb 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -27,7 +27,6 @@
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.SparseArray;
-import android.util.SparseLongArray;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -101,14 +100,11 @@
 
     private Message mSameThreadMessage;
 
-    // The connection cache is shared between all interrogating threads.
     private static final SparseArray<IAccessibilityServiceConnection> sConnectionCache =
         new SparseArray<IAccessibilityServiceConnection>();
 
-    // The connection cache is shared between all interrogating threads since
-    // at any given time there is only one window allowing querying.
-    private static final AccessibilityNodeInfoCache sAccessibilityNodeInfoCache =
-        new AccessibilityNodeInfoCache();
+    private static final AccessibilityCache sAccessibilityCache =
+        new AccessibilityCache();
 
     /**
      * @return The client for the current thread.
@@ -167,6 +163,86 @@
     }
 
     /**
+     * Gets the info for a window.
+     *
+     * @param connectionId The id of a connection for interacting with the system.
+     * @param accessibilityWindowId A unique window id. Use
+     *     {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
+     *     to query the currently active window.
+     * @return The {@link AccessibilityWindowInfo}.
+     */
+    public AccessibilityWindowInfo getWindow(int connectionId, int accessibilityWindowId) {
+        try {
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                AccessibilityWindowInfo window = sAccessibilityCache.getWindow(
+                        accessibilityWindowId);
+                if (window != null) {
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "Window cache hit");
+                    }
+                    return window;
+                }
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "Window cache miss");
+                }
+                window = connection.getWindow(accessibilityWindowId);
+                if (window != null) {
+                    sAccessibilityCache.addWindow(window);
+                    return window;
+                }
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while calling remote getWindow", re);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the info for all windows.
+     *
+     * @param connectionId The id of a connection for interacting with the system.
+     * @return The {@link AccessibilityWindowInfo} list.
+     */
+    public List<AccessibilityWindowInfo> getWindows(int connectionId) {
+        try {
+            IAccessibilityServiceConnection connection = getConnection(connectionId);
+            if (connection != null) {
+                List<AccessibilityWindowInfo> windows = sAccessibilityCache.getWindows();
+                if (windows != null) {
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "Window cache hit");
+                    }
+                    return windows;
+                }
+                if (DEBUG) {
+                    Log.i(LOG_TAG, "Window cache miss");
+                }
+                windows = connection.getWindows();
+                if (windows != null) {
+                    final int windowCount = windows.size();
+                    for (int i = 0; i < windowCount; i++) {
+                        AccessibilityWindowInfo window = windows.get(i);
+                        sAccessibilityCache.addWindow(window);
+                    }
+                    return windows;
+                }
+            } else {
+                if (DEBUG) {
+                    Log.w(LOG_TAG, "No connection for connection id: " + connectionId);
+                }
+            }
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "Error while calling remote getWindows", re);
+        }
+        return Collections.emptyList();
+    }
+
+    /**
      * Finds an {@link AccessibilityNodeInfo} by accessibility id.
      *
      * @param connectionId The id of a connection for interacting with the system.
@@ -184,15 +260,26 @@
     public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(int connectionId,
             int accessibilityWindowId, long accessibilityNodeId, boolean bypassCache,
             int prefetchFlags) {
+        if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0
+                && (prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) == 0) {
+            throw new IllegalArgumentException("FLAG_PREFETCH_SIBLINGS"
+                + " requires FLAG_PREFETCH_PREDECESSORS");
+        }
         try {
             IAccessibilityServiceConnection connection = getConnection(connectionId);
             if (connection != null) {
                 if (!bypassCache) {
-                    AccessibilityNodeInfo cachedInfo = sAccessibilityNodeInfoCache.get(
-                            accessibilityNodeId);
+                    AccessibilityNodeInfo cachedInfo = sAccessibilityCache.getNode(
+                            accessibilityWindowId, accessibilityNodeId);
                     if (cachedInfo != null) {
+                        if (DEBUG) {
+                            Log.i(LOG_TAG, "Node cache hit");
+                        }
                         return cachedInfo;
                     }
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "Node cache miss");
+                    }
                 }
                 final int interactionId = mInteractionIdCounter.getAndIncrement();
                 final boolean success = connection.findAccessibilityNodeInfoByAccessibilityId(
@@ -213,10 +300,8 @@
                 }
             }
         } catch (RemoteException re) {
-            if (DEBUG) {
-                Log.w(LOG_TAG, "Error while calling remote"
-                        + " findAccessibilityNodeInfoByAccessibilityId", re);
-            }
+            Log.e(LOG_TAG, "Error while calling remote"
+                    + " findAccessibilityNodeInfoByAccessibilityId", re);
         }
         return null;
     }
@@ -260,10 +345,8 @@
                 }
             }
         } catch (RemoteException re) {
-            if (DEBUG) {
-                Log.w(LOG_TAG, "Error while calling remote"
-                        + " findAccessibilityNodeInfoByViewIdInActiveWindow", re);
-            }
+            Log.w(LOG_TAG, "Error while calling remote"
+                    + " findAccessibilityNodeInfoByViewIdInActiveWindow", re);
         }
         return Collections.emptyList();
     }
@@ -308,10 +391,8 @@
                 }
             }
         } catch (RemoteException re) {
-            if (DEBUG) {
-                Log.w(LOG_TAG, "Error while calling remote"
-                        + " findAccessibilityNodeInfosByViewText", re);
-            }
+            Log.w(LOG_TAG, "Error while calling remote"
+                    + " findAccessibilityNodeInfosByViewText", re);
         }
         return Collections.emptyList();
     }
@@ -353,9 +434,7 @@
                 }
             }
         } catch (RemoteException re) {
-            if (DEBUG) {
-                Log.w(LOG_TAG, "Error while calling remote findFocus", re);
-            }
+            Log.w(LOG_TAG, "Error while calling remote findFocus", re);
         }
         return null;
     }
@@ -397,9 +476,7 @@
                 }
             }
         } catch (RemoteException re) {
-            if (DEBUG) {
-                Log.w(LOG_TAG, "Error while calling remote accessibilityFocusSearch", re);
-            }
+            Log.w(LOG_TAG, "Error while calling remote accessibilityFocusSearch", re);
         }
         return null;
     }
@@ -437,19 +514,21 @@
                 }
             }
         } catch (RemoteException re) {
-            if (DEBUG) {
-                Log.w(LOG_TAG, "Error while calling remote performAccessibilityAction", re);
-            }
+            Log.w(LOG_TAG, "Error while calling remote performAccessibilityAction", re);
         }
         return false;
     }
 
     public void clearCache() {
-        sAccessibilityNodeInfoCache.clear();
+        sAccessibilityCache.clear();
     }
 
     public void onAccessibilityEvent(AccessibilityEvent event) {
-        sAccessibilityNodeInfoCache.onAccessibilityEvent(event);
+        sAccessibilityCache.onAccessibilityEvent(event);
+    }
+
+    public void removeWindows(int[] windowIds) {
+        sAccessibilityCache.removeWindows(windowIds);
     }
 
     /**
@@ -614,7 +693,7 @@
         if (info != null) {
             info.setConnectionId(connectionId);
             info.setSealed(true);
-            sAccessibilityNodeInfoCache.add(info);
+            sAccessibilityCache.add(info);
         }
     }
 
@@ -718,10 +797,9 @@
                 Log.e(LOG_TAG, "Duplicate node.");
                 return;
             }
-            SparseLongArray childIds = current.getChildNodeIds();
-            final int childCount = childIds.size();
+            final int childCount = current.getChildCount();
             for (int i = 0; i < childCount; i++) {
-                final long childId = childIds.valueAt(i);
+                final long childId = current.getChildId(i);
                 for (int j = 0; j < infoCount; j++) {
                     AccessibilityNodeInfo child = infos.get(j);
                     if (child.getSourceNodeId() == childId) {
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 879e58f..cbc38c6 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -75,13 +75,49 @@
     /** @hide */
     public static final int STATE_FLAG_TOUCH_EXPLORATION_ENABLED = 0x00000002;
 
+    /** @hide */
+    public static final int INVERSION_DISABLED = -1;
+
+    /** @hide */
+    public static final int INVERSION_STANDARD = 0;
+
+    /** @hide */
+    public static final int INVERSION_HUE_ONLY = 1;
+
+    /** @hide */
+    public static final int INVERSION_VALUE_ONLY = 2;
+
+    /** @hide */
+    public static final int DALTONIZER_DISABLED = -1;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_MONOCHROMACY = 0;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_PROTANOMALY = 1;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_DEUTERANOMALY = 2;
+
+    /** @hide */
+    public static final int DALTONIZER_SIMULATE_TRITANOMALY = 3;
+
+    /** @hide */
+    public static final int DALTONIZER_CORRECT_PROTANOMALY = 11;
+
+    /** @hide */
+    public static final int DALTONIZER_CORRECT_DEUTERANOMALY = 12;
+
+    /** @hide */
+    public static final int DALTONIZER_CORRECT_TRITANOMALY = 13;
+
     static final Object sInstanceSync = new Object();
 
     private static AccessibilityManager sInstance;
 
-    private static final int DO_SET_STATE = 10;
+    private final Object mLock = new Object();
 
-    final IAccessibilityManager mService;
+    private IAccessibilityManager mService;
 
     final int mUserId;
 
@@ -130,29 +166,14 @@
         public void onTouchExplorationStateChanged(boolean enabled);
     }
 
-    final IAccessibilityManagerClient.Stub mClient = new IAccessibilityManagerClient.Stub() {
+    private final IAccessibilityManagerClient.Stub mClient =
+            new IAccessibilityManagerClient.Stub() {
         public void setState(int state) {
-            mHandler.obtainMessage(DO_SET_STATE, state, 0).sendToTarget();
-        }
-    };
-
-    class MyHandler extends Handler {
-
-        MyHandler(Looper mainLooper) {
-            super(mainLooper);
-        }
-
-        @Override
-        public void handleMessage(Message message) {
-            switch (message.what) {
-                case DO_SET_STATE :
-                    setState(message.arg1);
-                    return;
-                default :
-                    Log.w(LOG_TAG, "Unknown message type: " + message.what);
+            synchronized (mLock) {
+                setStateLocked(state);
             }
         }
-    }
+    };
 
     /**
      * Get an AccessibilityManager instance (create one if necessary).
@@ -198,17 +219,16 @@
         mHandler = new MyHandler(context.getMainLooper());
         mService = service;
         mUserId = userId;
-        if (mService == null) {
-            mIsEnabled = false;
+        synchronized (mLock) {
+            tryConnectToServiceLocked();
         }
-        try {
-            if (mService != null) {
-                final int stateFlags = mService.addClient(mClient, userId);
-                setState(stateFlags);
-            }
-        } catch (RemoteException re) {
-            Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
-        }
+    }
+
+    /**
+     * @hide
+     */
+    public IAccessibilityManagerClient getClient() {
+        return mClient;
     }
 
     /**
@@ -217,7 +237,11 @@
      * @return True if accessibility is enabled, false otherwise.
      */
     public boolean isEnabled() {
-        synchronized (mHandler) {
+        synchronized (mLock) {
+            IAccessibilityManager service = getServiceLocked();
+            if (service == null) {
+                return false;
+            }
             return mIsEnabled;
         }
     }
@@ -228,24 +252,16 @@
      * @return True if touch exploration is enabled, false otherwise.
      */
     public boolean isTouchExplorationEnabled() {
-        synchronized (mHandler) {
+        synchronized (mLock) {
+            IAccessibilityManager service = getServiceLocked();
+            if (service == null) {
+                return false;
+            }
             return mIsTouchExplorationEnabled;
         }
     }
 
     /**
-     * Returns the client interface this instance registers in
-     * the centralized accessibility manager service.
-     *
-     * @return The client.
-     *
-     * @hide
-     */
-    public IAccessibilityManagerClient getClient() {
-       return (IAccessibilityManagerClient) mClient.asBinder();
-    }
-
-    /**
      * Sends an {@link AccessibilityEvent}.
      *
      * @param event The event to send.
@@ -259,8 +275,17 @@
      * their descendants.
      */
     public void sendAccessibilityEvent(AccessibilityEvent event) {
-        if (!mIsEnabled) {
-            throw new IllegalStateException("Accessibility off. Did you forget to check that?");
+        final IAccessibilityManager service;
+        final int userId;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return;
+            }
+            if (!mIsEnabled) {
+                throw new IllegalStateException("Accessibility off. Did you forget to check that?");
+            }
+            userId = mUserId;
         }
         boolean doRecycle = false;
         try {
@@ -269,7 +294,7 @@
             // client using it is called through Binder from another process. Example: MMS
             // app adds a SMS notification and the NotificationManagerService calls this method
             long identityToken = Binder.clearCallingIdentity();
-            doRecycle = mService.sendAccessibilityEvent(event, mUserId);
+            doRecycle = service.sendAccessibilityEvent(event, userId);
             Binder.restoreCallingIdentity(identityToken);
             if (DEBUG) {
                 Log.i(LOG_TAG, event + " sent");
@@ -287,11 +312,20 @@
      * Requests feedback interruption from all accessibility services.
      */
     public void interrupt() {
-        if (!mIsEnabled) {
-            throw new IllegalStateException("Accessibility off. Did you forget to check that?");
+        final IAccessibilityManager service;
+        final int userId;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return;
+            }
+            if (!mIsEnabled) {
+                throw new IllegalStateException("Accessibility off. Did you forget to check that?");
+            }
+            userId = mUserId;
         }
         try {
-            mService.interrupt(mUserId);
+            service.interrupt(userId);
             if (DEBUG) {
                 Log.i(LOG_TAG, "Requested interrupt from all services");
             }
@@ -325,18 +359,30 @@
      * @return An unmodifiable list with {@link AccessibilityServiceInfo}s.
      */
     public List<AccessibilityServiceInfo> getInstalledAccessibilityServiceList() {
+        final IAccessibilityManager service;
+        final int userId;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return Collections.emptyList();
+            }
+            userId = mUserId;
+        }
+
         List<AccessibilityServiceInfo> services = null;
         try {
-            if (mService != null) {
-                services = mService.getInstalledAccessibilityServiceList(mUserId);
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
-                }
+            services = service.getInstalledAccessibilityServiceList(userId);
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
             }
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re);
         }
-        return services != null ? Collections.unmodifiableList(services) : Collections.EMPTY_LIST;
+        if (services != null) {
+            return Collections.unmodifiableList(services);
+        } else {
+            return Collections.emptyList();
+        }
     }
 
     /**
@@ -354,18 +400,30 @@
      */
     public List<AccessibilityServiceInfo> getEnabledAccessibilityServiceList(
             int feedbackTypeFlags) {
+        final IAccessibilityManager service;
+        final int userId;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return Collections.emptyList();
+            }
+            userId = mUserId;
+        }
+
         List<AccessibilityServiceInfo> services = null;
         try {
-            if (mService != null) {
-                services = mService.getEnabledAccessibilityServiceList(feedbackTypeFlags, mUserId);
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
-                }
+            services = service.getEnabledAccessibilityServiceList(feedbackTypeFlags, userId);
+            if (DEBUG) {
+                Log.i(LOG_TAG, "Installed AccessibilityServices " + services);
             }
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error while obtaining the installed AccessibilityServices. ", re);
         }
-        return services != null ? Collections.unmodifiableList(services) : Collections.EMPTY_LIST;
+        if (services != null) {
+            return Collections.unmodifiableList(services);
+        } else {
+            return Collections.emptyList();
+        }
     }
 
     /**
@@ -377,6 +435,7 @@
      */
     public boolean addAccessibilityStateChangeListener(
             AccessibilityStateChangeListener listener) {
+        // Final CopyOnArrayList - no lock needed.
         return mAccessibilityStateChangeListeners.add(listener);
     }
 
@@ -388,6 +447,7 @@
      */
     public boolean removeAccessibilityStateChangeListener(
             AccessibilityStateChangeListener listener) {
+        // Final CopyOnArrayList - no lock needed.
         return mAccessibilityStateChangeListeners.remove(listener);
     }
 
@@ -400,6 +460,7 @@
      */
     public boolean addTouchExplorationStateChangeListener(
             TouchExplorationStateChangeListener listener) {
+        // Final CopyOnArrayList - no lock needed.
         return mTouchExplorationStateChangeListeners.add(listener);
     }
 
@@ -411,6 +472,7 @@
      */
     public boolean removeTouchExplorationStateChangeListener(
             TouchExplorationStateChangeListener listener) {
+        // Final CopyOnArrayList - no lock needed.
         return mTouchExplorationStateChangeListeners.remove(listener);
     }
 
@@ -419,50 +481,24 @@
      *
      * @param stateFlags The state flags.
      */
-    private void setState(int stateFlags) {
+    private void setStateLocked(int stateFlags) {
         final boolean enabled = (stateFlags & STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
         final boolean touchExplorationEnabled =
                 (stateFlags & STATE_FLAG_TOUCH_EXPLORATION_ENABLED) != 0;
-        synchronized (mHandler) {
-            final boolean wasEnabled = mIsEnabled;
-            final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled;
 
-            // Ensure listeners get current state from isZzzEnabled() calls.
-            mIsEnabled = enabled;
-            mIsTouchExplorationEnabled = touchExplorationEnabled;
+        final boolean wasEnabled = mIsEnabled;
+        final boolean wasTouchExplorationEnabled = mIsTouchExplorationEnabled;
 
-            if (wasEnabled != enabled) {
-                notifyAccessibilityStateChangedLh();
-            }
+        // Ensure listeners get current state from isZzzEnabled() calls.
+        mIsEnabled = enabled;
+        mIsTouchExplorationEnabled = touchExplorationEnabled;
 
-            if (wasTouchExplorationEnabled != touchExplorationEnabled) {
-                notifyTouchExplorationStateChangedLh();
-            }
+        if (wasEnabled != enabled) {
+            mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED);
         }
-    }
 
-    /**
-     * Notifies the registered {@link AccessibilityStateChangeListener}s.
-     * <p>
-     * The caller must be locked on {@link #mHandler}.
-     */
-    private void notifyAccessibilityStateChangedLh() {
-        final int listenerCount = mAccessibilityStateChangeListeners.size();
-        for (int i = 0; i < listenerCount; i++) {
-            mAccessibilityStateChangeListeners.get(i).onAccessibilityStateChanged(mIsEnabled);
-        }
-    }
-
-    /**
-     * Notifies the registered {@link TouchExplorationStateChangeListener}s.
-     * <p>
-     * The caller must be locked on {@link #mHandler}.
-     */
-    private void notifyTouchExplorationStateChangedLh() {
-        final int listenerCount = mTouchExplorationStateChangeListeners.size();
-        for (int i = 0; i < listenerCount; i++) {
-            mTouchExplorationStateChangeListeners.get(i)
-                    .onTouchExplorationStateChanged(mIsTouchExplorationEnabled);
+        if (wasTouchExplorationEnabled != touchExplorationEnabled) {
+            mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_EXPLORATION_STATE_CHANGED);
         }
     }
 
@@ -475,11 +511,17 @@
      */
     public int addAccessibilityInteractionConnection(IWindow windowToken,
             IAccessibilityInteractionConnection connection) {
-        if (mService == null) {
-            return View.NO_ID;
+        final IAccessibilityManager service;
+        final int userId;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return View.NO_ID;
+            }
+            userId = mUserId;
         }
         try {
-            return mService.addAccessibilityInteractionConnection(windowToken, connection, mUserId);
+            return service.addAccessibilityInteractionConnection(windowToken, connection, userId);
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error while adding an accessibility interaction connection. ", re);
         }
@@ -493,12 +535,90 @@
      * @hide
      */
     public void removeAccessibilityInteractionConnection(IWindow windowToken) {
-        try {
-            if (mService != null) {
-                mService.removeAccessibilityInteractionConnection(windowToken);
+        final IAccessibilityManager service;
+        synchronized (mLock) {
+            service = getServiceLocked();
+            if (service == null) {
+                return;
             }
+        }
+        try {
+            service.removeAccessibilityInteractionConnection(windowToken);
         } catch (RemoteException re) {
             Log.e(LOG_TAG, "Error while removing an accessibility interaction connection. ", re);
         }
     }
+
+    private  IAccessibilityManager getServiceLocked() {
+        if (mService == null) {
+            tryConnectToServiceLocked();
+        }
+        return mService;
+    }
+
+    private void tryConnectToServiceLocked() {
+        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
+        if (iBinder == null) {
+            return;
+        }
+        IAccessibilityManager service = IAccessibilityManager.Stub.asInterface(iBinder);
+        try {
+            final int stateFlags = service.addClient(mClient, mUserId);
+            setStateLocked(stateFlags);
+            mService = service;
+        } catch (RemoteException re) {
+            Log.e(LOG_TAG, "AccessibilityManagerService is dead", re);
+        }
+    }
+
+    /**
+     * Notifies the registered {@link AccessibilityStateChangeListener}s.
+     */
+    private void handleNotifyAccessibilityStateChanged() {
+        final boolean isEnabled;
+        synchronized (mLock) {
+            isEnabled = mIsEnabled;
+        }
+        final int listenerCount = mAccessibilityStateChangeListeners.size();
+        for (int i = 0; i < listenerCount; i++) {
+            mAccessibilityStateChangeListeners.get(i).onAccessibilityStateChanged(isEnabled);
+        }
+    }
+
+    /**
+     * Notifies the registered {@link TouchExplorationStateChangeListener}s.
+     */
+    private void handleNotifyTouchExplorationStateChanged() {
+        final boolean isTouchExplorationEnabled;
+        synchronized (mLock) {
+            isTouchExplorationEnabled = mIsTouchExplorationEnabled;
+        }
+        final int listenerCount = mTouchExplorationStateChangeListeners.size();
+        for (int i = 0; i < listenerCount; i++) {
+            mTouchExplorationStateChangeListeners.get(i)
+                    .onTouchExplorationStateChanged(isTouchExplorationEnabled);
+        }
+    }
+
+    private final class MyHandler extends Handler {
+        public static final int MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED = 1;
+        public static final int MSG_NOTIFY_EXPLORATION_STATE_CHANGED = 2;
+
+        public MyHandler(Looper looper) {
+            super(looper, null, false);
+        }
+
+        @Override
+        public void handleMessage(Message message) {
+            switch (message.what) {
+                case MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED: {
+                    handleNotifyAccessibilityStateChanged();
+                } break;
+
+                case MSG_NOTIFY_EXPLORATION_STATE_CHANGED: {
+                    handleNotifyTouchExplorationStateChanged();
+                }
+            }
+        }
+    }
 }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 4f53c1e..a6904f7 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -22,8 +22,8 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.text.InputType;
+import android.util.LongArray;
 import android.util.Pools.SynchronizedPool;
-import android.util.SparseLongArray;
 import android.view.View;
 
 import java.util.Collections;
@@ -62,13 +62,19 @@
     private static final boolean DEBUG = false;
 
     /** @hide */
-    public static final int UNDEFINED = -1;
+    public static final int UNDEFINED_CONNECTION_ID = -1;
 
     /** @hide */
-    public static final long ROOT_NODE_ID = makeNodeId(UNDEFINED, UNDEFINED);
+    public static final int UNDEFINED_SELECTION_INDEX = -1;
 
     /** @hide */
-    public static final int ACTIVE_WINDOW_ID = UNDEFINED;
+    public static final int UNDEFINED_ITEM_ID = Integer.MAX_VALUE;
+
+    /** @hide */
+    public static final long ROOT_NODE_ID = makeNodeId(UNDEFINED_ITEM_ID, UNDEFINED_ITEM_ID);
+
+    /** @hide */
+    public static final int ACTIVE_WINDOW_ID = UNDEFINED_ITEM_ID;
 
     /** @hide */
     public static final int FLAG_PREFETCH_PREDECESSORS = 0x00000001;
@@ -282,6 +288,22 @@
      */
     public static final int ACTION_DISMISS = 0x00100000;
 
+    /**
+     * Action that sets the text of the node. Performing the action without argument, using <code>
+     * null</code> or empty {@link CharSequence} will clear the text. This action will also put the
+     * cursor at the end of text.
+     * <p>
+     * <strong>Arguments:</strong> {@link #ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE}<br>
+     * <strong>Example:</strong>
+     * <code><pre><p>
+     *   Bundle arguments = new Bundle();
+     *   arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE,
+     *       "android");
+     *   info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments);
+     * </code></pre></p>
+     */
+    public static final int ACTION_SET_TEXT = 0x00200000;
+
     // Action arguments
 
     /**
@@ -351,6 +373,18 @@
     public static final String ACTION_ARGUMENT_SELECTION_END_INT =
             "ACTION_ARGUMENT_SELECTION_END_INT";
 
+    /**
+     * Argument for specifying the text content to set
+     * <p>
+     * <strong>Type:</strong> CharSequence<br>
+     * <strong>Actions:</strong> {@link #ACTION_SET_TEXT}
+     * </p>
+     *
+     * @see #ACTION_SET_TEXT
+     */
+    public static final String ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE =
+            "ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE";
+
     // Focus types
 
     /**
@@ -476,6 +510,13 @@
      * @hide
      */
     public static long makeNodeId(int accessibilityViewId, int virtualDescendantId) {
+        // We changed the value for undefined node to positive due to wrong
+        // global id composition (two 32-bin ints into one 64-bit long) but
+        // the value used for the host node provider view has id -1 so we
+        // remap it here.
+        if (virtualDescendantId == AccessibilityNodeProvider.HOST_VIEW_ID) {
+            virtualDescendantId = UNDEFINED_ITEM_ID;
+        }
         return (((long) virtualDescendantId) << VIRTUAL_DESCENDANT_ID_SHIFT) | accessibilityViewId;
     }
 
@@ -487,7 +528,7 @@
     private boolean mSealed;
 
     // Data.
-    private int mWindowId = UNDEFINED;
+    private int mWindowId = UNDEFINED_ITEM_ID;
     private long mSourceNodeId = ROOT_NODE_ID;
     private long mParentNodeId = ROOT_NODE_ID;
     private long mLabelForId = ROOT_NODE_ID;
@@ -503,19 +544,19 @@
     private CharSequence mContentDescription;
     private String mViewIdResourceName;
 
-    private final SparseLongArray mChildNodeIds = new SparseLongArray();
+    private LongArray mChildNodeIds;
     private int mActions;
 
     private int mMovementGranularities;
 
-    private int mTextSelectionStart = UNDEFINED;
-    private int mTextSelectionEnd = UNDEFINED;
+    private int mTextSelectionStart = UNDEFINED_SELECTION_INDEX;
+    private int mTextSelectionEnd = UNDEFINED_SELECTION_INDEX;
     private int mInputType = InputType.TYPE_NULL;
     private int mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE;
 
     private Bundle mExtras;
 
-    private int mConnectionId = UNDEFINED;
+    private int mConnectionId = UNDEFINED_CONNECTION_ID;
 
     private RangeInfo mRangeInfo;
     private CollectionInfo mCollectionInfo;
@@ -539,7 +580,7 @@
      * @param source The info source.
      */
     public void setSource(View source) {
-        setSource(source, UNDEFINED);
+        setSource(source, UNDEFINED_ITEM_ID);
     }
 
     /**
@@ -563,9 +604,9 @@
      */
     public void setSource(View root, int virtualDescendantId) {
         enforceNotSealed();
-        mWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED;
+        mWindowId = (root != null) ? root.getAccessibilityWindowId() : UNDEFINED_ITEM_ID;
         final int rootAccessibilityViewId =
-            (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
+            (root != null) ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
         mSourceNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
     }
 
@@ -666,21 +707,35 @@
     }
 
     /**
-     * @return The ids of the children.
+     * Returns the array containing the IDs of this node's children.
      *
      * @hide
      */
-    public SparseLongArray getChildNodeIds() {
+    public LongArray getChildNodeIds() {
         return mChildNodeIds;
     }
 
     /**
+     * Returns the id of the child at the specified index.
+     *
+     * @throws IndexOutOfBoundsException when index &lt; 0 || index &gt;=
+     *             getChildCount()
+     * @hide
+     */
+    public long getChildId(int index) {
+        if (mChildNodeIds == null) {
+            throw new IndexOutOfBoundsException();
+        }
+        return mChildNodeIds.get(index);
+    }
+
+    /**
      * Gets the number of children.
      *
      * @return The child count.
      */
     public int getChildCount() {
-        return mChildNodeIds.size();
+        return mChildNodeIds == null ? 0 : mChildNodeIds.size();
     }
 
     /**
@@ -699,6 +754,9 @@
      */
     public AccessibilityNodeInfo getChild(int index) {
         enforceSealed();
+        if (mChildNodeIds == null) {
+            return null;
+        }
         if (!canPerformRequestOverConnection(mSourceNodeId)) {
             return null;
         }
@@ -721,7 +779,35 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void addChild(View child) {
-        addChild(child, UNDEFINED);
+        addChildInternal(child, UNDEFINED_ITEM_ID, true);
+    }
+
+    /**
+     * Unchecked version of {@link #addChild(View)} that does not verify
+     * uniqueness. For framework use only.
+     *
+     * @hide
+     */
+    public void addChildUnchecked(View child) {
+        addChildInternal(child, UNDEFINED_ITEM_ID, false);
+    }
+
+    /**
+     * Removes a child. If the child was not previously added to the node,
+     * calling this method has no effect.
+     * <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 child The child.
+     * @return true if the child was present
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public boolean removeChild(View child) {
+        return removeChild(child, UNDEFINED_ITEM_ID);
     }
 
     /**
@@ -739,12 +825,49 @@
      * @param virtualDescendantId The id of the virtual child.
      */
     public void addChild(View root, int virtualDescendantId) {
+        addChildInternal(root, virtualDescendantId, true);
+    }
+
+    private void addChildInternal(View root, int virtualDescendantId, boolean checked) {
         enforceNotSealed();
-        final int index = mChildNodeIds.size();
+        if (mChildNodeIds == null) {
+            mChildNodeIds = new LongArray();
+        }
         final int rootAccessibilityViewId =
-            (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
+            (root != null) ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
         final long childNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
-        mChildNodeIds.put(index, childNodeId);
+        // If we're checking uniqueness and the ID already exists, abort.
+        if (checked && mChildNodeIds.indexOf(childNodeId) >= 0) {
+            return;
+        }
+        mChildNodeIds.add(childNodeId);
+    }
+
+    /**
+     * Removes a virtual child which is a descendant of the given
+     * <code>root</code>. If the child was not previously added to the node,
+     * calling this method has no effect.
+     *
+     * @param root The root of the virtual subtree.
+     * @param virtualDescendantId The id of the virtual child.
+     * @return true if the child was present
+     * @see #addChild(View, int)
+     */
+    public boolean removeChild(View root, int virtualDescendantId) {
+        enforceNotSealed();
+        final LongArray childIds = mChildNodeIds;
+        if (childIds == null) {
+            return false;
+        }
+        final int rootAccessibilityViewId =
+                (root != null) ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
+        final long childNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
+        final int index = childIds.indexOf(childNodeId);
+        if (index < 0) {
+            return false;
+        }
+        childIds.remove(index);
+        return true;
     }
 
     /**
@@ -789,6 +912,24 @@
     }
 
     /**
+     * Removes an action that can be performed on the node. If the action was
+     * not already added to the node, calling this method has no effect.
+     * <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 action The action.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void removeAction(int action) {
+        enforceNotSealed();
+        mActions &= ~action;
+    }
+
+    /**
      * Sets the movement granularities for traversing the text of this node.
      * <p>
      *   <strong>Note:</strong> Cannot be called from an
@@ -915,6 +1056,22 @@
     }
 
     /**
+     * Gets the window to which this node belongs.
+     *
+     * @return The window.
+     *
+     * @see android.accessibilityservice.AccessibilityService#getWindows()
+     */
+    public AccessibilityWindowInfo getWindow() {
+        enforceSealed();
+        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+            return null;
+        }
+        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+        return client.getWindow(mConnectionId, mWindowId);
+    }
+
+    /**
      * Gets the parent.
      * <p>
      *   <strong>Note:</strong> It is a client responsibility to recycle the
@@ -931,7 +1088,8 @@
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                mWindowId, mParentNodeId, false, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+                mWindowId, mParentNodeId, false, FLAG_PREFETCH_PREDECESSORS
+                        | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
     }
 
     /**
@@ -956,7 +1114,7 @@
      * @throws IllegalStateException If called from an AccessibilityService.
      */
     public void setParent(View parent) {
-        setParent(parent, UNDEFINED);
+        setParent(parent, UNDEFINED_ITEM_ID);
     }
 
     /**
@@ -981,7 +1139,7 @@
     public void setParent(View root, int virtualDescendantId) {
         enforceNotSealed();
         final int rootAccessibilityViewId =
-            (root != null) ? root.getAccessibilityViewId() : UNDEFINED;
+            (root != null) ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
         mParentNodeId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
     }
 
@@ -1408,8 +1566,6 @@
      *   {@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();
@@ -1685,7 +1841,7 @@
      * @param labeled The view for which this info serves as a label.
      */
     public void setLabelFor(View labeled) {
-        setLabelFor(labeled, UNDEFINED);
+        setLabelFor(labeled, UNDEFINED_ITEM_ID);
     }
 
     /**
@@ -1710,7 +1866,7 @@
     public void setLabelFor(View root, int virtualDescendantId) {
         enforceNotSealed();
         final int rootAccessibilityViewId = (root != null)
-                ? root.getAccessibilityViewId() : UNDEFINED;
+                ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
         mLabelForId = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
     }
 
@@ -1732,7 +1888,8 @@
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                mWindowId, mLabelForId, false, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+                mWindowId, mLabelForId, false, FLAG_PREFETCH_PREDECESSORS
+                        | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
     }
 
     /**
@@ -1742,7 +1899,7 @@
      * @param label The view that labels this node's source.
      */
     public void setLabeledBy(View label) {
-        setLabeledBy(label, UNDEFINED);
+        setLabeledBy(label, UNDEFINED_ITEM_ID);
     }
 
     /**
@@ -1767,7 +1924,7 @@
     public void setLabeledBy(View root, int virtualDescendantId) {
         enforceNotSealed();
         final int rootAccessibilityViewId = (root != null)
-                ? root.getAccessibilityViewId() : UNDEFINED;
+                ? root.getAccessibilityViewId() : UNDEFINED_ITEM_ID;
         mLabeledById = makeNodeId(rootAccessibilityViewId, virtualDescendantId);
     }
 
@@ -1789,7 +1946,8 @@
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
         return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                mWindowId, mLabeledById, false, FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
+                mWindowId, mLabeledById, false, FLAG_PREFETCH_PREDECESSORS
+                        | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS);
     }
 
     /**
@@ -1951,6 +2109,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public int describeContents() {
         return 0;
     }
@@ -2114,6 +2273,7 @@
      *      is recycled. You must not touch the object after calling this function.
      * </p>
      */
+    @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(isSealed() ? 1 : 0);
         parcel.writeLong(mSourceNodeId);
@@ -2123,11 +2283,15 @@
         parcel.writeLong(mLabeledById);
         parcel.writeInt(mConnectionId);
 
-        SparseLongArray childIds = mChildNodeIds;
-        final int childIdsSize = childIds.size();
-        parcel.writeInt(childIdsSize);
-        for (int i = 0; i < childIdsSize; i++) {
-            parcel.writeLong(childIds.valueAt(i));
+        final LongArray childIds = mChildNodeIds;
+        if (childIds == null) {
+            parcel.writeInt(0);
+        } else {
+            final int childIdsSize = childIds.size();
+            parcel.writeInt(childIdsSize);
+            for (int i = 0; i < childIdsSize; i++) {
+                parcel.writeLong(childIds.get(i));
+            }
         }
 
         parcel.writeInt(mBoundsInParent.top);
@@ -2179,6 +2343,7 @@
             parcel.writeInt(mCollectionInfo.getRowCount());
             parcel.writeInt(mCollectionInfo.getColumnCount());
             parcel.writeInt(mCollectionInfo.isHierarchical() ? 1 : 0);
+            parcel.writeInt(mCollectionInfo.getSelectionMode());
         } else {
             parcel.writeInt(0);
         }
@@ -2190,6 +2355,7 @@
             parcel.writeInt(mCollectionItemInfo.getRowIndex());
             parcel.writeInt(mCollectionItemInfo.getRowSpan());
             parcel.writeInt(mCollectionItemInfo.isHeading() ? 1 : 0);
+            parcel.writeInt(mCollectionItemInfo.isSelected() ? 1 : 0);
         } else {
             parcel.writeInt(0);
         }
@@ -2222,10 +2388,17 @@
         mActions= other.mActions;
         mBooleanProperties = other.mBooleanProperties;
         mMovementGranularities = other.mMovementGranularities;
-        final int otherChildIdCount = other.mChildNodeIds.size();
-        for (int i = 0; i < otherChildIdCount; i++) {
-            mChildNodeIds.put(i, other.mChildNodeIds.valueAt(i));
+
+        final LongArray otherChildNodeIds = other.mChildNodeIds;
+        if (otherChildNodeIds != null && otherChildNodeIds.size() > 0) {
+            if (mChildNodeIds == null) {
+                mChildNodeIds = otherChildNodeIds.clone();
+            } else {
+                mChildNodeIds.clear();
+                mChildNodeIds.addAll(otherChildNodeIds);
+            }
         }
+
         mTextSelectionStart = other.mTextSelectionStart;
         mTextSelectionEnd = other.mTextSelectionEnd;
         mInputType = other.mInputType;
@@ -2255,11 +2428,15 @@
         mLabeledById = parcel.readLong();
         mConnectionId = parcel.readInt();
 
-        SparseLongArray childIds = mChildNodeIds;
         final int childrenSize = parcel.readInt();
-        for (int i = 0; i < childrenSize; i++) {
-            final long childId = parcel.readLong();
-            childIds.put(i, childId);
+        if (childrenSize <= 0) {
+            mChildNodeIds = null;
+        } else {
+            mChildNodeIds = new LongArray(childrenSize);
+            for (int i = 0; i < childrenSize; i++) {
+                final long childId = parcel.readLong();
+                mChildNodeIds.add(childId);
+            }
         }
 
         mBoundsInParent.top = parcel.readInt();
@@ -2306,7 +2483,8 @@
             mCollectionInfo = CollectionInfo.obtain(
                     parcel.readInt(),
                     parcel.readInt(),
-                    parcel.readInt() == 1);
+                    parcel.readInt() == 1,
+                    parcel.readInt());
         }
 
         if (parcel.readInt() == 1) {
@@ -2315,6 +2493,7 @@
                     parcel.readInt(),
                     parcel.readInt(),
                     parcel.readInt(),
+                    parcel.readInt() == 1,
                     parcel.readInt() == 1);
         }
     }
@@ -2328,10 +2507,12 @@
         mParentNodeId = ROOT_NODE_ID;
         mLabelForId = ROOT_NODE_ID;
         mLabeledById = ROOT_NODE_ID;
-        mWindowId = UNDEFINED;
-        mConnectionId = UNDEFINED;
+        mWindowId = UNDEFINED_ITEM_ID;
+        mConnectionId = UNDEFINED_CONNECTION_ID;
         mMovementGranularities = 0;
-        mChildNodeIds.clear();
+        if (mChildNodeIds != null) {
+            mChildNodeIds.clear();
+        }
         mBoundsInParent.set(0, 0, 0, 0);
         mBoundsInScreen.set(0, 0, 0, 0);
         mBooleanProperties = 0;
@@ -2341,8 +2522,8 @@
         mContentDescription = null;
         mViewIdResourceName = null;
         mActions = 0;
-        mTextSelectionStart = UNDEFINED;
-        mTextSelectionEnd = UNDEFINED;
+        mTextSelectionStart = UNDEFINED_SELECTION_INDEX;
+        mTextSelectionEnd = UNDEFINED_SELECTION_INDEX;
         mInputType = InputType.TYPE_NULL;
         mLiveRegion = View.ACCESSIBILITY_LIVE_REGION_NONE;
         if (mExtras != null) {
@@ -2435,9 +2616,9 @@
     }
 
     private boolean canPerformRequestOverConnection(long accessibilityNodeId) {
-        return (mWindowId != UNDEFINED
-                && getAccessibilityViewId(accessibilityNodeId) != UNDEFINED
-                && mConnectionId != UNDEFINED);
+        return (mWindowId != UNDEFINED_ITEM_ID
+                && getAccessibilityViewId(accessibilityNodeId) != UNDEFINED_ITEM_ID
+                && mConnectionId != UNDEFINED_CONNECTION_ID);
     }
 
     @Override
@@ -2477,6 +2658,7 @@
         builder.append(super.toString());
 
         if (DEBUG) {
+            builder.append("; sourceNodeId: " + mSourceNodeId);
             builder.append("; accessibilityViewId: " + getAccessibilityViewId(mSourceNodeId));
             builder.append("; virtualDescendantId: " + getVirtualDescendantId(mSourceNodeId));
             builder.append("; mParentNodeId: " + mParentNodeId);
@@ -2493,12 +2675,14 @@
             }
             builder.append("]");
 
-            SparseLongArray childIds = mChildNodeIds;
             builder.append("; childAccessibilityIds: [");
-            for (int i = 0, count = childIds.size(); i < count; i++) {
-                builder.append(childIds.valueAt(i));
-                if (i < count - 1) {
-                    builder.append(", ");
+            final LongArray childIds = mChildNodeIds;
+            if (childIds != null) {
+                for (int i = 0, count = childIds.size(); i < count; i++) {
+                    builder.append(childIds.get(i));
+                    if (i < count - 1) {
+                        builder.append(", ");
+                    }
                 }
             }
             builder.append("]");
@@ -2668,6 +2852,15 @@
      * </p>
      */
     public static final class CollectionInfo {
+        /** Selection mode where items are not selectable. */
+        public static final int SELECTION_MODE_NONE = 0;
+
+        /** Selection mode where a single item may be selected. */
+        public static final int SELECTION_MODE_SINGLE = 1;
+
+        /** Selection mode where multiple items may be selected. */
+        public static final int SELECTION_MODE_MULTIPLE = 2;
+
         private static final int MAX_POOL_SIZE = 20;
 
         private static final SynchronizedPool<CollectionInfo> sPool =
@@ -2676,17 +2869,17 @@
         private int mRowCount;
         private int mColumnCount;
         private boolean mHierarchical;
+        private int mSelectionMode;
 
         /**
          * 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);
+            return CollectionInfo.obtain(other.mRowCount, other.mColumnCount, other.mHierarchical,
+                    other.mSelectionMode);
         }
 
         /**
@@ -2698,9 +2891,34 @@
          */
         public static CollectionInfo obtain(int rowCount, int columnCount,
                 boolean hierarchical) {
-            CollectionInfo info = sPool.acquire();
-            return (info != null) ? info : new CollectionInfo(rowCount,
-                    columnCount, hierarchical);
+            return obtain(rowCount, columnCount, hierarchical, SELECTION_MODE_NONE);
+        }
+
+        /**
+         * Obtains a pooled instance.
+         *
+         * @param rowCount The number of rows.
+         * @param columnCount The number of columns.
+         * @param hierarchical Whether the collection is hierarchical.
+         * @param selectionMode The collection's selection mode, one of:
+         *            <ul>
+         *            <li>{@link #SELECTION_MODE_NONE}
+         *            <li>{@link #SELECTION_MODE_SINGLE}
+         *            <li>{@link #SELECTION_MODE_MULTIPLE}
+         *            </ul>
+         */
+        public static CollectionInfo obtain(int rowCount, int columnCount,
+                boolean hierarchical, int selectionMode) {
+           final CollectionInfo info = sPool.acquire();
+            if (info == null) {
+                return new CollectionInfo(rowCount, columnCount, hierarchical, selectionMode);
+            }
+
+            info.mRowCount = rowCount;
+            info.mColumnCount = columnCount;
+            info.mHierarchical = hierarchical;
+            info.mSelectionMode = selectionMode;
+            return info;
         }
 
         /**
@@ -2709,12 +2927,14 @@
          * @param rowCount The number of rows.
          * @param columnCount The number of columns.
          * @param hierarchical Whether the collection is hierarchical.
+         * @param selectionMode The collection's selection mode.
          */
-        private CollectionInfo(int rowCount, int columnCount,
-                boolean hierarchical) {
+        private CollectionInfo(int rowCount, int columnCount, boolean hierarchical,
+                int selectionMode) {
             mRowCount = rowCount;
             mColumnCount = columnCount;
             mHierarchical = hierarchical;
+            mSelectionMode = selectionMode;
         }
 
         /**
@@ -2745,6 +2965,20 @@
         }
 
         /**
+         * Gets the collection's selection mode.
+         *
+         * @return The collection's selection mode, one of:
+         *         <ul>
+         *         <li>{@link #SELECTION_MODE_NONE}
+         *         <li>{@link #SELECTION_MODE_SINGLE}
+         *         <li>{@link #SELECTION_MODE_MULTIPLE}
+         *         </ul>
+         */
+        public int getSelectionMode() {
+            return mSelectionMode;
+        }
+
+        /**
          * Recycles this instance.
          */
         void recycle() {
@@ -2756,6 +2990,7 @@
             mRowCount = 0;
             mColumnCount = 0;
             mHierarchical = false;
+            mSelectionMode = SELECTION_MODE_NONE;
         }
     }
 
@@ -2781,12 +3016,11 @@
          * 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);
+            return CollectionItemInfo.obtain(other.mRowIndex, other.mRowSpan, other.mColumnIndex,
+                    other.mColumnSpan, other.mHeading, other.mSelected);
         }
 
         /**
@@ -2800,9 +3034,34 @@
          */
         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);
+            return obtain(rowIndex, rowSpan, columnIndex, columnSpan, heading, false);
+        }
+
+        /**
+         * 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.
+         * @param selected Whether the item is selected.
+         */
+        public static CollectionItemInfo obtain(int rowIndex, int rowSpan,
+                int columnIndex, int columnSpan, boolean heading, boolean selected) {
+            final CollectionItemInfo info = sPool.acquire();
+            if (info == null) {
+                return new CollectionItemInfo(
+                        rowIndex, rowSpan, columnIndex, columnSpan, heading, selected);
+            }
+
+            info.mRowIndex = rowIndex;
+            info.mRowSpan = rowSpan;
+            info.mColumnIndex = columnIndex;
+            info.mColumnSpan = columnSpan;
+            info.mHeading = heading;
+            info.mSelected = selected;
+            return info;
         }
 
         private boolean mHeading;
@@ -2810,6 +3069,7 @@
         private int mRowIndex;
         private int mColumnSpan;
         private int mRowSpan;
+        private boolean mSelected;
 
         /**
          * Creates a new instance.
@@ -2820,13 +3080,14 @@
          * @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) {
+        private CollectionItemInfo(int rowIndex, int rowSpan, int columnIndex, int columnSpan,
+                boolean heading, boolean selected) {
             mRowIndex = rowIndex;
             mRowSpan = rowSpan;
             mColumnIndex = columnIndex;
             mColumnSpan = columnSpan;
             mHeading = heading;
+            mSelected = selected;
         }
 
         /**
@@ -2876,6 +3137,15 @@
         }
 
         /**
+         * Gets if the collection item is selected.
+         *
+         * @return If the item is selected.
+         */
+        public boolean isSelected() {
+            return mSelected;
+        }
+
+        /**
          * Recycles this instance.
          */
         void recycle() {
@@ -2889,20 +3159,23 @@
             mRowIndex = 0;
             mRowSpan = 0;
             mHeading = false;
+            mSelected = false;
         }
     }
 
     /**
-     * @see Parcelable.Creator
+     * @see android.os.Parcelable.Creator
      */
     public static final Parcelable.Creator<AccessibilityNodeInfo> CREATOR =
             new Parcelable.Creator<AccessibilityNodeInfo>() {
+        @Override
         public AccessibilityNodeInfo createFromParcel(Parcel parcel) {
             AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
             info.initFromParcel(parcel);
             return info;
         }
 
+        @Override
         public AccessibilityNodeInfo[] newArray(int size) {
             return new AccessibilityNodeInfo[size];
         }
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java b/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
deleted file mode 100644
index a9473a8..0000000
--- a/core/java/android/view/accessibility/AccessibilityNodeInfoCache.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.accessibility;
-
-import android.os.Build;
-import android.util.Log;
-import android.util.LongSparseArray;
-import android.util.SparseLongArray;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Queue;
-
-/**
- * Simple cache for AccessibilityNodeInfos. The cache is mapping an
- * accessibility id to an info. The cache allows storing of
- * <code>null</code> values. It also tracks accessibility events
- * and invalidates accordingly.
- *
- * @hide
- */
-public class AccessibilityNodeInfoCache {
-
-    private static final String LOG_TAG = AccessibilityNodeInfoCache.class.getSimpleName();
-
-    private static final boolean ENABLED = true;
-
-    private static final boolean DEBUG = false;
-
-    private static final boolean CHECK_INTEGRITY_IF_DEBUGGABLE_BUILD = true;
-
-    private final Object mLock = new Object();
-
-    private final LongSparseArray<AccessibilityNodeInfo> mCacheImpl;
-
-    private int mWindowId;
-
-    public AccessibilityNodeInfoCache() {
-        if (ENABLED) {
-            mCacheImpl = new LongSparseArray<AccessibilityNodeInfo>();
-        } else {
-            mCacheImpl = null;
-        }
-    }
-
-    /**
-     * The cache keeps track of {@link AccessibilityEvent}s and invalidates
-     * cached nodes as appropriate.
-     *
-     * @param event An event.
-     */
-    public void onAccessibilityEvent(AccessibilityEvent event) {
-        if (ENABLED) {
-            final int eventType = event.getEventType();
-            switch (eventType) {
-                case AccessibilityEvent.TYPE_TOUCH_EXPLORATION_GESTURE_END:
-                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
-                case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
-                case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: {
-                    // If the active window changes, clear the cache.
-                    final int windowId = event.getWindowId();
-                    if (mWindowId != windowId) {
-                        mWindowId = windowId;
-                        clear();
-                    }
-                } break;
-                case AccessibilityEvent.TYPE_VIEW_FOCUSED:
-                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED:
-                case AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED:
-                case AccessibilityEvent.TYPE_VIEW_SELECTED:
-                case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
-                case AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED: {
-                    refreshCachedNode(event.getSourceNodeId());
-                } break;
-                case AccessibilityEvent.TYPE_VIEW_SCROLLED: {
-                    synchronized (mLock) {
-                        clearSubTreeLocked(event.getSourceNodeId());
-                    }
-                } break;
-                case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED: {
-                    synchronized (mLock) {
-                        final long sourceId = event.getSourceNodeId();
-                        if ((event.getContentChangeTypes()
-                                & AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE) != 0) {
-                            clearSubTreeLocked(sourceId);
-                        } else {
-                            refreshCachedNode(sourceId);
-                        }
-                    }
-                } break;
-            }
-            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.
-     *
-     * @param accessibilityNodeId The info accessibility node id.
-     * @return The cached {@link AccessibilityNodeInfo} or null if such not found.
-     */
-    public AccessibilityNodeInfo get(long accessibilityNodeId) {
-        if (ENABLED) {
-            synchronized(mLock) {
-                AccessibilityNodeInfo info = mCacheImpl.get(accessibilityNodeId);
-                if (info != null) {
-                    // Return a copy since the client calls to AccessibilityNodeInfo#recycle()
-                    // will wipe the data of the cached info.
-                    info = AccessibilityNodeInfo.obtain(info);
-                }
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "get(" + accessibilityNodeId + ") = " + info);
-                }
-                return info;
-            }
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Caches an {@link AccessibilityNodeInfo} given its accessibility node id.
-     *
-     * @param info The {@link AccessibilityNodeInfo} to cache.
-     */
-    public void add(AccessibilityNodeInfo info) {
-        if (ENABLED) {
-            synchronized(mLock) {
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "add(" + info + ")");
-                }
-
-                final long sourceId = info.getSourceNodeId();
-                AccessibilityNodeInfo oldInfo = mCacheImpl.get(sourceId);
-                if (oldInfo != null) {
-                    // If the added node is in the cache we have to be careful if
-                    // the new one represents a source state where some of the
-                    // children have been removed to avoid having disconnected
-                    // subtrees in the cache.
-                    SparseLongArray oldChildrenIds = oldInfo.getChildNodeIds();
-                    SparseLongArray newChildrenIds = info.getChildNodeIds();
-                    final int oldChildCount = oldChildrenIds.size();
-                    for (int i = 0; i < oldChildCount; i++) {
-                        final long oldChildId = oldChildrenIds.valueAt(i);
-                        if (newChildrenIds.indexOfValue(oldChildId) < 0) {
-                            clearSubTreeLocked(oldChildId);
-                        }
-                    }
-
-                    // Also be careful if the parent has changed since the new
-                    // parent may be a predecessor of the old parent which will
-                    // make the cached tree cyclic.
-                    final long oldParentId = oldInfo.getParentNodeId();
-                    if (info.getParentNodeId() != oldParentId) {
-                        clearSubTreeLocked(oldParentId);
-                    }
-                }
-
-                // Cache a copy since the client calls to AccessibilityNodeInfo#recycle()
-                // will wipe the data of the cached info.
-                AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info);
-                mCacheImpl.put(sourceId, clone);
-            }
-        }
-    }
-
-    /**
-     * Clears the cache.
-     */
-    public void clear() {
-        if (ENABLED) {
-            synchronized(mLock) {
-                if (DEBUG) {
-                    Log.i(LOG_TAG, "clear()");
-                }
-                // Recycle the nodes before clearing the cache.
-                final int nodeCount = mCacheImpl.size();
-                for (int i = 0; i < nodeCount; i++) {
-                    AccessibilityNodeInfo info = mCacheImpl.valueAt(i);
-                    info.recycle();
-                }
-                mCacheImpl.clear();
-            }
-        }
-    }
-
-    /**
-     * Clears a subtree rooted at the node with the given id.
-     *
-     * @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;
-        }
-        mCacheImpl.remove(rootNodeId);
-        SparseLongArray childNodeIds = current.getChildNodeIds();
-        final int childCount = childNodeIds.size();
-        for (int i = 0; i < childCount; i++) {
-            final long childNodeId = childNodeIds.valueAt(i);
-            clearSubTreeRecursiveLocked(childNodeId);
-        }
-    }
-
-    /**
-     * Check the integrity of the cache which is it does not have nodes
-     * from more than one window, there are no duplicates, all nodes are
-     * connected, there is a single input focused node, and there is a
-     * single accessibility focused node.
-     */
-    private void checkIntegrity() {
-        synchronized (mLock) {
-            // Get the root.
-            if (mCacheImpl.size() <= 0) {
-                return;
-            }
-
-            // If the cache is a tree it does not matter from
-            // which node we start to search for the root.
-            AccessibilityNodeInfo root = mCacheImpl.valueAt(0);
-            AccessibilityNodeInfo parent = root;
-            while (parent != null) {
-                root = parent;
-                parent = mCacheImpl.get(parent.getParentNodeId());
-            }
-
-            // Traverse the tree and do some checks.
-            final int windowId = root.getWindowId();
-            AccessibilityNodeInfo accessFocus = null;
-            AccessibilityNodeInfo inputFocus = null;
-            HashSet<AccessibilityNodeInfo> seen = new HashSet<AccessibilityNodeInfo>();
-            Queue<AccessibilityNodeInfo> fringe = new LinkedList<AccessibilityNodeInfo>();
-            fringe.add(root);
-
-            while (!fringe.isEmpty()) {
-                AccessibilityNodeInfo current = fringe.poll();
-                // Check for duplicates
-                if (!seen.add(current)) {
-                    Log.e(LOG_TAG, "Duplicate node: " + current);
-                    return;
-                }
-
-                // Check for one accessibility focus.
-                if (current.isAccessibilityFocused()) {
-                    if (accessFocus != null) {
-                        Log.e(LOG_TAG, "Duplicate accessibility focus:" + current);
-                    } else {
-                        accessFocus = current;
-                    }
-                }
-
-                // Check for one input focus.
-                if (current.isFocused()) {
-                    if (inputFocus != null) {
-                        Log.e(LOG_TAG, "Duplicate input focus: " + current);
-                    } else {
-                        inputFocus = current;
-                    }
-                }
-
-                SparseLongArray childIds = current.getChildNodeIds();
-                final int childCount = childIds.size();
-                for (int i = 0; i < childCount; i++) {
-                    final long childId = childIds.valueAt(i);
-                    AccessibilityNodeInfo child = mCacheImpl.get(childId);
-                    if (child != null) {
-                        fringe.add(child);
-                    }
-                }
-            }
-
-            // Check for disconnected nodes or ones from another window.
-            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: " + info);
-                    } else {
-                        Log.e(LOG_TAG, "Node from: " + info.getWindowId() + " not from:"
-                                + windowId + " " + info);
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeProvider.java b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
index 718c32f..abcbb70 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeProvider.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeProvider.java
@@ -70,9 +70,14 @@
 public abstract class AccessibilityNodeProvider {
 
     /**
+     * The virtual id for the hosting View.
+     */
+    public static final int HOST_VIEW_ID = -1;
+
+    /**
      * Returns an {@link AccessibilityNodeInfo} representing a virtual view,
      * i.e. a descendant of the host View, with the given <code>virtualViewId</code>
-     * or the host View itself if <code>virtualViewId</code> equals to {@link View#NO_ID}.
+     * or the host View itself if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      * <p>
      * A virtual descendant is an imaginary View that is reported as a part of the view
      * hierarchy for accessibility purposes. This enables custom views that draw complex
@@ -99,7 +104,7 @@
     /**
      * Performs an accessibility action on a virtual view, i.e. a descendant of the
      * host View, with the given <code>virtualViewId</code> or the host View itself
-     * if <code>virtualViewId</code> equals to {@link View#NO_ID}.
+     * if <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      *
      * @param virtualViewId A client defined virtual view id.
      * @param action The action to perform.
@@ -117,8 +122,8 @@
     /**
      * Finds {@link AccessibilityNodeInfo}s by text. The match is case insensitive
      * containment. The search is relative to the virtual view, i.e. a descendant of the
-     * host View, with the given <code>virtualViewId</code> or the host View itself 
-     * <code>virtualViewId</code> equals to {@link View#NO_ID}.
+     * host View, with the given <code>virtualViewId</code> or the host View itself
+     * <code>virtualViewId</code> equals to {@link #HOST_VIEW_ID}.
      *
      * @param virtualViewId A client defined virtual view id which defined
      *     the root of the tree in which to perform the search.
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.aidl b/core/java/android/view/accessibility/AccessibilityRecord.aidl
new file mode 100644
index 0000000..d542af0
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityRecord.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+parcelable AccessibilityRecord;
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 3fcd218..cc6a71d 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -78,7 +78,7 @@
     private boolean mIsInPool;
 
     boolean mSealed;
-    int mBooleanProperties = PROPERTY_IMPORTANT_FOR_ACCESSIBILITY;
+    int mBooleanProperties = 0;
     int mCurrentItemIndex = UNDEFINED;
     int mItemCount = UNDEFINED;
     int mFromIndex = UNDEFINED;
@@ -791,7 +791,7 @@
      */
     void clear() {
         mSealed = false;
-        mBooleanProperties = PROPERTY_IMPORTANT_FOR_ACCESSIBILITY;
+        mBooleanProperties = 0;
         mCurrentItemIndex = UNDEFINED;
         mItemCount = UNDEFINED;
         mFromIndex = UNDEFINED;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl b/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
new file mode 100644
index 0000000..fdb25fb
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+parcelable AccessibilityWindowInfo;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
new file mode 100644
index 0000000..80b5c50
--- /dev/null
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -0,0 +1,574 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.accessibility;
+
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.LongArray;
+import android.util.Pools.SynchronizedPool;
+
+/**
+ * This class represents a state snapshot of a window for accessibility
+ * purposes. The screen content contains one or more windows where some
+ * windows can be descendants of other windows, which is the windows are
+ * hierarchically ordered. Note that there is no root window. Hence, the
+ * screen content can be seen as a collection of window trees.
+ */
+public final class AccessibilityWindowInfo implements Parcelable {
+
+    private static final boolean DEBUG = false;
+
+    /**
+     * Window type: This is an application window. Such a window shows UI for
+     * interacting with an application.
+     */
+    public static final int TYPE_APPLICATION = 1;
+
+    /**
+     * Window type: This is an input method window. Such a window shows UI for
+     * inputting text such as keyboard, suggestions, etc.
+     */
+    public static final int TYPE_INPUT_METHOD = 2;
+
+    /**
+     * Window type: This is an system window. Such a window shows UI for
+     * interacting with the system.
+     */
+    public static final int TYPE_SYSTEM = 3;
+
+    private static final int UNDEFINED = -1;
+
+    private static final int BOOLEAN_PROPERTY_ACTIVE = 1 << 0;
+    private static final int BOOLEAN_PROPERTY_FOCUSED = 1 << 1;
+
+    // Housekeeping.
+    private static final int MAX_POOL_SIZE = 10;
+    private static final SynchronizedPool<AccessibilityWindowInfo> sPool =
+            new SynchronizedPool<AccessibilityWindowInfo>(MAX_POOL_SIZE);
+
+    // Data.
+    private int mType = UNDEFINED;
+    private int mLayer = UNDEFINED;
+    private int mBooleanProperties;
+    private int mId = UNDEFINED;
+    private int mParentId = UNDEFINED;
+    private final Rect mBoundsInScreen = new Rect();
+    private LongArray mChildIds;
+
+    private int mConnectionId = UNDEFINED;
+
+    private AccessibilityWindowInfo() {
+        /* do nothing - hide constructor */
+    }
+
+    /**
+     * Gets the type of the window.
+     *
+     * @return The type.
+     *
+     * @see #TYPE_APPLICATION
+     * @see #TYPE_INPUT_METHOD
+     * @see #TYPE_SYSTEM
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Sets the type of the window.
+     *
+     * @param The type
+     *
+     * @hide
+     */
+    public void setType(int type) {
+        mType = type;
+    }
+
+    /**
+     * Gets the layer which determines the Z-order of the window. Windows
+     * with greater layer appear on top of windows with lesser layer.
+     *
+     * @return The window layer.
+     */
+    public int getLayer() {
+        return mLayer;
+    }
+
+    /**
+     * Sets the layer which determines the Z-order of the window. Windows
+     * with greater layer appear on top of windows with lesser layer.
+     *
+     * @param The window layer.
+     *
+     * @hide
+     */
+    public void setLayer(int layer) {
+        mLayer = layer;
+    }
+
+    /**
+     * Gets the root node in the window's hierarchy.
+     *
+     * @return The root node.
+     */
+    public AccessibilityNodeInfo getRoot() {
+        if (mConnectionId == UNDEFINED) {
+            return null;
+        }
+        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
+                mId, AccessibilityNodeInfo.ROOT_NODE_ID,
+                true, AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS);
+    }
+
+    /**
+     * Gets the parent window if such.
+     *
+     * @return The parent window.
+     */
+    public AccessibilityWindowInfo getParent() {
+        if (mConnectionId == UNDEFINED || mParentId == UNDEFINED) {
+            return null;
+        }
+        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+        return client.getWindow(mConnectionId, mParentId);
+    }
+
+    /**
+     * Sets the parent window id.
+     *
+     * @param parentId The parent id.
+     *
+     * @hide
+     */
+    public void setParentId(int parentId) {
+        mParentId = parentId;
+    }
+
+    /**
+     * Gets the unique window id.
+     *
+     * @return windowId The window id.
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Sets the unique window id.
+     *
+     * @param windowId The window id.
+     *
+     * @hide
+     */
+    public void setId(int id) {
+        mId = id;
+    }
+
+    /**
+     * Sets the unique id of the IAccessibilityServiceConnection over which
+     * this instance can send requests to the system.
+     *
+     * @param connectionId The connection id.
+     *
+     * @hide
+     */
+    public void setConnectionId(int connectionId) {
+        mConnectionId = connectionId;
+    }
+
+    /**
+     * Gets the bounds of this window in the screen.
+     *
+     * @param outBounds The out window bounds.
+     */
+    public void getBoundsInScreen(Rect outBounds) {
+        outBounds.set(mBoundsInScreen);
+    }
+
+    /**
+     * Sets the bounds of this window in the screen.
+     *
+     * @param bounds The out window bounds.
+     *
+     * @hide
+     */
+    public void setBoundsInScreen(Rect bounds) {
+        mBoundsInScreen.set(bounds);
+    }
+
+    /**
+     * Gets if this window is active. An active window is the one
+     * the user is currently touching or the window has input focus
+     * and the user is not touching any window.
+     *
+     * @return Whether this is the active window.
+     */
+    public boolean isActive() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_ACTIVE);
+    }
+
+    /**
+     * Sets if this window is active, which is this is the window
+     * the user is currently touching or the window has input focus
+     * and the user is not touching any window.
+     *
+     * @param Whether this is the active window.
+     *
+     * @hide
+     */
+    public void setActive(boolean active) {
+        setBooleanProperty(BOOLEAN_PROPERTY_ACTIVE, active);
+    }
+
+    /**
+     * Gets if this window has input focus.
+     *
+     * @return Whether has input focus.
+     */
+    public boolean isFocused() {
+        return getBooleanProperty(BOOLEAN_PROPERTY_FOCUSED);
+    }
+
+    /**
+     * Sets if this window has input focus.
+     *
+     * @param Whether has input focus.
+     *
+     * @hide
+     */
+    public void setFocused(boolean focused) {
+        setBooleanProperty(BOOLEAN_PROPERTY_FOCUSED, focused);
+    }
+
+    /**
+     * Gets the number of child windows.
+     *
+     * @return The child count.
+     */
+    public int getChildCount() {
+        return (mChildIds != null) ? mChildIds.size() : 0;
+    }
+
+    /**
+     * Gets the child window at a given index.
+     *
+     * @param index The index.
+     * @return The child.
+     */
+    public AccessibilityWindowInfo getChild(int index) {
+        if (mChildIds == null) {
+            throw new IndexOutOfBoundsException();
+        }
+        if (mConnectionId == UNDEFINED) {
+            return null;
+        }
+        final int childId = (int) mChildIds.get(index);
+        AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
+        return client.getWindow(mConnectionId, childId);
+    }
+
+    /**
+     * Adds a child window.
+     *
+     * @param childId The child window id.
+     *
+     * @hide
+     */
+    public void addChild(int childId) {
+        if (mChildIds == null) {
+            mChildIds = new LongArray();
+        }
+        mChildIds.add(childId);
+    }
+
+    /**
+     * Returns a cached instance if such is available or a new one is
+     * created.
+     *
+     * @return An instance.
+     */
+    public static AccessibilityWindowInfo obtain() {
+        AccessibilityWindowInfo info = sPool.acquire();
+        if (info == null) {
+            info = new AccessibilityWindowInfo();
+        }
+        return info;
+    }
+
+    /**
+     * Returns a cached instance if such is available or a new one is
+     * created. The returned instance is initialized from the given
+     * <code>info</code>.
+     *
+     * @param info The other info.
+     * @return An instance.
+     */
+    public static AccessibilityWindowInfo obtain(AccessibilityWindowInfo info) {
+        AccessibilityWindowInfo infoClone = obtain();
+
+        infoClone.mType = info.mType;
+        infoClone.mLayer = info.mLayer;
+        infoClone.mBooleanProperties = info.mBooleanProperties;
+        infoClone.mId = info.mId;
+        infoClone.mParentId = info.mParentId;
+        infoClone.mBoundsInScreen.set(info.mBoundsInScreen);
+
+        if (info.mChildIds != null && info.mChildIds.size() > 0) {
+            if (infoClone.mChildIds == null) {
+                infoClone.mChildIds = info.mChildIds.clone();
+            } else {
+                infoClone.mChildIds.addAll(info.mChildIds);
+            }
+        }
+
+        infoClone.mConnectionId = info.mConnectionId;
+
+        return infoClone;
+    }
+
+    /**
+     * Return an instance back to be reused.
+     * <p>
+     * <strong>Note:</strong> You must not touch the object after calling this function.
+     * </p>
+     *
+     * @throws IllegalStateException If the info is already recycled.
+     */
+    public void recycle() {
+        clear();
+        sPool.release(this);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(mType);
+        parcel.writeInt(mLayer);
+        parcel.writeInt(mBooleanProperties);
+        parcel.writeInt(mId);
+        parcel.writeInt(mParentId);
+        mBoundsInScreen.writeToParcel(parcel, flags);
+
+        final LongArray childIds = mChildIds;
+        if (childIds == null) {
+            parcel.writeInt(0);
+        } else {
+            final int childCount = childIds.size();
+            parcel.writeInt(childCount);
+            for (int i = 0; i < childCount; i++) {
+                parcel.writeInt((int) childIds.get(i));
+            }
+        }
+
+        parcel.writeInt(mConnectionId);
+    }
+
+    private void initFromParcel(Parcel parcel) {
+        mType = parcel.readInt();
+        mLayer = parcel.readInt();
+        mBooleanProperties = parcel.readInt();
+        mId = parcel.readInt();
+        mParentId = parcel.readInt();
+        mBoundsInScreen.readFromParcel(parcel);
+
+        final int childCount = parcel.readInt();
+        if (childCount > 0) {
+            if (mChildIds == null) {
+                mChildIds = new LongArray(childCount);
+            }
+            for (int i = 0; i < childCount; i++) {
+                final int childId = parcel.readInt();
+                mChildIds.add(childId);
+            }
+        }
+
+        mConnectionId = parcel.readInt();
+    }
+
+    @Override
+    public int hashCode() {
+        return mId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        AccessibilityWindowInfo other = (AccessibilityWindowInfo) obj;
+        return (mId == other.mId);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append("AccessibilityWindowInfo[");
+        builder.append("id=").append(mId);
+        builder.append(", type=").append(typeToString(mType));
+        builder.append(", layer=").append(mLayer);
+        builder.append(", bounds=").append(mBoundsInScreen);
+        builder.append(", focused=").append(isFocused());
+        builder.append(", active=").append(isActive());
+        if (DEBUG) {
+            builder.append(", parent=").append(mParentId);
+            builder.append(", children=[");
+            if (mChildIds != null) {
+                final int childCount = mChildIds.size();
+                for (int i = 0; i < childCount; i++) {
+                    builder.append(mChildIds.get(i));
+                    if (i < childCount - 1) {
+                        builder.append(',');
+                    }
+                }
+            } else {
+                builder.append("null");
+            }
+            builder.append(']');
+        } else {
+            builder.append(", hasParent=").append(mParentId != UNDEFINED);
+            builder.append(", hasChildren=").append(mChildIds != null
+                    && mChildIds.size() > 0);
+        }
+        builder.append(']');
+        return builder.toString();
+    }
+
+    /**
+     * Clears the internal state.
+     */
+    private void clear() {
+        mType = UNDEFINED;
+        mLayer = UNDEFINED;
+        mBooleanProperties = 0;
+        mId = UNDEFINED;
+        mParentId = UNDEFINED;
+        mBoundsInScreen.setEmpty();
+        if (mChildIds != null) {
+            mChildIds.clear();
+        }
+        mConnectionId = UNDEFINED;
+    }
+
+    /**
+     * Gets the value of a boolean property.
+     *
+     * @param property The property.
+     * @return The value.
+     */
+    private boolean getBooleanProperty(int property) {
+        return (mBooleanProperties & property) != 0;
+    }
+
+    /**
+     * Sets a boolean property.
+     *
+     * @param property The property.
+     * @param value The value.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    private void setBooleanProperty(int property, boolean value) {
+        if (value) {
+            mBooleanProperties |= property;
+        } else {
+            mBooleanProperties &= ~property;
+        }
+    }
+
+    private static String typeToString(int type) {
+        switch (type) {
+            case TYPE_APPLICATION: {
+                return "TYPE_APPLICATION";
+            }
+            case TYPE_INPUT_METHOD: {
+                return "TYPE_INPUT_METHOD";
+            }
+            case TYPE_SYSTEM: {
+                return "TYPE_SYSTEM";
+            }
+            default:
+                return "<UNKNOWN>";
+        }
+    }
+
+    /**
+     * Checks whether this window changed. The argument should be
+     * another state of the same window, which is have the same id
+     * and type as they never change.
+     *
+     * @param other The new state.
+     * @return Whether something changed.
+     *
+     * @hide
+     */
+    public boolean changed(AccessibilityWindowInfo other) {
+        if (other.mId != mId) {
+            throw new IllegalArgumentException("Not same window.");
+        }
+        if (other.mType != mType) {
+            throw new IllegalArgumentException("Not same type.");
+        }
+        if (!mBoundsInScreen.equals(mBoundsInScreen)) {
+            return true;
+        }
+        if (mLayer != other.mLayer) {
+            return true;
+        }
+        if (mBooleanProperties != other.mBooleanProperties) {
+            return true;
+        }
+        if (mParentId != other.mParentId) {
+            return true;
+        }
+        if (mChildIds == null) {
+            if (other.mChildIds != null) {
+                return true;
+            }
+        } else if (!mChildIds.equals(other.mChildIds)) {
+            return true;
+        }
+        return false;
+    }
+
+    public static final Parcelable.Creator<AccessibilityWindowInfo> CREATOR =
+            new Creator<AccessibilityWindowInfo>() {
+        @Override
+        public AccessibilityWindowInfo createFromParcel(Parcel parcel) {
+            AccessibilityWindowInfo info = obtain();
+            info.initFromParcel(parcel);
+            return info;
+        }
+
+        @Override
+        public AccessibilityWindowInfo[] newArray(int size) {
+            return new AccessibilityWindowInfo[size];
+        }
+    };
+}
diff --git a/core/java/android/view/accessibility/CaptioningManager.java b/core/java/android/view/accessibility/CaptioningManager.java
index 557239f..a0134d6 100644
--- a/core/java/android/view/accessibility/CaptioningManager.java
+++ b/core/java/android/view/accessibility/CaptioningManager.java
@@ -250,6 +250,9 @@
      * background colors, edge properties, and typeface.
      */
     public static final class CaptionStyle {
+        /** Packed value for a color of 'none' and a cached opacity of 100%. */
+        private static final int COLOR_NONE_OPAQUE = 0x000000FF;
+
         private static final CaptionStyle WHITE_ON_BLACK;
         private static final CaptionStyle BLACK_ON_WHITE;
         private static final CaptionStyle YELLOW_ON_BLACK;
@@ -271,6 +274,12 @@
         /** Edge type value specifying drop-shadowed character edges. */
         public static final int EDGE_TYPE_DROP_SHADOW = 2;
 
+        /** Edge type value specifying raised bevel character edges. */
+        public static final int EDGE_TYPE_RAISED = 3;
+
+        /** Edge type value specifying depressed bevel character edges. */
+        public static final int EDGE_TYPE_DEPRESSED = 4;
+
         /** The preferred foreground color for video captions. */
         public final int foregroundColor;
 
@@ -283,6 +292,8 @@
          * <li>{@link #EDGE_TYPE_NONE}
          * <li>{@link #EDGE_TYPE_OUTLINE}
          * <li>{@link #EDGE_TYPE_DROP_SHADOW}
+         * <li>{@link #EDGE_TYPE_RAISED}
+         * <li>{@link #EDGE_TYPE_DEPRESSED}
          * </ul>
          */
         public final int edgeType;
@@ -293,6 +304,9 @@
          */
         public final int edgeColor;
 
+        /** The preferred window color for video captions. */
+        public final int windowColor;
+
         /**
          * @hide
          */
@@ -301,11 +315,12 @@
         private Typeface mParsedTypeface;
 
         private CaptionStyle(int foregroundColor, int backgroundColor, int edgeType, int edgeColor,
-                String rawTypeface) {
+                int windowColor, String rawTypeface) {
             this.foregroundColor = foregroundColor;
             this.backgroundColor = backgroundColor;
             this.edgeType = edgeType;
             this.edgeColor = edgeColor;
+            this.windowColor = windowColor;
 
             mRawTypeface = rawTypeface;
         }
@@ -334,25 +349,27 @@
                     cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE, defStyle.edgeType);
             final int edgeColor = Secure.getInt(
                     cr, Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR, defStyle.edgeColor);
+            final int windowColor = Secure.getInt(
+                    cr, Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR, defStyle.windowColor);
 
             String rawTypeface = Secure.getString(cr, Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE);
             if (rawTypeface == null) {
                 rawTypeface = defStyle.mRawTypeface;
             }
 
-            return new CaptionStyle(
-                    foregroundColor, backgroundColor, edgeType, edgeColor, rawTypeface);
+            return new CaptionStyle(foregroundColor, backgroundColor, edgeType, edgeColor,
+                    windowColor, 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);
+            WHITE_ON_BLACK = new CaptionStyle(Color.WHITE, Color.BLACK, EDGE_TYPE_NONE,
+                    Color.BLACK, COLOR_NONE_OPAQUE, null);
+            BLACK_ON_WHITE = new CaptionStyle(Color.BLACK, Color.WHITE, EDGE_TYPE_NONE,
+                    Color.BLACK, COLOR_NONE_OPAQUE, null);
+            YELLOW_ON_BLACK = new CaptionStyle(Color.YELLOW, Color.BLACK, EDGE_TYPE_NONE,
+                    Color.BLACK, COLOR_NONE_OPAQUE, null);
+            YELLOW_ON_BLUE = new CaptionStyle(Color.YELLOW, Color.BLUE, EDGE_TYPE_NONE,
+                    Color.BLACK, COLOR_NONE_OPAQUE, null);
 
             PRESETS = new CaptionStyle[] {
                     WHITE_ON_BLACK, BLACK_ON_WHITE, YELLOW_ON_BLACK, YELLOW_ON_BLUE
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java
index 38043b2..1d1fa1e 100644
--- a/core/java/android/view/animation/AnimationUtils.java
+++ b/core/java/android/view/animation/AnimationUtils.java
@@ -324,6 +324,8 @@
                 interpolator = new AnticipateOvershootInterpolator(c, attrs);
             } else if (name.equals("bounceInterpolator")) {
                 interpolator = new BounceInterpolator(c, attrs);
+            } else if (name.equals("pathInterpolator")) {
+                interpolator = new PathInterpolator(c, attrs);
             } else {
                 throw new RuntimeException("Unknown interpolator name: " + parser.getName());
             }
diff --git a/core/java/android/view/animation/BounceInterpolator.java b/core/java/android/view/animation/BounceInterpolator.java
index f79e730..ecf99a7 100644
--- a/core/java/android/view/animation/BounceInterpolator.java
+++ b/core/java/android/view/animation/BounceInterpolator.java
@@ -17,7 +17,6 @@
 package android.view.animation;
 
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.util.AttributeSet;
 
 /**
diff --git a/core/java/android/view/animation/ClipRectAnimation.java b/core/java/android/view/animation/ClipRectAnimation.java
new file mode 100644
index 0000000..2361501
--- /dev/null
+++ b/core/java/android/view/animation/ClipRectAnimation.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.animation;
+
+import android.graphics.Rect;
+
+/**
+ * An animation that controls the clip of an object. See the
+ * {@link android.view.animation full package} description for details and
+ * sample code.
+ *
+ * @hide
+ */
+public class ClipRectAnimation extends Animation {
+    private Rect mFromRect = new Rect();
+    private Rect mToRect = new Rect();
+
+    /**
+     * Constructor to use when building a ClipRectAnimation from code
+     *
+     * @param fromClip the clip rect to animate from
+     * @param toClip the clip rect to animate to
+     */
+    public ClipRectAnimation(Rect fromClip, Rect toClip) {
+        if (fromClip == null || toClip == null) {
+            throw new RuntimeException("Expected non-null animation clip rects");
+        }
+        mFromRect.set(fromClip);
+        mToRect.set(toClip);
+    }
+
+    @Override
+    protected void applyTransformation(float it, Transformation tr) {
+        int l = mFromRect.left + (int) ((mToRect.left - mFromRect.left) * it);
+        int t = mFromRect.top + (int) ((mToRect.top - mFromRect.top) * it);
+        int r = mFromRect.right + (int) ((mToRect.right - mFromRect.right) * it);
+        int b = mFromRect.bottom + (int) ((mToRect.bottom - mFromRect.bottom) * it);
+        tr.setClipRect(l, t, r, b);
+    }
+
+    @Override
+    public boolean willChangeTransformationMatrix() {
+        return false;
+    }
+}
diff --git a/core/java/android/view/animation/PathInterpolator.java b/core/java/android/view/animation/PathInterpolator.java
new file mode 100644
index 0000000..a369509
--- /dev/null
+++ b/core/java/android/view/animation/PathInterpolator.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.animation;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.view.InflateException;
+
+/**
+ * An interpolator that can traverse a Path that extends from <code>Point</code>
+ * <code>(0, 0)</code> to <code>(1, 1)</code>. The x coordinate along the <code>Path</code>
+ * is the input value and the output is the y coordinate of the line at that point.
+ * This means that the Path must conform to a function <code>y = f(x)</code>.
+ *
+ * <p>The <code>Path</code> must not have gaps in the x direction and must not
+ * loop back on itself such that there can be two points sharing the same x coordinate.
+ * It is alright to have a disjoint line in the vertical direction:</p>
+ * <p><blockquote><pre>
+ *     Path path = new Path();
+ *     path.lineTo(0.25f, 0.25f);
+ *     path.moveTo(0.25f, 0.5f);
+ *     path.lineTo(1f, 1f);
+ * </pre></blockquote></p>
+ */
+public class PathInterpolator implements Interpolator {
+
+    // This governs how accurate the approximation of the Path is.
+    private static final float PRECISION = 0.002f;
+
+    private float[] mX; // x coordinates in the line
+
+    private float[] mY; // y coordinates in the line
+
+    /**
+     * Create an interpolator for an arbitrary <code>Path</code>. The <code>Path</code>
+     * must begin at <code>(0, 0)</code> and end at <code>(1, 1)</code>.
+     *
+     * @param path The <code>Path</code> to use to make the line representing the interpolator.
+     */
+    public PathInterpolator(Path path) {
+        initPath(path);
+    }
+
+    /**
+     * Create an interpolator for a quadratic Bezier curve. The end points
+     * <code>(0, 0)</code> and <code>(1, 1)</code> are assumed.
+     *
+     * @param controlX The x coordinate of the quadratic Bezier control point.
+     * @param controlY The y coordinate of the quadratic Bezier control point.
+     */
+    public PathInterpolator(float controlX, float controlY) {
+        initQuad(controlX, controlY);
+    }
+
+    /**
+     * Create an interpolator for a cubic Bezier curve.  The end points
+     * <code>(0, 0)</code> and <code>(1, 1)</code> are assumed.
+     *
+     * @param controlX1 The x coordinate of the first control point of the cubic Bezier.
+     * @param controlY1 The y coordinate of the first control point of the cubic Bezier.
+     * @param controlX2 The x coordinate of the second control point of the cubic Bezier.
+     * @param controlY2 The y coordinate of the second control point of the cubic Bezier.
+     */
+    public PathInterpolator(float controlX1, float controlY1, float controlX2, float controlY2) {
+        initCubic(controlX1, controlY1, controlX2, controlY2);
+    }
+
+    public PathInterpolator(Context context, AttributeSet attrs) {
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.PathInterpolator);
+        if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX1)) {
+            throw new InflateException("pathInterpolator requires the controlX1 attribute");
+        } else if (!a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY1)) {
+            throw new InflateException("pathInterpolator requires the controlY1 attribute");
+        }
+        float x1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX1, 0);
+        float y1 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY1, 0);
+
+        boolean hasX2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlX2);
+        boolean hasY2 = a.hasValue(com.android.internal.R.styleable.PathInterpolator_controlY2);
+
+        if (hasX2 != hasY2) {
+            throw new InflateException(
+                    "pathInterpolator requires both controlX2 and controlY2 for cubic Beziers.");
+        }
+
+        if (!hasX2) {
+            initQuad(x1, y1);
+        } else {
+            float x2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlX2, 0);
+            float y2 = a.getFloat(com.android.internal.R.styleable.PathInterpolator_controlY2, 0);
+            initCubic(x1, y1, x2, y2);
+        }
+
+        a.recycle();
+    }
+
+    private void initQuad(float controlX, float controlY) {
+        Path path = new Path();
+        path.moveTo(0, 0);
+        path.quadTo(controlX, controlY, 1f, 1f);
+        initPath(path);
+    }
+
+    private void initCubic(float x1, float y1, float x2, float y2) {
+        Path path = new Path();
+        path.moveTo(0, 0);
+        path.cubicTo(x1, y1, x2, y2, 1f, 1f);
+        initPath(path);
+    }
+
+    private void initPath(Path path) {
+        float[] pointComponents = path.approximate(PRECISION);
+
+        int numPoints = pointComponents.length / 3;
+        if (pointComponents[1] != 0 || pointComponents[2] != 0
+                || pointComponents[pointComponents.length - 2] != 1
+                || pointComponents[pointComponents.length - 1] != 1) {
+            throw new IllegalArgumentException("The Path must start at (0,0) and end at (1,1)");
+        }
+
+        mX = new float[numPoints];
+        mY = new float[numPoints];
+        float prevX = 0;
+        float prevFraction = 0;
+        int componentIndex = 0;
+        for (int i = 0; i < numPoints; i++) {
+            float fraction = pointComponents[componentIndex++];
+            float x = pointComponents[componentIndex++];
+            float y = pointComponents[componentIndex++];
+            if (fraction == prevFraction && x != prevX) {
+                throw new IllegalArgumentException(
+                        "The Path cannot have discontinuity in the X axis.");
+            }
+            if (x < prevX) {
+                throw new IllegalArgumentException("The Path cannot loop back on itself.");
+            }
+            mX[i] = x;
+            mY[i] = y;
+            prevX = x;
+            prevFraction = fraction;
+        }
+    }
+
+    /**
+     * Using the line in the Path in this interpolator that can be described as
+     * <code>y = f(x)</code>, finds the y coordinate of the line given <code>t</code>
+     * as the x coordinate. Values less than 0 will always return 0 and values greater
+     * than 1 will always return 1.
+     *
+     * @param t Treated as the x coordinate along the line.
+     * @return The y coordinate of the Path along the line where x = <code>t</code>.
+     * @see Interpolator#getInterpolation(float)
+     */
+    @Override
+    public float getInterpolation(float t) {
+        if (t <= 0) {
+            return 0;
+        } else if (t >= 1) {
+            return 1;
+        }
+        // Do a binary search for the correct x to interpolate between.
+        int startIndex = 0;
+        int endIndex = mX.length - 1;
+
+        while (endIndex - startIndex > 1) {
+            int midIndex = (startIndex + endIndex) / 2;
+            if (t < mX[midIndex]) {
+                endIndex = midIndex;
+            } else {
+                startIndex = midIndex;
+            }
+        }
+
+        float xRange = mX[endIndex] - mX[startIndex];
+        if (xRange == 0) {
+            return mY[startIndex];
+        }
+
+        float tInRange = t - mX[startIndex];
+        float fraction = tInRange / xRange;
+
+        float startY = mY[startIndex];
+        float endY = mY[endIndex];
+        return startY + (fraction * (endY - startY));
+    }
+
+}
diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java
index 890909b..2f4fe73 100644
--- a/core/java/android/view/animation/Transformation.java
+++ b/core/java/android/view/animation/Transformation.java
@@ -17,6 +17,7 @@
 package android.view.animation;
 
 import android.graphics.Matrix;
+import android.graphics.Rect;
 
 import java.io.PrintWriter;
 
@@ -47,6 +48,9 @@
     protected float mAlpha;
     protected int mTransformationType;
 
+    private boolean mHasClipRect;
+    private Rect mClipRect = new Rect();
+
     /**
      * Creates a new transformation with alpha = 1 and the identity matrix.
      */
@@ -65,6 +69,8 @@
         } else {
             mMatrix.reset();
         }
+        mClipRect.setEmpty();
+        mHasClipRect = false;
         mAlpha = 1.0f;
         mTransformationType = TYPE_BOTH;
     }
@@ -98,9 +104,15 @@
     public void set(Transformation t) {
         mAlpha = t.getAlpha();
         mMatrix.set(t.getMatrix());
+        if (t.mHasClipRect) {
+            setClipRect(t.getClipRect());
+        } else {
+            mHasClipRect = false;
+            mClipRect.setEmpty();
+        }
         mTransformationType = t.getTransformationType();
     }
-    
+
     /**
      * Apply this Transformation to an existing Transformation, e.g. apply
      * a scale effect to something that has already been rotated.
@@ -109,6 +121,9 @@
     public void compose(Transformation t) {
         mAlpha *= t.getAlpha();
         mMatrix.preConcat(t.getMatrix());
+        if (t.mHasClipRect) {
+            setClipRect(t.getClipRect());
+        }
     }
     
     /**
@@ -119,6 +134,9 @@
     public void postCompose(Transformation t) {
         mAlpha *= t.getAlpha();
         mMatrix.postConcat(t.getMatrix());
+        if (t.mHasClipRect) {
+            setClipRect(t.getClipRect());
+        }
     }
 
     /**
@@ -138,6 +156,39 @@
     }
 
     /**
+     * Sets the current Transform's clip rect
+     * @hide
+     */
+    public void setClipRect(Rect r) {
+        setClipRect(r.left, r.top, r.right, r.bottom);
+    }
+
+    /**
+     * Sets the current Transform's clip rect
+     * @hide
+     */
+    public void setClipRect(int l, int t, int r, int b) {
+        mClipRect.set(l, t, r, b);
+        mHasClipRect = true;
+    }
+
+    /**
+     * Returns the current Transform's clip rect
+     * @hide
+     */
+    public Rect getClipRect() {
+        return mClipRect;
+    }
+
+    /**
+     * Returns whether the current Transform's clip rect is set
+     * @hide
+     */
+    public boolean hasClipRect() {
+        return mHasClipRect;
+    }
+
+    /**
      * @return The degree of transparency
      */
     public float getAlpha() {
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index f730cf7..cccfa78 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -484,10 +484,10 @@
         final Editable content = getEditable();
         if (content == null) return false;
         int len = content.length();
-        if (start > len || end > len) {
+        if (start > len || end > len || start < 0 || end < 0) {
             // If the given selection is out of bounds, just ignore it.
             // Most likely the text was changed out from under the IME,
-            // the the IME is going to have to update all of its state
+            // and the IME is going to have to update all of its state
             // anyway.
             return true;
         }
@@ -601,7 +601,11 @@
         }
         
         beginBatchEdit();
-        
+        if (!composing && !TextUtils.isEmpty(text)) {
+            // Notify the text is committed by the user to InputMethodManagerService
+            mIMM.notifyTextCommitted();
+        }
+
         // delete composing text set previously.
         int a = getComposingSpanStart(content);
         int b = getComposingSpanEnd(content);
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index d4e005b..c0395cf 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -26,13 +26,13 @@
 /**
  * An EditorInfo describes several attributes of a text editing object
  * that an input method is communicating with (typically an EditText), most
- * importantly the type of text content it contains.
+ * importantly the type of text content it contains and the current cursor position.
  */
 public class EditorInfo implements InputType, Parcelable {
     /**
      * The content type of the text box, whose bits are defined by
      * {@link InputType}.
-     * 
+     *
      * @see InputType
      * @see #TYPE_MASK_CLASS
      * @see #TYPE_MASK_VARIATION
@@ -47,55 +47,55 @@
      * to provide alternative mechanisms for providing that command.
      */
     public static final int IME_MASK_ACTION = 0x000000ff;
-    
+
     /**
      * Bits of {@link #IME_MASK_ACTION}: no specific action has been
      * associated with this editor, let the editor come up with its own if
      * it can.
      */
     public static final int IME_ACTION_UNSPECIFIED = 0x00000000;
-    
+
     /**
      * Bits of {@link #IME_MASK_ACTION}: there is no available action.
      */
     public static final int IME_ACTION_NONE = 0x00000001;
-    
+
     /**
      * Bits of {@link #IME_MASK_ACTION}: the action key performs a "go"
      * operation to take the user to the target of the text they typed.
      * Typically used, for example, when entering a URL.
      */
     public static final int IME_ACTION_GO = 0x00000002;
-    
+
     /**
      * Bits of {@link #IME_MASK_ACTION}: the action key performs a "search"
      * operation, taking the user to the results of searching for the text
      * they have typed (in whatever context is appropriate).
      */
     public static final int IME_ACTION_SEARCH = 0x00000003;
-    
+
     /**
      * Bits of {@link #IME_MASK_ACTION}: the action key performs a "send"
      * operation, delivering the text to its target.  This is typically used
      * when composing a message in IM or SMS where sending is immediate.
      */
     public static final int IME_ACTION_SEND = 0x00000004;
-    
+
     /**
      * Bits of {@link #IME_MASK_ACTION}: the action key performs a "next"
      * operation, taking the user to the next field that will accept text.
      */
     public static final int IME_ACTION_NEXT = 0x00000005;
-    
+
     /**
      * Bits of {@link #IME_MASK_ACTION}: the action key performs a "done"
      * operation, typically meaning there is nothing more to input and the
      * IME will be closed.
      */
     public static final int IME_ACTION_DONE = 0x00000006;
-    
+
     /**
-     * Bits of {@link #IME_MASK_ACTION}: Like {@link #IME_ACTION_NEXT}, but
+     * Bits of {@link #IME_MASK_ACTION}: like {@link #IME_ACTION_NEXT}, but
      * for moving to the previous field.  This will normally not be used to
      * specify an action (since it precludes {@link #IME_ACTION_NEXT}), but
      * can be returned to the app if it sets {@link #IME_FLAG_NAVIGATE_PREVIOUS}.
@@ -154,7 +154,7 @@
      * on older versions of the platform.
      */
     public static final int IME_FLAG_NO_EXTRACT_UI = 0x10000000;
-    
+
     /**
      * Flag of {@link #imeOptions}: used in conjunction with one of the actions
      * masked by {@link #IME_MASK_ACTION}, this indicates that the action
@@ -167,7 +167,7 @@
      * to show more text.
      */
     public static final int IME_FLAG_NO_ACCESSORY_ACTION = 0x20000000;
-    
+
     /**
      * Flag of {@link #imeOptions}: used in conjunction with one of the actions
      * masked by {@link #IME_MASK_ACTION}. If this flag is not set, IMEs will
@@ -202,13 +202,13 @@
      * Generic unspecified type for {@link #imeOptions}.
      */
     public static final int IME_NULL = 0x00000000;
-    
+
     /**
      * Extended type information for the editor, to help the IME better
      * integrate with it.
      */
     public int imeOptions = IME_NULL;
-    
+
     /**
      * A string supplying additional information options that are
      * private to a particular IME implementation.  The string must be
@@ -221,7 +221,7 @@
      * attribute of a TextView.
      */
     public String privateImeOptions = null;
-    
+
     /**
      * In some cases an IME may be able to display an arbitrary label for
      * a command the user can perform, which you can specify here. This is
@@ -233,7 +233,7 @@
      * ignore this.
      */
     public CharSequence actionLabel = null;
-    
+
     /**
      * If {@link #actionLabel} has been given, this is the id for that command
      * when the user presses its button that is delivered back with
@@ -241,50 +241,66 @@
      * InputConnection.performEditorAction()}.
      */
     public int actionId = 0;
-    
+
     /**
      * The text offset of the start of the selection at the time editing
-     * began; -1 if not known. Keep in mind some IMEs may not be able
-     * to give their full feature set without knowing the cursor position;
-     * avoid passing -1 here if you can.
+     * begins; -1 if not known. Keep in mind that, without knowing the cursor
+     * position, many IMEs will not be able to offer their full feature set and
+     * may even behave in unpredictable ways: pass the actual cursor position
+     * here if possible at all.
+     *
+     * <p>Also, this needs to be the cursor position <strong>right now</strong>,
+     * not at some point in the past, even if input is starting in the same text field
+     * as before. When the app is filling this object, input is about to start by
+     * definition, and this value will override any value the app may have passed to
+     * {@link InputMethodManager#updateSelection(android.view.View, int, int, int, int)}
+     * before.</p>
      */
     public int initialSelStart = -1;
-    
+
     /**
-     * The text offset of the end of the selection at the time editing
-     * began; -1 if not known. Keep in mind some IMEs may not be able
-     * to give their full feature set without knowing the cursor position;
-     * avoid passing -1 here if you can.
+     * <p>The text offset of the end of the selection at the time editing
+     * begins; -1 if not known. Keep in mind that, without knowing the cursor
+     * position, many IMEs will not be able to offer their full feature set and
+     * may behave in unpredictable ways: pass the actual cursor position
+     * here if possible at all.</p>
+     *
+     * <p>Also, this needs to be the cursor position <strong>right now</strong>,
+     * not at some point in the past, even if input is starting in the same text field
+     * as before. When the app is filling this object, input is about to start by
+     * definition, and this value will override any value the app may have passed to
+     * {@link InputMethodManager#updateSelection(android.view.View, int, int, int, int)}
+     * before.</p>
      */
     public int initialSelEnd = -1;
-    
+
     /**
      * The capitalization mode of the first character being edited in the
      * text.  Values may be any combination of
      * {@link TextUtils#CAP_MODE_CHARACTERS TextUtils.CAP_MODE_CHARACTERS},
      * {@link TextUtils#CAP_MODE_WORDS TextUtils.CAP_MODE_WORDS}, and
      * {@link TextUtils#CAP_MODE_SENTENCES TextUtils.CAP_MODE_SENTENCES}, though
-     * you should generally just take a non-zero value to mean start out in
-     * caps mode.
+     * you should generally just take a non-zero value to mean "start out in
+     * caps mode".
      */
     public int initialCapsMode = 0;
-    
+
     /**
      * The "hint" text of the text view, typically shown in-line when the
      * text is empty to tell the user what to enter.
      */
     public CharSequence hintText;
-    
+
     /**
      * A label to show to the user describing the text they are writing.
      */
     public CharSequence label;
-    
+
     /**
      * Name of the package that owns this editor.
      */
     public String packageName;
-    
+
     /**
      * Identifier for the editor's field.  This is optional, and may be
      * 0.  By default it is filled in with the result of
@@ -292,14 +308,14 @@
      * is being edited.
      */
     public int fieldId;
-    
+
     /**
      * Additional name for the editor's field.  This can supply additional
      * name information for the field.  By default it is null.  The actual
      * contents have no meaning.
      */
     public String fieldName;
-    
+
     /**
      * Any extra data to supply to the input method.  This is for extended
      * communication with specific input methods; the name fields in the
@@ -309,7 +325,7 @@
      * attribute of a TextView.
      */
     public Bundle extras;
-    
+
     /**
      * Ensure that the data in this EditorInfo is compatible with an application
      * that was developed against the given target API version.  This can
@@ -365,10 +381,10 @@
                 + " fieldName=" + fieldName);
         pw.println(prefix + "extras=" + extras);
     }
-    
+
     /**
      * Used to package this object into a {@link Parcel}.
-     * 
+     *
      * @param dest The {@link Parcel} to be written.
      * @param flags The flags used for parceling.
      */
@@ -392,30 +408,31 @@
     /**
      * Used to make this class parcelable.
      */
-    public static final Parcelable.Creator<EditorInfo> CREATOR = new Parcelable.Creator<EditorInfo>() {
-        public EditorInfo createFromParcel(Parcel source) {
-            EditorInfo res = new EditorInfo();
-            res.inputType = source.readInt();
-            res.imeOptions = source.readInt();
-            res.privateImeOptions = source.readString();
-            res.actionLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            res.actionId = source.readInt();
-            res.initialSelStart = source.readInt();
-            res.initialSelEnd = source.readInt();
-            res.initialCapsMode = source.readInt();
-            res.hintText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            res.label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            res.packageName = source.readString();
-            res.fieldId = source.readInt();
-            res.fieldName = source.readString();
-            res.extras = source.readBundle();
-            return res;
-        }
+    public static final Parcelable.Creator<EditorInfo> CREATOR =
+            new Parcelable.Creator<EditorInfo>() {
+                public EditorInfo createFromParcel(Parcel source) {
+                    EditorInfo res = new EditorInfo();
+                    res.inputType = source.readInt();
+                    res.imeOptions = source.readInt();
+                    res.privateImeOptions = source.readString();
+                    res.actionLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+                    res.actionId = source.readInt();
+                    res.initialSelStart = source.readInt();
+                    res.initialSelEnd = source.readInt();
+                    res.initialCapsMode = source.readInt();
+                    res.hintText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+                    res.label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+                    res.packageName = source.readString();
+                    res.fieldId = source.readInt();
+                    res.fieldName = source.readString();
+                    res.extras = source.readBundle();
+                    return res;
+                }
 
-        public EditorInfo[] newArray(int size) {
-            return new EditorInfo[size];
-        }
-    };
+                public EditorInfo[] newArray(int size) {
+                    return new EditorInfo[size];
+                }
+            };
 
     public int describeContents() {
         return 0;
diff --git a/core/java/android/view/inputmethod/ExtractedTextRequest.java b/core/java/android/view/inputmethod/ExtractedTextRequest.java
index f658b87..bf0bef3 100644
--- a/core/java/android/view/inputmethod/ExtractedTextRequest.java
+++ b/core/java/android/view/inputmethod/ExtractedTextRequest.java
@@ -18,7 +18,6 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
 
 /**
  * Description of what an input method would like from an application when
diff --git a/core/java/android/view/inputmethod/InputBinding.java b/core/java/android/view/inputmethod/InputBinding.java
index f4209ef..bcd459e 100644
--- a/core/java/android/view/inputmethod/InputBinding.java
+++ b/core/java/android/view/inputmethod/InputBinding.java
@@ -19,7 +19,6 @@
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.text.TextUtils;
 
 /**
  * Information given to an {@link InputMethod} about a client connecting
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 5df5811..f8160c8 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -1,12 +1,12 @@
 /*
  * Copyright (C) 2007-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
@@ -37,6 +37,7 @@
 import android.util.Slog;
 import android.util.Xml;
 import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+import android.view.inputmethod.InputMethodSubtypeArray;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -64,7 +65,7 @@
      * The Service that implements this input method component.
      */
     final ResolveInfo mService;
-    
+
     /**
      * The unique string Id to identify the input method.  This is generated
      * from the input method component.
@@ -86,9 +87,9 @@
     final int mIsDefaultResId;
 
     /**
-     * The array of the subtypes.
+     * An array-like container of the subtypes.
      */
-    private final ArrayList<InputMethodSubtype> mSubtypes = new ArrayList<InputMethodSubtype>();
+    private final InputMethodSubtypeArray mSubtypes;
 
     private final boolean mIsAuxIme;
 
@@ -138,28 +139,29 @@
         int isDefaultResId = 0;
 
         XmlResourceParser parser = null;
+        final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
         try {
             parser = si.loadXmlMetaData(pm, InputMethod.SERVICE_META_DATA);
             if (parser == null) {
                 throw new XmlPullParserException("No "
                         + InputMethod.SERVICE_META_DATA + " meta-data");
             }
-        
+
             Resources res = pm.getResourcesForApplication(si.applicationInfo);
-            
+
             AttributeSet attrs = Xml.asAttributeSet(parser);
-            
+
             int type;
             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
                     && type != XmlPullParser.START_TAG) {
             }
-            
+
             String nodeName = parser.getName();
             if (!"input-method".equals(nodeName)) {
                 throw new XmlPullParserException(
                         "Meta-data does not start with input-method tag");
             }
-            
+
             TypedArray sa = res.obtainAttributes(attrs,
                     com.android.internal.R.styleable.InputMethod);
             settingsActivityComponent = sa.getString(
@@ -206,7 +208,7 @@
                     if (!subtype.isAuxiliary()) {
                         isAuxIme = false;
                     }
-                    mSubtypes.add(subtype);
+                    subtypes.add(subtype);
                 }
             }
         } catch (NameNotFoundException e) {
@@ -216,7 +218,7 @@
             if (parser != null) parser.close();
         }
 
-        if (mSubtypes.size() == 0) {
+        if (subtypes.size() == 0) {
             isAuxIme = false;
         }
 
@@ -225,14 +227,15 @@
             final int N = additionalSubtypes.size();
             for (int i = 0; i < N; ++i) {
                 final InputMethodSubtype subtype = additionalSubtypes.get(i);
-                if (!mSubtypes.contains(subtype)) {
-                    mSubtypes.add(subtype);
+                if (!subtypes.contains(subtype)) {
+                    subtypes.add(subtype);
                 } else {
                     Slog.w(TAG, "Duplicated subtype definition found: "
                             + subtype.getLocale() + ", " + subtype.getMode());
                 }
             }
         }
+        mSubtypes = new InputMethodSubtypeArray(subtypes);
         mSettingsActivityName = settingsActivityComponent;
         mIsDefaultResId = isDefaultResId;
         mIsAuxIme = isAuxIme;
@@ -246,7 +249,7 @@
         mIsAuxIme = source.readInt() == 1;
         mSupportsSwitchingToNextInputMethod = source.readInt() == 1;
         mService = ResolveInfo.CREATOR.createFromParcel(source);
-        source.readTypedList(mSubtypes, InputMethodSubtype.CREATOR);
+        mSubtypes = new InputMethodSubtypeArray(source);
         mForceDefault = false;
     }
 
@@ -272,9 +275,7 @@
         mSettingsActivityName = settingsActivity;
         mIsDefaultResId = isDefaultResId;
         mIsAuxIme = isAuxIme;
-        if (subtypes != null) {
-            mSubtypes.addAll(subtypes);
-        }
+        mSubtypes = new InputMethodSubtypeArray(subtypes);
         mForceDefault = forceDefault;
         mSupportsSwitchingToNextInputMethod = true;
     }
@@ -338,7 +339,7 @@
 
     /**
      * Load the user-displayed label for this input method.
-     * 
+     *
      * @param pm Supply a PackageManager used to load the input method's
      * resources.
      */
@@ -348,7 +349,7 @@
 
     /**
      * Load the user-displayed icon for this input method.
-     * 
+     *
      * @param pm Supply a PackageManager used to load the input method's
      * resources.
      */
@@ -362,9 +363,9 @@
      * an {@link android.content.Intent} whose action is MAIN and with an
      * explicit {@link android.content.ComponentName}
      * composed of {@link #getPackageName} and the class name returned here.
-     * 
+     *
      * <p>A null will be returned if there is no settings activity associated
-     * with the input method.
+     * with the input method.</p>
      */
     public String getSettingsActivity() {
         return mSettingsActivityName;
@@ -374,7 +375,7 @@
      * Return the count of the subtypes of Input Method.
      */
     public int getSubtypeCount() {
-        return mSubtypes.size();
+        return mSubtypes.getCount();
     }
 
     /**
@@ -419,7 +420,7 @@
         pw.println(prefix + "Service:");
         mService.dump(pw, prefix + "  ");
     }
-    
+
     @Override
     public String toString() {
         return "InputMethodInfo{" + mId
@@ -430,7 +431,7 @@
     /**
      * Used to test whether the given parameter object is an
      * {@link InputMethodInfo} and its Id is the same to this one.
-     * 
+     *
      * @return true if the given parameter object is an
      *         {@link InputMethodInfo} and its Id is the same to this one.
      */
@@ -467,7 +468,7 @@
 
     /**
      * Used to package this object into a {@link Parcel}.
-     * 
+     *
      * @param dest The {@link Parcel} to be written.
      * @param flags The flags used for parceling.
      */
@@ -479,7 +480,7 @@
         dest.writeInt(mIsAuxIme ? 1 : 0);
         dest.writeInt(mSupportsSwitchingToNextInputMethod ? 1 : 0);
         mService.writeToParcel(dest, flags);
-        dest.writeTypedList(mSubtypes);
+        mSubtypes.writeToParcel(dest);
     }
 
     /**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 53f7c79..f2ce113 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -714,6 +714,7 @@
      * Reset all of the state associated with being bound to an input method.
      */
     void clearBindingLocked() {
+        if (DEBUG) Log.v(TAG, "Clearing binding!");
         clearConnectionLocked();
         setInputChannelLocked(null);
         mBindSequence = -1;
@@ -1394,6 +1395,14 @@
     
     /**
      * Report the current selection range.
+     *
+     * <p><strong>Editor authors</strong>, you need to call this method whenever
+     * the cursor moves in your editor. Remember that in addition to doing this, your
+     * editor needs to always supply current cursor values in
+     * {@link EditorInfo#initialSelStart} and {@link EditorInfo#initialSelEnd} every
+     * time {@link android.view.View#onCreateInputConnection(EditorInfo)} is
+     * called, which happens whenever the keyboard shows up or the focus changes
+     * to a text field, among other cases.</p>
      */
     public void updateSelection(View view, int selStart, int selEnd,
             int candidatesStart, int candidatesEnd) {
@@ -1805,6 +1814,20 @@
     }
 
     /**
+     * Notify the current IME commits text
+     * @hide
+     */
+    public void notifyTextCommitted() {
+        synchronized (mH) {
+            try {
+                mService.notifyTextCommitted();
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+            }
+        }
+    }
+
+    /**
      * Returns a map of all shortcut input method info and their subtypes.
      */
     public Map<InputMethodInfo, List<InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() {
@@ -1840,6 +1863,21 @@
     }
 
     /**
+     * @return The current height of the input method window.
+     * @hide
+     */
+    public int getInputMethodWindowVisibleHeight() {
+        synchronized (mH) {
+            try {
+                return mService.getInputMethodWindowVisibleHeight();
+            } catch (RemoteException e) {
+                Log.w(TAG, "IME died: " + mCurId, e);
+                return 0;
+            }
+        }
+    }
+
+    /**
      * Force switch to the last used input method and subtype. If the last input method didn't have
      * any subtypes, the framework will simply switch to the last input method with no subtype
      * specified.
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 2ab3024..e7ada27 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -472,12 +472,12 @@
                 return (subtype.hashCode() == hashCode());
             }
             return (subtype.hashCode() == hashCode())
-                && (subtype.getNameResId() == getNameResId())
-                && (subtype.getMode().equals(getMode()))
-                && (subtype.getIconResId() == getIconResId())
                 && (subtype.getLocale().equals(getLocale()))
+                && (subtype.getMode().equals(getMode()))
                 && (subtype.getExtraValue().equals(getExtraValue()))
                 && (subtype.isAuxiliary() == isAuxiliary())
+                && (subtype.overridesImplicitlyEnabledSubtype()
+                        == overridesImplicitlyEnabledSubtype())
                 && (subtype.isAsciiCapable() == isAsciiCapable());
         }
         return false;
diff --git a/core/java/android/view/inputmethod/InputMethodSubtypeArray.java b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
new file mode 100644
index 0000000..5bef71f
--- /dev/null
+++ b/core/java/android/view/inputmethod/InputMethodSubtypeArray.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2007-2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.view.inputmethod;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AndroidRuntimeException;
+import android.util.Slog;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * An array-like container that stores multiple instances of {@link InputMethodSubtype}.
+ *
+ * <p>This container is designed to reduce the risk of {@link TransactionTooLargeException}
+ * when one or more instancess of {@link InputMethodInfo} are transferred through IPC.
+ * Basically this class does following three tasks.</p>
+ * <ul>
+ * <li>Applying compression for the marshalled data</li>
+ * <li>Lazily unmarshalling objects</li>
+ * <li>Caching the marshalled data when appropriate</li>
+ * </ul>
+ *
+ * @hide
+ */
+public class InputMethodSubtypeArray {
+    private final static String TAG = "InputMethodSubtypeArray";
+
+    /**
+     * Create a new instance of {@link InputMethodSubtypeArray} from an existing list of
+     * {@link InputMethodSubtype}.
+     *
+     * @param subtypes A list of {@link InputMethodSubtype} from which
+     * {@link InputMethodSubtypeArray} will be created.
+     */
+    public InputMethodSubtypeArray(final List<InputMethodSubtype> subtypes) {
+        if (subtypes == null) {
+            mCount = 0;
+            return;
+        }
+        mCount = subtypes.size();
+        mInstance = subtypes.toArray(new InputMethodSubtype[mCount]);
+    }
+
+    /**
+     * Unmarshall an instance of {@link InputMethodSubtypeArray} from a given {@link Parcel}
+     * object.
+     *
+     * @param source A {@link Parcel} object from which {@link InputMethodSubtypeArray} will be
+     * unmarshalled.
+     */
+    public InputMethodSubtypeArray(final Parcel source) {
+        mCount = source.readInt();
+        if (mCount > 0) {
+            mDecompressedSize = source.readInt();
+            mCompressedData = source.createByteArray();
+        }
+    }
+
+    /**
+     * Marshall the instance into a given {@link Parcel} object.
+     *
+     * <p>This methods may take a bit additional time to compress data lazily when called
+     * first time.</p>
+     *
+     * @param source A {@link Parcel} object to which {@link InputMethodSubtypeArray} will be
+     * marshalled.
+     */
+    public void writeToParcel(final Parcel dest) {
+        if (mCount == 0) {
+            dest.writeInt(mCount);
+            return;
+        }
+
+        byte[] compressedData = mCompressedData;
+        int decompressedSize = mDecompressedSize;
+        if (compressedData == null && decompressedSize == 0) {
+            synchronized (mLockObject) {
+                compressedData = mCompressedData;
+                decompressedSize = mDecompressedSize;
+                if (compressedData == null && decompressedSize == 0) {
+                    final byte[] decompressedData = marshall(mInstance);
+                    compressedData = compress(decompressedData);
+                    if (compressedData == null) {
+                        decompressedSize = -1;
+                        Slog.i(TAG, "Failed to compress data.");
+                    } else {
+                        decompressedSize = decompressedData.length;
+                    }
+                    mDecompressedSize = decompressedSize;
+                    mCompressedData = compressedData;
+                }
+            }
+        }
+
+        if (compressedData != null && decompressedSize > 0) {
+            dest.writeInt(mCount);
+            dest.writeInt(decompressedSize);
+            dest.writeByteArray(compressedData);
+        } else {
+            Slog.i(TAG, "Unexpected state. Behaving as an empty array.");
+            dest.writeInt(0);
+        }
+    }
+
+    /**
+     * Return {@link InputMethodSubtype} specified with the given index.
+     *
+     * <p>This methods may take a bit additional time to decompress data lazily when called
+     * first time.</p>
+     *
+     * @param index The index of {@link InputMethodSubtype}.
+     */
+    public InputMethodSubtype get(final int index) {
+        if (index < 0 || mCount <= index) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        InputMethodSubtype[] instance = mInstance;
+        if (instance == null) {
+            synchronized (mLockObject) {
+                instance = mInstance;
+                if (instance == null) {
+                    final byte[] decompressedData =
+                          decompress(mCompressedData, mDecompressedSize);
+                    // Clear the compressed data until {@link #getMarshalled()} is called.
+                    mCompressedData = null;
+                    mDecompressedSize = 0;
+                    if (decompressedData != null) {
+                        instance = unmarshall(decompressedData);
+                    } else {
+                        Slog.e(TAG, "Failed to decompress data. Returns null as fallback.");
+                        instance = new InputMethodSubtype[mCount];
+                    }
+                    mInstance = instance;
+                }
+            }
+        }
+        return instance[index];
+    }
+
+    /**
+     * Return the number of {@link InputMethodSubtype} objects.
+     */
+    public int getCount() {
+        return mCount;
+    }
+
+    private final Object mLockObject = new Object();
+    private final int mCount;
+
+    private volatile InputMethodSubtype[] mInstance;
+    private volatile byte[] mCompressedData;
+    private volatile int mDecompressedSize;
+
+    private static byte[] marshall(final InputMethodSubtype[] array) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.writeTypedArray(array, 0);
+            return parcel.marshall();
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+                parcel = null;
+            }
+        }
+    }
+
+    private static InputMethodSubtype[] unmarshall(final byte[] data) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.unmarshall(data, 0, data.length);
+            parcel.setDataPosition(0);
+            return parcel.createTypedArray(InputMethodSubtype.CREATOR);
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+                parcel = null;
+            }
+        }
+    }
+
+    private static byte[] compress(final byte[] data) {
+        ByteArrayOutputStream resultStream = null;
+        GZIPOutputStream zipper = null;
+        try {
+            resultStream = new ByteArrayOutputStream();
+            zipper = new GZIPOutputStream(resultStream);
+            zipper.write(data);
+        } catch(IOException e) {
+            return null;
+        } finally {
+            try {
+                if (zipper != null) {
+                    zipper.close();
+                }
+            } catch (IOException e) {
+                zipper = null;
+                Slog.e(TAG, "Failed to close the stream.", e);
+                // swallowed, not propagated back to the caller
+            }
+            try {
+                if (resultStream != null) {
+                    resultStream.close();
+                }
+            } catch (IOException e) {
+                resultStream = null;
+                Slog.e(TAG, "Failed to close the stream.", e);
+                // swallowed, not propagated back to the caller
+            }
+        }
+        return resultStream != null ? resultStream.toByteArray() : null;
+    }
+
+    private static byte[] decompress(final byte[] data, final int expectedSize) {
+        ByteArrayInputStream inputStream = null;
+        GZIPInputStream unzipper = null;
+        try {
+            inputStream = new ByteArrayInputStream(data);
+            unzipper = new GZIPInputStream(inputStream);
+            final byte [] result = new byte[expectedSize];
+            int totalReadBytes = 0;
+            while (totalReadBytes < result.length) {
+                final int restBytes = result.length - totalReadBytes;
+                final int readBytes = unzipper.read(result, totalReadBytes, restBytes);
+                if (readBytes < 0) {
+                    break;
+                }
+                totalReadBytes += readBytes;
+            }
+            if (expectedSize != totalReadBytes) {
+                return null;
+            }
+            return result;
+        } catch(IOException e) {
+            return null;
+        } finally {
+            try {
+                if (unzipper != null) {
+                    unzipper.close();
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to close the stream.", e);
+                // swallowed, not propagated back to the caller
+            }
+            try {
+                if (inputStream != null) {
+                  inputStream.close();
+                }
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to close the stream.", e);
+                // swallowed, not propagated back to the caller
+            }
+        }
+    }
+}
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index bbd3f2b..45e6eb3 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -16,13 +16,7 @@
 
 package android.webkit;
 
-import android.content.Context;
-import android.net.http.Headers;
-import android.util.Log;
-
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
diff --git a/core/java/android/webkit/DateSorter.java b/core/java/android/webkit/DateSorter.java
index 82c13ae..fede244 100644
--- a/core/java/android/webkit/DateSorter.java
+++ b/core/java/android/webkit/DateSorter.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 
 import java.util.Calendar;
-import java.util.Date;
 import java.util.Locale;
 
 import libcore.icu.LocaleData;
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index b5ca8c1..7b3cb1b 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -31,7 +31,6 @@
     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;
 
diff --git a/core/java/android/webkit/Plugin.java b/core/java/android/webkit/Plugin.java
index 529820b..072e02a 100644
--- a/core/java/android/webkit/Plugin.java
+++ b/core/java/android/webkit/Plugin.java
@@ -21,7 +21,6 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.webkit.WebView;
 
 /**
  * Represents a plugin (Java equivalent of the PluginPackageAndroid
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
index b7171ee..f21e2b4 100644
--- a/core/java/android/webkit/WebResourceResponse.java
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -16,8 +16,6 @@
 
 package android.webkit;
 
-import android.net.http.Headers;
-
 import java.io.InputStream;
 
 /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index d53bb74..81d36a4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -28,7 +28,6 @@
 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;
@@ -255,7 +254,7 @@
     // Throwing an exception for incorrect thread usage if the
     // build target is JB MR2 or newer. Defaults to false, and is
     // set in the WebView constructor.
-    private static Boolean sEnforceThreadChecking = false;
+    private static volatile boolean sEnforceThreadChecking = false;
 
     /**
      *  Transportation object for returning WebView across thread boundaries.
@@ -449,10 +448,12 @@
      *
      * @param context a Context object used to access application assets
      * @param attrs an AttributeSet passed to our parent
-     * @param defStyle the default style resource ID
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public WebView(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, false);
+    public WebView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     /**
@@ -460,7 +461,26 @@
      *
      * @param context a Context object used to access application assets
      * @param attrs an AttributeSet passed to our parent
-     * @param defStyle the default style resource ID
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes a resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        this(context, attrs, defStyleAttr, defStyleRes, null, false);
+    }
+
+    /**
+     * Constructs a new WebView with layout parameters and a default style.
+     *
+     * @param context a Context object used to access application assets
+     * @param attrs an AttributeSet passed to our parent
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @param privateBrowsing whether this WebView will be initialized in
      *                        private mode
      *
@@ -470,9 +490,9 @@
      * and {@link WebStorage} for fine-grained control of privacy data.
      */
     @Deprecated
-    public WebView(Context context, AttributeSet attrs, int defStyle,
+    public WebView(Context context, AttributeSet attrs, int defStyleAttr,
             boolean privateBrowsing) {
-        this(context, attrs, defStyle, null, privateBrowsing);
+        this(context, attrs, defStyleAttr, 0, null, privateBrowsing);
     }
 
     /**
@@ -483,7 +503,9 @@
      *
      * @param context a Context object used to access application assets
      * @param attrs an AttributeSet passed to our parent
-     * @param defStyle the default style resource ID
+     * @param defStyleAttr an attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @param javaScriptInterfaces a Map of interface names, as keys, and
      *                             object implementing those interfaces, as
      *                             values
@@ -492,10 +514,18 @@
      * @hide This is used internally by dumprendertree, as it requires the javaScript interfaces to
      *       be added synchronously, before a subsequent loadUrl call takes effect.
      */
-    @SuppressWarnings("deprecation")  // for super() call into deprecated base class constructor.
-    protected WebView(Context context, AttributeSet attrs, int defStyle,
+    protected WebView(Context context, AttributeSet attrs, int defStyleAttr,
             Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
-        super(context, attrs, defStyle);
+        this(context, attrs, defStyleAttr, 0, javaScriptInterfaces, privateBrowsing);
+    }
+
+    /**
+     * @hide
+     */
+    @SuppressWarnings("deprecation")  // for super() call into deprecated base class constructor.
+    protected WebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes,
+            Map<String, Object> javaScriptInterfaces, boolean privateBrowsing) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         if (context == null) {
             throw new IllegalArgumentException("Invalid context argument");
         }
@@ -790,7 +820,15 @@
      */
     public void loadUrl(String url, Map<String, String> additionalHttpHeaders) {
         checkThread();
-        if (DebugFlags.TRACE_API) Log.d(LOGTAG, "loadUrl(extra headers)=" + url);
+        if (DebugFlags.TRACE_API) {
+            StringBuilder headers = new StringBuilder();
+            if (additionalHttpHeaders != null) {
+                for (Map.Entry<String, String> entry : additionalHttpHeaders.entrySet()) {
+                    headers.append(entry.getKey() + ":" + entry.getValue() + "\n");
+                }
+            }
+            Log.d(LOGTAG, "loadUrl(extra headers)=" + url + "\n" + headers);
+        }
         mProvider.loadUrl(url, additionalHttpHeaders);
     }
 
@@ -807,8 +845,8 @@
 
     /**
      * Loads the URL with postData using "POST" method into this WebView. If url
-     * is not a network URL, it will be loaded with {link
-     * {@link #loadUrl(String)} instead.
+     * is not a network URL, it will be loaded with {@link #loadUrl(String)}
+     * instead, ignoring the postData param.
      *
      * @param url the URL of the resource to load
      * @param postData the data will be passed to "POST" request, which must be
@@ -817,7 +855,11 @@
     public void postUrl(String url, byte[] postData) {
         checkThread();
         if (DebugFlags.TRACE_API) Log.d(LOGTAG, "postUrl=" + url);
-        mProvider.postUrl(url, postData);
+        if (URLUtil.isNetworkUrl(url)) {
+            mProvider.postUrl(url, postData);
+        } else {
+            mProvider.loadUrl(url);
+        }
     }
 
     /**
@@ -2097,10 +2139,11 @@
         mProvider.getViewDelegate().onAttachedToWindow();
     }
 
+    /** @hide */
     @Override
-    protected void onDetachedFromWindow() {
+    protected void onDetachedFromWindowInternal() {
         mProvider.getViewDelegate().onDetachedFromWindow();
-        super.onDetachedFromWindow();
+        super.onDetachedFromWindowInternal();
     }
 
     @Override
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index b9131bf..25bcd44 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -16,9 +16,7 @@
 
 package android.webkit;
 
-import android.os.Build;
 import android.os.StrictMode;
-import android.os.SystemProperties;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 25a43a6..96a2ab5 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -36,6 +36,7 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.LongSparseArray;
+import android.util.MathUtils;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.util.StateSet;
@@ -59,6 +60,9 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 import android.view.animation.LinearInterpolator;
 import android.view.inputmethod.BaseInputConnection;
@@ -417,7 +421,7 @@
     /**
      * Handles scrolling between positions within the list.
      */
-    PositionScroller mPositionScroller;
+    AbsPositionScroller mPositionScroller;
 
     /**
      * The offset in pixels form the top of the AdapterView to the top
@@ -581,7 +585,13 @@
     /**
      * Helper object that renders and controls the fast scroll thumb.
      */
-    private FastScroller mFastScroller;
+    private FastScroller mFastScroll;
+
+    /**
+     * Temporary holder for fast scroller style until a FastScroller object
+     * is created.
+     */
+    private int mFastScrollStyle;
 
     private boolean mGlobalLayoutListenerAddedFilter;
 
@@ -693,6 +703,11 @@
     private SavedState mPendingSync;
 
     /**
+     * Whether the view is in the process of detaching from its window.
+     */
+    private boolean mIsDetaching;
+
+    /**
      * Interface definition for a callback to be invoked when the list or grid
      * has been scrolled.
      */
@@ -773,14 +788,18 @@
         this(context, attrs, com.android.internal.R.attr.absListViewStyle);
     }
 
-    public AbsListView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initAbsListView();
 
         mOwnerThread = Thread.currentThread();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AbsListView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.AbsListView, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(com.android.internal.R.styleable.AbsListView_listSelector);
         if (d != null) {
@@ -809,6 +828,9 @@
         boolean enableFastScroll = a.getBoolean(R.styleable.AbsListView_fastScrollEnabled, false);
         setFastScrollEnabled(enableFastScroll);
 
+        int fastScrollStyle = a.getResourceId(R.styleable.AbsListView_fastScrollStyle, 0);
+        setFastScrollStyle(fastScrollStyle);
+
         boolean smoothScrollbar = a.getBoolean(R.styleable.AbsListView_smoothScrollbar, true);
         setSmoothScrollbarEnabled(smoothScrollbar);
 
@@ -1238,17 +1260,31 @@
     }
 
     private void setFastScrollerEnabledUiThread(boolean enabled) {
-        if (mFastScroller != null) {
-            mFastScroller.setEnabled(enabled);
+        if (mFastScroll != null) {
+            mFastScroll.setEnabled(enabled);
         } else if (enabled) {
-            mFastScroller = new FastScroller(this);
-            mFastScroller.setEnabled(true);
+            mFastScroll = new FastScroller(this, mFastScrollStyle);
+            mFastScroll.setEnabled(true);
         }
 
         resolvePadding();
 
-        if (mFastScroller != null) {
-            mFastScroller.updateLayout();
+        if (mFastScroll != null) {
+            mFastScroll.updateLayout();
+        }
+    }
+
+    /**
+     * Specifies the style of the fast scroller decorations.
+     *
+     * @param styleResId style resource containing fast scroller properties
+     * @see android.R.styleable#FastScroll
+     */
+    public void setFastScrollStyle(int styleResId) {
+        if (mFastScroll == null) {
+            mFastScrollStyle = styleResId;
+        } else {
+            mFastScroll.setStyle(styleResId);
         }
     }
 
@@ -1288,8 +1324,8 @@
     }
 
     private void setFastScrollerAlwaysVisibleUiThread(boolean alwaysShow) {
-        if (mFastScroller != null) {
-            mFastScroller.setAlwaysShow(alwaysShow);
+        if (mFastScroll != null) {
+            mFastScroll.setAlwaysShow(alwaysShow);
         }
     }
 
@@ -1307,17 +1343,17 @@
      * @see #setFastScrollAlwaysVisible(boolean)
      */
     public boolean isFastScrollAlwaysVisible() {
-        if (mFastScroller == null) {
+        if (mFastScroll == null) {
             return mFastScrollEnabled && mFastScrollAlwaysVisible;
         } else {
-            return mFastScroller.isEnabled() && mFastScroller.isAlwaysShowEnabled();
+            return mFastScroll.isEnabled() && mFastScroll.isAlwaysShowEnabled();
         }
     }
 
     @Override
     public int getVerticalScrollbarWidth() {
-        if (mFastScroller != null && mFastScroller.isEnabled()) {
-            return Math.max(super.getVerticalScrollbarWidth(), mFastScroller.getWidth());
+        if (mFastScroll != null && mFastScroll.isEnabled()) {
+            return Math.max(super.getVerticalScrollbarWidth(), mFastScroll.getWidth());
         }
         return super.getVerticalScrollbarWidth();
     }
@@ -1330,26 +1366,26 @@
      */
     @ViewDebug.ExportedProperty
     public boolean isFastScrollEnabled() {
-        if (mFastScroller == null) {
+        if (mFastScroll == null) {
             return mFastScrollEnabled;
         } else {
-            return mFastScroller.isEnabled();
+            return mFastScroll.isEnabled();
         }
     }
 
     @Override
     public void setVerticalScrollbarPosition(int position) {
         super.setVerticalScrollbarPosition(position);
-        if (mFastScroller != null) {
-            mFastScroller.setScrollbarPosition(position);
+        if (mFastScroll != null) {
+            mFastScroll.setScrollbarPosition(position);
         }
     }
 
     @Override
     public void setScrollBarStyle(int style) {
         super.setScrollBarStyle(style);
-        if (mFastScroller != null) {
-            mFastScroller.setScrollBarStyle(style);
+        if (mFastScroll != null) {
+            mFastScroll.setScrollBarStyle(style);
         }
     }
 
@@ -1410,8 +1446,8 @@
      * Notify our scroll listener (if there is one) of a change in scroll state
      */
     void invokeOnItemScrollListener() {
-        if (mFastScroller != null) {
-            mFastScroller.onScroll(mFirstPosition, getChildCount(), mItemCount);
+        if (mFastScroll != null) {
+            mFastScroll.onScroll(mFirstPosition, getChildCount(), mItemCount);
         }
         if (mOnScrollListener != null) {
             mOnScrollListener.onScroll(this, mFirstPosition, getChildCount(), mItemCount);
@@ -1460,6 +1496,21 @@
         }
     }
 
+    int getSelectionModeForAccessibility() {
+        final int choiceMode = getChoiceMode();
+        switch (choiceMode) {
+            case CHOICE_MODE_NONE:
+                return CollectionInfo.SELECTION_MODE_NONE;
+            case CHOICE_MODE_SINGLE:
+                return CollectionInfo.SELECTION_MODE_SINGLE;
+            case CHOICE_MODE_MULTIPLE:
+            case CHOICE_MODE_MULTIPLE_MODAL:
+                return CollectionInfo.SELECTION_MODE_MULTIPLE;
+            default:
+                return CollectionInfo.SELECTION_MODE_NONE;
+        }
+    }
+
     @Override
     public boolean performAccessibilityAction(int action, Bundle arguments) {
         if (super.performAccessibilityAction(action, arguments)) {
@@ -1576,7 +1627,7 @@
     }
 
     private void useDefaultSelector() {
-        setSelector(getResources().getDrawable(
+        setSelector(getContext().getDrawable(
                 com.android.internal.R.drawable.list_selector_background));
     }
 
@@ -2090,8 +2141,8 @@
         mOverscrollMax = (b - t) / OVERSCROLL_LIMIT_DIVISOR;
 
         // TODO: Move somewhere sane. This doesn't belong in onLayout().
-        if (mFastScroller != null) {
-            mFastScroller.onItemCountChanged(getChildCount(), mItemCount);
+        if (mFastScroll != null) {
+            mFastScroll.onItemCountChanged(getChildCount(), mItemCount);
         }
     }
 
@@ -2121,6 +2172,25 @@
     protected void layoutChildren() {
     }
 
+    /**
+     * @param focusedView view that holds accessibility focus
+     * @return direct child that contains accessibility focus, or null if no
+     *         child contains accessibility focus
+     */
+    View getAccessibilityFocusedChild(View focusedView) {
+        ViewParent viewParent = focusedView.getParent();
+        while ((viewParent instanceof View) && (viewParent != this)) {
+            focusedView = (View) viewParent;
+            viewParent = viewParent.getParent();
+        }
+
+        if (!(viewParent instanceof View)) {
+            return null;
+        }
+
+        return focusedView;
+    }
+
     void updateScrollIndicators() {
         if (mScrollUp != null) {
             boolean canScrollUp;
@@ -2242,6 +2312,7 @@
 
                 // If we failed to re-bind the data, scrap the obtained view.
                 if (updatedView != transientView) {
+                    setItemViewLayoutParams(updatedView, position);
                     mRecycler.addScrapView(updatedView, position);
                 }
             }
@@ -2260,12 +2331,6 @@
             } else {
                 isScrap[0] = true;
 
-                // Clear any system-managed transient state so that we can
-                // recycle this view and bind it to different data.
-                if (child.isAccessibilityFocused()) {
-                    child.clearAccessibilityFocus();
-                }
-
                 child.dispatchFinishTemporaryDetach();
             }
         }
@@ -2278,19 +2343,7 @@
             child.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
         }
 
-        if (mAdapterHasStableIds) {
-            final ViewGroup.LayoutParams vlp = child.getLayoutParams();
-            LayoutParams lp;
-            if (vlp == null) {
-                lp = (LayoutParams) generateDefaultLayoutParams();
-            } else if (!checkLayoutParams(vlp)) {
-                lp = (LayoutParams) generateLayoutParams(vlp);
-            } else {
-                lp = (LayoutParams) vlp;
-            }
-            lp.itemId = mAdapter.getItemId(position);
-            child.setLayoutParams(lp);
-        }
+        setItemViewLayoutParams(child, position);
 
         if (AccessibilityManager.getInstance(mContext).isEnabled()) {
             if (mAccessibilityDelegate == null) {
@@ -2306,6 +2359,24 @@
         return child;
     }
 
+    private void setItemViewLayoutParams(View child, int position) {
+        final ViewGroup.LayoutParams vlp = child.getLayoutParams();
+        LayoutParams lp;
+        if (vlp == null) {
+            lp = (LayoutParams) generateDefaultLayoutParams();
+        } else if (!checkLayoutParams(vlp)) {
+            lp = (LayoutParams) generateLayoutParams(vlp);
+        } else {
+            lp = (LayoutParams) vlp;
+        }
+
+        if (mAdapterHasStableIds) {
+            lp.itemId = mAdapter.getItemId(position);
+        }
+        lp.viewType = mAdapter.getItemViewType(position);
+        child.setLayoutParams(lp);
+    }
+
     class ListItemAccessibilityDelegate extends AccessibilityDelegate {
         @Override
         public AccessibilityNodeInfo createAccessibilityNodeInfo(View host) {
@@ -2506,8 +2577,8 @@
             rememberSyncState();
         }
 
-        if (mFastScroller != null) {
-            mFastScroller.onSizeChanged(w, h, oldw, oldh);
+        if (mFastScroll != null) {
+            mFastScroll.onSizeChanged(w, h, oldw, oldh);
         }
     }
 
@@ -2566,7 +2637,7 @@
      * @attr ref android.R.styleable#AbsListView_listSelector
      */
     public void setSelector(int resID) {
-        setSelector(getResources().getDrawable(resID));
+        setSelector(getContext().getDrawable(resID));
     }
 
     public void setSelector(Drawable sel) {
@@ -2728,6 +2799,8 @@
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
+        mIsDetaching = true;
+
         // Dismiss the popup in case onSaveInstanceState() was not invoked
         dismissPopup();
 
@@ -2776,6 +2849,8 @@
             removeCallbacks(mTouchModeReset);
             mTouchModeReset.run();
         }
+
+        mIsDetaching = false;
     }
 
     @Override
@@ -2836,8 +2911,8 @@
     @Override
     public void onRtlPropertiesChanged(int layoutDirection) {
         super.onRtlPropertiesChanged(layoutDirection);
-        if (mFastScroller != null) {
-           mFastScroller.setScrollbarPosition(getVerticalScrollbarPosition());
+        if (mFastScroll != null) {
+           mFastScroll.setScrollbarPosition(getVerticalScrollbarPosition());
         }
     }
 
@@ -3402,7 +3477,7 @@
             mPositionScroller.stop();
         }
 
-        if (!isAttachedToWindow()) {
+        if (mIsDetaching || !isAttachedToWindow()) {
             // Something isn't right.
             // Since we rely on being attached to get data set change notifications,
             // don't risk doing anything where we might try to resync and find things
@@ -3410,8 +3485,8 @@
             return false;
         }
 
-        if (mFastScroller != null) {
-            boolean intercepted = mFastScroller.onTouchEvent(ev);
+        if (mFastScroll != null) {
+            boolean intercepted = mFastScroll.onTouchEvent(ev);
             if (intercepted) {
                 return true;
             }
@@ -3641,7 +3716,7 @@
                                     mTouchMode = TOUCH_MODE_REST;
                                     child.setPressed(false);
                                     setPressed(false);
-                                    if (!mDataChanged && isAttachedToWindow()) {
+                                    if (!mDataChanged && !mIsDetaching && isAttachedToWindow()) {
                                         performClick.run();
                                     }
                                 }
@@ -3900,7 +3975,7 @@
 
     @Override
     public boolean onInterceptHoverEvent(MotionEvent event) {
-        if (mFastScroller != null && mFastScroller.onInterceptHoverEvent(event)) {
+        if (mFastScroll != null && mFastScroll.onInterceptHoverEvent(event)) {
             return true;
         }
 
@@ -3916,7 +3991,7 @@
             mPositionScroller.stop();
         }
 
-        if (!isAttachedToWindow()) {
+        if (mIsDetaching || !isAttachedToWindow()) {
             // Something isn't right.
             // Since we rely on being attached to get data set change notifications,
             // don't risk doing anything where we might try to resync and find things
@@ -3924,7 +3999,7 @@
             return false;
         }
 
-        if (mFastScroller != null && mFastScroller.onInterceptTouchEvent(ev)) {
+        if (mFastScroll != null && mFastScroll.onInterceptTouchEvent(ev)) {
             return true;
         }
 
@@ -4321,447 +4396,6 @@
         }
     }
 
-    class PositionScroller implements Runnable {
-        private static final int SCROLL_DURATION = 200;
-
-        private static final int MOVE_DOWN_POS = 1;
-        private static final int MOVE_UP_POS = 2;
-        private static final int MOVE_DOWN_BOUND = 3;
-        private static final int MOVE_UP_BOUND = 4;
-        private static final int MOVE_OFFSET = 5;
-
-        private int mMode;
-        private int mTargetPos;
-        private int mBoundPos;
-        private int mLastSeenPos;
-        private int mScrollDuration;
-        private final int mExtraScroll;
-
-        private int mOffsetFromTop;
-
-        PositionScroller() {
-            mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
-        }
-
-        void start(final int position) {
-            stop();
-
-            if (mDataChanged) {
-                // Wait until we're back in a stable state to try this.
-                mPositionScrollAfterLayout = new Runnable() {
-                    @Override public void run() {
-                        start(position);
-                    }
-                };
-                return;
-            }
-
-            final int childCount = getChildCount();
-            if (childCount == 0) {
-                // Can't scroll without children.
-                return;
-            }
-
-            final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + childCount - 1;
-
-            int viewTravelCount;
-            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
-            if (clampedPosition < firstPos) {
-                viewTravelCount = firstPos - clampedPosition + 1;
-                mMode = MOVE_UP_POS;
-            } else if (clampedPosition > lastPos) {
-                viewTravelCount = clampedPosition - lastPos + 1;
-                mMode = MOVE_DOWN_POS;
-            } else {
-                scrollToVisible(clampedPosition, INVALID_POSITION, SCROLL_DURATION);
-                return;
-            }
-
-            if (viewTravelCount > 0) {
-                mScrollDuration = SCROLL_DURATION / viewTravelCount;
-            } else {
-                mScrollDuration = SCROLL_DURATION;
-            }
-            mTargetPos = clampedPosition;
-            mBoundPos = INVALID_POSITION;
-            mLastSeenPos = INVALID_POSITION;
-
-            postOnAnimation(this);
-        }
-
-        void start(final int position, final int boundPosition) {
-            stop();
-
-            if (boundPosition == INVALID_POSITION) {
-                start(position);
-                return;
-            }
-
-            if (mDataChanged) {
-                // Wait until we're back in a stable state to try this.
-                mPositionScrollAfterLayout = new Runnable() {
-                    @Override public void run() {
-                        start(position, boundPosition);
-                    }
-                };
-                return;
-            }
-
-            final int childCount = getChildCount();
-            if (childCount == 0) {
-                // Can't scroll without children.
-                return;
-            }
-
-            final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + childCount - 1;
-
-            int viewTravelCount;
-            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
-            if (clampedPosition < firstPos) {
-                final int boundPosFromLast = lastPos - boundPosition;
-                if (boundPosFromLast < 1) {
-                    // Moving would shift our bound position off the screen. Abort.
-                    return;
-                }
-
-                final int posTravel = firstPos - clampedPosition + 1;
-                final int boundTravel = boundPosFromLast - 1;
-                if (boundTravel < posTravel) {
-                    viewTravelCount = boundTravel;
-                    mMode = MOVE_UP_BOUND;
-                } else {
-                    viewTravelCount = posTravel;
-                    mMode = MOVE_UP_POS;
-                }
-            } else if (clampedPosition > lastPos) {
-                final int boundPosFromFirst = boundPosition - firstPos;
-                if (boundPosFromFirst < 1) {
-                    // Moving would shift our bound position off the screen. Abort.
-                    return;
-                }
-
-                final int posTravel = clampedPosition - lastPos + 1;
-                final int boundTravel = boundPosFromFirst - 1;
-                if (boundTravel < posTravel) {
-                    viewTravelCount = boundTravel;
-                    mMode = MOVE_DOWN_BOUND;
-                } else {
-                    viewTravelCount = posTravel;
-                    mMode = MOVE_DOWN_POS;
-                }
-            } else {
-                scrollToVisible(clampedPosition, boundPosition, SCROLL_DURATION);
-                return;
-            }
-
-            if (viewTravelCount > 0) {
-                mScrollDuration = SCROLL_DURATION / viewTravelCount;
-            } else {
-                mScrollDuration = SCROLL_DURATION;
-            }
-            mTargetPos = clampedPosition;
-            mBoundPos = boundPosition;
-            mLastSeenPos = INVALID_POSITION;
-
-            postOnAnimation(this);
-        }
-
-        void startWithOffset(int position, int offset) {
-            startWithOffset(position, offset, SCROLL_DURATION);
-        }
-
-        void startWithOffset(final int position, int offset, final int duration) {
-            stop();
-
-            if (mDataChanged) {
-                // Wait until we're back in a stable state to try this.
-                final int postOffset = offset;
-                mPositionScrollAfterLayout = new Runnable() {
-                    @Override public void run() {
-                        startWithOffset(position, postOffset, duration);
-                    }
-                };
-                return;
-            }
-
-            final int childCount = getChildCount();
-            if (childCount == 0) {
-                // Can't scroll without children.
-                return;
-            }
-
-            offset += getPaddingTop();
-
-            mTargetPos = Math.max(0, Math.min(getCount() - 1, position));
-            mOffsetFromTop = offset;
-            mBoundPos = INVALID_POSITION;
-            mLastSeenPos = INVALID_POSITION;
-            mMode = MOVE_OFFSET;
-
-            final int firstPos = mFirstPosition;
-            final int lastPos = firstPos + childCount - 1;
-
-            int viewTravelCount;
-            if (mTargetPos < firstPos) {
-                viewTravelCount = firstPos - mTargetPos;
-            } else if (mTargetPos > lastPos) {
-                viewTravelCount = mTargetPos - lastPos;
-            } else {
-                // On-screen, just scroll.
-                final int targetTop = getChildAt(mTargetPos - firstPos).getTop();
-                smoothScrollBy(targetTop - offset, duration, true);
-                return;
-            }
-
-            // Estimate how many screens we should travel
-            final float screenTravelCount = (float) viewTravelCount / childCount;
-            mScrollDuration = screenTravelCount < 1 ?
-                    duration : (int) (duration / screenTravelCount);
-            mLastSeenPos = INVALID_POSITION;
-
-            postOnAnimation(this);
-        }
-
-        /**
-         * Scroll such that targetPos is in the visible padded region without scrolling
-         * boundPos out of view. Assumes targetPos is onscreen.
-         */
-        void scrollToVisible(int targetPos, int boundPos, int duration) {
-            final int firstPos = mFirstPosition;
-            final int childCount = getChildCount();
-            final int lastPos = firstPos + childCount - 1;
-            final int paddedTop = mListPadding.top;
-            final int paddedBottom = getHeight() - mListPadding.bottom;
-
-            if (targetPos < firstPos || targetPos > lastPos) {
-                Log.w(TAG, "scrollToVisible called with targetPos " + targetPos +
-                        " not visible [" + firstPos + ", " + lastPos + "]");
-            }
-            if (boundPos < firstPos || boundPos > lastPos) {
-                // boundPos doesn't matter, it's already offscreen.
-                boundPos = INVALID_POSITION;
-            }
-
-            final View targetChild = getChildAt(targetPos - firstPos);
-            final int targetTop = targetChild.getTop();
-            final int targetBottom = targetChild.getBottom();
-            int scrollBy = 0;
-
-            if (targetBottom > paddedBottom) {
-                scrollBy = targetBottom - paddedBottom;
-            }
-            if (targetTop < paddedTop) {
-                scrollBy = targetTop - paddedTop;
-            }
-
-            if (scrollBy == 0) {
-                return;
-            }
-
-            if (boundPos >= 0) {
-                final View boundChild = getChildAt(boundPos - firstPos);
-                final int boundTop = boundChild.getTop();
-                final int boundBottom = boundChild.getBottom();
-                final int absScroll = Math.abs(scrollBy);
-
-                if (scrollBy < 0 && boundBottom + absScroll > paddedBottom) {
-                    // Don't scroll the bound view off the bottom of the screen.
-                    scrollBy = Math.max(0, boundBottom - paddedBottom);
-                } else if (scrollBy > 0 && boundTop - absScroll < paddedTop) {
-                    // Don't scroll the bound view off the top of the screen.
-                    scrollBy = Math.min(0, boundTop - paddedTop);
-                }
-            }
-
-            smoothScrollBy(scrollBy, duration);
-        }
-
-        void stop() {
-            removeCallbacks(this);
-        }
-
-        @Override
-        public void run() {
-            final int listHeight = getHeight();
-            final int firstPos = mFirstPosition;
-
-            switch (mMode) {
-            case MOVE_DOWN_POS: {
-                final int lastViewIndex = getChildCount() - 1;
-                final int lastPos = firstPos + lastViewIndex;
-
-                if (lastViewIndex < 0) {
-                    return;
-                }
-
-                if (lastPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View lastView = getChildAt(lastViewIndex);
-                final int lastViewHeight = lastView.getHeight();
-                final int lastViewTop = lastView.getTop();
-                final int lastViewPixelsShowing = listHeight - lastViewTop;
-                final int extraScroll = lastPos < mItemCount - 1 ?
-                        Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom;
-
-                final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
-                smoothScrollBy(scrollBy, mScrollDuration, true);
-
-                mLastSeenPos = lastPos;
-                if (lastPos < mTargetPos) {
-                    postOnAnimation(this);
-                }
-                break;
-            }
-
-            case MOVE_DOWN_BOUND: {
-                final int nextViewIndex = 1;
-                final int childCount = getChildCount();
-
-                if (firstPos == mBoundPos || childCount <= nextViewIndex
-                        || firstPos + childCount >= mItemCount) {
-                    return;
-                }
-                final int nextPos = firstPos + nextViewIndex;
-
-                if (nextPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View nextView = getChildAt(nextViewIndex);
-                final int nextViewHeight = nextView.getHeight();
-                final int nextViewTop = nextView.getTop();
-                final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll);
-                if (nextPos < mBoundPos) {
-                    smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll),
-                            mScrollDuration, true);
-
-                    mLastSeenPos = nextPos;
-
-                    postOnAnimation(this);
-                } else  {
-                    if (nextViewTop > extraScroll) {
-                        smoothScrollBy(nextViewTop - extraScroll, mScrollDuration, true);
-                    }
-                }
-                break;
-            }
-
-            case MOVE_UP_POS: {
-                if (firstPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View firstView = getChildAt(0);
-                if (firstView == null) {
-                    return;
-                }
-                final int firstViewTop = firstView.getTop();
-                final int extraScroll = firstPos > 0 ?
-                        Math.max(mExtraScroll, mListPadding.top) : mListPadding.top;
-
-                smoothScrollBy(firstViewTop - extraScroll, mScrollDuration, true);
-
-                mLastSeenPos = firstPos;
-
-                if (firstPos > mTargetPos) {
-                    postOnAnimation(this);
-                }
-                break;
-            }
-
-            case MOVE_UP_BOUND: {
-                final int lastViewIndex = getChildCount() - 2;
-                if (lastViewIndex < 0) {
-                    return;
-                }
-                final int lastPos = firstPos + lastViewIndex;
-
-                if (lastPos == mLastSeenPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                final View lastView = getChildAt(lastViewIndex);
-                final int lastViewHeight = lastView.getHeight();
-                final int lastViewTop = lastView.getTop();
-                final int lastViewPixelsShowing = listHeight - lastViewTop;
-                final int extraScroll = Math.max(mListPadding.top, mExtraScroll);
-                mLastSeenPos = lastPos;
-                if (lastPos > mBoundPos) {
-                    smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration, true);
-                    postOnAnimation(this);
-                } else {
-                    final int bottom = listHeight - extraScroll;
-                    final int lastViewBottom = lastViewTop + lastViewHeight;
-                    if (bottom > lastViewBottom) {
-                        smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration, true);
-                    }
-                }
-                break;
-            }
-
-            case MOVE_OFFSET: {
-                if (mLastSeenPos == firstPos) {
-                    // No new views, let things keep going.
-                    postOnAnimation(this);
-                    return;
-                }
-
-                mLastSeenPos = firstPos;
-
-                final int childCount = getChildCount();
-                final int position = mTargetPos;
-                final int lastPos = firstPos + childCount - 1;
-
-                int viewTravelCount = 0;
-                if (position < firstPos) {
-                    viewTravelCount = firstPos - position + 1;
-                } else if (position > lastPos) {
-                    viewTravelCount = position - lastPos;
-                }
-
-                // Estimate how many screens we should travel
-                final float screenTravelCount = (float) viewTravelCount / childCount;
-
-                final float modifier = Math.min(Math.abs(screenTravelCount), 1.f);
-                if (position < firstPos) {
-                    final int distance = (int) (-getHeight() * modifier);
-                    final int duration = (int) (mScrollDuration * modifier);
-                    smoothScrollBy(distance, duration, true);
-                    postOnAnimation(this);
-                } else if (position > lastPos) {
-                    final int distance = (int) (getHeight() * modifier);
-                    final int duration = (int) (mScrollDuration * modifier);
-                    smoothScrollBy(distance, duration, true);
-                    postOnAnimation(this);
-                } else {
-                    // On-screen, just scroll.
-                    final int targetTop = getChildAt(position - firstPos).getTop();
-                    final int distance = targetTop - mOffsetFromTop;
-                    final int duration = (int) (mScrollDuration *
-                            ((float) Math.abs(distance) / getHeight()));
-                    smoothScrollBy(distance, duration, true);
-                }
-                break;
-            }
-
-            default:
-                break;
-            }
-        }
-    }
-
     /**
      * The amount of friction applied to flings. The default value
      * is {@link ViewConfiguration#getScrollFriction}.
@@ -4784,20 +4418,27 @@
     }
 
     /**
+     * Override this for better control over position scrolling.
+     */
+    AbsPositionScroller createPositionScroller() {
+        return new PositionScroller();
+    }
+
+    /**
      * Smoothly scroll to the specified adapter position. The view will
      * scroll such that the indicated position is displayed.
      * @param position Scroll to this adapter position.
      */
     public void smoothScrollToPosition(int position) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
         mPositionScroller.start(position);
     }
 
     /**
      * Smoothly scroll to the specified adapter position. The view will scroll
-     * such that the indicated position is displayed <code>offset</code> pixels from
+     * such that the indicated position is displayed <code>offset</code> pixels below
      * the top edge of the view. If this is impossible, (e.g. the offset would scroll
      * the first or last item beyond the boundaries of the list) it will get as close
      * as possible. The scroll will take <code>duration</code> milliseconds to complete.
@@ -4809,14 +4450,14 @@
      */
     public void smoothScrollToPositionFromTop(int position, int offset, int duration) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
         mPositionScroller.startWithOffset(position, offset, duration);
     }
 
     /**
      * Smoothly scroll to the specified adapter position. The view will scroll
-     * such that the indicated position is displayed <code>offset</code> pixels from
+     * such that the indicated position is displayed <code>offset</code> pixels below
      * the top edge of the view. If this is impossible, (e.g. the offset would scroll
      * the first or last item beyond the boundaries of the list) it will get as close
      * as possible.
@@ -4827,9 +4468,9 @@
      */
     public void smoothScrollToPositionFromTop(int position, int offset) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
-        mPositionScroller.startWithOffset(position, offset);
+        mPositionScroller.startWithOffset(position, offset, offset);
     }
 
     /**
@@ -4837,13 +4478,14 @@
      * scroll such that the indicated position is displayed, but it will
      * stop early if scrolling further would scroll boundPosition out of
      * view.
+     *
      * @param position Scroll to this adapter position.
      * @param boundPosition Do not scroll if it would move this adapter
      *          position out of view.
      */
     public void smoothScrollToPosition(int position, int boundPosition) {
         if (mPositionScroller == null) {
-            mPositionScroller = new PositionScroller();
+            mPositionScroller = createPositionScroller();
         }
         mPositionScroller.start(position, boundPosition);
     }
@@ -6285,16 +5927,16 @@
         @Override
         public void onChanged() {
             super.onChanged();
-            if (mFastScroller != null) {
-                mFastScroller.onSectionsChanged();
+            if (mFastScroll != null) {
+                mFastScroll.onSectionsChanged();
             }
         }
 
         @Override
         public void onInvalidated() {
             super.onInvalidated();
-            if (mFastScroller != null) {
-                mFastScroller.onSectionsChanged();
+            if (mFastScroll != null) {
+                mFastScroll.onSectionsChanged();
             }
         }
     }
@@ -6555,18 +6197,12 @@
         void clear() {
             if (mViewTypeCount == 1) {
                 final ArrayList<View> scrap = mCurrentScrap;
-                final int scrapCount = scrap.size();
-                for (int i = 0; i < scrapCount; i++) {
-                    removeDetachedView(scrap.remove(scrapCount - 1 - i), false);
-                }
+                clearScrap(scrap);
             } else {
                 final int typeCount = mViewTypeCount;
                 for (int i = 0; i < typeCount; i++) {
                     final ArrayList<View> scrap = mScrapViews[i];
-                    final int scrapCount = scrap.size();
-                    for (int j = 0; j < scrapCount; j++) {
-                        removeDetachedView(scrap.remove(scrapCount - 1 - j), false);
-                    }
+                    clearScrap(scrap);
                 }
             }
 
@@ -6667,7 +6303,7 @@
             if (mViewTypeCount == 1) {
                 return retrieveFromScrap(mCurrentScrap, position);
             } else {
-                int whichScrap = mAdapter.getItemViewType(position);
+                final int whichScrap = mAdapter.getItemViewType(position);
                 if (whichScrap >= 0 && whichScrap < mScrapViews.length) {
                     return retrieveFromScrap(mScrapViews[whichScrap], position);
                 }
@@ -6739,13 +6375,6 @@
                     mScrapViews[viewType].add(scrap);
                 }
 
-                // Clear any system-managed transient state.
-                if (scrap.isAccessibilityFocused()) {
-                    scrap.clearAccessibilityFocus();
-                }
-
-                scrap.setAccessibilityDelegate(null);
-
                 if (mRecyclerListener != null) {
                     mRecyclerListener.onMovedToScrapHeap(scrap);
                 }
@@ -6819,7 +6448,6 @@
                         lp.scrappedFromPosition = mFirstActivePosition + i;
                         scrapViews.add(victim);
 
-                        victim.setAccessibilityDelegate(null);
                         if (hasListener) {
                             mRecyclerListener.onMovedToScrapHeap(victim);
                         }
@@ -6923,23 +6551,861 @@
                 }
             }
         }
+
+        private View retrieveFromScrap(ArrayList<View> scrapViews, int position) {
+            final int size = scrapViews.size();
+            if (size > 0) {
+                // See if we still have a view for this position or ID.
+                for (int i = 0; i < size; i++) {
+                    final View view = scrapViews.get(i);
+                    final AbsListView.LayoutParams params =
+                            (AbsListView.LayoutParams) view.getLayoutParams();
+
+                    if (mAdapterHasStableIds) {
+                        final long id = mAdapter.getItemId(position);
+                        if (id == params.itemId) {
+                            return scrapViews.remove(i);
+                        }
+                    } else if (params.scrappedFromPosition == position) {
+                        final View scrap = scrapViews.remove(i);
+                        clearAccessibilityFromScrap(scrap);
+                        return scrap;
+                    }
+                }
+                final View scrap = scrapViews.remove(size - 1);
+                clearAccessibilityFromScrap(scrap);
+                return scrap;
+            } else {
+                return null;
+            }
+        }
+
+        private void clearScrap(final ArrayList<View> scrap) {
+            final int scrapCount = scrap.size();
+            for (int j = 0; j < scrapCount; j++) {
+                removeDetachedView(scrap.remove(scrapCount - 1 - j), false);
+            }
+        }
+
+        private void clearAccessibilityFromScrap(View view) {
+            if (view.isAccessibilityFocused()) {
+                view.clearAccessibilityFocus();
+            }
+            view.setAccessibilityDelegate(null);
+        }
+
+        private void removeDetachedView(View child, boolean animate) {
+            child.setAccessibilityDelegate(null);
+            AbsListView.this.removeDetachedView(child, animate);
+        }
     }
 
-    static View retrieveFromScrap(ArrayList<View> scrapViews, int position) {
-        int size = scrapViews.size();
-        if (size > 0) {
-            // See if we still have a view for this position.
-            for (int i=0; i<size; i++) {
-                View view = scrapViews.get(i);
-                if (((AbsListView.LayoutParams)view.getLayoutParams())
-                        .scrappedFromPosition == position) {
-                    scrapViews.remove(i);
-                    return view;
+    /**
+     * Returns the height of the view for the specified position.
+     *
+     * @param position the item position
+     * @return view height in pixels
+     */
+    int getHeightForPosition(int position) {
+        final int firstVisiblePosition = getFirstVisiblePosition();
+        final int childCount = getChildCount();
+        final int index = position - firstVisiblePosition;
+        if (index >= 0 && index < childCount) {
+            // Position is on-screen, use existing view.
+            final View view = getChildAt(index);
+            return view.getHeight();
+        } else {
+            // Position is off-screen, obtain & recycle view.
+            final View view = obtainView(position, mIsScrap);
+            view.measure(mWidthMeasureSpec, MeasureSpec.UNSPECIFIED);
+            final int height = view.getMeasuredHeight();
+            mRecycler.addScrapView(view, position);
+            return height;
+        }
+    }
+
+    /**
+     * Sets the selected item and positions the selection y pixels from the top edge
+     * of the ListView. (If in touch mode, the item will not be selected but it will
+     * still be positioned appropriately.)
+     *
+     * @param position Index (starting at 0) of the data item to be selected.
+     * @param y The distance from the top edge of the ListView (plus padding) that the
+     *        item will be positioned.
+     */
+    public void setSelectionFromTop(int position, int y) {
+        if (mAdapter == null) {
+            return;
+        }
+
+        if (!isInTouchMode()) {
+            position = lookForSelectablePosition(position, true);
+            if (position >= 0) {
+                setNextSelectedPositionInt(position);
+            }
+        } else {
+            mResurrectToPosition = position;
+        }
+
+        if (position >= 0) {
+            mLayoutMode = LAYOUT_SPECIFIC;
+            mSpecificTop = mListPadding.top + y;
+
+            if (mNeedSync) {
+                mSyncPosition = position;
+                mSyncRowId = mAdapter.getItemId(position);
+            }
+
+            if (mPositionScroller != null) {
+                mPositionScroller.stop();
+            }
+            requestLayout();
+        }
+    }
+
+    /**
+     * Abstract positon scroller used to handle smooth scrolling.
+     */
+    static abstract class AbsPositionScroller {
+        public abstract void start(int position);
+        public abstract void start(int position, int boundPosition);
+        public abstract void startWithOffset(int position, int offset);
+        public abstract void startWithOffset(int position, int offset, int duration);
+        public abstract void stop();
+    }
+
+    /**
+     * Default position scroller that simulates a fling.
+     */
+    class PositionScroller extends AbsPositionScroller implements Runnable {
+        private static final int SCROLL_DURATION = 200;
+
+        private static final int MOVE_DOWN_POS = 1;
+        private static final int MOVE_UP_POS = 2;
+        private static final int MOVE_DOWN_BOUND = 3;
+        private static final int MOVE_UP_BOUND = 4;
+        private static final int MOVE_OFFSET = 5;
+
+        private int mMode;
+        private int mTargetPos;
+        private int mBoundPos;
+        private int mLastSeenPos;
+        private int mScrollDuration;
+        private final int mExtraScroll;
+
+        private int mOffsetFromTop;
+
+        PositionScroller() {
+            mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
+        }
+
+        @Override
+        public void start(final int position) {
+            stop();
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override public void run() {
+                        start(position);
+                    }
+                };
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
+            final int firstPos = mFirstPosition;
+            final int lastPos = firstPos + childCount - 1;
+
+            int viewTravelCount;
+            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
+            if (clampedPosition < firstPos) {
+                viewTravelCount = firstPos - clampedPosition + 1;
+                mMode = MOVE_UP_POS;
+            } else if (clampedPosition > lastPos) {
+                viewTravelCount = clampedPosition - lastPos + 1;
+                mMode = MOVE_DOWN_POS;
+            } else {
+                scrollToVisible(clampedPosition, INVALID_POSITION, SCROLL_DURATION);
+                return;
+            }
+
+            if (viewTravelCount > 0) {
+                mScrollDuration = SCROLL_DURATION / viewTravelCount;
+            } else {
+                mScrollDuration = SCROLL_DURATION;
+            }
+            mTargetPos = clampedPosition;
+            mBoundPos = INVALID_POSITION;
+            mLastSeenPos = INVALID_POSITION;
+
+            postOnAnimation(this);
+        }
+
+        @Override
+        public void start(final int position, final int boundPosition) {
+            stop();
+
+            if (boundPosition == INVALID_POSITION) {
+                start(position);
+                return;
+            }
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override public void run() {
+                        start(position, boundPosition);
+                    }
+                };
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
+            final int firstPos = mFirstPosition;
+            final int lastPos = firstPos + childCount - 1;
+
+            int viewTravelCount;
+            int clampedPosition = Math.max(0, Math.min(getCount() - 1, position));
+            if (clampedPosition < firstPos) {
+                final int boundPosFromLast = lastPos - boundPosition;
+                if (boundPosFromLast < 1) {
+                    // Moving would shift our bound position off the screen. Abort.
+                    return;
+                }
+
+                final int posTravel = firstPos - clampedPosition + 1;
+                final int boundTravel = boundPosFromLast - 1;
+                if (boundTravel < posTravel) {
+                    viewTravelCount = boundTravel;
+                    mMode = MOVE_UP_BOUND;
+                } else {
+                    viewTravelCount = posTravel;
+                    mMode = MOVE_UP_POS;
+                }
+            } else if (clampedPosition > lastPos) {
+                final int boundPosFromFirst = boundPosition - firstPos;
+                if (boundPosFromFirst < 1) {
+                    // Moving would shift our bound position off the screen. Abort.
+                    return;
+                }
+
+                final int posTravel = clampedPosition - lastPos + 1;
+                final int boundTravel = boundPosFromFirst - 1;
+                if (boundTravel < posTravel) {
+                    viewTravelCount = boundTravel;
+                    mMode = MOVE_DOWN_BOUND;
+                } else {
+                    viewTravelCount = posTravel;
+                    mMode = MOVE_DOWN_POS;
+                }
+            } else {
+                scrollToVisible(clampedPosition, boundPosition, SCROLL_DURATION);
+                return;
+            }
+
+            if (viewTravelCount > 0) {
+                mScrollDuration = SCROLL_DURATION / viewTravelCount;
+            } else {
+                mScrollDuration = SCROLL_DURATION;
+            }
+            mTargetPos = clampedPosition;
+            mBoundPos = boundPosition;
+            mLastSeenPos = INVALID_POSITION;
+
+            postOnAnimation(this);
+        }
+
+        @Override
+        public void startWithOffset(int position, int offset) {
+            startWithOffset(position, offset, SCROLL_DURATION);
+        }
+
+        @Override
+        public void startWithOffset(final int position, int offset, final int duration) {
+            stop();
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                final int postOffset = offset;
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override public void run() {
+                        startWithOffset(position, postOffset, duration);
+                    }
+                };
+                return;
+            }
+
+            final int childCount = getChildCount();
+            if (childCount == 0) {
+                // Can't scroll without children.
+                return;
+            }
+
+            offset += getPaddingTop();
+
+            mTargetPos = Math.max(0, Math.min(getCount() - 1, position));
+            mOffsetFromTop = offset;
+            mBoundPos = INVALID_POSITION;
+            mLastSeenPos = INVALID_POSITION;
+            mMode = MOVE_OFFSET;
+
+            final int firstPos = mFirstPosition;
+            final int lastPos = firstPos + childCount - 1;
+
+            int viewTravelCount;
+            if (mTargetPos < firstPos) {
+                viewTravelCount = firstPos - mTargetPos;
+            } else if (mTargetPos > lastPos) {
+                viewTravelCount = mTargetPos - lastPos;
+            } else {
+                // On-screen, just scroll.
+                final int targetTop = getChildAt(mTargetPos - firstPos).getTop();
+                smoothScrollBy(targetTop - offset, duration, true);
+                return;
+            }
+
+            // Estimate how many screens we should travel
+            final float screenTravelCount = (float) viewTravelCount / childCount;
+            mScrollDuration = screenTravelCount < 1 ?
+                    duration : (int) (duration / screenTravelCount);
+            mLastSeenPos = INVALID_POSITION;
+
+            postOnAnimation(this);
+        }
+
+        /**
+         * Scroll such that targetPos is in the visible padded region without scrolling
+         * boundPos out of view. Assumes targetPos is onscreen.
+         */
+        private void scrollToVisible(int targetPos, int boundPos, int duration) {
+            final int firstPos = mFirstPosition;
+            final int childCount = getChildCount();
+            final int lastPos = firstPos + childCount - 1;
+            final int paddedTop = mListPadding.top;
+            final int paddedBottom = getHeight() - mListPadding.bottom;
+
+            if (targetPos < firstPos || targetPos > lastPos) {
+                Log.w(TAG, "scrollToVisible called with targetPos " + targetPos +
+                        " not visible [" + firstPos + ", " + lastPos + "]");
+            }
+            if (boundPos < firstPos || boundPos > lastPos) {
+                // boundPos doesn't matter, it's already offscreen.
+                boundPos = INVALID_POSITION;
+            }
+
+            final View targetChild = getChildAt(targetPos - firstPos);
+            final int targetTop = targetChild.getTop();
+            final int targetBottom = targetChild.getBottom();
+            int scrollBy = 0;
+
+            if (targetBottom > paddedBottom) {
+                scrollBy = targetBottom - paddedBottom;
+            }
+            if (targetTop < paddedTop) {
+                scrollBy = targetTop - paddedTop;
+            }
+
+            if (scrollBy == 0) {
+                return;
+            }
+
+            if (boundPos >= 0) {
+                final View boundChild = getChildAt(boundPos - firstPos);
+                final int boundTop = boundChild.getTop();
+                final int boundBottom = boundChild.getBottom();
+                final int absScroll = Math.abs(scrollBy);
+
+                if (scrollBy < 0 && boundBottom + absScroll > paddedBottom) {
+                    // Don't scroll the bound view off the bottom of the screen.
+                    scrollBy = Math.max(0, boundBottom - paddedBottom);
+                } else if (scrollBy > 0 && boundTop - absScroll < paddedTop) {
+                    // Don't scroll the bound view off the top of the screen.
+                    scrollBy = Math.min(0, boundTop - paddedTop);
                 }
             }
-            return scrapViews.remove(size - 1);
-        } else {
-            return null;
+
+            smoothScrollBy(scrollBy, duration);
+        }
+
+        @Override
+        public void stop() {
+            removeCallbacks(this);
+        }
+
+        @Override
+        public void run() {
+            final int listHeight = getHeight();
+            final int firstPos = mFirstPosition;
+
+            switch (mMode) {
+            case MOVE_DOWN_POS: {
+                final int lastViewIndex = getChildCount() - 1;
+                final int lastPos = firstPos + lastViewIndex;
+
+                if (lastViewIndex < 0) {
+                    return;
+                }
+
+                if (lastPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View lastView = getChildAt(lastViewIndex);
+                final int lastViewHeight = lastView.getHeight();
+                final int lastViewTop = lastView.getTop();
+                final int lastViewPixelsShowing = listHeight - lastViewTop;
+                final int extraScroll = lastPos < mItemCount - 1 ?
+                        Math.max(mListPadding.bottom, mExtraScroll) : mListPadding.bottom;
+
+                final int scrollBy = lastViewHeight - lastViewPixelsShowing + extraScroll;
+                smoothScrollBy(scrollBy, mScrollDuration, true);
+
+                mLastSeenPos = lastPos;
+                if (lastPos < mTargetPos) {
+                    postOnAnimation(this);
+                }
+                break;
+            }
+
+            case MOVE_DOWN_BOUND: {
+                final int nextViewIndex = 1;
+                final int childCount = getChildCount();
+
+                if (firstPos == mBoundPos || childCount <= nextViewIndex
+                        || firstPos + childCount >= mItemCount) {
+                    return;
+                }
+                final int nextPos = firstPos + nextViewIndex;
+
+                if (nextPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View nextView = getChildAt(nextViewIndex);
+                final int nextViewHeight = nextView.getHeight();
+                final int nextViewTop = nextView.getTop();
+                final int extraScroll = Math.max(mListPadding.bottom, mExtraScroll);
+                if (nextPos < mBoundPos) {
+                    smoothScrollBy(Math.max(0, nextViewHeight + nextViewTop - extraScroll),
+                            mScrollDuration, true);
+
+                    mLastSeenPos = nextPos;
+
+                    postOnAnimation(this);
+                } else  {
+                    if (nextViewTop > extraScroll) {
+                        smoothScrollBy(nextViewTop - extraScroll, mScrollDuration, true);
+                    }
+                }
+                break;
+            }
+
+            case MOVE_UP_POS: {
+                if (firstPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View firstView = getChildAt(0);
+                if (firstView == null) {
+                    return;
+                }
+                final int firstViewTop = firstView.getTop();
+                final int extraScroll = firstPos > 0 ?
+                        Math.max(mExtraScroll, mListPadding.top) : mListPadding.top;
+
+                smoothScrollBy(firstViewTop - extraScroll, mScrollDuration, true);
+
+                mLastSeenPos = firstPos;
+
+                if (firstPos > mTargetPos) {
+                    postOnAnimation(this);
+                }
+                break;
+            }
+
+            case MOVE_UP_BOUND: {
+                final int lastViewIndex = getChildCount() - 2;
+                if (lastViewIndex < 0) {
+                    return;
+                }
+                final int lastPos = firstPos + lastViewIndex;
+
+                if (lastPos == mLastSeenPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                final View lastView = getChildAt(lastViewIndex);
+                final int lastViewHeight = lastView.getHeight();
+                final int lastViewTop = lastView.getTop();
+                final int lastViewPixelsShowing = listHeight - lastViewTop;
+                final int extraScroll = Math.max(mListPadding.top, mExtraScroll);
+                mLastSeenPos = lastPos;
+                if (lastPos > mBoundPos) {
+                    smoothScrollBy(-(lastViewPixelsShowing - extraScroll), mScrollDuration, true);
+                    postOnAnimation(this);
+                } else {
+                    final int bottom = listHeight - extraScroll;
+                    final int lastViewBottom = lastViewTop + lastViewHeight;
+                    if (bottom > lastViewBottom) {
+                        smoothScrollBy(-(bottom - lastViewBottom), mScrollDuration, true);
+                    }
+                }
+                break;
+            }
+
+            case MOVE_OFFSET: {
+                if (mLastSeenPos == firstPos) {
+                    // No new views, let things keep going.
+                    postOnAnimation(this);
+                    return;
+                }
+
+                mLastSeenPos = firstPos;
+
+                final int childCount = getChildCount();
+                final int position = mTargetPos;
+                final int lastPos = firstPos + childCount - 1;
+
+                int viewTravelCount = 0;
+                if (position < firstPos) {
+                    viewTravelCount = firstPos - position + 1;
+                } else if (position > lastPos) {
+                    viewTravelCount = position - lastPos;
+                }
+
+                // Estimate how many screens we should travel
+                final float screenTravelCount = (float) viewTravelCount / childCount;
+
+                final float modifier = Math.min(Math.abs(screenTravelCount), 1.f);
+                if (position < firstPos) {
+                    final int distance = (int) (-getHeight() * modifier);
+                    final int duration = (int) (mScrollDuration * modifier);
+                    smoothScrollBy(distance, duration, true);
+                    postOnAnimation(this);
+                } else if (position > lastPos) {
+                    final int distance = (int) (getHeight() * modifier);
+                    final int duration = (int) (mScrollDuration * modifier);
+                    smoothScrollBy(distance, duration, true);
+                    postOnAnimation(this);
+                } else {
+                    // On-screen, just scroll.
+                    final int targetTop = getChildAt(position - firstPos).getTop();
+                    final int distance = targetTop - mOffsetFromTop;
+                    final int duration = (int) (mScrollDuration *
+                            ((float) Math.abs(distance) / getHeight()));
+                    smoothScrollBy(distance, duration, true);
+                }
+                break;
+            }
+
+            default:
+                break;
+            }
+        }
+    }
+
+    /**
+     * Abstract position scroller that handles sub-position scrolling but has no
+     * understanding of layout.
+     */
+    abstract class AbsSubPositionScroller extends AbsPositionScroller {
+        private static final int DURATION_AUTO = -1;
+
+        private static final int DURATION_AUTO_MIN = 100;
+        private static final int DURATION_AUTO_MAX = 500;
+
+        private final SubScroller mSubScroller = new SubScroller();
+
+        /**
+         * The target offset in pixels between the top of the list and the top
+         * of the target position.
+         */
+        private int mOffset;
+
+        /**
+         * Scroll the minimum amount to get the target view entirely on-screen.
+         */
+        private void scrollToPosition(final int targetPosition, final boolean useOffset,
+                final int offset, final int boundPosition, final int duration) {
+            stop();
+
+            if (mDataChanged) {
+                // Wait until we're back in a stable state to try this.
+                mPositionScrollAfterLayout = new Runnable() {
+                    @Override
+                    public void run() {
+                        scrollToPosition(
+                                targetPosition, useOffset, offset, boundPosition, duration);
+                    }
+                };
+                return;
+            }
+
+            if (mAdapter == null) {
+                // Can't scroll anywhere without an adapter.
+                return;
+            }
+
+            final int itemCount = getCount();
+            final int clampedPosition = MathUtils.constrain(targetPosition, 0, itemCount - 1);
+            final int clampedBoundPosition = MathUtils.constrain(boundPosition, 0, itemCount - 1);
+            final int firstPosition = getFirstVisiblePosition();
+            final int lastPosition = firstPosition + getChildCount();
+            final int targetRow = getRowForPosition(clampedPosition);
+            final int firstRow = getRowForPosition(firstPosition);
+            final int lastRow = getRowForPosition(lastPosition);
+            if (useOffset || targetRow <= firstRow) {
+                // Offset so the target row is top-aligned.
+                mOffset = offset;
+            } else if (targetRow >= lastRow - 1) {
+                // Offset so the target row is bottom-aligned.
+                final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+                mOffset = getHeightForPosition(clampedPosition) - listHeight;
+            } else {
+                // Don't scroll, target is entirely on-screen.
+                return;
+            }
+
+            float endSubRow = targetRow;
+            if (clampedBoundPosition != INVALID_POSITION) {
+                final int boundRow = getRowForPosition(clampedBoundPosition);
+                if (boundRow >= firstRow && boundRow < lastRow && boundRow != targetRow) {
+                    endSubRow = computeBoundSubRow(targetRow, boundRow);
+                }
+            }
+
+            final View firstChild = getChildAt(0);
+            if (firstChild == null) {
+                return;
+            }
+
+            final int firstChildHeight = firstChild.getHeight();
+            final float startOffsetRatio;
+            if (firstChildHeight == 0) {
+                startOffsetRatio = 0;
+            } else {
+                startOffsetRatio = -firstChild.getTop() / (float) firstChildHeight;
+            }
+
+            final float startSubRow = MathUtils.constrain(
+                    firstRow + startOffsetRatio, 0, getCount());
+            if (startSubRow == endSubRow && mOffset == 0) {
+                // Don't scroll, target is already in position.
+                return;
+            }
+
+            final int durationMillis;
+            if (duration == DURATION_AUTO) {
+                final float subRowDelta = Math.abs(startSubRow - endSubRow);
+                durationMillis = (int) MathUtils.lerp(
+                        DURATION_AUTO_MIN, DURATION_AUTO_MAX, subRowDelta / getCount());
+            } else {
+                durationMillis = duration;
+            }
+
+            mSubScroller.startScroll(startSubRow, endSubRow, durationMillis);
+
+            postOnAnimation(mAnimationFrame);
+        }
+
+        /**
+         * Given a target row and offset, computes the sub-row position that
+         * aligns with the top of the list. If the offset is negative, the
+         * resulting sub-row will be smaller than the target row.
+         */
+        private float resolveOffset(int targetRow, int offset) {
+            // Compute the target sub-row position by finding the actual row
+            // indicated by the target and offset.
+            int remainingOffset = offset;
+            int targetHeight = getHeightForRow(targetRow);
+            if (offset < 0) {
+                // Subtract row heights until we find the right row.
+                while (targetRow > 0 && remainingOffset < 0) {
+                    remainingOffset += targetHeight;
+                    targetRow--;
+                    targetHeight = getHeightForRow(targetRow);
+                }
+            } else if (offset > 0) {
+                // Add row heights until we find the right row.
+                while (targetRow < getCount() - 1 && remainingOffset > targetHeight) {
+                    remainingOffset -= targetHeight;
+                    targetRow++;
+                    targetHeight = getHeightForRow(targetRow);
+                }
+            }
+
+            final float targetOffsetRatio;
+            if (remainingOffset < 0 || targetHeight == 0) {
+                targetOffsetRatio = 0;
+            } else {
+                targetOffsetRatio = remainingOffset / (float) targetHeight;
+            }
+
+            return targetRow + targetOffsetRatio;
+        }
+
+        private float computeBoundSubRow(int targetRow, int boundRow) {
+            final float targetSubRow = resolveOffset(targetRow, mOffset);
+            mOffset = 0;
+
+            // The target row is below the bound row, so the end position would
+            // push the bound position above the list. Abort!
+            if (targetSubRow >= boundRow) {
+                return boundRow;
+            }
+
+            // Compute the closest possible sub-position that wouldn't push the
+            // bound position's view further below the list.
+            final int listHeight = getHeight() - getPaddingTop() - getPaddingBottom();
+            final int boundHeight = getHeightForRow(boundRow);
+            final float boundSubRow = resolveOffset(boundRow, -listHeight + boundHeight);
+
+            return Math.max(boundSubRow, targetSubRow);
+        }
+
+        @Override
+        public void start(int position) {
+            scrollToPosition(position, false, 0, INVALID_POSITION, DURATION_AUTO);
+        }
+
+        @Override
+        public void start(int position, int boundPosition) {
+            scrollToPosition(position, false, 0, boundPosition, DURATION_AUTO);
+        }
+
+        @Override
+        public void startWithOffset(int position, int offset) {
+            scrollToPosition(position, true, offset, INVALID_POSITION, DURATION_AUTO);
+        }
+
+        @Override
+        public void startWithOffset(int position, int offset, int duration) {
+            scrollToPosition(position, true, offset, INVALID_POSITION, duration);
+        }
+
+        @Override
+        public void stop() {
+            removeCallbacks(mAnimationFrame);
+        }
+
+        /**
+         * Returns the height of a row, which is computed as the maximum height of
+         * the items in the row.
+         *
+         * @param row the row index
+         * @return row height in pixels
+         */
+        public abstract int getHeightForRow(int row);
+
+        /**
+         * Returns the row for the specified item position.
+         *
+         * @param position the item position
+         * @return the row index
+         */
+        public abstract int getRowForPosition(int position);
+
+        /**
+         * Returns the first item position within the specified row.
+         *
+         * @param row the row
+         * @return the position of the first item in the row
+         */
+        public abstract int getFirstPositionForRow(int row);
+
+        private void onAnimationFrame() {
+            final boolean shouldPost = mSubScroller.computePosition();
+            final float subRow = mSubScroller.getPosition();
+
+            final int row = (int) subRow;
+            final int position = getFirstPositionForRow(row);
+            if (position >= getCount()) {
+                // Invalid position, abort scrolling.
+                return;
+            }
+
+            final int rowHeight = getHeightForRow(row);
+            final int offset = (int) (rowHeight * (subRow - row));
+            final int addOffset = (int) (mOffset * mSubScroller.getInterpolatedValue());
+            setSelectionFromTop(position, -offset - addOffset);
+
+            if (shouldPost) {
+                postOnAnimation(mAnimationFrame);
+            }
+        }
+
+        private Runnable mAnimationFrame = new Runnable() {
+            @Override
+            public void run() {
+                onAnimationFrame();
+            }
+        };
+    }
+
+    /**
+     * Scroller capable of returning floating point positions.
+     */
+    static class SubScroller {
+        private static final Interpolator INTERPOLATOR = new AccelerateDecelerateInterpolator();
+
+        private float mStartPosition;
+        private float mEndPosition;
+        private long mStartTime;
+        private long mDuration;
+
+        private float mPosition;
+        private float mInterpolatedValue;
+
+        public void startScroll(float startPosition, float endPosition, int duration) {
+            mStartPosition = startPosition;
+            mEndPosition = endPosition;
+            mDuration = duration;
+
+            mStartTime = AnimationUtils.currentAnimationTimeMillis();
+            mPosition = startPosition;
+            mInterpolatedValue = 0;
+        }
+
+        public boolean computePosition() {
+            final long elapsed = AnimationUtils.currentAnimationTimeMillis() - mStartTime;
+            final float value;
+            if (mDuration <= 0) {
+                value = 1;
+            } else {
+                value = MathUtils.constrain(elapsed / (float) mDuration, 0, 1);
+            }
+
+            mInterpolatedValue = INTERPOLATOR.getInterpolation(value);
+            mPosition = (mEndPosition - mStartPosition) * mInterpolatedValue + mStartPosition;
+
+            return elapsed < mDuration;
+        }
+
+        public float getPosition() {
+            return mPosition;
+        }
+
+        public float getInterpolatedValue() {
+            return mInterpolatedValue;
         }
     }
 }
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index fe2fc96..438a9da 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -65,11 +65,15 @@
         super(context, attrs);
     }
 
-    public AbsSeekBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.SeekBar, defStyle, 0);
+    public AbsSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.SeekBar, defStyleAttr, defStyleRes);
         Drawable thumb = a.getDrawable(com.android.internal.R.styleable.SeekBar_thumb);
         setThumb(thumb); // will guess mThumbOffset if thumb != null...
         // ...but allow layout to override this
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index f26527f..6a4ad75 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -64,12 +64,16 @@
         this(context, attrs, 0);
     }
 
-    public AbsSpinner(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initAbsSpinner();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AbsSpinner, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.AbsSpinner, defStyleAttr, defStyleRes);
 
         CharSequence[] entries = a.getTextArray(R.styleable.AbsSpinner_entries);
         if (entries != null) {
diff --git a/core/java/android/widget/AbsoluteLayout.java b/core/java/android/widget/AbsoluteLayout.java
index 7df6aab..4ce0d5d 100644
--- a/core/java/android/widget/AbsoluteLayout.java
+++ b/core/java/android/widget/AbsoluteLayout.java
@@ -40,16 +40,19 @@
 @RemoteView
 public class AbsoluteLayout extends ViewGroup {
     public AbsoluteLayout(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public AbsoluteLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public AbsoluteLayout(Context context, AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsoluteLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsoluteLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/ActionMenuPresenter.java b/core/java/android/widget/ActionMenuPresenter.java
new file mode 100644
index 0000000..1f405a7
--- /dev/null
+++ b/core/java/android/widget/ActionMenuPresenter.java
@@ -0,0 +1,756 @@
+/*
+ * 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.widget;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseBooleanArray;
+import android.view.ActionProvider;
+import android.view.Gravity;
+import android.view.MenuItem;
+import android.view.SoundEffectConstants;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.ListPopupWindow.ForwardingListener;
+import com.android.internal.transition.ActionBarTransition;
+import com.android.internal.view.ActionBarPolicy;
+import com.android.internal.view.menu.ActionMenuItemView;
+import com.android.internal.view.menu.BaseMenuPresenter;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuPopupHelper;
+import com.android.internal.view.menu.MenuView;
+import com.android.internal.view.menu.SubMenuBuilder;
+
+import java.util.ArrayList;
+
+/**
+ * MenuPresenter for building action menus as seen in the action bar and action modes.
+ *
+ * @hide
+ */
+public class ActionMenuPresenter extends BaseMenuPresenter
+        implements ActionProvider.SubUiVisibilityListener {
+    private static final String TAG = "ActionMenuPresenter";
+
+    private View mOverflowButton;
+    private boolean mReserveOverflow;
+    private boolean mReserveOverflowSet;
+    private int mWidthLimit;
+    private int mActionItemWidthLimit;
+    private int mMaxItems;
+    private boolean mMaxItemsSet;
+    private boolean mStrictWidthLimit;
+    private boolean mWidthLimitSet;
+    private boolean mExpandedActionViewsExclusive;
+
+    private int mMinCellSize;
+
+    // Group IDs that have been added as actions - used temporarily, allocated here for reuse.
+    private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();
+
+    private View mScrapActionButtonView;
+
+    private OverflowPopup mOverflowPopup;
+    private ActionButtonSubmenu mActionButtonPopup;
+
+    private OpenOverflowRunnable mPostedOpenRunnable;
+    private ActionMenuPopupCallback mPopupCallback;
+
+    final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
+    int mOpenSubMenuId;
+
+    public ActionMenuPresenter(Context context) {
+        super(context, com.android.internal.R.layout.action_menu_layout,
+                com.android.internal.R.layout.action_menu_item_layout);
+    }
+
+    @Override
+    public void initForMenu(Context context, MenuBuilder menu) {
+        super.initForMenu(context, menu);
+
+        final Resources res = context.getResources();
+
+        final ActionBarPolicy abp = ActionBarPolicy.get(context);
+        if (!mReserveOverflowSet) {
+            mReserveOverflow = abp.showsOverflowMenuButton();
+        }
+
+        if (!mWidthLimitSet) {
+            mWidthLimit = abp.getEmbeddedMenuWidthLimit();
+        }
+
+        // Measure for initial configuration
+        if (!mMaxItemsSet) {
+            mMaxItems = abp.getMaxActionButtons();
+        }
+
+        int width = mWidthLimit;
+        if (mReserveOverflow) {
+            if (mOverflowButton == null) {
+                mOverflowButton = new OverflowMenuButton(mSystemContext);
+                final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+                mOverflowButton.measure(spec, spec);
+            }
+            width -= mOverflowButton.getMeasuredWidth();
+        } else {
+            mOverflowButton = null;
+        }
+
+        mActionItemWidthLimit = width;
+
+        mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density);
+
+        // Drop a scrap view as it may no longer reflect the proper context/config.
+        mScrapActionButtonView = null;
+    }
+
+    public void onConfigurationChanged(Configuration newConfig) {
+        if (!mMaxItemsSet) {
+            mMaxItems = mContext.getResources().getInteger(
+                    com.android.internal.R.integer.max_action_buttons);
+        }
+        if (mMenu != null) {
+            mMenu.onItemsChanged(true);
+        }
+    }
+
+    public void setWidthLimit(int width, boolean strict) {
+        mWidthLimit = width;
+        mStrictWidthLimit = strict;
+        mWidthLimitSet = true;
+    }
+
+    public void setReserveOverflow(boolean reserveOverflow) {
+        mReserveOverflow = reserveOverflow;
+        mReserveOverflowSet = true;
+    }
+
+    public void setItemLimit(int itemCount) {
+        mMaxItems = itemCount;
+        mMaxItemsSet = true;
+    }
+
+    public void setExpandedActionViewsExclusive(boolean isExclusive) {
+        mExpandedActionViewsExclusive = isExclusive;
+    }
+
+    @Override
+    public MenuView getMenuView(ViewGroup root) {
+        MenuView result = super.getMenuView(root);
+        ((ActionMenuView) result).setPresenter(this);
+        return result;
+    }
+
+    @Override
+    public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) {
+        View actionView = item.getActionView();
+        if (actionView == null || item.hasCollapsibleActionView()) {
+            actionView = super.getItemView(item, convertView, parent);
+        }
+        actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
+
+        final ActionMenuView menuParent = (ActionMenuView) parent;
+        final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
+        if (!menuParent.checkLayoutParams(lp)) {
+            actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
+        }
+        return actionView;
+    }
+
+    @Override
+    public void bindItemView(MenuItemImpl item, MenuView.ItemView itemView) {
+        itemView.initialize(item, 0);
+
+        final ActionMenuView menuView = (ActionMenuView) mMenuView;
+        final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
+        actionItemView.setItemInvoker(menuView);
+
+        if (mPopupCallback == null) {
+            mPopupCallback = new ActionMenuPopupCallback();
+        }
+        actionItemView.setPopupCallback(mPopupCallback);
+    }
+
+    @Override
+    public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
+        return item.isActionButton();
+    }
+
+    @Override
+    public void updateMenuView(boolean cleared) {
+        final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent();
+        if (menuViewParent != null) {
+            ActionBarTransition.beginDelayedTransition(menuViewParent);
+        }
+        super.updateMenuView(cleared);
+
+        ((View) mMenuView).requestLayout();
+
+        if (mMenu != null) {
+            final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems();
+            final int count = actionItems.size();
+            for (int i = 0; i < count; i++) {
+                final ActionProvider provider = actionItems.get(i).getActionProvider();
+                if (provider != null) {
+                    provider.setSubUiVisibilityListener(this);
+                }
+            }
+        }
+
+        final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ?
+                mMenu.getNonActionItems() : null;
+
+        boolean hasOverflow = false;
+        if (mReserveOverflow && nonActionItems != null) {
+            final int count = nonActionItems.size();
+            if (count == 1) {
+                hasOverflow = !nonActionItems.get(0).isActionViewExpanded();
+            } else {
+                hasOverflow = count > 0;
+            }
+        }
+
+        if (hasOverflow) {
+            if (mOverflowButton == null) {
+                mOverflowButton = new OverflowMenuButton(mSystemContext);
+            }
+            ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
+            if (parent != mMenuView) {
+                if (parent != null) {
+                    parent.removeView(mOverflowButton);
+                }
+                ActionMenuView menuView = (ActionMenuView) mMenuView;
+                menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams());
+            }
+        } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) {
+            ((ViewGroup) mMenuView).removeView(mOverflowButton);
+        }
+
+        ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow);
+    }
+
+    @Override
+    public boolean filterLeftoverView(ViewGroup parent, int childIndex) {
+        if (parent.getChildAt(childIndex) == mOverflowButton) return false;
+        return super.filterLeftoverView(parent, childIndex);
+    }
+
+    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
+        if (!subMenu.hasVisibleItems()) return false;
+
+        SubMenuBuilder topSubMenu = subMenu;
+        while (topSubMenu.getParentMenu() != mMenu) {
+            topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu();
+        }
+        View anchor = findViewForItem(topSubMenu.getItem());
+        if (anchor == null) {
+            if (mOverflowButton == null) return false;
+            anchor = mOverflowButton;
+        }
+
+        mOpenSubMenuId = subMenu.getItem().getItemId();
+        mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu);
+        mActionButtonPopup.setAnchorView(anchor);
+        mActionButtonPopup.show();
+        super.onSubMenuSelected(subMenu);
+        return true;
+    }
+
+    private View findViewForItem(MenuItem item) {
+        final ViewGroup parent = (ViewGroup) mMenuView;
+        if (parent == null) return null;
+
+        final int count = parent.getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = parent.getChildAt(i);
+            if (child instanceof MenuView.ItemView &&
+                    ((MenuView.ItemView) child).getItemData() == item) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Display the overflow menu if one is present.
+     * @return true if the overflow menu was shown, false otherwise.
+     */
+    public boolean showOverflowMenu() {
+        if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null &&
+                mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) {
+            OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true);
+            mPostedOpenRunnable = new OpenOverflowRunnable(popup);
+            // Post this for later; we might still need a layout for the anchor to be right.
+            ((View) mMenuView).post(mPostedOpenRunnable);
+
+            // ActionMenuPresenter uses null as a callback argument here
+            // to indicate overflow is opening.
+            super.onSubMenuSelected(null);
+
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Hide the overflow menu if it is currently showing.
+     *
+     * @return true if the overflow menu was hidden, false otherwise.
+     */
+    public boolean hideOverflowMenu() {
+        if (mPostedOpenRunnable != null && mMenuView != null) {
+            ((View) mMenuView).removeCallbacks(mPostedOpenRunnable);
+            mPostedOpenRunnable = null;
+            return true;
+        }
+
+        MenuPopupHelper popup = mOverflowPopup;
+        if (popup != null) {
+            popup.dismiss();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Dismiss all popup menus - overflow and submenus.
+     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
+     */
+    public boolean dismissPopupMenus() {
+        boolean result = hideOverflowMenu();
+        result |= hideSubMenus();
+        return result;
+    }
+
+    /**
+     * Dismiss all submenu popups.
+     *
+     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
+     */
+    public boolean hideSubMenus() {
+        if (mActionButtonPopup != null) {
+            mActionButtonPopup.dismiss();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @return true if the overflow menu is currently showing
+     */
+    public boolean isOverflowMenuShowing() {
+        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.
+     */
+    public boolean isOverflowReserved() {
+        return mReserveOverflow;
+    }
+
+    public boolean flagActionItems() {
+        final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
+        final int itemsSize = visibleItems.size();
+        int maxActions = mMaxItems;
+        int widthLimit = mActionItemWidthLimit;
+        final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        final ViewGroup parent = (ViewGroup) mMenuView;
+
+        int requiredItems = 0;
+        int requestedItems = 0;
+        int firstActionWidth = 0;
+        boolean hasOverflow = false;
+        for (int i = 0; i < itemsSize; i++) {
+            MenuItemImpl item = visibleItems.get(i);
+            if (item.requiresActionButton()) {
+                requiredItems++;
+            } else if (item.requestsActionButton()) {
+                requestedItems++;
+            } else {
+                hasOverflow = true;
+            }
+            if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) {
+                // Overflow everything if we have an expanded action view and we're
+                // space constrained.
+                maxActions = 0;
+            }
+        }
+
+        // Reserve a spot for the overflow item if needed.
+        if (mReserveOverflow &&
+                (hasOverflow || requiredItems + requestedItems > maxActions)) {
+            maxActions--;
+        }
+        maxActions -= requiredItems;
+
+        final SparseBooleanArray seenGroups = mActionButtonGroups;
+        seenGroups.clear();
+
+        int cellSize = 0;
+        int cellsRemaining = 0;
+        if (mStrictWidthLimit) {
+            cellsRemaining = widthLimit / mMinCellSize;
+            final int cellSizeRemaining = widthLimit % mMinCellSize;
+            cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining;
+        }
+
+        // Flag as many more requested items as will fit.
+        for (int i = 0; i < itemsSize; i++) {
+            MenuItemImpl item = visibleItems.get(i);
+
+            if (item.requiresActionButton()) {
+                View v = getItemView(item, mScrapActionButtonView, parent);
+                if (mScrapActionButtonView == null) {
+                    mScrapActionButtonView = v;
+                }
+                if (mStrictWidthLimit) {
+                    cellsRemaining -= ActionMenuView.measureChildForCells(v,
+                            cellSize, cellsRemaining, querySpec, 0);
+                } else {
+                    v.measure(querySpec, querySpec);
+                }
+                final int measuredWidth = v.getMeasuredWidth();
+                widthLimit -= measuredWidth;
+                if (firstActionWidth == 0) {
+                    firstActionWidth = measuredWidth;
+                }
+                final int groupId = item.getGroupId();
+                if (groupId != 0) {
+                    seenGroups.put(groupId, true);
+                }
+                item.setIsActionButton(true);
+            } else if (item.requestsActionButton()) {
+                // Items in a group with other items that already have an action slot
+                // can break the max actions rule, but not the width limit.
+                final int groupId = item.getGroupId();
+                final boolean inGroup = seenGroups.get(groupId);
+                boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
+                        (!mStrictWidthLimit || cellsRemaining > 0);
+
+                if (isAction) {
+                    View v = getItemView(item, mScrapActionButtonView, parent);
+                    if (mScrapActionButtonView == null) {
+                        mScrapActionButtonView = v;
+                    }
+                    if (mStrictWidthLimit) {
+                        final int cells = ActionMenuView.measureChildForCells(v,
+                                cellSize, cellsRemaining, querySpec, 0);
+                        cellsRemaining -= cells;
+                        if (cells == 0) {
+                            isAction = false;
+                        }
+                    } else {
+                        v.measure(querySpec, querySpec);
+                    }
+                    final int measuredWidth = v.getMeasuredWidth();
+                    widthLimit -= measuredWidth;
+                    if (firstActionWidth == 0) {
+                        firstActionWidth = measuredWidth;
+                    }
+
+                    if (mStrictWidthLimit) {
+                        isAction &= widthLimit >= 0;
+                    } else {
+                        // Did this push the entire first item past the limit?
+                        isAction &= widthLimit + firstActionWidth > 0;
+                    }
+                }
+
+                if (isAction && groupId != 0) {
+                    seenGroups.put(groupId, true);
+                } else if (inGroup) {
+                    // We broke the width limit. Demote the whole group, they all overflow now.
+                    seenGroups.put(groupId, false);
+                    for (int j = 0; j < i; j++) {
+                        MenuItemImpl areYouMyGroupie = visibleItems.get(j);
+                        if (areYouMyGroupie.getGroupId() == groupId) {
+                            // Give back the action slot
+                            if (areYouMyGroupie.isActionButton()) maxActions++;
+                            areYouMyGroupie.setIsActionButton(false);
+                        }
+                    }
+                }
+
+                if (isAction) maxActions--;
+
+                item.setIsActionButton(isAction);
+            } else {
+                // Neither requires nor requests an action button.
+                item.setIsActionButton(false);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+        dismissPopupMenus();
+        super.onCloseMenu(menu, allMenusAreClosing);
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        SavedState state = new SavedState();
+        state.openSubMenuId = mOpenSubMenuId;
+        return state;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState saved = (SavedState) state;
+        if (saved.openSubMenuId > 0) {
+            MenuItem item = mMenu.findItem(saved.openSubMenuId);
+            if (item != null) {
+                SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
+                onSubMenuSelected(subMenu);
+            }
+        }
+    }
+
+    @Override
+    public void onSubUiVisibilityChanged(boolean isVisible) {
+        if (isVisible) {
+            // Not a submenu, but treat it like one.
+            super.onSubMenuSelected(null);
+        } else {
+            mMenu.close(false);
+        }
+    }
+
+    public void setMenuView(ActionMenuView menuView) {
+        mMenuView = menuView;
+    }
+
+    private static class SavedState implements Parcelable {
+        public int openSubMenuId;
+
+        SavedState() {
+        }
+
+        SavedState(Parcel in) {
+            openSubMenuId = in.readInt();
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(openSubMenuId);
+        }
+
+        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];
+            }
+        };
+    }
+
+    private class OverflowMenuButton extends ImageButton implements ActionMenuView.ActionMenuChildView {
+        public OverflowMenuButton(Context context) {
+            super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle);
+
+            setClickable(true);
+            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
+        public boolean performClick() {
+            if (super.performClick()) {
+                return true;
+            }
+
+            playSoundEffect(SoundEffectConstants.CLICK);
+            showOverflowMenu();
+            return true;
+        }
+
+        @Override
+        public boolean needsDividerBefore() {
+            return false;
+        }
+
+        @Override
+        public boolean needsDividerAfter() {
+            return false;
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
+                // Fill available height
+                heightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                        MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
+            }
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(info);
+            info.setCanOpenPopup(true);
+        }
+    }
+
+    private class OverflowPopup extends MenuPopupHelper {
+        public OverflowPopup(Context context, MenuBuilder menu, View anchorView,
+                boolean overflowOnly) {
+            super(context, menu, anchorView, overflowOnly);
+            setGravity(Gravity.END);
+            setCallback(mPopupPresenterCallback);
+        }
+
+        @Override
+        public void onDismiss() {
+            super.onDismiss();
+            mMenu.close();
+            mOverflowPopup = null;
+        }
+    }
+
+    private class ActionButtonSubmenu extends MenuPopupHelper {
+        private SubMenuBuilder mSubMenu;
+
+        public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) {
+            super(context, subMenu);
+            mSubMenu = subMenu;
+
+            MenuItemImpl item = (MenuItemImpl) subMenu.getItem();
+            if (!item.isActionButton()) {
+                // Give a reasonable anchor to nested submenus.
+                setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton);
+            }
+
+            setCallback(mPopupPresenterCallback);
+
+            boolean preserveIconSpacing = false;
+            final int count = subMenu.size();
+            for (int i = 0; i < count; i++) {
+                MenuItem childItem = subMenu.getItem(i);
+                if (childItem.isVisible() && childItem.getIcon() != null) {
+                    preserveIconSpacing = true;
+                    break;
+                }
+            }
+            setForceShowIcon(preserveIconSpacing);
+        }
+
+        @Override
+        public void onDismiss() {
+            super.onDismiss();
+            mActionButtonPopup = null;
+            mOpenSubMenuId = 0;
+        }
+    }
+
+    private class PopupPresenterCallback implements Callback {
+
+        @Override
+        public boolean onOpenSubMenu(MenuBuilder subMenu) {
+            if (subMenu == null) return false;
+
+            mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
+            final Callback cb = getCallback();
+            return cb != null ? cb.onOpenSubMenu(subMenu) : false;
+        }
+
+        @Override
+        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
+            if (menu instanceof SubMenuBuilder) {
+                ((SubMenuBuilder) menu).getRootMenu().close(false);
+            }
+            final Callback cb = getCallback();
+            if (cb != null) {
+                cb.onCloseMenu(menu, allMenusAreClosing);
+            }
+        }
+    }
+
+    private class OpenOverflowRunnable implements Runnable {
+        private OverflowPopup mPopup;
+
+        public OpenOverflowRunnable(OverflowPopup popup) {
+            mPopup = popup;
+        }
+
+        public void run() {
+            mMenu.changeMenuMode();
+            final View menuView = (View) mMenuView;
+            if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) {
+                mOverflowPopup = mPopup;
+            }
+            mPostedOpenRunnable = null;
+        }
+    }
+
+    private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback {
+        @Override
+        public ListPopupWindow getPopup() {
+            return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
+        }
+    }
+}
diff --git a/core/java/android/widget/ActionMenuView.java b/core/java/android/widget/ActionMenuView.java
new file mode 100644
index 0000000..32c7086
--- /dev/null
+++ b/core/java/android/widget/ActionMenuView.java
@@ -0,0 +1,648 @@
+/*
+ * 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.widget;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import com.android.internal.view.menu.ActionMenuItemView;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuItemImpl;
+import com.android.internal.view.menu.MenuView;
+
+/**
+ * ActionMenuView is a presentation of a series of menu options as a View. It provides
+ * several top level options as action buttons while spilling remaining options over as
+ * items in an overflow menu. This allows applications to present packs of actions inline with
+ * specific or repeating content.
+ */
+public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvoker, MenuView {
+    private static final String TAG = "ActionMenuView";
+    
+    static final int MIN_CELL_SIZE = 56; // dips
+    static final int GENERATED_ITEM_PADDING = 4; // dips
+
+    private MenuBuilder mMenu;
+
+    private boolean mReserveOverflow;
+    private ActionMenuPresenter mPresenter;
+    private boolean mFormatItems;
+    private int mFormatItemsWidth;
+    private int mMinCellSize;
+    private int mGeneratedItemPadding;
+
+    public ActionMenuView(Context context) {
+        this(context, null);
+    }
+    
+    public ActionMenuView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setBaselineAligned(false);
+        final float density = context.getResources().getDisplayMetrics().density;
+        mMinCellSize = (int) (MIN_CELL_SIZE * density);
+        mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density);
+    }
+
+    /** @hide */
+    public void setPresenter(ActionMenuPresenter presenter) {
+        mPresenter = presenter;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mPresenter.updateMenuView(false);
+
+        if (mPresenter != null && mPresenter.isOverflowMenuShowing()) {
+            mPresenter.hideOverflowMenu();
+            mPresenter.showOverflowMenu();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // If we've been given an exact size to match, apply special formatting during layout.
+        final boolean wasFormatted = mFormatItems;
+        mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
+
+        if (wasFormatted != mFormatItems) {
+            mFormatItemsWidth = 0; // Reset this when switching modes
+        }
+
+        // Special formatting can change whether items can fit as action buttons.
+        // Kick the menu and update presenters when this changes.
+        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) {
+            mFormatItemsWidth = widthSize;
+            mMenu.onItemsChanged(true);
+        }
+
+        if (mFormatItems) {
+            onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec);
+        } else {
+            // Previous measurement at exact format may have set margins - reset them.
+            final int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                lp.leftMargin = lp.rightMargin = 0;
+            }
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+
+    private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) {
+        // We already know the width mode is EXACTLY if we're here.
+        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+
+        final int widthPadding = getPaddingLeft() + getPaddingRight();
+        final int heightPadding = getPaddingTop() + getPaddingBottom();
+
+        final int itemHeightSpec = getChildMeasureSpec(heightMeasureSpec, heightPadding,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        widthSize -= widthPadding;
+
+        // Divide the view into cells.
+        final int cellCount = widthSize / mMinCellSize;
+        final int cellSizeRemaining = widthSize % mMinCellSize;
+
+        if (cellCount == 0) {
+            // Give up, nothing fits.
+            setMeasuredDimension(widthSize, 0);
+            return;
+        }
+
+        final int cellSize = mMinCellSize + cellSizeRemaining / cellCount;
+
+        int cellsRemaining = cellCount;
+        int maxChildHeight = 0;
+        int maxCellsUsed = 0;
+        int expandableItemCount = 0;
+        int visibleItemCount = 0;
+        boolean hasOverflow = false;
+
+        // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64.
+        long smallestItemsAt = 0;
+
+        final int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) continue;
+
+            final boolean isGeneratedItem = child instanceof ActionMenuItemView;
+            visibleItemCount++;
+
+            if (isGeneratedItem) {
+                // Reset padding for generated menu item views; it may change below
+                // and views are recycled.
+                child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0);
+            }
+
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            lp.expanded = false;
+            lp.extraPixels = 0;
+            lp.cellsUsed = 0;
+            lp.expandable = false;
+            lp.leftMargin = 0;
+            lp.rightMargin = 0;
+            lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText();
+
+            // Overflow always gets 1 cell. No more, no less.
+            final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
+
+            final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable,
+                    itemHeightSpec, heightPadding);
+
+            maxCellsUsed = Math.max(maxCellsUsed, cellsUsed);
+            if (lp.expandable) expandableItemCount++;
+            if (lp.isOverflowButton) hasOverflow = true;
+
+            cellsRemaining -= cellsUsed;
+            maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
+            if (cellsUsed == 1) smallestItemsAt |= (1 << i);
+        }
+
+        // When we have overflow and a single expanded (text) item, we want to try centering it
+        // visually in the available space even though overflow consumes some of it.
+        final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2;
+
+        // Divide space for remaining cells if we have items that can expand.
+        // Try distributing whole leftover cells to smaller items first.
+
+        boolean needsExpansion = false;
+        while (expandableItemCount > 0 && cellsRemaining > 0) {
+            int minCells = Integer.MAX_VALUE;
+            long minCellsAt = 0; // Bit locations are indices of relevant child views
+            int minCellsItemCount = 0;
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+                // Don't try to expand items that shouldn't.
+                if (!lp.expandable) continue;
+
+                // Mark indices of children that can receive an extra cell.
+                if (lp.cellsUsed < minCells) {
+                    minCells = lp.cellsUsed;
+                    minCellsAt = 1 << i;
+                    minCellsItemCount = 1;
+                } else if (lp.cellsUsed == minCells) {
+                    minCellsAt |= 1 << i;
+                    minCellsItemCount++;
+                }
+            }
+
+            // Items that get expanded will always be in the set of smallest items when we're done.
+            smallestItemsAt |= minCellsAt;
+
+            if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
+
+            // We have enough cells, all minimum size items will be incremented.
+            minCells++;
+
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                if ((minCellsAt & (1 << i)) == 0) {
+                    // If this item is already at our small item count, mark it for later.
+                    if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i;
+                    continue;
+                }
+
+                if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) {
+                    // Add padding to this item such that it centers.
+                    child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0);
+                }
+                lp.cellsUsed++;
+                lp.expanded = true;
+                cellsRemaining--;
+            }
+
+            needsExpansion = true;
+        }
+
+        // Divide any space left that wouldn't divide along cell boundaries
+        // evenly among the smallest items
+
+        final boolean singleItem = !hasOverflow && visibleItemCount == 1;
+        if (cellsRemaining > 0 && smallestItemsAt != 0 &&
+                (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) {
+            float expandCount = Long.bitCount(smallestItemsAt);
+
+            if (!singleItem) {
+                // The items at the far edges may only expand by half in order to pin to either side.
+                if ((smallestItemsAt & 1) != 0) {
+                    LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams();
+                    if (!lp.preventEdgeOffset) expandCount -= 0.5f;
+                }
+                if ((smallestItemsAt & (1 << (childCount - 1))) != 0) {
+                    LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams());
+                    if (!lp.preventEdgeOffset) expandCount -= 0.5f;
+                }
+            }
+
+            final int extraPixels = expandCount > 0 ?
+                    (int) (cellsRemaining * cellSize / expandCount) : 0;
+
+            for (int i = 0; i < childCount; i++) {
+                if ((smallestItemsAt & (1 << i)) == 0) continue;
+
+                final View child = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+                if (child instanceof ActionMenuItemView) {
+                    // If this is one of our views, expand and measure at the larger size.
+                    lp.extraPixels = extraPixels;
+                    lp.expanded = true;
+                    if (i == 0 && !lp.preventEdgeOffset) {
+                        // First item gets part of its new padding pushed out of sight.
+                        // The last item will get this implicitly from layout.
+                        lp.leftMargin = -extraPixels / 2;
+                    }
+                    needsExpansion = true;
+                } else if (lp.isOverflowButton) {
+                    lp.extraPixels = extraPixels;
+                    lp.expanded = true;
+                    lp.rightMargin = -extraPixels / 2;
+                    needsExpansion = true;
+                } else {
+                    // If we don't know what it is, give it some margins instead
+                    // and let it center within its space. We still want to pin
+                    // against the edges.
+                    if (i != 0) {
+                        lp.leftMargin = extraPixels / 2;
+                    }
+                    if (i != childCount - 1) {
+                        lp.rightMargin = extraPixels / 2;
+                    }
+                }
+            }
+
+            cellsRemaining = 0;
+        }
+
+        // Remeasure any items that have had extra space allocated to them.
+        if (needsExpansion) {
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+                if (!lp.expanded) continue;
+
+                final int width = lp.cellsUsed * cellSize + lp.extraPixels;
+                child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                        itemHeightSpec);
+            }
+        }
+
+        if (heightMode != MeasureSpec.EXACTLY) {
+            heightSize = maxChildHeight;
+        }
+
+        setMeasuredDimension(widthSize, heightSize);
+    }
+
+    /**
+     * Measure a child view to fit within cell-based formatting. The child's width
+     * will be measured to a whole multiple of cellSize.
+     *
+     * <p>Sets the expandable and cellsUsed fields of LayoutParams.
+     *
+     * @param child Child to measure
+     * @param cellSize Size of one cell
+     * @param cellsRemaining Number of cells remaining that this view can expand to fill
+     * @param parentHeightMeasureSpec MeasureSpec used by the parent view
+     * @param parentHeightPadding Padding present in the parent view
+     * @return Number of cells this child was measured to occupy
+     */
+    static int measureChildForCells(View child, int cellSize, int cellsRemaining,
+            int parentHeightMeasureSpec, int parentHeightPadding) {
+        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+        final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) -
+                parentHeightPadding;
+        final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec);
+        final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode);
+
+        final ActionMenuItemView itemView = child instanceof ActionMenuItemView ?
+                (ActionMenuItemView) child : null;
+        final boolean hasText = itemView != null && itemView.hasText();
+
+        int cellsUsed = 0;
+        if (cellsRemaining > 0 && (!hasText || cellsRemaining >= 2)) {
+            final int childWidthSpec = MeasureSpec.makeMeasureSpec(
+                    cellSize * cellsRemaining, MeasureSpec.AT_MOST);
+            child.measure(childWidthSpec, childHeightSpec);
+
+            final int measuredWidth = child.getMeasuredWidth();
+            cellsUsed = measuredWidth / cellSize;
+            if (measuredWidth % cellSize != 0) cellsUsed++;
+            if (hasText && cellsUsed < 2) cellsUsed = 2;
+        }
+
+        final boolean expandable = !lp.isOverflowButton && hasText;
+        lp.expandable = expandable;
+
+        lp.cellsUsed = cellsUsed;
+        final int targetWidth = cellsUsed * cellSize;
+        child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY),
+                childHeightSpec);
+        return cellsUsed;
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        if (!mFormatItems) {
+            super.onLayout(changed, left, top, right, bottom);
+            return;
+        }
+
+        final int childCount = getChildCount();
+        final int midVertical = (top + bottom) / 2;
+        final int dividerWidth = getDividerWidth();
+        int overflowWidth = 0;
+        int nonOverflowWidth = 0;
+        int nonOverflowCount = 0;
+        int widthRemaining = right - left - getPaddingRight() - getPaddingLeft();
+        boolean hasOverflow = false;
+        final boolean isLayoutRtl = isLayoutRtl();
+        for (int i = 0; i < childCount; i++) {
+            final View v = getChildAt(i);
+            if (v.getVisibility() == GONE) {
+                continue;
+            }
+
+            LayoutParams p = (LayoutParams) v.getLayoutParams();
+            if (p.isOverflowButton) {
+                overflowWidth = v.getMeasuredWidth();
+                if (hasDividerBeforeChildAt(i)) {
+                    overflowWidth += dividerWidth;
+                }
+
+                int height = v.getMeasuredHeight();
+                int r;
+                int l;
+                if (isLayoutRtl) {
+                    l = getPaddingLeft() + p.leftMargin;
+                    r = l + overflowWidth;
+                } else {
+                    r = getWidth() - getPaddingRight() - p.rightMargin;
+                    l = r - overflowWidth;
+                }
+                int t = midVertical - (height / 2);
+                int b = t + height;
+                v.layout(l, t, r, b);
+
+                widthRemaining -= overflowWidth;
+                hasOverflow = true;
+            } else {
+                final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin;
+                nonOverflowWidth += size;
+                widthRemaining -= size;
+                if (hasDividerBeforeChildAt(i)) {
+                    nonOverflowWidth += dividerWidth;
+                }
+                nonOverflowCount++;
+            }
+        }
+
+        if (childCount == 1 && !hasOverflow) {
+            // Center a single child
+            final View v = getChildAt(0);
+            final int width = v.getMeasuredWidth();
+            final int height = v.getMeasuredHeight();
+            final int midHorizontal = (right - left) / 2;
+            final int l = midHorizontal - width / 2;
+            final int t = midVertical - height / 2;
+            v.layout(l, t, l + width, t + height);
+            return;
+        }
+
+        final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1);
+        final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0);
+
+        if (isLayoutRtl) {
+            int startRight = getWidth() - getPaddingRight();
+            for (int i = 0; i < childCount; i++) {
+                final View v = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) v.getLayoutParams();
+                if (v.getVisibility() == GONE || lp.isOverflowButton) {
+                    continue;
+                }
+
+                startRight -= lp.rightMargin;
+                int width = v.getMeasuredWidth();
+                int height = v.getMeasuredHeight();
+                int t = midVertical - height / 2;
+                v.layout(startRight - width, t, startRight, t + height);
+                startRight -= width + lp.leftMargin + spacerSize;
+            }
+        } else {
+            int startLeft = getPaddingLeft();
+            for (int i = 0; i < childCount; i++) {
+                final View v = getChildAt(i);
+                final LayoutParams lp = (LayoutParams) v.getLayoutParams();
+                if (v.getVisibility() == GONE || lp.isOverflowButton) {
+                    continue;
+                }
+
+                startLeft += lp.leftMargin;
+                int width = v.getMeasuredWidth();
+                int height = v.getMeasuredHeight();
+                int t = midVertical - height / 2;
+                v.layout(startLeft, t, startLeft + width, t + height);
+                startLeft += width + lp.rightMargin + spacerSize;
+            }
+        }
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mPresenter.dismissPopupMenus();
+    }
+
+    /** @hide */
+    public boolean isOverflowReserved() {
+        return mReserveOverflow;
+    }
+
+    /** @hide */
+    public void setOverflowReserved(boolean reserveOverflow) {
+        mReserveOverflow = reserveOverflow;
+    }
+
+    @Override
+    protected LayoutParams generateDefaultLayoutParams() {
+        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
+                LayoutParams.WRAP_CONTENT);
+        params.gravity = Gravity.CENTER_VERTICAL;
+        return params;
+    }
+    
+    @Override
+    public LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        if (p != null) {
+            final LayoutParams result = p instanceof LayoutParams
+                    ? new LayoutParams((LayoutParams) p)
+                    : new LayoutParams(p);
+            if (result.gravity <= Gravity.NO_GRAVITY) {
+                result.gravity = Gravity.CENTER_VERTICAL;
+            }
+            return result;
+        }
+        return generateDefaultLayoutParams();
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p != null && p instanceof LayoutParams;
+    }
+
+    /** @hide */
+    public LayoutParams generateOverflowButtonLayoutParams() {
+        LayoutParams result = generateDefaultLayoutParams();
+        result.isOverflowButton = true;
+        return result;
+    }
+
+    /** @hide */
+    public boolean invokeItem(MenuItemImpl item) {
+        return mMenu.performItemAction(item, 0);
+    }
+
+    /** @hide */
+    public int getWindowAnimations() {
+        return 0;
+    }
+
+    /** @hide */
+    public void initialize(MenuBuilder menu) {
+        mMenu = menu;
+    }
+
+    /**
+     * Returns the Menu object that this ActionMenuView is currently presenting.
+     *
+     * <p>Applications should use this method to obtain the ActionMenuView's Menu object
+     * and inflate or add content to it as necessary.</p>
+     *
+     * @return the Menu presented by this view
+     */
+    public Menu getMenu() {
+        if (mMenu == null) {
+            final Context context = getContext();
+            mMenu = new MenuBuilder(context);
+            mPresenter = new ActionMenuPresenter(context);
+            mPresenter.initForMenu(context, mMenu);
+            mPresenter.setMenuView(this);
+        }
+
+        return mMenu;
+    }
+
+    /**
+     * @hide Private LinearLayout (superclass) API. Un-hide if LinearLayout API is made public.
+     */
+    @Override
+    protected boolean hasDividerBeforeChildAt(int childIndex) {
+        if (childIndex == 0) {
+            return false;
+        }
+        final View childBefore = getChildAt(childIndex - 1);
+        final View child = getChildAt(childIndex);
+        boolean result = false;
+        if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) {
+            result |= ((ActionMenuChildView) childBefore).needsDividerAfter();
+        }
+        if (childIndex > 0 && child instanceof ActionMenuChildView) {
+            result |= ((ActionMenuChildView) child).needsDividerBefore();
+        }
+        return result;
+    }
+
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        return false;
+    }
+
+    /** @hide */
+    public interface ActionMenuChildView {
+        public boolean needsDividerBefore();
+        public boolean needsDividerAfter();
+    }
+
+    public static class LayoutParams extends LinearLayout.LayoutParams {
+        /** @hide */
+        @ViewDebug.ExportedProperty(category = "layout")
+        public boolean isOverflowButton;
+
+        /** @hide */
+        @ViewDebug.ExportedProperty(category = "layout")
+        public int cellsUsed;
+
+        /** @hide */
+        @ViewDebug.ExportedProperty(category = "layout")
+        public int extraPixels;
+
+        /** @hide */
+        @ViewDebug.ExportedProperty(category = "layout")
+        public boolean expandable;
+
+        /** @hide */
+        @ViewDebug.ExportedProperty(category = "layout")
+        public boolean preventEdgeOffset;
+
+        /** @hide */
+        public boolean expanded;
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+        }
+
+        public LayoutParams(ViewGroup.LayoutParams other) {
+            super(other);
+        }
+
+        public LayoutParams(LayoutParams other) {
+            super((LinearLayout.LayoutParams) other);
+            isOverflowButton = other.isOverflowButton;
+        }
+
+        public LayoutParams(int width, int height) {
+            super(width, height);
+            isOverflowButton = false;
+        }
+
+        /** @hide */
+        public LayoutParams(int width, int height, boolean isOverflowButton) {
+            super(width, height);
+            this.isOverflowButton = isOverflowButton;
+        }
+    }
+}
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 8612964..f9af2f9 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -18,7 +18,6 @@
 
 import com.android.internal.R;
 
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -31,7 +30,6 @@
 import android.util.Log;
 import android.view.ActionProvider;
 import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
@@ -204,13 +202,32 @@
      *
      * @param context The application environment.
      * @param attrs A collection of attributes.
-     * @param defStyle The default style to apply to this view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public ActivityChooserView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ActivityChooserView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Create a new instance.
+     *
+     * @param context The application environment.
+     * @param attrs A collection of attributes.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public ActivityChooserView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         TypedArray attributesArray = context.obtainStyledAttributes(attrs,
-                R.styleable.ActivityChooserView, defStyle, 0);
+                R.styleable.ActivityChooserView, defStyleAttr, defStyleRes);
 
         mInitialActivityCount = attributesArray.getInt(
                 R.styleable.ActivityChooserView_initialActivityCount,
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index a06344f..1da22ca 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -223,15 +223,19 @@
     boolean mBlockLayoutRequests = false;
 
     public AdapterView(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public AdapterView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public AdapterView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AdapterView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AdapterView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         // If not explicitly specified this view is important for accessibility.
         if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 90e949a..1bc2f4b 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -173,10 +173,15 @@
     }
 
     public AdapterViewAnimator(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AdapterViewAnimator, defStyleAttr, 0);
+    public AdapterViewAnimator(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.AdapterViewAnimator, defStyleAttr, defStyleRes);
         int resource = a.getResourceId(
                 com.android.internal.R.styleable.AdapterViewAnimator_inAnimation, 0);
         if (resource > 0) {
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index aea029b..3b026bd 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -59,10 +59,19 @@
     }
 
     public AdapterViewFlipper(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.AdapterViewFlipper);
+    public AdapterViewFlipper(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AdapterViewFlipper(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.AdapterViewFlipper, defStyleAttr, defStyleRes);
         mFlipInterval = a.getInt(
                 com.android.internal.R.styleable.AdapterViewFlipper_flipInterval, DEFAULT_INTERVAL);
         mAutoStart = a.getBoolean(
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index c7da818..5b80648 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -67,27 +67,30 @@
         this(context, attrs, 0);
     }
 
-    public AnalogClock(Context context, AttributeSet attrs,
-                       int defStyle) {
-        super(context, attrs, defStyle);
-        Resources r = mContext.getResources();
-        TypedArray a =
-                context.obtainStyledAttributes(
-                        attrs, com.android.internal.R.styleable.AnalogClock, defStyle, 0);
+    public AnalogClock(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AnalogClock(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final Resources r = context.getResources();
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.AnalogClock, defStyleAttr, defStyleRes);
 
         mDial = a.getDrawable(com.android.internal.R.styleable.AnalogClock_dial);
         if (mDial == null) {
-            mDial = r.getDrawable(com.android.internal.R.drawable.clock_dial);
+            mDial = context.getDrawable(com.android.internal.R.drawable.clock_dial);
         }
 
         mHourHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_hour);
         if (mHourHand == null) {
-            mHourHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_hour);
+            mHourHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_hour);
         }
 
         mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);
         if (mMinuteHand == null) {
-            mMinuteHand = r.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
+            mMinuteHand = context.getDrawable(com.android.internal.R.drawable.clock_hand_minute);
         }
 
         mCalendar = new Time();
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 34cfea5..10e56c7 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -322,7 +322,7 @@
             CharSequence grpName, CharSequence description, boolean dangerous) {
         LayoutInflater inflater = (LayoutInflater)context.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
-        Drawable icon = context.getResources().getDrawable(dangerous
+        Drawable icon = context.getDrawable(dangerous
                 ? R.drawable.ic_bullet_key_permission : R.drawable.ic_text_dot);
         return getPermissionItemViewOld(context, inflater, grpName,
                 description, dangerous, icon);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index f0eb94f..eb232fd 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -133,17 +133,21 @@
         this(context, attrs, com.android.internal.R.attr.autoCompleteTextViewStyle);
     }
 
-    public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AutoCompleteTextView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mPopup = new ListPopupWindow(context, attrs,
                 com.android.internal.R.attr.autoCompleteTextViewStyle);
         mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
         mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
 
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.AutoCompleteTextView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.AutoCompleteTextView, defStyleAttr, defStyleRes);
 
         mThreshold = a.getInt(
                 R.styleable.AutoCompleteTextView_completionThreshold, 2);
@@ -362,7 +366,7 @@
      * @attr ref android.R.styleable#PopupWindow_popupBackground
      */
     public void setDropDownBackgroundResource(int id) {
-        mPopup.setBackgroundDrawable(getResources().getDrawable(id));
+        mPopup.setBackgroundDrawable(getContext().getDrawable(id));
     }
     
     /**
diff --git a/core/java/android/widget/Button.java b/core/java/android/widget/Button.java
index 2ac56ac..1663620 100644
--- a/core/java/android/widget/Button.java
+++ b/core/java/android/widget/Button.java
@@ -103,8 +103,12 @@
         this(context, attrs, com.android.internal.R.attr.buttonStyle);
     }
 
-    public Button(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Button(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java
index e90b460..ea60abb 100644
--- a/core/java/android/widget/CalendarView.java
+++ b/core/java/android/widget/CalendarView.java
@@ -80,234 +80,7 @@
      */
     private static final String LOG_TAG = CalendarView.class.getSimpleName();
 
-    /**
-     * Default value whether to show week number.
-     */
-    private static final boolean DEFAULT_SHOW_WEEK_NUMBER = true;
-
-    /**
-     * The number of milliseconds in a day.e
-     */
-    private static final long MILLIS_IN_DAY = 86400000L;
-
-    /**
-     * The number of day in a week.
-     */
-    private static final int DAYS_PER_WEEK = 7;
-
-    /**
-     * The number of milliseconds in a week.
-     */
-    private static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
-
-    /**
-     * Affects when the month selection will change while scrolling upe
-     */
-    private static final int SCROLL_HYST_WEEKS = 2;
-
-    /**
-     * How long the GoTo fling animation should last.
-     */
-    private static final int GOTO_SCROLL_DURATION = 1000;
-
-    /**
-     * The duration of the adjustment upon a user scroll in milliseconds.
-     */
-    private static final int ADJUSTMENT_SCROLL_DURATION = 500;
-
-    /**
-     * How long to wait after receiving an onScrollStateChanged notification
-     * before acting on it.
-     */
-    private static final int SCROLL_CHANGE_DELAY = 40;
-
-    /**
-     * String for parsing dates.
-     */
-    private static final String DATE_FORMAT = "MM/dd/yyyy";
-
-    /**
-     * The default minimal date.
-     */
-    private static final String DEFAULT_MIN_DATE = "01/01/1900";
-
-    /**
-     * The default maximal date.
-     */
-    private static final String DEFAULT_MAX_DATE = "01/01/2100";
-
-    private static final int DEFAULT_SHOWN_WEEK_COUNT = 6;
-
-    private static final int DEFAULT_DATE_TEXT_SIZE = 14;
-
-    private static final int UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH = 6;
-
-    private static final int UNSCALED_WEEK_MIN_VISIBLE_HEIGHT = 12;
-
-    private static final int UNSCALED_LIST_SCROLL_TOP_OFFSET = 2;
-
-    private static final int UNSCALED_BOTTOM_BUFFER = 20;
-
-    private static final int UNSCALED_WEEK_SEPARATOR_LINE_WIDTH = 1;
-
-    private static final int DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID = -1;
-
-    private final int mWeekSeperatorLineWidth;
-
-    private int mDateTextSize;
-
-    private Drawable mSelectedDateVerticalBar;
-
-    private final int mSelectedDateVerticalBarWidth;
-
-    private int mSelectedWeekBackgroundColor;
-
-    private int mFocusedMonthDateColor;
-
-    private int mUnfocusedMonthDateColor;
-
-    private int mWeekSeparatorLineColor;
-
-    private int mWeekNumberColor;
-
-    private int mWeekDayTextAppearanceResId;
-
-    private int mDateTextAppearanceResId;
-
-    /**
-     * The top offset of the weeks list.
-     */
-    private int mListScrollTopOffset = 2;
-
-    /**
-     * The visible height of a week view.
-     */
-    private int mWeekMinVisibleHeight = 12;
-
-    /**
-     * The visible height of a week view.
-     */
-    private int mBottomBuffer = 20;
-
-    /**
-     * The number of shown weeks.
-     */
-    private int mShownWeekCount;
-
-    /**
-     * Flag whether to show the week number.
-     */
-    private boolean mShowWeekNumber;
-
-    /**
-     * The number of day per week to be shown.
-     */
-    private int mDaysPerWeek = 7;
-
-    /**
-     * The friction of the week list while flinging.
-     */
-    private float mFriction = .05f;
-
-    /**
-     * Scale for adjusting velocity of the week list while flinging.
-     */
-    private float mVelocityScale = 0.333f;
-
-    /**
-     * The adapter for the weeks list.
-     */
-    private WeeksAdapter mAdapter;
-
-    /**
-     * The weeks list.
-     */
-    private ListView mListView;
-
-    /**
-     * The name of the month to display.
-     */
-    private TextView mMonthName;
-
-    /**
-     * The header with week day names.
-     */
-    private ViewGroup mDayNamesHeader;
-
-    /**
-     * Cached labels for the week names header.
-     */
-    private String[] mDayLabels;
-
-    /**
-     * The first day of the week.
-     */
-    private int mFirstDayOfWeek;
-
-    /**
-     * Which month should be displayed/highlighted [0-11].
-     */
-    private int mCurrentMonthDisplayed = -1;
-
-    /**
-     * Used for tracking during a scroll.
-     */
-    private long mPreviousScrollPosition;
-
-    /**
-     * Used for tracking which direction the view is scrolling.
-     */
-    private boolean mIsScrollingUp = false;
-
-    /**
-     * The previous scroll state of the weeks ListView.
-     */
-    private int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-
-    /**
-     * The current scroll state of the weeks ListView.
-     */
-    private int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
-
-    /**
-     * Listener for changes in the selected day.
-     */
-    private OnDateChangeListener mOnDateChangeListener;
-
-    /**
-     * Command for adjusting the position after a scroll/fling.
-     */
-    private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
-
-    /**
-     * Temporary instance to avoid multiple instantiations.
-     */
-    private Calendar mTempDate;
-
-    /**
-     * The first day of the focused month.
-     */
-    private Calendar mFirstDayOfMonth;
-
-    /**
-     * The start date of the range supported by this picker.
-     */
-    private Calendar mMinDate;
-
-    /**
-     * The end date of the range supported by this picker.
-     */
-    private Calendar mMaxDate;
-
-    /**
-     * Date format for parsing dates.
-     */
-    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
-
-    /**
-     * The current locale.
-     */
-    private Locale mCurrentLocale;
+    private CalendarViewDelegate mDelegate;
 
     /**
      * The callback used to indicate the user changes the date.
@@ -330,91 +103,17 @@
     }
 
     public CalendarView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
+        this(context, attrs, R.attr.calendarViewStyle);
     }
 
-    public CalendarView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, 0);
+    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        // initialization based on locale
-        setCurrentLocale(Locale.getDefault());
+    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
-        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.CalendarView,
-                R.attr.calendarViewStyle, 0);
-        mShowWeekNumber = attributesArray.getBoolean(R.styleable.CalendarView_showWeekNumber,
-                DEFAULT_SHOW_WEEK_NUMBER);
-        mFirstDayOfWeek = attributesArray.getInt(R.styleable.CalendarView_firstDayOfWeek,
-                LocaleData.get(Locale.getDefault()).firstDayOfWeek);
-        String minDate = attributesArray.getString(R.styleable.CalendarView_minDate);
-        if (TextUtils.isEmpty(minDate) || !parseDate(minDate, mMinDate)) {
-            parseDate(DEFAULT_MIN_DATE, mMinDate);
-        }
-        String maxDate = attributesArray.getString(R.styleable.CalendarView_maxDate);
-        if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
-            parseDate(DEFAULT_MAX_DATE, mMaxDate);
-        }
-        if (mMaxDate.before(mMinDate)) {
-            throw new IllegalArgumentException("Max date cannot be before min date.");
-        }
-        mShownWeekCount = attributesArray.getInt(R.styleable.CalendarView_shownWeekCount,
-                DEFAULT_SHOWN_WEEK_COUNT);
-        mSelectedWeekBackgroundColor = attributesArray.getColor(
-                R.styleable.CalendarView_selectedWeekBackgroundColor, 0);
-        mFocusedMonthDateColor = attributesArray.getColor(
-                R.styleable.CalendarView_focusedMonthDateColor, 0);
-        mUnfocusedMonthDateColor = attributesArray.getColor(
-                R.styleable.CalendarView_unfocusedMonthDateColor, 0);
-        mWeekSeparatorLineColor = attributesArray.getColor(
-                R.styleable.CalendarView_weekSeparatorLineColor, 0);
-        mWeekNumberColor = attributesArray.getColor(R.styleable.CalendarView_weekNumberColor, 0);
-        mSelectedDateVerticalBar = attributesArray.getDrawable(
-                R.styleable.CalendarView_selectedDateVerticalBar);
-
-        mDateTextAppearanceResId = attributesArray.getResourceId(
-                R.styleable.CalendarView_dateTextAppearance, R.style.TextAppearance_Small);
-        updateDateTextSize();
-
-        mWeekDayTextAppearanceResId = attributesArray.getResourceId(
-                R.styleable.CalendarView_weekDayTextAppearance,
-                DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID);
-        attributesArray.recycle();
-
-        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
-        mWeekMinVisibleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_WEEK_MIN_VISIBLE_HEIGHT, displayMetrics);
-        mListScrollTopOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_LIST_SCROLL_TOP_OFFSET, displayMetrics);
-        mBottomBuffer = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_BOTTOM_BUFFER, displayMetrics);
-        mSelectedDateVerticalBarWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH, displayMetrics);
-        mWeekSeperatorLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
-                UNSCALED_WEEK_SEPARATOR_LINE_WIDTH, displayMetrics);
-
-        LayoutInflater layoutInflater = (LayoutInflater) context
-                .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
-        View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
-        addView(content);
-
-        mListView = (ListView) findViewById(R.id.list);
-        mDayNamesHeader = (ViewGroup) content.findViewById(com.android.internal.R.id.day_names);
-        mMonthName = (TextView) content.findViewById(com.android.internal.R.id.month_name);
-
-        setUpHeader();
-        setUpListView();
-        setUpAdapter();
-
-        // go to today or whichever is close to today min or max date
-        mTempDate.setTimeInMillis(System.currentTimeMillis());
-        if (mTempDate.before(mMinDate)) {
-            goTo(mMinDate, false, true, true);
-        } else if (mMaxDate.before(mTempDate)) {
-            goTo(mMaxDate, false, true, true);
-        } else {
-            goTo(mTempDate, false, true, true);
-        }
-
-        invalidate();
+        mDelegate = new LegacyCalendarViewDelegate(this, context, attrs, defStyleAttr, defStyleRes);
     }
 
     /**
@@ -425,10 +124,7 @@
      * @attr ref android.R.styleable#CalendarView_shownWeekCount
      */
     public void setShownWeekCount(int count) {
-        if (mShownWeekCount != count) {
-            mShownWeekCount = count;
-            invalidate();
-        }
+        mDelegate.setShownWeekCount(count);
     }
 
     /**
@@ -439,7 +135,7 @@
      * @attr ref android.R.styleable#CalendarView_shownWeekCount
      */
     public int getShownWeekCount() {
-        return mShownWeekCount;
+        return mDelegate.getShownWeekCount();
     }
 
     /**
@@ -450,16 +146,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedWeekBackgroundColor
      */
     public void setSelectedWeekBackgroundColor(int color) {
-        if (mSelectedWeekBackgroundColor != color) {
-            mSelectedWeekBackgroundColor = color;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasSelectedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setSelectedWeekBackgroundColor(color);
     }
 
     /**
@@ -470,7 +157,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedWeekBackgroundColor
      */
     public int getSelectedWeekBackgroundColor() {
-        return mSelectedWeekBackgroundColor;
+        return mDelegate.getSelectedWeekBackgroundColor();
     }
 
     /**
@@ -481,16 +168,7 @@
      * @attr ref android.R.styleable#CalendarView_focusedMonthDateColor
      */
     public void setFocusedMonthDateColor(int color) {
-        if (mFocusedMonthDateColor != color) {
-            mFocusedMonthDateColor = color;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasFocusedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setFocusedMonthDateColor(color);
     }
 
     /**
@@ -501,7 +179,7 @@
      * @attr ref android.R.styleable#CalendarView_focusedMonthDateColor
      */
     public int getFocusedMonthDateColor() {
-        return mFocusedMonthDateColor;
+        return mDelegate.getFocusedMonthDateColor();
     }
 
     /**
@@ -512,16 +190,7 @@
      * @attr ref android.R.styleable#CalendarView_unfocusedMonthDateColor
      */
     public void setUnfocusedMonthDateColor(int color) {
-        if (mUnfocusedMonthDateColor != color) {
-            mUnfocusedMonthDateColor = color;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasUnfocusedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setUnfocusedMonthDateColor(color);
     }
 
     /**
@@ -532,7 +201,7 @@
      * @attr ref android.R.styleable#CalendarView_unfocusedMonthDateColor
      */
     public int getUnfocusedMonthDateColor() {
-        return mFocusedMonthDateColor;
+        return mDelegate.getUnfocusedMonthDateColor();
     }
 
     /**
@@ -543,12 +212,7 @@
      * @attr ref android.R.styleable#CalendarView_weekNumberColor
      */
     public void setWeekNumberColor(int color) {
-        if (mWeekNumberColor != color) {
-            mWeekNumberColor = color;
-            if (mShowWeekNumber) {
-                invalidateAllWeekViews();
-            }
-        }
+        mDelegate.setWeekNumberColor(color);
     }
 
     /**
@@ -559,7 +223,7 @@
      * @attr ref android.R.styleable#CalendarView_weekNumberColor
      */
     public int getWeekNumberColor() {
-        return mWeekNumberColor;
+        return mDelegate.getWeekNumberColor();
     }
 
     /**
@@ -570,10 +234,7 @@
      * @attr ref android.R.styleable#CalendarView_weekSeparatorLineColor
      */
     public void setWeekSeparatorLineColor(int color) {
-        if (mWeekSeparatorLineColor != color) {
-            mWeekSeparatorLineColor = color;
-            invalidateAllWeekViews();
-        }
+        mDelegate.setWeekSeparatorLineColor(color);
     }
 
     /**
@@ -584,7 +245,7 @@
      * @attr ref android.R.styleable#CalendarView_weekSeparatorLineColor
      */
     public int getWeekSeparatorLineColor() {
-        return mWeekSeparatorLineColor;
+        return mDelegate.getWeekSeparatorLineColor();
     }
 
     /**
@@ -596,8 +257,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedDateVerticalBar
      */
     public void setSelectedDateVerticalBar(int resourceId) {
-        Drawable drawable = getResources().getDrawable(resourceId);
-        setSelectedDateVerticalBar(drawable);
+        mDelegate.setSelectedDateVerticalBar(resourceId);
     }
 
     /**
@@ -609,16 +269,7 @@
      * @attr ref android.R.styleable#CalendarView_selectedDateVerticalBar
      */
     public void setSelectedDateVerticalBar(Drawable drawable) {
-        if (mSelectedDateVerticalBar != drawable) {
-            mSelectedDateVerticalBar = drawable;
-            final int childCount = mListView.getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                WeekView weekView = (WeekView) mListView.getChildAt(i);
-                if (weekView.mHasSelectedDay) {
-                    weekView.invalidate();
-                }
-            }
-        }
+        mDelegate.setSelectedDateVerticalBar(drawable);
     }
 
     /**
@@ -628,7 +279,7 @@
      * @return The vertical bar drawable.
      */
     public Drawable getSelectedDateVerticalBar() {
-        return mSelectedDateVerticalBar;
+        return mDelegate.getSelectedDateVerticalBar();
     }
 
     /**
@@ -639,10 +290,7 @@
      * @attr ref android.R.styleable#CalendarView_weekDayTextAppearance
      */
     public void setWeekDayTextAppearance(int resourceId) {
-        if (mWeekDayTextAppearanceResId != resourceId) {
-            mWeekDayTextAppearanceResId = resourceId;
-            setUpHeader();
-        }
+        mDelegate.setWeekDayTextAppearance(resourceId);
     }
 
     /**
@@ -653,7 +301,7 @@
      * @attr ref android.R.styleable#CalendarView_weekDayTextAppearance
      */
     public int getWeekDayTextAppearance() {
-        return mWeekDayTextAppearanceResId;
+        return mDelegate.getWeekDayTextAppearance();
     }
 
     /**
@@ -664,11 +312,7 @@
      * @attr ref android.R.styleable#CalendarView_dateTextAppearance
      */
     public void setDateTextAppearance(int resourceId) {
-        if (mDateTextAppearanceResId != resourceId) {
-            mDateTextAppearanceResId = resourceId;
-            updateDateTextSize();
-            invalidateAllWeekViews();
-        }
+        mDelegate.setDateTextAppearance(resourceId);
     }
 
     /**
@@ -679,35 +323,17 @@
      * @attr ref android.R.styleable#CalendarView_dateTextAppearance
      */
     public int getDateTextAppearance() {
-        return mDateTextAppearanceResId;
+        return mDelegate.getDateTextAppearance();
     }
 
     @Override
     public void setEnabled(boolean enabled) {
-        mListView.setEnabled(enabled);
+        mDelegate.setEnabled(enabled);
     }
 
     @Override
     public boolean isEnabled() {
-        return mListView.isEnabled();
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        setCurrentLocale(newConfig.locale);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setClassName(CalendarView.class.getName());
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(CalendarView.class.getName());
+        return mDelegate.isEnabled();
     }
 
     /**
@@ -723,7 +349,7 @@
      * @attr ref android.R.styleable#CalendarView_minDate
      */
     public long getMinDate() {
-        return mMinDate.getTimeInMillis();
+        return mDelegate.getMinDate();
     }
 
     /**
@@ -736,30 +362,7 @@
      * @attr ref android.R.styleable#CalendarView_minDate
      */
     public void setMinDate(long minDate) {
-        mTempDate.setTimeInMillis(minDate);
-        if (isSameDate(mTempDate, mMinDate)) {
-            return;
-        }
-        mMinDate.setTimeInMillis(minDate);
-        // make sure the current date is not earlier than
-        // the new min date since the latter is used for
-        // calculating the indices in the adapter thus
-        // avoiding out of bounds error
-        Calendar date = mAdapter.mSelectedDate;
-        if (date.before(mMinDate)) {
-            mAdapter.setSelectedDay(mMinDate);
-        }
-        // reinitialize the adapter since its range depends on min date
-        mAdapter.init();
-        if (date.before(mMinDate)) {
-            setDate(mTempDate.getTimeInMillis());
-        } else {
-            // we go to the current date to force the ListView to query its
-            // adapter for the shown views since we have changed the adapter
-            // range and the base from which the later calculates item indices
-            // note that calling setDate will not work since the date is the same
-            goTo(date, false, true, false);
-        }
+        mDelegate.setMinDate(minDate);
     }
 
     /**
@@ -775,7 +378,7 @@
      * @attr ref android.R.styleable#CalendarView_maxDate
      */
     public long getMaxDate() {
-        return mMaxDate.getTimeInMillis();
+        return mDelegate.getMaxDate();
     }
 
     /**
@@ -788,23 +391,7 @@
      * @attr ref android.R.styleable#CalendarView_maxDate
      */
     public void setMaxDate(long maxDate) {
-        mTempDate.setTimeInMillis(maxDate);
-        if (isSameDate(mTempDate, mMaxDate)) {
-            return;
-        }
-        mMaxDate.setTimeInMillis(maxDate);
-        // reinitialize the adapter since its range depends on max date
-        mAdapter.init();
-        Calendar date = mAdapter.mSelectedDate;
-        if (date.after(mMaxDate)) {
-            setDate(mMaxDate.getTimeInMillis());
-        } else {
-            // we go to the current date to force the ListView to query its
-            // adapter for the shown views since we have changed the adapter
-            // range and the base from which the later calculates item indices
-            // note that calling setDate will not work since the date is the same
-            goTo(date, false, true, false);
-        }
+        mDelegate.setMaxDate(maxDate);
     }
 
     /**
@@ -815,12 +402,7 @@
      * @attr ref android.R.styleable#CalendarView_showWeekNumber
      */
     public void setShowWeekNumber(boolean showWeekNumber) {
-        if (mShowWeekNumber == showWeekNumber) {
-            return;
-        }
-        mShowWeekNumber = showWeekNumber;
-        mAdapter.notifyDataSetChanged();
-        setUpHeader();
+        mDelegate.setShowWeekNumber(showWeekNumber);
     }
 
     /**
@@ -831,7 +413,7 @@
      * @attr ref android.R.styleable#CalendarView_showWeekNumber
      */
     public boolean getShowWeekNumber() {
-        return mShowWeekNumber;
+        return mDelegate.getShowWeekNumber();
     }
 
     /**
@@ -850,7 +432,7 @@
      * @attr ref android.R.styleable#CalendarView_firstDayOfWeek
      */
     public int getFirstDayOfWeek() {
-        return mFirstDayOfWeek;
+        return mDelegate.getFirstDayOfWeek();
     }
 
     /**
@@ -869,12 +451,7 @@
      * @attr ref android.R.styleable#CalendarView_firstDayOfWeek
      */
     public void setFirstDayOfWeek(int firstDayOfWeek) {
-        if (mFirstDayOfWeek == firstDayOfWeek) {
-            return;
-        }
-        mFirstDayOfWeek = firstDayOfWeek;
-        mAdapter.init();
-        setUpHeader();
+        mDelegate.setFirstDayOfWeek(firstDayOfWeek);
     }
 
     /**
@@ -883,7 +460,7 @@
      * @param listener The listener to be notified.
      */
     public void setOnDateChangeListener(OnDateChangeListener listener) {
-        mOnDateChangeListener = listener;
+        mDelegate.setOnDateChangeListener(listener);
     }
 
     /**
@@ -893,7 +470,7 @@
      * @return The selected date.
      */
     public long getDate() {
-        return mAdapter.mSelectedDate.getTimeInMillis();
+        return mDelegate.getDate();
     }
 
     /**
@@ -910,7 +487,7 @@
      * @see #setMaxDate(long)
      */
     public void setDate(long date) {
-        setDate(date, false, false);
+        mDelegate.setDate(date);
     }
 
     /**
@@ -928,937 +505,1648 @@
      * @see #setMaxDate(long)
      */
     public void setDate(long date, boolean animate, boolean center) {
-        mTempDate.setTimeInMillis(date);
-        if (isSameDate(mTempDate, mAdapter.mSelectedDate)) {
-            return;
-        }
-        goTo(mTempDate, animate, true, center);
+        mDelegate.setDate(date, animate, center);
     }
 
-    private void updateDateTextSize() {
-        TypedArray dateTextAppearance = mContext.obtainStyledAttributes(
-                mDateTextAppearanceResId, R.styleable.TextAppearance);
-        mDateTextSize = dateTextAppearance.getDimensionPixelSize(
-                R.styleable.TextAppearance_textSize, DEFAULT_DATE_TEXT_SIZE);
-        dateTextAppearance.recycle();
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mDelegate.onConfigurationChanged(newConfig);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        mDelegate.onInitializeAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        mDelegate.onInitializeAccessibilityNodeInfo(info);
     }
 
     /**
-     * Invalidates all week views.
+     * A delegate interface that defined the public API of the CalendarView. Allows different
+     * CalendarView implementations. This would need to be implemented by the CalendarView delegates
+     * for the real behavior.
      */
-    private void invalidateAllWeekViews() {
-        final int childCount = mListView.getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            View view = mListView.getChildAt(i);
-            view.invalidate();
+    private interface CalendarViewDelegate {
+        void setShownWeekCount(int count);
+        int getShownWeekCount();
+
+        void setSelectedWeekBackgroundColor(int color);
+        int getSelectedWeekBackgroundColor();
+
+        void setFocusedMonthDateColor(int color);
+        int getFocusedMonthDateColor();
+
+        void setUnfocusedMonthDateColor(int color);
+        int getUnfocusedMonthDateColor();
+
+        void setWeekNumberColor(int color);
+        int getWeekNumberColor();
+
+        void setWeekSeparatorLineColor(int color);
+        int getWeekSeparatorLineColor();
+
+        void setSelectedDateVerticalBar(int resourceId);
+        void setSelectedDateVerticalBar(Drawable drawable);
+        Drawable getSelectedDateVerticalBar();
+
+        void setWeekDayTextAppearance(int resourceId);
+        int getWeekDayTextAppearance();
+
+        void setDateTextAppearance(int resourceId);
+        int getDateTextAppearance();
+
+        void setEnabled(boolean enabled);
+        boolean isEnabled();
+
+        void setMinDate(long minDate);
+        long getMinDate();
+
+        void setMaxDate(long maxDate);
+        long getMaxDate();
+
+        void setShowWeekNumber(boolean showWeekNumber);
+        boolean getShowWeekNumber();
+
+        void setFirstDayOfWeek(int firstDayOfWeek);
+        int getFirstDayOfWeek();
+
+        void setDate(long date);
+        void setDate(long date, boolean animate, boolean center);
+        long getDate();
+
+        void setOnDateChangeListener(OnDateChangeListener listener);
+
+        void onConfigurationChanged(Configuration newConfig);
+        void onInitializeAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
+    }
+
+    /**
+     * An abstract class which can be used as a start for CalendarView implementations
+     */
+    abstract static class AbstractCalendarViewDelegate implements CalendarViewDelegate {
+        // The delegator
+        protected CalendarView mDelegator;
+
+        // The context
+        protected Context mContext;
+
+        // The current locale
+        protected Locale mCurrentLocale;
+
+        AbstractCalendarViewDelegate(CalendarView delegator, Context context) {
+            mDelegator = delegator;
+            mContext = context;
+
+            // Initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+        }
+
+        protected void setCurrentLocale(Locale locale) {
+            if (locale.equals(mCurrentLocale)) {
+                return;
+            }
+            mCurrentLocale = locale;
         }
     }
 
     /**
-     * Sets the current locale.
-     *
-     * @param locale The current locale.
+     * A delegate implementing the legacy CalendarView
      */
-    private void setCurrentLocale(Locale locale) {
-        if (locale.equals(mCurrentLocale)) {
-            return;
+    private static class LegacyCalendarViewDelegate extends AbstractCalendarViewDelegate {
+
+        /**
+         * Default value whether to show week number.
+         */
+        private static final boolean DEFAULT_SHOW_WEEK_NUMBER = true;
+
+        /**
+         * The number of milliseconds in a day.e
+         */
+        private static final long MILLIS_IN_DAY = 86400000L;
+
+        /**
+         * The number of day in a week.
+         */
+        private static final int DAYS_PER_WEEK = 7;
+
+        /**
+         * The number of milliseconds in a week.
+         */
+        private static final long MILLIS_IN_WEEK = DAYS_PER_WEEK * MILLIS_IN_DAY;
+
+        /**
+         * Affects when the month selection will change while scrolling upe
+         */
+        private static final int SCROLL_HYST_WEEKS = 2;
+
+        /**
+         * How long the GoTo fling animation should last.
+         */
+        private static final int GOTO_SCROLL_DURATION = 1000;
+
+        /**
+         * The duration of the adjustment upon a user scroll in milliseconds.
+         */
+        private static final int ADJUSTMENT_SCROLL_DURATION = 500;
+
+        /**
+         * How long to wait after receiving an onScrollStateChanged notification
+         * before acting on it.
+         */
+        private static final int SCROLL_CHANGE_DELAY = 40;
+
+        /**
+         * String for parsing dates.
+         */
+        private static final String DATE_FORMAT = "MM/dd/yyyy";
+
+        /**
+         * The default minimal date.
+         */
+        private static final String DEFAULT_MIN_DATE = "01/01/1900";
+
+        /**
+         * The default maximal date.
+         */
+        private static final String DEFAULT_MAX_DATE = "01/01/2100";
+
+        private static final int DEFAULT_SHOWN_WEEK_COUNT = 6;
+
+        private static final int DEFAULT_DATE_TEXT_SIZE = 14;
+
+        private static final int UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH = 6;
+
+        private static final int UNSCALED_WEEK_MIN_VISIBLE_HEIGHT = 12;
+
+        private static final int UNSCALED_LIST_SCROLL_TOP_OFFSET = 2;
+
+        private static final int UNSCALED_BOTTOM_BUFFER = 20;
+
+        private static final int UNSCALED_WEEK_SEPARATOR_LINE_WIDTH = 1;
+
+        private static final int DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID = -1;
+
+        private final int mWeekSeperatorLineWidth;
+
+        private int mDateTextSize;
+
+        private Drawable mSelectedDateVerticalBar;
+
+        private final int mSelectedDateVerticalBarWidth;
+
+        private int mSelectedWeekBackgroundColor;
+
+        private int mFocusedMonthDateColor;
+
+        private int mUnfocusedMonthDateColor;
+
+        private int mWeekSeparatorLineColor;
+
+        private int mWeekNumberColor;
+
+        private int mWeekDayTextAppearanceResId;
+
+        private int mDateTextAppearanceResId;
+
+        /**
+         * The top offset of the weeks list.
+         */
+        private int mListScrollTopOffset = 2;
+
+        /**
+         * The visible height of a week view.
+         */
+        private int mWeekMinVisibleHeight = 12;
+
+        /**
+         * The visible height of a week view.
+         */
+        private int mBottomBuffer = 20;
+
+        /**
+         * The number of shown weeks.
+         */
+        private int mShownWeekCount;
+
+        /**
+         * Flag whether to show the week number.
+         */
+        private boolean mShowWeekNumber;
+
+        /**
+         * The number of day per week to be shown.
+         */
+        private int mDaysPerWeek = 7;
+
+        /**
+         * The friction of the week list while flinging.
+         */
+        private float mFriction = .05f;
+
+        /**
+         * Scale for adjusting velocity of the week list while flinging.
+         */
+        private float mVelocityScale = 0.333f;
+
+        /**
+         * The adapter for the weeks list.
+         */
+        private WeeksAdapter mAdapter;
+
+        /**
+         * The weeks list.
+         */
+        private ListView mListView;
+
+        /**
+         * The name of the month to display.
+         */
+        private TextView mMonthName;
+
+        /**
+         * The header with week day names.
+         */
+        private ViewGroup mDayNamesHeader;
+
+        /**
+         * Cached labels for the week names header.
+         */
+        private String[] mDayLabels;
+
+        /**
+         * The first day of the week.
+         */
+        private int mFirstDayOfWeek;
+
+        /**
+         * Which month should be displayed/highlighted [0-11].
+         */
+        private int mCurrentMonthDisplayed = -1;
+
+        /**
+         * Used for tracking during a scroll.
+         */
+        private long mPreviousScrollPosition;
+
+        /**
+         * Used for tracking which direction the view is scrolling.
+         */
+        private boolean mIsScrollingUp = false;
+
+        /**
+         * The previous scroll state of the weeks ListView.
+         */
+        private int mPreviousScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+        /**
+         * The current scroll state of the weeks ListView.
+         */
+        private int mCurrentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
+
+        /**
+         * Listener for changes in the selected day.
+         */
+        private OnDateChangeListener mOnDateChangeListener;
+
+        /**
+         * Command for adjusting the position after a scroll/fling.
+         */
+        private ScrollStateRunnable mScrollStateChangedRunnable = new ScrollStateRunnable();
+
+        /**
+         * Temporary instance to avoid multiple instantiations.
+         */
+        private Calendar mTempDate;
+
+        /**
+         * The first day of the focused month.
+         */
+        private Calendar mFirstDayOfMonth;
+
+        /**
+         * The start date of the range supported by this picker.
+         */
+        private Calendar mMinDate;
+
+        /**
+         * The end date of the range supported by this picker.
+         */
+        private Calendar mMaxDate;
+
+        /**
+         * Date format for parsing dates.
+         */
+        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+        LegacyCalendarViewDelegate(CalendarView delegator, Context context, AttributeSet attrs,
+                                   int defStyleAttr, int defStyleRes) {
+            super(delegator, context);
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+
+            TypedArray attributesArray = context.obtainStyledAttributes(attrs,
+                    R.styleable.CalendarView, defStyleAttr, defStyleRes);
+            mShowWeekNumber = attributesArray.getBoolean(R.styleable.CalendarView_showWeekNumber,
+                    DEFAULT_SHOW_WEEK_NUMBER);
+            mFirstDayOfWeek = attributesArray.getInt(R.styleable.CalendarView_firstDayOfWeek,
+                    LocaleData.get(Locale.getDefault()).firstDayOfWeek);
+            String minDate = attributesArray.getString(R.styleable.CalendarView_minDate);
+            if (TextUtils.isEmpty(minDate) || !parseDate(minDate, mMinDate)) {
+                parseDate(DEFAULT_MIN_DATE, mMinDate);
+            }
+            String maxDate = attributesArray.getString(R.styleable.CalendarView_maxDate);
+            if (TextUtils.isEmpty(maxDate) || !parseDate(maxDate, mMaxDate)) {
+                parseDate(DEFAULT_MAX_DATE, mMaxDate);
+            }
+            if (mMaxDate.before(mMinDate)) {
+                throw new IllegalArgumentException("Max date cannot be before min date.");
+            }
+            mShownWeekCount = attributesArray.getInt(R.styleable.CalendarView_shownWeekCount,
+                    DEFAULT_SHOWN_WEEK_COUNT);
+            mSelectedWeekBackgroundColor = attributesArray.getColor(
+                    R.styleable.CalendarView_selectedWeekBackgroundColor, 0);
+            mFocusedMonthDateColor = attributesArray.getColor(
+                    R.styleable.CalendarView_focusedMonthDateColor, 0);
+            mUnfocusedMonthDateColor = attributesArray.getColor(
+                    R.styleable.CalendarView_unfocusedMonthDateColor, 0);
+            mWeekSeparatorLineColor = attributesArray.getColor(
+                    R.styleable.CalendarView_weekSeparatorLineColor, 0);
+            mWeekNumberColor = attributesArray.getColor(R.styleable.CalendarView_weekNumberColor, 0);
+            mSelectedDateVerticalBar = attributesArray.getDrawable(
+                    R.styleable.CalendarView_selectedDateVerticalBar);
+
+            mDateTextAppearanceResId = attributesArray.getResourceId(
+                    R.styleable.CalendarView_dateTextAppearance, R.style.TextAppearance_Small);
+            updateDateTextSize();
+
+            mWeekDayTextAppearanceResId = attributesArray.getResourceId(
+                    R.styleable.CalendarView_weekDayTextAppearance,
+                    DEFAULT_WEEK_DAY_TEXT_APPEARANCE_RES_ID);
+            attributesArray.recycle();
+
+            DisplayMetrics displayMetrics = mDelegator.getResources().getDisplayMetrics();
+            mWeekMinVisibleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_WEEK_MIN_VISIBLE_HEIGHT, displayMetrics);
+            mListScrollTopOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_LIST_SCROLL_TOP_OFFSET, displayMetrics);
+            mBottomBuffer = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_BOTTOM_BUFFER, displayMetrics);
+            mSelectedDateVerticalBarWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_SELECTED_DATE_VERTICAL_BAR_WIDTH, displayMetrics);
+            mWeekSeperatorLineWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                    UNSCALED_WEEK_SEPARATOR_LINE_WIDTH, displayMetrics);
+
+            LayoutInflater layoutInflater = (LayoutInflater) mContext
+                    .getSystemService(Service.LAYOUT_INFLATER_SERVICE);
+            View content = layoutInflater.inflate(R.layout.calendar_view, null, false);
+            mDelegator.addView(content);
+
+            mListView = (ListView) mDelegator.findViewById(R.id.list);
+            mDayNamesHeader = (ViewGroup) content.findViewById(com.android.internal.R.id.day_names);
+            mMonthName = (TextView) content.findViewById(com.android.internal.R.id.month_name);
+
+            setUpHeader();
+            setUpListView();
+            setUpAdapter();
+
+            // go to today or whichever is close to today min or max date
+            mTempDate.setTimeInMillis(System.currentTimeMillis());
+            if (mTempDate.before(mMinDate)) {
+                goTo(mMinDate, false, true, true);
+            } else if (mMaxDate.before(mTempDate)) {
+                goTo(mMaxDate, false, true, true);
+            } else {
+                goTo(mTempDate, false, true, true);
+            }
+
+            mDelegator.invalidate();
         }
 
-        mCurrentLocale = locale;
-
-        mTempDate = getCalendarForLocale(mTempDate, locale);
-        mFirstDayOfMonth = getCalendarForLocale(mFirstDayOfMonth, locale);
-        mMinDate = getCalendarForLocale(mMinDate, locale);
-        mMaxDate = getCalendarForLocale(mMaxDate, locale);
-    }
-
-    /**
-     * Gets a calendar for locale bootstrapped with the value of a given calendar.
-     *
-     * @param oldCalendar The old calendar.
-     * @param locale The locale.
-     */
-    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
-        if (oldCalendar == null) {
-            return Calendar.getInstance(locale);
-        } else {
-            final long currentTimeMillis = oldCalendar.getTimeInMillis();
-            Calendar newCalendar = Calendar.getInstance(locale);
-            newCalendar.setTimeInMillis(currentTimeMillis);
-            return newCalendar;
+        @Override
+        public void setShownWeekCount(int count) {
+            if (mShownWeekCount != count) {
+                mShownWeekCount = count;
+                mDelegator.invalidate();
+            }
         }
-    }
 
-    /**
-     * @return True if the <code>firstDate</code> is the same as the <code>
-     * secondDate</code>.
-     */
-    private boolean isSameDate(Calendar firstDate, Calendar secondDate) {
-        return (firstDate.get(Calendar.DAY_OF_YEAR) == secondDate.get(Calendar.DAY_OF_YEAR)
-                && firstDate.get(Calendar.YEAR) == secondDate.get(Calendar.YEAR));
-    }
+        @Override
+        public int getShownWeekCount() {
+            return mShownWeekCount;
+        }
 
-    /**
-     * Creates a new adapter if necessary and sets up its parameters.
-     */
-    private void setUpAdapter() {
-        if (mAdapter == null) {
-            mAdapter = new WeeksAdapter();
-            mAdapter.registerDataSetObserver(new DataSetObserver() {
-                @Override
-                public void onChanged() {
-                    if (mOnDateChangeListener != null) {
-                        Calendar selectedDay = mAdapter.getSelectedDay();
-                        mOnDateChangeListener.onSelectedDayChange(CalendarView.this,
-                                selectedDay.get(Calendar.YEAR),
-                                selectedDay.get(Calendar.MONTH),
-                                selectedDay.get(Calendar.DAY_OF_MONTH));
+        @Override
+        public void setSelectedWeekBackgroundColor(int color) {
+            if (mSelectedWeekBackgroundColor != color) {
+                mSelectedWeekBackgroundColor = color;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasSelectedDay) {
+                        weekView.invalidate();
                     }
                 }
-            });
-            mListView.setAdapter(mAdapter);
-        }
-
-        // refresh the view with the new parameters
-        mAdapter.notifyDataSetChanged();
-    }
-
-    /**
-     * 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 = 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);
-        }
-        // 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) {
-                label.setText(mDayLabels[i]);
+        }
+
+        @Override
+        public int getSelectedWeekBackgroundColor() {
+            return mSelectedWeekBackgroundColor;
+        }
+
+        @Override
+        public void setFocusedMonthDateColor(int color) {
+            if (mFocusedMonthDateColor != color) {
+                mFocusedMonthDateColor = color;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasFocusedDay) {
+                        weekView.invalidate();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public int getFocusedMonthDateColor() {
+            return mFocusedMonthDateColor;
+        }
+
+        @Override
+        public void setUnfocusedMonthDateColor(int color) {
+            if (mUnfocusedMonthDateColor != color) {
+                mUnfocusedMonthDateColor = color;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasUnfocusedDay) {
+                        weekView.invalidate();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public int getUnfocusedMonthDateColor() {
+            return mFocusedMonthDateColor;
+        }
+
+        @Override
+        public void setWeekNumberColor(int color) {
+            if (mWeekNumberColor != color) {
+                mWeekNumberColor = color;
+                if (mShowWeekNumber) {
+                    invalidateAllWeekViews();
+                }
+            }
+        }
+
+        @Override
+        public int getWeekNumberColor() {
+            return mWeekNumberColor;
+        }
+
+        @Override
+        public void setWeekSeparatorLineColor(int color) {
+            if (mWeekSeparatorLineColor != color) {
+                mWeekSeparatorLineColor = color;
+                invalidateAllWeekViews();
+            }
+        }
+
+        @Override
+        public int getWeekSeparatorLineColor() {
+            return mWeekSeparatorLineColor;
+        }
+
+        @Override
+        public void setSelectedDateVerticalBar(int resourceId) {
+            Drawable drawable = mDelegator.getContext().getDrawable(resourceId);
+            setSelectedDateVerticalBar(drawable);
+        }
+
+        @Override
+        public void setSelectedDateVerticalBar(Drawable drawable) {
+            if (mSelectedDateVerticalBar != drawable) {
+                mSelectedDateVerticalBar = drawable;
+                final int childCount = mListView.getChildCount();
+                for (int i = 0; i < childCount; i++) {
+                    WeekView weekView = (WeekView) mListView.getChildAt(i);
+                    if (weekView.mHasSelectedDay) {
+                        weekView.invalidate();
+                    }
+                }
+            }
+        }
+
+        @Override
+        public Drawable getSelectedDateVerticalBar() {
+            return mSelectedDateVerticalBar;
+        }
+
+        @Override
+        public void setWeekDayTextAppearance(int resourceId) {
+            if (mWeekDayTextAppearanceResId != resourceId) {
+                mWeekDayTextAppearanceResId = resourceId;
+                setUpHeader();
+            }
+        }
+
+        @Override
+        public int getWeekDayTextAppearance() {
+            return mWeekDayTextAppearanceResId;
+        }
+
+        @Override
+        public void setDateTextAppearance(int resourceId) {
+            if (mDateTextAppearanceResId != resourceId) {
+                mDateTextAppearanceResId = resourceId;
+                updateDateTextSize();
+                invalidateAllWeekViews();
+            }
+        }
+
+        @Override
+        public int getDateTextAppearance() {
+            return mDateTextAppearanceResId;
+        }
+
+        @Override
+        public void setEnabled(boolean enabled) {
+            mListView.setEnabled(enabled);
+        }
+
+        @Override
+        public boolean isEnabled() {
+            return mListView.isEnabled();
+        }
+
+        @Override
+        public void setMinDate(long minDate) {
+            mTempDate.setTimeInMillis(minDate);
+            if (isSameDate(mTempDate, mMinDate)) {
+                return;
+            }
+            mMinDate.setTimeInMillis(minDate);
+            // make sure the current date is not earlier than
+            // the new min date since the latter is used for
+            // calculating the indices in the adapter thus
+            // avoiding out of bounds error
+            Calendar date = mAdapter.mSelectedDate;
+            if (date.before(mMinDate)) {
+                mAdapter.setSelectedDay(mMinDate);
+            }
+            // reinitialize the adapter since its range depends on min date
+            mAdapter.init();
+            if (date.before(mMinDate)) {
+                setDate(mTempDate.getTimeInMillis());
+            } else {
+                // we go to the current date to force the ListView to query its
+                // adapter for the shown views since we have changed the adapter
+                // range and the base from which the later calculates item indices
+                // note that calling setDate will not work since the date is the same
+                goTo(date, false, true, false);
+            }
+        }
+
+        @Override
+        public long getMinDate() {
+            return mMinDate.getTimeInMillis();
+        }
+
+        @Override
+        public void setMaxDate(long maxDate) {
+            mTempDate.setTimeInMillis(maxDate);
+            if (isSameDate(mTempDate, mMaxDate)) {
+                return;
+            }
+            mMaxDate.setTimeInMillis(maxDate);
+            // reinitialize the adapter since its range depends on max date
+            mAdapter.init();
+            Calendar date = mAdapter.mSelectedDate;
+            if (date.after(mMaxDate)) {
+                setDate(mMaxDate.getTimeInMillis());
+            } else {
+                // we go to the current date to force the ListView to query its
+                // adapter for the shown views since we have changed the adapter
+                // range and the base from which the later calculates item indices
+                // note that calling setDate will not work since the date is the same
+                goTo(date, false, true, false);
+            }
+        }
+
+        @Override
+        public long getMaxDate() {
+            return mMaxDate.getTimeInMillis();
+        }
+
+        @Override
+        public void setShowWeekNumber(boolean showWeekNumber) {
+            if (mShowWeekNumber == showWeekNumber) {
+                return;
+            }
+            mShowWeekNumber = showWeekNumber;
+            mAdapter.notifyDataSetChanged();
+            setUpHeader();
+        }
+
+        @Override
+        public boolean getShowWeekNumber() {
+            return mShowWeekNumber;
+        }
+
+        @Override
+        public void setFirstDayOfWeek(int firstDayOfWeek) {
+            if (mFirstDayOfWeek == firstDayOfWeek) {
+                return;
+            }
+            mFirstDayOfWeek = firstDayOfWeek;
+            mAdapter.init();
+            mAdapter.notifyDataSetChanged();
+            setUpHeader();
+        }
+
+        @Override
+        public int getFirstDayOfWeek() {
+            return mFirstDayOfWeek;
+        }
+
+        @Override
+        public void setDate(long date) {
+            setDate(date, false, false);
+        }
+
+        @Override
+        public void setDate(long date, boolean animate, boolean center) {
+            mTempDate.setTimeInMillis(date);
+            if (isSameDate(mTempDate, mAdapter.mSelectedDate)) {
+                return;
+            }
+            goTo(mTempDate, animate, true, center);
+        }
+
+        @Override
+        public long getDate() {
+            return mAdapter.mSelectedDate.getTimeInMillis();
+        }
+
+        @Override
+        public void setOnDateChangeListener(OnDateChangeListener listener) {
+            mOnDateChangeListener = listener;
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+            setCurrentLocale(newConfig.locale);
+        }
+
+        @Override
+        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+            event.setClassName(CalendarView.class.getName());
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+            info.setClassName(CalendarView.class.getName());
+        }
+
+        /**
+         * Sets the current locale.
+         *
+         * @param locale The current locale.
+         */
+        @Override
+        protected void setCurrentLocale(Locale locale) {
+            super.setCurrentLocale(locale);
+
+            mTempDate = getCalendarForLocale(mTempDate, locale);
+            mFirstDayOfMonth = getCalendarForLocale(mFirstDayOfMonth, locale);
+            mMinDate = getCalendarForLocale(mMinDate, locale);
+            mMaxDate = getCalendarForLocale(mMaxDate, locale);
+        }
+        private void updateDateTextSize() {
+            TypedArray dateTextAppearance = mDelegator.getContext().obtainStyledAttributes(
+                    mDateTextAppearanceResId, R.styleable.TextAppearance);
+            mDateTextSize = dateTextAppearance.getDimensionPixelSize(
+                    R.styleable.TextAppearance_textSize, DEFAULT_DATE_TEXT_SIZE);
+            dateTextAppearance.recycle();
+        }
+
+        /**
+         * Invalidates all week views.
+         */
+        private void invalidateAllWeekViews() {
+            final int childCount = mListView.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                View view = mListView.getChildAt(i);
+                view.invalidate();
+            }
+        }
+
+        /**
+         * Gets a calendar for locale bootstrapped with the value of a given calendar.
+         *
+         * @param oldCalendar The old calendar.
+         * @param locale The locale.
+         */
+        private static Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
+            if (oldCalendar == null) {
+                return Calendar.getInstance(locale);
+            } else {
+                final long currentTimeMillis = oldCalendar.getTimeInMillis();
+                Calendar newCalendar = Calendar.getInstance(locale);
+                newCalendar.setTimeInMillis(currentTimeMillis);
+                return newCalendar;
+            }
+        }
+
+        /**
+         * @return True if the <code>firstDate</code> is the same as the <code>
+         * secondDate</code>.
+         */
+        private static boolean isSameDate(Calendar firstDate, Calendar secondDate) {
+            return (firstDate.get(Calendar.DAY_OF_YEAR) == secondDate.get(Calendar.DAY_OF_YEAR)
+                    && firstDate.get(Calendar.YEAR) == secondDate.get(Calendar.YEAR));
+        }
+
+        /**
+         * Creates a new adapter if necessary and sets up its parameters.
+         */
+        private void setUpAdapter() {
+            if (mAdapter == null) {
+                mAdapter = new WeeksAdapter(mContext);
+                mAdapter.registerDataSetObserver(new DataSetObserver() {
+                    @Override
+                    public void onChanged() {
+                        if (mOnDateChangeListener != null) {
+                            Calendar selectedDay = mAdapter.getSelectedDay();
+                            mOnDateChangeListener.onSelectedDayChange(mDelegator,
+                                    selectedDay.get(Calendar.YEAR),
+                                    selectedDay.get(Calendar.MONTH),
+                                    selectedDay.get(Calendar.DAY_OF_MONTH));
+                        }
+                    }
+                });
+                mListView.setAdapter(mAdapter);
+            }
+
+            // refresh the view with the new parameters
+            mAdapter.notifyDataSetChanged();
+        }
+
+        /**
+         * Sets up the strings to be used by the header.
+         */
+        private void setUpHeader() {
+            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);
+            }
+
+            TextView label = (TextView) mDayNamesHeader.getChildAt(0);
+            if (mShowWeekNumber) {
                 label.setVisibility(View.VISIBLE);
             } else {
                 label.setVisibility(View.GONE);
             }
-        }
-        mDayNamesHeader.invalidate();
-    }
-
-    /**
-     * Sets all the required fields for the list view.
-     */
-    private void setUpListView() {
-        // Configure the listview
-        mListView.setDivider(null);
-        mListView.setItemsCanFocus(true);
-        mListView.setVerticalScrollBarEnabled(false);
-        mListView.setOnScrollListener(new OnScrollListener() {
-            public void onScrollStateChanged(AbsListView view, int scrollState) {
-                CalendarView.this.onScrollStateChanged(view, scrollState);
-            }
-
-            public void onScroll(
-                    AbsListView view, int firstVisibleItem, int visibleItemCount,
-                    int totalItemCount) {
-                CalendarView.this.onScroll(view, firstVisibleItem, visibleItemCount,
-                        totalItemCount);
-            }
-        });
-        // Make the scrolling behavior nicer
-        mListView.setFriction(mFriction);
-        mListView.setVelocityScale(mVelocityScale);
-    }
-
-    /**
-     * This moves to the specified time in the view. If the time is not already
-     * in range it will move the list so that the first of the month containing
-     * the time is at the top of the view. If the new time is already in view
-     * the list will not be scrolled unless forceScroll is true. This time may
-     * optionally be highlighted as selected as well.
-     *
-     * @param date The time to move to.
-     * @param animate Whether to scroll to the given time or just redraw at the
-     *            new location.
-     * @param setSelected Whether to set the given time as selected.
-     * @param forceScroll Whether to recenter even if the time is already
-     *            visible.
-     *
-     * @throws IllegalArgumentException of the provided date is before the
-     *        range start of after the range end.
-     */
-    private void goTo(Calendar date, boolean animate, boolean setSelected, boolean forceScroll) {
-        if (date.before(mMinDate) || date.after(mMaxDate)) {
-            throw new IllegalArgumentException("Time not between " + mMinDate.getTime()
-                    + " and " + mMaxDate.getTime());
-        }
-        // Find the first and last entirely visible weeks
-        int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
-        View firstChild = mListView.getChildAt(0);
-        if (firstChild != null && firstChild.getTop() < 0) {
-            firstFullyVisiblePosition++;
-        }
-        int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
-        if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
-            lastFullyVisiblePosition--;
-        }
-        if (setSelected) {
-            mAdapter.setSelectedDay(date);
-        }
-        // Get the week we're going to
-        int position = getWeeksSinceMinDate(date);
-
-        // Check if the selected day is now outside of our visible range
-        // and if so scroll to the month that contains it
-        if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
-                || forceScroll) {
-            mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
-            mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
-
-            setMonthDisplayed(mFirstDayOfMonth);
-
-            // the earliest time we can scroll to is the min date
-            if (mFirstDayOfMonth.before(mMinDate)) {
-                position = 0;
-            } else {
-                position = getWeeksSinceMinDate(mFirstDayOfMonth);
-            }
-
-            mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
-            if (animate) {
-                mListView.smoothScrollToPositionFromTop(position, mListScrollTopOffset,
-                        GOTO_SCROLL_DURATION);
-            } else {
-                mListView.setSelectionFromTop(position, mListScrollTopOffset);
-                // Perform any after scroll operations that are needed
-                onScrollStateChanged(mListView, OnScrollListener.SCROLL_STATE_IDLE);
-            }
-        } else if (setSelected) {
-            // Otherwise just set the selection
-            setMonthDisplayed(date);
-        }
-    }
-
-    /**
-     * Parses the given <code>date</code> and in case of success sets
-     * the result to the <code>outDate</code>.
-     *
-     * @return True if the date was parsed.
-     */
-    private boolean parseDate(String date, Calendar outDate) {
-        try {
-            outDate.setTime(mDateFormat.parse(date));
-            return true;
-        } catch (ParseException e) {
-            Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
-            return false;
-        }
-    }
-
-    /**
-     * Called when a <code>view</code> transitions to a new <code>scrollState
-     * </code>.
-     */
-    private void onScrollStateChanged(AbsListView view, int scrollState) {
-        mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
-    }
-
-    /**
-     * Updates the title and selected month if the <code>view</code> has moved to a new
-     * month.
-     */
-    private void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
-            int totalItemCount) {
-        WeekView child = (WeekView) view.getChildAt(0);
-        if (child == null) {
-            return;
-        }
-
-        // Figure out where we are
-        long currScroll = view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
-
-        // If we have moved since our last call update the direction
-        if (currScroll < mPreviousScrollPosition) {
-            mIsScrollingUp = true;
-        } else if (currScroll > mPreviousScrollPosition) {
-            mIsScrollingUp = false;
-        } else {
-            return;
-        }
-
-        // Use some hysteresis for checking which month to highlight. This
-        // causes the month to transition when two full weeks of a month are
-        // visible when scrolling up, and when the first day in a month reaches
-        // the top of the screen when scrolling down.
-        int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
-        if (mIsScrollingUp) {
-            child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
-        } else if (offset != 0) {
-            child = (WeekView) view.getChildAt(offset);
-        }
-
-        if (child != null) {
-            // Find out which month we're moving into
-            int month;
-            if (mIsScrollingUp) {
-                month = child.getMonthOfFirstWeekDay();
-            } else {
-                month = child.getMonthOfLastWeekDay();
-            }
-
-            // And how it relates to our current highlighted month
-            int monthDiff;
-            if (mCurrentMonthDisplayed == 11 && month == 0) {
-                monthDiff = 1;
-            } else if (mCurrentMonthDisplayed == 0 && month == 11) {
-                monthDiff = -1;
-            } else {
-                monthDiff = month - mCurrentMonthDisplayed;
-            }
-
-            // Only switch months if we're scrolling away from the currently
-            // selected month
-            if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
-                Calendar firstDay = child.getFirstDay();
-                if (mIsScrollingUp) {
-                    firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
-                } else {
-                    firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+            for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
+                label = (TextView) mDayNamesHeader.getChildAt(i);
+                if (mWeekDayTextAppearanceResId > -1) {
+                    label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
                 }
-                setMonthDisplayed(firstDay);
+                if (i < mDaysPerWeek + 1) {
+                    label.setText(mDayLabels[i - 1]);
+                    label.setVisibility(View.VISIBLE);
+                } else {
+                    label.setVisibility(View.GONE);
+                }
             }
+            mDayNamesHeader.invalidate();
         }
 
-        mPreviousScrollPosition = currScroll;
-        mPreviousScrollState = mCurrentScrollState;
-    }
-
-    /**
-     * Sets the month displayed at the top of this view based on time. Override
-     * to add custom events when the title is changed.
-     *
-     * @param calendar A day in the new focus month.
-     */
-    private void setMonthDisplayed(Calendar calendar) {
-        mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
-        mAdapter.setFocusMonth(mCurrentMonthDisplayed);
-        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
-                | DateUtils.FORMAT_SHOW_YEAR;
-        final long millis = calendar.getTimeInMillis();
-        String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
-        mMonthName.setText(newMonthName);
-        mMonthName.invalidate();
-    }
-
-    /**
-     * @return Returns the number of weeks between the current <code>date</code>
-     *         and the <code>mMinDate</code>.
-     */
-    private int getWeeksSinceMinDate(Calendar date) {
-        if (date.before(mMinDate)) {
-            throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
-                    + " does not precede toDate: " + date.getTime());
-        }
-        long endTimeMillis = date.getTimeInMillis()
-                + date.getTimeZone().getOffset(date.getTimeInMillis());
-        long startTimeMillis = mMinDate.getTimeInMillis()
-                + mMinDate.getTimeZone().getOffset(mMinDate.getTimeInMillis());
-        long dayOffsetMillis = (mMinDate.get(Calendar.DAY_OF_WEEK) - mFirstDayOfWeek)
-                * MILLIS_IN_DAY;
-        return (int) ((endTimeMillis - startTimeMillis + dayOffsetMillis) / MILLIS_IN_WEEK);
-    }
-
-    /**
-     * Command responsible for acting upon scroll state changes.
-     */
-    private class ScrollStateRunnable implements Runnable {
-        private AbsListView mView;
-
-        private int mNewState;
-
         /**
-         * Sets up the runnable with a short delay in case the scroll state
-         * immediately changes again.
-         *
-         * @param view The list view that changed state
-         * @param scrollState The new state it changed to
+         * Sets all the required fields for the list view.
          */
-        public void doScrollStateChange(AbsListView view, int scrollState) {
-            mView = view;
-            mNewState = scrollState;
-            removeCallbacks(this);
-            postDelayed(this, SCROLL_CHANGE_DELAY);
+        private void setUpListView() {
+            // Configure the listview
+            mListView.setDivider(null);
+            mListView.setItemsCanFocus(true);
+            mListView.setVerticalScrollBarEnabled(false);
+            mListView.setOnScrollListener(new OnScrollListener() {
+                public void onScrollStateChanged(AbsListView view, int scrollState) {
+                    LegacyCalendarViewDelegate.this.onScrollStateChanged(view, scrollState);
+                }
+
+                public void onScroll(
+                        AbsListView view, int firstVisibleItem, int visibleItemCount,
+                        int totalItemCount) {
+                    LegacyCalendarViewDelegate.this.onScroll(view, firstVisibleItem,
+                            visibleItemCount, totalItemCount);
+                }
+            });
+            // Make the scrolling behavior nicer
+            mListView.setFriction(mFriction);
+            mListView.setVelocityScale(mVelocityScale);
         }
 
-        public void run() {
-            mCurrentScrollState = mNewState;
-            // Fix the position after a scroll or a fling ends
-            if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
-                    && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
-                View child = mView.getChildAt(0);
-                if (child == null) {
-                    // The view is no longer visible, just return
-                    return;
+        /**
+         * This moves to the specified time in the view. If the time is not already
+         * in range it will move the list so that the first of the month containing
+         * the time is at the top of the view. If the new time is already in view
+         * the list will not be scrolled unless forceScroll is true. This time may
+         * optionally be highlighted as selected as well.
+         *
+         * @param date The time to move to.
+         * @param animate Whether to scroll to the given time or just redraw at the
+         *            new location.
+         * @param setSelected Whether to set the given time as selected.
+         * @param forceScroll Whether to recenter even if the time is already
+         *            visible.
+         *
+         * @throws IllegalArgumentException of the provided date is before the
+         *        range start of after the range end.
+         */
+        private void goTo(Calendar date, boolean animate, boolean setSelected,
+                boolean forceScroll) {
+            if (date.before(mMinDate) || date.after(mMaxDate)) {
+                throw new IllegalArgumentException("Time not between " + mMinDate.getTime()
+                        + " and " + mMaxDate.getTime());
+            }
+            // Find the first and last entirely visible weeks
+            int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+            View firstChild = mListView.getChildAt(0);
+            if (firstChild != null && firstChild.getTop() < 0) {
+                firstFullyVisiblePosition++;
+            }
+            int lastFullyVisiblePosition = firstFullyVisiblePosition + mShownWeekCount - 1;
+            if (firstChild != null && firstChild.getTop() > mBottomBuffer) {
+                lastFullyVisiblePosition--;
+            }
+            if (setSelected) {
+                mAdapter.setSelectedDay(date);
+            }
+            // Get the week we're going to
+            int position = getWeeksSinceMinDate(date);
+
+            // Check if the selected day is now outside of our visible range
+            // and if so scroll to the month that contains it
+            if (position < firstFullyVisiblePosition || position > lastFullyVisiblePosition
+                    || forceScroll) {
+                mFirstDayOfMonth.setTimeInMillis(date.getTimeInMillis());
+                mFirstDayOfMonth.set(Calendar.DAY_OF_MONTH, 1);
+
+                setMonthDisplayed(mFirstDayOfMonth);
+
+                // the earliest time we can scroll to is the min date
+                if (mFirstDayOfMonth.before(mMinDate)) {
+                    position = 0;
+                } else {
+                    position = getWeeksSinceMinDate(mFirstDayOfMonth);
                 }
-                int dist = child.getBottom() - mListScrollTopOffset;
-                if (dist > mListScrollTopOffset) {
+
+                mPreviousScrollState = OnScrollListener.SCROLL_STATE_FLING;
+                if (animate) {
+                    mListView.smoothScrollToPositionFromTop(position, mListScrollTopOffset,
+                            GOTO_SCROLL_DURATION);
+                } else {
+                    mListView.setSelectionFromTop(position, mListScrollTopOffset);
+                    // Perform any after scroll operations that are needed
+                    onScrollStateChanged(mListView, OnScrollListener.SCROLL_STATE_IDLE);
+                }
+            } else if (setSelected) {
+                // Otherwise just set the selection
+                setMonthDisplayed(date);
+            }
+        }
+
+        /**
+         * Parses the given <code>date</code> and in case of success sets
+         * the result to the <code>outDate</code>.
+         *
+         * @return True if the date was parsed.
+         */
+        private boolean parseDate(String date, Calendar outDate) {
+            try {
+                outDate.setTime(mDateFormat.parse(date));
+                return true;
+            } catch (ParseException e) {
+                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
+                return false;
+            }
+        }
+
+        /**
+         * Called when a <code>view</code> transitions to a new <code>scrollState
+         * </code>.
+         */
+        private void onScrollStateChanged(AbsListView view, int scrollState) {
+            mScrollStateChangedRunnable.doScrollStateChange(view, scrollState);
+        }
+
+        /**
+         * Updates the title and selected month if the <code>view</code> has moved to a new
+         * month.
+         */
+        private void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+                              int totalItemCount) {
+            WeekView child = (WeekView) view.getChildAt(0);
+            if (child == null) {
+                return;
+            }
+
+            // Figure out where we are
+            long currScroll =
+                    view.getFirstVisiblePosition() * child.getHeight() - child.getBottom();
+
+            // If we have moved since our last call update the direction
+            if (currScroll < mPreviousScrollPosition) {
+                mIsScrollingUp = true;
+            } else if (currScroll > mPreviousScrollPosition) {
+                mIsScrollingUp = false;
+            } else {
+                return;
+            }
+
+            // Use some hysteresis for checking which month to highlight. This
+            // causes the month to transition when two full weeks of a month are
+            // visible when scrolling up, and when the first day in a month reaches
+            // the top of the screen when scrolling down.
+            int offset = child.getBottom() < mWeekMinVisibleHeight ? 1 : 0;
+            if (mIsScrollingUp) {
+                child = (WeekView) view.getChildAt(SCROLL_HYST_WEEKS + offset);
+            } else if (offset != 0) {
+                child = (WeekView) view.getChildAt(offset);
+            }
+
+            if (child != null) {
+                // Find out which month we're moving into
+                int month;
+                if (mIsScrollingUp) {
+                    month = child.getMonthOfFirstWeekDay();
+                } else {
+                    month = child.getMonthOfLastWeekDay();
+                }
+
+                // And how it relates to our current highlighted month
+                int monthDiff;
+                if (mCurrentMonthDisplayed == 11 && month == 0) {
+                    monthDiff = 1;
+                } else if (mCurrentMonthDisplayed == 0 && month == 11) {
+                    monthDiff = -1;
+                } else {
+                    monthDiff = month - mCurrentMonthDisplayed;
+                }
+
+                // Only switch months if we're scrolling away from the currently
+                // selected month
+                if ((!mIsScrollingUp && monthDiff > 0) || (mIsScrollingUp && monthDiff < 0)) {
+                    Calendar firstDay = child.getFirstDay();
                     if (mIsScrollingUp) {
-                        mView.smoothScrollBy(dist - child.getHeight(), ADJUSTMENT_SCROLL_DURATION);
+                        firstDay.add(Calendar.DAY_OF_MONTH, -DAYS_PER_WEEK);
                     } else {
-                        mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
+                        firstDay.add(Calendar.DAY_OF_MONTH, DAYS_PER_WEEK);
+                    }
+                    setMonthDisplayed(firstDay);
+                }
+            }
+            mPreviousScrollPosition = currScroll;
+            mPreviousScrollState = mCurrentScrollState;
+        }
+
+        /**
+         * Sets the month displayed at the top of this view based on time. Override
+         * to add custom events when the title is changed.
+         *
+         * @param calendar A day in the new focus month.
+         */
+        private void setMonthDisplayed(Calendar calendar) {
+            mCurrentMonthDisplayed = calendar.get(Calendar.MONTH);
+            mAdapter.setFocusMonth(mCurrentMonthDisplayed);
+            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_MONTH_DAY
+                    | DateUtils.FORMAT_SHOW_YEAR;
+            final long millis = calendar.getTimeInMillis();
+            String newMonthName = DateUtils.formatDateRange(mContext, millis, millis, flags);
+            mMonthName.setText(newMonthName);
+            mMonthName.invalidate();
+        }
+
+        /**
+         * @return Returns the number of weeks between the current <code>date</code>
+         *         and the <code>mMinDate</code>.
+         */
+        private int getWeeksSinceMinDate(Calendar date) {
+            if (date.before(mMinDate)) {
+                throw new IllegalArgumentException("fromDate: " + mMinDate.getTime()
+                        + " does not precede toDate: " + date.getTime());
+            }
+            long endTimeMillis = date.getTimeInMillis()
+                    + date.getTimeZone().getOffset(date.getTimeInMillis());
+            long startTimeMillis = mMinDate.getTimeInMillis()
+                    + mMinDate.getTimeZone().getOffset(mMinDate.getTimeInMillis());
+            long dayOffsetMillis = (mMinDate.get(Calendar.DAY_OF_WEEK) - mFirstDayOfWeek)
+                    * MILLIS_IN_DAY;
+            return (int) ((endTimeMillis - startTimeMillis + dayOffsetMillis) / MILLIS_IN_WEEK);
+        }
+
+        /**
+         * Command responsible for acting upon scroll state changes.
+         */
+        private class ScrollStateRunnable implements Runnable {
+            private AbsListView mView;
+
+            private int mNewState;
+
+            /**
+             * Sets up the runnable with a short delay in case the scroll state
+             * immediately changes again.
+             *
+             * @param view The list view that changed state
+             * @param scrollState The new state it changed to
+             */
+            public void doScrollStateChange(AbsListView view, int scrollState) {
+                mView = view;
+                mNewState = scrollState;
+                mDelegator.removeCallbacks(this);
+                mDelegator.postDelayed(this, SCROLL_CHANGE_DELAY);
+            }
+
+            public void run() {
+                mCurrentScrollState = mNewState;
+                // Fix the position after a scroll or a fling ends
+                if (mNewState == OnScrollListener.SCROLL_STATE_IDLE
+                        && mPreviousScrollState != OnScrollListener.SCROLL_STATE_IDLE) {
+                    View child = mView.getChildAt(0);
+                    if (child == null) {
+                        // The view is no longer visible, just return
+                        return;
+                    }
+                    int dist = child.getBottom() - mListScrollTopOffset;
+                    if (dist > mListScrollTopOffset) {
+                        if (mIsScrollingUp) {
+                            mView.smoothScrollBy(dist - child.getHeight(),
+                                    ADJUSTMENT_SCROLL_DURATION);
+                        } else {
+                            mView.smoothScrollBy(dist, ADJUSTMENT_SCROLL_DURATION);
+                        }
                     }
                 }
+                mPreviousScrollState = mNewState;
             }
-            mPreviousScrollState = mNewState;
-        }
-    }
-
-    /**
-     * <p>
-     * This is a specialized adapter for creating a list of weeks with
-     * selectable days. It can be configured to display the week number, start
-     * the week on a given day, show a reduced number of days, or display an
-     * arbitrary number of weeks at a time.
-     * </p>
-     */
-    private class WeeksAdapter extends BaseAdapter implements OnTouchListener {
-        private final Calendar mSelectedDate = Calendar.getInstance();
-        private final GestureDetector mGestureDetector;
-
-        private int mSelectedWeek;
-
-        private int mFocusedMonth;
-
-        private int mTotalWeekCount;
-
-        public WeeksAdapter() {
-            mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
-            init();
         }
 
         /**
-         * Set up the gesture detector and selected time
+         * <p>
+         * This is a specialized adapter for creating a list of weeks with
+         * selectable days. It can be configured to display the week number, start
+         * the week on a given day, show a reduced number of days, or display an
+         * arbitrary number of weeks at a time.
+         * </p>
          */
-        private void init() {
-            mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
-            mTotalWeekCount = getWeeksSinceMinDate(mMaxDate);
-            if (mMinDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek
-                || mMaxDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek) {
-                mTotalWeekCount++;
-            }
-            notifyDataSetChanged();
-        }
+        private class WeeksAdapter extends BaseAdapter implements OnTouchListener {
 
-        /**
-         * Updates the selected day and related parameters.
-         *
-         * @param selectedDay The time to highlight
-         */
-        public void setSelectedDay(Calendar selectedDay) {
-            if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
-                    && selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
-                return;
-            }
-            mSelectedDate.setTimeInMillis(selectedDay.getTimeInMillis());
-            mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
-            mFocusedMonth = mSelectedDate.get(Calendar.MONTH);
-            notifyDataSetChanged();
-        }
+            private int mSelectedWeek;
 
-        /**
-         * @return The selected day of month.
-         */
-        public Calendar getSelectedDay() {
-            return mSelectedDate;
-        }
+            private GestureDetector mGestureDetector;
 
-        @Override
-        public int getCount() {
-            return mTotalWeekCount;
-        }
+            private int mFocusedMonth;
 
-        @Override
-        public Object getItem(int position) {
-            return null;
-        }
+            private final Calendar mSelectedDate = Calendar.getInstance();
 
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
+            private int mTotalWeekCount;
 
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            WeekView weekView = null;
-            if (convertView != null) {
-                weekView = (WeekView) convertView;
-            } else {
-                weekView = new WeekView(mContext);
-                android.widget.AbsListView.LayoutParams params =
-                    new android.widget.AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT,
-                            LayoutParams.WRAP_CONTENT);
-                weekView.setLayoutParams(params);
-                weekView.setClickable(true);
-                weekView.setOnTouchListener(this);
+            public WeeksAdapter(Context context) {
+                mContext = context;
+                mGestureDetector = new GestureDetector(mContext, new CalendarGestureListener());
+                init();
             }
 
-            int selectedWeekDay = (mSelectedWeek == position) ? mSelectedDate.get(
-                    Calendar.DAY_OF_WEEK) : -1;
-            weekView.init(position, selectedWeekDay, mFocusedMonth);
-
-            return weekView;
-        }
-
-        /**
-         * Changes which month is in focus and updates the view.
-         *
-         * @param month The month to show as in focus [0-11]
-         */
-        public void setFocusMonth(int month) {
-            if (mFocusedMonth == month) {
-                return;
-            }
-            mFocusedMonth = month;
-            notifyDataSetChanged();
-        }
-
-        @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            if (mListView.isEnabled() && mGestureDetector.onTouchEvent(event)) {
-                WeekView weekView = (WeekView) v;
-                // if we cannot find a day for the given location we are done
-                if (!weekView.getDayFromLocation(event.getX(), mTempDate)) {
-                    return true;
+            /**
+             * Set up the gesture detector and selected time
+             */
+            private void init() {
+                mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
+                mTotalWeekCount = getWeeksSinceMinDate(mMaxDate);
+                if (mMinDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek
+                        || mMaxDate.get(Calendar.DAY_OF_WEEK) != mFirstDayOfWeek) {
+                    mTotalWeekCount++;
                 }
-                // it is possible that the touched day is outside the valid range
-                // we draw whole weeks but range end can fall not on the week end
-                if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
-                    return true;
-                }
-                onDateTapped(mTempDate);
-                return true;
+                notifyDataSetChanged();
             }
-            return false;
-        }
 
-        /**
-         * Maintains the same hour/min/sec but moves the day to the tapped day.
-         *
-         * @param day The day that was tapped
-         */
-        private void onDateTapped(Calendar day) {
-            setSelectedDay(day);
-            setMonthDisplayed(day);
-        }
+            /**
+             * Updates the selected day and related parameters.
+             *
+             * @param selectedDay The time to highlight
+             */
+            public void setSelectedDay(Calendar selectedDay) {
+                if (selectedDay.get(Calendar.DAY_OF_YEAR) == mSelectedDate.get(Calendar.DAY_OF_YEAR)
+                        && selectedDay.get(Calendar.YEAR) == mSelectedDate.get(Calendar.YEAR)) {
+                    return;
+                }
+                mSelectedDate.setTimeInMillis(selectedDay.getTimeInMillis());
+                mSelectedWeek = getWeeksSinceMinDate(mSelectedDate);
+                mFocusedMonth = mSelectedDate.get(Calendar.MONTH);
+                notifyDataSetChanged();
+            }
 
-        /**
-         * This is here so we can identify single tap events and set the
-         * selected day correctly
-         */
-        class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
+            /**
+             * @return The selected day of month.
+             */
+            public Calendar getSelectedDay() {
+                return mSelectedDate;
+            }
+
             @Override
-            public boolean onSingleTapUp(MotionEvent e) {
-                return true;
-            }
-        }
-    }
-
-    /**
-     * <p>
-     * This is a dynamic view for drawing a single week. It can be configured to
-     * display the week number, start the week on a given day, or show a reduced
-     * number of days. It is intended for use as a single view within a
-     * ListView. See {@link WeeksAdapter} for usage.
-     * </p>
-     */
-    private class WeekView extends View {
-
-        private final Rect mTempRect = new Rect();
-
-        private final Paint mDrawPaint = new Paint();
-
-        private final Paint mMonthNumDrawPaint = new Paint();
-
-        // Cache the number strings so we don't have to recompute them each time
-        private String[] mDayNumbers;
-
-        // Quick lookup for checking which days are in the focus month
-        private boolean[] mFocusDay;
-
-        // Whether this view has a focused day.
-        private boolean mHasFocusedDay;
-
-        // Whether this view has only focused days.
-        private boolean mHasUnfocusedDay;
-
-        // The first day displayed by this item
-        private Calendar mFirstDay;
-
-        // The month of the first day in this week
-        private int mMonthOfFirstWeekDay = -1;
-
-        // The month of the last day in this week
-        private int mLastWeekDayMonth = -1;
-
-        // The position of this week, equivalent to weeks since the week of Jan
-        // 1st, 1900
-        private int mWeek = -1;
-
-        // Quick reference to the width of this view, matches parent
-        private int mWidth;
-
-        // The height this view should draw at in pixels, set by height param
-        private int mHeight;
-
-        // If this view contains the selected day
-        private boolean mHasSelectedDay = false;
-
-        // Which day is selected [0-6] or -1 if no day is selected
-        private int mSelectedDay = -1;
-
-        // The number of days + a spot for week number if it is displayed
-        private int mNumCells;
-
-        // The left edge of the selected day
-        private int mSelectedLeft = -1;
-
-        // The right edge of the selected day
-        private int mSelectedRight = -1;
-
-        public WeekView(Context context) {
-            super(context);
-
-            // Sets up any standard paints that will be used
-            initilaizePaints();
-        }
-
-        /**
-         * Initializes this week view.
-         *
-         * @param weekNumber The number of the week this view represents. The
-         *            week number is a zero based index of the weeks since
-         *            {@link CalendarView#getMinDate()}.
-         * @param selectedWeekDay The selected day of the week from 0 to 6, -1 if no
-         *            selected day.
-         * @param focusedMonth The month that is currently in focus i.e.
-         *            highlighted.
-         */
-        public void init(int weekNumber, int selectedWeekDay, int focusedMonth) {
-            mSelectedDay = selectedWeekDay;
-            mHasSelectedDay = mSelectedDay != -1;
-            mNumCells = mShowWeekNumber ? mDaysPerWeek + 1 : mDaysPerWeek;
-            mWeek = weekNumber;
-            mTempDate.setTimeInMillis(mMinDate.getTimeInMillis());
-
-            mTempDate.add(Calendar.WEEK_OF_YEAR, mWeek);
-            mTempDate.setFirstDayOfWeek(mFirstDayOfWeek);
-
-            // Allocate space for caching the day numbers and focus values
-            mDayNumbers = new String[mNumCells];
-            mFocusDay = new boolean[mNumCells];
-
-            // If we're showing the week number calculate it based on Monday
-            int i = 0;
-            if (mShowWeekNumber) {
-                mDayNumbers[0] = String.format(Locale.getDefault(), "%d",
-                        mTempDate.get(Calendar.WEEK_OF_YEAR));
-                i++;
+            public int getCount() {
+                return mTotalWeekCount;
             }
 
-            // Now adjust our starting day based on the start day of the week
-            int diff = mFirstDayOfWeek - mTempDate.get(Calendar.DAY_OF_WEEK);
-            mTempDate.add(Calendar.DAY_OF_MONTH, diff);
+            @Override
+            public Object getItem(int position) {
+                return null;
+            }
 
-            mFirstDay = (Calendar) mTempDate.clone();
-            mMonthOfFirstWeekDay = mTempDate.get(Calendar.MONTH);
+            @Override
+            public long getItemId(int position) {
+                return position;
+            }
 
-            mHasUnfocusedDay = true;
-            for (; i < mNumCells; i++) {
-                final boolean isFocusedDay = (mTempDate.get(Calendar.MONTH) == focusedMonth);
-                mFocusDay[i] = isFocusedDay;
-                mHasFocusedDay |= isFocusedDay;
-                mHasUnfocusedDay &= !isFocusedDay;
-                // do not draw dates outside the valid range to avoid user confusion
-                if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
-                    mDayNumbers[i] = "";
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                WeekView weekView = null;
+                if (convertView != null) {
+                    weekView = (WeekView) convertView;
                 } else {
-                    mDayNumbers[i] = String.format(Locale.getDefault(), "%d",
-                            mTempDate.get(Calendar.DAY_OF_MONTH));
+                    weekView = new WeekView(mContext);
+                    android.widget.AbsListView.LayoutParams params =
+                            new android.widget.AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT,
+                                    LayoutParams.WRAP_CONTENT);
+                    weekView.setLayoutParams(params);
+                    weekView.setClickable(true);
+                    weekView.setOnTouchListener(this);
                 }
-                mTempDate.add(Calendar.DAY_OF_MONTH, 1);
-            }
-            // We do one extra add at the end of the loop, if that pushed us to
-            // new month undo it
-            if (mTempDate.get(Calendar.DAY_OF_MONTH) == 1) {
-                mTempDate.add(Calendar.DAY_OF_MONTH, -1);
-            }
-            mLastWeekDayMonth = mTempDate.get(Calendar.MONTH);
 
-            updateSelectionPositions();
-        }
+                int selectedWeekDay = (mSelectedWeek == position) ? mSelectedDate.get(
+                        Calendar.DAY_OF_WEEK) : -1;
+                weekView.init(position, selectedWeekDay, mFocusedMonth);
 
-        /**
-         * Initialize the paint instances.
-         */
-        private void initilaizePaints() {
-            mDrawPaint.setFakeBoldText(false);
-            mDrawPaint.setAntiAlias(true);
-            mDrawPaint.setStyle(Style.FILL);
-
-            mMonthNumDrawPaint.setFakeBoldText(true);
-            mMonthNumDrawPaint.setAntiAlias(true);
-            mMonthNumDrawPaint.setStyle(Style.FILL);
-            mMonthNumDrawPaint.setTextAlign(Align.CENTER);
-            mMonthNumDrawPaint.setTextSize(mDateTextSize);
-        }
-
-        /**
-         * Returns the month of the first day in this week.
-         *
-         * @return The month the first day of this view is in.
-         */
-        public int getMonthOfFirstWeekDay() {
-            return mMonthOfFirstWeekDay;
-        }
-
-        /**
-         * Returns the month of the last day in this week
-         *
-         * @return The month the last day of this view is in
-         */
-        public int getMonthOfLastWeekDay() {
-            return mLastWeekDayMonth;
-        }
-
-        /**
-         * Returns the first day in this view.
-         *
-         * @return The first day in the view.
-         */
-        public Calendar getFirstDay() {
-            return mFirstDay;
-        }
-
-        /**
-         * Calculates the day that the given x position is in, accounting for
-         * week number.
-         *
-         * @param x The x position of the touch event.
-         * @return True if a day was found for the given location.
-         */
-        public boolean getDayFromLocation(float x, Calendar outCalendar) {
-            final boolean isLayoutRtl = isLayoutRtl();
-
-            int start;
-            int end;
-
-            if (isLayoutRtl) {
-                start = 0;
-                end = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-            } else {
-                start = mShowWeekNumber ? mWidth / mNumCells : 0;
-                end = mWidth;
+                return weekView;
             }
 
-            if (x < start || x > end) {
-                outCalendar.clear();
+            /**
+             * Changes which month is in focus and updates the view.
+             *
+             * @param month The month to show as in focus [0-11]
+             */
+            public void setFocusMonth(int month) {
+                if (mFocusedMonth == month) {
+                    return;
+                }
+                mFocusedMonth = month;
+                notifyDataSetChanged();
+            }
+
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (mListView.isEnabled() && mGestureDetector.onTouchEvent(event)) {
+                    WeekView weekView = (WeekView) v;
+                    // if we cannot find a day for the given location we are done
+                    if (!weekView.getDayFromLocation(event.getX(), mTempDate)) {
+                        return true;
+                    }
+                    // it is possible that the touched day is outside the valid range
+                    // we draw whole weeks but range end can fall not on the week end
+                    if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
+                        return true;
+                    }
+                    onDateTapped(mTempDate);
+                    return true;
+                }
                 return false;
             }
 
-            // Selection is (x - start) / (pixels/day) which is (x - start) * day / pixels
-            int dayPosition = (int) ((x - start) * mDaysPerWeek / (end - start));
-
-            if (isLayoutRtl) {
-                dayPosition = mDaysPerWeek - 1 - dayPosition;
+            /**
+             * Maintains the same hour/min/sec but moves the day to the tapped day.
+             *
+             * @param day The day that was tapped
+             */
+            private void onDateTapped(Calendar day) {
+                setSelectedDay(day);
+                setMonthDisplayed(day);
             }
 
-            outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
-            outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
-
-            return true;
-        }
-
-        @Override
-        protected void onDraw(Canvas canvas) {
-            drawBackground(canvas);
-            drawWeekNumbersAndDates(canvas);
-            drawWeekSeparators(canvas);
-            drawSelectedDateVerticalBars(canvas);
+            /**
+             * This is here so we can identify single tap events and set the
+             * selected day correctly
+             */
+            class CalendarGestureListener extends GestureDetector.SimpleOnGestureListener {
+                @Override
+                public boolean onSingleTapUp(MotionEvent e) {
+                    return true;
+                }
+            }
         }
 
         /**
-         * This draws the selection highlight if a day is selected in this week.
-         *
-         * @param canvas The canvas to draw on
+         * <p>
+         * This is a dynamic view for drawing a single week. It can be configured to
+         * display the week number, start the week on a given day, or show a reduced
+         * number of days. It is intended for use as a single view within a
+         * ListView. See {@link WeeksAdapter} for usage.
+         * </p>
          */
-        private void drawBackground(Canvas canvas) {
-            if (!mHasSelectedDay) {
-                return;
+        private class WeekView extends View {
+
+            private final Rect mTempRect = new Rect();
+
+            private final Paint mDrawPaint = new Paint();
+
+            private final Paint mMonthNumDrawPaint = new Paint();
+
+            // Cache the number strings so we don't have to recompute them each time
+            private String[] mDayNumbers;
+
+            // Quick lookup for checking which days are in the focus month
+            private boolean[] mFocusDay;
+
+            // Whether this view has a focused day.
+            private boolean mHasFocusedDay;
+
+            // Whether this view has only focused days.
+            private boolean mHasUnfocusedDay;
+
+            // The first day displayed by this item
+            private Calendar mFirstDay;
+
+            // The month of the first day in this week
+            private int mMonthOfFirstWeekDay = -1;
+
+            // The month of the last day in this week
+            private int mLastWeekDayMonth = -1;
+
+            // The position of this week, equivalent to weeks since the week of Jan
+            // 1st, 1900
+            private int mWeek = -1;
+
+            // Quick reference to the width of this view, matches parent
+            private int mWidth;
+
+            // The height this view should draw at in pixels, set by height param
+            private int mHeight;
+
+            // If this view contains the selected day
+            private boolean mHasSelectedDay = false;
+
+            // Which day is selected [0-6] or -1 if no day is selected
+            private int mSelectedDay = -1;
+
+            // The number of days + a spot for week number if it is displayed
+            private int mNumCells;
+
+            // The left edge of the selected day
+            private int mSelectedLeft = -1;
+
+            // The right edge of the selected day
+            private int mSelectedRight = -1;
+
+            public WeekView(Context context) {
+                super(context);
+
+                // Sets up any standard paints that will be used
+                initilaizePaints();
             }
-            mDrawPaint.setColor(mSelectedWeekBackgroundColor);
 
-            mTempRect.top = mWeekSeperatorLineWidth;
-            mTempRect.bottom = mHeight;
+            /**
+             * Initializes this week view.
+             *
+             * @param weekNumber The number of the week this view represents. The
+             *            week number is a zero based index of the weeks since
+             *            {@link CalendarView#getMinDate()}.
+             * @param selectedWeekDay The selected day of the week from 0 to 6, -1 if no
+             *            selected day.
+             * @param focusedMonth The month that is currently in focus i.e.
+             *            highlighted.
+             */
+            public void init(int weekNumber, int selectedWeekDay, int focusedMonth) {
+                mSelectedDay = selectedWeekDay;
+                mHasSelectedDay = mSelectedDay != -1;
+                mNumCells = mShowWeekNumber ? mDaysPerWeek + 1 : mDaysPerWeek;
+                mWeek = weekNumber;
+                mTempDate.setTimeInMillis(mMinDate.getTimeInMillis());
 
-            final boolean isLayoutRtl = isLayoutRtl();
+                mTempDate.add(Calendar.WEEK_OF_YEAR, mWeek);
+                mTempDate.setFirstDayOfWeek(mFirstDayOfWeek);
 
-            if (isLayoutRtl) {
-                mTempRect.left = 0;
-                mTempRect.right = mSelectedLeft - 2;
-            } else {
-                mTempRect.left = mShowWeekNumber ? mWidth / mNumCells : 0;
-                mTempRect.right = mSelectedLeft - 2;
-            }
-            canvas.drawRect(mTempRect, mDrawPaint);
+                // Allocate space for caching the day numbers and focus values
+                mDayNumbers = new String[mNumCells];
+                mFocusDay = new boolean[mNumCells];
 
-            if (isLayoutRtl) {
-                mTempRect.left = mSelectedRight + 3;
-                mTempRect.right = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-            } else {
-                mTempRect.left = mSelectedRight + 3;
-                mTempRect.right = mWidth;
-            }
-            canvas.drawRect(mTempRect, mDrawPaint);
-        }
-
-        /**
-         * Draws the week and month day numbers for this week.
-         *
-         * @param canvas The canvas to draw on
-         */
-        private void drawWeekNumbersAndDates(Canvas canvas) {
-            final float textHeight = mDrawPaint.getTextSize();
-            final int y = (int) ((mHeight + textHeight) / 2) - mWeekSeperatorLineWidth;
-            final int nDays = mNumCells;
-            final int divisor = 2 * nDays;
-
-            mDrawPaint.setTextAlign(Align.CENTER);
-            mDrawPaint.setTextSize(mDateTextSize);
-
-            int i = 0;
-
-            if (isLayoutRtl()) {
-                for (; i < nDays - 1; i++) {
-                    mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
-                            : mUnfocusedMonthDateColor);
-                    int x = (2 * i + 1) * mWidth / divisor;
-                    canvas.drawText(mDayNumbers[nDays - 1 - i], x, y, mMonthNumDrawPaint);
-                }
+                // If we're showing the week number calculate it based on Monday
+                int i = 0;
                 if (mShowWeekNumber) {
-                    mDrawPaint.setColor(mWeekNumberColor);
-                    int x = mWidth - mWidth / divisor;
-                    canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
-                }
-            } else {
-                if (mShowWeekNumber) {
-                    mDrawPaint.setColor(mWeekNumberColor);
-                    int x = mWidth / divisor;
-                    canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                    mDayNumbers[0] = String.format(Locale.getDefault(), "%d",
+                            mTempDate.get(Calendar.WEEK_OF_YEAR));
                     i++;
                 }
-                for (; i < nDays; i++) {
-                    mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
-                            : mUnfocusedMonthDateColor);
-                    int x = (2 * i + 1) * mWidth / divisor;
-                    canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
+
+                // Now adjust our starting day based on the start day of the week
+                int diff = mFirstDayOfWeek - mTempDate.get(Calendar.DAY_OF_WEEK);
+                mTempDate.add(Calendar.DAY_OF_MONTH, diff);
+
+                mFirstDay = (Calendar) mTempDate.clone();
+                mMonthOfFirstWeekDay = mTempDate.get(Calendar.MONTH);
+
+                mHasUnfocusedDay = true;
+                for (; i < mNumCells; i++) {
+                    final boolean isFocusedDay = (mTempDate.get(Calendar.MONTH) == focusedMonth);
+                    mFocusDay[i] = isFocusedDay;
+                    mHasFocusedDay |= isFocusedDay;
+                    mHasUnfocusedDay &= !isFocusedDay;
+                    // do not draw dates outside the valid range to avoid user confusion
+                    if (mTempDate.before(mMinDate) || mTempDate.after(mMaxDate)) {
+                        mDayNumbers[i] = "";
+                    } else {
+                        mDayNumbers[i] = String.format(Locale.getDefault(), "%d",
+                                mTempDate.get(Calendar.DAY_OF_MONTH));
+                    }
+                    mTempDate.add(Calendar.DAY_OF_MONTH, 1);
                 }
-            }
-        }
+                // We do one extra add at the end of the loop, if that pushed us to
+                // new month undo it
+                if (mTempDate.get(Calendar.DAY_OF_MONTH) == 1) {
+                    mTempDate.add(Calendar.DAY_OF_MONTH, -1);
+                }
+                mLastWeekDayMonth = mTempDate.get(Calendar.MONTH);
 
-        /**
-         * Draws a horizontal line for separating the weeks.
-         *
-         * @param canvas The canvas to draw on.
-         */
-        private void drawWeekSeparators(Canvas canvas) {
-            // If it is the topmost fully visible child do not draw separator line
-            int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
-            if (mListView.getChildAt(0).getTop() < 0) {
-                firstFullyVisiblePosition++;
+                updateSelectionPositions();
             }
-            if (firstFullyVisiblePosition == mWeek) {
-                return;
-            }
-            mDrawPaint.setColor(mWeekSeparatorLineColor);
-            mDrawPaint.setStrokeWidth(mWeekSeperatorLineWidth);
-            float startX;
-            float stopX;
-            if (isLayoutRtl()) {
-                startX = 0;
-                stopX = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
-            } else {
-                startX = mShowWeekNumber ? mWidth / mNumCells : 0;
-                stopX = mWidth;
-            }
-            canvas.drawLine(startX, 0, stopX, 0, mDrawPaint);
-        }
 
-        /**
-         * Draws the selected date bars if this week has a selected day.
-         *
-         * @param canvas The canvas to draw on
-         */
-        private void drawSelectedDateVerticalBars(Canvas canvas) {
-            if (!mHasSelectedDay) {
-                return;
+            /**
+             * Initialize the paint instances.
+             */
+            private void initilaizePaints() {
+                mDrawPaint.setFakeBoldText(false);
+                mDrawPaint.setAntiAlias(true);
+                mDrawPaint.setStyle(Style.FILL);
+
+                mMonthNumDrawPaint.setFakeBoldText(true);
+                mMonthNumDrawPaint.setAntiAlias(true);
+                mMonthNumDrawPaint.setStyle(Style.FILL);
+                mMonthNumDrawPaint.setTextAlign(Align.CENTER);
+                mMonthNumDrawPaint.setTextSize(mDateTextSize);
             }
-            mSelectedDateVerticalBar.setBounds(mSelectedLeft - mSelectedDateVerticalBarWidth / 2,
-                    mWeekSeperatorLineWidth,
-                    mSelectedLeft + mSelectedDateVerticalBarWidth / 2, mHeight);
-            mSelectedDateVerticalBar.draw(canvas);
-            mSelectedDateVerticalBar.setBounds(mSelectedRight - mSelectedDateVerticalBarWidth / 2,
-                    mWeekSeperatorLineWidth,
-                    mSelectedRight + mSelectedDateVerticalBarWidth / 2, mHeight);
-            mSelectedDateVerticalBar.draw(canvas);
-        }
 
-        @Override
-        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-            mWidth = w;
-            updateSelectionPositions();
-        }
+            /**
+             * Returns the month of the first day in this week.
+             *
+             * @return The month the first day of this view is in.
+             */
+            public int getMonthOfFirstWeekDay() {
+                return mMonthOfFirstWeekDay;
+            }
 
-        /**
-         * This calculates the positions for the selected day lines.
-         */
-        private void updateSelectionPositions() {
-            if (mHasSelectedDay) {
+            /**
+             * Returns the month of the last day in this week
+             *
+             * @return The month the last day of this view is in
+             */
+            public int getMonthOfLastWeekDay() {
+                return mLastWeekDayMonth;
+            }
+
+            /**
+             * Returns the first day in this view.
+             *
+             * @return The first day in the view.
+             */
+            public Calendar getFirstDay() {
+                return mFirstDay;
+            }
+
+            /**
+             * Calculates the day that the given x position is in, accounting for
+             * week number.
+             *
+             * @param x The x position of the touch event.
+             * @return True if a day was found for the given location.
+             */
+            public boolean getDayFromLocation(float x, Calendar outCalendar) {
                 final boolean isLayoutRtl = isLayoutRtl();
-                int selectedPosition = mSelectedDay - mFirstDayOfWeek;
-                if (selectedPosition < 0) {
-                    selectedPosition += 7;
-                }
-                if (mShowWeekNumber && !isLayoutRtl) {
-                    selectedPosition++;
-                }
-                if (isLayoutRtl) {
-                    mSelectedLeft = (mDaysPerWeek - 1 - selectedPosition) * mWidth / mNumCells;
 
+                int start;
+                int end;
+
+                if (isLayoutRtl) {
+                    start = 0;
+                    end = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
                 } else {
-                    mSelectedLeft = selectedPosition * mWidth / mNumCells;
+                    start = mShowWeekNumber ? mWidth / mNumCells : 0;
+                    end = mWidth;
                 }
-                mSelectedRight = mSelectedLeft + mWidth / mNumCells;
+
+                if (x < start || x > end) {
+                    outCalendar.clear();
+                    return false;
+                }
+
+                // Selection is (x - start) / (pixels/day) which is (x - start) * day / pixels
+                int dayPosition = (int) ((x - start) * mDaysPerWeek / (end - start));
+
+                if (isLayoutRtl) {
+                    dayPosition = mDaysPerWeek - 1 - dayPosition;
+                }
+
+                outCalendar.setTimeInMillis(mFirstDay.getTimeInMillis());
+                outCalendar.add(Calendar.DAY_OF_MONTH, dayPosition);
+
+                return true;
+            }
+
+            @Override
+            protected void onDraw(Canvas canvas) {
+                drawBackground(canvas);
+                drawWeekNumbersAndDates(canvas);
+                drawWeekSeparators(canvas);
+                drawSelectedDateVerticalBars(canvas);
+            }
+
+            /**
+             * This draws the selection highlight if a day is selected in this week.
+             *
+             * @param canvas The canvas to draw on
+             */
+            private void drawBackground(Canvas canvas) {
+                if (!mHasSelectedDay) {
+                    return;
+                }
+                mDrawPaint.setColor(mSelectedWeekBackgroundColor);
+
+                mTempRect.top = mWeekSeperatorLineWidth;
+                mTempRect.bottom = mHeight;
+
+                final boolean isLayoutRtl = isLayoutRtl();
+
+                if (isLayoutRtl) {
+                    mTempRect.left = 0;
+                    mTempRect.right = mSelectedLeft - 2;
+                } else {
+                    mTempRect.left = mShowWeekNumber ? mWidth / mNumCells : 0;
+                    mTempRect.right = mSelectedLeft - 2;
+                }
+                canvas.drawRect(mTempRect, mDrawPaint);
+
+                if (isLayoutRtl) {
+                    mTempRect.left = mSelectedRight + 3;
+                    mTempRect.right = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
+                } else {
+                    mTempRect.left = mSelectedRight + 3;
+                    mTempRect.right = mWidth;
+                }
+                canvas.drawRect(mTempRect, mDrawPaint);
+            }
+
+            /**
+             * Draws the week and month day numbers for this week.
+             *
+             * @param canvas The canvas to draw on
+             */
+            private void drawWeekNumbersAndDates(Canvas canvas) {
+                final float textHeight = mDrawPaint.getTextSize();
+                final int y = (int) ((mHeight + textHeight) / 2) - mWeekSeperatorLineWidth;
+                final int nDays = mNumCells;
+                final int divisor = 2 * nDays;
+
+                mDrawPaint.setTextAlign(Align.CENTER);
+                mDrawPaint.setTextSize(mDateTextSize);
+
+                int i = 0;
+
+                if (isLayoutRtl()) {
+                    for (; i < nDays - 1; i++) {
+                        mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+                                : mUnfocusedMonthDateColor);
+                        int x = (2 * i + 1) * mWidth / divisor;
+                        canvas.drawText(mDayNumbers[nDays - 1 - i], x, y, mMonthNumDrawPaint);
+                    }
+                    if (mShowWeekNumber) {
+                        mDrawPaint.setColor(mWeekNumberColor);
+                        int x = mWidth - mWidth / divisor;
+                        canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                    }
+                } else {
+                    if (mShowWeekNumber) {
+                        mDrawPaint.setColor(mWeekNumberColor);
+                        int x = mWidth / divisor;
+                        canvas.drawText(mDayNumbers[0], x, y, mDrawPaint);
+                        i++;
+                    }
+                    for (; i < nDays; i++) {
+                        mMonthNumDrawPaint.setColor(mFocusDay[i] ? mFocusedMonthDateColor
+                                : mUnfocusedMonthDateColor);
+                        int x = (2 * i + 1) * mWidth / divisor;
+                        canvas.drawText(mDayNumbers[i], x, y, mMonthNumDrawPaint);
+                    }
+                }
+            }
+
+            /**
+             * Draws a horizontal line for separating the weeks.
+             *
+             * @param canvas The canvas to draw on.
+             */
+            private void drawWeekSeparators(Canvas canvas) {
+                // If it is the topmost fully visible child do not draw separator line
+                int firstFullyVisiblePosition = mListView.getFirstVisiblePosition();
+                if (mListView.getChildAt(0).getTop() < 0) {
+                    firstFullyVisiblePosition++;
+                }
+                if (firstFullyVisiblePosition == mWeek) {
+                    return;
+                }
+                mDrawPaint.setColor(mWeekSeparatorLineColor);
+                mDrawPaint.setStrokeWidth(mWeekSeperatorLineWidth);
+                float startX;
+                float stopX;
+                if (isLayoutRtl()) {
+                    startX = 0;
+                    stopX = mShowWeekNumber ? mWidth - mWidth / mNumCells : mWidth;
+                } else {
+                    startX = mShowWeekNumber ? mWidth / mNumCells : 0;
+                    stopX = mWidth;
+                }
+                canvas.drawLine(startX, 0, stopX, 0, mDrawPaint);
+            }
+
+            /**
+             * Draws the selected date bars if this week has a selected day.
+             *
+             * @param canvas The canvas to draw on
+             */
+            private void drawSelectedDateVerticalBars(Canvas canvas) {
+                if (!mHasSelectedDay) {
+                    return;
+                }
+                mSelectedDateVerticalBar.setBounds(
+                        mSelectedLeft - mSelectedDateVerticalBarWidth / 2,
+                        mWeekSeperatorLineWidth,
+                        mSelectedLeft + mSelectedDateVerticalBarWidth / 2,
+                        mHeight);
+                mSelectedDateVerticalBar.draw(canvas);
+                mSelectedDateVerticalBar.setBounds(
+                        mSelectedRight - mSelectedDateVerticalBarWidth / 2,
+                        mWeekSeperatorLineWidth,
+                        mSelectedRight + mSelectedDateVerticalBarWidth / 2,
+                        mHeight);
+                mSelectedDateVerticalBar.draw(canvas);
+            }
+
+            @Override
+            protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+                mWidth = w;
+                updateSelectionPositions();
+            }
+
+            /**
+             * This calculates the positions for the selected day lines.
+             */
+            private void updateSelectionPositions() {
+                if (mHasSelectedDay) {
+                    final boolean isLayoutRtl = isLayoutRtl();
+                    int selectedPosition = mSelectedDay - mFirstDayOfWeek;
+                    if (selectedPosition < 0) {
+                        selectedPosition += 7;
+                    }
+                    if (mShowWeekNumber && !isLayoutRtl) {
+                        selectedPosition++;
+                    }
+                    if (isLayoutRtl) {
+                        mSelectedLeft = (mDaysPerWeek - 1 - selectedPosition) * mWidth / mNumCells;
+
+                    } else {
+                        mSelectedLeft = selectedPosition * mWidth / mNumCells;
+                    }
+                    mSelectedRight = mSelectedLeft + mWidth / mNumCells;
+                }
+            }
+
+            @Override
+            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+                mHeight = (mListView.getHeight() - mListView.getPaddingTop() - mListView
+                        .getPaddingBottom()) / mShownWeekCount;
+                setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
             }
         }
 
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            mHeight = (mListView.getHeight() - mListView.getPaddingTop() - mListView
-                    .getPaddingBottom()) / mShownWeekCount;
-            setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), mHeight);
-        }
     }
+
 }
diff --git a/core/java/android/widget/CheckBox.java b/core/java/android/widget/CheckBox.java
index f1804f8..71438c9 100644
--- a/core/java/android/widget/CheckBox.java
+++ b/core/java/android/widget/CheckBox.java
@@ -64,8 +64,12 @@
         this(context, attrs, com.android.internal.R.attr.checkboxStyle);
     }
 
-    public CheckBox(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public CheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public CheckBox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 5c10a77..1533510 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -58,11 +58,15 @@
         this(context, attrs, R.attr.checkedTextViewStyle);
     }
 
-    public CheckedTextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public CheckedTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.CheckedTextView, defStyle, 0);
+    public CheckedTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.CheckedTextView, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(R.styleable.CheckedTextView_checkMark);
         if (d != null) {
@@ -119,7 +123,7 @@
 
         Drawable d = null;
         if (mCheckMarkResource != 0) {
-            d = getResources().getDrawable(mCheckMarkResource);
+            d = getContext().getDrawable(mCheckMarkResource);
         }
         setCheckMarkDrawable(d);
     }
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index b7a126e..f94789d 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -18,14 +18,12 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.graphics.Canvas;
 import android.os.Handler;
 import android.os.Message;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Slog;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
@@ -96,12 +94,15 @@
      * Initialize with standard view layout information and style.
      * Sets the base to the current time.
      */
-    public Chronometer(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Chronometer(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(
-                attrs,
-                com.android.internal.R.styleable.Chronometer, defStyle, 0);
+    public Chronometer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Chronometer, defStyleAttr, defStyleRes);
         setFormat(a.getString(com.android.internal.R.styleable.Chronometer_format));
         a.recycle();
 
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index abddc90..4298545 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -64,12 +64,15 @@
         this(context, attrs, 0);
     }
 
-    public CompoundButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a =
-                context.obtainStyledAttributes(
-                        attrs, com.android.internal.R.styleable.CompoundButton, defStyle, 0);
+    public CompoundButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.CompoundButton, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
         if (d != null) {
@@ -183,7 +186,7 @@
 
         Drawable d = null;
         if (mButtonResource != 0) {
-            d = getResources().getDrawable(mButtonResource);
+            d = getContext().getDrawable(mButtonResource);
         }
         setButtonDrawable(d);
     }
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index d03161e..265dbcd 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -24,7 +24,6 @@
 import android.os.Parcelable;
 import android.text.TextUtils;
 import android.text.InputType;
-import android.text.format.DateFormat;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -76,53 +75,7 @@
 
     private static final String LOG_TAG = DatePicker.class.getSimpleName();
 
-    private static final String DATE_FORMAT = "MM/dd/yyyy";
-
-    private static final int DEFAULT_START_YEAR = 1900;
-
-    private static final int DEFAULT_END_YEAR = 2100;
-
-    private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
-
-    private static final boolean DEFAULT_SPINNERS_SHOWN = true;
-
-    private static final boolean DEFAULT_ENABLED_STATE = true;
-
-    private final LinearLayout mSpinners;
-
-    private final NumberPicker mDaySpinner;
-
-    private final NumberPicker mMonthSpinner;
-
-    private final NumberPicker mYearSpinner;
-
-    private final EditText mDaySpinnerInput;
-
-    private final EditText mMonthSpinnerInput;
-
-    private final EditText mYearSpinnerInput;
-
-    private final CalendarView mCalendarView;
-
-    private Locale mCurrentLocale;
-
-    private OnDateChangedListener mOnDateChangedListener;
-
-    private String[] mShortMonths;
-
-    private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
-
-    private int mNumberOfMonths;
-
-    private Calendar mTempDate;
-
-    private Calendar mMinDate;
-
-    private Calendar mMaxDate;
-
-    private Calendar mCurrentDate;
-
-    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+    private DatePickerDelegate mDelegate;
 
     /**
      * The callback used to indicate the user changes\d the date.
@@ -149,443 +102,14 @@
         this(context, attrs, R.attr.datePickerStyle);
     }
 
-    public DatePicker(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        // initialization based on locale
-        setCurrentLocale(Locale.getDefault());
-
-        TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
-                defStyle, 0);
-        boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
-                DEFAULT_SPINNERS_SHOWN);
-        boolean calendarViewShown = attributesArray.getBoolean(
-                R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
-        int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
-                DEFAULT_START_YEAR);
-        int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
-        String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
-        String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
-        int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_internalLayout,
-                R.layout.date_picker);
-        attributesArray.recycle();
-
-        LayoutInflater inflater = (LayoutInflater) context
-                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(layoutResourceId, this, true);
-
-        OnValueChangeListener onChangeListener = new OnValueChangeListener() {
-            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
-                updateInputState();
-                mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
-                // take care of wrapping of days and months to update greater fields
-                if (picker == mDaySpinner) {
-                    int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
-                    if (oldVal == maxDayOfMonth && newVal == 1) {
-                        mTempDate.add(Calendar.DAY_OF_MONTH, 1);
-                    } else if (oldVal == 1 && newVal == maxDayOfMonth) {
-                        mTempDate.add(Calendar.DAY_OF_MONTH, -1);
-                    } else {
-                        mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
-                    }
-                } else if (picker == mMonthSpinner) {
-                    if (oldVal == 11 && newVal == 0) {
-                        mTempDate.add(Calendar.MONTH, 1);
-                    } else if (oldVal == 0 && newVal == 11) {
-                        mTempDate.add(Calendar.MONTH, -1);
-                    } else {
-                        mTempDate.add(Calendar.MONTH, newVal - oldVal);
-                    }
-                } else if (picker == mYearSpinner) {
-                    mTempDate.set(Calendar.YEAR, newVal);
-                } else {
-                    throw new IllegalArgumentException();
-                }
-                // now set the date to the adjusted one
-                setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
-                        mTempDate.get(Calendar.DAY_OF_MONTH));
-                updateSpinners();
-                updateCalendarView();
-                notifyDateChanged();
-            }
-        };
-
-        mSpinners = (LinearLayout) findViewById(R.id.pickers);
-
-        // calendar view day-picker
-        mCalendarView = (CalendarView) findViewById(R.id.calendar_view);
-        mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
-            public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
-                setDate(year, month, monthDay);
-                updateSpinners();
-                notifyDateChanged();
-            }
-        });
-
-        // day
-        mDaySpinner = (NumberPicker) findViewById(R.id.day);
-        mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
-        mDaySpinner.setOnLongPressUpdateInterval(100);
-        mDaySpinner.setOnValueChangedListener(onChangeListener);
-        mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
-
-        // month
-        mMonthSpinner = (NumberPicker) findViewById(R.id.month);
-        mMonthSpinner.setMinValue(0);
-        mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
-        mMonthSpinner.setDisplayedValues(mShortMonths);
-        mMonthSpinner.setOnLongPressUpdateInterval(200);
-        mMonthSpinner.setOnValueChangedListener(onChangeListener);
-        mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
-
-        // year
-        mYearSpinner = (NumberPicker) findViewById(R.id.year);
-        mYearSpinner.setOnLongPressUpdateInterval(100);
-        mYearSpinner.setOnValueChangedListener(onChangeListener);
-        mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
-
-        // show only what the user required but make sure we
-        // show something and the spinners have higher priority
-        if (!spinnersShown && !calendarViewShown) {
-            setSpinnersShown(true);
-        } else {
-            setSpinnersShown(spinnersShown);
-            setCalendarViewShown(calendarViewShown);
-        }
-
-        // set the min date giving priority of the minDate over startYear
-        mTempDate.clear();
-        if (!TextUtils.isEmpty(minDate)) {
-            if (!parseDate(minDate, mTempDate)) {
-                mTempDate.set(startYear, 0, 1);
-            }
-        } else {
-            mTempDate.set(startYear, 0, 1);
-        }
-        setMinDate(mTempDate.getTimeInMillis());
-
-        // set the max date giving priority of the maxDate over endYear
-        mTempDate.clear();
-        if (!TextUtils.isEmpty(maxDate)) {
-            if (!parseDate(maxDate, mTempDate)) {
-                mTempDate.set(endYear, 11, 31);
-            }
-        } else {
-            mTempDate.set(endYear, 11, 31);
-        }
-        setMaxDate(mTempDate.getTimeInMillis());
-
-        // initialize to current date
-        mCurrentDate.setTimeInMillis(System.currentTimeMillis());
-        init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
-                .get(Calendar.DAY_OF_MONTH), null);
-
-        // re-order the number spinners to match the current date format
-        reorderSpinners();
-
-        // accessibility
-        setContentDescriptions();
-
-        // If not explicitly specified this view is important for accessibility.
-        if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
-            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
-        }
+    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
-    /**
-     * Gets the minimal date supported by this {@link DatePicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     * <p>
-     * Note: The default minimal date is 01/01/1900.
-     * <p>
-     *
-     * @return The minimal supported date.
-     */
-    public long getMinDate() {
-        return mCalendarView.getMinDate();
-    }
+    public DatePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
-    /**
-     * Sets the minimal date supported by this {@link NumberPicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     *
-     * @param minDate The minimal supported date.
-     */
-    public void setMinDate(long minDate) {
-        mTempDate.setTimeInMillis(minDate);
-        if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
-            return;
-        }
-        mMinDate.setTimeInMillis(minDate);
-        mCalendarView.setMinDate(minDate);
-        if (mCurrentDate.before(mMinDate)) {
-            mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
-            updateCalendarView();
-        }
-        updateSpinners();
-    }
-
-    /**
-     * Gets the maximal date supported by this {@link DatePicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     * <p>
-     * Note: The default maximal date is 12/31/2100.
-     * <p>
-     *
-     * @return The maximal supported date.
-     */
-    public long getMaxDate() {
-        return mCalendarView.getMaxDate();
-    }
-
-    /**
-     * Sets the maximal date supported by this {@link DatePicker} in
-     * milliseconds since January 1, 1970 00:00:00 in
-     * {@link TimeZone#getDefault()} time zone.
-     *
-     * @param maxDate The maximal supported date.
-     */
-    public void setMaxDate(long maxDate) {
-        mTempDate.setTimeInMillis(maxDate);
-        if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
-                && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
-            return;
-        }
-        mMaxDate.setTimeInMillis(maxDate);
-        mCalendarView.setMaxDate(maxDate);
-        if (mCurrentDate.after(mMaxDate)) {
-            mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
-            updateCalendarView();
-        }
-        updateSpinners();
-    }
-
-    @Override
-    public void setEnabled(boolean enabled) {
-        if (mIsEnabled == enabled) {
-            return;
-        }
-        super.setEnabled(enabled);
-        mDaySpinner.setEnabled(enabled);
-        mMonthSpinner.setEnabled(enabled);
-        mYearSpinner.setEnabled(enabled);
-        mCalendarView.setEnabled(enabled);
-        mIsEnabled = enabled;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    @Override
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        onPopulateAccessibilityEvent(event);
-        return true;
-    }
-
-    @Override
-    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
-        super.onPopulateAccessibilityEvent(event);
-
-        final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
-        String selectedDateUtterance = DateUtils.formatDateTime(mContext,
-                mCurrentDate.getTimeInMillis(), flags);
-        event.getText().add(selectedDateUtterance);
-    }
-
-    @Override
-    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
-        super.onInitializeAccessibilityEvent(event);
-        event.setClassName(DatePicker.class.getName());
-    }
-
-    @Override
-    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-        super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(DatePicker.class.getName());
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        setCurrentLocale(newConfig.locale);
-    }
-
-    /**
-     * Gets whether the {@link CalendarView} is shown.
-     *
-     * @return True if the calendar view is shown.
-     * @see #getCalendarView()
-     */
-    public boolean getCalendarViewShown() {
-        return (mCalendarView.getVisibility() == View.VISIBLE);
-    }
-
-    /**
-     * Gets the {@link CalendarView}.
-     *
-     * @return The calendar view.
-     * @see #getCalendarViewShown()
-     */
-    public CalendarView getCalendarView () {
-        return mCalendarView;
-    }
-
-    /**
-     * Sets whether the {@link CalendarView} is shown.
-     *
-     * @param shown True if the calendar view is to be shown.
-     */
-    public void setCalendarViewShown(boolean shown) {
-        mCalendarView.setVisibility(shown ? VISIBLE : GONE);
-    }
-
-    /**
-     * Gets whether the spinners are shown.
-     *
-     * @return True if the spinners are shown.
-     */
-    public boolean getSpinnersShown() {
-        return mSpinners.isShown();
-    }
-
-    /**
-     * Sets whether the spinners are shown.
-     *
-     * @param shown True if the spinners are to be shown.
-     */
-    public void setSpinnersShown(boolean shown) {
-        mSpinners.setVisibility(shown ? VISIBLE : GONE);
-    }
-
-    /**
-     * Sets the current locale.
-     *
-     * @param locale The current locale.
-     */
-    private void setCurrentLocale(Locale locale) {
-        if (locale.equals(mCurrentLocale)) {
-            return;
-        }
-
-        mCurrentLocale = locale;
-
-        mTempDate = getCalendarForLocale(mTempDate, locale);
-        mMinDate = getCalendarForLocale(mMinDate, locale);
-        mMaxDate = getCalendarForLocale(mMaxDate, locale);
-        mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
-
-        mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
-        mShortMonths = new DateFormatSymbols().getShortMonths();
-
-        if (usingNumericMonths()) {
-            // We're in a locale where a date should either be all-numeric, or all-text.
-            // All-text would require custom NumberPicker formatters for day and year.
-            mShortMonths = new String[mNumberOfMonths];
-            for (int i = 0; i < mNumberOfMonths; ++i) {
-                mShortMonths[i] = String.format("%d", i + 1);
-            }
-        }
-    }
-
-    /**
-     * Tests whether the current locale is one where there are no real month names,
-     * such as Chinese, Japanese, or Korean locales.
-     */
-    private boolean usingNumericMonths() {
-        return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
-    }
-
-    /**
-     * Gets a calendar for locale bootstrapped with the value of a given calendar.
-     *
-     * @param oldCalendar The old calendar.
-     * @param locale The locale.
-     */
-    private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
-        if (oldCalendar == null) {
-            return Calendar.getInstance(locale);
-        } else {
-            final long currentTimeMillis = oldCalendar.getTimeInMillis();
-            Calendar newCalendar = Calendar.getInstance(locale);
-            newCalendar.setTimeInMillis(currentTimeMillis);
-            return newCalendar;
-        }
-    }
-
-    /**
-     * Reorders the spinners according to the date format that is
-     * explicitly set by the user and if no such is set fall back
-     * to the current locale's default format.
-     */
-    private void reorderSpinners() {
-        mSpinners.removeAllViews();
-        // We use numeric spinners for year and day, but textual months. Ask icu4c what
-        // order the user's locale uses for that combination. http://b/7207103.
-        String pattern = ICU.getBestDateTimePattern("yyyyMMMdd", Locale.getDefault().toString());
-        char[] order = ICU.getDateFormatOrder(pattern);
-        final int spinnerCount = order.length;
-        for (int i = 0; i < spinnerCount; i++) {
-            switch (order[i]) {
-                case 'd':
-                    mSpinners.addView(mDaySpinner);
-                    setImeOptions(mDaySpinner, spinnerCount, i);
-                    break;
-                case 'M':
-                    mSpinners.addView(mMonthSpinner);
-                    setImeOptions(mMonthSpinner, spinnerCount, i);
-                    break;
-                case 'y':
-                    mSpinners.addView(mYearSpinner);
-                    setImeOptions(mYearSpinner, spinnerCount, i);
-                    break;
-                default:
-                    throw new IllegalArgumentException(Arrays.toString(order));
-            }
-        }
-    }
-
-    /**
-     * Updates the current date.
-     *
-     * @param year The year.
-     * @param month The month which is <strong>starting from zero</strong>.
-     * @param dayOfMonth The day of the month.
-     */
-    public void updateDate(int year, int month, int dayOfMonth) {
-        if (!isNewDate(year, month, dayOfMonth)) {
-            return;
-        }
-        setDate(year, month, dayOfMonth);
-        updateSpinners();
-        updateCalendarView();
-        notifyDateChanged();
-    }
-
-    // Override so we are in complete control of save / restore for this widget.
-    @Override
-    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
-        dispatchThawSelfOnly(container);
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Parcelable superState = super.onSaveInstanceState();
-        return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-        setDate(ss.mYear, ss.mMonth, ss.mDay);
-        updateSpinners();
-        updateCalendarView();
+        mDelegate = new LegacyDatePickerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
     }
 
     /**
@@ -599,191 +123,881 @@
      *            user, can be null.
      */
     public void init(int year, int monthOfYear, int dayOfMonth,
-            OnDateChangedListener onDateChangedListener) {
-        setDate(year, monthOfYear, dayOfMonth);
-        updateSpinners();
-        updateCalendarView();
-        mOnDateChangedListener = onDateChangedListener;
+                     OnDateChangedListener onDateChangedListener) {
+        mDelegate.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
     }
 
     /**
-     * Parses the given <code>date</code> and in case of success sets the result
-     * to the <code>outDate</code>.
+     * Updates the current date.
      *
-     * @return True if the date was parsed.
+     * @param year The year.
+     * @param month The month which is <strong>starting from zero</strong>.
+     * @param dayOfMonth The day of the month.
      */
-    private boolean parseDate(String date, Calendar outDate) {
-        try {
-            outDate.setTime(mDateFormat.parse(date));
-            return true;
-        } catch (ParseException e) {
-            Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
-            return false;
-        }
-    }
-
-    private boolean isNewDate(int year, int month, int dayOfMonth) {
-        return (mCurrentDate.get(Calendar.YEAR) != year
-                || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
-                || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
-    }
-
-    private void setDate(int year, int month, int dayOfMonth) {
-        mCurrentDate.set(year, month, dayOfMonth);
-        if (mCurrentDate.before(mMinDate)) {
-            mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
-        } else if (mCurrentDate.after(mMaxDate)) {
-            mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
-        }
-    }
-
-    private void updateSpinners() {
-        // set the spinner ranges respecting the min and max dates
-        if (mCurrentDate.equals(mMinDate)) {
-            mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setWrapSelectorWheel(false);
-            mMonthSpinner.setDisplayedValues(null);
-            mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
-            mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
-            mMonthSpinner.setWrapSelectorWheel(false);
-        } else if (mCurrentDate.equals(mMaxDate)) {
-            mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setWrapSelectorWheel(false);
-            mMonthSpinner.setDisplayedValues(null);
-            mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
-            mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
-            mMonthSpinner.setWrapSelectorWheel(false);
-        } else {
-            mDaySpinner.setMinValue(1);
-            mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
-            mDaySpinner.setWrapSelectorWheel(true);
-            mMonthSpinner.setDisplayedValues(null);
-            mMonthSpinner.setMinValue(0);
-            mMonthSpinner.setMaxValue(11);
-            mMonthSpinner.setWrapSelectorWheel(true);
-        }
-
-        // make sure the month names are a zero based array
-        // with the months in the month spinner
-        String[] displayedValues = Arrays.copyOfRange(mShortMonths,
-                mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
-        mMonthSpinner.setDisplayedValues(displayedValues);
-
-        // year spinner range does not change based on the current date
-        mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
-        mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
-        mYearSpinner.setWrapSelectorWheel(false);
-
-        // set the spinner values
-        mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
-        mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
-        mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
-
-        if (usingNumericMonths()) {
-            mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
-        }
-    }
-
-    /**
-     * Updates the calendar view with the current date.
-     */
-    private void updateCalendarView() {
-         mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
+    public void updateDate(int year, int month, int dayOfMonth) {
+        mDelegate.updateDate(year, month, dayOfMonth);
     }
 
     /**
      * @return The selected year.
      */
     public int getYear() {
-        return mCurrentDate.get(Calendar.YEAR);
+        return mDelegate.getYear();
     }
 
     /**
      * @return The selected month.
      */
     public int getMonth() {
-        return mCurrentDate.get(Calendar.MONTH);
+        return mDelegate.getMonth();
     }
 
     /**
      * @return The selected day of month.
      */
     public int getDayOfMonth() {
-        return mCurrentDate.get(Calendar.DAY_OF_MONTH);
+        return mDelegate.getDayOfMonth();
     }
 
     /**
-     * Notifies the listener, if such, for a change in the selected date.
-     */
-    private void notifyDateChanged() {
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-        if (mOnDateChangedListener != null) {
-            mOnDateChangedListener.onDateChanged(this, getYear(), getMonth(), getDayOfMonth());
-        }
-    }
-
-    /**
-     * Sets the IME options for a spinner based on its ordering.
+     * Gets the minimal date supported by this {@link DatePicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     * <p>
+     * Note: The default minimal date is 01/01/1900.
+     * <p>
      *
-     * @param spinner The spinner.
-     * @param spinnerCount The total spinner count.
-     * @param spinnerIndex The index of the given spinner.
+     * @return The minimal supported date.
      */
-    private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
-        final int imeOptions;
-        if (spinnerIndex < spinnerCount - 1) {
-            imeOptions = EditorInfo.IME_ACTION_NEXT;
-        } else {
-            imeOptions = EditorInfo.IME_ACTION_DONE;
+    public long getMinDate() {
+        return mDelegate.getMinDate();
+    }
+
+    /**
+     * Sets the minimal date supported by this {@link NumberPicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     *
+     * @param minDate The minimal supported date.
+     */
+    public void setMinDate(long minDate) {
+        mDelegate.setMinDate(minDate);
+    }
+
+    /**
+     * Gets the maximal date supported by this {@link DatePicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     * <p>
+     * Note: The default maximal date is 12/31/2100.
+     * <p>
+     *
+     * @return The maximal supported date.
+     */
+    public long getMaxDate() {
+        return mDelegate.getMaxDate();
+    }
+
+    /**
+     * Sets the maximal date supported by this {@link DatePicker} in
+     * milliseconds since January 1, 1970 00:00:00 in
+     * {@link TimeZone#getDefault()} time zone.
+     *
+     * @param maxDate The maximal supported date.
+     */
+    public void setMaxDate(long maxDate) {
+        mDelegate.setMaxDate(maxDate);
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (mDelegate.isEnabled() == enabled) {
+            return;
         }
-        TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
-        input.setImeOptions(imeOptions);
+        super.setEnabled(enabled);
+        mDelegate.setEnabled(enabled);
     }
 
-    private void setContentDescriptions() {
-        // Day
-        trySetContentDescription(mDaySpinner, R.id.increment,
-                R.string.date_picker_increment_day_button);
-        trySetContentDescription(mDaySpinner, R.id.decrement,
-                R.string.date_picker_decrement_day_button);
-        // Month
-        trySetContentDescription(mMonthSpinner, R.id.increment,
-                R.string.date_picker_increment_month_button);
-        trySetContentDescription(mMonthSpinner, R.id.decrement,
-                R.string.date_picker_decrement_month_button);
-        // Year
-        trySetContentDescription(mYearSpinner, R.id.increment,
-                R.string.date_picker_increment_year_button);
-        trySetContentDescription(mYearSpinner, R.id.decrement,
-                R.string.date_picker_decrement_year_button);
+    @Override
+    public boolean isEnabled() {
+        return mDelegate.isEnabled();
     }
 
-    private void trySetContentDescription(View root, int viewId, int contDescResId) {
-        View target = root.findViewById(viewId);
-        if (target != null) {
-            target.setContentDescription(mContext.getString(contDescResId));
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        return mDelegate.dispatchPopulateAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        super.onPopulateAccessibilityEvent(event);
+        mDelegate.onPopulateAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        mDelegate.onInitializeAccessibilityEvent(event);
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        mDelegate.onInitializeAccessibilityNodeInfo(info);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mDelegate.onConfigurationChanged(newConfig);
+    }
+
+    /**
+     * Gets whether the {@link CalendarView} is shown.
+     *
+     * @return True if the calendar view is shown.
+     * @see #getCalendarView()
+     */
+    public boolean getCalendarViewShown() {
+        return mDelegate.getCalendarViewShown();
+    }
+
+    /**
+     * Gets the {@link CalendarView}.
+     *
+     * @return The calendar view.
+     * @see #getCalendarViewShown()
+     */
+    public CalendarView getCalendarView () {
+        return mDelegate.getCalendarView();
+    }
+
+    /**
+     * Sets whether the {@link CalendarView} is shown.
+     *
+     * @param shown True if the calendar view is to be shown.
+     */
+    public void setCalendarViewShown(boolean shown) {
+        mDelegate.setCalendarViewShown(shown);
+    }
+
+    /**
+     * Gets whether the spinners are shown.
+     *
+     * @return True if the spinners are shown.
+     */
+    public boolean getSpinnersShown() {
+        return mDelegate.getSpinnersShown();
+    }
+
+    /**
+     * Sets whether the spinners are shown.
+     *
+     * @param shown True if the spinners are to be shown.
+     */
+    public void setSpinnersShown(boolean shown) {
+        mDelegate.setSpinnersShown(shown);
+    }
+
+    // Override so we are in complete control of save / restore for this widget.
+    @Override
+    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+        mDelegate.dispatchRestoreInstanceState(container);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        return mDelegate.onSaveInstanceState(superState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mDelegate.onRestoreInstanceState(ss);
+    }
+
+    /**
+     * A delegate interface that defined the public API of the DatePicker. Allows different
+     * DatePicker implementations. This would need to be implemented by the DatePicker delegates
+     * for the real behavior.
+     */
+    interface DatePickerDelegate {
+        void init(int year, int monthOfYear, int dayOfMonth,
+                  OnDateChangedListener onDateChangedListener);
+
+        void updateDate(int year, int month, int dayOfMonth);
+
+        int getYear();
+        int getMonth();
+        int getDayOfMonth();
+
+        void setMinDate(long minDate);
+        long getMinDate();
+
+        void setMaxDate(long maxDate);
+        long getMaxDate();
+
+        void setEnabled(boolean enabled);
+        boolean isEnabled();
+
+        CalendarView getCalendarView ();
+
+        void setCalendarViewShown(boolean shown);
+        boolean getCalendarViewShown();
+
+        void setSpinnersShown(boolean shown);
+        boolean getSpinnersShown();
+
+        void onConfigurationChanged(Configuration newConfig);
+
+        void dispatchRestoreInstanceState(SparseArray<Parcelable> container);
+        Parcelable onSaveInstanceState(Parcelable superState);
+        void onRestoreInstanceState(Parcelable state);
+
+        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
+    }
+
+    /**
+     * An abstract class which can be used as a start for DatePicker implementations
+     */
+    abstract static class AbstractTimePickerDelegate implements DatePickerDelegate {
+        // The delegator
+        protected DatePicker mDelegator;
+
+        // The context
+        protected Context mContext;
+
+        // The current locale
+        protected Locale mCurrentLocale;
+
+        // Callbacks
+        protected  OnDateChangedListener mOnDateChangedListener;
+
+        public AbstractTimePickerDelegate(DatePicker delegator, Context context) {
+            mDelegator = delegator;
+            mContext = context;
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+        }
+
+        protected void setCurrentLocale(Locale locale) {
+            if (locale.equals(mCurrentLocale)) {
+                return;
+            }
+            mCurrentLocale = locale;
         }
     }
 
-    private void updateInputState() {
-        // Make sure that if the user changes the value and the IME is active
-        // for one of the inputs if this widget, the IME is closed. If the user
-        // changed the value via the IME and there is a next input the IME will
-        // be shown, otherwise the user chose another means of changing the
-        // value and having the IME up makes no sense.
-        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
-        if (inputMethodManager != null) {
-            if (inputMethodManager.isActive(mYearSpinnerInput)) {
-                mYearSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
-                mMonthSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
-                mDaySpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+    /**
+     * A delegate implementing the basic DatePicker
+     */
+    private static class LegacyDatePickerDelegate extends AbstractTimePickerDelegate {
+
+        private static final String DATE_FORMAT = "MM/dd/yyyy";
+
+        private static final int DEFAULT_START_YEAR = 1900;
+
+        private static final int DEFAULT_END_YEAR = 2100;
+
+        private static final boolean DEFAULT_CALENDAR_VIEW_SHOWN = true;
+
+        private static final boolean DEFAULT_SPINNERS_SHOWN = true;
+
+        private static final boolean DEFAULT_ENABLED_STATE = true;
+
+        private final LinearLayout mSpinners;
+
+        private final NumberPicker mDaySpinner;
+
+        private final NumberPicker mMonthSpinner;
+
+        private final NumberPicker mYearSpinner;
+
+        private final EditText mDaySpinnerInput;
+
+        private final EditText mMonthSpinnerInput;
+
+        private final EditText mYearSpinnerInput;
+
+        private final CalendarView mCalendarView;
+
+        private String[] mShortMonths;
+
+        private final java.text.DateFormat mDateFormat = new SimpleDateFormat(DATE_FORMAT);
+
+        private int mNumberOfMonths;
+
+        private Calendar mTempDate;
+
+        private Calendar mMinDate;
+
+        private Calendar mMaxDate;
+
+        private Calendar mCurrentDate;
+
+        private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+
+        LegacyDatePickerDelegate(DatePicker delegator, Context context, AttributeSet attrs,
+                int defStyleAttr, int defStyleRes) {
+            super(delegator, context);
+
+            mDelegator = delegator;
+            mContext = context;
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+
+            final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
+                    R.styleable.DatePicker, defStyleAttr, defStyleRes);
+            boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
+                    DEFAULT_SPINNERS_SHOWN);
+            boolean calendarViewShown = attributesArray.getBoolean(
+                    R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
+            int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
+                    DEFAULT_START_YEAR);
+            int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
+            String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
+            String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
+            int layoutResourceId = attributesArray.getResourceId(
+                    R.styleable.DatePicker_internalLayout, R.layout.date_picker);
+            attributesArray.recycle();
+
+            LayoutInflater inflater = (LayoutInflater) context
+                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            inflater.inflate(layoutResourceId, mDelegator, true);
+
+            OnValueChangeListener onChangeListener = new OnValueChangeListener() {
+                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                    updateInputState();
+                    mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
+                    // take care of wrapping of days and months to update greater fields
+                    if (picker == mDaySpinner) {
+                        int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
+                        if (oldVal == maxDayOfMonth && newVal == 1) {
+                            mTempDate.add(Calendar.DAY_OF_MONTH, 1);
+                        } else if (oldVal == 1 && newVal == maxDayOfMonth) {
+                            mTempDate.add(Calendar.DAY_OF_MONTH, -1);
+                        } else {
+                            mTempDate.add(Calendar.DAY_OF_MONTH, newVal - oldVal);
+                        }
+                    } else if (picker == mMonthSpinner) {
+                        if (oldVal == 11 && newVal == 0) {
+                            mTempDate.add(Calendar.MONTH, 1);
+                        } else if (oldVal == 0 && newVal == 11) {
+                            mTempDate.add(Calendar.MONTH, -1);
+                        } else {
+                            mTempDate.add(Calendar.MONTH, newVal - oldVal);
+                        }
+                    } else if (picker == mYearSpinner) {
+                        mTempDate.set(Calendar.YEAR, newVal);
+                    } else {
+                        throw new IllegalArgumentException();
+                    }
+                    // now set the date to the adjusted one
+                    setDate(mTempDate.get(Calendar.YEAR), mTempDate.get(Calendar.MONTH),
+                            mTempDate.get(Calendar.DAY_OF_MONTH));
+                    updateSpinners();
+                    updateCalendarView();
+                    notifyDateChanged();
+                }
+            };
+
+            mSpinners = (LinearLayout) mDelegator.findViewById(R.id.pickers);
+
+            // calendar view day-picker
+            mCalendarView = (CalendarView) mDelegator.findViewById(R.id.calendar_view);
+            mCalendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
+                public void onSelectedDayChange(CalendarView view, int year, int month, int monthDay) {
+                    setDate(year, month, monthDay);
+                    updateSpinners();
+                    notifyDateChanged();
+                }
+            });
+
+            // day
+            mDaySpinner = (NumberPicker) mDelegator.findViewById(R.id.day);
+            mDaySpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
+            mDaySpinner.setOnLongPressUpdateInterval(100);
+            mDaySpinner.setOnValueChangedListener(onChangeListener);
+            mDaySpinnerInput = (EditText) mDaySpinner.findViewById(R.id.numberpicker_input);
+
+            // month
+            mMonthSpinner = (NumberPicker) mDelegator.findViewById(R.id.month);
+            mMonthSpinner.setMinValue(0);
+            mMonthSpinner.setMaxValue(mNumberOfMonths - 1);
+            mMonthSpinner.setDisplayedValues(mShortMonths);
+            mMonthSpinner.setOnLongPressUpdateInterval(200);
+            mMonthSpinner.setOnValueChangedListener(onChangeListener);
+            mMonthSpinnerInput = (EditText) mMonthSpinner.findViewById(R.id.numberpicker_input);
+
+            // year
+            mYearSpinner = (NumberPicker) mDelegator.findViewById(R.id.year);
+            mYearSpinner.setOnLongPressUpdateInterval(100);
+            mYearSpinner.setOnValueChangedListener(onChangeListener);
+            mYearSpinnerInput = (EditText) mYearSpinner.findViewById(R.id.numberpicker_input);
+
+            // show only what the user required but make sure we
+            // show something and the spinners have higher priority
+            if (!spinnersShown && !calendarViewShown) {
+                setSpinnersShown(true);
+            } else {
+                setSpinnersShown(spinnersShown);
+                setCalendarViewShown(calendarViewShown);
+            }
+
+            // set the min date giving priority of the minDate over startYear
+            mTempDate.clear();
+            if (!TextUtils.isEmpty(minDate)) {
+                if (!parseDate(minDate, mTempDate)) {
+                    mTempDate.set(startYear, 0, 1);
+                }
+            } else {
+                mTempDate.set(startYear, 0, 1);
+            }
+            setMinDate(mTempDate.getTimeInMillis());
+
+            // set the max date giving priority of the maxDate over endYear
+            mTempDate.clear();
+            if (!TextUtils.isEmpty(maxDate)) {
+                if (!parseDate(maxDate, mTempDate)) {
+                    mTempDate.set(endYear, 11, 31);
+                }
+            } else {
+                mTempDate.set(endYear, 11, 31);
+            }
+            setMaxDate(mTempDate.getTimeInMillis());
+
+            // initialize to current date
+            mCurrentDate.setTimeInMillis(System.currentTimeMillis());
+            init(mCurrentDate.get(Calendar.YEAR), mCurrentDate.get(Calendar.MONTH), mCurrentDate
+                    .get(Calendar.DAY_OF_MONTH), null);
+
+            // re-order the number spinners to match the current date format
+            reorderSpinners();
+
+            // accessibility
+            setContentDescriptions();
+
+            // If not explicitly specified this view is important for accessibility.
+            if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+                mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+            }
+        }
+
+        @Override
+        public void init(int year, int monthOfYear, int dayOfMonth,
+                         OnDateChangedListener onDateChangedListener) {
+            setDate(year, monthOfYear, dayOfMonth);
+            updateSpinners();
+            updateCalendarView();
+            mOnDateChangedListener = onDateChangedListener;
+        }
+
+        @Override
+        public void updateDate(int year, int month, int dayOfMonth) {
+            if (!isNewDate(year, month, dayOfMonth)) {
+                return;
+            }
+            setDate(year, month, dayOfMonth);
+            updateSpinners();
+            updateCalendarView();
+            notifyDateChanged();
+        }
+
+        @Override
+        public int getYear() {
+            return mCurrentDate.get(Calendar.YEAR);
+        }
+
+        @Override
+        public int getMonth() {
+            return mCurrentDate.get(Calendar.MONTH);
+        }
+
+        @Override
+        public int getDayOfMonth() {
+            return mCurrentDate.get(Calendar.DAY_OF_MONTH);
+        }
+
+        @Override
+        public void setMinDate(long minDate) {
+            mTempDate.setTimeInMillis(minDate);
+            if (mTempDate.get(Calendar.YEAR) == mMinDate.get(Calendar.YEAR)
+                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMinDate.get(Calendar.DAY_OF_YEAR)) {
+                return;
+            }
+            mMinDate.setTimeInMillis(minDate);
+            mCalendarView.setMinDate(minDate);
+            if (mCurrentDate.before(mMinDate)) {
+                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
+                updateCalendarView();
+            }
+            updateSpinners();
+        }
+
+        @Override
+        public long getMinDate() {
+            return mCalendarView.getMinDate();
+        }
+
+        @Override
+        public void setMaxDate(long maxDate) {
+            mTempDate.setTimeInMillis(maxDate);
+            if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)
+                    && mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {
+                return;
+            }
+            mMaxDate.setTimeInMillis(maxDate);
+            mCalendarView.setMaxDate(maxDate);
+            if (mCurrentDate.after(mMaxDate)) {
+                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
+                updateCalendarView();
+            }
+            updateSpinners();
+        }
+
+        @Override
+        public long getMaxDate() {
+            return mCalendarView.getMaxDate();
+        }
+
+        @Override
+        public void setEnabled(boolean enabled) {
+            mDaySpinner.setEnabled(enabled);
+            mMonthSpinner.setEnabled(enabled);
+            mYearSpinner.setEnabled(enabled);
+            mCalendarView.setEnabled(enabled);
+            mIsEnabled = enabled;
+        }
+
+        @Override
+        public boolean isEnabled() {
+            return mIsEnabled;
+        }
+
+        @Override
+        public CalendarView getCalendarView() {
+            return mCalendarView;
+        }
+
+        @Override
+        public void setCalendarViewShown(boolean shown) {
+            mCalendarView.setVisibility(shown ? VISIBLE : GONE);
+        }
+
+        @Override
+        public boolean getCalendarViewShown() {
+            return (mCalendarView.getVisibility() == View.VISIBLE);
+        }
+
+        @Override
+        public void setSpinnersShown(boolean shown) {
+            mSpinners.setVisibility(shown ? VISIBLE : GONE);
+        }
+
+        @Override
+        public boolean getSpinnersShown() {
+            return mSpinners.isShown();
+        }
+
+        @Override
+        public void onConfigurationChanged(Configuration newConfig) {
+            setCurrentLocale(newConfig.locale);
+        }
+
+        @Override
+        public void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+            mDelegator.dispatchThawSelfOnly(container);
+        }
+
+        @Override
+        public Parcelable onSaveInstanceState(Parcelable superState) {
+            return new SavedState(superState, getYear(), getMonth(), getDayOfMonth());
+        }
+
+        @Override
+        public void onRestoreInstanceState(Parcelable state) {
+            SavedState ss = (SavedState) state;
+            setDate(ss.mYear, ss.mMonth, ss.mDay);
+            updateSpinners();
+            updateCalendarView();
+        }
+
+        @Override
+        public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+            onPopulateAccessibilityEvent(event);
+            return true;
+        }
+
+        @Override
+        public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+            final int flags = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR;
+            String selectedDateUtterance = DateUtils.formatDateTime(mContext,
+                    mCurrentDate.getTimeInMillis(), flags);
+            event.getText().add(selectedDateUtterance);
+        }
+
+        @Override
+        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+            event.setClassName(DatePicker.class.getName());
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+            info.setClassName(DatePicker.class.getName());
+        }
+
+        /**
+         * Sets the current locale.
+         *
+         * @param locale The current locale.
+         */
+        @Override
+        protected void setCurrentLocale(Locale locale) {
+            super.setCurrentLocale(locale);
+
+            mTempDate = getCalendarForLocale(mTempDate, locale);
+            mMinDate = getCalendarForLocale(mMinDate, locale);
+            mMaxDate = getCalendarForLocale(mMaxDate, locale);
+            mCurrentDate = getCalendarForLocale(mCurrentDate, locale);
+
+            mNumberOfMonths = mTempDate.getActualMaximum(Calendar.MONTH) + 1;
+            mShortMonths = new DateFormatSymbols().getShortMonths();
+
+            if (usingNumericMonths()) {
+                // We're in a locale where a date should either be all-numeric, or all-text.
+                // All-text would require custom NumberPicker formatters for day and year.
+                mShortMonths = new String[mNumberOfMonths];
+                for (int i = 0; i < mNumberOfMonths; ++i) {
+                    mShortMonths[i] = String.format("%d", i + 1);
+                }
+            }
+        }
+
+        /**
+         * Tests whether the current locale is one where there are no real month names,
+         * such as Chinese, Japanese, or Korean locales.
+         */
+        private boolean usingNumericMonths() {
+            return Character.isDigit(mShortMonths[Calendar.JANUARY].charAt(0));
+        }
+
+        /**
+         * Gets a calendar for locale bootstrapped with the value of a given calendar.
+         *
+         * @param oldCalendar The old calendar.
+         * @param locale The locale.
+         */
+        private Calendar getCalendarForLocale(Calendar oldCalendar, Locale locale) {
+            if (oldCalendar == null) {
+                return Calendar.getInstance(locale);
+            } else {
+                final long currentTimeMillis = oldCalendar.getTimeInMillis();
+                Calendar newCalendar = Calendar.getInstance(locale);
+                newCalendar.setTimeInMillis(currentTimeMillis);
+                return newCalendar;
+            }
+        }
+
+        /**
+         * Reorders the spinners according to the date format that is
+         * explicitly set by the user and if no such is set fall back
+         * to the current locale's default format.
+         */
+        private void reorderSpinners() {
+            mSpinners.removeAllViews();
+            // We use numeric spinners for year and day, but textual months. Ask icu4c what
+            // order the user's locale uses for that combination. http://b/7207103.
+            String pattern = ICU.getBestDateTimePattern("yyyyMMMdd",
+                    Locale.getDefault().toString());
+            char[] order = ICU.getDateFormatOrder(pattern);
+            final int spinnerCount = order.length;
+            for (int i = 0; i < spinnerCount; i++) {
+                switch (order[i]) {
+                    case 'd':
+                        mSpinners.addView(mDaySpinner);
+                        setImeOptions(mDaySpinner, spinnerCount, i);
+                        break;
+                    case 'M':
+                        mSpinners.addView(mMonthSpinner);
+                        setImeOptions(mMonthSpinner, spinnerCount, i);
+                        break;
+                    case 'y':
+                        mSpinners.addView(mYearSpinner);
+                        setImeOptions(mYearSpinner, spinnerCount, i);
+                        break;
+                    default:
+                        throw new IllegalArgumentException(Arrays.toString(order));
+                }
+            }
+        }
+
+        /**
+         * Parses the given <code>date</code> and in case of success sets the result
+         * to the <code>outDate</code>.
+         *
+         * @return True if the date was parsed.
+         */
+        private boolean parseDate(String date, Calendar outDate) {
+            try {
+                outDate.setTime(mDateFormat.parse(date));
+                return true;
+            } catch (ParseException e) {
+                Log.w(LOG_TAG, "Date: " + date + " not in format: " + DATE_FORMAT);
+                return false;
+            }
+        }
+
+        private boolean isNewDate(int year, int month, int dayOfMonth) {
+            return (mCurrentDate.get(Calendar.YEAR) != year
+                    || mCurrentDate.get(Calendar.MONTH) != dayOfMonth
+                    || mCurrentDate.get(Calendar.DAY_OF_MONTH) != month);
+        }
+
+        private void setDate(int year, int month, int dayOfMonth) {
+            mCurrentDate.set(year, month, dayOfMonth);
+            if (mCurrentDate.before(mMinDate)) {
+                mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
+            } else if (mCurrentDate.after(mMaxDate)) {
+                mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
+            }
+        }
+
+        private void updateSpinners() {
+            // set the spinner ranges respecting the min and max dates
+            if (mCurrentDate.equals(mMinDate)) {
+                mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setWrapSelectorWheel(false);
+                mMonthSpinner.setDisplayedValues(null);
+                mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
+                mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
+                mMonthSpinner.setWrapSelectorWheel(false);
+            } else if (mCurrentDate.equals(mMaxDate)) {
+                mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setWrapSelectorWheel(false);
+                mMonthSpinner.setDisplayedValues(null);
+                mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
+                mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
+                mMonthSpinner.setWrapSelectorWheel(false);
+            } else {
+                mDaySpinner.setMinValue(1);
+                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
+                mDaySpinner.setWrapSelectorWheel(true);
+                mMonthSpinner.setDisplayedValues(null);
+                mMonthSpinner.setMinValue(0);
+                mMonthSpinner.setMaxValue(11);
+                mMonthSpinner.setWrapSelectorWheel(true);
+            }
+
+            // make sure the month names are a zero based array
+            // with the months in the month spinner
+            String[] displayedValues = Arrays.copyOfRange(mShortMonths,
+                    mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
+            mMonthSpinner.setDisplayedValues(displayedValues);
+
+            // year spinner range does not change based on the current date
+            mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
+            mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));
+            mYearSpinner.setWrapSelectorWheel(false);
+
+            // set the spinner values
+            mYearSpinner.setValue(mCurrentDate.get(Calendar.YEAR));
+            mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
+            mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
+
+            if (usingNumericMonths()) {
+                mMonthSpinnerInput.setRawInputType(InputType.TYPE_CLASS_NUMBER);
+            }
+        }
+
+        /**
+         * Updates the calendar view with the current date.
+         */
+        private void updateCalendarView() {
+            mCalendarView.setDate(mCurrentDate.getTimeInMillis(), false, false);
+        }
+
+
+        /**
+         * Notifies the listener, if such, for a change in the selected date.
+         */
+        private void notifyDateChanged() {
+            mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+            if (mOnDateChangedListener != null) {
+                mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(),
+                        getDayOfMonth());
+            }
+        }
+
+        /**
+         * Sets the IME options for a spinner based on its ordering.
+         *
+         * @param spinner The spinner.
+         * @param spinnerCount The total spinner count.
+         * @param spinnerIndex The index of the given spinner.
+         */
+        private void setImeOptions(NumberPicker spinner, int spinnerCount, int spinnerIndex) {
+            final int imeOptions;
+            if (spinnerIndex < spinnerCount - 1) {
+                imeOptions = EditorInfo.IME_ACTION_NEXT;
+            } else {
+                imeOptions = EditorInfo.IME_ACTION_DONE;
+            }
+            TextView input = (TextView) spinner.findViewById(R.id.numberpicker_input);
+            input.setImeOptions(imeOptions);
+        }
+
+        private void setContentDescriptions() {
+            // Day
+            trySetContentDescription(mDaySpinner, R.id.increment,
+                    R.string.date_picker_increment_day_button);
+            trySetContentDescription(mDaySpinner, R.id.decrement,
+                    R.string.date_picker_decrement_day_button);
+            // Month
+            trySetContentDescription(mMonthSpinner, R.id.increment,
+                    R.string.date_picker_increment_month_button);
+            trySetContentDescription(mMonthSpinner, R.id.decrement,
+                    R.string.date_picker_decrement_month_button);
+            // Year
+            trySetContentDescription(mYearSpinner, R.id.increment,
+                    R.string.date_picker_increment_year_button);
+            trySetContentDescription(mYearSpinner, R.id.decrement,
+                    R.string.date_picker_decrement_year_button);
+        }
+
+        private void trySetContentDescription(View root, int viewId, int contDescResId) {
+            View target = root.findViewById(viewId);
+            if (target != null) {
+                target.setContentDescription(mContext.getString(contDescResId));
+            }
+        }
+
+        private void updateInputState() {
+            // Make sure that if the user changes the value and the IME is active
+            // for one of the inputs if this widget, the IME is closed. If the user
+            // changed the value via the IME and there is a next input the IME will
+            // be shown, otherwise the user chose another means of changing the
+            // value and having the IME up makes no sense.
+            InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+            if (inputMethodManager != null) {
+                if (inputMethodManager.isActive(mYearSpinnerInput)) {
+                    mYearSpinnerInput.clearFocus();
+                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+                } else if (inputMethodManager.isActive(mMonthSpinnerInput)) {
+                    mMonthSpinnerInput.clearFocus();
+                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+                } else if (inputMethodManager.isActive(mDaySpinnerInput)) {
+                    mDaySpinnerInput.clearFocus();
+                    inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+                }
             }
         }
     }
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index af6bbcb..45d1403 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -27,12 +27,9 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.provider.Settings;
-import android.provider.Settings.SettingNotFoundException;
 import android.widget.TextView;
 import android.widget.RemoteViews.RemoteView;
 
-import com.android.internal.R;
-
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
diff --git a/core/java/android/widget/DialerFilter.java b/core/java/android/widget/DialerFilter.java
index 20bc114..78786e1 100644
--- a/core/java/android/widget/DialerFilter.java
+++ b/core/java/android/widget/DialerFilter.java
@@ -28,8 +28,6 @@
 import android.text.method.KeyListener;
 import android.text.method.TextKeyListener;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.KeyCharacterMap;
 import android.view.View;
 import android.graphics.Rect;
 
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 30752e0..fa37443 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -136,8 +136,8 @@
      */
     public EdgeEffect(Context context) {
         final Resources res = context.getResources();
-        mEdge = res.getDrawable(R.drawable.overscroll_edge);
-        mGlow = res.getDrawable(R.drawable.overscroll_glow);
+        mEdge = context.getDrawable(R.drawable.overscroll_edge);
+        mGlow = context.getDrawable(R.drawable.overscroll_glow);
 
         mEdgeHeight = mEdge.getIntrinsicHeight();
         mGlowHeight = mGlow.getIntrinsicHeight();
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index 57e51c2..a8ff562 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -17,6 +17,7 @@
 package android.widget;
 
 import android.content.Context;
+import android.os.Bundle;
 import android.text.Editable;
 import android.text.Selection;
 import android.text.Spannable;
@@ -56,8 +57,12 @@
         this(context, attrs, com.android.internal.R.attr.editTextStyle);
     }
 
-    public EditText(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public EditText(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public EditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
@@ -128,4 +133,22 @@
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(EditText.class.getName());
     }
+
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_SET_TEXT: {
+                CharSequence text = (arguments != null) ? arguments.getCharSequence(
+                        AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE) : null;
+                setText(text);
+                if (text != null && text.length() > 0) {
+                    setSelection(text.length());
+                }
+                return true;
+            }
+            default: {
+                return super.performAccessibilityAction(action, arguments);
+            }
+        }
+    }
 }
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 748af7b..333e631 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -23,6 +23,7 @@
 import android.os.Parcelable;
 import android.text.InputFilter;
 import android.text.SpannableString;
+
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.EditableInputConnection;
 
@@ -45,8 +46,6 @@
 import android.inputmethodservice.ExtractEditText;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.DynamicLayout;
@@ -75,10 +74,11 @@
 import android.util.Log;
 import android.view.ActionMode;
 import android.view.ActionMode.Callback;
-import android.view.DisplayList;
+import android.view.RenderNode;
 import android.view.DragEvent;
 import android.view.Gravity;
 import android.view.HardwareCanvas;
+import android.view.HardwareRenderer;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -137,7 +137,16 @@
     InputContentType mInputContentType;
     InputMethodState mInputMethodState;
 
-    DisplayList[] mTextDisplayLists;
+    private static class TextDisplayList {
+        RenderNode displayList;
+        boolean isDirty;
+        public TextDisplayList(String name) {
+            isDirty = true;
+            displayList = RenderNode.create(name);
+        }
+        boolean needsRecord() { return isDirty || !displayList.isValid(); }
+    }
+    TextDisplayList[] mTextDisplayLists;
 
     boolean mFrozenWithFocus;
     boolean mSelectionMoved;
@@ -262,7 +271,7 @@
             mTextView.removeCallbacks(mShowSuggestionRunnable);
         }
 
-        invalidateTextDisplayList();
+        destroyDisplayListsData();
 
         if (mSpellChecker != null) {
             mSpellChecker.closeSession();
@@ -277,6 +286,18 @@
         mTemporaryDetach = false;
     }
 
+    private void destroyDisplayListsData() {
+        if (mTextDisplayLists != null) {
+            for (int i = 0; i < mTextDisplayLists.length; i++) {
+                RenderNode displayList = mTextDisplayLists[i] != null
+                        ? mTextDisplayLists[i].displayList : null;
+                if (displayList != null && displayList.isValid()) {
+                    displayList.destroyDisplayListData();
+                }
+            }
+        }
+    }
+
     private void showError() {
         if (mTextView.getWindowToken() == null) {
             mShowErrorAfterAttach = true;
@@ -1316,10 +1337,11 @@
 
         layout.drawBackground(canvas, highlight, highlightPaint, cursorOffsetVertical,
                 firstLine, lastLine);
+        final HardwareRenderer renderer = mTextView.getHardwareRenderer();
 
         if (layout instanceof DynamicLayout) {
             if (mTextDisplayLists == null) {
-                mTextDisplayLists = new DisplayList[ArrayUtils.idealObjectArraySize(0)];
+                mTextDisplayLists = new TextDisplayList[ArrayUtils.idealObjectArraySize(0)];
             }
 
             DynamicLayout dynamicLayout = (DynamicLayout) layout;
@@ -1343,15 +1365,13 @@
                     searchStartIndex = blockIndex + 1;
                 }
 
-                DisplayList blockDisplayList = mTextDisplayLists[blockIndex];
-                if (blockDisplayList == null) {
-                    blockDisplayList = mTextDisplayLists[blockIndex] =
-                            mTextView.getHardwareRenderer().createDisplayList("Text " + blockIndex);
-                } else {
-                    if (blockIsInvalid) blockDisplayList.clear();
+                if (mTextDisplayLists[blockIndex] == null) {
+                    mTextDisplayLists[blockIndex] =
+                            new TextDisplayList("Text " + blockIndex);
                 }
 
-                final boolean blockDisplayListIsInvalid = !blockDisplayList.isValid();
+                final boolean blockDisplayListIsInvalid = mTextDisplayLists[blockIndex].needsRecord();
+                RenderNode blockDisplayList = mTextDisplayLists[blockIndex].displayList;
                 if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
                     final int blockBeginLine = endOfPreviousBlock + 1;
                     final int top = layout.getLineTop(blockBeginLine);
@@ -1381,7 +1401,7 @@
                             // No need to untranslate, previous context is popped after
                             // drawDisplayList
                         } finally {
-                            blockDisplayList.end();
+                            blockDisplayList.end(renderer, hardwareCanvas);
                             // Same as drawDisplayList below, handled by our TextView's parent
                             blockDisplayList.setClipToBounds(false);
                         }
@@ -1422,7 +1442,7 @@
 
         // No available index found, the pool has to grow
         int newSize = ArrayUtils.idealIntArraySize(length + 1);
-        DisplayList[] displayLists = new DisplayList[newSize];
+        TextDisplayList[] displayLists = new TextDisplayList[newSize];
         System.arraycopy(mTextDisplayLists, 0, displayLists, 0, length);
         mTextDisplayLists = displayLists;
         return length;
@@ -1461,7 +1481,7 @@
             while (i < numberOfBlocks) {
                 final int blockIndex = blockIndices[i];
                 if (blockIndex != DynamicLayout.INVALID_BLOCK_INDEX) {
-                    mTextDisplayLists[blockIndex].clear();
+                    mTextDisplayLists[blockIndex].isDirty = true;
                 }
                 if (blockEndLines[i] >= lastLine) break;
                 i++;
@@ -1472,7 +1492,7 @@
     void invalidateTextDisplayList() {
         if (mTextDisplayLists != null) {
             for (int i = 0; i < mTextDisplayLists.length; i++) {
-                if (mTextDisplayLists[i] != null) mTextDisplayLists[i].clear();
+                if (mTextDisplayLists[i] != null) mTextDisplayLists[i].isDirty = true;
             }
         }
     }
@@ -1681,7 +1701,7 @@
 
     private void updateCursorPosition(int cursorIndex, int top, int bottom, float horizontal) {
         if (mCursorDrawable[cursorIndex] == null)
-            mCursorDrawable[cursorIndex] = mTextView.getResources().getDrawable(
+            mCursorDrawable[cursorIndex] = mTextView.getContext().getDrawable(
                     mTextView.mCursorDrawableRes);
 
         if (mTempRect == null) mTempRect = new Rect();
@@ -2321,8 +2341,8 @@
         private final HashMap<SuggestionSpan, Integer> mSpansLengths;
 
         private class CustomPopupWindow extends PopupWindow {
-            public CustomPopupWindow(Context context, int defStyle) {
-                super(context, null, defStyle);
+            public CustomPopupWindow(Context context, int defStyleAttr) {
+                super(context, null, defStyleAttr);
             }
 
             @Override
@@ -2971,7 +2991,7 @@
                 positionY += mContentView.getMeasuredHeight();
 
                 // Assumes insertion and selection handles share the same height
-                final Drawable handle = mTextView.getResources().getDrawable(
+                final Drawable handle = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRes);
                 positionY += handle.getIntrinsicHeight();
             }
@@ -3548,7 +3568,7 @@
 
         private InsertionHandleView getHandle() {
             if (mSelectHandleCenter == null) {
-                mSelectHandleCenter = mTextView.getResources().getDrawable(
+                mSelectHandleCenter = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRes);
             }
             if (mHandle == null) {
@@ -3594,11 +3614,11 @@
 
         private void initDrawables() {
             if (mSelectHandleLeft == null) {
-                mSelectHandleLeft = mTextView.getContext().getResources().getDrawable(
+                mSelectHandleLeft = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleLeftRes);
             }
             if (mSelectHandleRight == null) {
-                mSelectHandleRight = mTextView.getContext().getResources().getDrawable(
+                mSelectHandleRight = mTextView.getContext().getDrawable(
                         mTextView.mTextSelectHandleRightRes);
             }
         }
diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java
index 7b81aa8..70089e0 100644
--- a/core/java/android/widget/ExpandableListView.java
+++ b/core/java/android/widget/ExpandableListView.java
@@ -227,12 +227,16 @@
         this(context, attrs, com.android.internal.R.attr.expandableListViewStyle);
     }
 
-    public ExpandableListView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ExpandableListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a =
-            context.obtainStyledAttributes(attrs,
-                    com.android.internal.R.styleable.ExpandableListView, defStyle, 0);
+    public ExpandableListView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.ExpandableListView, defStyleAttr, defStyleRes);
 
         mGroupIndicator = a.getDrawable(
                 com.android.internal.R.styleable.ExpandableListView_groupIndicator);
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 4379bf6..c0961fd 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -24,11 +24,11 @@
 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.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.os.SystemClock;
 import android.text.TextUtils;
 import android.text.TextUtils.TruncateAt;
 import android.util.IntProperty;
@@ -43,7 +43,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroupOverlay;
 import android.widget.AbsListView.OnScrollListener;
-import com.android.internal.R;
+import android.widget.ImageView.ScaleType;
 
 /**
  * Helper class for AbsListView to draw and control the Fast Scroll thumb
@@ -76,24 +76,6 @@
     /** 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,
-        android.R.attr.fastScrollTrackDrawable,
-        android.R.attr.fastScrollPreviewBackgroundLeft,
-        android.R.attr.fastScrollPreviewBackgroundRight,
-        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;
-    private static final int PREVIEW_BACKGROUND_LEFT = 3;
-    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;
@@ -115,7 +97,7 @@
     private final TextView mSecondaryText;
     private final ImageView mThumbImage;
     private final ImageView mTrackImage;
-    private final ImageView mPreviewImage;
+    private final View mPreviewImage;
 
     /**
      * Preview image resource IDs for left- and right-aligned layouts. See
@@ -127,13 +109,25 @@
      * 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;
+    private int mPreviewPadding;
 
-    /** Whether there is a track image to display. */
-    private final boolean mHasTrackImage;
+    private int mPreviewMinWidth;
+    private int mPreviewMinHeight;
+    private int mThumbMinWidth;
+    private int mThumbMinHeight;
+
+    /** Theme-specified text size. Used only if text appearance is not set. */
+    private float mTextSize;
+
+    /** Theme-specified text color. Used only if text appearance is not set. */
+    private ColorStateList mTextColor;
+
+    private Drawable mThumbDrawable;
+    private Drawable mTrackDrawable;
+    private int mTextAppearance;
 
     /** Total width of decorations. */
-    private final int mWidth;
+    private int mWidth;
 
     /** Set containing decoration transition animations. */
     private AnimatorSet mDecorAnimation;
@@ -180,7 +174,7 @@
     /** Whether the preview image is visible. */
     private boolean mShowingPreview;
 
-    private BaseAdapter mListAdapter;
+    private Adapter mListAdapter;
     private SectionIndexer mSectionIndexer;
 
     /** Whether decorations should be laid out from right to left. */
@@ -208,22 +202,9 @@
     private boolean mMatchDragPosition;
 
     private float mInitialTouchY;
-    private boolean mHasPendingDrag;
+    private long mPendingDrag = -1;
     private int mScaledTouchSlop;
 
-    private final Runnable mDeferStartDrag = new Runnable() {
-        @Override
-        public void run() {
-            if (mList.isAttachedToWindow()) {
-                beginDrag();
-
-                final float pos = getPosFromMotionEvent(mInitialTouchY);
-                scrollTo(pos);
-            }
-
-            mHasPendingDrag = false;
-        }
-    };
     private int mOldItemCount;
     private int mOldChildCount;
 
@@ -247,92 +228,145 @@
         }
     };
 
-    public FastScroller(AbsListView listView) {
+    public FastScroller(AbsListView listView, int styleResId) {
         mList = listView;
-        mOverlay = listView.getOverlay();
         mOldItemCount = listView.getCount();
         mOldChildCount = listView.getChildCount();
 
         final Context context = listView.getContext();
         mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mScrollBarStyle = listView.getScrollBarStyle();
 
-        final Resources res = context.getResources();
-        final TypedArray ta = context.getTheme().obtainStyledAttributes(ATTRS);
+        mScrollCompleted = true;
+        mState = STATE_VISIBLE;
+        mMatchDragPosition =
+                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
 
-        final ImageView trackImage = new ImageView(context);
-        mTrackImage = trackImage;
+        mTrackImage = new ImageView(context);
+        mTrackImage.setScaleType(ScaleType.FIT_XY);
+        mThumbImage = new ImageView(context);
+        mThumbImage.setScaleType(ScaleType.FIT_XY);
+        mPreviewImage = new View(context);
+        mPreviewImage.setAlpha(0f);
 
+        mPrimaryText = createPreviewTextView(context);
+        mSecondaryText = createPreviewTextView(context);
+
+        setStyle(styleResId);
+
+        final ViewGroupOverlay overlay = listView.getOverlay();
+        mOverlay = overlay;
+        overlay.add(mTrackImage);
+        overlay.add(mThumbImage);
+        overlay.add(mPreviewImage);
+        overlay.add(mPrimaryText);
+        overlay.add(mSecondaryText);
+
+        getSectionsFromIndexer();
         updateLongList(mOldChildCount, mOldItemCount);
+        setScrollbarPosition(listView.getVerticalScrollbarPosition());
+        postAutoHide();
+    }
+
+    private void updateAppearance() {
+        final Context context = mList.getContext();
         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;
+        mTrackImage.setImageDrawable(mTrackDrawable);
+        if (mTrackDrawable != null) {
+            width = Math.max(width, mTrackDrawable.getIntrinsicWidth());
         }
 
-        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());
+        mThumbImage.setImageDrawable(mThumbDrawable);
+        mThumbImage.setMinimumWidth(mThumbMinWidth);
+        mThumbImage.setMinimumHeight(mThumbMinHeight);
+        if (mThumbDrawable != null) {
+            width = Math.max(width, mThumbDrawable.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);
+        // Account for minimum thumb width.
+        mWidth = Math.max(width, mThumbMinWidth);
+
+        mPreviewImage.setMinimumWidth(mPreviewMinWidth);
+        mPreviewImage.setMinimumHeight(mPreviewMinHeight);
+
+        if (mTextAppearance != 0) {
+            mPrimaryText.setTextAppearance(context, mTextAppearance);
+            mSecondaryText.setTextAppearance(context, mTextAppearance);
         }
 
-        mWidth = width;
+        if (mTextColor != null) {
+            mPrimaryText.setTextColor(mTextColor);
+            mSecondaryText.setTextColor(mTextColor);
+        }
 
-        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);
+        if (mTextSize > 0) {
+            mPrimaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
+            mSecondaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
+        }
 
-        mPreviewPadding = res.getDimensionPixelSize(R.dimen.fastscroll_overlay_padding);
-
-        final int textMinSize = Math.max(0, previewSize - mPreviewPadding);
-        mPrimaryText = createPreviewTextView(context, ta);
+        final int textMinSize = Math.max(0, mPreviewMinHeight);
         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 setStyle(int resId) {
+        final Context context = mList.getContext();
+        final TypedArray ta = context.obtainStyledAttributes(null,
+                com.android.internal.R.styleable.FastScroll, android.R.attr.fastScrollStyle, resId);
+        final int N = ta.getIndexCount();
+        for (int i = 0; i < N; i++) {
+            final int index = ta.getIndex(i);
+            switch (index) {
+                case com.android.internal.R.styleable.FastScroll_position:
+                    mOverlayPosition = ta.getInt(index, OVERLAY_FLOATING);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_backgroundLeft:
+                    mPreviewResId[PREVIEW_LEFT] = ta.getResourceId(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_backgroundRight:
+                    mPreviewResId[PREVIEW_RIGHT] = ta.getResourceId(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_thumbDrawable:
+                    mThumbDrawable = ta.getDrawable(index);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_trackDrawable:
+                    mTrackDrawable = ta.getDrawable(index);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_textAppearance:
+                    mTextAppearance = ta.getResourceId(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_textColor:
+                    mTextColor = ta.getColorStateList(index);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_textSize:
+                    mTextSize = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_minWidth:
+                    mPreviewMinWidth = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_minHeight:
+                    mPreviewMinHeight = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_thumbMinWidth:
+                    mThumbMinWidth = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_thumbMinHeight:
+                    mThumbMinHeight = ta.getDimensionPixelSize(index, 0);
+                    break;
+                case com.android.internal.R.styleable.FastScroll_padding:
+                    mPreviewPadding = ta.getDimensionPixelSize(index, 0);
+                    break;
+            }
+        }
+
+        updateAppearance();
     }
 
     /**
@@ -353,7 +387,7 @@
         if (mEnabled != enabled) {
             mEnabled = enabled;
 
-            onStateDependencyChanged();
+            onStateDependencyChanged(true);
         }
     }
 
@@ -371,7 +405,7 @@
         if (mAlwaysShow != alwaysShow) {
             mAlwaysShow = alwaysShow;
 
-            onStateDependencyChanged();
+            onStateDependencyChanged(false);
         }
     }
 
@@ -385,13 +419,18 @@
 
     /**
      * Called when one of the variables affecting enabled state changes.
+     *
+     * @param peekIfEnabled whether the thumb should peek, if enabled
      */
-    private void onStateDependencyChanged() {
+    private void onStateDependencyChanged(boolean peekIfEnabled) {
         if (isEnabled()) {
             if (isAlwaysShowEnabled()) {
                 setState(STATE_VISIBLE);
             } else if (mState == STATE_VISIBLE) {
                 postAutoHide();
+            } else if (peekIfEnabled) {
+                setState(STATE_VISIBLE);
+                postAutoHide();
             }
         } else {
             stop();
@@ -470,24 +509,18 @@
         if (mLongList != longList) {
             mLongList = longList;
 
-            onStateDependencyChanged();
+            onStateDependencyChanged(false);
         }
     }
 
     /**
      * Creates a view into which preview text can be placed.
      */
-    private TextView createPreviewTextView(Context context, TypedArray ta) {
+    private TextView createPreviewTextView(Context context) {
         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.getDimensionPixelSize(R.dimen.fastscroll_overlay_text_size);
         final TextView textView = new TextView(context);
         textView.setLayoutParams(params);
-        textView.setTextColor(textColor);
-        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
         textView.setSingleLine(true);
         textView.setEllipsize(TruncateAt.MIDDLE);
         textView.setGravity(Gravity.CENTER);
@@ -611,7 +644,7 @@
         view.measure(widthMeasureSpec, heightMeasureSpec);
 
         // Align to the left or right.
-        final int width = view.getMeasuredWidth();
+        final int width = Math.min(adjMaxWidth, view.getMeasuredWidth());
         final int left;
         final int right;
         if (mLayoutFromRight) {
@@ -872,15 +905,15 @@
                     .getAdapter();
             if (expAdapter instanceof SectionIndexer) {
                 mSectionIndexer = (SectionIndexer) expAdapter;
-                mListAdapter = (BaseAdapter) adapter;
+                mListAdapter = adapter;
                 mSections = mSectionIndexer.getSections();
             }
         } else if (adapter instanceof SectionIndexer) {
-            mListAdapter = (BaseAdapter) adapter;
+            mListAdapter = adapter;
             mSectionIndexer = (SectionIndexer) adapter;
             mSections = mSectionIndexer.getSections();
         } else {
-            mListAdapter = (BaseAdapter) adapter;
+            mListAdapter = adapter;
             mSections = null;
         }
     }
@@ -1028,7 +1061,7 @@
         }
 
         final Rect bounds = mTempBounds;
-        final ImageView preview = mPreviewImage;
+        final View preview = mPreviewImage;
         final TextView showing;
         final TextView target;
         if (mShowingPrimary) {
@@ -1054,10 +1087,10 @@
         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();
+        bounds.left -= preview.getPaddingLeft();
+        bounds.top -= preview.getPaddingTop();
+        bounds.right += preview.getPaddingRight();
+        bounds.bottom += preview.getPaddingBottom();
         final Animator resizePreview = animateBounds(preview, bounds);
         resizePreview.setDuration(DURATION_RESIZE);
 
@@ -1105,8 +1138,8 @@
         final int top = container.top;
         final int bottom = container.bottom;
 
-        final ImageView trackImage = mTrackImage;
-        final ImageView thumbImage = mThumbImage;
+        final View trackImage = mTrackImage;
+        final View thumbImage = mThumbImage;
         final float min = trackImage.getTop();
         final float max = trackImage.getBottom();
         final float offset = min;
@@ -1117,7 +1150,7 @@
         final float previewPos = mOverlayPosition == OVERLAY_AT_THUMB ? thumbMiddle : 0;
 
         // Center the preview on the thumb, constrained to the list bounds.
-        final ImageView previewImage = mPreviewImage;
+        final View previewImage = mPreviewImage;
         final float previewHalfHeight = previewImage.getHeight() / 2f;
         final float minP = top + previewHalfHeight;
         final float maxP = bottom - previewHalfHeight;
@@ -1130,11 +1163,7 @@
     }
 
     private float getPosFromMotionEvent(float y) {
-        final Rect container = mContainerRect;
-        final int top = container.top;
-        final int bottom = container.bottom;
-
-        final ImageView trackImage = mTrackImage;
+        final View trackImage = mTrackImage;
         final float min = trackImage.getTop();
         final float max = trackImage.getBottom();
         final float offset = min;
@@ -1235,8 +1264,7 @@
      * @see #startPendingDrag()
      */
     private void cancelPendingDrag() {
-        mList.removeCallbacks(mDeferStartDrag);
-        mHasPendingDrag = false;
+        mPendingDrag = -1;
     }
 
     /**
@@ -1244,11 +1272,12 @@
      * scrolling, rather than tapping.
      */
     private void startPendingDrag() {
-        mHasPendingDrag = true;
-        mList.postDelayed(mDeferStartDrag, TAP_TIMEOUT);
+        mPendingDrag = SystemClock.uptimeMillis() + TAP_TIMEOUT;
     }
 
     private void beginDrag() {
+        mPendingDrag = -1;
+
         setState(STATE_DRAGGING);
 
         if (mListAdapter == null && mList != null) {
@@ -1288,6 +1317,13 @@
             case MotionEvent.ACTION_MOVE:
                 if (!isPointInside(ev.getX(), ev.getY())) {
                     cancelPendingDrag();
+                } else if (mPendingDrag >= 0 && mPendingDrag <= SystemClock.uptimeMillis()) {
+                    beginDrag();
+
+                    final float pos = getPosFromMotionEvent(mInitialTouchY);
+                    scrollTo(pos);
+
+                    return onTouchEvent(ev);
                 }
                 break;
             case MotionEvent.ACTION_UP:
@@ -1322,7 +1358,7 @@
 
         switch (me.getActionMasked()) {
             case MotionEvent.ACTION_UP: {
-                if (mHasPendingDrag) {
+                if (mPendingDrag >= 0) {
                     // Allow a tap to scroll.
                     beginDrag();
 
@@ -1330,7 +1366,6 @@
                     setThumbPos(pos);
                     scrollTo(pos);
 
-                    cancelPendingDrag();
                     // Will hit the STATE_DRAGGING check below
                 }
 
@@ -1351,20 +1386,9 @@
             } break;
 
             case MotionEvent.ACTION_MOVE: {
-                if (mHasPendingDrag && Math.abs(me.getY() - mInitialTouchY) > mScaledTouchSlop) {
-                    setState(STATE_DRAGGING);
+                if (mPendingDrag >= 0 && Math.abs(me.getY() - mInitialTouchY) > mScaledTouchSlop) {
+                    beginDrag();
 
-                    if (mListAdapter == null && mList != null) {
-                        getSectionsFromIndexer();
-                    }
-
-                    if (mList != null) {
-                        mList.requestDisallowInterceptTouchEvent(true);
-                        mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
-                    }
-
-                    cancelFling();
-                    cancelPendingDrag();
                     // Will hit the STATE_DRAGGING check below
                 }
 
@@ -1401,7 +1425,7 @@
      * @return Whether the coordinate is inside the scroller's activation area.
      */
     private boolean isPointInside(float x, float y) {
-        return isPointInsideX(x) && (mHasTrackImage || isPointInsideY(y));
+        return isPointInsideX(x) && (mTrackDrawable != null || isPointInsideY(y));
     }
 
     private boolean isPointInsideX(float x) {
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index d9d4ad7..b029328 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -97,11 +97,15 @@
         this(context, attrs, 0);
     }
 
-    public FrameLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public FrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.FrameLayout,
-                    defStyle, 0);
+    public FrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.FrameLayout, defStyleAttr, defStyleRes);
 
         mForegroundGravity = a.getInt(
                 com.android.internal.R.styleable.FrameLayout_foregroundGravity, mForegroundGravity);
diff --git a/core/java/android/widget/Gallery.java b/core/java/android/widget/Gallery.java
index 78ba6e0..f7c839f 100644
--- a/core/java/android/widget/Gallery.java
+++ b/core/java/android/widget/Gallery.java
@@ -196,14 +196,18 @@
         this(context, attrs, R.attr.galleryStyle);
     }
 
-    public Gallery(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Gallery(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public Gallery(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         
         mGestureDetector = new GestureDetector(context, this);
         mGestureDetector.setIsLongpressEnabled(true);
-        
-        TypedArray a = context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.Gallery, defStyle, 0);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Gallery, defStyleAttr, defStyleRes);
 
         int index = a.getInt(com.android.internal.R.styleable.Gallery_gravity, -1);
         if (index >= 0) {
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 54cc3f4..8511601 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -35,6 +36,8 @@
 import android.widget.RemoteViews.RemoteView;
 import com.android.internal.R;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -165,6 +168,11 @@
 
     // Public constants
 
+    /** @hide */
+    @IntDef({HORIZONTAL, VERTICAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Orientation {}
+
     /**
      * The horizontal orientation.
      */
@@ -186,6 +194,11 @@
      */
     public static final int UNDEFINED = Integer.MIN_VALUE;
 
+    /** @hide */
+    @IntDef({ALIGN_BOUNDS, ALIGN_MARGINS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AlignmentMode {}
+
     /**
      * This constant is an {@link #setAlignmentMode(int) alignmentMode}.
      * When the {@code alignmentMode} is set to {@link #ALIGN_BOUNDS}, alignment
@@ -262,13 +275,23 @@
 
     // Constructors
 
-    /**
-     * {@inheritDoc}
-     */
-    public GridLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public GridLayout(Context context) {
+        this(context, null);
+    }
+
+    public GridLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public GridLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public GridLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         mDefaultGap = context.getResources().getDimensionPixelOffset(R.dimen.default_gap);
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GridLayout);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.GridLayout, defStyleAttr, defStyleRes);
         try {
             setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
             setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT));
@@ -282,21 +305,6 @@
         }
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    public GridLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public GridLayout(Context context) {
-        //noinspection NullableProblems
-        this(context, null);
-    }
-
     // Implementation
 
     /**
@@ -308,6 +316,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_orientation
      */
+    @Orientation
     public int getOrientation() {
         return mOrientation;
     }
@@ -348,7 +357,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_orientation
      */
-    public void setOrientation(int orientation) {
+    public void setOrientation(@Orientation int orientation) {
         if (this.mOrientation != orientation) {
             this.mOrientation = orientation;
             invalidateStructure();
@@ -479,6 +488,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
+    @AlignmentMode
     public int getAlignmentMode() {
         return mAlignmentMode;
     }
@@ -498,7 +508,7 @@
      *
      * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
-    public void setAlignmentMode(int alignmentMode) {
+    public void setAlignmentMode(@AlignmentMode int alignmentMode) {
         this.mAlignmentMode = alignmentMode;
         requestLayout();
     }
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 15daf83..04b18c1 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -16,26 +16,32 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.os.Trace;
 import android.util.AttributeSet;
+import android.util.MathUtils;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.SoundEffectConstants;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
+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.view.animation.GridLayoutAnimationController;
-import android.widget.AbsListView.LayoutParams;
 import android.widget.RemoteViews.RemoteView;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 
 /**
  * A view that shows items in two-dimensional scrolling grid. The items in the
@@ -53,6 +59,11 @@
  */
 @RemoteView
 public class GridView extends AbsListView {
+    /** @hide */
+    @IntDef({NO_STRETCH, STRETCH_SPACING, STRETCH_COLUMN_WIDTH, STRETCH_SPACING_UNIFORM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StretchMode {}
+
     /**
      * Disables stretching.
      * 
@@ -110,11 +121,15 @@
         this(context, attrs, com.android.internal.R.attr.gridViewStyle);
     }
 
-    public GridView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public GridView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.GridView, defStyle, 0);
+    public GridView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.GridView, defStyleAttr, defStyleRes);
 
         int hSpacing = a.getDimensionPixelOffset(
                 com.android.internal.R.styleable.GridView_horizontalSpacing, 0);
@@ -1014,6 +1029,11 @@
     }
 
     @Override
+    AbsPositionScroller createPositionScroller() {
+        return new GridViewPositionScroller();
+    }
+
+    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         // Sets up mListPadding
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -1202,6 +1222,34 @@
 
             setSelectedPositionInt(mNextSelectedPosition);
 
+            AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
+            View accessibilityFocusLayoutRestoreView = null;
+            int accessibilityFocusPosition = INVALID_POSITION;
+
+            // 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 focusHost = viewRootImpl.getAccessibilityFocusedHost();
+                if (focusHost != null) {
+                    final View focusChild = getAccessibilityFocusedChild(focusHost);
+                    if (focusChild != null) {
+                        if (!dataChanged || focusChild.hasTransientState()
+                                || mAdapterHasStableIds) {
+                            // The views won't be changing, so try to maintain
+                            // focus on the current host and virtual view.
+                            accessibilityFocusLayoutRestoreView = focusHost;
+                            accessibilityFocusLayoutRestoreNode = viewRootImpl
+                                    .getAccessibilityFocusedVirtualView();
+                        }
+
+                        // Try to maintain focus at the same position.
+                        accessibilityFocusPosition = getPositionForView(focusChild);
+                    }
+                }
+            }
+
             // Pull all children into the RecycleBin.
             // These views will be reused if possible
             final int firstPosition = mFirstPosition;
@@ -1216,7 +1264,6 @@
             }
 
             // Clear out old views
-            //removeAllViewsInLayout();
             detachAllViewsFromParent();
             recycleBin.removeSkippedScrap();
 
@@ -1287,6 +1334,35 @@
                 mSelectorRect.setEmpty();
             }
 
+            // Attempt to restore accessibility focus, if necessary.
+            if (viewRootImpl != null) {
+                final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
+                if (newAccessibilityFocusedView == null) {
+                    if (accessibilityFocusLayoutRestoreView != null
+                            && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
+                        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();
+                        }
+                    }
+                }
+            }
+
             mLayoutMode = LAYOUT_NORMAL;
             mDataChanged = false;
             if (mPositionScrollAfterLayout != null) {
@@ -2056,13 +2132,14 @@
      *
      * @attr ref android.R.styleable#GridView_stretchMode
      */
-    public void setStretchMode(int stretchMode) {
+    public void setStretchMode(@StretchMode int stretchMode) {
         if (stretchMode != mStretchMode) {
             mStretchMode = stretchMode;
             requestLayoutIfNecessary();
         }
     }
 
+    @StretchMode
     public int getStretchMode() {
         return mStretchMode;
     }
@@ -2265,7 +2342,9 @@
 
         final int columnsCount = getNumColumns();
         final int rowsCount = getCount() / columnsCount;
-        final CollectionInfo collectionInfo = CollectionInfo.obtain(columnsCount, rowsCount, false);
+        final int selectionMode = getSelectionModeForAccessibility();
+        final CollectionInfo collectionInfo = CollectionInfo.obtain(
+                columnsCount, rowsCount, false, selectionMode);
         info.setCollectionInfo(collectionInfo);
     }
 
@@ -2292,7 +2371,38 @@
 
         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);
+        final boolean isSelected = isItemChecked(position);
+        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
+                column, 1, row, 1, isHeading, isSelected);
         info.setCollectionItemInfo(itemInfo);
     }
+
+    /**
+     * Sub-position scroller that understands the layout of a GridView.
+     */
+    class GridViewPositionScroller extends AbsSubPositionScroller {
+        @Override
+        public int getRowForPosition(int position) {
+            return position / mNumColumns;
+        }
+
+        @Override
+        public int getFirstPositionForRow(int row) {
+            return row * mNumColumns;
+        }
+
+        @Override
+        public int getHeightForRow(int row) {
+            final int firstRowPosition = row * mNumColumns;
+            final int lastRowPosition = Math.min(getCount(), firstRowPosition + mNumColumns);
+            int maxHeight = 0;
+            for (int i = firstRowPosition; i < lastRowPosition; i++) {
+                final int height = getHeightForPosition(i);
+                if (height > maxHeight) {
+                    maxHeight = height;
+                }
+            }
+            return maxHeight;
+        }
+    }
 }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index dab0962..25d4f42 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -146,12 +146,17 @@
         this(context, attrs, com.android.internal.R.attr.horizontalScrollViewStyle);
     }
 
-    public HorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public HorizontalScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public HorizontalScrollView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initScrollView();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                android.R.styleable.HorizontalScrollView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, android.R.styleable.HorizontalScrollView, defStyleAttr, defStyleRes);
 
         setFillViewport(a.getBoolean(android.R.styleable.HorizontalScrollView_fillViewport, false));
 
diff --git a/core/java/android/widget/ImageButton.java b/core/java/android/widget/ImageButton.java
index 379354ca..3a20628 100644
--- a/core/java/android/widget/ImageButton.java
+++ b/core/java/android/widget/ImageButton.java
@@ -17,16 +17,11 @@
 package android.widget;
 
 import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
 import android.util.AttributeSet;
-import android.view.MotionEvent;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
 
-import java.util.Map;
-
 /**
  * <p>
  * Displays a button with an image (instead of text) that can be pressed 
@@ -83,8 +78,12 @@
         this(context, attrs, com.android.internal.R.attr.imageButtonStyle);
     }
 
-    public ImageButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ImageButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         setFocusable(true);
     }
 
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index f05179b..572302a4 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -24,8 +24,10 @@
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.Matrix;
+import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Xfermode;
 import android.graphics.drawable.BitmapDrawable;
@@ -119,12 +121,17 @@
         this(context, attrs, 0);
     }
 
-    public ImageView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
         initImageView();
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ImageView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ImageView, defStyleAttr, defStyleRes);
 
         Drawable d = a.getDrawable(com.android.internal.R.styleable.ImageView_src);
         if (d != null) {
@@ -357,13 +364,13 @@
     @android.view.RemotableViewMethod
     public void setImageResource(int resId) {
         if (mUri != null || mResource != resId) {
+            final int oldWidth = mDrawableWidth;
+            final int oldHeight = mDrawableHeight;
+
             updateDrawable(null);
             mResource = resId;
             mUri = null;
 
-            final int oldWidth = mDrawableWidth;
-            final int oldHeight = mDrawableHeight;
-
             resolveUri();
 
             if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
@@ -635,7 +642,7 @@
 
         if (mResource != 0) {
             try {
-                d = rsrc.getDrawable(mResource);
+                d = mContext.getDrawable(mResource);
             } catch (Exception e) {
                 Log.w("ImageView", "Unable to find resource: " + mResource, e);
                 // Don't try again.
@@ -648,7 +655,7 @@
                     // Load drawable through Resources, to get the source density information
                     ContentResolver.OpenResourceIdResult r =
                             mContext.getContentResolver().getResourceId(mUri);
-                    d = r.r.getDrawable(r.id);
+                    d = r.r.getDrawable(r.id, mContext.getTheme());
                 } catch (Exception e) {
                     Log.w("ImageView", "Unable to open content: " + mUri, e);
                 }
@@ -1220,6 +1227,37 @@
         }
     }
 
+    @Override
+    public boolean isOpaque() {
+        return super.isOpaque() || mDrawable != null && mXfermode == null
+                && mDrawable.getOpacity() == PixelFormat.OPAQUE
+                && mAlpha * mViewAlphaScale >> 8 == 255
+                && isFilledByImage();
+    }
+
+    private boolean isFilledByImage() {
+        if (mDrawable == null) {
+            return false;
+        }
+
+        final Rect bounds = mDrawable.getBounds();
+        final Matrix matrix = mDrawMatrix;
+        if (matrix == null) {
+            return bounds.left <= 0 && bounds.top <= 0 && bounds.right >= getWidth()
+                    && bounds.bottom >= getHeight();
+        } else if (matrix.rectStaysRect()) {
+            final RectF boundsSrc = mTempSrc;
+            final RectF boundsDst = mTempDst;
+            boundsSrc.set(bounds);
+            matrix.mapRect(boundsDst, boundsSrc);
+            return boundsDst.left <= 0 && boundsDst.top <= 0 && boundsDst.right >= getWidth()
+                    && boundsDst.bottom >= getHeight();
+        } else {
+            // If the matrix doesn't map to a rectangle, assume the worst.
+            return false;
+        }
+    }
+
     @RemotableViewMethod
     @Override
     public void setVisibility(int visibility) {
diff --git a/core/java/android/widget/LegacyTimePickerDelegate.java b/core/java/android/widget/LegacyTimePickerDelegate.java
new file mode 100644
index 0000000..1634d5f
--- /dev/null
+++ b/core/java/android/widget/LegacyTimePickerDelegate.java
@@ -0,0 +1,638 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.content.Context;
+import android.content.res.Configuration;
+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;
+import android.view.inputmethod.InputMethodManager;
+import com.android.internal.R;
+
+import java.text.DateFormatSymbols;
+import java.util.Calendar;
+import java.util.Locale;
+
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES;
+
+/**
+ * A delegate implementing the basic TimePicker
+ */
+class LegacyTimePickerDelegate extends TimePicker.AbstractTimePickerDelegate {
+
+    private static final boolean DEFAULT_ENABLED_STATE = true;
+
+    private static final int HOURS_IN_HALF_DAY = 12;
+
+    // state
+    private boolean mIs24HourView;
+
+    private boolean mIsAm;
+
+    // ui components
+    private final NumberPicker mHourSpinner;
+
+    private final NumberPicker mMinuteSpinner;
+
+    private final NumberPicker mAmPmSpinner;
+
+    private final EditText mHourSpinnerInput;
+
+    private final EditText mMinuteSpinnerInput;
+
+    private final EditText mAmPmSpinnerInput;
+
+    private final TextView mDivider;
+
+    // Note that the legacy implementation of the TimePicker is
+    // using a button for toggling between AM/PM while the new
+    // version uses a NumberPicker spinner. Therefore the code
+    // accommodates these two cases to be backwards compatible.
+    private final Button mAmPmButton;
+
+    private final String[] mAmPmStrings;
+
+    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+
+    private Calendar mTempCalendar;
+
+    private boolean mHourWithTwoDigit;
+    private char mHourFormat;
+
+    /**
+     * A no-op callback used in the constructor to avoid null checks later in
+     * the code.
+     */
+    private static final TimePicker.OnTimeChangedListener NO_OP_CHANGE_LISTENER =
+            new TimePicker.OnTimeChangedListener() {
+                public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
+                }
+            };
+
+    public LegacyTimePickerDelegate(TimePicker delegator, Context context, AttributeSet attrs,
+                                    int defStyleAttr, int defStyleRes) {
+        super(delegator, context);
+
+        // process style attributes
+        final TypedArray attributesArray = mContext.obtainStyledAttributes(
+                attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes);
+        final int layoutResourceId = attributesArray.getResourceId(
+                R.styleable.TimePicker_legacyLayout, R.layout.time_picker_legacy);
+        attributesArray.recycle();
+
+        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(layoutResourceId, mDelegator, true);
+
+        // hour
+        mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour);
+        mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
+                updateInputState();
+                if (!is24HourView()) {
+                    if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) ||
+                            (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
+                    }
+                }
+                onTimeChanged();
+            }
+        });
+        mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
+        mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+
+        // divider (only for the new widget style)
+        mDivider = (TextView) mDelegator.findViewById(R.id.divider);
+        if (mDivider != null) {
+            setDividerText();
+        }
+
+        // minute
+        mMinuteSpinner = (NumberPicker) mDelegator.findViewById(R.id.minute);
+        mMinuteSpinner.setMinValue(0);
+        mMinuteSpinner.setMaxValue(59);
+        mMinuteSpinner.setOnLongPressUpdateInterval(100);
+        mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
+        mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
+                updateInputState();
+                int minValue = mMinuteSpinner.getMinValue();
+                int maxValue = mMinuteSpinner.getMaxValue();
+                if (oldVal == maxValue && newVal == minValue) {
+                    int newHour = mHourSpinner.getValue() + 1;
+                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
+                    }
+                    mHourSpinner.setValue(newHour);
+                } else if (oldVal == minValue && newVal == maxValue) {
+                    int newHour = mHourSpinner.getValue() - 1;
+                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) {
+                        mIsAm = !mIsAm;
+                        updateAmPmControl();
+                    }
+                    mHourSpinner.setValue(newHour);
+                }
+                onTimeChanged();
+            }
+        });
+        mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
+        mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+
+            /* Get the localized am/pm strings and use them in the spinner */
+        mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
+
+        // am/pm
+        View amPmView = mDelegator.findViewById(R.id.amPm);
+        if (amPmView instanceof Button) {
+            mAmPmSpinner = null;
+            mAmPmSpinnerInput = null;
+            mAmPmButton = (Button) amPmView;
+            mAmPmButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View button) {
+                    button.requestFocus();
+                    mIsAm = !mIsAm;
+                    updateAmPmControl();
+                    onTimeChanged();
+                }
+            });
+        } else {
+            mAmPmButton = null;
+            mAmPmSpinner = (NumberPicker) amPmView;
+            mAmPmSpinner.setMinValue(0);
+            mAmPmSpinner.setMaxValue(1);
+            mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+            mAmPmSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
+                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+                    updateInputState();
+                    picker.requestFocus();
+                    mIsAm = !mIsAm;
+                    updateAmPmControl();
+                    onTimeChanged();
+                }
+            });
+            mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
+            mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
+        }
+
+        if (isAmPmAtStart()) {
+            // Move the am/pm view to the beginning
+            ViewGroup amPmParent = (ViewGroup) delegator.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();
+        updateAmPmControl();
+
+        setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
+
+        // set to current time
+        setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
+        setCurrentMinute(mTempCalendar.get(Calendar.MINUTE));
+
+        if (!isEnabled()) {
+            setEnabled(false);
+        }
+
+        // set the content descriptions
+        setContentDescriptions();
+
+        // If not explicitly specified this view is important for accessibility.
+        if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+            mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+        }
+    }
+
+    private void getHourFormatData() {
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                (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 String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                "hm" /* skeleton */);
+
+        return bestDateTimePattern.startsWith("a");
+    }
+
+    /**
+     * 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 String skeleton = (mIs24HourView) ? "Hm" : "hm";
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                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 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;
+        }
+        if (!is24HourView()) {
+            // convert [0,23] ordinal to wall clock display
+            if (currentHour >= HOURS_IN_HALF_DAY) {
+                mIsAm = false;
+                if (currentHour > HOURS_IN_HALF_DAY) {
+                    currentHour = currentHour - HOURS_IN_HALF_DAY;
+                }
+            } else {
+                mIsAm = true;
+                if (currentHour == 0) {
+                    currentHour = HOURS_IN_HALF_DAY;
+                }
+            }
+            updateAmPmControl();
+        }
+        mHourSpinner.setValue(currentHour);
+        if (notifyTimeChanged) {
+            onTimeChanged();
+        }
+    }
+
+    @Override
+    public Integer getCurrentHour() {
+        int currentHour = mHourSpinner.getValue();
+        if (is24HourView()) {
+            return currentHour;
+        } else if (mIsAm) {
+            return currentHour % HOURS_IN_HALF_DAY;
+        } else {
+            return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
+        }
+    }
+
+    @Override
+    public void setCurrentMinute(Integer currentMinute) {
+        if (currentMinute == getCurrentMinute()) {
+            return;
+        }
+        mMinuteSpinner.setValue(currentMinute);
+        onTimeChanged();
+    }
+
+    @Override
+    public Integer getCurrentMinute() {
+        return mMinuteSpinner.getValue();
+    }
+
+    @Override
+    public void setIs24HourView(Boolean is24HourView) {
+        if (mIs24HourView == is24HourView) {
+            return;
+        }
+        // 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, false);
+        updateMinuteControl();
+        updateAmPmControl();
+    }
+
+    @Override
+    public boolean is24HourView() {
+        return mIs24HourView;
+    }
+
+    @Override
+    public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener onTimeChangedListener) {
+        mOnTimeChangedListener = onTimeChangedListener;
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        mMinuteSpinner.setEnabled(enabled);
+        if (mDivider != null) {
+            mDivider.setEnabled(enabled);
+        }
+        mHourSpinner.setEnabled(enabled);
+        if (mAmPmSpinner != null) {
+            mAmPmSpinner.setEnabled(enabled);
+        } else {
+            mAmPmButton.setEnabled(enabled);
+        }
+        mIsEnabled = enabled;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    @Override
+    public void setShowDoneButton(boolean showDoneButton) {
+        // Nothing to do
+    }
+
+    @Override
+    public void setDismissCallback(TimePicker.TimePickerDismissCallback callback) {
+        // Nothing to do
+    }
+
+    @Override
+    public int getBaseline() {
+        return mHourSpinner.getBaseline();
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        setCurrentLocale(newConfig.locale);
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState(Parcelable superState) {
+        return new SavedState(superState, getCurrentHour(), getCurrentMinute());
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        setCurrentHour(ss.getHour());
+        setCurrentMinute(ss.getMinute());
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        onPopulateAccessibilityEvent(event);
+        return true;
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        int flags = DateUtils.FORMAT_SHOW_TIME;
+        if (mIs24HourView) {
+            flags |= DateUtils.FORMAT_24HOUR;
+        } else {
+            flags |= DateUtils.FORMAT_12HOUR;
+        }
+        mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour());
+        mTempCalendar.set(Calendar.MINUTE, getCurrentMinute());
+        String selectedDateUtterance = DateUtils.formatDateTime(mContext,
+                mTempCalendar.getTimeInMillis(), flags);
+        event.getText().add(selectedDateUtterance);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        event.setClassName(TimePicker.class.getName());
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        info.setClassName(TimePicker.class.getName());
+    }
+
+    private void updateInputState() {
+        // Make sure that if the user changes the value and the IME is active
+        // for one of the inputs if this widget, the IME is closed. If the user
+        // changed the value via the IME and there is a next input the IME will
+        // be shown, otherwise the user chose another means of changing the
+        // value and having the IME up makes no sense.
+        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
+        if (inputMethodManager != null) {
+            if (inputMethodManager.isActive(mHourSpinnerInput)) {
+                mHourSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) {
+                mMinuteSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+            } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) {
+                mAmPmSpinnerInput.clearFocus();
+                inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0);
+            }
+        }
+    }
+
+    private void updateAmPmControl() {
+        if (is24HourView()) {
+            if (mAmPmSpinner != null) {
+                mAmPmSpinner.setVisibility(View.GONE);
+            } else {
+                mAmPmButton.setVisibility(View.GONE);
+            }
+        } else {
+            int index = mIsAm ? Calendar.AM : Calendar.PM;
+            if (mAmPmSpinner != null) {
+                mAmPmSpinner.setValue(index);
+                mAmPmSpinner.setVisibility(View.VISIBLE);
+            } else {
+                mAmPmButton.setText(mAmPmStrings[index]);
+                mAmPmButton.setVisibility(View.VISIBLE);
+            }
+        }
+        mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+    }
+
+    /**
+     * Sets the current locale.
+     *
+     * @param locale The current locale.
+     */
+    @Override
+    public void setCurrentLocale(Locale locale) {
+        super.setCurrentLocale(locale);
+        mTempCalendar = Calendar.getInstance(locale);
+    }
+
+    private void onTimeChanged() {
+        mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        if (mOnTimeChangedListener != null) {
+            mOnTimeChangedListener.onTimeChanged(mDelegator, getCurrentHour(),
+                    getCurrentMinute());
+        }
+    }
+
+    private void updateHourControl() {
+        if (is24HourView()) {
+            // 'k' means 1-24 hour
+            if (mHourFormat == 'k') {
+                mHourSpinner.setMinValue(1);
+                mHourSpinner.setMaxValue(24);
+            } else {
+                mHourSpinner.setMinValue(0);
+                mHourSpinner.setMaxValue(23);
+            }
+        } else {
+            // '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() {
+        if (is24HourView()) {
+            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
+        } else {
+            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
+        }
+    }
+
+    private void setContentDescriptions() {
+        // Minute
+        trySetContentDescription(mMinuteSpinner, R.id.increment,
+                R.string.time_picker_increment_minute_button);
+        trySetContentDescription(mMinuteSpinner, R.id.decrement,
+                R.string.time_picker_decrement_minute_button);
+        // Hour
+        trySetContentDescription(mHourSpinner, R.id.increment,
+                R.string.time_picker_increment_hour_button);
+        trySetContentDescription(mHourSpinner, R.id.decrement,
+                R.string.time_picker_decrement_hour_button);
+        // AM/PM
+        if (mAmPmSpinner != null) {
+            trySetContentDescription(mAmPmSpinner, R.id.increment,
+                    R.string.time_picker_increment_set_pm_button);
+            trySetContentDescription(mAmPmSpinner, R.id.decrement,
+                    R.string.time_picker_decrement_set_am_button);
+        }
+    }
+
+    private void trySetContentDescription(View root, int viewId, int contDescResId) {
+        View target = root.findViewById(viewId);
+        if (target != null) {
+            target.setContentDescription(mContext.getString(contDescResId));
+        }
+    }
+
+    /**
+     * Used to save / restore state of time picker
+     */
+    private static class SavedState extends View.BaseSavedState {
+
+        private final int mHour;
+
+        private final int mMinute;
+
+        private SavedState(Parcelable superState, int hour, int minute) {
+            super(superState);
+            mHour = hour;
+            mMinute = minute;
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            mHour = in.readInt();
+            mMinute = in.readInt();
+        }
+
+        public int getHour() {
+            return mHour;
+        }
+
+        public int getMinute() {
+            return mMinute;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mHour);
+            dest.writeInt(mMinute);
+        }
+
+        @SuppressWarnings({"unused", "hiding"})
+        public static final Parcelable.Creator<SavedState> CREATOR = new 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/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index ad60a95..82e624d 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.R;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -31,6 +32,9 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.RemoteViews.RemoteView;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 
 /**
  * A Layout that arranges its children in a single column or a single row. The direction of 
@@ -57,9 +61,25 @@
  */
 @RemoteView
 public class LinearLayout extends ViewGroup {
+    /** @hide */
+    @IntDef({HORIZONTAL, VERTICAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface OrientationMode {}
+
     public static final int HORIZONTAL = 0;
     public static final int VERTICAL = 1;
 
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                SHOW_DIVIDER_NONE,
+                SHOW_DIVIDER_BEGINNING,
+                SHOW_DIVIDER_MIDDLE,
+                SHOW_DIVIDER_END
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DividerMode {}
+
     /**
      * Don't show any dividers.
      */
@@ -165,18 +185,22 @@
     private int mDividerPadding;
 
     public LinearLayout(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public LinearLayout(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
     
-    public LinearLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public LinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.LinearLayout, defStyle, 0);
+    public LinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.LinearLayout, defStyleAttr, defStyleRes);
 
         int index = a.getInt(com.android.internal.R.styleable.LinearLayout_orientation, -1);
         if (index >= 0) {
@@ -214,7 +238,7 @@
      *                     {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END},
      *                     or {@link #SHOW_DIVIDER_NONE} to show no dividers.
      */
-    public void setShowDividers(int showDividers) {
+    public void setShowDividers(@DividerMode int showDividers) {
         if (showDividers != mShowDividers) {
             requestLayout();
         }
@@ -230,6 +254,7 @@
      * @return A flag set indicating how dividers should be shown around items.
      * @see #setShowDividers(int)
      */
+    @DividerMode
     public int getShowDividers() {
         return mShowDividers;
     }
@@ -642,6 +667,7 @@
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 
         boolean matchWidth = false;
+        boolean skippedMeasure = false;
 
         final int baselineChildIndex = mBaselineAlignedChildIndex;        
         final boolean useLargestChild = mUseLargestChild;
@@ -676,6 +702,7 @@
                 // there is any leftover space.
                 final int totalLength = mTotalLength;
                 mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
+                skippedMeasure = true;
             } else {
                 int oldHeight = Integer.MIN_VALUE;
 
@@ -802,9 +829,10 @@
         heightSize = heightSizeAndState & MEASURED_SIZE_MASK;
         
         // Either expand children with weight to take up available space or
-        // shrink them if they extend beyond our current bounds
+        // shrink them if they extend beyond our current bounds. If we skipped
+        // measurement on any children, we need to measure them now.
         int delta = heightSize - mTotalLength;
-        if (delta != 0 && totalWeight > 0.0f) {
+        if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
             mTotalLength = 0;
@@ -970,6 +998,7 @@
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
 
         boolean matchHeight = false;
+        boolean skippedMeasure = false;
 
         if (mMaxAscent == null || mMaxDescent == null) {
             mMaxAscent = new int[VERTICAL_GRAVITY_COUNT];
@@ -1032,6 +1061,8 @@
                 if (baselineAligned) {
                     final int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                     child.measure(freeSpec, freeSpec);
+                } else {
+                    skippedMeasure = true;
                 }
             } else {
                 int oldWidth = Integer.MIN_VALUE;
@@ -1180,9 +1211,10 @@
         widthSize = widthSizeAndState & MEASURED_SIZE_MASK;
         
         // Either expand children with weight to take up available space or
-        // shrink them if they extend beyond our current bounds
+        // shrink them if they extend beyond our current bounds. If we skipped
+        // measurement on any children, we need to measure them now.
         int delta = widthSize - mTotalLength;
-        if (delta != 0 && totalWeight > 0.0f) {
+        if (skippedMeasure || delta != 0 && totalWeight > 0.0f) {
             float weightSum = mWeightSum > 0.0f ? mWeightSum : totalWeight;
 
             maxAscent[0] = maxAscent[1] = maxAscent[2] = maxAscent[3] = -1;
@@ -1673,12 +1705,12 @@
     
     /**
      * Should the layout be a column or a row.
-     * @param orientation Pass HORIZONTAL or VERTICAL. Default
-     * value is HORIZONTAL.
+     * @param orientation Pass {@link #HORIZONTAL} or {@link #VERTICAL}. Default
+     * value is {@link #HORIZONTAL}.
      * 
      * @attr ref android.R.styleable#LinearLayout_orientation
      */
-    public void setOrientation(int orientation) {
+    public void setOrientation(@OrientationMode int orientation) {
         if (mOrientation != orientation) {
             mOrientation = orientation;
             requestLayout();
@@ -1690,6 +1722,7 @@
      * 
      * @return either {@link #HORIZONTAL} or {@link #VERTICAL}
      */
+    @OrientationMode
     public int getOrientation() {
         return mOrientation;
     }
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 66fe46f..64953f8 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -33,7 +33,6 @@
 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;
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 78237c3..5de67c8 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -44,6 +44,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
 import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
 import android.widget.RemoteViews.RemoteView;
 
 import java.util.ArrayList;
@@ -142,11 +143,15 @@
         this(context, attrs, com.android.internal.R.attr.listViewStyle);
     }
 
-    public ListView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ListView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ListView, defStyle, 0);
+    public ListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ListView, defStyleAttr, defStyleRes);
 
         CharSequence[] entries = a.getTextArray(
                 com.android.internal.R.styleable.ListView_entries);
@@ -263,6 +268,7 @@
         info.data = data;
         info.isSelectable = isSelectable;
         mHeaderViewInfos.add(info);
+        mAreAllItemsSelectable &= isSelectable;
 
         // Wrap the adapter if it wasn't already wrapped.
         if (mAdapter != null) {
@@ -356,6 +362,7 @@
         info.data = data;
         info.isSelectable = isSelectable;
         mFooterViewInfos.add(info);
+        mAreAllItemsSelectable &= isSelectable;
 
         // Wrap the adapter if it wasn't already wrapped.
         if (mAdapter != null) {
@@ -1562,22 +1569,58 @@
 
             setSelectedPositionInt(mNextSelectedPosition);
 
-            // 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;
+            AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
+            View accessibilityFocusLayoutRestoreView = null;
+            int accessibilityFocusPosition = INVALID_POSITION;
+
+            // 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 focusHost = viewRootImpl.getAccessibilityFocusedHost();
+                if (focusHost != null) {
+                    final View focusChild = getAccessibilityFocusedChild(focusHost);
+                    if (focusChild != null) {
+                        if (!dataChanged || isDirectChildHeaderOrFooter(focusChild)
+                                || focusChild.hasTransientState() || mAdapterHasStableIds) {
+                            // The views won't be changing, so try to maintain
+                            // focus on the current host and virtual view.
+                            accessibilityFocusLayoutRestoreView = focusHost;
+                            accessibilityFocusLayoutRestoreNode = viewRootImpl
+                                    .getAccessibilityFocusedVirtualView();
+                        }
+
+                        // If all else fails, maintain focus at the same
+                        // position.
+                        accessibilityFocusPosition = getPositionForView(focusChild);
+                    }
+                }
             }
 
-            // 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.
+            View focusLayoutRestoreDirectChild = null;
+            View focusLayoutRestoreView = null;
+
+            // 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) {
-                focusedChild.setHasTransientState(true);
+                // TODO: in some cases focusedChild.getParent() == null
+
+                // We can remember the focused view to restore after re-layout
+                // 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();
             }
 
             // Pull all children into the RecycleBin.
@@ -1651,20 +1694,24 @@
             recycleBin.scrapActiveViews();
 
             if (sel != null) {
-                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.
+                // 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, but we still want to
+                        // make sure something else outside of the selected view
+                        // has 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);
@@ -1682,27 +1729,48 @@
                     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 necessary.
+            if (viewRootImpl != null) {
+                final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
+                if (newAccessibilityFocusedView == null) {
+                    if (accessibilityFocusLayoutRestoreView != null
+                            && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
+                        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();
+                        }
                     }
                 }
             }
 
-            if (focusedChild != null) {
-                focusedChild.setHasTransientState(false);
+            // 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();
             }
             
             mLayoutMode = LAYOUT_NORMAL;
@@ -1729,31 +1797,27 @@
     }
 
     /**
-     * @return the direct child that contains accessibility focus, or null if no
-     *         child contains accessibility focus
+     * @param child a direct child of this list.
+     * @return Whether child is a header or footer view.
      */
-    private View getAccessibilityFocusedChild() {
-        final ViewRootImpl viewRootImpl = getViewRootImpl();
-        if (viewRootImpl == null) {
-            return null;
+    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;
+            }
         }
 
-        View focusedView = viewRootImpl.getAccessibilityFocusedHost();
-        if (focusedView == null) {
-            return null;
+        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;
+            }
         }
 
-        ViewParent viewParent = focusedView.getParent();
-        while ((viewParent instanceof View) && (viewParent != this)) {
-            focusedView = (View) viewParent;
-            viewParent = viewParent.getParent();
-        }
-
-        if (!(viewParent instanceof View)) {
-            return null;
-        }
-
-        return focusedView;
+        return false;
     }
 
     /**
@@ -1915,45 +1979,6 @@
     }
 
     /**
-     * Sets the selected item and positions the selection y pixels from the top edge
-     * of the ListView. (If in touch mode, the item will not be selected but it will
-     * still be positioned appropriately.)
-     *
-     * @param position Index (starting at 0) of the data item to be selected.
-     * @param y The distance from the top edge of the ListView (plus padding) that the
-     *        item will be positioned.
-     */
-    public void setSelectionFromTop(int position, int y) {
-        if (mAdapter == null) {
-            return;
-        }
-
-        if (!isInTouchMode()) {
-            position = lookForSelectablePosition(position, true);
-            if (position >= 0) {
-                setNextSelectedPositionInt(position);
-            }
-        } else {
-            mResurrectToPosition = position;
-        }
-
-        if (position >= 0) {
-            mLayoutMode = LAYOUT_SPECIFIC;
-            mSpecificTop = mListPadding.top + y;
-
-            if (mNeedSync) {
-                mSyncPosition = position;
-                mSyncRowId = mAdapter.getItemId(position);
-            }
-
-            if (mPositionScroller != null) {
-                mPositionScroller.stop();
-            }
-            requestLayout();
-        }
-    }
-
-    /**
      * Makes the item at the supplied position selected.
      * 
      * @param position the position of the item to select
@@ -3266,14 +3291,13 @@
                         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))))) {
+                            // Draw dividers between enabled items, headers
+                            // and/or footers when enabled and requested, and
+                            // after the last enabled item.
+                            if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                    && (nextIndex >= headerCount)) && (isLastItem
+                                    || adapter.isEnabled(nextIndex) && (footerDividers || !isFooter
+                                            && (nextIndex < footerLimit)))) {
                                 bounds.top = bottom;
                                 bounds.bottom = bottom + dividerHeight;
                                 drawDivider(canvas, bounds, i);
@@ -3315,14 +3339,13 @@
                         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))))) {
+                            // Draw dividers between enabled items, headers
+                            // and/or footers when enabled and requested, and
+                            // before the first enabled item.
+                            if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                    && (previousIndex >= headerCount)) && (isFirstItem ||
+                                    adapter.isEnabled(previousIndex) && (footerDividers || !isFooter
+                                            && (previousIndex < footerLimit)))) {
                                 bounds.top = top - dividerHeight;
                                 bounds.bottom = top;
                                 // Give the method the child ABOVE the divider,
@@ -3771,6 +3794,79 @@
     }
 
     @Override
+    int getHeightForPosition(int position) {
+        final int height = super.getHeightForPosition(position);
+        if (shouldAdjustHeightForDivider(position)) {
+            return height + mDividerHeight;
+        }
+        return height;
+    }
+
+    private boolean shouldAdjustHeightForDivider(int itemIndex) {
+        final int dividerHeight = mDividerHeight;
+        final Drawable overscrollHeader = mOverScrollHeader;
+        final Drawable overscrollFooter = mOverScrollFooter;
+        final boolean drawOverscrollHeader = overscrollHeader != null;
+        final boolean drawOverscrollFooter = overscrollFooter != null;
+        final boolean drawDividers = dividerHeight > 0 && mDivider != null;
+
+        if (drawDividers) {
+            final boolean fillForMissingDividers = isOpaque() && !super.isOpaque();
+            final int itemCount = mItemCount;
+            final int headerCount = mHeaderViewInfos.size();
+            final int footerLimit = (itemCount - mFooterViewInfos.size());
+            final boolean isHeader = (itemIndex < headerCount);
+            final boolean isFooter = (itemIndex >= footerLimit);
+            final boolean headerDividers = mHeaderDividersEnabled;
+            final boolean footerDividers = mFooterDividersEnabled;
+            if ((headerDividers || !isHeader) && (footerDividers || !isFooter)) {
+                final ListAdapter adapter = mAdapter;
+                if (!mStackFromBottom) {
+                    final boolean isLastItem = (itemIndex == (itemCount - 1));
+                    if (!drawOverscrollFooter || !isLastItem) {
+                        final int nextIndex = itemIndex + 1;
+                        // Draw dividers between enabled items, headers
+                        // and/or footers when enabled and requested, and
+                        // after the last enabled item.
+                        if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                && (nextIndex >= headerCount)) && (isLastItem
+                                || adapter.isEnabled(nextIndex) && (footerDividers || !isFooter
+                                                && (nextIndex < footerLimit)))) {
+                            return true;
+                        } else if (fillForMissingDividers) {
+                            return true;
+                        }
+                    }
+                } else {
+                    final int start = drawOverscrollHeader ? 1 : 0;
+                    final boolean isFirstItem = (itemIndex == start);
+                    if (!isFirstItem) {
+                        final int previousIndex = (itemIndex - 1);
+                        // Draw dividers between enabled items, headers
+                        // and/or footers when enabled and requested, and
+                        // before the first enabled item.
+                        if (adapter.isEnabled(itemIndex) && (headerDividers || !isHeader
+                                && (previousIndex >= headerCount)) && (isFirstItem ||
+                                adapter.isEnabled(previousIndex) && (footerDividers || !isFooter
+                                        && (previousIndex < footerLimit)))) {
+                            return true;
+                        } else if (fillForMissingDividers) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    AbsPositionScroller createPositionScroller() {
+        return new ListViewPositionScroller();
+    }
+
+    @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
         event.setClassName(ListView.class.getName());
@@ -3782,7 +3878,8 @@
         info.setClassName(ListView.class.getName());
 
         final int count = getCount();
-        final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false);
+        final int selectionMode = getSelectionModeForAccessibility();
+        final CollectionInfo collectionInfo = CollectionInfo.obtain(1, count, false, selectionMode);
         info.setCollectionInfo(collectionInfo);
     }
 
@@ -3793,7 +3890,29 @@
 
         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);
+        final boolean isSelected = isItemChecked(position);
+        final CollectionItemInfo itemInfo = CollectionItemInfo.obtain(
+                0, 1, position, 1, isHeading, isSelected);
         info.setCollectionItemInfo(itemInfo);
     }
+
+    /**
+     * Sub-position scroller that understands the layout of a ListView.
+     */
+    class ListViewPositionScroller extends AbsSubPositionScroller {
+        @Override
+        public int getRowForPosition(int position) {
+            return position;
+        }
+
+        @Override
+        public int getFirstPositionForRow(int row) {
+            return row;
+        }
+
+        @Override
+        public int getHeightForRow(int row) {
+            return getHeightForPosition(row);
+        }
+    }
 }
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 9c61fd6..546cc5f 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -442,7 +442,19 @@
 
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        show(sDefaultTimeout);
+        switch (event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+                show(0); // show until hide is called
+                break;
+            case MotionEvent.ACTION_UP:
+                show(sDefaultTimeout); // start timeout
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                hide();
+                break;
+            default:
+                break;
+        }
         return true;
     }
 
diff --git a/core/java/android/widget/MultiAutoCompleteTextView.java b/core/java/android/widget/MultiAutoCompleteTextView.java
index 0b30c84..cbd01b0 100644
--- a/core/java/android/widget/MultiAutoCompleteTextView.java
+++ b/core/java/android/widget/MultiAutoCompleteTextView.java
@@ -67,8 +67,13 @@
         this(context, attrs, com.android.internal.R.attr.autoCompleteTextViewStyle);
     }
 
-    public MultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public MultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public MultiAutoCompleteTextView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     /* package */ void finishInit() { }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 9c6a2e3..00b2c13 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.annotation.Widget;
 import android.content.Context;
 import android.content.res.ColorStateList;
@@ -53,6 +54,8 @@
 import com.android.internal.R;
 import libcore.icu.LocaleData;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -493,6 +496,10 @@
      * Interface to listen for the picker scroll state.
      */
     public interface OnScrollListener {
+        /** @hide */
+        @IntDef({SCROLL_STATE_IDLE, SCROLL_STATE_TOUCH_SCROLL, SCROLL_STATE_FLING})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ScrollState {}
 
         /**
          * The view is not scrolling.
@@ -518,7 +525,7 @@
          *            {@link #SCROLL_STATE_TOUCH_SCROLL} or
          *            {@link #SCROLL_STATE_IDLE}.
          */
-        public void onScrollStateChange(NumberPicker view, int scrollState);
+        public void onScrollStateChange(NumberPicker view, @ScrollState int scrollState);
     }
 
     /**
@@ -559,14 +566,33 @@
      *
      * @param context the application environment.
      * @param attrs a collection of attributes.
-     * @param defStyle The default style to apply to this view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public NumberPicker(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public NumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Create a new number picker
+     *
+     * @param context the application environment.
+     * @param attrs a collection of attributes.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public NumberPicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         // process style attributes
-        TypedArray attributesArray = context.obtainStyledAttributes(
-                attrs, R.styleable.NumberPicker, defStyle, 0);
+        final TypedArray attributesArray = context.obtainStyledAttributes(
+                attrs, R.styleable.NumberPicker, defStyleAttr, defStyleRes);
         final int layoutResId = attributesArray.getResourceId(
                 R.styleable.NumberPicker_internalLayout, DEFAULT_LAYOUT_RESOURCE_ID);
 
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index f218199..7b3dd31 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -70,7 +70,11 @@
      * @hide
      */
     public OverScroller(Context context, Interpolator interpolator, boolean flywheel) {
-        mInterpolator = interpolator;
+        if (interpolator == null) {
+            mInterpolator = new Scroller.ViscousFluidInterpolator();
+        } else {
+            mInterpolator = interpolator;
+        }
         mFlywheel = flywheel;
         mScrollerX = new SplineOverScroller(context);
         mScrollerY = new SplineOverScroller(context);
@@ -112,7 +116,11 @@
     }
 
     void setInterpolator(Interpolator interpolator) {
-        mInterpolator = interpolator;
+        if (interpolator == null) {
+            mInterpolator = new Scroller.ViscousFluidInterpolator();
+        } else {
+            mInterpolator = interpolator;
+        }
     }
 
     /**
@@ -302,14 +310,7 @@
 
                 final int duration = mScrollerX.mDuration;
                 if (elapsedTime < duration) {
-                    float q = (float) (elapsedTime) / duration;
-
-                    if (mInterpolator == null) {
-                        q = Scroller.viscousFluid(q);
-                    } else {
-                        q = mInterpolator.getInterpolation(q);
-                    }
-
+                    final float q = mInterpolator.getInterpolation(elapsedTime / (float) duration);
                     mScrollerX.updateScroll(q);
                     mScrollerY.updateScroll(q);
                 } else {
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index be20d2d..6e71a5c 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -170,8 +170,8 @@
      *
      * <p>The popup does provide a background.</p>
      */
-    public PopupWindow(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, 0);
+    public PopupWindow(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
     
     /**
@@ -183,8 +183,7 @@
         mContext = context;
         mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
 
-        TypedArray a =
-            context.obtainStyledAttributes(
+        final TypedArray a = context.obtainStyledAttributes(
                 attrs, com.android.internal.R.styleable.PopupWindow, defStyleAttr, defStyleRes);
 
         mBackground = a.getDrawable(R.styleable.PopupWindow_popupBackground);
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 6a369a6..f7e81b8 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -242,29 +242,26 @@
         this(context, attrs, com.android.internal.R.attr.progressBarStyle);
     }
 
-    public ProgressBar(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, 0);
+    public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
-    /**
-     * @hide
-     */
-    public ProgressBar(Context context, AttributeSet attrs, int defStyle, int styleRes) {
-        super(context, attrs, defStyle);
+    public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
         mUiThreadId = Thread.currentThread().getId();
         initProgressBar();
 
-        TypedArray a =
-            context.obtainStyledAttributes(attrs, R.styleable.ProgressBar, defStyle, styleRes);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.ProgressBar, defStyleAttr, defStyleRes);
         
         mNoInvalidate = true;
         
         Drawable drawable = a.getDrawable(R.styleable.ProgressBar_progressDrawable);
         if (drawable != null) {
-            drawable = tileify(drawable, false);
             // Calling this method can set mMaxHeight, make sure the corresponding
             // XML attribute for mMaxHeight is read after calling this method
-            setProgressDrawable(drawable);
+            setProgressDrawableTiled(drawable);
         }
 
 
@@ -293,8 +290,7 @@
 
         drawable = a.getDrawable(R.styleable.ProgressBar_indeterminateDrawable);
         if (drawable != null) {
-            drawable = tileifyIndeterminate(drawable);
-            setIndeterminateDrawable(drawable);
+            setIndeterminateDrawableTiled(drawable);
         }
 
         mOnlyIndeterminate = a.getBoolean(
@@ -350,19 +346,24 @@
             return out;
             
         } else if (drawable instanceof BitmapDrawable) {
-            final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap();
+            final BitmapDrawable bitmap = (BitmapDrawable) drawable;
+            final Bitmap tileBitmap = bitmap.getBitmap();
             if (mSampleTile == null) {
                 mSampleTile = tileBitmap;
             }
-            
-            final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
 
+            final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape());
             final BitmapShader bitmapShader = new BitmapShader(tileBitmap,
                     Shader.TileMode.REPEAT, Shader.TileMode.CLAMP);
             shapeDrawable.getPaint().setShader(bitmapShader);
 
-            return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT,
-                    ClipDrawable.HORIZONTAL) : shapeDrawable;
+            // Ensure the color filter and tint are propagated.
+            shapeDrawable.setTint(bitmap.getTint());
+            shapeDrawable.setTintMode(bitmap.getTintMode());
+            shapeDrawable.setColorFilter(bitmap.getColorFilter());
+
+            return clip ? new ClipDrawable(
+                    shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL) : shapeDrawable;
         }
         
         return drawable;
@@ -472,11 +473,9 @@
     }
 
     /**
-     * <p>Define the drawable used to draw the progress bar in
-     * indeterminate mode.</p>
+     * Define the drawable used to draw the progress bar in indeterminate mode.
      *
      * @param d the new drawable
-     *
      * @see #getIndeterminateDrawable()
      * @see #setIndeterminate(boolean)
      */
@@ -493,6 +492,25 @@
             postInvalidate();
         }
     }
+
+    /**
+     * Define the tileable drawable used to draw the progress bar in
+     * indeterminate mode.
+     * <p>
+     * If the drawable is a BitmapDrawable or contains BitmapDrawables, a
+     * tiled copy will be generated for display as a progress bar.
+     *
+     * @param d the new drawable
+     * @see #getIndeterminateDrawable()
+     * @see #setIndeterminate(boolean)
+     */
+    public void setIndeterminateDrawableTiled(Drawable d) {
+        if (d != null) {
+            d = tileifyIndeterminate(d);
+        }
+
+        setIndeterminateDrawable(d);
+    }
     
     /**
      * <p>Get the drawable used to draw the progress bar in
@@ -508,11 +526,9 @@
     }
 
     /**
-     * <p>Define the drawable used to draw the progress bar in
-     * progress mode.</p>
+     * Define the drawable used to draw the progress bar in progress mode.
      *
      * @param d the new drawable
-     *
      * @see #getProgressDrawable()
      * @see #setIndeterminate(boolean)
      */
@@ -551,6 +567,25 @@
             doRefreshProgress(R.id.secondaryProgress, mSecondaryProgress, false, false);
         }
     }
+
+    /**
+     * Define the tileable drawable used to draw the progress bar in
+     * progress mode.
+     * <p>
+     * If the drawable is a BitmapDrawable or contains BitmapDrawables, a
+     * tiled copy will be generated for display as a progress bar.
+     *
+     * @param d the new drawable
+     * @see #getProgressDrawable()
+     * @see #setIndeterminate(boolean)
+     */
+    public void setProgressDrawableTiled(Drawable d) {
+        if (d != null) {
+            d = tileify(d, false);
+        }
+
+        setProgressDrawable(d);
+    }
     
     /**
      * @return The drawable currently used to draw the progress bar
diff --git a/core/java/android/widget/QuickContactBadge.java b/core/java/android/widget/QuickContactBadge.java
index fd2f754..74b41c9 100644
--- a/core/java/android/widget/QuickContactBadge.java
+++ b/core/java/android/widget/QuickContactBadge.java
@@ -84,8 +84,13 @@
         this(context, attrs, 0);
     }
 
-    public QuickContactBadge(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public QuickContactBadge(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public QuickContactBadge(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         TypedArray styledAttributes = mContext.obtainStyledAttributes(R.styleable.Theme);
         mOverlay = styledAttributes.getDrawable(
@@ -150,7 +155,7 @@
      */
     public void setImageToDefault() {
         if (mDefaultAvatar == null) {
-            mDefaultAvatar = getResources().getDrawable(R.drawable.ic_contact_picture);
+            mDefaultAvatar = mContext.getDrawable(R.drawable.ic_contact_picture);
         }
         setImageDrawable(mDefaultAvatar);
     }
diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java
new file mode 100644
index 0000000..1c9ab61
--- /dev/null
+++ b/core/java/android/widget/RadialTimePickerView.java
@@ -0,0 +1,1396 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
+import android.content.Context;
+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.Typeface;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.text.format.DateUtils;
+import android.text.format.Time;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import com.android.internal.R;
+
+import java.text.DateFormatSymbols;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Locale;
+
+/**
+ * View to show a clock circle picker (with one or two picking circles)
+ *
+ * @hide
+ */
+public class RadialTimePickerView extends View implements View.OnTouchListener {
+    private static final String TAG = "ClockView";
+
+    private static final boolean DEBUG = false;
+
+    private static final int DEBUG_COLOR = 0x20FF0000;
+    private static final int DEBUG_TEXT_COLOR = 0x60FF0000;
+    private static final int DEBUG_STROKE_WIDTH = 2;
+
+    private static final int HOURS = 0;
+    private static final int MINUTES = 1;
+    private static final int HOURS_INNER = 2;
+    private static final int AMPM = 3;
+
+    private static final int SELECTOR_CIRCLE = 0;
+    private static final int SELECTOR_DOT = 1;
+    private static final int SELECTOR_LINE = 2;
+
+    private static final int AM = 0;
+    private static final int PM = 1;
+
+    // Opaque alpha level
+    private static final int ALPHA_OPAQUE = 255;
+
+    // Transparent alpha level
+    private static final int ALPHA_TRANSPARENT = 0;
+
+    // Alpha level of color for selector.
+    private static final int ALPHA_SELECTOR = 51;
+
+    // Alpha level of color for selected circle.
+    private static final int ALPHA_AMPM_SELECTED = ALPHA_SELECTOR;
+
+    // Alpha level of color for pressed circle.
+    private static final int ALPHA_AMPM_PRESSED = 175;
+
+    private static final float COSINE_30_DEGREES = ((float) Math.sqrt(3)) * 0.5f;
+    private static final float SINE_30_DEGREES = 0.5f;
+
+    private static final int DEGREES_FOR_ONE_HOUR = 30;
+    private static final int DEGREES_FOR_ONE_MINUTE = 6;
+
+    private static final int[] HOURS_NUMBERS = {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+    private static final int[] HOURS_NUMBERS_24 = {0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
+    private static final int[] MINUTES_NUMBERS = {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55};
+
+    private static final int CENTER_RADIUS = 2;
+
+    private static int[] sSnapPrefer30sMap = new int[361];
+
+    private final String[] mHours12Texts = new String[12];
+    private final String[] mOuterHours24Texts = new String[12];
+    private final String[] mInnerHours24Texts = new String[12];
+    private final String[] mMinutesTexts = new String[12];
+
+    private final String[] mAmPmText = new String[2];
+
+    private final Paint[] mPaint = new Paint[2];
+    private final Paint mPaintCenter = new Paint();
+    private final Paint[][] mPaintSelector = new Paint[2][3];
+    private final Paint mPaintAmPmText = new Paint();
+    private final Paint[] mPaintAmPmCircle = new Paint[2];
+
+    private final Paint mPaintBackground = new Paint();
+    private final Paint mPaintDisabled = new Paint();
+    private final Paint mPaintDebug = new Paint();
+
+    private Typeface mTypeface;
+
+    private boolean mIs24HourMode;
+    private boolean mShowHours;
+    private boolean mIsOnInnerCircle;
+
+    private int mXCenter;
+    private int mYCenter;
+
+    private float[] mCircleRadius = new float[3];
+
+    private int mMinHypotenuseForInnerNumber;
+    private int mMaxHypotenuseForOuterNumber;
+    private int mHalfwayHypotenusePoint;
+
+    private float[] mTextSize = new float[2];
+    private float mInnerTextSize;
+
+    private float[][] mTextGridHeights = new float[2][7];
+    private float[][] mTextGridWidths = new float[2][7];
+
+    private float[] mInnerTextGridHeights = new float[7];
+    private float[] mInnerTextGridWidths = new float[7];
+
+    private String[] mOuterTextHours;
+    private String[] mInnerTextHours;
+    private String[] mOuterTextMinutes;
+
+    private float[] mCircleRadiusMultiplier = new float[2];
+    private float[] mNumbersRadiusMultiplier = new float[3];
+
+    private float[] mTextSizeMultiplier = new float[3];
+
+    private float[] mAnimationRadiusMultiplier = new float[3];
+
+    private float mTransitionMidRadiusMultiplier;
+    private float mTransitionEndRadiusMultiplier;
+
+    private AnimatorSet mTransition;
+    private InvalidateUpdateListener mInvalidateUpdateListener = new InvalidateUpdateListener();
+
+    private int[] mLineLength = new int[3];
+    private int[] mSelectionRadius = new int[3];
+    private float mSelectionRadiusMultiplier;
+    private int[] mSelectionDegrees = new int[3];
+
+    private int mAmPmCircleRadius;
+    private float mAmPmYCenter;
+
+    private float mAmPmCircleRadiusMultiplier;
+    private int mAmPmTextColor;
+
+    private float mLeftIndicatorXCenter;
+    private float mRightIndicatorXCenter;
+
+    private int mAmPmUnselectedColor;
+    private int mAmPmSelectedColor;
+
+    private int mAmOrPm;
+    private int mAmOrPmPressed;
+
+    private RectF mRectF = new RectF();
+    private boolean mInputEnabled = true;
+    private OnValueSelectedListener mListener;
+
+    private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<Animator>();
+    private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<Animator>();
+
+    public interface OnValueSelectedListener {
+        void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance);
+    }
+
+    static {
+        // Prepare mapping to snap touchable degrees to selectable degrees.
+        preparePrefer30sMap();
+    }
+
+    /**
+     * Split up the 360 degrees of the circle among the 60 selectable values. Assigns a larger
+     * selectable area to each of the 12 visible values, such that the ratio of space apportioned
+     * to a visible value : space apportioned to a non-visible value will be 14 : 4.
+     * E.g. the output of 30 degrees should have a higher range of input associated with it than
+     * the output of 24 degrees, because 30 degrees corresponds to a visible number on the clock
+     * circle (5 on the minutes, 1 or 13 on the hours).
+     */
+    private static void preparePrefer30sMap() {
+        // We'll split up the visible output and the non-visible output such that each visible
+        // output will correspond to a range of 14 associated input degrees, and each non-visible
+        // output will correspond to a range of 4 associate input degrees, so visible numbers
+        // are more than 3 times easier to get than non-visible numbers:
+        // {354-359,0-7}:0, {8-11}:6, {12-15}:12, {16-19}:18, {20-23}:24, {24-37}:30, etc.
+        //
+        // If an output of 30 degrees should correspond to a range of 14 associated degrees, then
+        // we'll need any input between 24 - 37 to snap to 30. Working out from there, 20-23 should
+        // snap to 24, while 38-41 should snap to 36. This is somewhat counter-intuitive, that you
+        // can be touching 36 degrees but have the selection snapped to 30 degrees; however, this
+        // inconsistency isn't noticeable at such fine-grained degrees, and it affords us the
+        // ability to aggressively prefer the visible values by a factor of more than 3:1, which
+        // greatly contributes to the selectability of these values.
+
+        // The first output is 0, and each following output will increment by 6 {0, 6, 12, ...}.
+        int snappedOutputDegrees = 0;
+        // Count of how many inputs we've designated to the specified output.
+        int count = 1;
+        // How many input we expect for a specified output. This will be 14 for output divisible
+        // by 30, and 4 for the remaining output. We'll special case the outputs of 0 and 360, so
+        // the caller can decide which they need.
+        int expectedCount = 8;
+        // Iterate through the input.
+        for (int degrees = 0; degrees < 361; degrees++) {
+            // Save the input-output mapping.
+            sSnapPrefer30sMap[degrees] = snappedOutputDegrees;
+            // If this is the last input for the specified output, calculate the next output and
+            // the next expected count.
+            if (count == expectedCount) {
+                snappedOutputDegrees += 6;
+                if (snappedOutputDegrees == 360) {
+                    expectedCount = 7;
+                } else if (snappedOutputDegrees % 30 == 0) {
+                    expectedCount = 14;
+                } else {
+                    expectedCount = 4;
+                }
+                count = 1;
+            } else {
+                count++;
+            }
+        }
+    }
+
+    /**
+     * Returns mapping of any input degrees (0 to 360) to one of 60 selectable output degrees,
+     * where the degrees corresponding to visible numbers (i.e. those divisible by 30) will be
+     * weighted heavier than the degrees corresponding to non-visible numbers.
+     * See {@link #preparePrefer30sMap()} documentation for the rationale and generation of the
+     * mapping.
+     */
+    private static int snapPrefer30s(int degrees) {
+        if (sSnapPrefer30sMap == null) {
+            return -1;
+        }
+        return sSnapPrefer30sMap[degrees];
+    }
+
+    /**
+     * Returns mapping of any input degrees (0 to 360) to one of 12 visible output degrees (all
+     * multiples of 30), where the input will be "snapped" to the closest visible degrees.
+     * @param degrees The input degrees
+     * @param forceHigherOrLower The output may be forced to either the higher or lower step, or may
+     * be allowed to snap to whichever is closer. Use 1 to force strictly higher, -1 to force
+     * strictly lower, and 0 to snap to the closer one.
+     * @return output degrees, will be a multiple of 30
+     */
+    private static int snapOnly30s(int degrees, int forceHigherOrLower) {
+        final int stepSize = DEGREES_FOR_ONE_HOUR;
+        int floor = (degrees / stepSize) * stepSize;
+        final int ceiling = floor + stepSize;
+        if (forceHigherOrLower == 1) {
+            degrees = ceiling;
+        } else if (forceHigherOrLower == -1) {
+            if (degrees == floor) {
+                floor -= stepSize;
+            }
+            degrees = floor;
+        } else {
+            if ((degrees - floor) < (ceiling - degrees)) {
+                degrees = floor;
+            } else {
+                degrees = ceiling;
+            }
+        }
+        return degrees;
+    }
+
+    public RadialTimePickerView(Context context, AttributeSet attrs)  {
+        this(context, attrs, R.attr.timePickerStyle);
+    }
+
+    public RadialTimePickerView(Context context, AttributeSet attrs, int defStyle)  {
+        super(context, attrs);
+
+        // process style attributes
+        final TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TimePicker,
+                defStyle, 0);
+
+        final Resources res = getResources();
+
+        mAmPmUnselectedColor = a.getColor(R.styleable.TimePicker_amPmUnselectedBackgroundColor,
+                res.getColor(
+                        R.color.timepicker_default_ampm_unselected_background_color_holo_light));
+
+        mAmPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor,
+                res.getColor(R.color.timepicker_default_ampm_selected_background_color_holo_light));
+
+        mAmPmTextColor = a.getColor(R.styleable.TimePicker_amPmTextColor,
+                res.getColor(R.color.timepicker_default_text_color_holo_light));
+
+        final int numbersTextColor = a.getColor(R.styleable.TimePicker_numbersTextColor,
+                res.getColor(R.color.timepicker_default_text_color_holo_light));
+
+        mTypeface = Typeface.create("sans-serif", Typeface.NORMAL);
+
+        mPaint[HOURS] = new Paint();
+        mPaint[HOURS].setColor(numbersTextColor);
+        mPaint[HOURS].setAntiAlias(true);
+        mPaint[HOURS].setTextAlign(Paint.Align.CENTER);
+
+        mPaint[MINUTES] = new Paint();
+        mPaint[MINUTES].setColor(numbersTextColor);
+        mPaint[MINUTES].setAntiAlias(true);
+        mPaint[MINUTES].setTextAlign(Paint.Align.CENTER);
+
+        mPaintCenter.setColor(numbersTextColor);
+        mPaintCenter.setAntiAlias(true);
+        mPaintCenter.setTextAlign(Paint.Align.CENTER);
+
+        mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint();
+        mPaintSelector[HOURS][SELECTOR_CIRCLE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true);
+
+        mPaintSelector[HOURS][SELECTOR_DOT] = new Paint();
+        mPaintSelector[HOURS][SELECTOR_DOT].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true);
+
+        mPaintSelector[HOURS][SELECTOR_LINE] = new Paint();
+        mPaintSelector[HOURS][SELECTOR_LINE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true);
+        mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2);
+
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint();
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true);
+
+        mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint();
+        mPaintSelector[MINUTES][SELECTOR_DOT].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true);
+
+        mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint();
+        mPaintSelector[MINUTES][SELECTOR_LINE].setColor(
+                a.getColor(R.styleable.TimePicker_numbersSelectorColor, R.color.holo_blue_light));
+        mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true);
+        mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2);
+
+        mPaintAmPmText.setColor(mAmPmTextColor);
+        mPaintAmPmText.setTypeface(mTypeface);
+        mPaintAmPmText.setAntiAlias(true);
+        mPaintAmPmText.setTextAlign(Paint.Align.CENTER);
+
+        mPaintAmPmCircle[AM] = new Paint();
+        mPaintAmPmCircle[AM].setAntiAlias(true);
+        mPaintAmPmCircle[PM] = new Paint();
+        mPaintAmPmCircle[PM].setAntiAlias(true);
+
+        mPaintBackground.setColor(
+                a.getColor(R.styleable.TimePicker_numbersBackgroundColor, Color.WHITE));
+        mPaintBackground.setAntiAlias(true);
+
+        final int disabledColor = a.getColor(R.styleable.TimePicker_disabledColor,
+                res.getColor(R.color.timepicker_default_disabled_color_holo_light));
+        mPaintDisabled.setColor(disabledColor);
+        mPaintDisabled.setAntiAlias(true);
+
+        if (DEBUG) {
+            mPaintDebug.setColor(DEBUG_COLOR);
+            mPaintDebug.setAntiAlias(true);
+            mPaintDebug.setStrokeWidth(DEBUG_STROKE_WIDTH);
+            mPaintDebug.setStyle(Paint.Style.STROKE);
+            mPaintDebug.setTextAlign(Paint.Align.CENTER);
+        }
+
+        mShowHours = true;
+        mIs24HourMode = false;
+        mAmOrPm = AM;
+        mAmOrPmPressed = -1;
+
+        initHoursAndMinutesText();
+        initData();
+
+        mTransitionMidRadiusMultiplier =  Float.parseFloat(
+                res.getString(R.string.timepicker_transition_mid_radius_multiplier));
+        mTransitionEndRadiusMultiplier = Float.parseFloat(
+                res.getString(R.string.timepicker_transition_end_radius_multiplier));
+
+        mTextGridHeights[HOURS] = new float[7];
+        mTextGridHeights[MINUTES] = new float[7];
+
+        mSelectionRadiusMultiplier = Float.parseFloat(
+                res.getString(R.string.timepicker_selection_radius_multiplier));
+
+        setOnTouchListener(this);
+
+        // Initial values
+        final Calendar calendar = Calendar.getInstance(Locale.getDefault());
+        final int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
+        final int currentMinute = calendar.get(Calendar.MINUTE);
+
+        setCurrentHour(currentHour);
+        setCurrentMinute(currentMinute);
+
+        setHapticFeedbackEnabled(true);
+    }
+
+    /**
+     * Measure the view to end up as a square, based on the minimum of the height and width.
+     */
+    @Override
+    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
+        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
+        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        int minDimension = Math.min(measuredWidth, measuredHeight);
+
+        super.onMeasure(MeasureSpec.makeMeasureSpec(minDimension, widthMode),
+                MeasureSpec.makeMeasureSpec(minDimension, heightMode));
+    }
+
+    public void initialize(int hour, int minute, boolean is24HourMode) {
+        mIs24HourMode = is24HourMode;
+        setCurrentHour(hour);
+        setCurrentMinute(minute);
+    }
+
+    public void setCurrentItemShowing(int item, boolean animate) {
+        switch (item){
+            case HOURS:
+                showHours(animate);
+                break;
+            case MINUTES:
+                showMinutes(animate);
+                break;
+            default:
+                Log.e(TAG, "ClockView does not support showing item " + item);
+        }
+    }
+
+    public int getCurrentItemShowing() {
+        return mShowHours ? HOURS : MINUTES;
+    }
+
+    public void setOnValueSelectedListener(OnValueSelectedListener listener) {
+        mListener = listener;
+    }
+
+    public void setCurrentHour(int hour) {
+        final int degrees = (hour % 12) * DEGREES_FOR_ONE_HOUR;
+        mSelectionDegrees[HOURS] = degrees;
+        mSelectionDegrees[HOURS_INNER] = degrees;
+        mAmOrPm = ((hour % 24) < 12) ? AM : PM;
+        if (mIs24HourMode) {
+            mIsOnInnerCircle = (mAmOrPm == AM);
+        } else {
+            mIsOnInnerCircle = false;
+        }
+        initData();
+        updateLayoutData();
+        invalidate();
+    }
+
+    // Return hours in 0-23 range
+    public int getCurrentHour() {
+        int hours =
+                mSelectionDegrees[mIsOnInnerCircle ? HOURS_INNER : HOURS] / DEGREES_FOR_ONE_HOUR;
+        if (mIs24HourMode) {
+            if (mIsOnInnerCircle) {
+                hours = hours % 12;
+            } else {
+                if (hours != 0) {
+                    hours += 12;
+                }
+            }
+        } else {
+            hours = hours % 12;
+            if (hours == 0) {
+                if (mAmOrPm == PM) {
+                    hours = 12;
+                }
+            } else {
+                if (mAmOrPm == PM) {
+                    hours += 12;
+                }
+            }
+        }
+        return hours;
+    }
+
+    public void setCurrentMinute(int minute) {
+        mSelectionDegrees[MINUTES] = (minute % 60) * DEGREES_FOR_ONE_MINUTE;
+        invalidate();
+    }
+
+    // Returns minutes in 0-59 range
+    public int getCurrentMinute() {
+        return (mSelectionDegrees[MINUTES] / DEGREES_FOR_ONE_MINUTE);
+    }
+
+    public void setAmOrPm(int val) {
+        mAmOrPm = (val % 2);
+        invalidate();
+    }
+
+    public int getAmOrPm() {
+        return mAmOrPm;
+    }
+
+    public void swapAmPm() {
+        mAmOrPm = (mAmOrPm == AM) ? PM : AM;
+        invalidate();
+    }
+
+    public void showHours(boolean animate) {
+        if (mShowHours) return;
+        mShowHours = true;
+        if (animate) {
+            startMinutesToHoursAnimation();
+        }
+        initData();
+        updateLayoutData();
+        invalidate();
+    }
+
+    public void showMinutes(boolean animate) {
+        if (!mShowHours) return;
+        mShowHours = false;
+        if (animate) {
+            startHoursToMinutesAnimation();
+        }
+        initData();
+        updateLayoutData();
+        invalidate();
+    }
+
+    private void initHoursAndMinutesText() {
+        // Initialize the hours and minutes numbers.
+        for (int i = 0; i < 12; i++) {
+            mHours12Texts[i] = String.format("%d", HOURS_NUMBERS[i]);
+            mOuterHours24Texts[i] = String.format("%02d", HOURS_NUMBERS_24[i]);
+            mInnerHours24Texts[i] = String.format("%d", HOURS_NUMBERS[i]);
+            mMinutesTexts[i] = String.format("%02d", MINUTES_NUMBERS[i]);
+        }
+
+        String[] amPmTexts = new DateFormatSymbols().getAmPmStrings();
+        mAmPmText[AM] = amPmTexts[0];
+        mAmPmText[PM] = amPmTexts[1];
+    }
+
+    private void initData() {
+        if (mIs24HourMode) {
+            mOuterTextHours = mOuterHours24Texts;
+            mInnerTextHours = mInnerHours24Texts;
+        } else {
+            mOuterTextHours = mHours12Texts;
+            mInnerTextHours = null;
+        }
+
+        mOuterTextMinutes = mMinutesTexts;
+
+        final Resources res = getResources();
+
+        if (mShowHours) {
+            if (mIs24HourMode) {
+                mCircleRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_circle_radius_multiplier_24HourMode));
+                mNumbersRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_numbers_radius_multiplier_outer));
+                mTextSizeMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_text_size_multiplier_outer));
+
+                mNumbersRadiusMultiplier[HOURS_INNER] = Float.parseFloat(
+                        res.getString(R.string.timepicker_numbers_radius_multiplier_inner));
+                mTextSizeMultiplier[HOURS_INNER] = Float.parseFloat(
+                        res.getString(R.string.timepicker_text_size_multiplier_inner));
+            } else {
+                mCircleRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_circle_radius_multiplier));
+                mNumbersRadiusMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_numbers_radius_multiplier_normal));
+                mTextSizeMultiplier[HOURS] = Float.parseFloat(
+                        res.getString(R.string.timepicker_text_size_multiplier_normal));
+            }
+        } else {
+            mCircleRadiusMultiplier[MINUTES] = Float.parseFloat(
+                    res.getString(R.string.timepicker_circle_radius_multiplier));
+            mNumbersRadiusMultiplier[MINUTES] = Float.parseFloat(
+                    res.getString(R.string.timepicker_numbers_radius_multiplier_normal));
+            mTextSizeMultiplier[MINUTES] = Float.parseFloat(
+                    res.getString(R.string.timepicker_text_size_multiplier_normal));
+        }
+
+        mAnimationRadiusMultiplier[HOURS] = 1;
+        mAnimationRadiusMultiplier[HOURS_INNER] = 1;
+        mAnimationRadiusMultiplier[MINUTES] = 1;
+
+        mAmPmCircleRadiusMultiplier = Float.parseFloat(
+                res.getString(R.string.timepicker_ampm_circle_radius_multiplier));
+
+        mPaint[HOURS].setAlpha(mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
+        mPaint[MINUTES].setAlpha(mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
+
+        mPaintSelector[HOURS][SELECTOR_CIRCLE].setAlpha(
+                mShowHours ?ALPHA_SELECTOR : ALPHA_TRANSPARENT);
+        mPaintSelector[HOURS][SELECTOR_DOT].setAlpha(
+                mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
+        mPaintSelector[HOURS][SELECTOR_LINE].setAlpha(
+                mShowHours ? ALPHA_SELECTOR : ALPHA_TRANSPARENT);
+
+        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAlpha(
+                mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
+        mPaintSelector[MINUTES][SELECTOR_DOT].setAlpha(
+                mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
+        mPaintSelector[MINUTES][SELECTOR_LINE].setAlpha(
+                mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        updateLayoutData();
+    }
+
+    private void updateLayoutData() {
+        mXCenter = getWidth() / 2;
+        mYCenter = getHeight() / 2;
+
+        final int min = Math.min(mXCenter, mYCenter);
+
+        mCircleRadius[HOURS] = min * mCircleRadiusMultiplier[HOURS];
+        mCircleRadius[HOURS_INNER] = min * mCircleRadiusMultiplier[HOURS];
+        mCircleRadius[MINUTES] = min * mCircleRadiusMultiplier[MINUTES];
+
+        if (!mIs24HourMode) {
+            // We'll need to draw the AM/PM circles, so the main circle will need to have
+            // a slightly higher center. To keep the entire view centered vertically, we'll
+            // have to push it up by half the radius of the AM/PM circles.
+            int amPmCircleRadius = (int) (mCircleRadius[HOURS] * mAmPmCircleRadiusMultiplier);
+            mYCenter -= amPmCircleRadius / 2;
+        }
+
+        mMinHypotenuseForInnerNumber = (int) (mCircleRadius[HOURS]
+                * mNumbersRadiusMultiplier[HOURS_INNER]) - mSelectionRadius[HOURS];
+        mMaxHypotenuseForOuterNumber = (int) (mCircleRadius[HOURS]
+                * mNumbersRadiusMultiplier[HOURS]) + mSelectionRadius[HOURS];
+        mHalfwayHypotenusePoint = (int) (mCircleRadius[HOURS]
+                * ((mNumbersRadiusMultiplier[HOURS] + mNumbersRadiusMultiplier[HOURS_INNER]) / 2));
+
+        mTextSize[HOURS] = mCircleRadius[HOURS] * mTextSizeMultiplier[HOURS];
+        mTextSize[MINUTES] = mCircleRadius[MINUTES] * mTextSizeMultiplier[MINUTES];
+
+        if (mIs24HourMode) {
+            mInnerTextSize = mCircleRadius[HOURS] * mTextSizeMultiplier[HOURS_INNER];
+        }
+
+        calculateGridSizesHours();
+        calculateGridSizesMinutes();
+
+        mSelectionRadius[HOURS] = (int) (mCircleRadius[HOURS] * mSelectionRadiusMultiplier);
+        mSelectionRadius[HOURS_INNER] = mSelectionRadius[HOURS];
+        mSelectionRadius[MINUTES] = (int) (mCircleRadius[MINUTES] * mSelectionRadiusMultiplier);
+
+        mAmPmCircleRadius = (int) (mCircleRadius[HOURS] * mAmPmCircleRadiusMultiplier);
+        mPaintAmPmText.setTextSize(mAmPmCircleRadius * 3 / 4);
+
+        // Line up the vertical center of the AM/PM circles with the bottom of the main circle.
+        mAmPmYCenter = mYCenter + mCircleRadius[HOURS];
+
+        // Line up the horizontal edges of the AM/PM circles with the horizontal edges
+        // of the main circle
+        mLeftIndicatorXCenter = mXCenter - mCircleRadius[HOURS] + mAmPmCircleRadius;
+        mRightIndicatorXCenter = mXCenter + mCircleRadius[HOURS] - mAmPmCircleRadius;
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        canvas.save();
+
+        calculateGridSizesHours();
+        calculateGridSizesMinutes();
+
+        drawCircleBackground(canvas);
+
+        drawTextElements(canvas, mTextSize[HOURS], mTypeface, mOuterTextHours,
+                mTextGridWidths[HOURS], mTextGridHeights[HOURS], mPaint[HOURS]);
+
+        if (mIs24HourMode && mInnerTextHours != null) {
+            drawTextElements(canvas, mInnerTextSize, mTypeface, mInnerTextHours,
+                    mInnerTextGridWidths, mInnerTextGridHeights, mPaint[HOURS]);
+        }
+
+        drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mOuterTextMinutes,
+                mTextGridWidths[MINUTES], mTextGridHeights[MINUTES], mPaint[MINUTES]);
+
+        drawCenter(canvas);
+        drawSelector(canvas);
+        if (!mIs24HourMode) {
+            drawAmPm(canvas);
+        }
+
+        if(!mInputEnabled) {
+            // Draw outer view rectangle
+            mRectF.set(0, 0, getWidth(), getHeight());
+            canvas.drawRect(mRectF, mPaintDisabled);
+        }
+
+        if (DEBUG) {
+            drawDebug(canvas);
+        }
+
+        canvas.restore();
+    }
+
+    private void drawCircleBackground(Canvas canvas) {
+        canvas.drawCircle(mXCenter, mYCenter, mCircleRadius[HOURS], mPaintBackground);
+    }
+
+    private void drawCenter(Canvas canvas) {
+        canvas.drawCircle(mXCenter, mYCenter, CENTER_RADIUS, mPaintCenter);
+    }
+
+    private void drawSelector(Canvas canvas) {
+        drawSelector(canvas, mIsOnInnerCircle ? HOURS_INNER : HOURS);
+        drawSelector(canvas, MINUTES);
+    }
+
+    private void drawAmPm(Canvas canvas) {
+        final boolean isLayoutRtl = isLayoutRtl();
+
+        int amColor = mAmPmUnselectedColor;
+        int amAlpha = ALPHA_OPAQUE;
+        int pmColor = mAmPmUnselectedColor;
+        int pmAlpha = ALPHA_OPAQUE;
+        if (mAmOrPm == AM) {
+            amColor = mAmPmSelectedColor;
+            amAlpha = ALPHA_AMPM_SELECTED;
+        } else if (mAmOrPm == PM) {
+            pmColor = mAmPmSelectedColor;
+            pmAlpha = ALPHA_AMPM_SELECTED;
+        }
+        if (mAmOrPmPressed == AM) {
+            amColor = mAmPmSelectedColor;
+            amAlpha = ALPHA_AMPM_PRESSED;
+        } else if (mAmOrPmPressed == PM) {
+            pmColor = mAmPmSelectedColor;
+            pmAlpha = ALPHA_AMPM_PRESSED;
+        }
+
+        // Draw the two circles
+        mPaintAmPmCircle[AM].setColor(amColor);
+        mPaintAmPmCircle[AM].setAlpha(amAlpha);
+        canvas.drawCircle(isLayoutRtl ? mRightIndicatorXCenter : mLeftIndicatorXCenter,
+                mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[AM]);
+
+        mPaintAmPmCircle[PM].setColor(pmColor);
+        mPaintAmPmCircle[PM].setAlpha(pmAlpha);
+        canvas.drawCircle(isLayoutRtl ? mLeftIndicatorXCenter : mRightIndicatorXCenter,
+                mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[PM]);
+
+        // Draw the AM/PM texts on top
+        mPaintAmPmText.setColor(mAmPmTextColor);
+        float textYCenter = mAmPmYCenter -
+                (int) (mPaintAmPmText.descent() + mPaintAmPmText.ascent()) / 2;
+
+        canvas.drawText(isLayoutRtl ? mAmPmText[PM] : mAmPmText[AM], mLeftIndicatorXCenter,
+                textYCenter, mPaintAmPmText);
+        canvas.drawText(isLayoutRtl ? mAmPmText[AM] : mAmPmText[PM], mRightIndicatorXCenter,
+                textYCenter, mPaintAmPmText);
+    }
+
+    private void drawSelector(Canvas canvas, int index) {
+        // Calculate the current radius at which to place the selection circle.
+        mLineLength[index] = (int) (mCircleRadius[index]
+                * mNumbersRadiusMultiplier[index] * mAnimationRadiusMultiplier[index]);
+
+        double selectionRadians = Math.toRadians(mSelectionDegrees[index]);
+
+        int pointX = mXCenter + (int) (mLineLength[index] * Math.sin(selectionRadians));
+        int pointY = mYCenter - (int) (mLineLength[index] * Math.cos(selectionRadians));
+
+        // Draw the selection circle
+        canvas.drawCircle(pointX, pointY, mSelectionRadius[index],
+                mPaintSelector[index % 2][SELECTOR_CIRCLE]);
+
+        // Draw the dot if needed
+        if (mSelectionDegrees[index] % 30 != 0) {
+            // We're not on a direct tick
+            canvas.drawCircle(pointX, pointY, (mSelectionRadius[index] * 2 / 7),
+                    mPaintSelector[index % 2][SELECTOR_DOT]);
+        } else {
+            // We're not drawing the dot, so shorten the line to only go as far as the edge of the
+            // selection circle
+            int lineLength = mLineLength[index] - mSelectionRadius[index];
+            pointX = mXCenter + (int) (lineLength * Math.sin(selectionRadians));
+            pointY = mYCenter - (int) (lineLength * Math.cos(selectionRadians));
+        }
+
+        // Draw the line
+        canvas.drawLine(mXCenter, mYCenter, pointX, pointY,
+                mPaintSelector[index % 2][SELECTOR_LINE]);
+    }
+
+    private void drawDebug(Canvas canvas) {
+        // Draw outer numbers circle
+        final float outerRadius = mCircleRadius[HOURS] * mNumbersRadiusMultiplier[HOURS];
+        canvas.drawCircle(mXCenter, mYCenter, outerRadius, mPaintDebug);
+
+        // Draw inner numbers circle
+        final float innerRadius = mCircleRadius[HOURS] * mNumbersRadiusMultiplier[HOURS_INNER];
+        canvas.drawCircle(mXCenter, mYCenter, innerRadius, mPaintDebug);
+
+        // Draw outer background circle
+        canvas.drawCircle(mXCenter, mYCenter, mCircleRadius[HOURS], mPaintDebug);
+
+        // Draw outer rectangle for circles
+        float left = mXCenter - outerRadius;
+        float top = mYCenter - outerRadius;
+        float right = mXCenter + outerRadius;
+        float bottom = mYCenter + outerRadius;
+        mRectF = new RectF(left, top, right, bottom);
+        canvas.drawRect(mRectF, mPaintDebug);
+
+        // Draw outer rectangle for background
+        left = mXCenter - mCircleRadius[HOURS];
+        top = mYCenter - mCircleRadius[HOURS];
+        right = mXCenter + mCircleRadius[HOURS];
+        bottom = mYCenter + mCircleRadius[HOURS];
+        mRectF.set(left, top, right, bottom);
+        canvas.drawRect(mRectF, mPaintDebug);
+
+        // Draw outer view rectangle
+        mRectF.set(0, 0, getWidth(), getHeight());
+        canvas.drawRect(mRectF, mPaintDebug);
+
+        // Draw selected time
+        final String selected = String.format("%02d:%02d", getCurrentHour(), getCurrentMinute());
+
+        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+        TextView tv = new TextView(getContext());
+        tv.setLayoutParams(lp);
+        tv.setText(selected);
+        tv.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+        Paint paint = tv.getPaint();
+        paint.setColor(DEBUG_TEXT_COLOR);
+
+        final int width = tv.getMeasuredWidth();
+
+        float height = paint.descent() - paint.ascent();
+        float x = mXCenter - width / 2;
+        float y = mYCenter + 1.5f * height;
+
+        canvas.drawText(selected.toString(), x, y, paint);
+    }
+
+    private void calculateGridSizesHours() {
+        // Calculate the text positions
+        float numbersRadius = mCircleRadius[HOURS]
+                * mNumbersRadiusMultiplier[HOURS] * mAnimationRadiusMultiplier[HOURS];
+
+        // Calculate the positions for the 12 numbers in the main circle.
+        calculateGridSizes(mPaint[HOURS], numbersRadius, mXCenter, mYCenter,
+                mTextSize[HOURS], mTextGridHeights[HOURS], mTextGridWidths[HOURS]);
+
+        // If we have an inner circle, calculate those positions too.
+        if (mIs24HourMode) {
+            float innerNumbersRadius = mCircleRadius[HOURS_INNER]
+                    * mNumbersRadiusMultiplier[HOURS_INNER]
+                    * mAnimationRadiusMultiplier[HOURS_INNER];
+
+            calculateGridSizes(mPaint[HOURS], innerNumbersRadius, mXCenter, mYCenter,
+                    mInnerTextSize, mInnerTextGridHeights, mInnerTextGridWidths);
+        }
+    }
+
+    private void calculateGridSizesMinutes() {
+        // Calculate the text positions
+        float numbersRadius = mCircleRadius[MINUTES]
+                * mNumbersRadiusMultiplier[MINUTES] * mAnimationRadiusMultiplier[MINUTES];
+
+        // Calculate the positions for the 12 numbers in the main circle.
+        calculateGridSizes(mPaint[MINUTES], numbersRadius, mXCenter, mYCenter,
+                mTextSize[MINUTES], mTextGridHeights[MINUTES], mTextGridWidths[MINUTES]);
+    }
+
+
+    /**
+     * Using the trigonometric Unit Circle, calculate the positions that the text will need to be
+     * drawn at based on the specified circle radius. Place the values in the textGridHeights and
+     * textGridWidths parameters.
+     */
+    private static void calculateGridSizes(Paint paint, float numbersRadius, float xCenter,
+            float yCenter, float textSize, float[] textGridHeights, float[] textGridWidths) {
+        /*
+         * The numbers need to be drawn in a 7x7 grid, representing the points on the Unit Circle.
+         */
+        final float offset1 = numbersRadius;
+        // cos(30) = a / r => r * cos(30)
+        final float offset2 = numbersRadius * COSINE_30_DEGREES;
+        // sin(30) = o / r => r * sin(30)
+        final float offset3 = numbersRadius * SINE_30_DEGREES;
+
+        paint.setTextSize(textSize);
+        // We'll need yTextBase to be slightly lower to account for the text's baseline.
+        yCenter -= (paint.descent() + paint.ascent()) / 2;
+
+        textGridHeights[0] = yCenter - offset1;
+        textGridWidths[0] = xCenter - offset1;
+        textGridHeights[1] = yCenter - offset2;
+        textGridWidths[1] = xCenter - offset2;
+        textGridHeights[2] = yCenter - offset3;
+        textGridWidths[2] = xCenter - offset3;
+        textGridHeights[3] = yCenter;
+        textGridWidths[3] = xCenter;
+        textGridHeights[4] = yCenter + offset3;
+        textGridWidths[4] = xCenter + offset3;
+        textGridHeights[5] = yCenter + offset2;
+        textGridWidths[5] = xCenter + offset2;
+        textGridHeights[6] = yCenter + offset1;
+        textGridWidths[6] = xCenter + offset1;
+    }
+
+    /**
+     * Draw the 12 text values at the positions specified by the textGrid parameters.
+     */
+    private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, String[] texts,
+            float[] textGridWidths, float[] textGridHeights, Paint paint) {
+        paint.setTextSize(textSize);
+        paint.setTypeface(typeface);
+        canvas.drawText(texts[0], textGridWidths[3], textGridHeights[0], paint);
+        canvas.drawText(texts[1], textGridWidths[4], textGridHeights[1], paint);
+        canvas.drawText(texts[2], textGridWidths[5], textGridHeights[2], paint);
+        canvas.drawText(texts[3], textGridWidths[6], textGridHeights[3], paint);
+        canvas.drawText(texts[4], textGridWidths[5], textGridHeights[4], paint);
+        canvas.drawText(texts[5], textGridWidths[4], textGridHeights[5], paint);
+        canvas.drawText(texts[6], textGridWidths[3], textGridHeights[6], paint);
+        canvas.drawText(texts[7], textGridWidths[2], textGridHeights[5], paint);
+        canvas.drawText(texts[8], textGridWidths[1], textGridHeights[4], paint);
+        canvas.drawText(texts[9], textGridWidths[0], textGridHeights[3], paint);
+        canvas.drawText(texts[10], textGridWidths[1], textGridHeights[2], paint);
+        canvas.drawText(texts[11], textGridWidths[2], textGridHeights[1], paint);
+    }
+
+    // Used for animating the hours by changing their radius
+    private void setAnimationRadiusMultiplierHours(float animationRadiusMultiplier) {
+        mAnimationRadiusMultiplier[HOURS] = animationRadiusMultiplier;
+        mAnimationRadiusMultiplier[HOURS_INNER] = animationRadiusMultiplier;
+    }
+
+    // Used for animating the minutes by changing their radius
+    private void setAnimationRadiusMultiplierMinutes(float animationRadiusMultiplier) {
+        mAnimationRadiusMultiplier[MINUTES] = animationRadiusMultiplier;
+    }
+
+    private static ObjectAnimator getRadiusDisappearAnimator(Object target,
+            String radiusPropertyName, InvalidateUpdateListener updateListener,
+            float midRadiusMultiplier, float endRadiusMultiplier) {
+        Keyframe kf0, kf1, kf2;
+        float midwayPoint = 0.2f;
+        int duration = 500;
+
+        kf0 = Keyframe.ofFloat(0f, 1);
+        kf1 = Keyframe.ofFloat(midwayPoint, midRadiusMultiplier);
+        kf2 = Keyframe.ofFloat(1f, endRadiusMultiplier);
+        PropertyValuesHolder radiusDisappear = PropertyValuesHolder.ofKeyframe(
+                radiusPropertyName, kf0, kf1, kf2);
+
+        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
+                target, radiusDisappear).setDuration(duration);
+        animator.addUpdateListener(updateListener);
+        return animator;
+    }
+
+    private static ObjectAnimator getRadiusReappearAnimator(Object target,
+            String radiusPropertyName, InvalidateUpdateListener updateListener,
+            float midRadiusMultiplier, float endRadiusMultiplier) {
+        Keyframe kf0, kf1, kf2, kf3;
+        float midwayPoint = 0.2f;
+        int duration = 500;
+
+        // Set up animator for reappearing.
+        float delayMultiplier = 0.25f;
+        float transitionDurationMultiplier = 1f;
+        float totalDurationMultiplier = transitionDurationMultiplier + delayMultiplier;
+        int totalDuration = (int) (duration * totalDurationMultiplier);
+        float delayPoint = (delayMultiplier * duration) / totalDuration;
+        midwayPoint = 1 - (midwayPoint * (1 - delayPoint));
+
+        kf0 = Keyframe.ofFloat(0f, endRadiusMultiplier);
+        kf1 = Keyframe.ofFloat(delayPoint, endRadiusMultiplier);
+        kf2 = Keyframe.ofFloat(midwayPoint, midRadiusMultiplier);
+        kf3 = Keyframe.ofFloat(1f, 1);
+        PropertyValuesHolder radiusReappear = PropertyValuesHolder.ofKeyframe(
+                radiusPropertyName, kf0, kf1, kf2, kf3);
+
+        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
+                target, radiusReappear).setDuration(totalDuration);
+        animator.addUpdateListener(updateListener);
+        return animator;
+    }
+
+    private static ObjectAnimator getFadeOutAnimator(Object target, int startAlpha, int endAlpha,
+                InvalidateUpdateListener updateListener) {
+        int duration = 500;
+        ObjectAnimator animator = ObjectAnimator.ofInt(target, "alpha", startAlpha, endAlpha);
+        animator.setDuration(duration);
+        animator.addUpdateListener(updateListener);
+
+        return animator;
+    }
+
+    private static ObjectAnimator getFadeInAnimator(Object target, int startAlpha, int endAlpha,
+                InvalidateUpdateListener updateListener) {
+        Keyframe kf0, kf1, kf2;
+        int duration = 500;
+
+        // Set up animator for reappearing.
+        float delayMultiplier = 0.25f;
+        float transitionDurationMultiplier = 1f;
+        float totalDurationMultiplier = transitionDurationMultiplier + delayMultiplier;
+        int totalDuration = (int) (duration * totalDurationMultiplier);
+        float delayPoint = (delayMultiplier * duration) / totalDuration;
+
+        kf0 = Keyframe.ofInt(0f, startAlpha);
+        kf1 = Keyframe.ofInt(delayPoint, startAlpha);
+        kf2 = Keyframe.ofInt(1f, endAlpha);
+        PropertyValuesHolder fadeIn = PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1, kf2);
+
+        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
+                target, fadeIn).setDuration(totalDuration);
+        animator.addUpdateListener(updateListener);
+        return animator;
+    }
+
+    private class InvalidateUpdateListener implements ValueAnimator.AnimatorUpdateListener {
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            RadialTimePickerView.this.invalidate();
+        }
+    }
+
+    private void startHoursToMinutesAnimation() {
+        if (mHoursToMinutesAnims.size() == 0) {
+            mHoursToMinutesAnims.add(getRadiusDisappearAnimator(this,
+                    "animationRadiusMultiplierHours", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaint[HOURS],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_LINE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+
+            mHoursToMinutesAnims.add(getRadiusReappearAnimator(this,
+                    "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaint[MINUTES],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_LINE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+        }
+
+        if (mTransition != null && mTransition.isRunning()) {
+            mTransition.end();
+        }
+        mTransition = new AnimatorSet();
+        mTransition.playTogether(mHoursToMinutesAnims);
+        mTransition.start();
+    }
+
+    private void startMinutesToHoursAnimation() {
+        if (mMinuteToHoursAnims.size() == 0) {
+            mMinuteToHoursAnims.add(getRadiusDisappearAnimator(this,
+                    "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaint[MINUTES],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
+                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_LINE],
+                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
+
+            mMinuteToHoursAnims.add(getRadiusReappearAnimator(this,
+                    "animationRadiusMultiplierHours", mInvalidateUpdateListener,
+                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaint[HOURS],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
+                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
+            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_LINE],
+                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
+        }
+
+        if (mTransition != null && mTransition.isRunning()) {
+            mTransition.end();
+        }
+        mTransition = new AnimatorSet();
+        mTransition.playTogether(mMinuteToHoursAnims);
+        mTransition.start();
+    }
+
+    private int getDegreesFromXY(float x, float y) {
+        final double hypotenuse = Math.sqrt(
+                (y - mYCenter) * (y - mYCenter) + (x - mXCenter) * (x - mXCenter));
+
+        // Basic check if we're outside the range of the disk
+        if (hypotenuse > mCircleRadius[HOURS]) {
+            return -1;
+        }
+        // Check
+        if (mIs24HourMode && mShowHours) {
+            if (hypotenuse >= mMinHypotenuseForInnerNumber
+                    && hypotenuse <= mHalfwayHypotenusePoint) {
+                mIsOnInnerCircle = true;
+            } else if (hypotenuse <= mMaxHypotenuseForOuterNumber
+                    && hypotenuse >= mHalfwayHypotenusePoint) {
+                mIsOnInnerCircle = false;
+            } else {
+                return -1;
+            }
+        } else {
+            final int index =  (mShowHours) ? HOURS : MINUTES;
+            final float length = (mCircleRadius[index] * mNumbersRadiusMultiplier[index]);
+            final int distanceToNumber = (int) Math.abs(hypotenuse - length);
+            final int maxAllowedDistance =
+                    (int) (mCircleRadius[index] * (1 - mNumbersRadiusMultiplier[index]));
+            if (distanceToNumber > maxAllowedDistance) {
+                return -1;
+            }
+        }
+
+        final float opposite = Math.abs(y - mYCenter);
+        double degrees = Math.toDegrees(Math.asin(opposite / hypotenuse));
+
+        // Now we have to translate to the correct quadrant.
+        boolean rightSide = (x > mXCenter);
+        boolean topSide = (y < mYCenter);
+        if (rightSide && topSide) {
+            degrees = 90 - degrees;
+        } else if (rightSide && !topSide) {
+            degrees = 90 + degrees;
+        } else if (!rightSide && !topSide) {
+            degrees = 270 - degrees;
+        } else if (!rightSide && topSide) {
+            degrees = 270 + degrees;
+        }
+        return (int) degrees;
+    }
+
+    private int getIsTouchingAmOrPm(float x, float y) {
+        final boolean isLayoutRtl = isLayoutRtl();
+        int squaredYDistance = (int) ((y - mAmPmYCenter) * (y - mAmPmYCenter));
+
+        int distanceToAmCenter = (int) Math.sqrt(
+                (x - mLeftIndicatorXCenter) * (x - mLeftIndicatorXCenter) + squaredYDistance);
+        if (distanceToAmCenter <= mAmPmCircleRadius) {
+            return (isLayoutRtl ? PM : AM);
+        }
+
+        int distanceToPmCenter = (int) Math.sqrt(
+                (x - mRightIndicatorXCenter) * (x - mRightIndicatorXCenter) + squaredYDistance);
+        if (distanceToPmCenter <= mAmPmCircleRadius) {
+            return (isLayoutRtl ? AM : PM);
+        }
+
+        // Neither was close enough.
+        return -1;
+    }
+
+    @Override
+    public boolean onTouch(View v, MotionEvent event) {
+        if(!mInputEnabled) {
+            return true;
+        }
+
+        final float eventX = event.getX();
+        final float eventY = event.getY();
+
+        int degrees;
+        int snapDegrees;
+        boolean result = false;
+
+        switch(event.getAction()) {
+            case MotionEvent.ACTION_DOWN:
+            case MotionEvent.ACTION_MOVE:
+                mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
+                if (mAmOrPmPressed != -1) {
+                    result = true;
+                } else {
+                    degrees = getDegreesFromXY(eventX, eventY);
+                    if (degrees != -1) {
+                        snapDegrees = (mShowHours ?
+                                snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
+                        if (mShowHours) {
+                            mSelectionDegrees[HOURS] = snapDegrees;
+                            mSelectionDegrees[HOURS_INNER] = snapDegrees;
+                        } else {
+                            mSelectionDegrees[MINUTES] = snapDegrees;
+                        }
+                        performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+                        if (mListener != null) {
+                            if (mShowHours) {
+                                mListener.onValueSelected(HOURS, getCurrentHour(), false);
+                            } else  {
+                                mListener.onValueSelected(MINUTES, getCurrentMinute(), false);
+                            }
+                        }
+                        result = true;
+                    }
+                }
+                invalidate();
+                return result;
+
+            case MotionEvent.ACTION_UP:
+                mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
+                if (mAmOrPmPressed != -1) {
+                    if (mAmOrPm != mAmOrPmPressed) {
+                        swapAmPm();
+                    }
+                    mAmOrPmPressed = -1;
+                    if (mListener != null) {
+                        mListener.onValueSelected(AMPM, getCurrentHour(), true);
+                    }
+                    result = true;
+                } else {
+                    degrees = getDegreesFromXY(eventX, eventY);
+                    if (degrees != -1) {
+                        snapDegrees = (mShowHours ?
+                                snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
+                        if (mShowHours) {
+                            mSelectionDegrees[HOURS] = snapDegrees;
+                            mSelectionDegrees[HOURS_INNER] = snapDegrees;
+                        } else {
+                            mSelectionDegrees[MINUTES] = snapDegrees;
+                        }
+                        if (mListener != null) {
+                            if (mShowHours) {
+                                mListener.onValueSelected(HOURS, getCurrentHour(), true);
+                            } else  {
+                                mListener.onValueSelected(MINUTES, getCurrentMinute(), true);
+                            }
+                        }
+                        result = true;
+                    }
+                }
+                if (result) {
+                    invalidate();
+                }
+                return result;
+
+            default:
+                break;
+        }
+        return false;
+    }
+
+    /**
+     * Necessary for accessibility, to ensure we support "scrolling" forward and backward
+     * in the circle.
+     */
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+    }
+
+    /**
+     * Announce the currently-selected time when launched.
+     */
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
+            // Clear the event's current text so that only the current time will be spoken.
+            event.getText().clear();
+            Time time = new Time();
+            time.hour = getCurrentHour();
+            time.minute = getCurrentMinute();
+            long millis = time.normalize(true);
+            int flags = DateUtils.FORMAT_SHOW_TIME;
+            if (mIs24HourMode) {
+                flags |= DateUtils.FORMAT_24HOUR;
+            }
+            String timeString = DateUtils.formatDateTime(getContext(), millis, flags);
+            event.getText().add(timeString);
+            return true;
+        }
+        return super.dispatchPopulateAccessibilityEvent(event);
+    }
+
+    /**
+     * When scroll forward/backward events are received, jump the time to the higher/lower
+     * discrete, visible value on the circle.
+     */
+    @SuppressLint("NewApi")
+    @Override
+    public boolean performAccessibilityAction(int action, Bundle arguments) {
+        if (super.performAccessibilityAction(action, arguments)) {
+            return true;
+        }
+
+        int changeMultiplier = 0;
+        if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
+            changeMultiplier = 1;
+        } else if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
+            changeMultiplier = -1;
+        }
+        if (changeMultiplier != 0) {
+            int value = 0;
+            int stepSize = 0;
+            if (mShowHours) {
+                stepSize = DEGREES_FOR_ONE_HOUR;
+                value = getCurrentHour() % 12;
+            } else {
+                stepSize = DEGREES_FOR_ONE_MINUTE;
+                value = getCurrentMinute();
+            }
+
+            int degrees = value * stepSize;
+            degrees = snapOnly30s(degrees, changeMultiplier);
+            value = degrees / stepSize;
+            int maxValue = 0;
+            int minValue = 0;
+            if (mShowHours) {
+                if (mIs24HourMode) {
+                    maxValue = 23;
+                } else {
+                    maxValue = 12;
+                    minValue = 1;
+                }
+            } else {
+                maxValue = 55;
+            }
+            if (value > maxValue) {
+                // If we scrolled forward past the highest number, wrap around to the lowest.
+                value = minValue;
+            } else if (value < minValue) {
+                // If we scrolled backward past the lowest number, wrap around to the highest.
+                value = maxValue;
+            }
+            if (mShowHours) {
+                setCurrentHour(value);
+                if (mListener != null) {
+                    mListener.onValueSelected(HOURS, value, false);
+                }
+            } else {
+                setCurrentMinute(value);
+                if (mListener != null) {
+                    mListener.onValueSelected(MINUTES, value, false);
+                }
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    public void setInputEnabled(boolean inputEnabled) {
+        mInputEnabled = inputEnabled;
+        invalidate();
+    }
+}
diff --git a/core/java/android/widget/RadioButton.java b/core/java/android/widget/RadioButton.java
index a0fef7d..afc4830 100644
--- a/core/java/android/widget/RadioButton.java
+++ b/core/java/android/widget/RadioButton.java
@@ -21,8 +21,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
-import com.android.internal.R;
-
 
 /**
  * <p>
@@ -59,8 +57,12 @@
         this(context, attrs, com.android.internal.R.attr.radioButtonStyle);
     }
 
-    public RadioButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public RadioButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public RadioButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     /**
diff --git a/core/java/android/widget/RatingBar.java b/core/java/android/widget/RatingBar.java
index 4d3c56c..82b490e 100644
--- a/core/java/android/widget/RatingBar.java
+++ b/core/java/android/widget/RatingBar.java
@@ -82,11 +82,15 @@
     
     private OnRatingBarChangeListener mOnRatingBarChangeListener;
     
-    public RatingBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RatingBar,
-                defStyle, 0);
+    public RatingBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public RatingBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.RatingBar, defStyleAttr, defStyleRes);
         final int numStars = a.getInt(R.styleable.RatingBar_numStars, mNumStars);
         setIsIndicator(a.getBoolean(R.styleable.RatingBar_isIndicator, !mIsUserSeekable));
         final float rating = a.getFloat(R.styleable.RatingBar_rating, -1);
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index e03e83d..90e80d3 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -228,24 +228,27 @@
     private static final int DEFAULT_WIDTH = 0x00010000;
 
     public RelativeLayout(Context context) {
-        super(context);
-        queryCompatibilityModes(context);
+        this(context, null);
     }
 
     public RelativeLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initFromAttributes(context, attrs);
+        this(context, attrs, 0);
+    }
+
+    public RelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public RelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
         queryCompatibilityModes(context);
     }
 
-    public RelativeLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        initFromAttributes(context, attrs);
-        queryCompatibilityModes(context);
-    }
-
-    private void initFromAttributes(Context context, AttributeSet attrs) {
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RelativeLayout);
+    private void initFromAttributes(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.RelativeLayout, defStyleAttr, defStyleRes);
         mIgnoreGravity = a.getResourceId(R.styleable.RelativeLayout_ignoreGravity, View.NO_ID);
         mGravity = a.getInt(R.styleable.RelativeLayout_gravity, mGravity);
         a.recycle();
@@ -738,19 +741,30 @@
     private int getChildMeasureSpec(int childStart, int childEnd,
             int childSize, int startMargin, int endMargin, int startPadding,
             int endPadding, int mySize) {
-        if (mySize < 0 && !mAllowBrokenMeasureSpecs) {
-            if (childSize >= 0) {
-                return MeasureSpec.makeMeasureSpec(childSize, MeasureSpec.EXACTLY);
-            }
-            // Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement
-            // is code for, "we got an unspecified mode in the RelativeLayout's measurespec."
-            // Carry it forward.
-            return MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        }
-
         int childSpecMode = 0;
         int childSpecSize = 0;
 
+        // Negative values in a mySize/myWidth/myWidth value in RelativeLayout
+        // measurement is code for, "we got an unspecified mode in the
+        // RelativeLayout's measure spec."
+        if (mySize < 0 && !mAllowBrokenMeasureSpecs) {
+            if (childStart >= 0 && childEnd >= 0) {
+                // Constraints fixed both edges, so child has an exact size.
+                childSpecSize = Math.max(0, childEnd - childStart);
+                childSpecMode = MeasureSpec.EXACTLY;
+            } else if (childSize >= 0) {
+                // The child specified an exact size.
+                childSpecSize = childSize;
+                childSpecMode = MeasureSpec.EXACTLY;
+            } else {
+                // Allow the child to be whatever size it wants.
+                childSpecSize = 0;
+                childSpecMode = MeasureSpec.UNSPECIFIED;
+            }
+
+            return MeasureSpec.makeMeasureSpec(childSpecSize, childSpecMode);
+        }
+
         // Figure out start and end bounds.
         int tempStart = childStart;
         int tempEnd = childEnd;
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 3ff0cee..bbe6f9e 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -32,7 +32,6 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
@@ -45,7 +44,6 @@
 
 import com.android.internal.widget.IRemoteViewsAdapterConnection;
 import com.android.internal.widget.IRemoteViewsFactory;
-import com.android.internal.widget.LockPatternUtils;
 
 /**
  * An adapter to a RemoteViewsService which fetches and caches RemoteViews
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 6680393..082d728 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -162,12 +162,16 @@
         this(context, attrs, com.android.internal.R.attr.scrollViewStyle);
     }
 
-    public ScrollView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initScrollView();
 
-        TypedArray a =
-            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ScrollView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ScrollView, defStyleAttr, defStyleRes);
 
         setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false));
 
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 3bfd39d..1a0ce9c 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -61,6 +61,8 @@
  * }</pre>
  */
 public class Scroller  {
+    private final Interpolator mInterpolator;
+
     private int mMode;
 
     private int mStartX;
@@ -81,7 +83,6 @@
     private float mDeltaX;
     private float mDeltaY;
     private boolean mFinished;
-    private Interpolator mInterpolator;
     private boolean mFlywheel;
 
     private float mVelocity;
@@ -142,18 +143,8 @@
             SPLINE_TIME[i] = coef * ((1.0f - y) * P1 + y * P2) + y * y * y;
         }
         SPLINE_POSITION[NB_SAMPLES] = SPLINE_TIME[NB_SAMPLES] = 1.0f;
-
-        // This controls the viscous fluid effect (how much of it)
-        sViscousFluidScale = 8.0f;
-        // must be set to 1.0 (used in viscousFluid())
-        sViscousFluidNormalize = 1.0f;
-        sViscousFluidNormalize = 1.0f / viscousFluid(1.0f);
-
     }
 
-    private static float sViscousFluidScale;
-    private static float sViscousFluidNormalize;
-
     /**
      * Create a Scroller with the default duration and interpolator.
      */
@@ -178,7 +169,11 @@
      */
     public Scroller(Context context, Interpolator interpolator, boolean flywheel) {
         mFinished = true;
-        mInterpolator = interpolator;
+        if (interpolator == null) {
+            mInterpolator = new ViscousFluidInterpolator();
+        } else {
+            mInterpolator = interpolator;
+        }
         mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
         mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
         mFlywheel = flywheel;
@@ -312,13 +307,7 @@
         if (timePassed < mDuration) {
             switch (mMode) {
             case SCROLL_MODE:
-                float x = timePassed * mDurationReciprocal;
-    
-                if (mInterpolator == null)
-                    x = viscousFluid(x); 
-                else
-                    x = mInterpolator.getInterpolation(x);
-    
+                final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
                 mCurrX = mStartX + Math.round(x * mDeltaX);
                 mCurrY = mStartY + Math.round(x * mDeltaY);
                 break;
@@ -499,20 +488,6 @@
         return mFlingFriction * mPhysicalCoeff * Math.exp(DECELERATION_RATE / decelMinusOne * l);
     }
 
-    static float viscousFluid(float x)
-    {
-        x *= sViscousFluidScale;
-        if (x < 1.0f) {
-            x -= (1.0f - (float)Math.exp(-x));
-        } else {
-            float start = 0.36787944117f;   // 1/e == exp(-1)
-            x = 1.0f - (float)Math.exp(1.0f - x);
-            x = start + x * (1.0f - start);
-        }
-        x *= sViscousFluidNormalize;
-        return x;
-    }
-    
     /**
      * Stops the animation. Contrary to {@link #forceFinished(boolean)},
      * aborting the animating cause the scroller to move to the final x and y
@@ -583,4 +558,41 @@
         return !mFinished && Math.signum(xvel) == Math.signum(mFinalX - mStartX) &&
                 Math.signum(yvel) == Math.signum(mFinalY - mStartY);
     }
+
+    static class ViscousFluidInterpolator implements Interpolator {
+        /** Controls the viscous fluid effect (how much of it). */
+        private static final float VISCOUS_FLUID_SCALE = 8.0f;
+
+        private static final float VISCOUS_FLUID_NORMALIZE;
+        private static final float VISCOUS_FLUID_OFFSET;
+
+        static {
+
+            // must be set to 1.0 (used in viscousFluid())
+            VISCOUS_FLUID_NORMALIZE = 1.0f / viscousFluid(1.0f);
+            // account for very small floating-point error
+            VISCOUS_FLUID_OFFSET = 1.0f - VISCOUS_FLUID_NORMALIZE * viscousFluid(1.0f);
+        }
+
+        private static float viscousFluid(float x) {
+            x *= VISCOUS_FLUID_SCALE;
+            if (x < 1.0f) {
+                x -= (1.0f - (float)Math.exp(-x));
+            } else {
+                float start = 0.36787944117f;   // 1/e == exp(-1)
+                x = 1.0f - (float)Math.exp(1.0f - x);
+                x = start + x * (1.0f - start);
+            }
+            return x;
+        }
+
+        @Override
+        public float getInterpolation(float input) {
+            final float interpolated = VISCOUS_FLUID_NORMALIZE * viscousFluid(input);
+            if (input > 0) {
+                return input + VISCOUS_FLUID_OFFSET;
+            }
+            return input;
+        }
+    }
 }
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 0281602..1eedc5d 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -242,7 +242,15 @@
     }
 
     public SearchView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
+    }
+
+    public SearchView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SearchView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         LayoutInflater inflater = (LayoutInflater) context
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -281,7 +289,8 @@
             }
         });
 
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SearchView, 0, 0);
+        TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.SearchView, defStyleAttr, defStyleRes);
         setIconifiedByDefault(a.getBoolean(R.styleable.SearchView_iconifiedByDefault, true));
         int maxWidth = a.getDimensionPixelSize(R.styleable.SearchView_maxWidth, -1);
         if (maxWidth != -1) {
@@ -304,7 +313,7 @@
 
         boolean focusable = true;
 
-        a = context.obtainStyledAttributes(attrs, R.styleable.View, 0, 0);
+        a = context.obtainStyledAttributes(attrs, R.styleable.View, defStyleAttr, defStyleRes);
         focusable = a.getBoolean(R.styleable.View_focusable, focusable);
         a.recycle();
         setFocusable(focusable);
@@ -1050,7 +1059,7 @@
 
         SpannableStringBuilder ssb = new SpannableStringBuilder("   "); // for the icon
         ssb.append(hintText);
-        Drawable searchIcon = getContext().getResources().getDrawable(getSearchIconId());
+        Drawable searchIcon = getContext().getDrawable(getSearchIconId());
         int textSize = (int) (mQueryTextView.getTextSize() * 1.25);
         searchIcon.setBounds(0, 0, textSize, textSize);
         ssb.setSpan(new ImageSpan(searchIcon), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
@@ -1661,8 +1670,14 @@
             mThreshold = getThreshold();
         }
 
-        public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
+        public SearchAutoComplete(Context context, AttributeSet attrs, int defStyleAttrs) {
+            super(context, attrs, defStyleAttrs);
+            mThreshold = getThreshold();
+        }
+
+        public SearchAutoComplete(
+                Context context, AttributeSet attrs, int defStyleAttrs, int defStyleRes) {
+            super(context, attrs, defStyleAttrs, defStyleRes);
             mThreshold = getThreshold();
         }
 
diff --git a/core/java/android/widget/SeekBar.java b/core/java/android/widget/SeekBar.java
index 2737f94..dc7c04c 100644
--- a/core/java/android/widget/SeekBar.java
+++ b/core/java/android/widget/SeekBar.java
@@ -79,8 +79,12 @@
         this(context, attrs, com.android.internal.R.attr.seekBarStyle);
     }
 
-    public SeekBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/android/widget/ShareActionProvider.java b/core/java/android/widget/ShareActionProvider.java
index bdaaa01..64a1574 100644
--- a/core/java/android/widget/ShareActionProvider.java
+++ b/core/java/android/widget/ShareActionProvider.java
@@ -168,7 +168,7 @@
         // Lookup and set the expand action icon.
         TypedValue outTypedValue = new TypedValue();
         mContext.getTheme().resolveAttribute(R.attr.actionModeShareDrawable, outTypedValue, true);
-        Drawable drawable = mContext.getResources().getDrawable(outTypedValue.resourceId);
+        Drawable drawable = mContext.getDrawable(outTypedValue.resourceId);
         activityChooserView.setExpandActivityOverflowButtonDrawable(drawable);
         activityChooserView.setProvider(this);
 
diff --git a/core/java/android/widget/SlidingDrawer.java b/core/java/android/widget/SlidingDrawer.java
index 517246b..ec06c02 100644
--- a/core/java/android/widget/SlidingDrawer.java
+++ b/core/java/android/widget/SlidingDrawer.java
@@ -192,11 +192,32 @@
      *
      * @param context The application's environment.
      * @param attrs The attributes defined in XML.
-     * @param defStyle The style to apply to this widget.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public SlidingDrawer(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlidingDrawer, defStyle, 0);
+    public SlidingDrawer(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * Creates a new SlidingDrawer from a specified set of attributes defined in XML.
+     *
+     * @param context The application's environment.
+     * @param attrs The attributes defined in XML.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public SlidingDrawer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.SlidingDrawer, defStyleAttr, defStyleRes);
 
         int orientation = a.getInt(R.styleable.SlidingDrawer_orientation, ORIENTATION_VERTICAL);
         mVertical = orientation == ORIENTATION_VERTICAL;
diff --git a/core/java/android/widget/Space.java b/core/java/android/widget/Space.java
index bb53a77..c4eaeb7 100644
--- a/core/java/android/widget/Space.java
+++ b/core/java/android/widget/Space.java
@@ -20,7 +20,6 @@
 import android.graphics.Canvas;
 import android.util.AttributeSet;
 import android.view.View;
-import android.view.ViewGroup;
 
 /**
  * Space is a lightweight View subclass that may be used to create gaps between components
@@ -30,8 +29,8 @@
     /**
      * {@inheritDoc}
      */
-    public Space(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Space(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         if (getVisibility() == VISIBLE) {
             setVisibility(INVISIBLE);
         }
@@ -40,6 +39,13 @@
     /**
      * {@inheritDoc}
      */
+    public Space(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     public Space(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index b204dfd..1cda631 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -731,10 +731,14 @@
                 }
             }
 
-            if (scheduleOtherSpellCheck) {
+            if (scheduleOtherSpellCheck && wordStart <= end) {
                 // Update range span: start new spell check from last wordStart
                 setRangeSpan(editable, wordStart, end);
             } else {
+                if (DBG && scheduleOtherSpellCheck) {
+                    Log.w(TAG, "Trying to schedule spellcheck for invalid region, from "
+                            + wordStart + " to " + end);
+                }
                 removeRangeSpan(editable);
             }
 
diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java
index 5cbabef..9601d4a 100644
--- a/core/java/android/widget/Spinner.java
+++ b/core/java/android/widget/Spinner.java
@@ -130,18 +130,17 @@
 
     /**
      * Construct a new spinner with the given context's theme, the supplied attribute set,
-     * and default style.
+     * and default style attribute.
      *
      * @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 that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public Spinner(Context context, AttributeSet attrs, int defStyle) {
-        this(context, attrs, defStyle, MODE_THEME);
+    public Spinner(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0, MODE_THEME);
     }
 
     /**
@@ -152,20 +151,44 @@
      * @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 that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      * @param mode Constant describing how the user will select choices from the spinner.
-     * 
+     *
      * @see #MODE_DIALOG
      * @see #MODE_DROPDOWN
      */
-    public Spinner(Context context, AttributeSet attrs, int defStyle, int mode) {
-        super(context, attrs, defStyle);
+    public Spinner(Context context, AttributeSet attrs, int defStyleAttr, int mode) {
+        this(context, attrs, defStyleAttr, 0, mode);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Spinner, defStyle, 0);
+    /**
+     * Construct a new spinner with the given context's theme, the supplied attribute set,
+     * and default style. <code>mode</code> may be one of {@link #MODE_DIALOG} or
+     * {@link #MODE_DROPDOWN} and determines how the user will select choices from the spinner.
+     *
+     * @param context The Context the view is running in, through which it can
+     *        access the current theme, resources, etc.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     * @param mode Constant describing how the user will select choices from the spinner.
+     *
+     * @see #MODE_DIALOG
+     * @see #MODE_DROPDOWN
+     */
+    public Spinner(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Spinner, defStyleAttr, defStyleRes);
 
         if (mode == MODE_THEME) {
             mode = a.getInt(com.android.internal.R.styleable.Spinner_spinnerMode, MODE_DIALOG);
@@ -178,7 +201,7 @@
         }
 
         case MODE_DROPDOWN: {
-            final DropdownPopup popup = new DropdownPopup(context, attrs, defStyle);
+            final DropdownPopup popup = new DropdownPopup(context, attrs, defStyleAttr, defStyleRes);
 
             mDropDownWidth = a.getLayoutDimension(
                     com.android.internal.R.styleable.Spinner_dropDownWidth,
@@ -258,7 +281,7 @@
      * @attr ref android.R.styleable#Spinner_popupBackground
      */
     public void setPopupBackgroundResource(int resId) {
-        setPopupBackgroundDrawable(getContext().getResources().getDrawable(resId));
+        setPopupBackgroundDrawable(getContext().getDrawable(resId));
     }
 
     /**
@@ -1033,8 +1056,9 @@
         private CharSequence mHintText;
         private ListAdapter mAdapter;
 
-        public DropdownPopup(Context context, AttributeSet attrs, int defStyleRes) {
-            super(context, attrs, 0, defStyleRes);
+        public DropdownPopup(
+                Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
 
             setAnchorView(Spinner.this);
             setModal(true);
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 6853660..d2e718c 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -168,9 +168,16 @@
      * {@inheritDoc}
      */
     public StackView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.StackView, defStyleAttr, 0);
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public StackView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.StackView, defStyleAttr, defStyleRes);
 
         mResOutColor = a.getColor(
                 com.android.internal.R.styleable.StackView_resOutColor, 0);
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index c44d431..c8917e0 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -529,7 +529,7 @@
                 return drawable;
             }
             // Not cached, find it by resource ID
-            drawable = mProviderContext.getResources().getDrawable(resourceId);
+            drawable = mProviderContext.getDrawable(resourceId);
             // Stick it in the cache, using the URI as key
             storeInIconCache(drawableUri, drawable);
             return drawable;
@@ -563,7 +563,7 @@
                 OpenResourceIdResult r =
                     mProviderContext.getContentResolver().getResourceId(uri);
                 try {
-                    return r.r.getDrawable(r.id);
+                    return r.r.getDrawable(r.id, mContext.getTheme());
                 } catch (Resources.NotFoundException ex) {
                     throw new FileNotFoundException("Resource does not exist: " + uri);
                 }
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index e754c17..3d23e4d 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -32,6 +33,8 @@
 import android.text.method.AllCapsTransformationMethod;
 import android.text.method.TransformationMethod2;
 import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.util.MathUtils;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -66,6 +69,8 @@
  * @attr ref android.R.styleable#Switch_track
  */
 public class Switch extends CompoundButton {
+    private static final int THUMB_ANIMATION_DURATION = 250;
+
     private static final int TOUCH_MODE_IDLE = 0;
     private static final int TOUCH_MODE_DOWN = 1;
     private static final int TOUCH_MODE_DRAGGING = 2;
@@ -105,6 +110,7 @@
     private Layout mOnLayout;
     private Layout mOffLayout;
     private TransformationMethod2 mSwitchTransformationMethod;
+    private ObjectAnimator mPositionAnimator;
 
     @SuppressWarnings("hiding")
     private final Rect mTempRect = new Rect();
@@ -139,19 +145,41 @@
      *
      * @param context The Context that will determine this widget's theming.
      * @param attrs Specification of attributes that should deviate from the default styling.
-     * @param defStyle An attribute ID within the active theme containing a reference to the
-     *                 default style for this widget. e.g. android.R.attr.switchStyle.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public Switch(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public Switch(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+
+    /**
+     * Construct a new Switch with a default style determined by the given theme
+     * attribute or style resource, overriding specific style attributes as
+     * requested.
+     *
+     * @param context The Context that will determine this widget's theming.
+     * @param attrs Specification of attributes that should deviate from the
+     *        default styling.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *        reference to a style resource that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *        supplies default values for the view, used only if
+     *        defStyleAttr is 0 or can not be found in the theme. Can be 0
+     *        to not look for defaults.
+     */
+    public Switch(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
         Resources res = getResources();
         mTextPaint.density = res.getDisplayMetrics().density;
         mTextPaint.setCompatibilityScaling(res.getCompatibilityInfo().applicationScale);
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Switch, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.Switch, defStyleAttr, defStyleRes);
 
         mThumbDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_thumb);
         mTrackDrawable = a.getDrawable(com.android.internal.R.styleable.Switch_track);
@@ -389,7 +417,7 @@
      * @attr ref android.R.styleable#Switch_track
      */
     public void setTrackResource(int resId) {
-        setTrackDrawable(getContext().getResources().getDrawable(resId));
+        setTrackDrawable(getContext().getDrawable(resId));
     }
 
     /**
@@ -425,7 +453,7 @@
      * @attr ref android.R.styleable#Switch_thumb
      */
     public void setThumbResource(int resId) {
-        setThumbDrawable(getContext().getResources().getDrawable(resId));
+        setThumbDrawable(getContext().getDrawable(resId));
     }
 
     /**
@@ -483,15 +511,18 @@
         if (mOnLayout == null) {
             mOnLayout = makeLayout(mTextOn);
         }
+
         if (mOffLayout == null) {
             mOffLayout = makeLayout(mTextOff);
         }
 
         mTrackDrawable.getPadding(mTempRect);
+
         final int maxTextWidth = Math.max(mOnLayout.getWidth(), mOffLayout.getWidth());
         final int switchWidth = Math.max(mSwitchMinWidth,
                 maxTextWidth * 2 + mThumbTextPadding * 4 + mTempRect.left + mTempRect.right);
-        final int switchHeight = mTrackDrawable.getIntrinsicHeight();
+        final int switchHeight = Math.max(mTrackDrawable.getIntrinsicHeight(),
+                mThumbDrawable.getIntrinsicHeight());
 
         mThumbWidth = maxTextWidth + mThumbTextPadding * 2;
 
@@ -528,9 +559,12 @@
      * @return true if (x, y) is within the target area of the switch thumb
      */
     private boolean hitThumb(float x, float y) {
+        // Relies on mTempRect, MUST be called first!
+        final int thumbOffset = getThumbOffset();
+
         mThumbDrawable.getPadding(mTempRect);
         final int thumbTop = mSwitchTop - mTouchSlop;
-        final int thumbLeft = mSwitchLeft + (int) (mThumbPosition + 0.5f) - mTouchSlop;
+        final int thumbLeft = mSwitchLeft + thumbOffset - mTouchSlop;
         final int thumbRight = thumbLeft + mThumbWidth +
                 mTempRect.left + mTempRect.right + mTouchSlop;
         final int thumbBottom = mSwitchBottom + mTouchSlop;
@@ -575,13 +609,23 @@
 
                     case TOUCH_MODE_DRAGGING: {
                         final float x = ev.getX();
-                        final float dx = x - mTouchX;
-                        float newPos = Math.max(0,
-                                Math.min(mThumbPosition + dx, getThumbScrollRange()));
+                        final int thumbScrollRange = getThumbScrollRange();
+                        final float thumbScrollOffset = x - mTouchX;
+                        float dPos;
+                        if (thumbScrollRange != 0) {
+                            dPos = thumbScrollOffset / thumbScrollRange;
+                        } else {
+                            // If the thumb scroll range is empty, just use the
+                            // movement direction to snap on or off.
+                            dPos = thumbScrollOffset > 0 ? 1 : -1;
+                        }
+                        if (isLayoutRtl()) {
+                            dPos = -dPos;
+                        }
+                        final float newPos = MathUtils.constrain(mThumbPosition + dPos, 0, 1);
                         if (newPos != mThumbPosition) {
-                            mThumbPosition = newPos;
                             mTouchX = x;
-                            invalidate();
+                            setThumbPosition(newPos);
                         }
                         return true;
                     }
@@ -618,62 +662,77 @@
      */
     private void stopDrag(MotionEvent ev) {
         mTouchMode = TOUCH_MODE_IDLE;
-        // Up and not canceled, also checks the switch has not been disabled during the drag
-        boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled();
 
-        cancelSuperTouch(ev);
-
+        // Commit the change if the event is up and not canceled and the switch
+        // has not been disabled during the drag.
+        final boolean commitChange = ev.getAction() == MotionEvent.ACTION_UP && isEnabled();
+        final boolean newState;
         if (commitChange) {
-            boolean newState;
             mVelocityTracker.computeCurrentVelocity(1000);
-            float xvel = mVelocityTracker.getXVelocity();
+            final float xvel = mVelocityTracker.getXVelocity();
             if (Math.abs(xvel) > mMinFlingVelocity) {
                 newState = isLayoutRtl() ? (xvel < 0) : (xvel > 0);
             } else {
                 newState = getTargetCheckedState();
             }
-            animateThumbToCheckedState(newState);
         } else {
-            animateThumbToCheckedState(isChecked());
+            newState = isChecked();
         }
+
+        setChecked(newState);
+        cancelSuperTouch(ev);
     }
 
     private void animateThumbToCheckedState(boolean newCheckedState) {
-        // TODO animate!
-        //float targetPos = newCheckedState ? 0 : getThumbScrollRange();
-        //mThumbPosition = targetPos;
-        setChecked(newCheckedState);
+        final float targetPosition = newCheckedState ? 1 : 0;
+        mPositionAnimator = ObjectAnimator.ofFloat(this, THUMB_POS, targetPosition);
+        mPositionAnimator.setDuration(THUMB_ANIMATION_DURATION);
+        mPositionAnimator.setAutoCancel(true);
+        mPositionAnimator.start();
+    }
+
+    private void cancelPositionAnimator() {
+        if (mPositionAnimator != null) {
+            mPositionAnimator.cancel();
+        }
     }
 
     private boolean getTargetCheckedState() {
-        if (isLayoutRtl()) {
-            return mThumbPosition <= getThumbScrollRange() / 2;
-        } else {
-            return mThumbPosition >= getThumbScrollRange() / 2;
-        }
+        return mThumbPosition > 0.5f;
     }
 
-    private void setThumbPosition(boolean checked) {
-        if (isLayoutRtl()) {
-            mThumbPosition = checked ? 0 : getThumbScrollRange();
-        } else {
-            mThumbPosition = checked ? getThumbScrollRange() : 0;
-        }
+    /**
+     * Sets the thumb position as a decimal value between 0 (off) and 1 (on).
+     *
+     * @param position new position between [0,1]
+     */
+    private void setThumbPosition(float position) {
+        mThumbPosition = position;
+        invalidate();
+    }
+
+    @Override
+    public void toggle() {
+        setChecked(!isChecked());
     }
 
     @Override
     public void setChecked(boolean checked) {
         super.setChecked(checked);
-        setThumbPosition(isChecked());
-        invalidate();
+
+        if (isAttachedToWindow() && isLaidOut()) {
+            animateThumbToCheckedState(checked);
+        } else {
+            // Immediately move the thumb to the new position.
+            cancelPositionAnimator();
+            setThumbPosition(checked ? 1 : 0);
+        }
     }
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
 
-        setThumbPosition(isChecked());
-
         int switchRight;
         int switchLeft;
 
@@ -716,47 +775,51 @@
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
 
+        final Rect tempRect = mTempRect;
+        final Drawable trackDrawable = mTrackDrawable;
+        final Drawable thumbDrawable = mThumbDrawable;
+
         // Draw the switch
-        int switchLeft = mSwitchLeft;
-        int switchTop = mSwitchTop;
-        int switchRight = mSwitchRight;
-        int switchBottom = mSwitchBottom;
+        final int switchLeft = mSwitchLeft;
+        final int switchTop = mSwitchTop;
+        final int switchRight = mSwitchRight;
+        final int switchBottom = mSwitchBottom;
+        trackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);
+        trackDrawable.draw(canvas);
 
-        mTrackDrawable.setBounds(switchLeft, switchTop, switchRight, switchBottom);
-        mTrackDrawable.draw(canvas);
+        final int saveCount = canvas.save();
 
-        canvas.save();
-
-        mTrackDrawable.getPadding(mTempRect);
-        int switchInnerLeft = switchLeft + mTempRect.left;
-        int switchInnerTop = switchTop + mTempRect.top;
-        int switchInnerRight = switchRight - mTempRect.right;
-        int switchInnerBottom = switchBottom - mTempRect.bottom;
+        trackDrawable.getPadding(tempRect);
+        final int switchInnerLeft = switchLeft + tempRect.left;
+        final int switchInnerTop = switchTop + tempRect.top;
+        final int switchInnerRight = switchRight - tempRect.right;
+        final int switchInnerBottom = switchBottom - tempRect.bottom;
         canvas.clipRect(switchInnerLeft, switchTop, switchInnerRight, switchBottom);
 
-        mThumbDrawable.getPadding(mTempRect);
-        final int thumbPos = (int) (mThumbPosition + 0.5f);
-        int thumbLeft = switchInnerLeft - mTempRect.left + thumbPos;
-        int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + mTempRect.right;
+        // Relies on mTempRect, MUST be called first!
+        final int thumbPos = getThumbOffset();
 
-        mThumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
-        mThumbDrawable.draw(canvas);
+        thumbDrawable.getPadding(tempRect);
+        int thumbLeft = switchInnerLeft - tempRect.left + thumbPos;
+        int thumbRight = switchInnerLeft + thumbPos + mThumbWidth + tempRect.right;
+        thumbDrawable.setBounds(thumbLeft, switchTop, thumbRight, switchBottom);
+        thumbDrawable.draw(canvas);
 
-        // mTextColors should not be null, but just in case
+        final int drawableState[] = getDrawableState();
         if (mTextColors != null) {
-            mTextPaint.setColor(mTextColors.getColorForState(getDrawableState(),
-                    mTextColors.getDefaultColor()));
+            mTextPaint.setColor(mTextColors.getColorForState(drawableState, 0));
         }
-        mTextPaint.drawableState = getDrawableState();
+        mTextPaint.drawableState = drawableState;
 
-        Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
+        final Layout switchText = getTargetCheckedState() ? mOnLayout : mOffLayout;
         if (switchText != null) {
-            canvas.translate((thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2,
-                    (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2);
+            final int left = (thumbLeft + thumbRight) / 2 - switchText.getWidth() / 2;
+            final int top = (switchInnerTop + switchInnerBottom) / 2 - switchText.getHeight() / 2;
+            canvas.translate(left, top);
             switchText.draw(canvas);
         }
 
-        canvas.restore();
+        canvas.restoreToCount(saveCount);
     }
 
     @Override
@@ -783,6 +846,22 @@
         return padding;
     }
 
+    /**
+     * Translates thumb position to offset according to current RTL setting and
+     * thumb scroll range.
+     *
+     * @return thumb offset
+     */
+    private int getThumbOffset() {
+        final float thumbPosition;
+        if (isLayoutRtl()) {
+            thumbPosition = 1 - mThumbPosition;
+        } else {
+            thumbPosition = mThumbPosition;
+        }
+        return (int) (thumbPosition * getThumbScrollRange() + 0.5f);
+    }
+
     private int getThumbScrollRange() {
         if (mTrackDrawable == null) {
             return 0;
@@ -848,4 +927,16 @@
             }
         }
     }
+
+    private static final FloatProperty<Switch> THUMB_POS = new FloatProperty<Switch>("thumbPos") {
+        @Override
+        public Float get(Switch object) {
+            return object.mThumbPosition;
+        }
+
+        @Override
+        public void setValue(Switch object, float value) {
+            object.setThumbPosition(value);
+        }
+    };
 }
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 238dc55..89df51a 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -77,11 +77,18 @@
     }
 
     public TabHost(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.tabWidgetStyle);
+    }
+
+    public TabHost(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TabHost(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs);
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.TabWidget,
-                com.android.internal.R.attr.tabWidgetStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.TabWidget, defStyleAttr, defStyleRes);
 
         mTabLayoutId = a.getResourceId(R.styleable.TabWidget_tabLayout, 0);
         a.recycle();
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 6bced1c..47a5449 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -74,11 +74,15 @@
         this(context, attrs, com.android.internal.R.attr.tabWidgetStyle);
     }
 
-    public TabWidget(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TabWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TabWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         final TypedArray a = context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.TabWidget, defStyle, 0);
+                attrs, com.android.internal.R.styleable.TabWidget, defStyleAttr, defStyleRes);
 
         setStripEnabled(a.getBoolean(R.styleable.TabWidget_tabStripEnabled, true));
         setLeftStripDrawable(a.getDrawable(R.styleable.TabWidget_tabStripLeft));
@@ -116,28 +120,27 @@
         setChildrenDrawingOrderEnabled(true);
 
         final Context context = mContext;
-        final Resources resources = context.getResources();
 
         // Tests the target Sdk version, as set in the Manifest. Could not be set using styles.xml
         // in a values-v? directory which targets the current platform Sdk version instead.
         if (context.getApplicationInfo().targetSdkVersion <= Build.VERSION_CODES.DONUT) {
             // Donut apps get old color scheme
             if (mLeftStrip == null) {
-                mLeftStrip = resources.getDrawable(
+                mLeftStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_left_v4);
             }
             if (mRightStrip == null) {
-                mRightStrip = resources.getDrawable(
+                mRightStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_right_v4);
             }
         } else {
             // Use modern color scheme for Eclair and beyond
             if (mLeftStrip == null) {
-                mLeftStrip = resources.getDrawable(
+                mLeftStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_left);
             }
             if (mRightStrip == null) {
-                mRightStrip = resources.getDrawable(
+                mRightStrip = context.getDrawable(
                         com.android.internal.R.drawable.tab_bottom_right);
             }
         }
@@ -242,7 +245,7 @@
      * divider.
      */
     public void setDividerDrawable(int resId) {
-        setDividerDrawable(getResources().getDrawable(resId));
+        setDividerDrawable(mContext.getDrawable(resId));
     }
     
     /**
@@ -263,7 +266,7 @@
      * left strip drawable
      */
     public void setLeftStripDrawable(int resId) {
-        setLeftStripDrawable(getResources().getDrawable(resId));
+        setLeftStripDrawable(mContext.getDrawable(resId));
     }
 
     /**
@@ -284,7 +287,7 @@
      * right strip drawable
      */
     public void setRightStripDrawable(int resId) {
-        setRightStripDrawable(getResources().getDrawable(resId));
+        setRightStripDrawable(mContext.getDrawable(resId));
     }
 
     /**
diff --git a/core/java/android/widget/TextClock.java b/core/java/android/widget/TextClock.java
index b3b95d9..4c5c71d 100644
--- a/core/java/android/widget/TextClock.java
+++ b/core/java/android/widget/TextClock.java
@@ -198,15 +198,19 @@
      * @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 that supplies default values for
+     *        the view. Can be 0 to not look for defaults.
      */
-    public TextClock(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextClock(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextClock, defStyle, 0);
+    public TextClock(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.TextClock, defStyleAttr, defStyleRes);
         try {
             mFormat12 = a.getText(R.styleable.TextClock_format12Hour);
             mFormat24 = a.getText(R.styleable.TextClock_format24Hour);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 37121e2..687036c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -136,7 +136,6 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Locale;
-import java.util.concurrent.locks.ReentrantLock;
 
 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
 
@@ -618,9 +617,14 @@
         this(context, attrs, com.android.internal.R.attr.textViewStyle);
     }
 
+    public TextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     @SuppressWarnings("deprecation")
-    public TextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
         mText = "";
 
         final Resources res = getResources();
@@ -657,8 +661,8 @@
          * to be able to parse the appearance first and then let specific tags
          * for this View override it.
          */
-        TypedArray a = theme.obtainStyledAttributes(
-                    attrs, com.android.internal.R.styleable.TextViewAppearance, defStyle, 0);
+        TypedArray a = theme.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.TextViewAppearance, defStyleAttr, defStyleRes);
         TypedArray appearance = null;
         int ap = a.getResourceId(
                 com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
@@ -751,7 +755,7 @@
         int inputType = EditorInfo.TYPE_NULL;
 
         a = theme.obtainStyledAttributes(
-                    attrs, com.android.internal.R.styleable.TextView, defStyle, 0);
+                    attrs, com.android.internal.R.styleable.TextView, defStyleAttr, defStyleRes);
 
         int n = a.getIndexCount();
         for (int i = 0; i < n; i++) {
@@ -1275,9 +1279,8 @@
          * However, TextViews that have input or movement methods *are*
          * focusable by default.
          */
-        a = context.obtainStyledAttributes(attrs,
-                                           com.android.internal.R.styleable.View,
-                                           defStyle, 0);
+        a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.View, defStyleAttr, defStyleRes);
 
         boolean focusable = mMovement != null || getKeyListener() != null;
         boolean clickable = focusable;
@@ -2070,11 +2073,11 @@
      */
     @android.view.RemotableViewMethod
     public void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) {
-        final Resources resources = getContext().getResources();
-        setCompoundDrawablesWithIntrinsicBounds(left != 0 ? resources.getDrawable(left) : null,
-                top != 0 ? resources.getDrawable(top) : null,
-                right != 0 ? resources.getDrawable(right) : null,
-                bottom != 0 ? resources.getDrawable(bottom) : null);
+        final Context context = getContext();
+        setCompoundDrawablesWithIntrinsicBounds(left != 0 ? context.getDrawable(left) : null,
+                top != 0 ? context.getDrawable(top) : null,
+                right != 0 ? context.getDrawable(right) : null,
+                bottom != 0 ? context.getDrawable(bottom) : null);
     }
 
     /**
@@ -2244,12 +2247,12 @@
     @android.view.RemotableViewMethod
     public void setCompoundDrawablesRelativeWithIntrinsicBounds(int start, int top, int end,
             int bottom) {
-        final Resources resources = getContext().getResources();
+        final Context context = getContext();
         setCompoundDrawablesRelativeWithIntrinsicBounds(
-                start != 0 ? resources.getDrawable(start) : null,
-                top != 0 ? resources.getDrawable(top) : null,
-                end != 0 ? resources.getDrawable(end) : null,
-                bottom != 0 ? resources.getDrawable(bottom) : null);
+                start != 0 ? context.getDrawable(start) : null,
+                top != 0 ? context.getDrawable(top) : null,
+                end != 0 ? context.getDrawable(end) : null,
+                bottom != 0 ? context.getDrawable(bottom) : null);
     }
 
     /**
@@ -4382,8 +4385,8 @@
         if (error == null) {
             setError(null, null);
         } else {
-            Drawable dr = getContext().getResources().
-                getDrawable(com.android.internal.R.drawable.indicator_input_error);
+            Drawable dr = getContext().getDrawable(
+                    com.android.internal.R.drawable.indicator_input_error);
 
             dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
             setError(error, dr);
@@ -4726,10 +4729,9 @@
         if (mEditor != null) mEditor.onAttachedToWindow();
     }
 
+    /** @hide */
     @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-
+    protected void onDetachedFromWindowInternal() {
         if (mPreDrawRegistered) {
             getViewTreeObserver().removeOnPreDrawListener(this);
             mPreDrawRegistered = false;
@@ -4738,6 +4740,8 @@
         resetResolvedDrawables();
 
         if (mEditor != null) mEditor.onDetachedFromWindow();
+
+        super.onDetachedFromWindowInternal();
     }
 
     @Override
@@ -4811,6 +4815,8 @@
 
     @Override
     public void invalidateDrawable(Drawable drawable) {
+        boolean handled = false;
+
         if (verifyDrawable(drawable)) {
             final Rect dirty = drawable.getBounds();
             int scrollX = mScrollX;
@@ -4828,6 +4834,7 @@
 
                     scrollX += mPaddingLeft;
                     scrollY += compoundPaddingTop + (vspace - drawables.mDrawableHeightLeft) / 2;
+                    handled = true;
                 } else if (drawable == drawables.mDrawableRight) {
                     final int compoundPaddingTop = getCompoundPaddingTop();
                     final int compoundPaddingBottom = getCompoundPaddingBottom();
@@ -4835,6 +4842,7 @@
 
                     scrollX += (mRight - mLeft - mPaddingRight - drawables.mDrawableSizeRight);
                     scrollY += compoundPaddingTop + (vspace - drawables.mDrawableHeightRight) / 2;
+                    handled = true;
                 } else if (drawable == drawables.mDrawableTop) {
                     final int compoundPaddingLeft = getCompoundPaddingLeft();
                     final int compoundPaddingRight = getCompoundPaddingRight();
@@ -4842,6 +4850,7 @@
 
                     scrollX += compoundPaddingLeft + (hspace - drawables.mDrawableWidthTop) / 2;
                     scrollY += mPaddingTop;
+                    handled = true;
                 } else if (drawable == drawables.mDrawableBottom) {
                     final int compoundPaddingLeft = getCompoundPaddingLeft();
                     final int compoundPaddingRight = getCompoundPaddingRight();
@@ -4849,11 +4858,18 @@
 
                     scrollX += compoundPaddingLeft + (hspace - drawables.mDrawableWidthBottom) / 2;
                     scrollY += (mBottom - mTop - mPaddingBottom - drawables.mDrawableSizeBottom);
+                    handled = true;
                 }
             }
 
-            invalidate(dirty.left + scrollX, dirty.top + scrollY,
-                    dirty.right + scrollX, dirty.bottom + scrollY);
+            if (handled) {
+                invalidate(dirty.left + scrollX, dirty.top + scrollY,
+                        dirty.right + scrollX, dirty.bottom + scrollY);
+            }
+        }
+
+        if (!handled) {
+            super.invalidateDrawable(drawable);
         }
     }
 
@@ -5794,6 +5810,7 @@
                 int end = text.partialEndOffset;
                 if (end > N) end = N;
                 removeParcelableSpans(content, start, end);
+                // If start > end, content.replace will swap them before using them.
                 content.replace(start, end, text.text);
             }
         }
@@ -8478,7 +8495,7 @@
             return false;
         }
 
-        if (mText.length() > 0 && hasSelection()) {
+        if (mText.length() > 0 && hasSelection() && mEditor != null) {
             return true;
         }
 
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index c26cb24..8e4ba0d 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -20,26 +20,17 @@
 import android.content.Context;
 import android.content.res.Configuration;
 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;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.NumberPicker.OnValueChangeListener;
 
 import com.android.internal.R;
 
-import java.text.DateFormatSymbols;
-import java.util.Calendar;
 import java.util.Locale;
 
+import static android.os.Build.VERSION_CODES.KITKAT;
+
 /**
  * A view for selecting the time of day, in either 24 hour or AM/PM mode. The
  * hour, each minute digit, and AM/PM (if applicable) can be conrolled by
@@ -57,58 +48,12 @@
 @Widget
 public class TimePicker extends FrameLayout {
 
-    private static final boolean DEFAULT_ENABLED_STATE = true;
+    private TimePickerDelegate mDelegate;
 
-    private static final int HOURS_IN_HALF_DAY = 12;
-
-    /**
-     * A no-op callback used in the constructor to avoid null checks later in
-     * the code.
-     */
-    private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() {
-        public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
-        }
-    };
-
-    // state
-    private boolean mIs24HourView;
-
-    private boolean mIsAm;
-
-    // ui components
-    private final NumberPicker mHourSpinner;
-
-    private final NumberPicker mMinuteSpinner;
-
-    private final NumberPicker mAmPmSpinner;
-
-    private final EditText mHourSpinnerInput;
-
-    private final EditText mMinuteSpinnerInput;
-
-    private final EditText mAmPmSpinnerInput;
-
-    private final TextView mDivider;
-
-    // Note that the legacy implementation of the TimePicker is
-    // using a button for toggling between AM/PM while the new
-    // version uses a NumberPicker spinner. Therefore the code
-    // accommodates these two cases to be backwards compatible.
-    private final Button mAmPmButton;
-
-    private final String[] mAmPmStrings;
-
-    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
-
-    // callbacks
-    private OnTimeChangedListener mOnTimeChangedListener;
-
-    private Calendar mTempCalendar;
-
-    private Locale mCurrentLocale;
-
-    private boolean mHourWithTwoDigit;
-    private char mHourFormat;
+    private AttributeSet mAttrs;
+    private int mDefStyleAttr;
+    private int mDefStyleRes;
+    private Context mContext;
 
     /**
      * The callback interface used to indicate the time has been adjusted.
@@ -131,345 +76,79 @@
         this(context, attrs, R.attr.timePickerStyle);
     }
 
-    public TimePicker(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        // initialization based on locale
-        setCurrentLocale(Locale.getDefault());
-
-        // process style attributes
-        TypedArray attributesArray = context.obtainStyledAttributes(
-                attrs, R.styleable.TimePicker, defStyle, 0);
-        int layoutResourceId = attributesArray.getResourceId(
-                R.styleable.TimePicker_internalLayout, R.layout.time_picker);
-        attributesArray.recycle();
-
-        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(layoutResourceId, this, true);
-
-        // hour
-        mHourSpinner = (NumberPicker) findViewById(R.id.hour);
-        mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
-            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
-                updateInputState();
-                if (!is24HourView()) {
-                    if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY)
-                            || (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) {
-                        mIsAm = !mIsAm;
-                        updateAmPmControl();
-                    }
-                }
-                onTimeChanged();
-            }
-        });
-        mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input);
-        mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
-
-        // divider (only for the new widget style)
-        mDivider = (TextView) findViewById(R.id.divider);
-        if (mDivider != null) {
-            setDividerText();
-        }
-
-        // minute
-        mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
-        mMinuteSpinner.setMinValue(0);
-        mMinuteSpinner.setMaxValue(59);
-        mMinuteSpinner.setOnLongPressUpdateInterval(100);
-        mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter());
-        mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
-            public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
-                updateInputState();
-                int minValue = mMinuteSpinner.getMinValue();
-                int maxValue = mMinuteSpinner.getMaxValue();
-                if (oldVal == maxValue && newVal == minValue) {
-                    int newHour = mHourSpinner.getValue() + 1;
-                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) {
-                        mIsAm = !mIsAm;
-                        updateAmPmControl();
-                    }
-                    mHourSpinner.setValue(newHour);
-                } else if (oldVal == minValue && newVal == maxValue) {
-                    int newHour = mHourSpinner.getValue() - 1;
-                    if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) {
-                        mIsAm = !mIsAm;
-                        updateAmPmControl();
-                    }
-                    mHourSpinner.setValue(newHour);
-                }
-                onTimeChanged();
-            }
-        });
-        mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input);
-        mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
-
-        /* Get the localized am/pm strings and use them in the spinner */
-        mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
-
-        // am/pm
-        View amPmView = findViewById(R.id.amPm);
-        if (amPmView instanceof Button) {
-            mAmPmSpinner = null;
-            mAmPmSpinnerInput = null;
-            mAmPmButton = (Button) amPmView;
-            mAmPmButton.setOnClickListener(new OnClickListener() {
-                public void onClick(View button) {
-                    button.requestFocus();
-                    mIsAm = !mIsAm;
-                    updateAmPmControl();
-                    onTimeChanged();
-                }
-            });
-        } else {
-            mAmPmButton = null;
-            mAmPmSpinner = (NumberPicker) amPmView;
-            mAmPmSpinner.setMinValue(0);
-            mAmPmSpinner.setMaxValue(1);
-            mAmPmSpinner.setDisplayedValues(mAmPmStrings);
-            mAmPmSpinner.setOnValueChangedListener(new OnValueChangeListener() {
-                public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
-                    updateInputState();
-                    picker.requestFocus();
-                    mIsAm = !mIsAm;
-                    updateAmPmControl();
-                    onTimeChanged();
-                }
-            });
-            mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input);
-            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();
-        updateAmPmControl();
-
-        setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
-
-        // set to current time
-        setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
-        setCurrentMinute(mTempCalendar.get(Calendar.MINUTE));
-
-        if (!isEnabled()) {
-            setEnabled(false);
-        }
-
-        // set the content descriptions
-        setContentDescriptions();
-
-        // If not explicitly specified this view is important for accessibility.
-        if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
-            setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
-        }
+    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
-    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;
-            }
-        }
+    public TimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        mContext = context;
+        mAttrs = attrs;
+        mDefStyleAttr = defStyleAttr;
+        mDefStyleRes = defStyleRes;
+
+        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TimePicker,
+                mDefStyleAttr, mDefStyleRes);
+
+        // Create the correct UI delegate. Default is the legacy one.
+        final boolean isLegacyMode = shouldForceLegacyMode() ?
+                true : a.getBoolean(R.styleable.TimePicker_legacyMode, true);
+        setLegacyMode(isLegacyMode);
     }
 
-    private boolean isAmPmAtStart() {
-        final Locale defaultLocale = Locale.getDefault();
-        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(defaultLocale,
-                "hm" /* skeleton */);
-
-        return bestDateTimePattern.startsWith("a");
+    private boolean shouldForceLegacyMode() {
+        final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
+        return targetSdkVersion < KITKAT;
     }
 
-    @Override
-    public void setEnabled(boolean enabled) {
-        if (mIsEnabled == enabled) {
-            return;
-        }
-        super.setEnabled(enabled);
-        mMinuteSpinner.setEnabled(enabled);
-        if (mDivider != null) {
-            mDivider.setEnabled(enabled);
-        }
-        mHourSpinner.setEnabled(enabled);
-        if (mAmPmSpinner != null) {
-            mAmPmSpinner.setEnabled(enabled);
-        } else {
-            mAmPmButton.setEnabled(enabled);
-        }
-        mIsEnabled = enabled;
+    private TimePickerDelegate createLegacyUIDelegate(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        return new LegacyTimePickerDelegate(this, context, attrs, defStyleAttr, defStyleRes);
     }
 
-    @Override
-    public boolean isEnabled() {
-        return mIsEnabled;
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        setCurrentLocale(newConfig.locale);
+    private TimePickerDelegate createNewUIDelegate(Context context, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        return new android.widget.TimePickerDelegate(this, context, attrs, defStyleAttr,
+                defStyleRes);
     }
 
     /**
-     * Sets the current locale.
-     *
-     * @param locale The current locale.
+     * @hide
      */
-    private void setCurrentLocale(Locale locale) {
-        if (locale.equals(mCurrentLocale)) {
-            return;
-        }
-        mCurrentLocale = locale;
-        mTempCalendar = Calendar.getInstance(locale);
-    }
-
-    /**
-     * Used to save / restore state of time picker
-     */
-    private static class SavedState extends BaseSavedState {
-
-        private final int mHour;
-
-        private final int mMinute;
-
-        private SavedState(Parcelable superState, int hour, int minute) {
-            super(superState);
-            mHour = hour;
-            mMinute = minute;
-        }
-
-        private SavedState(Parcel in) {
-            super(in);
-            mHour = in.readInt();
-            mMinute = in.readInt();
-        }
-
-        public int getHour() {
-            return mHour;
-        }
-
-        public int getMinute() {
-            return mMinute;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            super.writeToParcel(dest, flags);
-            dest.writeInt(mHour);
-            dest.writeInt(mMinute);
-        }
-
-        @SuppressWarnings({"unused", "hiding"})
-        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Parcelable superState = super.onSaveInstanceState();
-        return new SavedState(superState, getCurrentHour(), getCurrentMinute());
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-        setCurrentHour(ss.getHour());
-        setCurrentMinute(ss.getMinute());
-    }
-
-    /**
-     * Set the callback that indicates the time has been adjusted by the user.
-     *
-     * @param onTimeChangedListener the callback, should not be null.
-     */
-    public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
-        mOnTimeChangedListener = onTimeChangedListener;
-    }
-
-    /**
-     * @return The current hour in the range (0-23).
-     */
-    public Integer getCurrentHour() {
-        int currentHour = mHourSpinner.getValue();
-        if (is24HourView()) {
-            return currentHour;
-        } else if (mIsAm) {
-            return currentHour % HOURS_IN_HALF_DAY;
-        } else {
-            return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
-        }
+    public void setLegacyMode(boolean isLegacyMode) {
+        removeAllViewsInLayout();
+        mDelegate = isLegacyMode ?
+                createLegacyUIDelegate(mContext, mAttrs, mDefStyleAttr, mDefStyleRes) :
+                createNewUIDelegate(mContext, mAttrs, mDefStyleAttr, mDefStyleRes);
     }
 
     /**
      * Set the current hour.
      */
     public void setCurrentHour(Integer currentHour) {
-        setCurrentHour(currentHour, true);
+        mDelegate.setCurrentHour(currentHour);
     }
 
-    private void setCurrentHour(Integer currentHour, boolean notifyTimeChanged) {
-        // why was Integer used in the first place?
-        if (currentHour == null || currentHour == getCurrentHour()) {
-            return;
-        }
-        if (!is24HourView()) {
-            // convert [0,23] ordinal to wall clock display
-            if (currentHour >= HOURS_IN_HALF_DAY) {
-                mIsAm = false;
-                if (currentHour > HOURS_IN_HALF_DAY) {
-                    currentHour = currentHour - HOURS_IN_HALF_DAY;
-                }
-            } else {
-                mIsAm = true;
-                if (currentHour == 0) {
-                    currentHour = HOURS_IN_HALF_DAY;
-                }
-            }
-            updateAmPmControl();
-        }
-        mHourSpinner.setValue(currentHour);
-        if (notifyTimeChanged) {
-            onTimeChanged();
-        }
+    /**
+     * @return The current hour in the range (0-23).
+     */
+    public Integer getCurrentHour() {
+        return mDelegate.getCurrentHour();
+    }
+
+    /**
+     * Set the current minute (0-59).
+     */
+    public void setCurrentMinute(Integer currentMinute) {
+        mDelegate.setCurrentMinute(currentMinute);
+    }
+
+    /**
+     * @return The current minute.
+     */
+    public Integer getCurrentMinute() {
+        return mDelegate.getCurrentMinute();
     }
 
     /**
@@ -478,223 +157,174 @@
      * @param is24HourView True = 24 hour mode. False = AM/PM.
      */
     public void setIs24HourView(Boolean is24HourView) {
-        if (mIs24HourView == is24HourView) {
-            return;
-        }
-        // 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 - 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();
+        mDelegate.setIs24HourView(is24HourView);
     }
 
     /**
      * @return true if this is in 24 hour view else false.
      */
     public boolean is24HourView() {
-        return mIs24HourView;
+        return mDelegate.is24HourView();
     }
 
     /**
-     * @return The current minute.
+     * Set the callback that indicates the time has been adjusted by the user.
+     *
+     * @param onTimeChangedListener the callback, should not be null.
      */
-    public Integer getCurrentMinute() {
-        return mMinuteSpinner.getValue();
+    public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
+        mDelegate.setOnTimeChangedListener(onTimeChangedListener);
     }
 
-    /**
-     * Set the current minute (0-59).
-     */
-    public void setCurrentMinute(Integer currentMinute) {
-        if (currentMinute == getCurrentMinute()) {
+    @Override
+    public void setEnabled(boolean enabled) {
+        if (mDelegate.isEnabled() == enabled) {
             return;
         }
-        mMinuteSpinner.setValue(currentMinute);
-        onTimeChanged();
+        super.setEnabled(enabled);
+        mDelegate.setEnabled(enabled);
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mDelegate.isEnabled();
     }
 
     /**
-     * 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.
+     * @hide
      */
-    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);
+    public void setShowDoneButton(boolean showDoneButton) {
+        mDelegate.setShowDoneButton(showDoneButton);
+    }
+
+    /**
+     * @hide
+     */
+    public void setDismissCallback(TimePickerDismissCallback callback) {
+        mDelegate.setDismissCallback(callback);
     }
 
     @Override
     public int getBaseline() {
-        return mHourSpinner.getBaseline();
+        return mDelegate.getBaseline();
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        mDelegate.onConfigurationChanged(newConfig);
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        Parcelable superState = super.onSaveInstanceState();
+        return mDelegate.onSaveInstanceState(superState);
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        BaseSavedState ss = (BaseSavedState) state;
+        super.onRestoreInstanceState(ss.getSuperState());
+        mDelegate.onRestoreInstanceState(ss);
     }
 
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        onPopulateAccessibilityEvent(event);
-        return true;
+        return mDelegate.dispatchPopulateAccessibilityEvent(event);
     }
 
     @Override
     public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
         super.onPopulateAccessibilityEvent(event);
-
-        int flags = DateUtils.FORMAT_SHOW_TIME;
-        if (mIs24HourView) {
-            flags |= DateUtils.FORMAT_24HOUR;
-        } else {
-            flags |= DateUtils.FORMAT_12HOUR;
-        }
-        mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour());
-        mTempCalendar.set(Calendar.MINUTE, getCurrentMinute());
-        String selectedDateUtterance = DateUtils.formatDateTime(mContext,
-                mTempCalendar.getTimeInMillis(), flags);
-        event.getText().add(selectedDateUtterance);
+        mDelegate.onPopulateAccessibilityEvent(event);
     }
 
     @Override
     public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
         super.onInitializeAccessibilityEvent(event);
-        event.setClassName(TimePicker.class.getName());
+        mDelegate.onInitializeAccessibilityEvent(event);
     }
 
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
-        info.setClassName(TimePicker.class.getName());
+        mDelegate.onInitializeAccessibilityNodeInfo(info);
     }
 
-    private void updateHourControl() {
-        if (is24HourView()) {
-            // 'k' means 1-24 hour
-            if (mHourFormat == 'k') {
-                mHourSpinner.setMinValue(1);
-                mHourSpinner.setMaxValue(24);
-            } else {
-                mHourSpinner.setMinValue(0);
-                mHourSpinner.setMaxValue(23);
+    /**
+     * A delegate interface that defined the public API of the TimePicker. Allows different
+     * TimePicker implementations. This would need to be implemented by the TimePicker delegates
+     * for the real behavior.
+     */
+    interface TimePickerDelegate {
+        void setCurrentHour(Integer currentHour);
+        Integer getCurrentHour();
+
+        void setCurrentMinute(Integer currentMinute);
+        Integer getCurrentMinute();
+
+        void setIs24HourView(Boolean is24HourView);
+        boolean is24HourView();
+
+        void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
+
+        void setEnabled(boolean enabled);
+        boolean isEnabled();
+
+        void setShowDoneButton(boolean showDoneButton);
+        void setDismissCallback(TimePickerDismissCallback callback);
+
+        int getBaseline();
+
+        void onConfigurationChanged(Configuration newConfig);
+
+        Parcelable onSaveInstanceState(Parcelable superState);
+        void onRestoreInstanceState(Parcelable state);
+
+        boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onPopulateAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityEvent(AccessibilityEvent event);
+        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info);
+    }
+
+    /**
+     * A callback interface for dismissing the TimePicker when included into a Dialog
+     *
+     * @hide
+     */
+    public static interface TimePickerDismissCallback {
+        void dismiss(TimePicker view, boolean isCancel, int hourOfDay, int minute);
+    }
+
+    /**
+     * An abstract class which can be used as a start for TimePicker implementations
+     */
+    abstract static class AbstractTimePickerDelegate implements TimePickerDelegate {
+        // The delegator
+        protected TimePicker mDelegator;
+
+        // The context
+        protected Context mContext;
+
+        // The current locale
+        protected Locale mCurrentLocale;
+
+        // Callbacks
+        protected  OnTimeChangedListener mOnTimeChangedListener;
+
+        public AbstractTimePickerDelegate(TimePicker delegator, Context context) {
+            mDelegator = delegator;
+            mContext = context;
+
+            // initialization based on locale
+            setCurrentLocale(Locale.getDefault());
+        }
+
+        public void setCurrentLocale(Locale locale) {
+            if (locale.equals(mCurrentLocale)) {
+                return;
             }
-        } else {
-            // '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() {
-        if (is24HourView()) {
-            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
-        } else {
-            mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT);
-        }
-    }
-
-    private void updateAmPmControl() {
-        if (is24HourView()) {
-            if (mAmPmSpinner != null) {
-                mAmPmSpinner.setVisibility(View.GONE);
-            } else {
-                mAmPmButton.setVisibility(View.GONE);
-            }
-        } else {
-            int index = mIsAm ? Calendar.AM : Calendar.PM;
-            if (mAmPmSpinner != null) {
-                mAmPmSpinner.setValue(index);
-                mAmPmSpinner.setVisibility(View.VISIBLE);
-            } else {
-                mAmPmButton.setText(mAmPmStrings[index]);
-                mAmPmButton.setVisibility(View.VISIBLE);
-            }
-        }
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-    }
-
-    private void onTimeChanged() {
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-        if (mOnTimeChangedListener != null) {
-            mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute());
-        }
-    }
-
-    private void setContentDescriptions() {
-        // Minute
-        trySetContentDescription(mMinuteSpinner, R.id.increment,
-                R.string.time_picker_increment_minute_button);
-        trySetContentDescription(mMinuteSpinner, R.id.decrement,
-                R.string.time_picker_decrement_minute_button);
-        // Hour
-        trySetContentDescription(mHourSpinner, R.id.increment,
-                R.string.time_picker_increment_hour_button);
-        trySetContentDescription(mHourSpinner, R.id.decrement,
-                R.string.time_picker_decrement_hour_button);
-        // AM/PM
-        if (mAmPmSpinner != null) {
-            trySetContentDescription(mAmPmSpinner, R.id.increment,
-                    R.string.time_picker_increment_set_pm_button);
-            trySetContentDescription(mAmPmSpinner, R.id.decrement,
-                    R.string.time_picker_decrement_set_am_button);
-        }
-    }
-
-    private void trySetContentDescription(View root, int viewId, int contDescResId) {
-        View target = root.findViewById(viewId);
-        if (target != null) {
-            target.setContentDescription(mContext.getString(contDescResId));
-        }
-    }
-
-    private void updateInputState() {
-        // Make sure that if the user changes the value and the IME is active
-        // for one of the inputs if this widget, the IME is closed. If the user
-        // changed the value via the IME and there is a next input the IME will
-        // be shown, otherwise the user chose another means of changing the
-        // value and having the IME up makes no sense.
-        InputMethodManager inputMethodManager = InputMethodManager.peekInstance();
-        if (inputMethodManager != null) {
-            if (inputMethodManager.isActive(mHourSpinnerInput)) {
-                mHourSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) {
-                mMinuteSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) {
-                mAmPmSpinnerInput.clearFocus();
-                inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
-            }
+            mCurrentLocale = locale;
         }
     }
 }
diff --git a/core/java/android/widget/TimePickerDelegate.java b/core/java/android/widget/TimePickerDelegate.java
new file mode 100644
index 0000000..c9a9894
--- /dev/null
+++ b/core/java/android/widget/TimePickerDelegate.java
@@ -0,0 +1,1401 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget;
+
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.text.format.DateUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+import com.android.internal.R;
+
+import java.text.DateFormatSymbols;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Locale;
+
+/**
+ * A view for selecting the time of day, in either 24 hour or AM/PM mode.
+ */
+class TimePickerDelegate extends TimePicker.AbstractTimePickerDelegate implements
+        RadialTimePickerView.OnValueSelectedListener {
+
+    private static final String TAG = "TimePickerDelegate";
+
+    // Index used by RadialPickerLayout
+    private static final int HOUR_INDEX = 0;
+    private static final int MINUTE_INDEX = 1;
+
+    // NOT a real index for the purpose of what's showing.
+    private static final int AMPM_INDEX = 2;
+
+    // Also NOT a real index, just used for keyboard mode.
+    private static final int ENABLE_PICKER_INDEX = 3;
+
+    private static final int AM = 0;
+    private static final int PM = 1;
+
+    private static final boolean DEFAULT_ENABLED_STATE = true;
+    private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
+
+    private static final int HOURS_IN_HALF_DAY = 12;
+
+    // Delay in ms before starting the pulse animation
+    private static final int PULSE_ANIMATOR_DELAY = 300;
+
+    // Duration in ms of the pulse animation
+    private static final int PULSE_ANIMATOR_DURATION = 544;
+
+    private static int[] TEXT_APPEARANCE_TIME_LABEL_ATTR =
+            new int[] { R.attr.timePickerHeaderTimeLabelTextAppearance };
+
+    private final View mMainView;
+    private TextView mHourView;
+    private TextView mMinuteView;
+    private TextView mAmPmTextView;
+    private RadialTimePickerView mRadialTimePickerView;
+    private TextView mSeparatorView;
+
+    private ViewGroup mLayoutButtons;
+
+    private int mHeaderSelectedColor;
+    private int mHeaderUnSelectedColor;
+    private String mAmText;
+    private String mPmText;
+
+    private boolean mAllowAutoAdvance;
+    private int mInitialHourOfDay;
+    private int mInitialMinute;
+    private boolean mIs24HourView;
+
+    // For hardware IME input.
+    private char mPlaceholderText;
+    private String mDoublePlaceholderText;
+    private String mDeletedKeyFormat;
+    private boolean mInKbMode;
+    private ArrayList<Integer> mTypedTimes = new ArrayList<Integer>();
+    private Node mLegalTimesTree;
+    private int mAmKeyCode;
+    private int mPmKeyCode;
+
+    // For showing the done button when in a Dialog
+    private Button mDoneButton;
+    private boolean mShowDoneButton;
+    private TimePicker.TimePickerDismissCallback mDismissCallback;
+
+    // Accessibility strings.
+    private String mHourPickerDescription;
+    private String mSelectHours;
+    private String mMinutePickerDescription;
+    private String mSelectMinutes;
+
+    private Calendar mTempCalendar;
+
+    public TimePickerDelegate(TimePicker delegator, Context context, AttributeSet attrs,
+                              int defStyleAttr, int defStyleRes) {
+        super(delegator, context);
+
+        // process style attributes
+        final TypedArray a = mContext.obtainStyledAttributes(attrs,
+                R.styleable.TimePicker, defStyleAttr, defStyleRes);
+
+        final Resources res = mContext.getResources();
+
+        mHourPickerDescription = res.getString(R.string.hour_picker_description);
+        mSelectHours = res.getString(R.string.select_hours);
+        mMinutePickerDescription = res.getString(R.string.minute_picker_description);
+        mSelectMinutes = res.getString(R.string.select_minutes);
+
+        mHeaderSelectedColor = a.getColor(R.styleable.TimePicker_headerSelectedTextColor,
+                android.R.color.holo_blue_light);
+
+        mHeaderUnSelectedColor = getUnselectedColor(
+                R.color.timepicker_default_text_color_holo_light);
+        if (mHeaderUnSelectedColor == -1) {
+            mHeaderUnSelectedColor = a.getColor(R.styleable.TimePicker_headerUnselectedTextColor,
+                    R.color.timepicker_default_text_color_holo_light);
+        }
+
+        final int headerBackgroundColor = a.getColor(
+                R.styleable.TimePicker_headerBackgroundColor, 0);
+
+        a.recycle();
+
+        final int layoutResourceId = a.getResourceId(
+                R.styleable.TimePicker_internalLayout, R.layout.time_picker_holo);
+
+        final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+
+        mMainView = inflater.inflate(layoutResourceId, null);
+        mDelegator.addView(mMainView);
+
+        if (headerBackgroundColor != 0) {
+            RelativeLayout header = (RelativeLayout) mMainView.findViewById(R.id.time_header);
+            header.setBackgroundColor(headerBackgroundColor);
+        }
+
+        mHourView = (TextView) mMainView.findViewById(R.id.hours);
+        mMinuteView = (TextView) mMainView.findViewById(R.id.minutes);
+        mAmPmTextView = (TextView) mMainView.findViewById(R.id.ampm_label);
+        mSeparatorView = (TextView) mMainView.findViewById(R.id.separator);
+        mRadialTimePickerView = (RadialTimePickerView) mMainView.findViewById(R.id.radial_picker);
+
+        mLayoutButtons = (ViewGroup) mMainView.findViewById(R.id.layout_buttons);
+        mDoneButton = (Button) mMainView.findViewById(R.id.done_button);
+
+        String[] amPmTexts = new DateFormatSymbols().getAmPmStrings();
+        mAmText = amPmTexts[0];
+        mPmText = amPmTexts[1];
+
+        setupListeners();
+
+        mAllowAutoAdvance = true;
+
+        // Set up for keyboard mode.
+        mDoublePlaceholderText = res.getString(R.string.time_placeholder);
+        mDeletedKeyFormat = res.getString(R.string.deleted_key);
+        mPlaceholderText = mDoublePlaceholderText.charAt(0);
+        mAmKeyCode = mPmKeyCode = -1;
+        generateLegalTimesTree();
+
+        // Initialize with current time
+        final Calendar calendar = Calendar.getInstance(mCurrentLocale);
+        final int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
+        final int currentMinute = calendar.get(Calendar.MINUTE);
+        initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX, false);
+    }
+
+    private int getUnselectedColor(int defColor) {
+        int result = -1;
+        final Resources.Theme theme = mContext.getTheme();
+        final TypedValue outValue = new TypedValue();
+        theme.resolveAttribute(R.attr.timePickerHeaderTimeLabelTextAppearance, outValue, true);
+        final int appearanceResId = outValue.resourceId;
+        TypedArray appearance = null;
+        if (appearanceResId != -1) {
+            appearance = theme.obtainStyledAttributes(appearanceResId,
+                    com.android.internal.R.styleable.TextAppearance);
+        }
+        if (appearance != null) {
+            result = appearance.getColor(
+                    com.android.internal.R.styleable.TextAppearance_textColor, defColor);
+            appearance.recycle();
+        }
+        return result;
+    }
+
+    private void initialize(int hourOfDay, int minute, boolean is24HourView, int index,
+                            boolean showDoneButton) {
+        mInitialHourOfDay = hourOfDay;
+        mInitialMinute = minute;
+        mIs24HourView = is24HourView;
+        mInKbMode = false;
+        mShowDoneButton = showDoneButton;
+        updateUI(index);
+    }
+
+    private void setupListeners() {
+        KeyboardListener keyboardListener = new KeyboardListener();
+        mDelegator.setOnKeyListener(keyboardListener);
+
+        mHourView.setOnKeyListener(keyboardListener);
+        mMinuteView.setOnKeyListener(keyboardListener);
+        mAmPmTextView.setOnKeyListener(keyboardListener);
+        mRadialTimePickerView.setOnValueSelectedListener(this);
+        mRadialTimePickerView.setOnKeyListener(keyboardListener);
+
+        mHourView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setCurrentItemShowing(HOUR_INDEX, true, false, true);
+                tryVibrate();
+            }
+        });
+        mMinuteView.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                setCurrentItemShowing(MINUTE_INDEX, true, false, true);
+                tryVibrate();
+            }
+        });
+        mDoneButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mInKbMode && isTypedTimeFullyLegal()) {
+                    finishKbMode(false);
+                } else {
+                    tryVibrate();
+                }
+                if (mDismissCallback != null) {
+                    mDismissCallback.dismiss(mDelegator, false, getCurrentHour(),
+                            getCurrentMinute());
+                }
+            }
+        });
+        mDoneButton.setOnKeyListener(keyboardListener);
+    }
+
+    private void updateUI(int index) {
+        // Update RadialPicker values
+        updateRadialPicker(index);
+        // Enable or disable the AM/PM view.
+        updateHeaderAmPm();
+        // Show or hide Done button
+        updateDoneButton();
+        // Update Hour and Minutes
+        updateHeaderHour(mInitialHourOfDay, true);
+        // Update time separator
+        updateHeaderSeparator();
+        // Update Minutes
+        updateHeaderMinute(mInitialMinute);
+        // Invalidate everything
+        mDelegator.invalidate();
+    }
+
+    private void updateRadialPicker(int index) {
+        mRadialTimePickerView.initialize(mInitialHourOfDay, mInitialMinute, mIs24HourView);
+        setCurrentItemShowing(index, false, true, true);
+    }
+
+    private int computeMaxWidthOfNumbers(int max) {
+        TextView tempView = new TextView(mContext);
+        TypedArray a = mContext.obtainStyledAttributes(TEXT_APPEARANCE_TIME_LABEL_ATTR);
+        final int textAppearanceResId = a.getResourceId(0, 0);
+        tempView.setTextAppearance(mContext, (textAppearanceResId != 0) ?
+                textAppearanceResId : R.style.TextAppearance_Holo_TimePicker_TimeLabel);
+        a.recycle();
+        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+        tempView.setLayoutParams(lp);
+        int maxWidth = 0;
+        for (int minutes = 0; minutes < max; minutes++) {
+            final String text = String.format("%02d", minutes);
+            tempView.setText(text);
+            tempView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+            maxWidth = Math.max(maxWidth, tempView.getMeasuredWidth());
+        }
+        return maxWidth;
+    }
+
+    private void updateHeaderAmPm() {
+        if (mIs24HourView) {
+            mAmPmTextView.setVisibility(View.GONE);
+        } else {
+            mAmPmTextView.setVisibility(View.VISIBLE);
+            final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                    "hm");
+
+            boolean amPmOnLeft = bestDateTimePattern.startsWith("a");
+            if (TextUtils.getLayoutDirectionFromLocale(mCurrentLocale) ==
+                    View.LAYOUT_DIRECTION_RTL) {
+                amPmOnLeft = !amPmOnLeft;
+            }
+
+            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams)
+                    mAmPmTextView.getLayoutParams();
+
+            if (amPmOnLeft) {
+                layoutParams.rightMargin = computeMaxWidthOfNumbers(12 /* for hours */);
+                layoutParams.removeRule(RelativeLayout.RIGHT_OF);
+                layoutParams.addRule(RelativeLayout.LEFT_OF, R.id.separator);
+            } else {
+                layoutParams.leftMargin = computeMaxWidthOfNumbers(60 /* for minutes */);
+                layoutParams.removeRule(RelativeLayout.LEFT_OF);
+                layoutParams.addRule(RelativeLayout.RIGHT_OF, R.id.separator);
+            }
+
+            updateAmPmDisplay(mInitialHourOfDay < 12 ? AM : PM);
+            mAmPmTextView.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    tryVibrate();
+                    int amOrPm = mRadialTimePickerView.getAmOrPm();
+                    if (amOrPm == AM) {
+                        amOrPm = PM;
+                    } else if (amOrPm == PM){
+                        amOrPm = AM;
+                    }
+                    updateAmPmDisplay(amOrPm);
+                    mRadialTimePickerView.setAmOrPm(amOrPm);
+                }
+            });
+        }
+    }
+
+    private void updateDoneButton() {
+        mLayoutButtons.setVisibility(mShowDoneButton ? View.VISIBLE : View.GONE);
+    }
+
+    /**
+     * Set the current hour.
+     */
+    @Override
+    public void setCurrentHour(Integer currentHour) {
+        if (mInitialHourOfDay == currentHour) {
+            return;
+        }
+        mInitialHourOfDay = currentHour;
+        updateHeaderHour(currentHour, true /* accessibility announce */);
+        updateHeaderAmPm();
+        mRadialTimePickerView.setCurrentHour(currentHour);
+        mRadialTimePickerView.setAmOrPm(mInitialHourOfDay < 12 ? AM : PM);
+        mDelegator.invalidate();
+        onTimeChanged();
+    }
+
+    /**
+     * @return The current hour in the range (0-23).
+     */
+    @Override
+    public Integer getCurrentHour() {
+        int currentHour = mRadialTimePickerView.getCurrentHour();
+        if (mIs24HourView) {
+            return currentHour;
+        } else {
+            switch(mRadialTimePickerView.getAmOrPm()) {
+                case PM:
+                    return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY;
+                case AM:
+                default:
+                    return currentHour % HOURS_IN_HALF_DAY;
+            }
+        }
+    }
+
+    /**
+     * Set the current minute (0-59).
+     */
+    @Override
+    public void setCurrentMinute(Integer currentMinute) {
+        if (mInitialMinute == currentMinute) {
+            return;
+        }
+        mInitialMinute = currentMinute;
+        updateHeaderMinute(currentMinute);
+        mRadialTimePickerView.setCurrentMinute(currentMinute);
+        mDelegator.invalidate();
+        onTimeChanged();
+    }
+
+    /**
+     * @return The current minute.
+     */
+    @Override
+    public Integer getCurrentMinute() {
+        return mRadialTimePickerView.getCurrentMinute();
+    }
+
+    /**
+     * Set whether in 24 hour or AM/PM mode.
+     *
+     * @param is24HourView True = 24 hour mode. False = AM/PM.
+     */
+    @Override
+    public void setIs24HourView(Boolean is24HourView) {
+        if (is24HourView == mIs24HourView) {
+            return;
+        }
+        mIs24HourView = is24HourView;
+        generateLegalTimesTree();
+        int hour = mRadialTimePickerView.getCurrentHour();
+        mInitialHourOfDay = hour;
+        updateHeaderHour(hour, false /* no accessibility announce */);
+        updateHeaderAmPm();
+        updateRadialPicker(mRadialTimePickerView.getCurrentItemShowing());
+        mDelegator.invalidate();
+    }
+
+    /**
+     * @return true if this is in 24 hour view else false.
+     */
+    @Override
+    public boolean is24HourView() {
+        return mIs24HourView;
+    }
+
+    @Override
+    public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener callback) {
+        mOnTimeChangedListener = callback;
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        mHourView.setEnabled(enabled);
+        mMinuteView.setEnabled(enabled);
+        mAmPmTextView.setEnabled(enabled);
+        mRadialTimePickerView.setEnabled(enabled);
+        mIsEnabled = enabled;
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return mIsEnabled;
+    }
+
+    @Override
+    public void setShowDoneButton(boolean showDoneButton) {
+        mShowDoneButton = showDoneButton;
+        updateDoneButton();
+    }
+
+    @Override
+    public void setDismissCallback(TimePicker.TimePickerDismissCallback callback) {
+        mDismissCallback = callback;
+    }
+
+    @Override
+    public int getBaseline() {
+        // does not support baseline alignment
+        return -1;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        updateUI(mRadialTimePickerView.getCurrentItemShowing());
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState(Parcelable superState) {
+        return new SavedState(superState, getCurrentHour(), getCurrentMinute(),
+                is24HourView(), inKbMode(), getTypedTimes(), getCurrentItemShowing(),
+                isShowDoneButton());
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        SavedState ss = (SavedState) state;
+        setInKbMode(ss.inKbMode());
+        setTypedTimes(ss.getTypesTimes());
+        initialize(ss.getHour(), ss.getMinute(), ss.is24HourMode(), ss.getCurrentItemShowing(),
+                ss.isShowDoneButton());
+        mRadialTimePickerView.invalidate();
+        if (mInKbMode) {
+            tryStartingKbMode(-1);
+            mHourView.invalidate();
+        }
+    }
+
+    @Override
+    public void setCurrentLocale(Locale locale) {
+        super.setCurrentLocale(locale);
+        mTempCalendar = Calendar.getInstance(locale);
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        onPopulateAccessibilityEvent(event);
+        return true;
+    }
+
+    @Override
+    public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
+        int flags = DateUtils.FORMAT_SHOW_TIME;
+        if (mIs24HourView) {
+            flags |= DateUtils.FORMAT_24HOUR;
+        } else {
+            flags |= DateUtils.FORMAT_12HOUR;
+        }
+        mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour());
+        mTempCalendar.set(Calendar.MINUTE, getCurrentMinute());
+        String selectedDate = DateUtils.formatDateTime(mContext,
+                mTempCalendar.getTimeInMillis(), flags);
+        event.getText().add(selectedDate);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        event.setClassName(TimePicker.class.getName());
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        info.setClassName(TimePicker.class.getName());
+    }
+
+    /**
+     * Set whether in keyboard mode or not.
+     *
+     * @param inKbMode True means in keyboard mode.
+     */
+    private void setInKbMode(boolean inKbMode) {
+        mInKbMode = inKbMode;
+    }
+
+    /**
+     * @return true if in keyboard mode
+     */
+    private boolean inKbMode() {
+        return mInKbMode;
+    }
+
+    private void setTypedTimes(ArrayList<Integer> typeTimes) {
+        mTypedTimes = typeTimes;
+    }
+
+    /**
+     * @return an array of typed times
+     */
+    private ArrayList<Integer> getTypedTimes() {
+        return mTypedTimes;
+    }
+
+    /**
+     * @return the index of the current item showing
+     */
+    private int getCurrentItemShowing() {
+        return mRadialTimePickerView.getCurrentItemShowing();
+    }
+
+    private boolean isShowDoneButton() {
+        return mShowDoneButton;
+    }
+
+    /**
+     * Propagate the time change
+     */
+    private void onTimeChanged() {
+        mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
+        if (mOnTimeChangedListener != null) {
+            mOnTimeChangedListener.onTimeChanged(mDelegator,
+                    getCurrentHour(), getCurrentMinute());
+        }
+    }
+
+    /**
+     * Used to save / restore state of time picker
+     */
+    private static class SavedState extends View.BaseSavedState {
+
+        private final int mHour;
+        private final int mMinute;
+        private final boolean mIs24HourMode;
+        private final boolean mInKbMode;
+        private final ArrayList<Integer> mTypedTimes;
+        private final int mCurrentItemShowing;
+        private final boolean mShowDoneButton;
+
+        private SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode,
+                           boolean isKbMode, ArrayList<Integer> typedTimes,
+                           int currentItemShowing, boolean showDoneButton) {
+            super(superState);
+            mHour = hour;
+            mMinute = minute;
+            mIs24HourMode = is24HourMode;
+            mInKbMode = isKbMode;
+            mTypedTimes = typedTimes;
+            mCurrentItemShowing = currentItemShowing;
+            mShowDoneButton = showDoneButton;
+        }
+
+        private SavedState(Parcel in) {
+            super(in);
+            mHour = in.readInt();
+            mMinute = in.readInt();
+            mIs24HourMode = (in.readInt() == 1);
+            mInKbMode = (in.readInt() == 1);
+            mTypedTimes = in.readArrayList(getClass().getClassLoader());
+            mCurrentItemShowing = in.readInt();
+            mShowDoneButton = (in.readInt() == 1);
+        }
+
+        public int getHour() {
+            return mHour;
+        }
+
+        public int getMinute() {
+            return mMinute;
+        }
+
+        public boolean is24HourMode() {
+            return mIs24HourMode;
+        }
+
+        public boolean inKbMode() {
+            return mInKbMode;
+        }
+
+        public ArrayList<Integer> getTypesTimes() {
+            return mTypedTimes;
+        }
+
+        public int getCurrentItemShowing() {
+            return mCurrentItemShowing;
+        }
+
+        public boolean isShowDoneButton() {
+            return mShowDoneButton;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeInt(mHour);
+            dest.writeInt(mMinute);
+            dest.writeInt(mIs24HourMode ? 1 : 0);
+            dest.writeInt(mInKbMode ? 1 : 0);
+            dest.writeList(mTypedTimes);
+            dest.writeInt(mCurrentItemShowing);
+            dest.writeInt(mShowDoneButton ? 1 : 0);
+        }
+
+        @SuppressWarnings({"unused", "hiding"})
+        public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+
+    private void tryVibrate() {
+        mDelegator.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
+    }
+
+    private void updateAmPmDisplay(int amOrPm) {
+        if (amOrPm == AM) {
+            mAmPmTextView.setText(mAmText);
+            mRadialTimePickerView.announceForAccessibility(mAmText);
+        } else if (amOrPm == PM){
+            mAmPmTextView.setText(mPmText);
+            mRadialTimePickerView.announceForAccessibility(mPmText);
+        } else {
+            mAmPmTextView.setText(mDoublePlaceholderText);
+        }
+    }
+
+    /**
+     * Called by the picker for updating the header display.
+     */
+    @Override
+    public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) {
+        if (pickerIndex == HOUR_INDEX) {
+            updateHeaderHour(newValue, false);
+            String announcement = String.format("%d", newValue);
+            if (mAllowAutoAdvance && autoAdvance) {
+                setCurrentItemShowing(MINUTE_INDEX, true, true, false);
+                announcement += ". " + mSelectMinutes;
+            } else {
+                mRadialTimePickerView.setContentDescription(
+                        mHourPickerDescription + ": " + newValue);
+            }
+
+            mRadialTimePickerView.announceForAccessibility(announcement);
+        } else if (pickerIndex == MINUTE_INDEX){
+            updateHeaderMinute(newValue);
+            mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + newValue);
+        } else if (pickerIndex == AMPM_INDEX) {
+            updateAmPmDisplay(newValue);
+        } else if (pickerIndex == ENABLE_PICKER_INDEX) {
+            if (!isTypedTimeFullyLegal()) {
+                mTypedTimes.clear();
+            }
+            finishKbMode(true);
+        }
+    }
+
+    private void updateHeaderHour(int value, boolean announce) {
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                (mIs24HourView) ? "Hm" : "hm");
+        final int lengthPattern = bestDateTimePattern.length();
+        boolean hourWithTwoDigit = 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') {
+                hourFormat = c;
+                if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) {
+                    hourWithTwoDigit = true;
+                }
+                break;
+            }
+        }
+        final String format;
+        if (hourWithTwoDigit) {
+            format = "%02d";
+        } else {
+            format = "%d";
+        }
+        if (mIs24HourView) {
+            // 'k' means 1-24 hour
+            if (hourFormat == 'k' && value == 0) {
+                value = 24;
+            }
+        } else {
+            // 'K' means 0-11 hour
+            value = modulo12(value, hourFormat == 'K');
+        }
+        CharSequence text = String.format(format, value);
+        mHourView.setText(text);
+        if (announce) {
+            mRadialTimePickerView.announceForAccessibility(text);
+        }
+    }
+
+    private static int modulo12(int n, boolean startWithZero) {
+        int value = n % 12;
+        if (value == 0 && !startWithZero) {
+            value = 12;
+        }
+        return value;
+    }
+
+    /**
+     * 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 updateHeaderSeparator() {
+        final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale,
+                (mIs24HourView) ? "Hm" : "hm");
+        final String separatorText;
+        // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats
+        final char[] hourFormats = {'H', 'h', 'K', 'k'};
+        int hIndex = lastIndexOfAny(bestDateTimePattern, hourFormats);
+        if (hIndex == -1) {
+            // Default case
+            separatorText = ":";
+        } else {
+            separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1));
+        }
+        mSeparatorView.setText(separatorText);
+    }
+
+    static private int lastIndexOfAny(String str, char[] any) {
+        final int lengthAny = any.length;
+        if (lengthAny > 0) {
+            for (int i = str.length() - 1; i >= 0; i--) {
+                char c = str.charAt(i);
+                for (int j = 0; j < lengthAny; j++) {
+                    if (c == any[j]) {
+                        return i;
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
+    private void updateHeaderMinute(int value) {
+        if (value == 60) {
+            value = 0;
+        }
+        CharSequence text = String.format(mCurrentLocale, "%02d", value);
+        mRadialTimePickerView.announceForAccessibility(text);
+        mMinuteView.setText(text);
+    }
+
+    /**
+     * Show either Hours or Minutes.
+     */
+    private void setCurrentItemShowing(int index, boolean animateCircle, boolean delayLabelAnimate,
+                                       boolean announce) {
+        mRadialTimePickerView.setCurrentItemShowing(index, animateCircle);
+
+        TextView labelToAnimate;
+        if (index == HOUR_INDEX) {
+            int hours = mRadialTimePickerView.getCurrentHour();
+            if (!mIs24HourView) {
+                hours = hours % 12;
+            }
+            mRadialTimePickerView.setContentDescription(mHourPickerDescription + ": " + hours);
+            if (announce) {
+                mRadialTimePickerView.announceForAccessibility(mSelectHours);
+            }
+            labelToAnimate = mHourView;
+        } else {
+            int minutes = mRadialTimePickerView.getCurrentMinute();
+            mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + minutes);
+            if (announce) {
+                mRadialTimePickerView.announceForAccessibility(mSelectMinutes);
+            }
+            labelToAnimate = mMinuteView;
+        }
+
+        int hourColor = (index == HOUR_INDEX) ? mHeaderSelectedColor : mHeaderUnSelectedColor;
+        int minuteColor = (index == MINUTE_INDEX) ? mHeaderSelectedColor : mHeaderUnSelectedColor;
+        mHourView.setTextColor(hourColor);
+        mMinuteView.setTextColor(minuteColor);
+
+        ObjectAnimator pulseAnimator = getPulseAnimator(labelToAnimate, 0.85f, 1.1f);
+        if (delayLabelAnimate) {
+            pulseAnimator.setStartDelay(PULSE_ANIMATOR_DELAY);
+        }
+        pulseAnimator.start();
+    }
+
+    /**
+     * For keyboard mode, processes key events.
+     *
+     * @param keyCode the pressed key.
+     *
+     * @return true if the key was successfully processed, false otherwise.
+     */
+    private boolean processKeyUp(int keyCode) {
+        if (keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_BACK) {
+            if (mDismissCallback != null) {
+                mDismissCallback.dismiss(mDelegator, true, getCurrentHour(), getCurrentMinute());
+            }
+            return true;
+        } else if (keyCode == KeyEvent.KEYCODE_TAB) {
+            if(mInKbMode) {
+                if (isTypedTimeFullyLegal()) {
+                    finishKbMode(true);
+                }
+                return true;
+            }
+        } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
+            if (mInKbMode) {
+                if (!isTypedTimeFullyLegal()) {
+                    return true;
+                }
+                finishKbMode(false);
+            }
+            if (mOnTimeChangedListener != null) {
+                mOnTimeChangedListener.onTimeChanged(mDelegator,
+                        mRadialTimePickerView.getCurrentHour(),
+                        mRadialTimePickerView.getCurrentMinute());
+            }
+            if (mDismissCallback != null) {
+                mDismissCallback.dismiss(mDelegator, false, getCurrentHour(), getCurrentMinute());
+            }
+            return true;
+        } else if (keyCode == KeyEvent.KEYCODE_DEL) {
+            if (mInKbMode) {
+                if (!mTypedTimes.isEmpty()) {
+                    int deleted = deleteLastTypedKey();
+                    String deletedKeyStr;
+                    if (deleted == getAmOrPmKeyCode(AM)) {
+                        deletedKeyStr = mAmText;
+                    } else if (deleted == getAmOrPmKeyCode(PM)) {
+                        deletedKeyStr = mPmText;
+                    } else {
+                        deletedKeyStr = String.format("%d", getValFromKeyCode(deleted));
+                    }
+                    mRadialTimePickerView.announceForAccessibility(
+                            String.format(mDeletedKeyFormat, deletedKeyStr));
+                    updateDisplay(true);
+                }
+            }
+        } else if (keyCode == KeyEvent.KEYCODE_0 || keyCode == KeyEvent.KEYCODE_1
+                || keyCode == KeyEvent.KEYCODE_2 || keyCode == KeyEvent.KEYCODE_3
+                || keyCode == KeyEvent.KEYCODE_4 || keyCode == KeyEvent.KEYCODE_5
+                || keyCode == KeyEvent.KEYCODE_6 || keyCode == KeyEvent.KEYCODE_7
+                || keyCode == KeyEvent.KEYCODE_8 || keyCode == KeyEvent.KEYCODE_9
+                || (!mIs24HourView &&
+                (keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) {
+            if (!mInKbMode) {
+                if (mRadialTimePickerView == null) {
+                    // Something's wrong, because time picker should definitely not be null.
+                    Log.e(TAG, "Unable to initiate keyboard mode, TimePicker was null.");
+                    return true;
+                }
+                mTypedTimes.clear();
+                tryStartingKbMode(keyCode);
+                return true;
+            }
+            // We're already in keyboard mode.
+            if (addKeyIfLegal(keyCode)) {
+                updateDisplay(false);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Try to start keyboard mode with the specified key.
+     *
+     * @param keyCode The key to use as the first press. Keyboard mode will not be started if the
+     * key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting
+     * key.
+     */
+    private void tryStartingKbMode(int keyCode) {
+        if (keyCode == -1 || addKeyIfLegal(keyCode)) {
+            mInKbMode = true;
+            mDoneButton.setEnabled(false);
+            updateDisplay(false);
+            mRadialTimePickerView.setInputEnabled(false);
+        }
+    }
+
+    private boolean addKeyIfLegal(int keyCode) {
+        // If we're in 24hour mode, we'll need to check if the input is full. If in AM/PM mode,
+        // we'll need to see if AM/PM have been typed.
+        if ((mIs24HourView && mTypedTimes.size() == 4) ||
+                (!mIs24HourView && isTypedTimeFullyLegal())) {
+            return false;
+        }
+
+        mTypedTimes.add(keyCode);
+        if (!isTypedTimeLegalSoFar()) {
+            deleteLastTypedKey();
+            return false;
+        }
+
+        int val = getValFromKeyCode(keyCode);
+        mRadialTimePickerView.announceForAccessibility(String.format("%d", val));
+        // Automatically fill in 0's if AM or PM was legally entered.
+        if (isTypedTimeFullyLegal()) {
+            if (!mIs24HourView && mTypedTimes.size() <= 3) {
+                mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0);
+                mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0);
+            }
+            mDoneButton.setEnabled(true);
+        }
+
+        return true;
+    }
+
+    /**
+     * Traverse the tree to see if the keys that have been typed so far are legal as is,
+     * or may become legal as more keys are typed (excluding backspace).
+     */
+    private boolean isTypedTimeLegalSoFar() {
+        Node node = mLegalTimesTree;
+        for (int keyCode : mTypedTimes) {
+            node = node.canReach(keyCode);
+            if (node == null) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Check if the time that has been typed so far is completely legal, as is.
+     */
+    private boolean isTypedTimeFullyLegal() {
+        if (mIs24HourView) {
+            // For 24-hour mode, the time is legal if the hours and minutes are each legal. Note:
+            // getEnteredTime() will ONLY call isTypedTimeFullyLegal() when NOT in 24hour mode.
+            int[] values = getEnteredTime(null);
+            return (values[0] >= 0 && values[1] >= 0 && values[1] < 60);
+        } else {
+            // For AM/PM mode, the time is legal if it contains an AM or PM, as those can only be
+            // legally added at specific times based on the tree's algorithm.
+            return (mTypedTimes.contains(getAmOrPmKeyCode(AM)) ||
+                    mTypedTimes.contains(getAmOrPmKeyCode(PM)));
+        }
+    }
+
+    private int deleteLastTypedKey() {
+        int deleted = mTypedTimes.remove(mTypedTimes.size() - 1);
+        if (!isTypedTimeFullyLegal()) {
+            mDoneButton.setEnabled(false);
+        }
+        return deleted;
+    }
+
+    /**
+     * Get out of keyboard mode. If there is nothing in typedTimes, revert to TimePicker's time.
+     * @param updateDisplays If true, update the displays with the relevant time.
+     */
+    private void finishKbMode(boolean updateDisplays) {
+        mInKbMode = false;
+        if (!mTypedTimes.isEmpty()) {
+            int values[] = getEnteredTime(null);
+            mRadialTimePickerView.setCurrentHour(values[0]);
+            mRadialTimePickerView.setCurrentMinute(values[1]);
+            if (!mIs24HourView) {
+                mRadialTimePickerView.setAmOrPm(values[2]);
+            }
+            mTypedTimes.clear();
+        }
+        if (updateDisplays) {
+            updateDisplay(false);
+            mRadialTimePickerView.setInputEnabled(true);
+        }
+    }
+
+    /**
+     * Update the hours, minutes, and AM/PM displays with the typed times. If the typedTimes is
+     * empty, either show an empty display (filled with the placeholder text), or update from the
+     * timepicker's values.
+     *
+     * @param allowEmptyDisplay if true, then if the typedTimes is empty, use the placeholder text.
+     * Otherwise, revert to the timepicker's values.
+     */
+    private void updateDisplay(boolean allowEmptyDisplay) {
+        if (!allowEmptyDisplay && mTypedTimes.isEmpty()) {
+            int hour = mRadialTimePickerView.getCurrentHour();
+            int minute = mRadialTimePickerView.getCurrentMinute();
+            updateHeaderHour(hour, true);
+            updateHeaderMinute(minute);
+            if (!mIs24HourView) {
+                updateAmPmDisplay(hour < 12 ? AM : PM);
+            }
+            setCurrentItemShowing(mRadialTimePickerView.getCurrentItemShowing(), true, true, true);
+            mDoneButton.setEnabled(true);
+        } else {
+            boolean[] enteredZeros = {false, false};
+            int[] values = getEnteredTime(enteredZeros);
+            String hourFormat = enteredZeros[0] ? "%02d" : "%2d";
+            String minuteFormat = (enteredZeros[1]) ? "%02d" : "%2d";
+            String hourStr = (values[0] == -1) ? mDoublePlaceholderText :
+                    String.format(hourFormat, values[0]).replace(' ', mPlaceholderText);
+            String minuteStr = (values[1] == -1) ? mDoublePlaceholderText :
+                    String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText);
+            mHourView.setText(hourStr);
+            mHourView.setTextColor(mHeaderUnSelectedColor);
+            mMinuteView.setText(minuteStr);
+            mMinuteView.setTextColor(mHeaderUnSelectedColor);
+            if (!mIs24HourView) {
+                updateAmPmDisplay(values[2]);
+            }
+        }
+    }
+
+    private int getValFromKeyCode(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_0:
+                return 0;
+            case KeyEvent.KEYCODE_1:
+                return 1;
+            case KeyEvent.KEYCODE_2:
+                return 2;
+            case KeyEvent.KEYCODE_3:
+                return 3;
+            case KeyEvent.KEYCODE_4:
+                return 4;
+            case KeyEvent.KEYCODE_5:
+                return 5;
+            case KeyEvent.KEYCODE_6:
+                return 6;
+            case KeyEvent.KEYCODE_7:
+                return 7;
+            case KeyEvent.KEYCODE_8:
+                return 8;
+            case KeyEvent.KEYCODE_9:
+                return 9;
+            default:
+                return -1;
+        }
+    }
+
+    /**
+     * Get the currently-entered time, as integer values of the hours and minutes typed.
+     *
+     * @param enteredZeros A size-2 boolean array, which the caller should initialize, and which
+     * may then be used for the caller to know whether zeros had been explicitly entered as either
+     * hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's.
+     *
+     * @return A size-3 int array. The first value will be the hours, the second value will be the
+     * minutes, and the third will be either AM or PM.
+     */
+    private int[] getEnteredTime(boolean[] enteredZeros) {
+        int amOrPm = -1;
+        int startIndex = 1;
+        if (!mIs24HourView && isTypedTimeFullyLegal()) {
+            int keyCode = mTypedTimes.get(mTypedTimes.size() - 1);
+            if (keyCode == getAmOrPmKeyCode(AM)) {
+                amOrPm = AM;
+            } else if (keyCode == getAmOrPmKeyCode(PM)){
+                amOrPm = PM;
+            }
+            startIndex = 2;
+        }
+        int minute = -1;
+        int hour = -1;
+        for (int i = startIndex; i <= mTypedTimes.size(); i++) {
+            int val = getValFromKeyCode(mTypedTimes.get(mTypedTimes.size() - i));
+            if (i == startIndex) {
+                minute = val;
+            } else if (i == startIndex+1) {
+                minute += 10 * val;
+                if (enteredZeros != null && val == 0) {
+                    enteredZeros[1] = true;
+                }
+            } else if (i == startIndex+2) {
+                hour = val;
+            } else if (i == startIndex+3) {
+                hour += 10 * val;
+                if (enteredZeros != null && val == 0) {
+                    enteredZeros[0] = true;
+                }
+            }
+        }
+
+        int[] ret = {hour, minute, amOrPm};
+        return ret;
+    }
+
+    /**
+     * Get the keycode value for AM and PM in the current language.
+     */
+    private int getAmOrPmKeyCode(int amOrPm) {
+        // Cache the codes.
+        if (mAmKeyCode == -1 || mPmKeyCode == -1) {
+            // Find the first character in the AM/PM text that is unique.
+            KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+            char amChar;
+            char pmChar;
+            for (int i = 0; i < Math.max(mAmText.length(), mPmText.length()); i++) {
+                amChar = mAmText.toLowerCase(mCurrentLocale).charAt(i);
+                pmChar = mPmText.toLowerCase(mCurrentLocale).charAt(i);
+                if (amChar != pmChar) {
+                    KeyEvent[] events = kcm.getEvents(new char[]{amChar, pmChar});
+                    // There should be 4 events: a down and up for both AM and PM.
+                    if (events != null && events.length == 4) {
+                        mAmKeyCode = events[0].getKeyCode();
+                        mPmKeyCode = events[2].getKeyCode();
+                    } else {
+                        Log.e(TAG, "Unable to find keycodes for AM and PM.");
+                    }
+                    break;
+                }
+            }
+        }
+        if (amOrPm == AM) {
+            return mAmKeyCode;
+        } else if (amOrPm == PM) {
+            return mPmKeyCode;
+        }
+
+        return -1;
+    }
+
+    /**
+     * Create a tree for deciding what keys can legally be typed.
+     */
+    private void generateLegalTimesTree() {
+        // Create a quick cache of numbers to their keycodes.
+        final int k0 = KeyEvent.KEYCODE_0;
+        final int k1 = KeyEvent.KEYCODE_1;
+        final int k2 = KeyEvent.KEYCODE_2;
+        final int k3 = KeyEvent.KEYCODE_3;
+        final int k4 = KeyEvent.KEYCODE_4;
+        final int k5 = KeyEvent.KEYCODE_5;
+        final int k6 = KeyEvent.KEYCODE_6;
+        final int k7 = KeyEvent.KEYCODE_7;
+        final int k8 = KeyEvent.KEYCODE_8;
+        final int k9 = KeyEvent.KEYCODE_9;
+
+        // The root of the tree doesn't contain any numbers.
+        mLegalTimesTree = new Node();
+        if (mIs24HourView) {
+            // We'll be re-using these nodes, so we'll save them.
+            Node minuteFirstDigit = new Node(k0, k1, k2, k3, k4, k5);
+            Node minuteSecondDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            // The first digit must be followed by the second digit.
+            minuteFirstDigit.addChild(minuteSecondDigit);
+
+            // The first digit may be 0-1.
+            Node firstDigit = new Node(k0, k1);
+            mLegalTimesTree.addChild(firstDigit);
+
+            // When the first digit is 0-1, the second digit may be 0-5.
+            Node secondDigit = new Node(k0, k1, k2, k3, k4, k5);
+            firstDigit.addChild(secondDigit);
+            // We may now be followed by the first minute digit. E.g. 00:09, 15:58.
+            secondDigit.addChild(minuteFirstDigit);
+
+            // When the first digit is 0-1, and the second digit is 0-5, the third digit may be 6-9.
+            Node thirdDigit = new Node(k6, k7, k8, k9);
+            // The time must now be finished. E.g. 0:55, 1:08.
+            secondDigit.addChild(thirdDigit);
+
+            // When the first digit is 0-1, the second digit may be 6-9.
+            secondDigit = new Node(k6, k7, k8, k9);
+            firstDigit.addChild(secondDigit);
+            // We must now be followed by the first minute digit. E.g. 06:50, 18:20.
+            secondDigit.addChild(minuteFirstDigit);
+
+            // The first digit may be 2.
+            firstDigit = new Node(k2);
+            mLegalTimesTree.addChild(firstDigit);
+
+            // When the first digit is 2, the second digit may be 0-3.
+            secondDigit = new Node(k0, k1, k2, k3);
+            firstDigit.addChild(secondDigit);
+            // We must now be followed by the first minute digit. E.g. 20:50, 23:09.
+            secondDigit.addChild(minuteFirstDigit);
+
+            // When the first digit is 2, the second digit may be 4-5.
+            secondDigit = new Node(k4, k5);
+            firstDigit.addChild(secondDigit);
+            // We must now be followd by the last minute digit. E.g. 2:40, 2:53.
+            secondDigit.addChild(minuteSecondDigit);
+
+            // The first digit may be 3-9.
+            firstDigit = new Node(k3, k4, k5, k6, k7, k8, k9);
+            mLegalTimesTree.addChild(firstDigit);
+            // We must now be followed by the first minute digit. E.g. 3:57, 8:12.
+            firstDigit.addChild(minuteFirstDigit);
+        } else {
+            // We'll need to use the AM/PM node a lot.
+            // Set up AM and PM to respond to "a" and "p".
+            Node ampm = new Node(getAmOrPmKeyCode(AM), getAmOrPmKeyCode(PM));
+
+            // The first hour digit may be 1.
+            Node firstDigit = new Node(k1);
+            mLegalTimesTree.addChild(firstDigit);
+            // We'll allow quick input of on-the-hour times. E.g. 1pm.
+            firstDigit.addChild(ampm);
+
+            // When the first digit is 1, the second digit may be 0-2.
+            Node secondDigit = new Node(k0, k1, k2);
+            firstDigit.addChild(secondDigit);
+            // Also for quick input of on-the-hour times. E.g. 10pm, 12am.
+            secondDigit.addChild(ampm);
+
+            // When the first digit is 1, and the second digit is 0-2, the third digit may be 0-5.
+            Node thirdDigit = new Node(k0, k1, k2, k3, k4, k5);
+            secondDigit.addChild(thirdDigit);
+            // The time may be finished now. E.g. 1:02pm, 1:25am.
+            thirdDigit.addChild(ampm);
+
+            // When the first digit is 1, the second digit is 0-2, and the third digit is 0-5,
+            // the fourth digit may be 0-9.
+            Node fourthDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            thirdDigit.addChild(fourthDigit);
+            // The time must be finished now. E.g. 10:49am, 12:40pm.
+            fourthDigit.addChild(ampm);
+
+            // When the first digit is 1, and the second digit is 0-2, the third digit may be 6-9.
+            thirdDigit = new Node(k6, k7, k8, k9);
+            secondDigit.addChild(thirdDigit);
+            // The time must be finished now. E.g. 1:08am, 1:26pm.
+            thirdDigit.addChild(ampm);
+
+            // When the first digit is 1, the second digit may be 3-5.
+            secondDigit = new Node(k3, k4, k5);
+            firstDigit.addChild(secondDigit);
+
+            // When the first digit is 1, and the second digit is 3-5, the third digit may be 0-9.
+            thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            secondDigit.addChild(thirdDigit);
+            // The time must be finished now. E.g. 1:39am, 1:50pm.
+            thirdDigit.addChild(ampm);
+
+            // The hour digit may be 2-9.
+            firstDigit = new Node(k2, k3, k4, k5, k6, k7, k8, k9);
+            mLegalTimesTree.addChild(firstDigit);
+            // We'll allow quick input of on-the-hour-times. E.g. 2am, 5pm.
+            firstDigit.addChild(ampm);
+
+            // When the first digit is 2-9, the second digit may be 0-5.
+            secondDigit = new Node(k0, k1, k2, k3, k4, k5);
+            firstDigit.addChild(secondDigit);
+
+            // When the first digit is 2-9, and the second digit is 0-5, the third digit may be 0-9.
+            thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9);
+            secondDigit.addChild(thirdDigit);
+            // The time must be finished now. E.g. 2:57am, 9:30pm.
+            thirdDigit.addChild(ampm);
+        }
+    }
+
+    /**
+     * Simple node class to be used for traversal to check for legal times.
+     * mLegalKeys represents the keys that can be typed to get to the node.
+     * mChildren are the children that can be reached from this node.
+     */
+    private class Node {
+        private int[] mLegalKeys;
+        private ArrayList<Node> mChildren;
+
+        public Node(int... legalKeys) {
+            mLegalKeys = legalKeys;
+            mChildren = new ArrayList<Node>();
+        }
+
+        public void addChild(Node child) {
+            mChildren.add(child);
+        }
+
+        public boolean containsKey(int key) {
+            for (int i = 0; i < mLegalKeys.length; i++) {
+                if (mLegalKeys[i] == key) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public Node canReach(int key) {
+            if (mChildren == null) {
+                return null;
+            }
+            for (Node child : mChildren) {
+                if (child.containsKey(key)) {
+                    return child;
+                }
+            }
+            return null;
+        }
+    }
+
+    private class KeyboardListener implements View.OnKeyListener {
+        @Override
+        public boolean onKey(View v, int keyCode, KeyEvent event) {
+            if (event.getAction() == KeyEvent.ACTION_UP) {
+                return processKeyUp(keyCode);
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Render an animator to pulsate a view in place.
+     *
+     * @param labelToAnimate the view to pulsate.
+     * @return The animator object. Use .start() to begin.
+     */
+    private static ObjectAnimator getPulseAnimator(View labelToAnimate, float decreaseRatio,
+            float increaseRatio) {
+        final Keyframe k0 = Keyframe.ofFloat(0f, 1f);
+        final Keyframe k1 = Keyframe.ofFloat(0.275f, decreaseRatio);
+        final Keyframe k2 = Keyframe.ofFloat(0.69f, increaseRatio);
+        final Keyframe k3 = Keyframe.ofFloat(1f, 1f);
+
+        PropertyValuesHolder scaleX = PropertyValuesHolder.ofKeyframe("scaleX", k0, k1, k2, k3);
+        PropertyValuesHolder scaleY = PropertyValuesHolder.ofKeyframe("scaleY", k0, k1, k2, k3);
+        ObjectAnimator pulseAnimator =
+                ObjectAnimator.ofPropertyValuesHolder(labelToAnimate, scaleX, scaleY);
+        pulseAnimator.setDuration(PULSE_ANIMATOR_DURATION);
+
+        return pulseAnimator;
+    }
+}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index e38dfa7..bf5e49b9 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.annotation.IntDef;
 import android.app.INotificationManager;
 import android.app.ITransientNotification;
 import android.content.Context;
@@ -29,11 +30,13 @@
 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;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A toast is a view containing a quick little message for the user.  The toast class
  * helps you create and show those.
@@ -61,6 +64,11 @@
     static final String TAG = "Toast";
     static final boolean localLOGV = false;
 
+    /** @hide */
+    @IntDef({LENGTH_SHORT, LENGTH_LONG})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Duration {}
+
     /**
      * Show the view or text notification for a short period of time.  This time
      * could be user-definable.  This is the default.
@@ -152,7 +160,7 @@
      * @see #LENGTH_SHORT
      * @see #LENGTH_LONG
      */
-    public void setDuration(int duration) {
+    public void setDuration(@Duration int duration) {
         mDuration = duration;
     }
 
@@ -160,6 +168,7 @@
      * Return the duration.
      * @see #setDuration
      */
+    @Duration
     public int getDuration() {
         return mDuration;
     }
@@ -237,7 +246,7 @@
      *                 {@link #LENGTH_LONG}
      *
      */
-    public static Toast makeText(Context context, CharSequence text, int duration) {
+    public static Toast makeText(Context context, CharSequence text, @Duration int duration) {
         Toast result = new Toast(context);
 
         LayoutInflater inflate = (LayoutInflater)
@@ -263,7 +272,7 @@
      *
      * @throws Resources.NotFoundException if the resource can't be found.
      */
-    public static Toast makeText(Context context, int resId, int duration)
+    public static Toast makeText(Context context, int resId, @Duration int duration)
                                 throws Resources.NotFoundException {
         return makeText(context, context.getResources().getText(resId), duration);
     }
diff --git a/core/java/android/widget/ToggleButton.java b/core/java/android/widget/ToggleButton.java
index cedc777..28519d1 100644
--- a/core/java/android/widget/ToggleButton.java
+++ b/core/java/android/widget/ToggleButton.java
@@ -16,7 +16,6 @@
 
 package android.widget;
 
-
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -25,8 +24,6 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityNodeInfo;
 
-import com.android.internal.R;
-
 /**
  * Displays checked/unchecked states as a button
  * with a "light" indicator and by default accompanied with the text "ON" or "OFF".
@@ -46,13 +43,12 @@
 
     private static final int NO_ALPHA = 0xFF;
     private float mDisabledAlpha;
-    
-    public ToggleButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a =
-            context.obtainStyledAttributes(
-                    attrs, com.android.internal.R.styleable.ToggleButton, defStyle, 0);
+
+    public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.ToggleButton, defStyleAttr, defStyleRes);
         mTextOn = a.getText(com.android.internal.R.styleable.ToggleButton_textOn);
         mTextOff = a.getText(com.android.internal.R.styleable.ToggleButton_textOff);
         mDisabledAlpha = a.getFloat(com.android.internal.R.styleable.ToggleButton_disabledAlpha, 0.5f);
@@ -60,6 +56,10 @@
         a.recycle();
     }
 
+    public ToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public ToggleButton(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.buttonStyleToggle);
     }
diff --git a/core/java/android/widget/TwoLineListItem.java b/core/java/android/widget/TwoLineListItem.java
index f7e5266..5606c60 100644
--- a/core/java/android/widget/TwoLineListItem.java
+++ b/core/java/android/widget/TwoLineListItem.java
@@ -56,11 +56,15 @@
         this(context, attrs, 0); 
     }
 
-    public TwoLineListItem(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TwoLineListItem(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
 
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.TwoLineListItem, defStyle, 0);
+    public TwoLineListItem(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.TwoLineListItem, defStyleAttr, defStyleRes);
 
         a.recycle();
     }
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index d57b739..f23c64f 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -19,7 +19,6 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.media.AudioManager;
@@ -127,8 +126,12 @@
         initVideoView();
     }
 
-    public VideoView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public VideoView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public VideoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initVideoView();
     }
 
@@ -297,11 +300,8 @@
             // not ready for playback just yet, will try again later
             return;
         }
-        // Tell the music playback service to pause
-        // TODO: these constants need to be published somewhere in the framework.
-        Intent i = new Intent("com.android.music.musicservicecommand");
-        i.putExtra("command", "pause");
-        mContext.sendBroadcast(i);
+        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        am.requestAudioFocus(null, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
 
         // we shouldn't clear the target state, because somebody might have
         // called start() previously
diff --git a/core/java/android/widget/ZoomButton.java b/core/java/android/widget/ZoomButton.java
index af17c94..715e868 100644
--- a/core/java/android/widget/ZoomButton.java
+++ b/core/java/android/widget/ZoomButton.java
@@ -49,8 +49,12 @@
         this(context, attrs, 0);
     }
     
-    public ZoomButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ZoomButton(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ZoomButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         mHandler = new Handler();
         setOnLongClickListener(this);
     }
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index 50c803b..f7e9648 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -32,7 +32,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.view.ViewRootImpl;
 import android.view.WindowManager;
 import android.view.View.OnClickListener;
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 066d6c3..cc51a8b 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -42,7 +42,6 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
-import android.util.Log;
 import android.util.TypedValue;
 import android.view.ActionMode;
 import android.view.ContextThemeWrapper;
@@ -51,7 +50,6 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.Window;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AnimationUtils;
@@ -59,6 +57,7 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Map;
 
 /**
  * ActionBarImpl is the ActionBar implementation used
@@ -357,6 +356,10 @@
         setSubtitle(mContext.getString(resId));
     }
 
+    public void captureSharedElements(Map<String, View> sharedElements) {
+        mContainerView.findSharedElements(sharedElements);
+    }
+
     public void setSelectedNavigationItem(int position) {
         switch (mActionView.getNavigationMode()) {
         case NAVIGATION_MODE_TABS:
@@ -1083,7 +1086,7 @@
 
         @Override
         public Tab setIcon(int resId) {
-            return setIcon(mContext.getResources().getDrawable(resId));
+            return setIcon(mContext.getDrawable(resId));
         }
 
         @Override
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index fe532b0..7640749 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -70,6 +70,8 @@
     
     private View mView;
 
+    private int mViewLayoutResId;
+
     private int mViewSpacingLeft;
     
     private int mViewSpacingTop;
@@ -126,16 +128,20 @@
 
     private Handler mHandler;
 
-    View.OnClickListener mButtonHandler = new View.OnClickListener() {
+    private final View.OnClickListener mButtonHandler = new View.OnClickListener() {
+        @Override
         public void onClick(View v) {
-            Message m = null;
+            final Message m;
             if (v == mButtonPositive && mButtonPositiveMessage != null) {
                 m = Message.obtain(mButtonPositiveMessage);
             } else if (v == mButtonNegative && mButtonNegativeMessage != null) {
                 m = Message.obtain(mButtonNegativeMessage);
             } else if (v == mButtonNeutral && mButtonNeutralMessage != null) {
                 m = Message.obtain(mButtonNeutralMessage);
+            } else {
+                m = null;
             }
+
             if (m != null) {
                 m.sendToTarget();
             }
@@ -232,11 +238,6 @@
     public void installContent() {
         /* We use a custom title so never request a window title */
         mWindow.requestFeature(Window.FEATURE_NO_TITLE);
-        
-        if (mView == null || !canTextInput(mView)) {
-            mWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
-                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
-        }
         mWindow.setContentView(mAlertDialogLayout);
         setupView();
     }
@@ -263,10 +264,20 @@
     }
 
     /**
+     * Set the view resource to display in the dialog.
+     */
+    public void setView(int layoutResId) {
+        mView = null;
+        mViewLayoutResId = layoutResId;
+        mViewSpacingSpecified = false;
+    }
+
+    /**
      * Set the view to display in the dialog.
      */
     public void setView(View view) {
         mView = view;
+        mViewLayoutResId = 0;
         mViewSpacingSpecified = false;
     }
     
@@ -276,6 +287,7 @@
     public void setView(View view, int viewSpacingLeft, int viewSpacingTop, int viewSpacingRight,
             int viewSpacingBottom) {
         mView = view;
+        mViewLayoutResId = 0;
         mViewSpacingSpecified = true;
         mViewSpacingLeft = viewSpacingLeft;
         mViewSpacingTop = viewSpacingTop;
@@ -406,28 +418,44 @@
             mWindow.setCloseOnTouchOutsideIfNotSet(true);
         }
 
-        FrameLayout customPanel = null;
+        final FrameLayout customPanel = (FrameLayout) mWindow.findViewById(R.id.customPanel);
+        final View customView;
         if (mView != null) {
-            customPanel = (FrameLayout) mWindow.findViewById(R.id.customPanel);
-            FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.custom);
-            custom.addView(mView, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
+            customView = mView;
+        } else if (mViewLayoutResId != 0) {
+            final LayoutInflater inflater = LayoutInflater.from(mContext);
+            customView = inflater.inflate(mViewLayoutResId, customPanel, false);
+        } else {
+            customView = null;
+        }
+
+        final boolean hasCustomView = customView != null;
+        if (!hasCustomView || !canTextInput(customView)) {
+            mWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+        }
+
+        if (hasCustomView) {
+            final FrameLayout custom = (FrameLayout) mWindow.findViewById(R.id.custom);
+            custom.addView(customView, new LayoutParams(MATCH_PARENT, MATCH_PARENT));
+
             if (mViewSpacingSpecified) {
-                custom.setPadding(mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight,
-                        mViewSpacingBottom);
+                custom.setPadding(
+                        mViewSpacingLeft, mViewSpacingTop, mViewSpacingRight, mViewSpacingBottom);
             }
+
             if (mListView != null) {
                 ((LinearLayout.LayoutParams) customPanel.getLayoutParams()).weight = 0;
             }
         } else {
-            mWindow.findViewById(R.id.customPanel).setVisibility(View.GONE);
+            customPanel.setVisibility(View.GONE);
         }
-        
-        /* Only display the divider if we have a title and a 
-         * custom view or a message.
-         */
+
+        // Only display the divider if we have a title and a custom view or a
+        // message.
         if (hasTitle) {
-            View divider = null;
-            if (mMessage != null || mView != null || mListView != null) {
+            final View divider;
+            if (mMessage != null || customView != null || mListView != null) {
                 divider = mWindow.findViewById(R.id.titleDivider);
             } else {
                 divider = mWindow.findViewById(R.id.titleDividerTop);
@@ -437,8 +465,9 @@
                 divider.setVisibility(View.VISIBLE);
             }
         }
-        
-        setBackground(topPanel, contentPanel, customPanel, hasButtons, a, hasTitle, buttonPanel);
+
+        setBackground(a, topPanel, contentPanel, customPanel, buttonPanel, hasTitle, hasCustomView,
+                hasButtons);
         a.recycle();
     }
 
@@ -596,76 +625,64 @@
         }
     }
 
-    private void setBackground(LinearLayout topPanel, LinearLayout contentPanel,
-            View customPanel, boolean hasButtons, TypedArray a, boolean hasTitle, 
-            View buttonPanel) {
-        
-        /* Get all the different background required */
-        int fullDark = a.getResourceId(
-                R.styleable.AlertDialog_fullDark, R.drawable.popup_full_dark);
-        int topDark = a.getResourceId(
-                R.styleable.AlertDialog_topDark, R.drawable.popup_top_dark);
-        int centerDark = a.getResourceId(
-                R.styleable.AlertDialog_centerDark, R.drawable.popup_center_dark);
-        int bottomDark = a.getResourceId(
-                R.styleable.AlertDialog_bottomDark, R.drawable.popup_bottom_dark);
-        int fullBright = a.getResourceId(
-                R.styleable.AlertDialog_fullBright, R.drawable.popup_full_bright);
-        int topBright = a.getResourceId(
+    private void setBackground(TypedArray a, View topPanel, View contentPanel, View customPanel,
+            View buttonPanel, boolean hasTitle, boolean hasCustomView, boolean hasButtons) {
+        final int topBright = a.getResourceId(
                 R.styleable.AlertDialog_topBright, R.drawable.popup_top_bright);
-        int centerBright = a.getResourceId(
+        final int topDark = a.getResourceId(
+                R.styleable.AlertDialog_topDark, R.drawable.popup_top_dark);
+        final int centerBright = a.getResourceId(
                 R.styleable.AlertDialog_centerBright, R.drawable.popup_center_bright);
-        int bottomBright = a.getResourceId(
-                R.styleable.AlertDialog_bottomBright, R.drawable.popup_bottom_bright);
-        int bottomMedium = a.getResourceId(
-                R.styleable.AlertDialog_bottomMedium, R.drawable.popup_bottom_medium);
-        
-        /*
-         * We now set the background of all of the sections of the alert.
+        final int centerDark = a.getResourceId(
+                R.styleable.AlertDialog_centerDark, R.drawable.popup_center_dark);
+
+        /* We now set the background of all of the sections of the alert.
          * First collect together each section that is being displayed along
          * with whether it is on a light or dark background, then run through
          * them setting their backgrounds.  This is complicated because we need
          * to correctly use the full, top, middle, and bottom graphics depending
          * on how many views they are and where they appear.
          */
-        
-        View[] views = new View[4];
-        boolean[] light = new boolean[4];
+
+        final View[] views = new View[4];
+        final boolean[] light = new boolean[4];
         View lastView = null;
         boolean lastLight = false;
-        
+
         int pos = 0;
         if (hasTitle) {
             views[pos] = topPanel;
             light[pos] = false;
             pos++;
         }
-        
+
         /* The contentPanel displays either a custom text message or
          * a ListView. If it's text we should use the dark background
          * for ListView we should use the light background. If neither
          * are there the contentPanel will be hidden so set it as null.
          */
-        views[pos] = (contentPanel.getVisibility() == View.GONE) 
-                ? null : contentPanel;
+        views[pos] = contentPanel.getVisibility() == View.GONE ? null : contentPanel;
         light[pos] = mListView != null;
         pos++;
-        if (customPanel != null) {
+
+        if (hasCustomView) {
             views[pos] = customPanel;
             light[pos] = mForceInverseBackground;
             pos++;
         }
+
         if (hasButtons) {
             views[pos] = buttonPanel;
             light[pos] = true;
         }
-        
+
         boolean setView = false;
-        for (pos=0; pos<views.length; pos++) {
-            View v = views[pos];
+        for (pos = 0; pos < views.length; pos++) {
+            final View v = views[pos];
             if (v == null) {
                 continue;
             }
+
             if (lastView != null) {
                 if (!setView) {
                     lastView.setBackgroundResource(lastLight ? topBright : topDark);
@@ -674,23 +691,34 @@
                 }
                 setView = true;
             }
+
             lastView = v;
             lastLight = light[pos];
         }
-        
+
         if (lastView != null) {
             if (setView) {
-                
-                /* ListViews will use the Bright background but buttons use
-                 * the Medium background.
-                 */ 
+                final int bottomBright = a.getResourceId(
+                        R.styleable.AlertDialog_bottomBright, R.drawable.popup_bottom_bright);
+                final int bottomMedium = a.getResourceId(
+                        R.styleable.AlertDialog_bottomMedium, R.drawable.popup_bottom_medium);
+                final int bottomDark = a.getResourceId(
+                        R.styleable.AlertDialog_bottomDark, R.drawable.popup_bottom_dark);
+
+                // ListViews will use the Bright background, but buttons use the
+                // Medium background.
                 lastView.setBackgroundResource(
                         lastLight ? (hasButtons ? bottomMedium : bottomBright) : bottomDark);
             } else {
+                final int fullBright = a.getResourceId(
+                        R.styleable.AlertDialog_fullBright, R.drawable.popup_full_bright);
+                final int fullDark = a.getResourceId(
+                        R.styleable.AlertDialog_fullDark, R.drawable.popup_full_dark);
+
                 lastView.setBackgroundResource(lastLight ? fullBright : fullDark);
             }
         }
-        
+
         /* TODO: uncomment section below. The logic for this should be if 
          * it's a Contextual menu being displayed AND only a Cancel button 
          * is shown then do this.
@@ -715,12 +743,14 @@
             mListView.addFooterView(buttonPanel);
             */
 //        }
-        
-        if ((mListView != null) && (mAdapter != null)) {
-            mListView.setAdapter(mAdapter);
-            if (mCheckedItem > -1) {
-                mListView.setItemChecked(mCheckedItem, true);
-                mListView.setSelection(mCheckedItem);
+
+        final ListView listView = mListView;
+        if (listView != null && mAdapter != null) {
+            listView.setAdapter(mAdapter);
+            final int checkedItem = mCheckedItem;
+            if (checkedItem > -1) {
+                listView.setItemChecked(checkedItem, true);
+                listView.setSelection(checkedItem);
             }
         }
     }
@@ -736,8 +766,13 @@
             super(context, attrs);
         }
 
-        public RecycleListView(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
+        public RecycleListView(Context context, AttributeSet attrs, int defStyleAttr) {
+            super(context, attrs, defStyleAttr);
+        }
+
+        public RecycleListView(
+                Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
         }
 
         @Override
@@ -769,6 +804,7 @@
         public CharSequence[] mItems;
         public ListAdapter mAdapter;
         public DialogInterface.OnClickListener mOnClickListener;
+        public int mViewLayoutResId;
         public View mView;
         public int mViewSpacingLeft;
         public int mViewSpacingTop;
@@ -854,8 +890,10 @@
                 } else {
                     dialog.setView(mView);
                 }
+            } else if (mViewLayoutResId != 0) {
+                dialog.setView(mViewLayoutResId);
             }
-            
+
             /*
             dialog.setCancelable(mCancelable);
             dialog.setOnCancelListener(mOnCancelListener);
@@ -937,7 +975,8 @@
             
             if (mOnClickListener != null) {
                 listView.setOnItemClickListener(new OnItemClickListener() {
-                    public void onItemClick(AdapterView parent, View v, int position, long id) {
+                    @Override
+                    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                         mOnClickListener.onClick(dialog.mDialogInterface, position);
                         if (!mIsSingleChoice) {
                             dialog.mDialogInterface.dismiss();
@@ -946,7 +985,8 @@
                 });
             } else if (mOnCheckboxClickListener != null) {
                 listView.setOnItemClickListener(new OnItemClickListener() {
-                    public void onItemClick(AdapterView parent, View v, int position, long id) {
+                    @Override
+                    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
                         if (mCheckedItems != null) {
                             mCheckedItems[position] = listView.isItemChecked(position);
                         }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 70f90d3..1eda373 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -27,8 +27,9 @@
         Intent intent = getIntent();
         Parcelable targetParcelable = intent.getParcelableExtra(Intent.EXTRA_INTENT);
         if (!(targetParcelable instanceof Intent)) {
-            Log.w("ChooseActivity", "Target is not an intent: " + targetParcelable);
+            Log.w("ChooserActivity", "Target is not an intent: " + targetParcelable);
             finish();
+            super.onCreate(null);
             return;
         }
         Intent target = (Intent)targetParcelable;
@@ -42,9 +43,10 @@
             initialIntents = new Intent[pa.length];
             for (int i=0; i<pa.length; i++) {
                 if (!(pa[i] instanceof Intent)) {
-                    Log.w("ChooseActivity", "Initial intent #" + i
+                    Log.w("ChooserActivity", "Initial intent #" + i
                             + " not an Intent: " + pa[i]);
                     finish();
+                    super.onCreate(null);
                     return;
                 }
                 initialIntents[i] = (Intent)pa[i];
diff --git a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
index 3d46cdd..83ad9dc 100644
--- a/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
+++ b/core/java/com/android/internal/app/HeavyWeightSwitcherActivity.java
@@ -32,7 +32,6 @@
 import android.view.View;
 import android.view.Window;
 import android.view.View.OnClickListener;
-import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 16c41f3..cd75010 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -36,4 +36,6 @@
     List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
     void setMode(int code, int uid, String packageName, int mode);
     void resetAllModes();
+    int checkAudioOperation(int code, int stream, int uid, String packageName);
+    void setAudioRestriction(int code, int stream, int uid, int mode, in String[] exceptionPackages);
 }
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 43c4b49..32f700d 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -22,19 +22,28 @@
 import android.telephony.SignalStrength;
 
 interface IBatteryStats {
-    byte[] getStatistics();
-    void noteStartWakelock(int uid, int pid, String name, int type);
-    void noteStopWakelock(int uid, int pid, String name, int type);
-    
-    /* DO NOT CHANGE the position of noteStartSensor without updating
-       SensorService.cpp */
+    // These first methods are also called by native code, so must
+    // be kept in sync with frameworks/native/include/binder/IBatteryStats.h
     void noteStartSensor(int uid, int sensor);
-
-    /* DO NOT CHANGE the position of noteStopSensor without updating
-       SensorService.cpp */
     void noteStopSensor(int uid, int sensor);
 
-    void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, int type);
+    // Remaining methods are only used in Java.
+    byte[] getStatistics();
+
+    void addIsolatedUid(int isolatedUid, int appUid);
+    void removeIsolatedUid(int isolatedUid, int appUid);
+
+    void noteEvent(int code, String name, int uid);
+
+    void noteStartWakelock(int uid, int pid, String name, String historyName,
+            int type, boolean unimportantForLogging);
+    void noteStopWakelock(int uid, int pid, String name, int type);
+
+    void noteStartWakelockFromSource(in WorkSource ws, int pid, String name, String historyName,
+            int type, boolean unimportantForLogging);
+    void noteChangeWakelockFromSource(in WorkSource ws, int pid, String name, int type,
+            in WorkSource newWs, int newPid, String newName,
+            String newHistoryName, int newType, boolean newUnimportantForLogging);
     void noteStopWakelockFromSource(in WorkSource ws, int pid, String name, int type);
 
     void noteVibratorOn(int uid, long durationMillis);
@@ -46,6 +55,7 @@
     void noteScreenOff();
     void noteInputEvent();
     void noteUserActivity(int uid, int event);
+    void noteDataConnectionActive(int type, boolean active, long timestampNs);
     void notePhoneOn();
     void notePhoneOff();
     void notePhoneSignalStrength(in SignalStrength signalStrength);
@@ -56,8 +66,10 @@
     void noteWifiRunning(in WorkSource ws);
     void noteWifiRunningChanged(in WorkSource oldWs, in WorkSource newWs);
     void noteWifiStopped(in WorkSource ws);
+    void noteWifiState(int wifiState, String accessPoint);
     void noteBluetoothOn();
     void noteBluetoothOff();
+    void noteBluetoothState(int bluetoothState);
     void noteFullWifiLockAcquired(int uid);
     void noteFullWifiLockReleased(int uid);
     void noteWifiScanStarted(int uid);
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 043964f..ec2d654 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -117,7 +117,7 @@
         /** - TODO: Enable when zz_ZY Pseudolocale is complete
          *  if (!localeList.contains("zz_ZY")) {
          *      localeList.add("zz_ZY");
-         *	}
+         *  }
          */
         }
         String[] locales = new String[localeList.size()];
diff --git a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
index ae362af..237feed 100644
--- a/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
+++ b/core/java/com/android/internal/app/MediaRouteChooserDialogFragment.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.view.View;
-import android.view.View.OnClickListener;
 
 /**
  * Media route chooser dialog fragment.
diff --git a/core/java/com/android/internal/app/MediaRouteControllerDialog.java b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
index 8fc99c7..b0e0373 100644
--- a/core/java/com/android/internal/app/MediaRouteControllerDialog.java
+++ b/core/java/com/android/internal/app/MediaRouteControllerDialog.java
@@ -256,13 +256,13 @@
     private Drawable getIconDrawable() {
         if (mRoute.isConnecting()) {
             if (mMediaRouteConnectingDrawable == null) {
-                mMediaRouteConnectingDrawable = getContext().getResources().getDrawable(
+                mMediaRouteConnectingDrawable = getContext().getDrawable(
                         R.drawable.ic_media_route_connecting_holo_dark);
             }
             return mMediaRouteConnectingDrawable;
         } else {
             if (mMediaRouteOnDrawable == null) {
-                mMediaRouteOnDrawable = getContext().getResources().getDrawable(
+                mMediaRouteOnDrawable = getContext().getDrawable(
                         R.drawable.ic_media_route_on_holo_dark);
             }
             return mMediaRouteOnDrawable;
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 40a705c..8cdaf91 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
-import android.content.Context;
 import android.content.Intent;
 import android.graphics.Typeface;
 import android.provider.Settings;
@@ -26,19 +25,15 @@
 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.AccelerateInterpolator;
 import android.view.animation.AnticipateOvershootInterpolator;
 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 {
     FrameLayout mContent;
diff --git a/core/java/com/android/internal/app/ProcessStats.java b/core/java/com/android/internal/app/ProcessStats.java
index a87992a..b1535e3 100644
--- a/core/java/com/android/internal/app/ProcessStats.java
+++ b/core/java/com/android/internal/app/ProcessStats.java
@@ -171,7 +171,7 @@
     static final String CSV_SEP = "\t";
 
     // Current version of the parcel format.
-    private static final int PARCEL_VERSION = 13;
+    private static final int PARCEL_VERSION = 14;
     // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
     private static final int MAGIC = 0x50535453;
 
@@ -189,7 +189,8 @@
     public String mTimePeriodStartClockStr;
     public int mFlags;
 
-    public final ProcessMap<PackageState> mPackages = new ProcessMap<PackageState>();
+    public final ProcessMap<SparseArray<PackageState>> mPackages
+            = new ProcessMap<SparseArray<PackageState>>();
     public final ProcessMap<ProcessState> mProcesses = new ProcessMap<ProcessState>();
 
     public final long[] mMemFactorDurations = new long[ADJ_COUNT];
@@ -227,40 +228,45 @@
     }
 
     public void add(ProcessStats other) {
-        ArrayMap<String, SparseArray<PackageState>> pkgMap = other.mPackages.getMap();
+        ArrayMap<String, SparseArray<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);
+            final String pkgName = pkgMap.keyAt(ip);
+            final SparseArray<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);
+                final int uid = uids.keyAt(iu);
+                final SparseArray<PackageState> versions = uids.valueAt(iu);
+                for (int iv=0; iv<versions.size(); iv++) {
+                    final int vers = versions.keyAt(iv);
+                    final PackageState otherState = versions.valueAt(iv);
+                    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
+                                    + " vers " + vers + " proc " + otherProc.mName);
+                            ProcessState thisProc = getProcessStateLocked(pkgName, uid, vers,
+                                    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,
+                                        vers);
+                                thisProc = thisProc.clone(thisProc.mPackage, now);
+                                pkgState.mProcesses.put(thisProc.mName, thisProc);
+                            }
+                            thisProc.add(otherProc);
                         }
-                        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);
+                    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, vers,
+                                otherSvc.mProcessName, otherSvc.mName);
+                        thisSvc.add(otherSvc);
+                    }
                 }
             }
         }
@@ -275,9 +281,11 @@
                 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);
+                    thisProc = new ProcessState(this, otherProc.mPackage, uid, otherProc.mVersion,
+                            otherProc.mName);
                     mProcesses.put(otherProc.mName, uid, thisProc);
-                    PackageState thisState = getPackageStateLocked(otherProc.mPackage, uid);
+                    PackageState thisState = getPackageStateLocked(otherProc.mPackage, uid,
+                            otherProc.mVersion);
                     if (!thisState.mProcesses.containsKey(otherProc.mName)) {
                         thisState.mProcesses.put(otherProc.mName, thisProc);
                     }
@@ -440,7 +448,7 @@
     }
 
     static void dumpServiceTimeCheckin(PrintWriter pw, String label, String packageName,
-            int uid, String serviceName, ServiceState svc, int serviceType, int opCount,
+            int uid, int vers, String serviceName, ServiceState svc, int serviceType, int opCount,
             int curState, long curStartTime, long now) {
         if (opCount <= 0) {
             return;
@@ -451,6 +459,8 @@
         pw.print(",");
         pw.print(uid);
         pw.print(",");
+        pw.print(vers);
+        pw.print(",");
         pw.print(serviceName);
         pw.print(",");
         pw.print(opCount);
@@ -775,7 +785,7 @@
 
     static void dumpProcessSummaryLocked(PrintWriter pw, String prefix,
             ArrayList<ProcessState> procs, int[] screenStates, int[] memStates, int[] procStates,
-            long now, long totalTime) {
+            boolean inclUidVers, long now, long totalTime) {
         for (int i=procs.size()-1; i>=0; i--) {
             ProcessState proc = procs.get(i);
             pw.print(prefix);
@@ -783,6 +793,8 @@
             pw.print(proc.mName);
             pw.print(" / ");
             UserHandle.formatUid(pw, proc.mUid);
+            pw.print(" / v");
+            pw.print(proc.mVersion);
             pw.println(":");
             dumpProcessSummaryDetails(pw, proc, prefix, "         TOTAL: ", screenStates, memStates,
                     procStates, now, totalTime, true);
@@ -869,6 +881,8 @@
         pw.print("process");
         pw.print(CSV_SEP);
         pw.print("uid");
+        pw.print(CSV_SEP);
+        pw.print("vers");
         dumpStateHeadersCsv(pw, CSV_SEP, sepScreenStates ? screenStates : null,
                 sepMemStates ? memStates : null,
                 sepProcStates ? procStates : null);
@@ -878,6 +892,8 @@
             pw.print(proc.mName);
             pw.print(CSV_SEP);
             UserHandle.formatUid(pw, proc.mUid);
+            pw.print(CSV_SEP);
+            pw.print(proc.mVersion);
             dumpProcessStateCsv(pw, proc, sepScreenStates, screenStates,
                     sepMemStates, memStates, sepProcStates, procStates, now);
             pw.println();
@@ -979,46 +995,50 @@
     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();
+
+        // First initialize use count of all common processes.
+        final long now = SystemClock.uptimeMillis();
+        final ArrayMap<String, SparseArray<ProcessState>> procMap = mProcesses.getMap();
         for (int ip=procMap.size()-1; ip>=0; ip--) {
-            SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            final 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.valueAt(iu).makeDead();
-                    uids.removeAt(iu);
-                }
-            }
-            if (uids.size() <= 0) {
-                procMap.removeAt(ip);
-            }
+                uids.valueAt(iu).mTmpNumInUse = 0;
+           }
         }
-        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+
+        // Next reset or prune all per-package processes, and for the ones that are reset
+        // track this back to the common processes.
+        final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
         for (int ip=pkgMap.size()-1; ip>=0; ip--) {
-            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            final SparseArray<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.valueAt(iproc).makeDead();
-                        pkgState.mProcesses.removeAt(iproc);
+                final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+                for (int iv=vpkgs.size()-1; iv>=0; iv--) {
+                    final PackageState pkgState = vpkgs.valueAt(iv);
+                    for (int iproc=pkgState.mProcesses.size()-1; iproc>=0; iproc--) {
+                        final ProcessState ps = pkgState.mProcesses.valueAt(iproc);
+                        if (ps.isInUse()) {
+                            ps.resetSafely(now);
+                            ps.mCommonProcess.mTmpNumInUse++;
+                            ps.mCommonProcess.mTmpFoundSubProc = ps;
+                        } else {
+                            pkgState.mProcesses.valueAt(iproc).makeDead();
+                            pkgState.mProcesses.removeAt(iproc);
+                        }
+                    }
+                    for (int isvc=pkgState.mServices.size()-1; isvc>=0; isvc--) {
+                        final ServiceState ss = pkgState.mServices.valueAt(isvc);
+                        if (ss.isInUse()) {
+                            ss.resetSafely(now);
+                        } else {
+                            pkgState.mServices.removeAt(isvc);
+                        }
+                    }
+                    if (pkgState.mProcesses.size() <= 0 && pkgState.mServices.size() <= 0) {
+                        vpkgs.removeAt(iv);
                     }
                 }
-                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) {
+                if (vpkgs.size() <= 0) {
                     uids.removeAt(iu);
                 }
             }
@@ -1026,6 +1046,37 @@
                 pkgMap.removeAt(ip);
             }
         }
+
+        // Finally prune out any common processes that are no longer in use.
+        for (int ip=procMap.size()-1; ip>=0; ip--) {
+            final SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            for (int iu=uids.size()-1; iu>=0; iu--) {
+                ProcessState ps = uids.valueAt(iu);
+                if (ps.isInUse() || ps.mTmpNumInUse > 0) {
+                    // If this is a process for multiple packages, we could at this point
+                    // be back down to one package.  In that case, we want to revert back
+                    // to a single shared ProcessState.  We can do this by converting the
+                    // current package-specific ProcessState up to the shared ProcessState,
+                    // throwing away the current one we have here (because nobody else is
+                    // using it).
+                    if (!ps.mActive && ps.mMultiPackage && ps.mTmpNumInUse == 1) {
+                        // Here we go...
+                        ps = ps.mTmpFoundSubProc;
+                        ps.mCommonProcess = ps;
+                        uids.setValueAt(iu, ps);
+                    } else {
+                        ps.resetSafely(now);
+                    }
+                } else {
+                    ps.makeDead();
+                    uids.removeAt(iu);
+                }
+            }
+            if (uids.size() <= 0) {
+                procMap.removeAt(ip);
+            }
+        }
+
         mStartTime = now;
         if (DEBUG) Slog.d(TAG, "State reset; now " + mTimePeriodStartClockStr);
     }
@@ -1193,23 +1244,27 @@
                 uids.valueAt(iu).commitStateTime(now);
             }
         }
-        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
         final int NPKG = pkgMap.size();
         for (int ip=0; ip<NPKG; ip++) {
-            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            final SparseArray<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 SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+                final int NVERS = vpkgs.size();
+                for (int iv=0; iv<NVERS; iv++) {
+                    PackageState pkgState = vpkgs.valueAt(iv);
+                    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);
+                    final int NSRVS = pkgState.mServices.size();
+                    for (int isvc=0; isvc<NSRVS; isvc++) {
+                        pkgState.mServices.valueAt(isvc).commitStateTime(now);
+                    }
                 }
             }
         }
@@ -1239,46 +1294,53 @@
         out.writeInt(NPROC);
         for (int ip=0; ip<NPROC; ip++) {
             writeCommonString(out, procMap.keyAt(ip));
-            SparseArray<ProcessState> uids = procMap.valueAt(ip);
+            final 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);
+                final ProcessState proc = uids.valueAt(iu);
                 writeCommonString(out, proc.mPackage);
+                out.writeInt(proc.mVersion);
                 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 SparseArray<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 SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+                final int NVERS = vpkgs.size();
+                out.writeInt(NVERS);
+                for (int iv=0; iv<NVERS; iv++) {
+                    out.writeInt(vpkgs.keyAt(iv));
+                    final PackageState pkgState = vpkgs.valueAt(iv);
+                    final int NPROCS = pkgState.mProcesses.size();
+                    out.writeInt(NPROCS);
+                    for (int iproc=0; iproc<NPROCS; iproc++) {
+                        writeCommonString(out, pkgState.mProcesses.keyAt(iproc));
+                        final 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);
+                    final int NSRVS = pkgState.mServices.size();
+                    out.writeInt(NSRVS);
+                    for (int isvc=0; isvc<NSRVS; isvc++) {
+                        out.writeString(pkgState.mServices.keyAt(isvc));
+                        final ServiceState svc = pkgState.mServices.valueAt(isvc);
+                        writeCommonString(out, svc.mProcessName);
+                        svc.writeToParcel(out, now);
+                    }
                 }
             }
         }
@@ -1396,7 +1458,7 @@
         }
         while (NPROC > 0) {
             NPROC--;
-            String procName = readCommonString(in, version);
+            final String procName = readCommonString(in, version);
             if (procName == null) {
                 mReadError = "bad process name";
                 return;
@@ -1408,23 +1470,24 @@
             }
             while (NUID > 0) {
                 NUID--;
-                int uid = in.readInt();
+                final int uid = in.readInt();
                 if (uid < 0) {
                     mReadError = "bad uid: " + uid;
                     return;
                 }
-                String pkgName = readCommonString(in, version);
+                final String pkgName = readCommonString(in, version);
                 if (pkgName == null) {
                     mReadError = "bad process package name";
                     return;
                 }
+                final int vers = in.readInt();
                 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);
+                    proc = new ProcessState(this, pkgName, uid, vers, procName);
                     if (!proc.readFromParcel(in, true)) {
                         return;
                     }
@@ -1444,7 +1507,7 @@
         }
         while (NPKG > 0) {
             NPKG--;
-            String pkgName = readCommonString(in, version);
+            final String pkgName = readCommonString(in, version);
             if (pkgName == null) {
                 mReadError = "bad package name";
                 return;
@@ -1456,83 +1519,98 @@
             }
             while (NUID > 0) {
                 NUID--;
-                int uid = in.readInt();
+                final int uid = in.readInt();
                 if (uid < 0) {
                     mReadError = "bad uid: " + uid;
                     return;
                 }
-                PackageState pkgState = new PackageState(pkgName, uid);
-                mPackages.put(pkgName, uid, pkgState);
-                int NPROCS = in.readInt();
-                if (NPROCS < 0) {
-                    mReadError = "bad package process count: " + NPROCS;
+                int NVERS = in.readInt();
+                if (NVERS < 0) {
+                    mReadError = "bad versions count: " + NVERS;
                     return;
                 }
-                while (NPROCS > 0) {
-                    NPROCS--;
-                    String procName = readCommonString(in, version);
-                    if (procName == null) {
-                        mReadError = "bad package process name";
+                while (NVERS > 0) {
+                    NVERS--;
+                    final int vers = in.readInt();
+                    PackageState pkgState = new PackageState(pkgName, uid);
+                    SparseArray<PackageState> vpkg = mPackages.get(pkgName, uid);
+                    if (vpkg == null) {
+                        vpkg = new SparseArray<PackageState>();
+                        mPackages.put(pkgName, uid, vpkg);
+                    }
+                    vpkg.put(vers, pkgState);
+                    int NPROCS = in.readInt();
+                    if (NPROCS < 0) {
+                        mReadError = "bad package process count: " + NPROCS;
                         return;
                     }
-                    int hasProc = in.readInt();
-                    if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid
-                            + " process " + procName + " hasProc=" + hasProc);
-                    ProcessState commonProc = mProcesses.get(procName, uid);
-                    if (DEBUG_PARCEL) 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;
-                            }
+                    while (NPROCS > 0) {
+                        NPROCS--;
+                        String procName = readCommonString(in, version);
+                        if (procName == null) {
+                            mReadError = "bad package process name";
+                            return;
                         }
-                        if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
-                                + procName + " " + uid + " " + proc);
-                        pkgState.mProcesses.put(procName, proc);
-                    } else {
-                        if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
-                                + procName + " " + uid + " " + commonProc);
-                        pkgState.mProcesses.put(procName, commonProc);
+                        int hasProc = in.readInt();
+                        if (DEBUG_PARCEL) Slog.d(TAG, "Reading package " + pkgName + " " + uid
+                                + " process " + procName + " hasProc=" + hasProc);
+                        ProcessState commonProc = mProcesses.get(procName, uid);
+                        if (DEBUG_PARCEL) 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, vers, procName,
+                                        0);
+                                if (!proc.readFromParcel(in, true)) {
+                                    return;
+                                }
+                            }
+                            if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " process: "
+                                    + procName + " " + uid + " " + proc);
+                            pkgState.mProcesses.put(procName, proc);
+                        } else {
+                            if (DEBUG_PARCEL) 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";
+                    int NSRVS = in.readInt();
+                    if (NSRVS < 0) {
+                        mReadError = "bad package service count: " + NSRVS;
                         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);
+                    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_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: "
+                                + serviceName + " " + uid + " " + serv);
+                        pkgState.mServices.put(serviceName, serv);
                     }
-                    if (!serv.readFromParcel(in)) {
-                        return;
-                    }
-                    if (DEBUG_PARCEL) Slog.d(TAG, "Adding package " + pkgName + " service: "
-                            + serviceName + " " + uid + " " + serv);
-                    pkgState.mServices.put(serviceName, serv);
                 }
             }
         }
@@ -1627,30 +1705,36 @@
         return ~lo;  // value not present
     }
 
-    public PackageState getPackageStateLocked(String packageName, int uid) {
-        PackageState as = mPackages.get(packageName, uid);
+    public PackageState getPackageStateLocked(String packageName, int uid, int vers) {
+        SparseArray<PackageState> vpkg = mPackages.get(packageName, uid);
+        if (vpkg == null) {
+            vpkg = new SparseArray<PackageState>();
+            mPackages.put(packageName, uid, vpkg);
+        }
+        PackageState as = vpkg.get(vers);
         if (as != null) {
             return as;
         }
         as = new PackageState(packageName, uid);
-        mPackages.put(packageName, uid, as);
+        vpkg.put(vers, as);
         return as;
     }
 
-    public ProcessState getProcessStateLocked(String packageName, int uid, String processName) {
-        final PackageState pkgState = getPackageStateLocked(packageName, uid);
+    public ProcessState getProcessStateLocked(String packageName, int uid, int vers,
+            String processName) {
+        final PackageState pkgState = getPackageStateLocked(packageName, uid, vers);
         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);
+            commonProc = new ProcessState(this, packageName, uid, vers, processName);
             mProcesses.put(processName, uid, commonProc);
             if (DEBUG) Slog.d(TAG, "GETPROC created new common " + commonProc);
         }
         if (!commonProc.mMultiPackage) {
-            if (packageName.equals(commonProc.mPackage)) {
+            if (packageName.equals(commonProc.mPackage) && vers == commonProc.mVersion) {
                 // 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;
@@ -1668,7 +1752,8 @@
                 long now = SystemClock.uptimeMillis();
                 // First let's make a copy of the current process state and put
                 // that under the now unique state for its original package name.
-                final PackageState commonPkgState = getPackageStateLocked(commonProc.mPackage, uid);
+                final PackageState commonPkgState = getPackageStateLocked(commonProc.mPackage,
+                        uid, commonProc.mVersion);
                 if (commonPkgState != null) {
                     ProcessState cloned = commonProc.clone(commonProc.mPackage, now);
                     if (DEBUG) Slog.d(TAG, "GETPROC setting clone to pkg " + commonProc.mPackage
@@ -1691,13 +1776,13 @@
                             + "/" + uid + " for proc " + commonProc.mName);
                 }
                 // And now make a fresh new process state for the new package name.
-                ps = new ProcessState(commonProc, packageName, uid, processName, now);
+                ps = new ProcessState(commonProc, packageName, uid, vers, processName, now);
                 if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
             }
         } 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,
+            ps = new ProcessState(commonProc, packageName, uid, vers, processName,
                     SystemClock.uptimeMillis());
             if (DEBUG) Slog.d(TAG, "GETPROC created new pkg " + ps);
         }
@@ -1706,16 +1791,16 @@
         return ps;
     }
 
-    public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid,
+    public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid, int vers,
             String processName, String className) {
-        final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid);
+        final ProcessStats.PackageState as = getPackageStateLocked(packageName, uid, vers);
         ProcessStats.ServiceState ss = as.mServices.get(className);
         if (ss != null) {
             if (DEBUG) Slog.d(TAG, "GETSVC: returning existing " + ss);
             return ss;
         }
         final ProcessStats.ProcessState ps = processName != null
-                ? getProcessStateLocked(packageName, uid, processName) : null;
+                ? getProcessStateLocked(packageName, uid, vers, processName) : null;
         ss = new ProcessStats.ServiceState(this, packageName, className, processName, ps);
         as.mServices.put(className, ss);
         if (DEBUG) Slog.d(TAG, "GETSVC: creating " + ss + " in " + ps);
@@ -1756,119 +1841,124 @@
             boolean dumpAll, boolean activeOnly) {
         long totalTime = dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
                 mStartTime, now);
-        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
         boolean printedHeader = false;
         boolean sepNeeded = false;
         for (int ip=0; ip<pkgMap.size(); ip++) {
             final String pkgName = pkgMap.keyAt(ip);
-            final SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            final SparseArray<SparseArray<PackageState>> uids = pkgMap.valueAt(ip);
             for (int iu=0; iu<uids.size(); iu++) {
                 final int uid = uids.keyAt(iu);
-                final PackageState pkgState = uids.valueAt(iu);
-                final int NPROCS = pkgState.mProcesses.size();
-                final int NSRVS = pkgState.mServices.size();
-                final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
-                if (!pkgMatch) {
-                    boolean procMatch = false;
-                    for (int iproc=0; iproc<NPROCS; iproc++) {
-                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
-                        if (reqPackage.equals(proc.mName)) {
-                            procMatch = true;
-                            break;
+                final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+                for (int iv=0; iv<vpkgs.size(); iv++) {
+                    final int vers = vpkgs.keyAt(iv);
+                    final PackageState pkgState = vpkgs.valueAt(iv);
+                    final int NPROCS = pkgState.mProcesses.size();
+                    final int NSRVS = pkgState.mServices.size();
+                    final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
+                    if (!pkgMatch) {
+                        boolean procMatch = false;
+                        for (int iproc=0; iproc<NPROCS; iproc++) {
+                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                            if (reqPackage.equals(proc.mName)) {
+                                procMatch = true;
+                                break;
+                            }
                         }
-                    }
-                    if (!procMatch) {
-                        continue;
-                    }
-                }
-                if (NPROCS > 0 || NSRVS > 0) {
-                    if (!printedHeader) {
-                        pw.println("Per-Package Stats:");
-                        printedHeader = true;
-                        sepNeeded = true;
-                    }
-                    pw.print("  * "); pw.print(pkgName); pw.print(" / ");
-                            UserHandle.formatUid(pw, uid); pw.println(":");
-                }
-                if (!dumpSummary || dumpAll) {
-                    for (int iproc=0; iproc<NPROCS; iproc++) {
-                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
-                        if (!pkgMatch && !reqPackage.equals(proc.mName)) {
+                        if (!procMatch) {
                             continue;
                         }
-                        if (activeOnly && !proc.isInUse()) {
-                            pw.print("      (Not active: ");
-                                    pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
-                            continue;
-                        }
-                        pw.print("      Process ");
-                        pw.print(pkgState.mProcesses.keyAt(iproc));
-                        if (proc.mCommonProcess.mMultiPackage) {
-                            pw.print(" (multi, ");
-                        } else {
-                            pw.print(" (unique, ");
-                        }
-                        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);
-                        dumpProcessInternalLocked(pw, "        ", proc, dumpAll);
                     }
-                } else {
-                    ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
-                    for (int iproc=0; iproc<NPROCS; iproc++) {
-                        ProcessState proc = pkgState.mProcesses.valueAt(iproc);
-                        if (!pkgMatch && !reqPackage.equals(proc.mName)) {
-                            continue;
+                    if (NPROCS > 0 || NSRVS > 0) {
+                        if (!printedHeader) {
+                            pw.println("Per-Package Stats:");
+                            printedHeader = true;
+                            sepNeeded = true;
                         }
-                        if (activeOnly && !proc.isInUse()) {
-                            continue;
+                        pw.print("  * "); pw.print(pkgName); pw.print(" / ");
+                                UserHandle.formatUid(pw, uid); pw.print(" / v");
+                                pw.print(vers); pw.println(":");
+                    }
+                    if (!dumpSummary || dumpAll) {
+                        for (int iproc=0; iproc<NPROCS; iproc++) {
+                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                            if (!pkgMatch && !reqPackage.equals(proc.mName)) {
+                                continue;
+                            }
+                            if (activeOnly && !proc.isInUse()) {
+                                pw.print("      (Not active: ");
+                                        pw.print(pkgState.mProcesses.keyAt(iproc)); pw.println(")");
+                                continue;
+                            }
+                            pw.print("      Process ");
+                            pw.print(pkgState.mProcesses.keyAt(iproc));
+                            if (proc.mCommonProcess.mMultiPackage) {
+                                pw.print(" (multi, ");
+                            } else {
+                                pw.print(" (unique, ");
+                            }
+                            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);
+                            dumpProcessInternalLocked(pw, "        ", proc, dumpAll);
                         }
-                        procs.add(proc);
-                    }
-                    dumpProcessSummaryLocked(pw, "      ", procs, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
-                            NON_CACHED_PROC_STATES, now, totalTime);
-                }
-                for (int isvc=0; isvc<NSRVS; isvc++) {
-                    ServiceState svc = pkgState.mServices.valueAt(isvc);
-                    if (!pkgMatch && !reqPackage.equals(svc.mProcessName)) {
-                        continue;
-                    }
-                    if (activeOnly && !svc.isInUse()) {
-                        pw.print("      (Not active: ");
-                                pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
-                        continue;
-                    }
-                    if (dumpAll) {
-                        pw.print("      Service ");
                     } else {
-                        pw.print("      * ");
-                    }
-                    pw.print(pkgState.mServices.keyAt(isvc));
-                    pw.println(":");
-                    pw.print("        Process: "); pw.println(svc.mProcessName);
-                    dumpServiceStats(pw, "        ", "          ", "    ", "Running", svc,
-                            svc.mRunCount, ServiceState.SERVICE_RUN, svc.mRunState,
-                            svc.mRunStartTime, now, totalTime, !dumpSummary || dumpAll);
-                    dumpServiceStats(pw, "        ", "          ", "    ", "Started", svc,
-                            svc.mStartedCount, ServiceState.SERVICE_STARTED, svc.mStartedState,
-                            svc.mStartedStartTime, now, totalTime, !dumpSummary || dumpAll);
-                    dumpServiceStats(pw, "        ", "          ", "      ", "Bound", svc,
-                            svc.mBoundCount, ServiceState.SERVICE_BOUND, svc.mBoundState,
-                            svc.mBoundStartTime, now, totalTime, !dumpSummary || dumpAll);
-                    dumpServiceStats(pw, "        ", "          ", "  ", "Executing", svc,
-                            svc.mExecCount, ServiceState.SERVICE_EXEC, svc.mExecState,
-                            svc.mExecStartTime, now, totalTime, !dumpSummary || dumpAll);
-                    if (dumpAll) {
-                        if (svc.mOwner != null) {
-                            pw.print("        mOwner="); pw.println(svc.mOwner);
+                        ArrayList<ProcessState> procs = new ArrayList<ProcessState>();
+                        for (int iproc=0; iproc<NPROCS; iproc++) {
+                            ProcessState proc = pkgState.mProcesses.valueAt(iproc);
+                            if (!pkgMatch && !reqPackage.equals(proc.mName)) {
+                                continue;
+                            }
+                            if (activeOnly && !proc.isInUse()) {
+                                continue;
+                            }
+                            procs.add(proc);
                         }
-                        if (svc.mStarted || svc.mRestarting) {
-                            pw.print("        mStarted="); pw.print(svc.mStarted);
-                            pw.print(" mRestarting="); pw.println(svc.mRestarting);
+                        dumpProcessSummaryLocked(pw, "      ", procs, ALL_SCREEN_ADJ, ALL_MEM_ADJ,
+                                NON_CACHED_PROC_STATES, false, now, totalTime);
+                    }
+                    for (int isvc=0; isvc<NSRVS; isvc++) {
+                        ServiceState svc = pkgState.mServices.valueAt(isvc);
+                        if (!pkgMatch && !reqPackage.equals(svc.mProcessName)) {
+                            continue;
+                        }
+                        if (activeOnly && !svc.isInUse()) {
+                            pw.print("      (Not active: ");
+                                    pw.print(pkgState.mServices.keyAt(isvc)); pw.println(")");
+                            continue;
+                        }
+                        if (dumpAll) {
+                            pw.print("      Service ");
+                        } else {
+                            pw.print("      * ");
+                        }
+                        pw.print(pkgState.mServices.keyAt(isvc));
+                        pw.println(":");
+                        pw.print("        Process: "); pw.println(svc.mProcessName);
+                        dumpServiceStats(pw, "        ", "          ", "    ", "Running", svc,
+                                svc.mRunCount, ServiceState.SERVICE_RUN, svc.mRunState,
+                                svc.mRunStartTime, now, totalTime, !dumpSummary || dumpAll);
+                        dumpServiceStats(pw, "        ", "          ", "    ", "Started", svc,
+                                svc.mStartedCount, ServiceState.SERVICE_STARTED, svc.mStartedState,
+                                svc.mStartedStartTime, now, totalTime, !dumpSummary || dumpAll);
+                        dumpServiceStats(pw, "        ", "          ", "      ", "Bound", svc,
+                                svc.mBoundCount, ServiceState.SERVICE_BOUND, svc.mBoundState,
+                                svc.mBoundStartTime, now, totalTime, !dumpSummary || dumpAll);
+                        dumpServiceStats(pw, "        ", "          ", "  ", "Executing", svc,
+                                svc.mExecCount, ServiceState.SERVICE_EXEC, svc.mExecState,
+                                svc.mExecStartTime, now, totalTime, !dumpSummary || dumpAll);
+                        if (dumpAll) {
+                            if (svc.mOwner != null) {
+                                pw.print("        mOwner="); pw.println(svc.mOwner);
+                            }
+                            if (svc.mStarted || svc.mRestarting) {
+                                pw.print("        mStarted="); pw.print(svc.mStarted);
+                                pw.print(" mRestarting="); pw.println(svc.mRestarting);
+                            }
                         }
                     }
                 }
@@ -2059,7 +2149,7 @@
                 pw.println(header);
             }
             dumpProcessSummaryLocked(pw, prefix, procs, screenStates, memStates,
-                    sortProcStates, now, totalTime);
+                    sortProcStates, true, now, totalTime);
         }
     }
 
@@ -2067,23 +2157,27 @@
             int[] procStates, int sortProcStates[], long now, String reqPackage,
             boolean activeOnly) {
         final ArraySet<ProcessState> foundProcs = new ArraySet<ProcessState>();
-        final ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
+        final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
         for (int ip=0; ip<pkgMap.size(); ip++) {
             final String pkgName = pkgMap.keyAt(ip);
-            final SparseArray<PackageState> procs = pkgMap.valueAt(ip);
+            final SparseArray<SparseArray<PackageState>> procs = pkgMap.valueAt(ip);
             for (int iu=0; iu<procs.size(); iu++) {
-                final PackageState state = procs.valueAt(iu);
-                final int NPROCS = state.mProcesses.size();
-                final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
-                for (int iproc=0; iproc<NPROCS; iproc++) {
-                    final ProcessState proc = state.mProcesses.valueAt(iproc);
-                    if (!pkgMatch && !reqPackage.equals(proc.mName)) {
-                        continue;
+                final SparseArray<PackageState> vpkgs = procs.valueAt(iu);
+                final int NVERS = vpkgs.size();
+                for (int iv=0; iv<NVERS; iv++) {
+                    final PackageState state = vpkgs.valueAt(iv);
+                    final int NPROCS = state.mProcesses.size();
+                    final boolean pkgMatch = reqPackage == null || reqPackage.equals(pkgName);
+                    for (int iproc=0; iproc<NPROCS; iproc++) {
+                        final ProcessState proc = state.mProcesses.valueAt(iproc);
+                        if (!pkgMatch && !reqPackage.equals(proc.mName)) {
+                            continue;
+                        }
+                        if (activeOnly && !proc.isInUse()) {
+                            continue;
+                        }
+                        foundProcs.add(proc.mCommonProcess);
                     }
-                    if (activeOnly && !proc.isInUse()) {
-                        continue;
-                    }
-                    foundProcs.add(proc.mCommonProcess);
                 }
             }
         }
@@ -2128,8 +2222,8 @@
 
     public void dumpCheckinLocked(PrintWriter pw, String reqPackage) {
         final long now = SystemClock.uptimeMillis();
-        ArrayMap<String, SparseArray<PackageState>> pkgMap = mPackages.getMap();
-        pw.println("vers,3");
+        final ArrayMap<String, SparseArray<SparseArray<PackageState>>> pkgMap = mPackages.getMap();
+        pw.println("vers,4");
         pw.print("period,"); pw.print(mTimePeriodStartClockStr);
         pw.print(","); pw.print(mTimePeriodStartRealtime); pw.print(",");
         pw.print(mRunning ? SystemClock.elapsedRealtime() : mTimePeriodEndRealtime);
@@ -2152,75 +2246,85 @@
         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);
+            final String pkgName = pkgMap.keyAt(ip);
             if (reqPackage != null && !reqPackage.equals(pkgName)) {
                 continue;
             }
-            SparseArray<PackageState> uids = pkgMap.valueAt(ip);
+            final SparseArray<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,");
+                final int uid = uids.keyAt(iu);
+                final SparseArray<PackageState> vpkgs = uids.valueAt(iu);
+                for (int iv=0; iv<vpkgs.size(); iv++) {
+                    final int vers = vpkgs.keyAt(iv);
+                    final PackageState pkgState = vpkgs.valueAt(iv);
+                    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)));
-                        dumpAllProcessPssCheckin(pw, proc);
-                        pw.println();
-                    }
-                    if (proc.mNumExcessiveWake > 0 || proc.mNumExcessiveCpu > 0
-                            || proc.mNumCachedKill > 0) {
-                        pw.print("pkgkills,");
-                        pw.print(pkgName);
-                        pw.print(",");
-                        pw.print(uid);
+                        pw.print(vers);
                         pw.print(",");
                         pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
-                        pw.print(",");
-                        pw.print(proc.mNumExcessiveWake);
-                        pw.print(",");
-                        pw.print(proc.mNumExcessiveCpu);
-                        pw.print(",");
-                        pw.print(proc.mNumCachedKill);
-                        pw.print(",");
-                        pw.print(proc.mMinCachedKillPss);
-                        pw.print(":");
-                        pw.print(proc.mAvgCachedKillPss);
-                        pw.print(":");
-                        pw.print(proc.mMaxCachedKillPss);
+                        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(vers);
+                            pw.print(",");
+                            pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
+                            dumpAllProcessPssCheckin(pw, proc);
+                            pw.println();
+                        }
+                        if (proc.mNumExcessiveWake > 0 || proc.mNumExcessiveCpu > 0
+                                || proc.mNumCachedKill > 0) {
+                            pw.print("pkgkills,");
+                            pw.print(pkgName);
+                            pw.print(",");
+                            pw.print(uid);
+                            pw.print(",");
+                            pw.print(vers);
+                            pw.print(",");
+                            pw.print(collapseString(pkgName, pkgState.mProcesses.keyAt(iproc)));
+                            pw.print(",");
+                            pw.print(proc.mNumExcessiveWake);
+                            pw.print(",");
+                            pw.print(proc.mNumExcessiveCpu);
+                            pw.print(",");
+                            pw.print(proc.mNumCachedKill);
+                            pw.print(",");
+                            pw.print(proc.mMinCachedKillPss);
+                            pw.print(":");
+                            pw.print(proc.mAvgCachedKillPss);
+                            pw.print(":");
+                            pw.print(proc.mMaxCachedKillPss);
+                            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);
+                    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, vers, serviceName,
+                                svc, ServiceState.SERVICE_RUN, svc.mRunCount,
+                                svc.mRunState, svc.mRunStartTime, now);
+                        dumpServiceTimeCheckin(pw, "pkgsvc-start", pkgName, uid, vers, serviceName,
+                                svc, ServiceState.SERVICE_STARTED, svc.mStartedCount,
+                                svc.mStartedState, svc.mStartedStartTime, now);
+                        dumpServiceTimeCheckin(pw, "pkgsvc-bound", pkgName, uid, vers, serviceName,
+                                svc, ServiceState.SERVICE_BOUND, svc.mBoundCount,
+                                svc.mBoundState, svc.mBoundStartTime, now);
+                        dumpServiceTimeCheckin(pw, "pkgsvc-exec", pkgName, uid, vers, serviceName,
+                                svc, ServiceState.SERVICE_EXEC, svc.mExecCount,
+                                svc.mExecState, svc.mExecStartTime, now);
+                    }
                 }
             }
         }
@@ -2364,9 +2468,10 @@
     }
 
     public static final class ProcessState extends DurationsTable {
-        public final ProcessState mCommonProcess;
+        public ProcessState mCommonProcess;
         public final String mPackage;
         public final int mUid;
+        public final int mVersion;
 
         //final long[] mDurations = new long[STATE_COUNT*ADJ_COUNT];
         int mCurState = STATE_NOTHING;
@@ -2393,16 +2498,19 @@
         boolean mDead;
 
         public long mTmpTotalTime;
+        int mTmpNumInUse;
+        ProcessState mTmpFoundSubProc;
 
         /**
          * 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) {
+        public ProcessState(ProcessStats processStats, String pkg, int uid, int vers, String name) {
             super(processStats, name);
             mCommonProcess = this;
             mPackage = pkg;
             mUid = uid;
+            mVersion = vers;
         }
 
         /**
@@ -2410,18 +2518,19 @@
          * 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,
+        public ProcessState(ProcessState commonProcess, String pkg, int uid, int vers, String name,
                 long now) {
             super(commonProcess.mStats, name);
             mCommonProcess = commonProcess;
             mPackage = pkg;
             mUid = uid;
+            mVersion = vers;
             mCurState = commonProcess.mCurState;
             mStartTime = now;
         }
 
         ProcessState clone(String pkg, long now) {
-            ProcessState pnew = new ProcessState(this, pkg, mUid, mName, now);
+            ProcessState pnew = new ProcessState(this, pkg, mUid, mVersion, mName, now);
             copyDurationsTo(pnew);
             if (mPssTable != null) {
                 mStats.mAddLongTable = new int[mPssTable.length];
@@ -2811,9 +2920,20 @@
                 // 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);
+                SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgName, mUid);
+                if (vpkg == null) {
+                    throw new IllegalStateException("Didn't find package " + pkgName
+                            + " / " + mUid);
+                }
+                PackageState pkg = vpkg.get(mVersion);
+                if (pkg == null) {
+                    throw new IllegalStateException("Didn't find package " + pkgName
+                            + " / " + mUid + " vers " + mVersion);
+                }
+                ProcessState proc = pkg.mProcesses.get(mName);
                 if (proc == null) {
-                    throw new IllegalStateException("Didn't create per-package process");
+                    throw new IllegalStateException("Didn't create per-package process "
+                            + mName + " in pkg " + pkgName + " / " + mUid + " vers " + mVersion);
                 }
                 return proc;
             }
@@ -2829,18 +2949,26 @@
                 // are losing whatever data we had in the old process state.
                 Log.wtf(TAG, "Pulling dead proc: name=" + mName + " pkg=" + mPackage
                         + " uid=" + mUid + " common.name=" + mCommonProcess.mName);
-                proc = mStats.getProcessStateLocked(proc.mPackage, proc.mUid, proc.mName);
+                proc = mStats.getProcessStateLocked(proc.mPackage, proc.mUid, proc.mVersion,
+                        proc.mName);
             }
             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) {
+                SparseArray<PackageState> vpkg = mStats.mPackages.get(pkgList.keyAt(index),
+                        proc.mUid);
+                if (vpkg == null) {
                     throw new IllegalStateException("No existing package "
                             + pkgList.keyAt(index) + "/" + proc.mUid
                             + " for multi-proc " + proc.mName);
                 }
+                PackageState pkg = vpkg.get(proc.mVersion);
+                if (pkg == null) {
+                    throw new IllegalStateException("No existing package "
+                            + pkgList.keyAt(index) + "/" + proc.mUid
+                            + " for multi-proc " + proc.mName + " version " + proc.mVersion);
+                }
                 proc = pkg.mProcesses.get(proc.mName);
                 if (proc == null) {
                     throw new IllegalStateException("Didn't create per-package process "
@@ -3014,7 +3142,7 @@
         }
 
         public boolean isInUse() {
-            return mOwner != null;
+            return mOwner != null || mRestarting;
         }
 
         void add(ServiceState other) {
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index 7ddd5d2..5214dd9 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -59,6 +59,5 @@
     void bindRemoteViewsService(int appWidgetId, in Intent intent, in IBinder connection, int userId);
     void unbindRemoteViewsService(int appWidgetId, in Intent intent, int userId);
     int[] getAppWidgetIds(in ComponentName provider, int userId);
-
 }
 
diff --git a/core/java/com/android/internal/backup/LocalTransport.java b/core/java/com/android/internal/backup/LocalTransport.java
index 494bc78..1bfad05 100644
--- a/core/java/com/android/internal/backup/LocalTransport.java
+++ b/core/java/com/android/internal/backup/LocalTransport.java
@@ -23,22 +23,24 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.os.SELinux;
 import android.util.Log;
 
 import com.android.org.bouncycastle.util.encoders.Base64;
 
 import java.io.File;
-import java.io.FileFilter;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
+
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+import libcore.io.StructStat;
+import static libcore.io.OsConstants.*;
 
 /**
  * Backup transport for stashing stuff into a known location on disk, and
@@ -55,20 +57,24 @@
     private static final String TRANSPORT_DESTINATION_STRING
             = "Backing up to debug-only private cache";
 
-    // The single hardcoded restore set always has the same (nonzero!) token
-    private static final long RESTORE_TOKEN = 1;
+    // The currently-active restore set always has the same (nonzero!) token
+    private static final long CURRENT_SET_TOKEN = 1;
 
     private Context mContext;
     private File mDataDir = new File(Environment.getDownloadCacheDirectory(), "backup");
+    private File mCurrentSetDir = new File(mDataDir, Long.toString(CURRENT_SET_TOKEN));
+
     private PackageInfo[] mRestorePackages = null;
     private int mRestorePackage = -1;  // Index into mRestorePackages
+    private File mRestoreDataDir;
+    private long mRestoreToken;
 
 
     public LocalTransport(Context context) {
         mContext = context;
-        mDataDir.mkdirs();
-        if (!SELinux.restorecon(mDataDir)) {
-            Log.e(TAG, "SELinux restorecon failed for " + mDataDir);
+        mCurrentSetDir.mkdirs();
+        if (!SELinux.restorecon(mCurrentSetDir)) {
+            Log.e(TAG, "SELinux restorecon failed for " + mCurrentSetDir);
         }
     }
 
@@ -96,14 +102,23 @@
 
     public int initializeDevice() {
         if (DEBUG) Log.v(TAG, "wiping all data");
-        deleteContents(mDataDir);
+        deleteContents(mCurrentSetDir);
         return BackupConstants.TRANSPORT_OK;
     }
 
     public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
-        if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName);
+        if (DEBUG) {
+            try {
+            StructStat ss = Libcore.os.fstat(data.getFileDescriptor());
+            Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName
+                    + " size=" + ss.st_size);
+            } catch (ErrnoException e) {
+                Log.w(TAG, "Unable to stat input file in performBackup() on "
+                        + packageInfo.packageName);
+            }
+        }
 
-        File packageDir = new File(mDataDir, packageInfo.packageName);
+        File packageDir = new File(mCurrentSetDir, packageInfo.packageName);
         packageDir.mkdirs();
 
         // Each 'record' in the restore set is kept in its own file, named by
@@ -135,7 +150,16 @@
                         buf = new byte[bufSize];
                     }
                     changeSet.readEntityData(buf, 0, dataSize);
-                    if (DEBUG) Log.v(TAG, "  data size " + dataSize);
+                    if (DEBUG) {
+                        try {
+                            long cur = Libcore.os.lseek(data.getFileDescriptor(), 0, SEEK_CUR);
+                            Log.v(TAG, "  read entity data; new pos=" + cur);
+                        }
+                        catch (ErrnoException e) {
+                            Log.w(TAG, "Unable to stat input file in performBackup() on "
+                                    + packageInfo.packageName);
+                        }
+                    }
 
                     try {
                         entity.write(buf, 0, dataSize);
@@ -175,7 +199,7 @@
     public int clearBackupData(PackageInfo packageInfo) {
         if (DEBUG) Log.v(TAG, "clearBackupData() pkg=" + packageInfo.packageName);
 
-        File packageDir = new File(mDataDir, packageInfo.packageName);
+        File packageDir = new File(mCurrentSetDir, packageInfo.packageName);
         final File[] fileset = packageDir.listFiles();
         if (fileset != null) {
             for (File f : fileset) {
@@ -192,22 +216,38 @@
     }
 
     // Restore handling
+    static final long[] POSSIBLE_SETS = { 2, 3, 4, 5, 6, 7, 8, 9 }; 
     public RestoreSet[] getAvailableRestoreSets() throws android.os.RemoteException {
-        // one hardcoded restore set
-        RestoreSet set = new RestoreSet("Local disk image", "flash", RESTORE_TOKEN);
-        RestoreSet[] array = { set };
-        return array;
+        long[] existing = new long[POSSIBLE_SETS.length + 1];
+        int num = 0;
+
+        // see which possible non-current sets exist, then put the current set at the end
+        for (long token : POSSIBLE_SETS) {
+            if ((new File(mDataDir, Long.toString(token))).exists()) {
+                existing[num++] = token;
+            }
+        }
+        // and always the currently-active set last
+        existing[num++] = CURRENT_SET_TOKEN;
+
+        RestoreSet[] available = new RestoreSet[num];
+        for (int i = 0; i < available.length; i++) {
+            available[i] = new RestoreSet("Local disk image", "flash", existing[i]);
+        }
+        return available;
     }
 
     public long getCurrentRestoreSet() {
-        // The hardcoded restore set always has the same token
-        return RESTORE_TOKEN;
+        // The current restore set always has the same token
+        return CURRENT_SET_TOKEN;
     }
 
     public int startRestore(long token, PackageInfo[] packages) {
         if (DEBUG) Log.v(TAG, "start restore " + token);
         mRestorePackages = packages;
         mRestorePackage = -1;
+        mRestoreToken = token;
+        mRestoreDataDir = new File(mDataDir, Long.toString(token));
         return BackupConstants.TRANSPORT_OK;
     }
 
@@ -215,7 +255,9 @@
         if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
         while (++mRestorePackage < mRestorePackages.length) {
             String name = mRestorePackages[mRestorePackage].packageName;
-            if (new File(mDataDir, name).isDirectory()) {
+            // skip packages where we have a data dir but no actual contents
+            String[] contents = (new File(mRestoreDataDir, name)).list();
+            if (contents != null && contents.length > 0) {
                 if (DEBUG) Log.v(TAG, "  nextRestorePackage() = " + name);
                 return name;
             }
@@ -228,29 +270,32 @@
     public int getRestoreData(ParcelFileDescriptor outFd) {
         if (mRestorePackages == null) throw new IllegalStateException("startRestore not called");
         if (mRestorePackage < 0) throw new IllegalStateException("nextRestorePackage not called");
-        File packageDir = new File(mDataDir, mRestorePackages[mRestorePackage].packageName);
+        File packageDir = new File(mRestoreDataDir, mRestorePackages[mRestorePackage].packageName);
 
         // The restore set is the concatenation of the individual record blobs,
-        // each of which is a file in the package's directory
-        File[] blobs = packageDir.listFiles();
+        // each of which is a file in the package's directory.  We return the
+        // data in lexical order sorted by key, so that apps which use synthetic
+        // keys like BLOB_1, BLOB_2, etc will see the date in the most obvious
+        // order.
+        ArrayList<DecodedFilename> blobs = contentsByKey(packageDir);
         if (blobs == null) {  // nextRestorePackage() ensures the dir exists, so this is an error
-            Log.e(TAG, "Error listing directory: " + packageDir);
+            Log.e(TAG, "No keys for package: " + packageDir);
             return BackupConstants.TRANSPORT_ERROR;
         }
 
         // We expect at least some data if the directory exists in the first place
-        if (DEBUG) Log.v(TAG, "  getRestoreData() found " + blobs.length + " key files");
+        if (DEBUG) Log.v(TAG, "  getRestoreData() found " + blobs.size() + " key files");
         BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor());
         try {
-            for (File f : blobs) {
+            for (DecodedFilename keyEntry : blobs) {
+                File f = keyEntry.file;
                 FileInputStream in = new FileInputStream(f);
                 try {
                     int size = (int) f.length();
                     byte[] buf = new byte[size];
                     in.read(buf);
-                    String key = new String(Base64.decode(f.getName()));
-                    if (DEBUG) Log.v(TAG, "    ... key=" + key + " size=" + size);
-                    out.writeEntityHeader(key, size);
+                    if (DEBUG) Log.v(TAG, "    ... key=" + keyEntry.key + " size=" + size);
+                    out.writeEntityHeader(keyEntry.key, size);
                     out.writeEntityData(buf, size);
                 } finally {
                     in.close();
@@ -263,6 +308,39 @@
         }
     }
 
+    static class DecodedFilename implements Comparable<DecodedFilename> {
+        public File file;
+        public String key;
+
+        public DecodedFilename(File f) {
+            file = f;
+            key = new String(Base64.decode(f.getName()));
+        }
+
+        @Override
+        public int compareTo(DecodedFilename other) {
+            // sorts into ascending lexical order by decoded key
+            return key.compareTo(other.key);
+        }
+    }
+
+    // Return a list of the files in the given directory, sorted lexically by
+    // the Base64-decoded file name, not by the on-disk filename
+    private ArrayList<DecodedFilename> contentsByKey(File dir) {
+        File[] allFiles = dir.listFiles();
+        if (allFiles == null || allFiles.length == 0) {
+            return null;
+        }
+
+        // Decode the filenames into keys then sort lexically by key
+        ArrayList<DecodedFilename> contents = new ArrayList<DecodedFilename>();
+        for (File f : allFiles) {
+            contents.add(new DecodedFilename(f));
+        }
+        Collections.sort(contents);
+        return contents;
+    }
+
     public void finishRestore() {
         if (DEBUG) Log.v(TAG, "finishRestore()");
     }
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 942995b..31ca3de 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -22,7 +22,6 @@
 import android.content.IntentFilter;
 import android.net.Uri;
 import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.UserHandle;
 import com.android.internal.os.BackgroundThread;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
new file mode 100644
index 0000000..dcc0a4c
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.inputmethod;
+
+import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodSubtype;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.TreeMap;
+
+/**
+ * InputMethodSubtypeSwitchingController controls the switching behavior of the subtypes.
+ */
+public class InputMethodSubtypeSwitchingController {
+    private static final String TAG = InputMethodSubtypeSwitchingController.class.getSimpleName();
+    private static final boolean DEBUG = false;
+    // TODO: Turn on this flag and add CTS when the platform starts expecting that all IMEs return
+    // true for supportsSwitchingToNextInputMethod().
+    private static final boolean REQUIRE_SWITCHING_SUPPORT = false;
+    private static final int MAX_HISTORY_SIZE = 4;
+    private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID;
+
+    private static class SubtypeParams {
+        public final InputMethodInfo mImi;
+        public final InputMethodSubtype mSubtype;
+        public final long mTime;
+
+        public SubtypeParams(InputMethodInfo imi, InputMethodSubtype subtype) {
+            mImi = imi;
+            mSubtype = subtype;
+            mTime = System.currentTimeMillis();
+        }
+    }
+
+    public static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
+        public final CharSequence mImeName;
+        public final CharSequence mSubtypeName;
+        public final InputMethodInfo mImi;
+        public final int mSubtypeId;
+        private final boolean mIsSystemLocale;
+        private final boolean mIsSystemLanguage;
+
+        public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
+                InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
+            mImeName = imeName;
+            mSubtypeName = subtypeName;
+            mImi = imi;
+            mSubtypeId = subtypeId;
+            if (TextUtils.isEmpty(subtypeLocale)) {
+                mIsSystemLocale = false;
+                mIsSystemLanguage = false;
+            } else {
+                mIsSystemLocale = subtypeLocale.equals(systemLocale);
+                mIsSystemLanguage = mIsSystemLocale
+                        || subtypeLocale.startsWith(systemLocale.substring(0, 2));
+            }
+        }
+
+        @Override
+        public int compareTo(ImeSubtypeListItem other) {
+            if (TextUtils.isEmpty(mImeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mImeName)) {
+                return -1;
+            }
+            if (!TextUtils.equals(mImeName, other.mImeName)) {
+                return mImeName.toString().compareTo(other.mImeName.toString());
+            }
+            if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) {
+                return 0;
+            }
+            if (mIsSystemLocale) {
+                return -1;
+            }
+            if (other.mIsSystemLocale) {
+                return 1;
+            }
+            if (mIsSystemLanguage) {
+                return -1;
+            }
+            if (other.mIsSystemLanguage) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(mSubtypeName)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(other.mSubtypeName)) {
+                return -1;
+            }
+            return mSubtypeName.toString().compareTo(other.mSubtypeName.toString());
+        }
+    }
+
+    private static class InputMethodAndSubtypeCircularList {
+        private final Context mContext;
+        // Used to load label
+        private final PackageManager mPm;
+        private final String mSystemLocaleStr;
+        private final InputMethodSettings mSettings;
+
+        public InputMethodAndSubtypeCircularList(Context context, InputMethodSettings settings) {
+            mContext = context;
+            mSettings = settings;
+            mPm = context.getPackageManager();
+            final Locale locale = context.getResources().getConfiguration().locale;
+            mSystemLocaleStr = locale != null ? locale.toString() : "";
+        }
+
+        private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
+                new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
+                        new Comparator<InputMethodInfo>() {
+                            @Override
+                            public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
+                                if (imi2 == null)
+                                    return 0;
+                                if (imi1 == null)
+                                    return 1;
+                                if (mPm == null) {
+                                    return imi1.getId().compareTo(imi2.getId());
+                                }
+                                CharSequence imiId1 = imi1.loadLabel(mPm) + "/" + imi1.getId();
+                                CharSequence imiId2 = imi2.loadLabel(mPm) + "/" + imi2.getId();
+                                return imiId1.toString().compareTo(imiId2.toString());
+                            }
+                        });
+
+        public ImeSubtypeListItem getNextInputMethod(
+                boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
+            if (imi == null) {
+                return null;
+            }
+            final List<ImeSubtypeListItem> imList =
+                    getSortedInputMethodAndSubtypeList();
+            if (imList.size() <= 1) {
+                return null;
+            }
+            final int N = imList.size();
+            final int currentSubtypeId =
+                    subtype != null ? InputMethodUtils.getSubtypeIdFromHashCode(imi,
+                            subtype.hashCode()) : NOT_A_SUBTYPE_ID;
+            for (int i = 0; i < N; ++i) {
+                final ImeSubtypeListItem isli = imList.get(i);
+                if (isli.mImi.equals(imi) && isli.mSubtypeId == currentSubtypeId) {
+                    if (!onlyCurrentIme) {
+                        return imList.get((i + 1) % N);
+                    }
+                    for (int j = 0; j < N - 1; ++j) {
+                        final ImeSubtypeListItem candidate = imList.get((i + j + 1) % N);
+                        if (candidate.mImi.equals(imi)) {
+                            return candidate;
+                        }
+                    }
+                    return null;
+                }
+            }
+            return null;
+        }
+
+        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList() {
+            return getSortedInputMethodAndSubtypeList(true, false, false);
+        }
+
+        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
+                boolean showSubtypes, boolean inputShown, boolean isScreenLocked) {
+            final ArrayList<ImeSubtypeListItem> imList =
+                    new ArrayList<ImeSubtypeListItem>();
+            final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
+                    mSettings.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(
+                            mContext);
+            if (immis == null || immis.size() == 0) {
+                return Collections.emptyList();
+            }
+            mSortedImmis.clear();
+            mSortedImmis.putAll(immis);
+            for (InputMethodInfo imi : mSortedImmis.keySet()) {
+                if (imi == null) {
+                    continue;
+                }
+                List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
+                HashSet<String> enabledSubtypeSet = new HashSet<String>();
+                for (InputMethodSubtype subtype : explicitlyOrImplicitlyEnabledSubtypeList) {
+                    enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
+                }
+                final CharSequence imeLabel = imi.loadLabel(mPm);
+                if (showSubtypes && enabledSubtypeSet.size() > 0) {
+                    final int subtypeCount = imi.getSubtypeCount();
+                    if (DEBUG) {
+                        Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
+                    }
+                    for (int j = 0; j < subtypeCount; ++j) {
+                        final InputMethodSubtype subtype = imi.getSubtypeAt(j);
+                        final String subtypeHashCode = String.valueOf(subtype.hashCode());
+                        // We show all enabled IMEs and subtypes when an IME is shown.
+                        if (enabledSubtypeSet.contains(subtypeHashCode)
+                                && ((inputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
+                            final CharSequence subtypeLabel =
+                                    subtype.overridesImplicitlyEnabledSubtype() ? null : subtype
+                                            .getDisplayName(mContext, imi.getPackageName(),
+                                                    imi.getServiceInfo().applicationInfo);
+                            imList.add(new ImeSubtypeListItem(imeLabel,
+                                    subtypeLabel, imi, j, subtype.getLocale(), mSystemLocaleStr));
+
+                            // Removing this subtype from enabledSubtypeSet because we no
+                            // longer need to add an entry of this subtype to imList to avoid
+                            // duplicated entries.
+                            enabledSubtypeSet.remove(subtypeHashCode);
+                        }
+                    }
+                } else {
+                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID, null,
+                            mSystemLocaleStr));
+                }
+            }
+            Collections.sort(imList);
+            return imList;
+        }
+    }
+
+    private final ArrayDeque<SubtypeParams> mTypedSubtypeHistory = new ArrayDeque<SubtypeParams>();
+    private final Object mLock = new Object();
+    private final InputMethodSettings mSettings;
+    private InputMethodAndSubtypeCircularList mSubtypeList;
+
+    public InputMethodSubtypeSwitchingController(InputMethodSettings settings) {
+        mSettings = settings;
+    }
+
+    // TODO: write unit tests for this method and the logic that determines the next subtype
+    public void onCommitText(InputMethodInfo imi, InputMethodSubtype subtype) {
+        synchronized (mTypedSubtypeHistory) {
+            if (subtype == null) {
+                Slog.w(TAG, "Invalid InputMethodSubtype: " + imi.getId() + ", " + subtype);
+                return;
+            }
+            if (DEBUG) {
+                Slog.d(TAG, "onCommitText: " + imi.getId() + ", " + subtype);
+            }
+            if (REQUIRE_SWITCHING_SUPPORT) {
+                if (!imi.supportsSwitchingToNextInputMethod()) {
+                    Slog.w(TAG, imi.getId() + " doesn't support switching to next input method.");
+                    return;
+                }
+            }
+            if (mTypedSubtypeHistory.size() >= MAX_HISTORY_SIZE) {
+                mTypedSubtypeHistory.poll();
+            }
+            mTypedSubtypeHistory.addFirst(new SubtypeParams(imi, subtype));
+        }
+    }
+
+    public void resetCircularListLocked(Context context) {
+        synchronized(mLock) {
+            mSubtypeList = new InputMethodAndSubtypeCircularList(context, mSettings);
+        }
+    }
+
+    public ImeSubtypeListItem getNextInputMethod(
+            boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
+        synchronized(mLock) {
+            return mSubtypeList.getNextInputMethod(onlyCurrentIme, imi, subtype);
+        }
+    }
+
+    public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(boolean showSubtypes,
+            boolean inputShown, boolean isScreenLocked) {
+        synchronized(mLock) {
+            return mSubtypeList.getSortedInputMethodAndSubtypeList(
+                    showSubtypes, inputShown, isScreenLocked);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 63d018f..03a053c 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -504,6 +504,7 @@
 
         private String mEnabledInputMethodsStrCache;
         private int mCurrentUserId;
+        private int[] mRelatedUserIds = new int[0];
 
         private static void buildEnabledInputMethodsSettingString(
                 StringBuilder builder, Pair<String, ArrayList<String>> pair) {
@@ -536,6 +537,22 @@
             mCurrentUserId = userId;
         }
 
+        public void setRelatedUserIds(int[] relatedUserIds) {
+            synchronized (this) {
+                mRelatedUserIds = relatedUserIds;
+            }
+        }
+
+        public boolean isRelatedToOrCurrentUser(int userId) {
+            synchronized (this) {
+                if (userId == mCurrentUserId) return true;
+                for (int i = 0; i < mRelatedUserIds.length; i++) {
+                    if (userId == mRelatedUserIds[i]) return true;
+                }
+                return false;
+            }
+        }
+
         public List<InputMethodInfo> getEnabledInputMethodListLocked() {
             return createEnabledInputMethodListLocked(
                     getEnabledInputMethodsAndSubtypeListLocked());
@@ -959,5 +976,16 @@
                 addSubtypeToHistory(curMethodId, subtypeId);
             }
         }
+
+        public HashMap<InputMethodInfo, List<InputMethodSubtype>>
+                getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(Context context) {
+            HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledInputMethodAndSubtypes =
+                    new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
+            for (InputMethodInfo imi: getEnabledInputMethodListLocked()) {
+                enabledInputMethodAndSubtypes.put(
+                        imi, getEnabledInputMethodSubtypeListLocked(context, imi, true));
+            }
+            return enabledInputMethodAndSubtypes;
+        }
     }
 }
diff --git a/core/java/com/android/internal/net/NetworkStatsFactory.java b/core/java/com/android/internal/net/NetworkStatsFactory.java
index 8282d23..e2a2b1e 100644
--- a/core/java/com/android/internal/net/NetworkStatsFactory.java
+++ b/core/java/com/android/internal/net/NetworkStatsFactory.java
@@ -17,6 +17,7 @@
 package com.android.internal.net;
 
 import static android.net.NetworkStats.SET_ALL;
+import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.kernelToTag;
@@ -26,6 +27,7 @@
 import android.os.SystemClock;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.ProcFileReader;
 
 import java.io.File;
@@ -165,22 +167,32 @@
     }
 
     public NetworkStats readNetworkStatsDetail() throws IOException {
-        return readNetworkStatsDetail(UID_ALL);
+        return readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
     }
 
-    public NetworkStats readNetworkStatsDetail(int limitUid) throws IOException {
+    public NetworkStats readNetworkStatsDetail(int limitUid, String[] limitIfaces, int limitTag,
+            NetworkStats lastStats)
+            throws IOException {
         if (USE_NATIVE_PARSING) {
-            final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
-            if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), limitUid) != 0) {
+            final NetworkStats stats;
+            if (lastStats != null) {
+                stats = lastStats;
+                stats.setElapsedRealtime(SystemClock.elapsedRealtime());
+            } else {
+                stats = new NetworkStats(SystemClock.elapsedRealtime(), -1);
+            }
+            if (nativeReadNetworkStatsDetail(stats, mStatsXtUid.getAbsolutePath(), limitUid,
+                    limitIfaces, limitTag) != 0) {
                 throw new IOException("Failed to parse network stats");
             }
             if (SANITY_CHECK_NATIVE) {
-                final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid, limitUid);
+                final NetworkStats javaStats = javaReadNetworkStatsDetail(mStatsXtUid, limitUid,
+                        limitIfaces, limitTag);
                 assertEquals(javaStats, stats);
             }
             return stats;
         } else {
-            return javaReadNetworkStatsDetail(mStatsXtUid, limitUid);
+            return javaReadNetworkStatsDetail(mStatsXtUid, limitUid, limitIfaces, limitTag);
         }
     }
 
@@ -189,7 +201,8 @@
      * expected to monotonically increase since device boot.
      */
     @VisibleForTesting
-    public static NetworkStats javaReadNetworkStatsDetail(File detailPath, int limitUid)
+    public static NetworkStats javaReadNetworkStatsDetail(File detailPath, int limitUid,
+            String[] limitIfaces, int limitTag)
             throws IOException {
         final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
 
@@ -222,7 +235,9 @@
                 entry.txBytes = reader.nextLong();
                 entry.txPackets = reader.nextLong();
 
-                if (limitUid == UID_ALL || limitUid == entry.uid) {
+                if ((limitIfaces == null || ArrayUtils.contains(limitIfaces, entry.iface))
+                        && (limitUid == UID_ALL || limitUid == entry.uid)
+                        && (limitTag == TAG_ALL || limitTag == entry.tag)) {
                     stats.addValues(entry);
                 }
 
@@ -264,5 +279,5 @@
      */
     @VisibleForTesting
     public static native int nativeReadNetworkStatsDetail(
-            NetworkStats stats, String path, int limitUid);
+            NetworkStats stats, String path, int limitUid, String[] limitIfaces, int limitTag);
 }
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 98599d0..0d00f41 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -25,8 +25,6 @@
 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;
diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java
new file mode 100644
index 0000000..6ca24d7
--- /dev/null
+++ b/core/java/com/android/internal/os/BatterySipper.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os;
+
+import android.os.BatteryStats.Uid;
+
+/**
+ * Contains power usage of an application, system service, or hardware type.
+ */
+public class BatterySipper implements Comparable<BatterySipper> {
+    public int userId;
+    public Uid uidObj;
+    public double value;
+    public double[] values;
+    public DrainType drainType;
+    public long usageTime;
+    public long cpuTime;
+    public long gpsTime;
+    public long wifiRunningTime;
+    public long cpuFgTime;
+    public long wakeLockTime;
+    public long mobileRxPackets;
+    public long mobileTxPackets;
+    public long mobileActive;
+    public int mobileActiveCount;
+    public double mobilemspp;         // milliseconds per packet
+    public long wifiRxPackets;
+    public long wifiTxPackets;
+    public long mobileRxBytes;
+    public long mobileTxBytes;
+    public long wifiRxBytes;
+    public long wifiTxBytes;
+    public double percent;
+    public double noCoveragePercent;
+    public String[] mPackages;
+    public String packageWithHighestDrain;
+
+    public enum DrainType {
+        IDLE,
+        CELL,
+        PHONE,
+        WIFI,
+        BLUETOOTH,
+        SCREEN,
+        APP,
+        USER,
+        UNACCOUNTED,
+        OVERCOUNTED
+    }
+
+    public BatterySipper(DrainType drainType, Uid uid, double[] values) {
+        this.values = values;
+        if (values != null) value = values[0];
+        this.drainType = drainType;
+        uidObj = uid;
+    }
+
+    public double[] getValues() {
+        return values;
+    }
+
+    public void computeMobilemspp() {
+        long packets = mobileRxPackets+mobileTxPackets;
+        mobilemspp = packets > 0 ? (mobileActive / (double)packets) : 0;
+    }
+
+    @Override
+    public int compareTo(BatterySipper other) {
+        // Return the flipped value because we want the items in descending order
+        return Double.compare(other.value, value);
+    }
+
+    /**
+     * Gets a list of packages associated with the current user
+     */
+    public String[] getPackages() {
+        return mPackages;
+    }
+
+    public int getUid() {
+        // Bail out if the current sipper is not an App sipper.
+        if (uidObj == null) {
+            return 0;
+        }
+        return uidObj.getUid();
+    }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
new file mode 100644
index 0000000..1dd1f5e
--- /dev/null
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -0,0 +1,807 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import static android.os.BatteryStats.NETWORK_MOBILE_RX_DATA;
+import static android.os.BatteryStats.NETWORK_MOBILE_TX_DATA;
+import static android.os.BatteryStats.NETWORK_WIFI_RX_DATA;
+import static android.os.BatteryStats.NETWORK_WIFI_TX_DATA;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.net.ConnectivityManager;
+import android.os.BatteryStats;
+import android.os.BatteryStats.Uid;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.telephony.SignalStrength;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.os.BatterySipper.DrainType;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A helper class for retrieving the power usage information for all applications and services.
+ *
+ * The caller must initialize this class as soon as activity object is ready to use (for example, in
+ * onAttach() for Fragment), call create() in onCreate() and call destroy() in onDestroy().
+ */
+public class BatteryStatsHelper {
+
+    private static final boolean DEBUG = false;
+
+    private static final String TAG = BatteryStatsHelper.class.getSimpleName();
+
+    private static BatteryStats sStatsXfer;
+
+    final private Context mContext;
+
+    private IBatteryStats mBatteryInfo;
+    private BatteryStats mStats;
+    private PowerProfile mPowerProfile;
+
+    private final List<BatterySipper> mUsageList = new ArrayList<BatterySipper>();
+    private final List<BatterySipper> mWifiSippers = new ArrayList<BatterySipper>();
+    private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>();
+    private final SparseArray<List<BatterySipper>> mUserSippers
+            = new SparseArray<List<BatterySipper>>();
+    private final SparseArray<Double> mUserPower = new SparseArray<Double>();
+
+    private final List<BatterySipper> mMobilemsppList = new ArrayList<BatterySipper>();
+
+    private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
+    private int mAsUser = 0;
+
+    long mRawRealtime;
+    long mRawUptime;
+    long mBatteryRealtime;
+    long mBatteryUptime;
+    long mTypeBatteryRealtime;
+    long mTypeBatteryUptime;
+
+    private long mStatsPeriod = 0;
+    private double mMaxPower = 1;
+    private double mComputedPower;
+    private double mTotalPower;
+    private double mWifiPower;
+    private double mBluetoothPower;
+    private double mMinDrainedPower;
+    private double mMaxDrainedPower;
+
+    // How much the apps together have kept the mobile radio active.
+    private long mAppMobileActive;
+
+    // How much the apps together have left WIFI running.
+    private long mAppWifiRunning;
+
+    public BatteryStatsHelper(Context context) {
+        mContext = context;
+    }
+
+    /** Clears the current stats and forces recreating for future use. */
+    public void clearStats() {
+        mStats = null;
+    }
+
+    public BatteryStats getStats() {
+        if (mStats == null) {
+            load();
+        }
+        return mStats;
+    }
+
+    public PowerProfile getPowerProfile() {
+        return mPowerProfile;
+    }
+
+    public void create(BatteryStats stats) {
+        mPowerProfile = new PowerProfile(mContext);
+        mStats = stats;
+    }
+
+    public void create(Bundle icicle) {
+        if (icicle != null) {
+            mStats = sStatsXfer;
+        }
+        mBatteryInfo = IBatteryStats.Stub.asInterface(
+                ServiceManager.getService(BatteryStats.SERVICE_NAME));
+        mPowerProfile = new PowerProfile(mContext);
+    }
+
+    public void storeState() {
+        sStatsXfer = mStats;
+    }
+
+    public static String makemAh(double power) {
+        if (power < .00001) return String.format("%.8f", power);
+        else if (power < .0001) return String.format("%.7f", power);
+        else if (power < .001) return String.format("%.6f", power);
+        else if (power < .01) return String.format("%.5f", power);
+        else if (power < .1) return String.format("%.4f", power);
+        else if (power < 1) return String.format("%.3f", power);
+        else if (power < 10) return String.format("%.2f", power);
+        else if (power < 100) return String.format("%.1f", power);
+        else return String.format("%.0f", power);
+    }
+
+    /**
+     * Refreshes the power usage list.
+     */
+    public void refreshStats(int statsType, int asUser) {
+        refreshStats(statsType, asUser, SystemClock.elapsedRealtime() * 1000,
+                SystemClock.uptimeMillis() * 1000);
+    }
+
+    public void refreshStats(int statsType, int asUser, long rawRealtimeUs, long rawUptimeUs) {
+        // Initialize mStats if necessary.
+        getStats();
+
+        mMaxPower = 0;
+        mComputedPower = 0;
+        mTotalPower = 0;
+        mWifiPower = 0;
+        mBluetoothPower = 0;
+        mAppMobileActive = 0;
+        mAppWifiRunning = 0;
+
+        mUsageList.clear();
+        mWifiSippers.clear();
+        mBluetoothSippers.clear();
+        mUserSippers.clear();
+        mUserPower.clear();
+        mMobilemsppList.clear();
+
+        if (mStats == null) {
+            return;
+        }
+
+        mStatsType = statsType;
+        mAsUser = asUser;
+        mRawUptime = rawUptimeUs;
+        mRawRealtime = rawRealtimeUs;
+        mBatteryUptime = mStats.getBatteryUptime(rawUptimeUs);
+        mBatteryRealtime = mStats.getBatteryRealtime(rawRealtimeUs);
+        mTypeBatteryUptime = mStats.computeBatteryUptime(rawUptimeUs, mStatsType);
+        mTypeBatteryRealtime = mStats.computeBatteryRealtime(rawRealtimeUs, mStatsType);
+
+        if (DEBUG) {
+            Log.d(TAG, "Raw time: realtime=" + (rawRealtimeUs/1000) + " uptime="
+                    + (rawUptimeUs/1000));
+            Log.d(TAG, "Battery time: realtime=" + (mBatteryRealtime/1000) + " uptime="
+                    + (mBatteryUptime/1000));
+            Log.d(TAG, "Battery type time: realtime=" + (mTypeBatteryRealtime/1000) + " uptime="
+                    + (mTypeBatteryUptime/1000));
+        }
+        mMinDrainedPower = (mStats.getLowDischargeAmountSinceCharge()
+                * mPowerProfile.getBatteryCapacity()) / 100;
+        mMaxDrainedPower = (mStats.getHighDischargeAmountSinceCharge()
+                * mPowerProfile.getBatteryCapacity()) / 100;
+
+        processAppUsage();
+
+        // Before aggregating apps in to users, collect all apps to sort by their ms per packet.
+        for (int i=0; i<mUsageList.size(); i++) {
+            BatterySipper bs = mUsageList.get(i);
+            bs.computeMobilemspp();
+            if (bs.mobilemspp != 0) {
+                mMobilemsppList.add(bs);
+            }
+        }
+        for (int i=0; i<mUserSippers.size(); i++) {
+            List<BatterySipper> user = mUserSippers.valueAt(i);
+            for (int j=0; j<user.size(); j++) {
+                BatterySipper bs = user.get(j);
+                bs.computeMobilemspp();
+                if (bs.mobilemspp != 0) {
+                    mMobilemsppList.add(bs);
+                }
+            }
+        }
+        Collections.sort(mMobilemsppList, new Comparator<BatterySipper>() {
+            @Override
+            public int compare(BatterySipper lhs, BatterySipper rhs) {
+                if (lhs.mobilemspp < rhs.mobilemspp) {
+                    return 1;
+                } else if (lhs.mobilemspp > rhs.mobilemspp) {
+                    return -1;
+                }
+                return 0;
+            }
+        });
+
+        processMiscUsage();
+
+        if (DEBUG) {
+            Log.d(TAG, "Accuracy: total computed=" + makemAh(mComputedPower) + ", min discharge="
+                    + makemAh(mMinDrainedPower) + ", max discharge=" + makemAh(mMaxDrainedPower));
+        }
+        mTotalPower = mComputedPower;
+        if (mStats.getLowDischargeAmountSinceCharge() > 1) {
+            if (mMinDrainedPower > mComputedPower) {
+                double amount = mMinDrainedPower - mComputedPower;
+                mTotalPower = mMinDrainedPower;
+                addEntryNoTotal(BatterySipper.DrainType.UNACCOUNTED, 0, amount);
+            } else if (mMaxDrainedPower < mComputedPower) {
+                double amount = mComputedPower - mMaxDrainedPower;
+                addEntryNoTotal(BatterySipper.DrainType.OVERCOUNTED, 0, amount);
+            }
+        }
+
+        Collections.sort(mUsageList);
+    }
+
+    private void processAppUsage() {
+        SensorManager sensorManager = (SensorManager) mContext.getSystemService(
+                Context.SENSOR_SERVICE);
+        final int which = mStatsType;
+        final int speedSteps = mPowerProfile.getNumSpeedSteps();
+        final double[] powerCpuNormal = new double[speedSteps];
+        final long[] cpuSpeedStepTimes = new long[speedSteps];
+        for (int p = 0; p < speedSteps; p++) {
+            powerCpuNormal[p] = mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_ACTIVE, p);
+        }
+        final double mobilePowerPerPacket = getMobilePowerPerPacket();
+        final double mobilePowerPerMs = getMobilePowerPerMs();
+        final double wifiPowerPerPacket = getWifiPowerPerPacket();
+        long appWakelockTimeUs = 0;
+        BatterySipper osApp = null;
+        mStatsPeriod = mTypeBatteryRealtime;
+        SparseArray<? extends Uid> uidStats = mStats.getUidStats();
+        final int NU = uidStats.size();
+        for (int iu = 0; iu < NU; iu++) {
+            Uid u = uidStats.valueAt(iu);
+            double p; // in mAs
+            double power = 0; // in mAs
+            double highestDrain = 0;
+            String packageWithHighestDrain = null;
+            Map<String, ? extends BatteryStats.Uid.Proc> processStats = u.getProcessStats();
+            long cpuTime = 0;
+            long cpuFgTime = 0;
+            long wakelockTime = 0;
+            long gpsTime = 0;
+            if (processStats.size() > 0) {
+                // Process CPU time
+                for (Map.Entry<String, ? extends BatteryStats.Uid.Proc> ent
+                        : processStats.entrySet()) {
+                    Uid.Proc ps = ent.getValue();
+                    final long userTime = ps.getUserTime(which);
+                    final long systemTime = ps.getSystemTime(which);
+                    final long foregroundTime = ps.getForegroundTime(which);
+                    cpuFgTime += foregroundTime * 10; // convert to millis
+                    final long tmpCpuTime = (userTime + systemTime) * 10; // convert to millis
+                    int totalTimeAtSpeeds = 0;
+                    // Get the total first
+                    for (int step = 0; step < speedSteps; step++) {
+                        cpuSpeedStepTimes[step] = ps.getTimeAtCpuSpeedStep(step, which);
+                        totalTimeAtSpeeds += cpuSpeedStepTimes[step];
+                    }
+                    if (totalTimeAtSpeeds == 0) totalTimeAtSpeeds = 1;
+                    // Then compute the ratio of time spent at each speed
+                    double processPower = 0;
+                    for (int step = 0; step < speedSteps; step++) {
+                        double ratio = (double) cpuSpeedStepTimes[step] / totalTimeAtSpeeds;
+                        if (DEBUG && ratio != 0) Log.d(TAG, "UID " + u.getUid() + ": CPU step #"
+                                + step + " ratio=" + makemAh(ratio) + " power="
+                                + makemAh(ratio*tmpCpuTime*powerCpuNormal[step] / (60*60*1000)));
+                        processPower += ratio * tmpCpuTime * powerCpuNormal[step];
+                    }
+                    cpuTime += tmpCpuTime;
+                    if (DEBUG && processPower != 0) {
+                        Log.d(TAG, String.format("process %s, cpu power=%s",
+                                ent.getKey(), makemAh(processPower / (60*60*1000))));
+                    }
+                    power += processPower;
+                    if (packageWithHighestDrain == null
+                            || packageWithHighestDrain.startsWith("*")) {
+                        highestDrain = processPower;
+                        packageWithHighestDrain = ent.getKey();
+                    } else if (highestDrain < processPower
+                            && !ent.getKey().startsWith("*")) {
+                        highestDrain = processPower;
+                        packageWithHighestDrain = ent.getKey();
+                    }
+                }
+            }
+            if (cpuFgTime > cpuTime) {
+                if (DEBUG && cpuFgTime > cpuTime + 10000) {
+                    Log.d(TAG, "WARNING! Cputime is more than 10 seconds behind Foreground time");
+                }
+                cpuTime = cpuFgTime; // Statistics may not have been gathered yet.
+            }
+            power /= (60*60*1000);
+
+            // Process wake lock usage
+            Map<String, ? extends BatteryStats.Uid.Wakelock> wakelockStats = u.getWakelockStats();
+            for (Map.Entry<String, ? extends BatteryStats.Uid.Wakelock> wakelockEntry
+                    : wakelockStats.entrySet()) {
+                Uid.Wakelock wakelock = wakelockEntry.getValue();
+                // Only care about partial wake locks since full wake locks
+                // are canceled when the user turns the screen off.
+                BatteryStats.Timer timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL);
+                if (timer != null) {
+                    wakelockTime += timer.getTotalTimeLocked(mRawRealtime, which);
+                }
+            }
+            appWakelockTimeUs += wakelockTime;
+            wakelockTime /= 1000; // convert to millis
+
+            // Add cost of holding a wake lock
+            p = (wakelockTime
+                    * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE)) / (60*60*1000);
+            if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wake "
+                    + wakelockTime + " power=" + makemAh(p));
+            power += p;
+
+            // Add cost of mobile traffic
+            final long mobileRx = u.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType);
+            final long mobileTx = u.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
+            final long mobileRxB = u.getNetworkActivityBytes(NETWORK_MOBILE_RX_DATA, mStatsType);
+            final long mobileTxB = u.getNetworkActivityBytes(NETWORK_MOBILE_TX_DATA, mStatsType);
+            final long mobileActive = u.getMobileRadioActiveTime(mStatsType);
+            if (mobileActive > 0) {
+                // We are tracking when the radio is up, so can use the active time to
+                // determine power use.
+                mAppMobileActive += mobileActive;
+                p = (mobilePowerPerMs * mobileActive) / 1000;
+            } else {
+                // We are not tracking when the radio is up, so must approximate power use
+                // based on the number of packets.
+                p = (mobileRx + mobileTx) * mobilePowerPerPacket;
+            }
+            if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": mobile packets "
+                    + (mobileRx+mobileTx) + " active time " + mobileActive
+                    + " power=" + makemAh(p));
+            power += p;
+
+            // Add cost of wifi traffic
+            final long wifiRx = u.getNetworkActivityPackets(NETWORK_WIFI_RX_DATA, mStatsType);
+            final long wifiTx = u.getNetworkActivityPackets(NETWORK_WIFI_TX_DATA, mStatsType);
+            final long wifiRxB = u.getNetworkActivityBytes(NETWORK_WIFI_RX_DATA, mStatsType);
+            final long wifiTxB = u.getNetworkActivityBytes(NETWORK_WIFI_TX_DATA, mStatsType);
+            p = (wifiRx + wifiTx) * wifiPowerPerPacket;
+            if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wifi packets "
+                    + (mobileRx+mobileTx) + " power=" + makemAh(p));
+            power += p;
+
+            // Add cost of keeping WIFI running.
+            long wifiRunningTimeMs = u.getWifiRunningTime(mRawRealtime, which) / 1000;
+            mAppWifiRunning += wifiRunningTimeMs;
+            p = (wifiRunningTimeMs
+                    * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)) / (60*60*1000);
+            if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wifi running "
+                    + wifiRunningTimeMs + " power=" + makemAh(p));
+            power += p;
+
+            // Add cost of WIFI scans
+            long wifiScanTimeMs = u.getWifiScanTime(mRawRealtime, which) / 1000;
+            p = (wifiScanTimeMs
+                    * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_SCAN)) / (60*60*1000);
+            if (DEBUG) Log.d(TAG, "UID " + u.getUid() + ": wifi scan " + wifiScanTimeMs
+                    + " power=" + makemAh(p));
+            power += p;
+            for (int bin = 0; bin < BatteryStats.Uid.NUM_WIFI_BATCHED_SCAN_BINS; bin++) {
+                long batchScanTimeMs = u.getWifiBatchedScanTime(bin, mRawRealtime, which) / 1000;
+                p = ((batchScanTimeMs
+                        * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_BATCHED_SCAN, bin))
+                    ) / (60*60*1000);
+                if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": wifi batched scan # " + bin
+                        + " time=" + batchScanTimeMs + " power=" + makemAh(p));
+                power += p;
+            }
+
+            // Process Sensor usage
+            Map<Integer, ? extends BatteryStats.Uid.Sensor> sensorStats = u.getSensorStats();
+            for (Map.Entry<Integer, ? extends BatteryStats.Uid.Sensor> sensorEntry
+                    : sensorStats.entrySet()) {
+                Uid.Sensor sensor = sensorEntry.getValue();
+                int sensorHandle = sensor.getHandle();
+                BatteryStats.Timer timer = sensor.getSensorTime();
+                long sensorTime = timer.getTotalTimeLocked(mRawRealtime, which) / 1000;
+                double multiplier = 0;
+                switch (sensorHandle) {
+                    case Uid.Sensor.GPS:
+                        multiplier = mPowerProfile.getAveragePower(PowerProfile.POWER_GPS_ON);
+                        gpsTime = sensorTime;
+                        break;
+                    default:
+                        List<Sensor> sensorList = sensorManager.getSensorList(
+                                android.hardware.Sensor.TYPE_ALL);
+                        for (android.hardware.Sensor s : sensorList) {
+                            if (s.getHandle() == sensorHandle) {
+                                multiplier = s.getPower();
+                                break;
+                            }
+                        }
+                }
+                p = (multiplier * sensorTime) / (60*60*1000);
+                if (DEBUG && p != 0) Log.d(TAG, "UID " + u.getUid() + ": sensor #" + sensorHandle
+                        + " time=" + sensorTime + " power=" + makemAh(p));
+                power += p;
+            }
+
+            if (DEBUG && power != 0) Log.d(TAG, String.format("UID %d: total power=%s",
+                    u.getUid(), makemAh(power)));
+
+            // Add the app to the list if it is consuming power
+            final int userId = UserHandle.getUserId(u.getUid());
+            if (power != 0 || u.getUid() == 0) {
+                BatterySipper app = new BatterySipper(BatterySipper.DrainType.APP, u,
+                        new double[] {power});
+                app.cpuTime = cpuTime;
+                app.gpsTime = gpsTime;
+                app.wifiRunningTime = wifiRunningTimeMs;
+                app.cpuFgTime = cpuFgTime;
+                app.wakeLockTime = wakelockTime;
+                app.mobileRxPackets = mobileRx;
+                app.mobileTxPackets = mobileTx;
+                app.mobileActive = mobileActive / 1000;
+                app.mobileActiveCount = u.getMobileRadioActiveCount(mStatsType);
+                app.wifiRxPackets = wifiRx;
+                app.wifiTxPackets = wifiTx;
+                app.mobileRxBytes = mobileRxB;
+                app.mobileTxBytes = mobileTxB;
+                app.wifiRxBytes = wifiRxB;
+                app.wifiTxBytes = wifiTxB;
+                app.packageWithHighestDrain = packageWithHighestDrain;
+                if (u.getUid() == Process.WIFI_UID) {
+                    mWifiSippers.add(app);
+                    mWifiPower += power;
+                } else if (u.getUid() == Process.BLUETOOTH_UID) {
+                    mBluetoothSippers.add(app);
+                    mBluetoothPower += power;
+                } else if (mAsUser != UserHandle.USER_ALL && userId != mAsUser
+                        && UserHandle.getAppId(u.getUid()) >= Process.FIRST_APPLICATION_UID) {
+                    List<BatterySipper> list = mUserSippers.get(userId);
+                    if (list == null) {
+                        list = new ArrayList<BatterySipper>();
+                        mUserSippers.put(userId, list);
+                    }
+                    list.add(app);
+                    if (power != 0) {
+                        Double userPower = mUserPower.get(userId);
+                        if (userPower == null) {
+                            userPower = power;
+                        } else {
+                            userPower += power;
+                        }
+                        mUserPower.put(userId, userPower);
+                    }
+                } else {
+                    mUsageList.add(app);
+                    if (power > mMaxPower) mMaxPower = power;
+                    mComputedPower += power;
+                }
+                if (u.getUid() == 0) {
+                    osApp = app;
+                }
+            }
+        }
+
+        // The device has probably been awake for longer than the screen on
+        // time and application wake lock time would account for.  Assign
+        // this remainder to the OS, if possible.
+        if (osApp != null) {
+            long wakeTimeMillis = mBatteryUptime / 1000;
+            wakeTimeMillis -= (appWakelockTimeUs / 1000)
+                    + (mStats.getScreenOnTime(mRawRealtime, which) / 1000);
+            if (wakeTimeMillis > 0) {
+                double power = (wakeTimeMillis
+                        * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_AWAKE))
+                        /  (60*60*1000);
+                if (DEBUG) Log.d(TAG, "OS wakeLockTime " + wakeTimeMillis + " power "
+                        + makemAh(power));
+                osApp.wakeLockTime += wakeTimeMillis;
+                osApp.value += power;
+                osApp.values[0] += power;
+                if (osApp.value > mMaxPower) mMaxPower = osApp.value;
+                mComputedPower += power;
+            }
+        }
+    }
+
+    private void addPhoneUsage() {
+        long phoneOnTimeMs = mStats.getPhoneOnTime(mRawRealtime, mStatsType) / 1000;
+        double phoneOnPower = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
+                * phoneOnTimeMs / (60*60*1000);
+        if (phoneOnPower != 0) {
+            BatterySipper bs = addEntry(BatterySipper.DrainType.PHONE, phoneOnTimeMs, phoneOnPower);
+        }
+    }
+
+    private void addScreenUsage() {
+        double power = 0;
+        long screenOnTimeMs = mStats.getScreenOnTime(mRawRealtime, mStatsType) / 1000;
+        power += screenOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_ON);
+        final double screenFullPower =
+                mPowerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);
+        for (int i = 0; i < BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; i++) {
+            double screenBinPower = screenFullPower * (i + 0.5f)
+                    / BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
+            long brightnessTime = mStats.getScreenBrightnessTime(i, mRawRealtime, mStatsType)
+                    / 1000;
+            double p = screenBinPower*brightnessTime;
+            if (DEBUG && p != 0) {
+                Log.d(TAG, "Screen bin #" + i + ": time=" + brightnessTime
+                        + " power=" + makemAh(p / (60 * 60 * 1000)));
+            }
+            power += p;
+        }
+        power /= (60*60*1000); // To hours
+        if (power != 0) {
+            addEntry(BatterySipper.DrainType.SCREEN, screenOnTimeMs, power);
+        }
+    }
+
+    private void addRadioUsage() {
+        double power = 0;
+        final int BINS = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
+        long signalTimeMs = 0;
+        long noCoverageTimeMs = 0;
+        for (int i = 0; i < BINS; i++) {
+            long strengthTimeMs = mStats.getPhoneSignalStrengthTime(i, mRawRealtime, mStatsType)
+                    / 1000;
+            double p = (strengthTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ON, i))
+                        / (60*60*1000);
+            if (DEBUG && p != 0) {
+                Log.d(TAG, "Cell strength #" + i + ": time=" + strengthTimeMs + " power="
+                        + makemAh(p));
+            }
+            power += p;
+            signalTimeMs += strengthTimeMs;
+            if (i == 0) {
+                noCoverageTimeMs = strengthTimeMs;
+            }
+        }
+        long scanningTimeMs = mStats.getPhoneSignalScanningTime(mRawRealtime, mStatsType)
+                / 1000;
+        double p = (scanningTimeMs * mPowerProfile.getAveragePower(
+                        PowerProfile.POWER_RADIO_SCANNING))
+                        / (60*60*1000);
+        if (DEBUG && p != 0) {
+            Log.d(TAG, "Cell radio scanning: time=" + scanningTimeMs + " power=" + makemAh(p));
+        }
+        power += p;
+        long radioActiveTimeUs = mStats.getMobileRadioActiveTime(mRawRealtime, mStatsType);
+        long remainingActiveTime = (radioActiveTimeUs - mAppMobileActive) / 1000;
+        if (remainingActiveTime > 0) {
+            power += getMobilePowerPerMs() * remainingActiveTime;
+        }
+        if (power != 0) {
+            BatterySipper bs =
+                    addEntry(BatterySipper.DrainType.CELL, signalTimeMs, power);
+            if (signalTimeMs != 0) {
+                bs.noCoveragePercent = noCoverageTimeMs * 100.0 / signalTimeMs;
+            }
+            bs.mobileActive = remainingActiveTime;
+            bs.mobileActiveCount = mStats.getMobileRadioActiveUnknownCount(mStatsType);
+        }
+    }
+
+    private void aggregateSippers(BatterySipper bs, List<BatterySipper> from, String tag) {
+        for (int i=0; i<from.size(); i++) {
+            BatterySipper wbs = from.get(i);
+            if (DEBUG) Log.d(TAG, tag + " adding sipper " + wbs + ": cpu=" + wbs.cpuTime);
+            bs.cpuTime += wbs.cpuTime;
+            bs.gpsTime += wbs.gpsTime;
+            bs.wifiRunningTime += wbs.wifiRunningTime;
+            bs.cpuFgTime += wbs.cpuFgTime;
+            bs.wakeLockTime += wbs.wakeLockTime;
+            bs.mobileRxPackets += wbs.mobileRxPackets;
+            bs.mobileTxPackets += wbs.mobileTxPackets;
+            bs.mobileActive += wbs.mobileActive;
+            bs.mobileActiveCount += wbs.mobileActiveCount;
+            bs.wifiRxPackets += wbs.wifiRxPackets;
+            bs.wifiTxPackets += wbs.wifiTxPackets;
+            bs.mobileRxBytes += wbs.mobileRxBytes;
+            bs.mobileTxBytes += wbs.mobileTxBytes;
+            bs.wifiRxBytes += wbs.wifiRxBytes;
+            bs.wifiTxBytes += wbs.wifiTxBytes;
+        }
+        bs.computeMobilemspp();
+    }
+
+    private void addWiFiUsage() {
+        long onTimeMs = mStats.getWifiOnTime(mRawRealtime, mStatsType) / 1000;
+        long runningTimeMs = mStats.getGlobalWifiRunningTime(mRawRealtime, mStatsType) / 1000;
+        if (DEBUG) Log.d(TAG, "WIFI runningTime=" + runningTimeMs
+                + " app runningTime=" + mAppWifiRunning);
+        runningTimeMs -= mAppWifiRunning;
+        if (runningTimeMs < 0) runningTimeMs = 0;
+        double wifiPower = (onTimeMs * 0 /* TODO */
+                    * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON)
+                + runningTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ON))
+                / (60*60*1000);
+        if (DEBUG && wifiPower != 0) {
+            Log.d(TAG, "Wifi: time=" + runningTimeMs + " power=" + makemAh(wifiPower));
+        }
+        if ((wifiPower+mWifiPower) != 0) {
+            BatterySipper bs = addEntry(BatterySipper.DrainType.WIFI, runningTimeMs,
+                    wifiPower + mWifiPower);
+            aggregateSippers(bs, mWifiSippers, "WIFI");
+        }
+    }
+
+    private void addIdleUsage() {
+        long idleTimeMs = (mTypeBatteryRealtime
+                - mStats.getScreenOnTime(mRawRealtime, mStatsType)) / 1000;
+        double idlePower = (idleTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_CPU_IDLE))
+                / (60*60*1000);
+        if (DEBUG && idlePower != 0) {
+            Log.d(TAG, "Idle: time=" + idleTimeMs + " power=" + makemAh(idlePower));
+        }
+        if (idlePower != 0) {
+            addEntry(BatterySipper.DrainType.IDLE, idleTimeMs, idlePower);
+        }
+    }
+
+    private void addBluetoothUsage() {
+        long btOnTimeMs = mStats.getBluetoothOnTime(mRawRealtime, mStatsType) / 1000;
+        double btPower = btOnTimeMs * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_ON)
+                / (60*60*1000);
+        if (DEBUG && btPower != 0) {
+            Log.d(TAG, "Bluetooth: time=" + btOnTimeMs + " power=" + makemAh(btPower));
+        }
+        int btPingCount = mStats.getBluetoothPingCount();
+        double pingPower = (btPingCount
+                * mPowerProfile.getAveragePower(PowerProfile.POWER_BLUETOOTH_AT_CMD))
+                / (60*60*1000);
+        if (DEBUG && pingPower != 0) {
+            Log.d(TAG, "Bluetooth ping: count=" + btPingCount + " power=" + makemAh(pingPower));
+        }
+        btPower += pingPower;
+        if ((btPower+mBluetoothPower) != 0) {
+            BatterySipper bs = addEntry(BatterySipper.DrainType.BLUETOOTH, btOnTimeMs,
+                    btPower + mBluetoothPower);
+            aggregateSippers(bs, mBluetoothSippers, "Bluetooth");
+        }
+    }
+
+    private void addUserUsage() {
+        for (int i=0; i<mUserSippers.size(); i++) {
+            final int userId = mUserSippers.keyAt(i);
+            final List<BatterySipper> sippers = mUserSippers.valueAt(i);
+            Double userPower = mUserPower.get(userId);
+            double power = (userPower != null) ? userPower : 0.0;
+            BatterySipper bs = addEntry(BatterySipper.DrainType.USER, 0, power);
+            bs.userId = userId;
+            aggregateSippers(bs, sippers, "User");
+        }
+    }
+
+    /**
+     * Return estimated power (in mAs) of sending or receiving a packet with the mobile radio.
+     */
+    private double getMobilePowerPerPacket() {
+        final long MOBILE_BPS = 200000; // TODO: Extract average bit rates from system
+        final double MOBILE_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE)
+                / 3600;
+
+        final long mobileRx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_RX_DATA, mStatsType);
+        final long mobileTx = mStats.getNetworkActivityPackets(NETWORK_MOBILE_TX_DATA, mStatsType);
+        final long mobileData = mobileRx + mobileTx;
+
+        final long radioDataUptimeMs
+                = mStats.getMobileRadioActiveTime(mRawRealtime, mStatsType) / 1000;
+        final double mobilePps = (mobileData != 0 && radioDataUptimeMs != 0)
+                ? (mobileData / (double)radioDataUptimeMs)
+                : (((double)MOBILE_BPS) / 8 / 2048);
+
+        return (MOBILE_POWER / mobilePps) / (60*60);
+    }
+
+    /**
+     * Return estimated power (in mAs) of keeping the radio up
+     */
+    private double getMobilePowerPerMs() {
+        return mPowerProfile.getAveragePower(PowerProfile.POWER_RADIO_ACTIVE) / (60*60*1000);
+    }
+
+    /**
+     * Return estimated power (in mAs) of sending a byte with the Wi-Fi radio.
+     */
+    private double getWifiPowerPerPacket() {
+        final long WIFI_BPS = 1000000; // TODO: Extract average bit rates from system
+        final double WIFI_POWER = mPowerProfile.getAveragePower(PowerProfile.POWER_WIFI_ACTIVE)
+                / 3600;
+        return (WIFI_POWER / (((double)WIFI_BPS) / 8 / 2048)) / (60*60);
+    }
+
+    private void processMiscUsage() {
+        addUserUsage();
+        addPhoneUsage();
+        addScreenUsage();
+        addWiFiUsage();
+        addBluetoothUsage();
+        addIdleUsage(); // Not including cellular idle power
+        // Don't compute radio usage if it's a wifi-only device
+        ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        if (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)) {
+            addRadioUsage();
+        }
+    }
+
+    private BatterySipper addEntry(DrainType drainType, long time, double power) {
+        mComputedPower += power;
+        return addEntryNoTotal(drainType, time, power);
+    }
+
+    private BatterySipper addEntryNoTotal(DrainType drainType, long time, double power) {
+        if (power > mMaxPower) mMaxPower = power;
+        BatterySipper bs = new BatterySipper(drainType, null, new double[] {power});
+        bs.usageTime = time;
+        mUsageList.add(bs);
+        return bs;
+    }
+
+    public List<BatterySipper> getUsageList() {
+        return mUsageList;
+    }
+
+    public List<BatterySipper> getMobilemsppList() {
+        return mMobilemsppList;
+    }
+
+    public long getStatsPeriod() { return mStatsPeriod; }
+
+    public int getStatsType() { return mStatsType; };
+
+    public double getMaxPower() { return mMaxPower; }
+
+    public double getTotalPower() { return mTotalPower; }
+
+    public double getComputedPower() { return mComputedPower; }
+
+    public double getMinDrainedPower() {
+        return mMinDrainedPower;
+    }
+
+    public double getMaxDrainedPower() {
+        return mMaxDrainedPower;
+    }
+
+    private void load() {
+        if (mBatteryInfo == null) {
+            return;
+        }
+        try {
+            byte[] data = mBatteryInfo.getStatistics();
+            Parcel parcel = Parcel.obtain();
+            parcel.unmarshall(data, 0, data.length);
+            parcel.setDataPosition(0);
+            BatteryStatsImpl stats = com.android.internal.os.BatteryStatsImpl.CREATOR
+                    .createFromParcel(parcel);
+            stats.distributeWorkLocked(BatteryStats.STATS_SINCE_CHARGED);
+            mStats = stats;
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException:", e);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8728610..39636fe 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -16,12 +16,15 @@
 
 package com.android.internal.os;
 
+import static android.net.NetworkStats.UID_ALL;
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
+import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkStats;
+import android.os.BadParcelableException;
 import android.os.BatteryManager;
 import android.os.BatteryStats;
 import android.os.FileUtils;
@@ -44,24 +47,23 @@
 import android.util.Printer;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
 import android.util.TimeUtils;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.net.NetworkStatsFactory;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.JournaledFile;
-import com.google.android.collect.Sets;
 
-import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -85,7 +87,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 67 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 101 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -141,6 +143,11 @@
     private BatteryCallback mCallback;
 
     /**
+     * Mapping isolated uids to the actual owning app uid.
+     */
+    final SparseIntArray mIsolatedUids = new SparseIntArray();
+
+    /**
      * The statistics we have collected organized by uids.
      */
     final SparseArray<BatteryStatsImpl.Uid> mUidStats =
@@ -167,13 +174,24 @@
 
     // These are the objects that will want to do something when the device
     // is unplugged from power.
-    final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>();
+    final TimeBase mOnBatteryTimeBase = new TimeBase();
+
+    // These are the objects that will want to do something when the device
+    // is unplugged from power *and* the screen is off.
+    final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
+
+    // Set to true when we want to distribute CPU across wakelocks for the next
+    // CPU update, even if we aren't currently running wake locks.
+    boolean mDistributeWakelockCpu;
 
     boolean mShuttingDown;
 
+    HashMap<String, SparseBooleanArray>[] mActiveEvents
+            = (HashMap<String, SparseBooleanArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
+
     long mHistoryBaseTime;
     boolean mHaveBatteryLevel = false;
-    boolean mRecordingHistory = true;
+    boolean mRecordingHistory = false;
     int mNumHistoryItems;
 
     static final int MAX_HISTORY_BUFFER = 128*1024; // 128KB
@@ -182,9 +200,18 @@
     final HistoryItem mHistoryLastWritten = new HistoryItem();
     final HistoryItem mHistoryLastLastWritten = new HistoryItem();
     final HistoryItem mHistoryReadTmp = new HistoryItem();
+    final HistoryItem mHistoryAddTmp = new HistoryItem();
+    final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<HistoryTag, Integer>();
+    String[] mReadHistoryStrings;
+    int[] mReadHistoryUids;
+    int mReadHistoryChars;
+    int mNextHistoryTagIdx = 0;
+    int mNumHistoryTagChars = 0;
     int mHistoryBufferLastPos = -1;
     boolean mHistoryOverflow = false;
-    long mLastHistoryTime = 0;
+    long mLastHistoryElapsedRealtime = 0;
+    long mTrackRunningHistoryElapsedRealtime = 0;
+    long mTrackRunningHistoryUptime = 0;
 
     final HistoryItem mHistoryCur = new HistoryItem();
 
@@ -199,17 +226,15 @@
 
     int mStartCount;
 
-    long mBatteryUptime;
-    long mBatteryLastUptime;
-    long mBatteryRealtime;
-    long mBatteryLastRealtime;
+    long mStartClockTime;
 
     long mUptime;
     long mUptimeStart;
-    long mLastUptime;
     long mRealtime;
     long mRealtimeStart;
-    long mLastRealtime;
+
+    int mWakeLockNesting;
+    boolean mWakeLockImportant;
 
     boolean mScreenOn;
     StopwatchTimer mScreenOnTimer;
@@ -239,19 +264,33 @@
     final StopwatchTimer[] mPhoneDataConnectionsTimer =
             new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
 
-    final LongSamplingCounter[] mNetworkActivityCounters =
+    final LongSamplingCounter[] mNetworkByteActivityCounters =
+            new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+    final LongSamplingCounter[] mNetworkPacketActivityCounters =
             new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
 
     boolean mWifiOn;
     StopwatchTimer mWifiOnTimer;
-    int mWifiOnUid = -1;
 
     boolean mGlobalWifiRunning;
     StopwatchTimer mGlobalWifiRunningTimer;
 
+    int mWifiState = -1;
+    final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
+
     boolean mBluetoothOn;
     StopwatchTimer mBluetoothOnTimer;
 
+    int mBluetoothState = -1;
+    final StopwatchTimer[] mBluetoothStateTimer = new StopwatchTimer[NUM_BLUETOOTH_STATES];
+
+    boolean mMobileRadioActive;
+    StopwatchTimer mMobileRadioActiveTimer;
+    StopwatchTimer mMobileRadioActivePerAppTimer;
+    LongSamplingCounter mMobileRadioActiveAdjustedTime;
+    LongSamplingCounter mMobileRadioActiveUnknownTime;
+    LongSamplingCounter mMobileRadioActiveUnknownCount;
+
     /** Bluetooth headset object */
     BluetoothHeadset mBtHeadset;
 
@@ -261,13 +300,6 @@
      */
     boolean mOnBattery;
     boolean mOnBatteryInternal;
-    long mTrackBatteryPastUptime;
-    long mTrackBatteryUptimeStart;
-    long mTrackBatteryPastRealtime;
-    long mTrackBatteryRealtimeStart;
-
-    long mUnpluggedBatteryUptime;
-    long mUnpluggedBatteryRealtime;
 
     /*
      * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
@@ -286,9 +318,6 @@
 
     long mLastWriteTime = 0; // Milliseconds
 
-    private long mRadioDataUptime;
-    private long mRadioDataStart;
-
     private int mBluetoothPingCount;
     private int mBluetoothPingStart = -1;
 
@@ -302,12 +331,21 @@
     private final HashMap<String, SamplingTimer> mKernelWakelockStats =
             new HashMap<String, SamplingTimer>();
 
-    public Map<String, ? extends SamplingTimer> getKernelWakelockStats() {
+    public Map<String, ? extends Timer> getKernelWakelockStats() {
         return mKernelWakelockStats;
     }
 
     private static int sKernelWakelockUpdateVersion = 0;
 
+    String mLastWakeupReason = null;
+    long mLastWakeupUptimeMs = 0;
+    private final HashMap<String, LongSamplingCounter> mWakeupReasonStats =
+            new HashMap<String, LongSamplingCounter>();
+
+    public Map<String, ? extends LongCounter> getWakeupReasonStats() {
+        return mWakeupReasonStats;
+    }
+
     private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
         Process.PROC_TAB_TERM|Process.PROC_OUT_STRING|                // 0: name
                               Process.PROC_QUOTES,
@@ -340,15 +378,18 @@
     private final Map<String, KernelWakelockStats> mProcWakelockFileStats =
             new HashMap<String, KernelWakelockStats>();
 
-    private HashMap<String, Integer> mUidCache = new HashMap<String, Integer>();
-
     private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
-    private NetworkStats mLastSnapshot;
+    private NetworkStats mCurMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mLastMobileSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mCurWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mLastWifiSnapshot = new NetworkStats(SystemClock.elapsedRealtime(), 50);
+    private NetworkStats mTmpNetworkStats;
+    private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
 
     @GuardedBy("this")
-    private HashSet<String> mMobileIfaces = Sets.newHashSet();
+    private String[] mMobileIfaces = new String[0];
     @GuardedBy("this")
-    private HashSet<String> mWifiIfaces = Sets.newHashSet();
+    private String[] mWifiIfaces = new String[0];
 
     // For debugging
     public BatteryStatsImpl() {
@@ -356,35 +397,226 @@
         mHandler = null;
     }
 
-    public static interface Unpluggable {
-        void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
-        void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime);
+    public static interface TimeBaseObs {
+        void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
+        void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
+    }
+
+    static class TimeBase {
+        private final ArrayList<TimeBaseObs> mObservers = new ArrayList<TimeBaseObs>();
+
+        private long mUptime;
+        private long mRealtime;
+
+        private boolean mRunning;
+
+        private long mPastUptime;
+        private long mUptimeStart;
+        private long mPastRealtime;
+        private long mRealtimeStart;
+        private long mUnpluggedUptime;
+        private long mUnpluggedRealtime;
+
+        public void dump(PrintWriter pw, String prefix) {
+            StringBuilder sb = new StringBuilder(128);
+            pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("mUptime=");
+                    formatTimeMs(sb, mUptime / 1000);
+            pw.println(sb.toString());
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("mRealtime=");
+                    formatTimeMs(sb, mRealtime / 1000);
+            pw.println(sb.toString());
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("mPastUptime=");
+                    formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
+                    formatTimeMs(sb, mUptimeStart / 1000);
+                    sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
+            pw.println(sb.toString());
+            sb.setLength(0);
+            sb.append(prefix);
+                    sb.append("mPastRealtime=");
+                    formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
+                    formatTimeMs(sb, mRealtimeStart / 1000);
+                    sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
+            pw.println(sb.toString());
+        }
+
+        public void add(TimeBaseObs observer) {
+            mObservers.add(observer);
+        }
+
+        public void remove(TimeBaseObs observer) {
+            if (!mObservers.remove(observer)) {
+                Slog.wtf(TAG, "Removed unknown observer: " + observer);
+            }
+        }
+
+        public void init(long uptime, long realtime) {
+            mRealtime = 0;
+            mUptime = 0;
+            mPastUptime = 0;
+            mPastRealtime = 0;
+            mUptimeStart = uptime;
+            mRealtimeStart = realtime;
+            mUnpluggedUptime = getUptime(mUptimeStart);
+            mUnpluggedRealtime = getRealtime(mRealtimeStart);
+        }
+
+        public void reset(long uptime, long realtime) {
+            if (!mRunning) {
+                mPastUptime = 0;
+                mPastRealtime = 0;
+            } else {
+                mUptimeStart = uptime;
+                mRealtimeStart = realtime;
+                mUnpluggedUptime = getUptime(uptime);
+                mUnpluggedRealtime = getRealtime(realtime);
+            }
+        }
+
+        public long computeUptime(long curTime, int which) {
+            switch (which) {
+                case STATS_SINCE_CHARGED:
+                    return mUptime + getUptime(curTime);
+                case STATS_CURRENT:
+                    return getUptime(curTime);
+                case STATS_SINCE_UNPLUGGED:
+                    return getUptime(curTime) - mUnpluggedUptime;
+            }
+            return 0;
+        }
+
+        public long computeRealtime(long curTime, int which) {
+            switch (which) {
+                case STATS_SINCE_CHARGED:
+                    return mRealtime + getRealtime(curTime);
+                case STATS_CURRENT:
+                    return getRealtime(curTime);
+                case STATS_SINCE_UNPLUGGED:
+                    return getRealtime(curTime) - mUnpluggedRealtime;
+            }
+            return 0;
+        }
+
+        public long getUptime(long curTime) {
+            long time = mPastUptime;
+            if (mRunning) {
+                time += curTime - mUptimeStart;
+            }
+            return time;
+        }
+
+        public long getRealtime(long curTime) {
+            long time = mPastRealtime;
+            if (mRunning) {
+                time += curTime - mRealtimeStart;
+            }
+            return time;
+        }
+
+        public long getUptimeStart() {
+            return mUptimeStart;
+        }
+
+        public long getRealtimeStart() {
+            return mRealtimeStart;
+        }
+
+        public boolean isRunning() {
+            return mRunning;
+        }
+
+        public boolean setRunning(boolean running, long uptime, long realtime) {
+            if (mRunning != running) {
+                mRunning = running;
+                if (running) {
+                    mUptimeStart = uptime;
+                    mRealtimeStart = realtime;
+                    long batteryUptime = mUnpluggedUptime = getUptime(uptime);
+                    long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
+
+                    for (int i = mObservers.size() - 1; i >= 0; i--) {
+                        mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
+                    }
+                } else {
+                    mPastUptime += uptime - mUptimeStart;
+                    mPastRealtime += realtime - mRealtimeStart;
+
+                    long batteryUptime = getUptime(uptime);
+                    long batteryRealtime = getRealtime(realtime);
+
+                    for (int i = mObservers.size() - 1; i >= 0; i--) {
+                        mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+
+        public void readSummaryFromParcel(Parcel in) {
+            mUptime = in.readLong();
+            mRealtime = in.readLong();
+        }
+
+        public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
+            out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
+            out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
+        }
+
+        public void readFromParcel(Parcel in) {
+            mRunning = false;
+            mUptime = in.readLong();
+            mPastUptime = in.readLong();
+            mUptimeStart = in.readLong();
+            mPastRealtime = in.readLong();
+            mRealtimeStart = in.readLong();
+            mUnpluggedUptime = in.readLong();
+            mUnpluggedRealtime = in.readLong();
+        }
+
+        public void writeToParcel(Parcel out, long uptime, long realtime) {
+            final long runningUptime = getUptime(uptime);
+            final long runningRealtime = getRealtime(realtime);
+            out.writeLong(mUptime);
+            out.writeLong(runningUptime);
+            out.writeLong(mUptimeStart);
+            out.writeLong(runningRealtime);
+            out.writeLong(mRealtimeStart);
+            out.writeLong(mUnpluggedUptime);
+            out.writeLong(mUnpluggedRealtime);
+        }
     }
 
     /**
      * State for keeping track of counting information.
      */
-    public static class Counter extends BatteryStats.Counter implements Unpluggable {
+    public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
         final AtomicInteger mCount = new AtomicInteger();
-        final ArrayList<Unpluggable> mUnpluggables;
+        final TimeBase mTimeBase;
         int mLoadedCount;
         int mLastCount;
         int mUnpluggedCount;
         int mPluggedCount;
 
-        Counter(ArrayList<Unpluggable> unpluggables, Parcel in) {
-            mUnpluggables = unpluggables;
+        Counter(TimeBase timeBase, Parcel in) {
+            mTimeBase = timeBase;
             mPluggedCount = in.readInt();
             mCount.set(mPluggedCount);
             mLoadedCount = in.readInt();
             mLastCount = 0;
             mUnpluggedCount = in.readInt();
-            unpluggables.add(this);
+            timeBase.add(this);
         }
 
-        Counter(ArrayList<Unpluggable> unpluggables) {
-            mUnpluggables = unpluggables;
-            unpluggables.add(this);
+        Counter(TimeBase timeBase) {
+            mTimeBase = timeBase;
+            timeBase.add(this);
         }
 
         public void writeToParcel(Parcel out) {
@@ -393,12 +625,12 @@
             out.writeInt(mUnpluggedCount);
         }
 
-        public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
             mUnpluggedCount = mPluggedCount;
             mCount.set(mPluggedCount);
         }
 
-        public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             mPluggedCount = mCount.get();
         }
 
@@ -420,16 +652,11 @@
 
         @Override
         public int getCountLocked(int which) {
-            int val;
-            if (which == STATS_LAST) {
-                val = mLastCount;
-            } else {
-                val = mCount.get();
-                if (which == STATS_SINCE_UNPLUGGED) {
-                    val -= mUnpluggedCount;
-                } else if (which != STATS_SINCE_CHARGED) {
-                    val -= mLoadedCount;
-                }
+            int val = mCount.get();
+            if (which == STATS_SINCE_UNPLUGGED) {
+                val -= mUnpluggedCount;
+            } else if (which != STATS_SINCE_CHARGED) {
+                val -= mLoadedCount;
             }
 
             return val;
@@ -458,7 +685,7 @@
         }
 
         void detach() {
-            mUnpluggables.remove(this);
+            mTimeBase.remove(this);
         }
 
         void writeSummaryFromParcelLocked(Parcel out) {
@@ -475,12 +702,12 @@
     }
 
     public static class SamplingCounter extends Counter {
-        SamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
-            super(unpluggables, in);
+        SamplingCounter(TimeBase timeBase, Parcel in) {
+            super(timeBase, in);
         }
 
-        SamplingCounter(ArrayList<Unpluggable> unpluggables) {
-            super(unpluggables);
+        SamplingCounter(TimeBase timeBase) {
+            super(timeBase);
         }
 
         public void addCountAtomic(long count) {
@@ -488,27 +715,27 @@
         }
     }
 
-    public static class LongSamplingCounter implements Unpluggable {
-        final ArrayList<Unpluggable> mUnpluggables;
+    public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
+        final TimeBase mTimeBase;
         long mCount;
         long mLoadedCount;
         long mLastCount;
         long mUnpluggedCount;
         long mPluggedCount;
 
-        LongSamplingCounter(ArrayList<Unpluggable> unpluggables, Parcel in) {
-            mUnpluggables = unpluggables;
+        LongSamplingCounter(TimeBase timeBase, Parcel in) {
+            mTimeBase = timeBase;
             mPluggedCount = in.readLong();
             mCount = mPluggedCount;
             mLoadedCount = in.readLong();
             mLastCount = 0;
             mUnpluggedCount = in.readLong();
-            unpluggables.add(this);
+            timeBase.add(this);
         }
 
-        LongSamplingCounter(ArrayList<Unpluggable> unpluggables) {
-            mUnpluggables = unpluggables;
-            unpluggables.add(this);
+        LongSamplingCounter(TimeBase timeBase) {
+            mTimeBase = timeBase;
+            timeBase.add(this);
         }
 
         public void writeToParcel(Parcel out) {
@@ -518,32 +745,35 @@
         }
 
         @Override
-        public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
             mUnpluggedCount = mPluggedCount;
             mCount = mPluggedCount;
         }
 
         @Override
-        public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             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;
-                }
+            long val = mCount;
+            if (which == STATS_SINCE_UNPLUGGED) {
+                val -= mUnpluggedCount;
+            } else if (which != STATS_SINCE_CHARGED) {
+                val -= mLoadedCount;
             }
 
             return val;
         }
 
+        @Override
+        public void logState(Printer pw, String prefix) {
+            pw.println(prefix + "mCount=" + mCount
+                    + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
+                    + " mUnpluggedCount=" + mUnpluggedCount
+                    + " mPluggedCount=" + mPluggedCount);
+        }
+
         void addCountLocked(long count) {
             mCount += count;
         }
@@ -560,7 +790,7 @@
         }
 
         void detach() {
-            mUnpluggables.remove(this);
+            mTimeBase.remove(this);
         }
 
         void writeSummaryFromParcelLocked(Parcel out) {
@@ -578,9 +808,9 @@
     /**
      * State for keeping track of timing information.
      */
-    public static abstract class Timer extends BatteryStats.Timer implements Unpluggable {
+    public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
         final int mType;
-        final ArrayList<Unpluggable> mUnpluggables;
+        final TimeBase mTimeBase;
 
         int mCount;
         int mLoadedCount;
@@ -619,12 +849,12 @@
         /**
          * Constructs from a parcel.
          * @param type
-         * @param unpluggables
+         * @param timeBase
          * @param in
          */
-        Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
+        Timer(int type, TimeBase timeBase, Parcel in) {
             mType = type;
-            mUnpluggables = unpluggables;
+            mTimeBase = timeBase;
 
             mCount = in.readInt();
             mLoadedCount = in.readInt();
@@ -634,13 +864,13 @@
             mLoadedTime = in.readLong();
             mLastTime = 0;
             mUnpluggedTime = in.readLong();
-            unpluggables.add(this);
+            timeBase.add(this);
         }
 
-        Timer(int type, ArrayList<Unpluggable> unpluggables) {
+        Timer(int type, TimeBase timeBase) {
             mType = type;
-            mUnpluggables = unpluggables;
-            unpluggables.add(this);
+            mTimeBase = timeBase;
+            timeBase.add(this);
         }
 
         protected abstract long computeRunTimeLocked(long curBatteryRealtime);
@@ -651,7 +881,7 @@
          * Clear state of this timer.  Returns true if the timer is inactive
          * so can be completely dropped.
          */
-        boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
+        boolean reset(boolean detachIfReset) {
             mTotalTime = mLoadedTime = mLastTime = 0;
             mCount = mLoadedCount = mLastCount = 0;
             if (detachIfReset) {
@@ -661,25 +891,25 @@
         }
 
         void detach() {
-            mUnpluggables.remove(this);
+            mTimeBase.remove(this);
         }
 
-        public void writeToParcel(Parcel out, long batteryRealtime) {
+        public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
             out.writeInt(mCount);
             out.writeInt(mLoadedCount);
             out.writeInt(mUnpluggedCount);
-            out.writeLong(computeRunTimeLocked(batteryRealtime));
+            out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
             out.writeLong(mLoadedTime);
             out.writeLong(mUnpluggedTime);
         }
 
-        public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
             if (DEBUG && mType < 0) {
-                Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
+                Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
                         + " old mUnpluggedTime=" + mUnpluggedTime
                         + " old mUnpluggedCount=" + mUnpluggedCount);
             }
-            mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
+            mUnpluggedTime = computeRunTimeLocked(baseRealtime);
             mUnpluggedCount = mCount;
             if (DEBUG && mType < 0) {
                 Log.v(TAG, "unplug #" + mType
@@ -688,12 +918,12 @@
             }
         }
 
-        public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             if (DEBUG && mType < 0) {
-                Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
+                Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
                         + " old mTotalTime=" + mTotalTime);
             }
-            mTotalTime = computeRunTimeLocked(batteryRealtime);
+            mTotalTime = computeRunTimeLocked(baseRealtime);
             mCount = computeCurrentCountLocked();
             if (DEBUG && mType < 0) {
                 Log.v(TAG, "plug #" + mType
@@ -707,29 +937,23 @@
          * @param out the Parcel to be written to.
          * @param timer a Timer, or null.
          */
-        public static void writeTimerToParcel(Parcel out, Timer timer,
-                long batteryRealtime) {
+        public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
             if (timer == null) {
                 out.writeInt(0); // indicates null
                 return;
             }
             out.writeInt(1); // indicates non-null
 
-            timer.writeToParcel(out, batteryRealtime);
+            timer.writeToParcel(out, elapsedRealtimeUs);
         }
 
         @Override
-        public long getTotalTimeLocked(long batteryRealtime, int which) {
-            long val;
-            if (which == STATS_LAST) {
-                val = mLastTime;
-            } else {
-                val = computeRunTimeLocked(batteryRealtime);
-                if (which == STATS_SINCE_UNPLUGGED) {
-                    val -= mUnpluggedTime;
-                } else if (which != STATS_SINCE_CHARGED) {
-                    val -= mLoadedTime;
-                }
+        public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
+            long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
+            if (which == STATS_SINCE_UNPLUGGED) {
+                val -= mUnpluggedTime;
+            } else if (which != STATS_SINCE_CHARGED) {
+                val -= mLoadedTime;
             }
 
             return val;
@@ -737,16 +961,11 @@
 
         @Override
         public int getCountLocked(int which) {
-            int val;
-            if (which == STATS_LAST) {
-                val = mLastCount;
-            } else {
-                val = computeCurrentCountLocked();
-                if (which == STATS_SINCE_UNPLUGGED) {
-                    val -= mUnpluggedCount;
-                } else if (which != STATS_SINCE_CHARGED) {
-                    val -= mLoadedCount;
-                }
+            int val = computeCurrentCountLocked();
+            if (which == STATS_SINCE_UNPLUGGED) {
+                val -= mUnpluggedCount;
+            } else if (which != STATS_SINCE_CHARGED) {
+                val -= mLoadedCount;
             }
 
             return val;
@@ -763,16 +982,15 @@
         }
 
 
-        void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
-            long runTime = computeRunTimeLocked(batteryRealtime);
-            // Divide by 1000 for backwards compatibility
-            out.writeLong((runTime + 500) / 1000);
+        void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
+            long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
+            out.writeLong(runTime);
             out.writeInt(mCount);
         }
 
         void readSummaryFromParcelLocked(Parcel in) {
             // Multiply by 1000 for backwards compatibility
-            mTotalTime = mLoadedTime = in.readLong() * 1000;
+            mTotalTime = mLoadedTime = in.readLong();
             mLastTime = 0;
             mUnpluggedTime = mTotalTime;
             mCount = mLoadedCount = in.readInt();
@@ -809,7 +1027,7 @@
         /**
          * Whether we are currently in a discharge cycle.
          */
-        boolean mInDischarge;
+        boolean mTimeBaseRunning;
 
         /**
          * Whether we are currently recording reported values.
@@ -821,21 +1039,20 @@
          */
         int mUpdateVersion;
 
-        SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge, Parcel in) {
-            super(0, unpluggables, in);
+        SamplingTimer(TimeBase timeBase, Parcel in) {
+            super(0, timeBase, in);
             mCurrentReportedCount = in.readInt();
             mUnpluggedReportedCount = in.readInt();
             mCurrentReportedTotalTime = in.readLong();
             mUnpluggedReportedTotalTime = in.readLong();
             mTrackingReportedValues = in.readInt() == 1;
-            mInDischarge = inDischarge;
+            mTimeBaseRunning = timeBase.isRunning();
         }
 
-        SamplingTimer(ArrayList<Unpluggable> unpluggables, boolean inDischarge,
-                boolean trackReportedValues) {
-            super(0, unpluggables);
+        SamplingTimer(TimeBase timeBase, boolean trackReportedValues) {
+            super(0, timeBase);
             mTrackingReportedValues = trackReportedValues;
-            mInDischarge = inDischarge;
+            mTimeBaseRunning = timeBase.isRunning();
         }
 
         public void setStale() {
@@ -853,7 +1070,7 @@
         }
 
         public void updateCurrentReportedCount(int count) {
-            if (mInDischarge && mUnpluggedReportedCount == 0) {
+            if (mTimeBaseRunning && mUnpluggedReportedCount == 0) {
                 // Updating the reported value for the first time.
                 mUnpluggedReportedCount = count;
                 // If we are receiving an update update mTrackingReportedValues;
@@ -863,7 +1080,7 @@
         }
 
         public void updateCurrentReportedTotalTime(long totalTime) {
-            if (mInDischarge && mUnpluggedReportedTotalTime == 0) {
+            if (mTimeBaseRunning && mUnpluggedReportedTotalTime == 0) {
                 // Updating the reported value for the first time.
                 mUnpluggedReportedTotalTime = totalTime;
                 // If we are receiving an update update mTrackingReportedValues;
@@ -872,18 +1089,18 @@
             mCurrentReportedTotalTime = totalTime;
         }
 
-        public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
-            super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
+        public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
+            super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
             if (mTrackingReportedValues) {
                 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
                 mUnpluggedReportedCount = mCurrentReportedCount;
             }
-            mInDischarge = true;
+            mTimeBaseRunning = true;
         }
 
-        public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
-            super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
-            mInDischarge = false;
+        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
+            super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
+            mTimeBaseRunning = false;
         }
 
         public void logState(Printer pw, String prefix) {
@@ -895,17 +1112,17 @@
         }
 
         protected long computeRunTimeLocked(long curBatteryRealtime) {
-            return mTotalTime + (mInDischarge && mTrackingReportedValues
+            return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
                     ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
         }
 
         protected int computeCurrentCountLocked() {
-            return mCount + (mInDischarge && mTrackingReportedValues
+            return mCount + (mTimeBaseRunning && mTrackingReportedValues
                     ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
         }
 
-        public void writeToParcel(Parcel out, long batteryRealtime) {
-            super.writeToParcel(out, batteryRealtime);
+        public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
+            super.writeToParcel(out, elapsedRealtimeUs);
             out.writeInt(mCurrentReportedCount);
             out.writeInt(mUnpluggedReportedCount);
             out.writeLong(mCurrentReportedTotalTime);
@@ -913,8 +1130,8 @@
             out.writeInt(mTrackingReportedValues ? 1 : 0);
         }
 
-        boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
-            super.reset(stats, detachIfReset);
+        boolean reset(boolean detachIfReset) {
+            super.reset(detachIfReset);
             setStale();
             return true;
         }
@@ -956,45 +1173,43 @@
          */
         boolean mInDischarge;
 
-        BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
-                boolean inDischarge, Parcel in) {
-            super(type, unpluggables, in);
+        BatchTimer(Uid uid, int type, TimeBase timeBase, Parcel in) {
+            super(type, timeBase, in);
             mUid = uid;
             mLastAddedTime = in.readLong();
             mLastAddedDuration = in.readLong();
-            mInDischarge = inDischarge;
+            mInDischarge = timeBase.isRunning();
         }
 
-        BatchTimer(Uid uid, int type, ArrayList<Unpluggable> unpluggables,
-                boolean inDischarge) {
-            super(type, unpluggables);
+        BatchTimer(Uid uid, int type, TimeBase timeBase) {
+            super(type, timeBase);
             mUid = uid;
-            mInDischarge = inDischarge;
+            mInDischarge = timeBase.isRunning();
         }
 
         @Override
-        public void writeToParcel(Parcel out, long batteryRealtime) {
-            super.writeToParcel(out, batteryRealtime);
+        public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
+            super.writeToParcel(out, elapsedRealtimeUs);
             out.writeLong(mLastAddedTime);
             out.writeLong(mLastAddedDuration);
         }
 
         @Override
-        public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
             mInDischarge = false;
-            super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
+            super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
         }
 
         @Override
-        public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
             recomputeLastDuration(elapsedRealtime, false);
             mInDischarge = true;
             // If we are still within the last added duration, then re-added whatever remains.
             if (mLastAddedTime == elapsedRealtime) {
                 mTotalTime += mLastAddedDuration;
             }
-            super.unplug(elapsedRealtime, batteryUptime, batteryRealtime);
+            super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
         }
 
         @Override
@@ -1060,11 +1275,11 @@
         }
 
         @Override
-        boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
+        boolean reset(boolean detachIfReset) {
             final long now = SystemClock.elapsedRealtime() * 1000;
             recomputeLastDuration(now, true);
             boolean stillActive = mLastAddedTime == now;
-            super.reset(stats, !stillActive && detachIfReset);
+            super.reset(!stillActive && detachIfReset);
             return !stillActive;
         }
     }
@@ -1100,16 +1315,16 @@
         boolean mInList;
 
         StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
-                ArrayList<Unpluggable> unpluggables, Parcel in) {
-            super(type, unpluggables, in);
+                TimeBase timeBase, Parcel in) {
+            super(type, timeBase, in);
             mUid = uid;
             mTimerPool = timerPool;
             mUpdateTime = in.readLong();
         }
 
         StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
-                ArrayList<Unpluggable> unpluggables) {
-            super(type, unpluggables);
+                TimeBase timeBase) {
+            super(type, timeBase);
             mUid = uid;
             mTimerPool = timerPool;
         }
@@ -1118,18 +1333,18 @@
             mTimeout = timeout;
         }
 
-        public void writeToParcel(Parcel out, long batteryRealtime) {
-            super.writeToParcel(out, batteryRealtime);
+        public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
+            super.writeToParcel(out, elapsedRealtimeUs);
             out.writeLong(mUpdateTime);
         }
 
-        public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+        public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             if (mNesting > 0) {
                 if (DEBUG && mType < 0) {
                     Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
                 }
-                super.plug(elapsedRealtime, batteryUptime, batteryRealtime);
-                mUpdateTime = batteryRealtime;
+                super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
+                mUpdateTime = baseRealtime;
                 if (DEBUG && mType < 0) {
                     Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
                 }
@@ -1142,14 +1357,14 @@
                     + " mAcquireTime=" + mAcquireTime);
         }
 
-        void startRunningLocked(BatteryStatsImpl stats) {
+        void startRunningLocked(long elapsedRealtimeMs) {
             if (mNesting++ == 0) {
-                mUpdateTime = stats.getBatteryRealtimeLocked(
-                        SystemClock.elapsedRealtime() * 1000);
+                final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
+                mUpdateTime = batteryRealtime;
                 if (mTimerPool != null) {
                     // Accumulate time to all currently active timers before adding
                     // this new one to the pool.
-                    refreshTimersLocked(stats, mTimerPool);
+                    refreshTimersLocked(batteryRealtime, mTimerPool, null);
                     // Add this timer to the active pool
                     mTimerPool.add(this);
                 }
@@ -1168,21 +1383,39 @@
             return mNesting > 0;
         }
 
-        void stopRunningLocked(BatteryStatsImpl stats) {
+        long checkpointRunningLocked(long elapsedRealtimeMs) {
+            if (mNesting > 0) {
+                // We are running...
+                final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
+                if (mTimerPool != null) {
+                    return refreshTimersLocked(batteryRealtime, mTimerPool, this);
+                }
+                final long heldTime = batteryRealtime - mUpdateTime;
+                mUpdateTime = batteryRealtime;
+                mTotalTime += heldTime;
+                return heldTime;
+            }
+            return 0;
+        }
+
+        long getLastUpdateTimeMs() {
+            return mUpdateTime;
+        }
+
+        void stopRunningLocked(long elapsedRealtimeMs) {
             // Ignore attempt to stop a timer that isn't running
             if (mNesting == 0) {
                 return;
             }
             if (--mNesting == 0) {
+                final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
                 if (mTimerPool != null) {
                     // Accumulate time to all active counters, scaled by the total
                     // active in the pool, before taking this one out of the pool.
-                    refreshTimersLocked(stats, mTimerPool);
+                    refreshTimersLocked(batteryRealtime, mTimerPool, null);
                     // Remove this timer from the active pool
                     mTimerPool.remove(this);
                 } else {
-                    final long realtime = SystemClock.elapsedRealtime() * 1000;
-                    final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
                     mNesting = 1;
                     mTotalTime = computeRunTimeLocked(batteryRealtime);
                     mNesting = 0;
@@ -1204,19 +1437,23 @@
 
         // Update the total time for all other running Timers with the same type as this Timer
         // due to a change in timer count
-        private static void refreshTimersLocked(final BatteryStatsImpl stats,
-                final ArrayList<StopwatchTimer> pool) {
-            final long realtime = SystemClock.elapsedRealtime() * 1000;
-            final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
+        private static long refreshTimersLocked(long batteryRealtime,
+                final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
+            long selfTime = 0;
             final int N = pool.size();
             for (int i=N-1; i>= 0; i--) {
                 final StopwatchTimer t = pool.get(i);
                 long heldTime = batteryRealtime - t.mUpdateTime;
                 if (heldTime > 0) {
-                    t.mTotalTime += heldTime / N;
+                    final long myTime = heldTime / N;
+                    if (t == self) {
+                        selfTime = myTime;
+                    }
+                    t.mTotalTime += myTime;
                 }
                 t.mUpdateTime = batteryRealtime;
             }
+            return selfTime;
         }
 
         @Override
@@ -1235,12 +1472,11 @@
             return mCount;
         }
 
-        boolean reset(BatteryStatsImpl stats, boolean detachIfReset) {
+        boolean reset(boolean detachIfReset) {
             boolean canDetach = mNesting <= 0;
-            super.reset(stats, canDetach && detachIfReset);
+            super.reset(canDetach && detachIfReset);
             if (mNesting > 0) {
-                mUpdateTime = stats.getBatteryRealtimeLocked(
-                        SystemClock.elapsedRealtime() * 1000);
+                mUpdateTime = mTimeBase.getRealtime(SystemClock.elapsedRealtime() * 1000);
             }
             mAcquireTime = mTotalTime;
             return canDetach;
@@ -1259,6 +1495,19 @@
         }
     }
 
+    /*
+     * Get the wakeup reason counter, and create a new one if one
+     * doesn't already exist.
+     */
+    public LongSamplingCounter getWakeupReasonCounterLocked(String name) {
+        LongSamplingCounter counter = mWakeupReasonStats.get(name);
+        if (counter == null) {
+            counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase);
+            mWakeupReasonStats.put(name, counter);
+        }
+        return counter;
+    }
+
     private final Map<String, KernelWakelockStats> readKernelWakelockStats() {
 
         FileInputStream is;
@@ -1403,51 +1652,12 @@
     public SamplingTimer getKernelWakelockTimerLocked(String name) {
         SamplingTimer kwlt = mKernelWakelockStats.get(name);
         if (kwlt == null) {
-            kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
-                    true /* track reported values */);
+            kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, true /* track reported values */);
             mKernelWakelockStats.put(name, kwlt);
         }
         return kwlt;
     }
 
-    /**
-     * Radio uptime in microseconds when transferring data. This value is very approximate.
-     * @return
-     */
-    private long getCurrentRadioDataUptime() {
-        try {
-            File awakeTimeFile = new File("/sys/devices/virtual/net/rmnet0/awake_time_ms");
-            if (!awakeTimeFile.exists()) return 0;
-            BufferedReader br = new BufferedReader(new FileReader(awakeTimeFile));
-            String line = br.readLine();
-            br.close();
-            return Long.parseLong(line) * 1000;
-        } catch (NumberFormatException nfe) {
-            // Nothing
-        } catch (IOException ioe) {
-            // Nothing
-        }
-        return 0;
-    }
-
-    /**
-     * @deprecated use getRadioDataUptime
-     */
-    public long getRadioDataUptimeMs() {
-        return getRadioDataUptime() / 1000;
-    }
-
-    /**
-     * Returns the duration that the cell radio was up for data transfers.
-     */
-    public long getRadioDataUptime() {
-        if (mRadioDataStart == -1) {
-            return mRadioDataUptime;
-        } else {
-            return getCurrentRadioDataUptime() - mRadioDataStart;
-        }
-    }
-
     private int getCurrentBluetoothPingCount() {
         if (mBtHeadset != null) {
             List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
@@ -1474,83 +1684,434 @@
         mBtHeadset = headset;
     }
 
-    int mChangedBufferStates = 0;
+    private int writeHistoryTag(HistoryTag tag) {
+        Integer idxObj = mHistoryTagPool.get(tag);
+        int idx;
+        if (idxObj != null) {
+            idx = idxObj;
+        } else {
+            idx = mNextHistoryTagIdx;
+            HistoryTag key = new HistoryTag();
+            key.setTo(tag);
+            tag.poolIdx = idx;
+            mHistoryTagPool.put(key, idx);
+            mNextHistoryTagIdx++;
+            mNumHistoryTagChars += key.string.length() + 1;
+        }
+        return idx;
+    }
 
-    void addHistoryBufferLocked(long curTime) {
+    private void readHistoryTag(int index, HistoryTag tag) {
+        tag.string = mReadHistoryStrings[index];
+        tag.uid = mReadHistoryUids[index];
+        tag.poolIdx = index;
+    }
+
+    // Part of initial delta int that specifies the time delta.
+    static final int DELTA_TIME_MASK = 0x7ffff;
+    static final int DELTA_TIME_LONG = 0x7ffff;   // The delta is a following long
+    static final int DELTA_TIME_INT = 0x7fffe;    // The delta is a following int
+    static final int DELTA_TIME_ABS = 0x7fffd;    // Following is an entire abs update.
+    // Flag in delta int: a new battery level int follows.
+    static final int DELTA_BATTERY_LEVEL_FLAG   = 0x00080000;
+    // Flag in delta int: a new full state and battery status int follows.
+    static final int DELTA_STATE_FLAG           = 0x00100000;
+    // Flag in delta int: a new full state2 int follows.
+    static final int DELTA_STATE2_FLAG          = 0x00200000;
+    // Flag in delta int: contains a wakelock or wakeReason tag.
+    static final int DELTA_WAKELOCK_FLAG        = 0x00400000;
+    // Flag in delta int: contains an event description.
+    static final int DELTA_EVENT_FLAG           = 0x00800000;
+    // These upper bits are the frequently changing state bits.
+    static final int DELTA_STATE_MASK           = 0xff000000;
+
+    // These are the pieces of battery state that are packed in to the upper bits of
+    // the state int that have been packed in to the first delta int.  They must fit
+    // in DELTA_STATE_MASK.
+    static final int STATE_BATTERY_STATUS_MASK  = 0x00000007;
+    static final int STATE_BATTERY_STATUS_SHIFT = 29;
+    static final int STATE_BATTERY_HEALTH_MASK  = 0x00000007;
+    static final int STATE_BATTERY_HEALTH_SHIFT = 26;
+    static final int STATE_BATTERY_PLUG_MASK    = 0x00000003;
+    static final int STATE_BATTERY_PLUG_SHIFT   = 24;
+
+    public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
+        if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
+            dest.writeInt(DELTA_TIME_ABS);
+            cur.writeToParcel(dest, 0);
+            return;
+        }
+
+        final long deltaTime = cur.time - last.time;
+        final int lastBatteryLevelInt = buildBatteryLevelInt(last);
+        final int lastStateInt = buildStateInt(last);
+
+        int deltaTimeToken;
+        if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
+            deltaTimeToken = DELTA_TIME_LONG;
+        } else if (deltaTime >= DELTA_TIME_ABS) {
+            deltaTimeToken = DELTA_TIME_INT;
+        } else {
+            deltaTimeToken = (int)deltaTime;
+        }
+        int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
+        final int batteryLevelInt = buildBatteryLevelInt(cur);
+        final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
+        if (batteryLevelIntChanged) {
+            firstToken |= DELTA_BATTERY_LEVEL_FLAG;
+        }
+        final int stateInt = buildStateInt(cur);
+        final boolean stateIntChanged = stateInt != lastStateInt;
+        if (stateIntChanged) {
+            firstToken |= DELTA_STATE_FLAG;
+        }
+        final boolean state2IntChanged = cur.states2 != last.states2;
+        if (state2IntChanged) {
+            firstToken |= DELTA_STATE2_FLAG;
+        }
+        if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
+            firstToken |= DELTA_WAKELOCK_FLAG;
+        }
+        if (cur.eventCode != HistoryItem.EVENT_NONE) {
+            firstToken |= DELTA_EVENT_FLAG;
+        }
+        dest.writeInt(firstToken);
+        if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
+                + " deltaTime=" + deltaTime);
+
+        if (deltaTimeToken >= DELTA_TIME_INT) {
+            if (deltaTimeToken == DELTA_TIME_INT) {
+                if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
+                dest.writeInt((int)deltaTime);
+            } else {
+                if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
+                dest.writeLong(deltaTime);
+            }
+        }
+        if (batteryLevelIntChanged) {
+            dest.writeInt(batteryLevelInt);
+            if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
+                    + Integer.toHexString(batteryLevelInt)
+                    + " batteryLevel=" + cur.batteryLevel
+                    + " batteryTemp=" + cur.batteryTemperature
+                    + " batteryVolt=" + (int)cur.batteryVoltage);
+        }
+        if (stateIntChanged) {
+            dest.writeInt(stateInt);
+            if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
+                    + Integer.toHexString(stateInt)
+                    + " batteryStatus=" + cur.batteryStatus
+                    + " batteryHealth=" + cur.batteryHealth
+                    + " batteryPlugType=" + cur.batteryPlugType
+                    + " states=0x" + Integer.toHexString(cur.states));
+        }
+        if (state2IntChanged) {
+            dest.writeInt(cur.states2);
+            if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
+                    + Integer.toHexString(cur.states2));
+        }
+        if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
+            int wakeLockIndex;
+            int wakeReasonIndex;
+            if (cur.wakelockTag != null) {
+                wakeLockIndex = writeHistoryTag(cur.wakelockTag);
+                if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
+                    + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
+            } else {
+                wakeLockIndex = 0xffff;
+            }
+            if (cur.wakeReasonTag != null) {
+                wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
+                if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
+                    + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
+            } else {
+                wakeReasonIndex = 0xffff;
+            }
+            dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
+        }
+        if (cur.eventCode != HistoryItem.EVENT_NONE) {
+            int index = writeHistoryTag(cur.eventTag);
+            int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
+            dest.writeInt(codeAndIndex);
+            if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
+                    + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
+                    + cur.eventTag.string);
+        }
+    }
+
+    private int buildBatteryLevelInt(HistoryItem h) {
+        return ((((int)h.batteryLevel)<<25)&0xfe000000)
+                | ((((int)h.batteryTemperature)<<14)&0x01ffc000)
+                | (((int)h.batteryVoltage)&0x00003fff);
+    }
+
+    private int buildStateInt(HistoryItem h) {
+        int plugType = 0;
+        if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
+            plugType = 1;
+        } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
+            plugType = 2;
+        } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
+            plugType = 3;
+        }
+        return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
+                | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
+                | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
+                | (h.states&(~DELTA_STATE_MASK));
+    }
+
+    public void readHistoryDelta(Parcel src, HistoryItem cur) {
+        int firstToken = src.readInt();
+        int deltaTimeToken = firstToken&DELTA_TIME_MASK;
+        cur.cmd = HistoryItem.CMD_UPDATE;
+        cur.numReadInts = 1;
+        if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
+                + " deltaTimeToken=" + deltaTimeToken);
+
+        if (deltaTimeToken < DELTA_TIME_ABS) {
+            cur.time += deltaTimeToken;
+        } else if (deltaTimeToken == DELTA_TIME_ABS) {
+            cur.time = src.readLong();
+            cur.numReadInts += 2;
+            if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
+            cur.readFromParcel(src);
+            return;
+        } else if (deltaTimeToken == DELTA_TIME_INT) {
+            int delta = src.readInt();
+            cur.time += delta;
+            cur.numReadInts += 1;
+            if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
+        } else {
+            long delta = src.readLong();
+            if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
+            cur.time += delta;
+            cur.numReadInts += 2;
+        }
+
+        if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
+            int batteryLevelInt = src.readInt();
+            cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
+            cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
+            cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
+            cur.numReadInts += 1;
+            if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
+                    + Integer.toHexString(batteryLevelInt)
+                    + " batteryLevel=" + cur.batteryLevel
+                    + " batteryTemp=" + cur.batteryTemperature
+                    + " batteryVolt=" + (int)cur.batteryVoltage);
+        }
+
+        if ((firstToken&DELTA_STATE_FLAG) != 0) {
+            int stateInt = src.readInt();
+            cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
+            cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
+                    & STATE_BATTERY_STATUS_MASK);
+            cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
+                    & STATE_BATTERY_HEALTH_MASK);
+            cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
+                    & STATE_BATTERY_PLUG_MASK);
+            switch (cur.batteryPlugType) {
+                case 1:
+                    cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
+                    break;
+                case 2:
+                    cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
+                    break;
+                case 3:
+                    cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
+                    break;
+            }
+            cur.numReadInts += 1;
+            if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
+                    + Integer.toHexString(stateInt)
+                    + " batteryStatus=" + cur.batteryStatus
+                    + " batteryHealth=" + cur.batteryHealth
+                    + " batteryPlugType=" + cur.batteryPlugType
+                    + " states=0x" + Integer.toHexString(cur.states));
+        } else {
+            cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
+        }
+
+        if ((firstToken&DELTA_STATE2_FLAG) != 0) {
+            cur.states2 = src.readInt();
+            if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
+                    + Integer.toHexString(cur.states2));
+        }
+
+        if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
+            int indexes = src.readInt();
+            int wakeLockIndex = indexes&0xffff;
+            int wakeReasonIndex = (indexes>>16)&0xffff;
+            if (wakeLockIndex != 0xffff) {
+                cur.wakelockTag = cur.localWakelockTag;
+                readHistoryTag(wakeLockIndex, cur.wakelockTag);
+                if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
+                    + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
+            } else {
+                cur.wakelockTag = null;
+            }
+            if (wakeReasonIndex != 0xffff) {
+                cur.wakeReasonTag = cur.localWakeReasonTag;
+                readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
+                if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
+                    + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
+            } else {
+                cur.wakeReasonTag = null;
+            }
+            cur.numReadInts += 1;
+        } else {
+            cur.wakelockTag = null;
+            cur.wakeReasonTag = null;
+        }
+
+        if ((firstToken&DELTA_EVENT_FLAG) != 0) {
+            cur.eventTag = cur.localEventTag;
+            final int codeAndIndex = src.readInt();
+            cur.eventCode = (codeAndIndex&0xffff);
+            final int index = ((codeAndIndex>>16)&0xffff);
+            readHistoryTag(index, cur.eventTag);
+            cur.numReadInts += 1;
+            if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
+                    + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
+                    + cur.eventTag.string);
+        } else {
+            cur.eventCode = HistoryItem.EVENT_NONE;
+        }
+    }
+
+    void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
         if (!mHaveBatteryLevel || !mRecordingHistory) {
             return;
         }
 
-        final long timeDiff = (mHistoryBaseTime+curTime) - mHistoryLastWritten.time;
+        final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
+        final int diffStates = mHistoryLastWritten.states^cur.states;
+        final int diffStates2 = mHistoryLastWritten.states2^cur.states2;
+        final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
+        final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
+        if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
+                + Integer.toHexString(diffStates) + " lastDiff="
+                + Integer.toHexString(lastDiffStates) + " diff2="
+                + Integer.toHexString(diffStates2) + " lastDiff2="
+                + Integer.toHexString(lastDiffStates2));
         if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
-                && timeDiff < 2000
-                && ((mHistoryLastWritten.states^mHistoryCur.states)&mChangedBufferStates) == 0) {
-            // If the current is the same as the one before, then we no
-            // longer need the entry.
+                && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
+                && (diffStates2&lastDiffStates2) == 0
+                && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
+                && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
+                && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
+                        || cur.eventCode == HistoryItem.EVENT_NONE)
+                && mHistoryLastWritten.batteryLevel == cur.batteryLevel
+                && mHistoryLastWritten.batteryStatus == cur.batteryStatus
+                && mHistoryLastWritten.batteryHealth == cur.batteryHealth
+                && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
+                && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
+                && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
+            // We can merge this new change in with the last one.  Merging is
+            // allowed as long as only the states have changed, and within those states
+            // as long as no bit has changed both between now and the last entry, as
+            // well as the last entry and the one before it (so we capture any toggles).
+            if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
             mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
             mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
             mHistoryBufferLastPos = -1;
-            if (mHistoryLastLastWritten.cmd == HistoryItem.CMD_UPDATE
-                    && timeDiff < 500 && mHistoryLastLastWritten.same(mHistoryCur)) {
-                // If this results in us returning to the state written
-                // prior to the last one, then we can just delete the last
-                // written one and drop the new one.  Nothing more to do.
-                mHistoryLastWritten.setTo(mHistoryLastLastWritten);
-                mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
-                return;
+            elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
+            // If the last written history had a wakelock tag, we need to retain it.
+            // Note that the condition above made sure that we aren't in a case where
+            // both it and the current history item have a wakelock tag.
+            if (mHistoryLastWritten.wakelockTag != null) {
+                cur.wakelockTag = cur.localWakelockTag;
+                cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
             }
-            mChangedBufferStates |= mHistoryLastWritten.states^mHistoryCur.states;
-            curTime = mHistoryLastWritten.time - mHistoryBaseTime;
+            // If the last written history had a wake reason tag, we need to retain it.
+            // Note that the condition above made sure that we aren't in a case where
+            // both it and the current history item have a wakelock tag.
+            if (mHistoryLastWritten.wakeReasonTag != null) {
+                cur.wakeReasonTag = cur.localWakeReasonTag;
+                cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
+            }
+            // If the last written history had an event, we need to retain it.
+            // Note that the condition above made sure that we aren't in a case where
+            // both it and the current history item have an event.
+            if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
+                cur.eventCode = mHistoryLastWritten.eventCode;
+                cur.eventTag = cur.localEventTag;
+                cur.eventTag.setTo(mHistoryLastWritten.eventTag);
+            }
             mHistoryLastWritten.setTo(mHistoryLastLastWritten);
-        } else {
-            mChangedBufferStates = 0;
         }
 
         final int dataSize = mHistoryBuffer.dataSize();
         if (dataSize >= MAX_HISTORY_BUFFER) {
             if (!mHistoryOverflow) {
                 mHistoryOverflow = true;
-                addHistoryBufferLocked(curTime, HistoryItem.CMD_OVERFLOW);
+                addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
+                addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
+                return;
             }
 
             // Once we've reached the maximum number of items, we only
             // record changes to the battery level and the most interesting states.
             // Once we've reached the maximum maximum number of items, we only
             // record changes to the battery level.
-            if (mHistoryLastWritten.batteryLevel == mHistoryCur.batteryLevel &&
+            if (mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
                     (dataSize >= MAX_MAX_HISTORY_BUFFER
-                            || ((mHistoryLastWritten.states^mHistoryCur.states)
+                            || ((mHistoryLastWritten.states^cur.states)
                                     & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
                 return;
             }
+
+            addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
+            return;
         }
 
-        addHistoryBufferLocked(curTime, HistoryItem.CMD_UPDATE);
+        addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
     }
 
-    void addHistoryBufferLocked(long curTime, byte cmd) {
-        int origPos = 0;
+    private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
+            HistoryItem cur) {
         if (mIteratingHistory) {
-            origPos = mHistoryBuffer.dataPosition();
-            mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
+            throw new IllegalStateException("Can't do this while iterating history!");
         }
         mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
         mHistoryLastLastWritten.setTo(mHistoryLastWritten);
-        mHistoryLastWritten.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
-        mHistoryLastWritten.writeDelta(mHistoryBuffer, mHistoryLastLastWritten);
-        mLastHistoryTime = curTime;
+        mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
+        writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
+        mLastHistoryElapsedRealtime = elapsedRealtimeMs;
+        cur.wakelockTag = null;
+        cur.wakeReasonTag = null;
+        cur.eventCode = HistoryItem.EVENT_NONE;
+        cur.eventTag = null;
         if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
                 + " now " + mHistoryBuffer.dataPosition()
                 + " size is now " + mHistoryBuffer.dataSize());
-        if (mIteratingHistory) {
-            mHistoryBuffer.setDataPosition(origPos);
-        }
     }
 
     int mChangedStates = 0;
+    int mChangedStates2 = 0;
 
-    void addHistoryRecordLocked(long curTime) {
-        addHistoryBufferLocked(curTime);
+    void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
+        if (mTrackRunningHistoryElapsedRealtime != 0) {
+            final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
+            final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
+            if (diffUptime < (diffElapsed-20)) {
+                final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
+                mHistoryAddTmp.setTo(mHistoryLastWritten);
+                mHistoryAddTmp.wakelockTag = null;
+                mHistoryAddTmp.wakeReasonTag = null;
+                mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
+                mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
+                addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
+            }
+        }
+        mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
+        mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
+        mTrackRunningHistoryUptime = uptimeMs;
+        addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
+    }
+
+    void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
+        addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
 
         if (!USE_OLD_HISTORY) {
             return;
@@ -1565,30 +2126,33 @@
         // are now resetting back to their original value, then just collapse
         // into one record.
         if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
-                && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+2000)
-                && ((mHistoryEnd.states^mHistoryCur.states)&mChangedStates) == 0) {
+                && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
+                && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0
+                && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) {
             // If the current is the same as the one before, then we no
             // longer need the entry.
             if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
-                    && (mHistoryBaseTime+curTime) < (mHistoryEnd.time+500)
-                    && mHistoryLastEnd.same(mHistoryCur)) {
+                    && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
+                    && mHistoryLastEnd.sameNonEvent(cur)) {
                 mHistoryLastEnd.next = null;
                 mHistoryEnd.next = mHistoryCache;
                 mHistoryCache = mHistoryEnd;
                 mHistoryEnd = mHistoryLastEnd;
                 mHistoryLastEnd = null;
             } else {
-                mChangedStates |= mHistoryEnd.states^mHistoryCur.states;
-                mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, mHistoryCur);
+                mChangedStates |= mHistoryEnd.states^cur.states;
+                mChangedStates2 |= mHistoryEnd.states^cur.states2;
+                mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
             }
             return;
         }
 
         mChangedStates = 0;
+        mChangedStates2 = 0;
 
         if (mNumHistoryItems == MAX_HISTORY_ITEMS
                 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
-            addHistoryRecordLocked(curTime, HistoryItem.CMD_OVERFLOW);
+            addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
         }
 
         if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
@@ -1597,25 +2161,34 @@
             // Once we've reached the maximum maximum number of items, we only
             // record changes to the battery level.
             if (mHistoryEnd != null && mHistoryEnd.batteryLevel
-                    == mHistoryCur.batteryLevel &&
+                    == cur.batteryLevel &&
                     (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
-                            || ((mHistoryEnd.states^mHistoryCur.states)
+                            || ((mHistoryEnd.states^cur.states)
                                     & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
                 return;
             }
         }
 
-        addHistoryRecordLocked(curTime, HistoryItem.CMD_UPDATE);
+        addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
     }
 
-    void addHistoryRecordLocked(long curTime, byte cmd) {
+    void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
+            String name, int uid) {
+        mHistoryCur.eventCode = code;
+        mHistoryCur.eventTag = mHistoryCur.localEventTag;
+        mHistoryCur.eventTag.string = name;
+        mHistoryCur.eventTag.uid = uid;
+        addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
+    }
+
+    void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
         HistoryItem rec = mHistoryCache;
         if (rec != null) {
             mHistoryCache = rec.next;
         } else {
             rec = new HistoryItem();
         }
-        rec.setTo(mHistoryBaseTime + curTime, cmd, mHistoryCur);
+        rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
 
         addHistoryRecordLocked(rec);
     }
@@ -1644,114 +2217,252 @@
         }
 
         mHistoryBaseTime = 0;
-        mLastHistoryTime = 0;
+        mLastHistoryElapsedRealtime = 0;
+        mTrackRunningHistoryElapsedRealtime = 0;
+        mTrackRunningHistoryUptime = 0;
 
         mHistoryBuffer.setDataSize(0);
         mHistoryBuffer.setDataPosition(0);
-        mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER/2);
-        mHistoryLastLastWritten.cmd = HistoryItem.CMD_NULL;
-        mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
+        mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
+        mHistoryLastLastWritten.clear();
+        mHistoryLastWritten.clear();
+        mHistoryTagPool.clear();
+        mNextHistoryTagIdx = 0;
+        mNumHistoryTagChars = 0;
         mHistoryBufferLastPos = -1;
         mHistoryOverflow = false;
     }
 
-    public void doUnplugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
-        for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
-            mUnpluggables.get(i).unplug(elapsedRealtime, batteryUptime, batteryRealtime);
+    public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
+            long realtime) {
+        if (mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime)) {
+            if (unplugged) {
+                // Track bt headset ping count
+                mBluetoothPingStart = getCurrentBluetoothPingCount();
+                mBluetoothPingCount = 0;
+            } else {
+                // Track bt headset ping count
+                mBluetoothPingCount = getBluetoothPingCount();
+                mBluetoothPingStart = -1;
+            }
         }
 
-        // Track radio awake time
-        mRadioDataStart = getCurrentRadioDataUptime();
-        mRadioDataUptime = 0;
-
-        // Track bt headset ping count
-        mBluetoothPingStart = getCurrentBluetoothPingCount();
-        mBluetoothPingCount = 0;
-    }
-
-    public void doPlugLocked(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
-        for (int i = mUnpluggables.size() - 1; i >= 0; i--) {
-            mUnpluggables.get(i).plug(elapsedRealtime, batteryUptime, batteryRealtime);
+        boolean unpluggedScreenOff = unplugged && screenOff;
+        if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
+            updateKernelWakelocksLocked();
+            requestWakelockCpuUpdate();
+            if (!unpluggedScreenOff) {
+                // We are switching to no longer tracking wake locks, but we want
+                // the next CPU update we receive to take them in to account.
+                mDistributeWakelockCpu = true;
+            }
+            mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
         }
-
-        // Track radio awake time
-        mRadioDataUptime = getRadioDataUptime();
-        mRadioDataStart = -1;
-
-        // Track bt headset ping count
-        mBluetoothPingCount = getBluetoothPingCount();
-        mBluetoothPingStart = -1;
     }
 
-    int mWakeLockNesting;
+    public void addIsolatedUidLocked(int isolatedUid, int appUid) {
+        mIsolatedUids.put(isolatedUid, appUid);
+    }
 
-    public void noteStartWakeLocked(int uid, int pid, String name, int type) {
+    public void removeIsolatedUidLocked(int isolatedUid, int appUid) {
+        int curUid = mIsolatedUids.get(isolatedUid, -1);
+        if (curUid == appUid) {
+            mIsolatedUids.delete(isolatedUid);
+        }
+    }
+
+    public int mapUid(int uid) {
+        int isolated = mIsolatedUids.get(uid, -1);
+        return isolated > 0 ? isolated : uid;
+    }
+
+    public void noteEventLocked(int code, String name, int uid) {
+        uid = mapUid(uid);
+        if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
+            int idx = code&~HistoryItem.EVENT_FLAG_START;
+            HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
+            if (active == null) {
+                active = new HashMap<String, SparseBooleanArray>();
+                mActiveEvents[idx] = active;
+            }
+            SparseBooleanArray uids = active.get(name);
+            if (uids == null) {
+                uids = new SparseBooleanArray();
+                active.put(name, uids);
+            }
+            if (uids.get(uid)) {
+                // Already set, nothing to do!
+                return;
+            }
+            uids.put(uid, true);
+        } else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
+            int idx = code&~HistoryItem.EVENT_FLAG_FINISH;
+            HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
+            if (active == null) {
+                // not currently active, nothing to do.
+                return;
+            }
+            SparseBooleanArray uids = active.get(name);
+            if (uids == null) {
+                // not currently active, nothing to do.
+                return;
+            }
+            idx = uids.indexOfKey(uid);
+            if (idx < 0 || !uids.valueAt(idx)) {
+                // not currently active, nothing to do.
+                return;
+            }
+            uids.removeAt(idx);
+            if (uids.size() <= 0) {
+                active.remove(name);
+            }
+        }
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
+        addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
+    }
+
+    private void requestWakelockCpuUpdate() {
+        if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
+            Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
+            mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
+        }
+    }
+
+    public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
+            boolean unimportantForLogging, long elapsedRealtime, long uptime) {
+        uid = mapUid(uid);
         if (type == WAKE_TYPE_PARTIAL) {
             // Only care about partial wake locks, since full wake locks
             // will be canceled when the user puts the screen to sleep.
+            aggregateLastWakeupUptimeLocked(uptime);
             if (mWakeLockNesting == 0) {
                 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
                         + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
+                mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
+                mHistoryCur.wakelockTag.uid = uid;
+                mWakeLockImportant = !unimportantForLogging;
+                addHistoryRecordLocked(elapsedRealtime, uptime);
+            } else if (!mWakeLockImportant && !unimportantForLogging) {
+                if (mHistoryLastWritten.wakelockTag != null) {
+                    // We'll try to update the last tag.
+                    mHistoryLastWritten.wakelockTag = null;
+                    mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
+                    mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
+                    mHistoryCur.wakelockTag.uid = uid;
+                    addHistoryRecordLocked(elapsedRealtime, uptime);
+                }
+                mWakeLockImportant = true;
             }
             mWakeLockNesting++;
         }
         if (uid >= 0) {
-            if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
-                Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
-                mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
-            }
-            getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type);
+            //if (uid == 0) {
+            //    Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
+            //}
+            requestWakelockCpuUpdate();
+            getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
         }
     }
 
-    public void noteStopWakeLocked(int uid, int pid, String name, int type) {
+    public void noteStopWakeLocked(int uid, int pid, String name, int type, long elapsedRealtime,
+            long uptime) {
+        uid = mapUid(uid);
         if (type == WAKE_TYPE_PARTIAL) {
             mWakeLockNesting--;
             if (mWakeLockNesting == 0) {
                 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
                         + Integer.toHexString(mHistoryCur.states));
-                addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                addHistoryRecordLocked(elapsedRealtime, uptime);
             }
         }
         if (uid >= 0) {
-            if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
-                Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
-                mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
-            }
-            getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type);
+            requestWakelockCpuUpdate();
+            getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
         }
     }
 
-    public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
-        int N = ws.size();
+    public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
+            String historyName, int type, boolean unimportantForLogging) {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
+        final int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStartWakeLocked(ws.get(i), pid, name, type);
+            noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
+                    elapsedRealtime, uptime);
+        }
+    }
+
+    public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name, int type,
+            WorkSource newWs, int newPid, String newName,
+            String newHistoryName, int newType, boolean newUnimportantForLogging) {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
+        // For correct semantics, we start the need worksources first, so that we won't
+        // make inappropriate history items as if all wake locks went away and new ones
+        // appeared.  This is okay because tracking of wake locks allows nesting.
+        final int NN = newWs.size();
+        for (int i=0; i<NN; i++) {
+            noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
+                    newUnimportantForLogging, elapsedRealtime, uptime);
+        }
+        final int NO = ws.size();
+        for (int i=0; i<NO; i++) {
+            noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime, uptime);
         }
     }
 
     public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name, int type) {
-        int N = ws.size();
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
+        final int N = ws.size();
         for (int i=0; i<N; i++) {
-            noteStopWakeLocked(ws.get(i), pid, name, type);
+            noteStopWakeLocked(ws.get(i), pid, name, type, elapsedRealtime, uptime);
         }
     }
 
+    void aggregateLastWakeupUptimeLocked(long uptimeMs) {
+        if (mLastWakeupReason != null) {
+            long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
+            LongSamplingCounter timer = getWakeupReasonCounterLocked(mLastWakeupReason);
+            timer.addCountLocked(deltaUptime);
+            mLastWakeupReason = null;
+        }
+    }
+
+    public void noteWakeupReasonLocked(String reason) {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
+        if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason reason \"" + reason +"\": "
+                + Integer.toHexString(mHistoryCur.states));
+        aggregateLastWakeupUptimeLocked(uptime);
+        mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
+        mHistoryCur.wakeReasonTag.string = reason;
+        mHistoryCur.wakeReasonTag.uid = 0;
+        mLastWakeupReason = reason;
+        mLastWakeupUptimeMs = uptime;
+        addHistoryRecordLocked(elapsedRealtime, uptime);
+    }
+
     public int startAddingCpuLocked() {
         mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
 
-        if (mScreenOn) {
-            return 0;
-        }
-
         final int N = mPartialTimers.size();
         if (N == 0) {
             mLastPartialTimers.clear();
+            mDistributeWakelockCpu = false;
             return 0;
         }
 
+        if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
+            return 0;
+        }
+
+        mDistributeWakelockCpu = false;
+
         // How many timers should consume CPU?  Only want to include ones
         // that have already been in the list.
         for (int i=0; i<N; i++) {
@@ -1838,6 +2549,7 @@
     }
 
     public void noteProcessDiedLocked(int uid, int pid) {
+        uid = mapUid(uid);
         Uid u = mUidStats.get(uid);
         if (u != null) {
             u.mPids.remove(pid);
@@ -1845,17 +2557,19 @@
     }
 
     public long getProcessWakeTime(int uid, int pid, long realtime) {
+        uid = mapUid(uid);
         Uid u = mUidStats.get(uid);
         if (u != null) {
             Uid.Pid p = u.mPids.get(pid);
             if (p != null) {
-                return p.mWakeSum + (p.mWakeStart != 0 ? (realtime - p.mWakeStart) : 0);
+                return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
             }
         }
         return 0;
     }
 
     public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
+        uid = mapUid(uid);
         Uid u = mUidStats.get(uid);
         if (u != null) {
             u.reportExcessiveWakeLocked(proc, overTime, usedTime);
@@ -1863,6 +2577,7 @@
     }
 
     public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
+        uid = mapUid(uid);
         Uid u = mUidStats.get(uid);
         if (u != null) {
             u.reportExcessiveCpuLocked(proc, overTime, usedTime);
@@ -1872,67 +2587,85 @@
     int mSensorNesting;
 
     public void noteStartSensorLocked(int uid, int sensor) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mSensorNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
         mSensorNesting++;
-        getUidStatsLocked(uid).noteStartSensor(sensor);
+        getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
     }
 
     public void noteStopSensorLocked(int uid, int sensor) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         mSensorNesting--;
         if (mSensorNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
-        getUidStatsLocked(uid).noteStopSensor(sensor);
+        getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
     }
 
     int mGpsNesting;
 
     public void noteStartGpsLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mGpsNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
         mGpsNesting++;
-        getUidStatsLocked(uid).noteStartGps();
+        getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
     }
 
     public void noteStopGpsLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         mGpsNesting--;
         if (mGpsNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
-        getUidStatsLocked(uid).noteStopGps();
+        getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
     }
 
     public void noteScreenOnLocked() {
         if (!mScreenOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mScreenOn = true;
-            mScreenOnTimer.startRunningLocked(this);
+            mScreenOnTimer.startRunningLocked(elapsedRealtime);
             if (mScreenBrightnessBin >= 0) {
-                mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(this);
+                mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
             }
 
+            updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
+                    SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
+
             // Fake a wake lock, so we consider the device waked as long
             // as the screen is on.
-            noteStartWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
-            
+            noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
+                    elapsedRealtime, uptime);
+
             // Update discharge amounts.
             if (mOnBatteryInternal) {
                 updateDischargeScreenLevelsLocked(false, true);
@@ -1942,18 +2675,24 @@
 
     public void noteScreenOffLocked() {
         if (mScreenOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mScreenOn = false;
-            mScreenOnTimer.stopRunningLocked(this);
+            mScreenOnTimer.stopRunningLocked(elapsedRealtime);
             if (mScreenBrightnessBin >= 0) {
-                mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
+                mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
             }
 
-            noteStopWakeLocked(-1, -1, "dummy", WAKE_TYPE_PARTIAL);
-            
+            noteStopWakeLocked(-1, -1, "screen", WAKE_TYPE_PARTIAL,
+                    elapsedRealtime, uptime);
+
+            updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
+                    SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
+
             // Update discharge amounts.
             if (mOnBatteryInternal) {
                 updateDischargeScreenLevelsLocked(true, false);
@@ -1967,16 +2706,18 @@
         if (bin < 0) bin = 0;
         else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
         if (mScreenBrightnessBin != bin) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
                     | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
             if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             if (mScreenOn) {
                 if (mScreenBrightnessBin >= 0) {
-                    mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this);
+                    mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
                 }
-                mScreenBrightnessTimer[bin].startRunningLocked(this);
+                mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
             }
             mScreenBrightnessBin = bin;
         }
@@ -1987,38 +2728,84 @@
     }
 
     public void noteUserActivityLocked(int uid, int event) {
-        getUidStatsLocked(uid).noteUserActivityLocked(event);
+        if (mOnBatteryInternal) {
+            uid = mapUid(uid);
+            getUidStatsLocked(uid).noteUserActivityLocked(event);
+        }
+    }
+
+    public void noteDataConnectionActive(int type, boolean active, long timestampNs) {
+        if (ConnectivityManager.isNetworkTypeMobile(type)) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
+            if (mMobileRadioActive != active) {
+                long realElapsedRealtimeMs;
+                if (active) {
+                    realElapsedRealtimeMs = elapsedRealtime;
+                    mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                } else {
+                    realElapsedRealtimeMs = timestampNs / (1000*1000);
+                    long lastUpdateTimeMs = mMobileRadioActiveTimer.getLastUpdateTimeMs();
+                    if (realElapsedRealtimeMs < lastUpdateTimeMs) {
+                        Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
+                                + " is before start time " + lastUpdateTimeMs);
+                        realElapsedRealtimeMs = elapsedRealtime;
+                    } else if (realElapsedRealtimeMs < elapsedRealtime) {
+                        mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
+                                - realElapsedRealtimeMs);
+                    }
+                    mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
+                }
+                if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
+                        + Integer.toHexString(mHistoryCur.states));
+                addHistoryRecordLocked(elapsedRealtime, uptime);
+                mMobileRadioActive = active;
+                if (active) {
+                    mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
+                    mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
+                } else {
+                    mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
+                    updateNetworkActivityLocked(NET_UPDATE_MOBILE, realElapsedRealtimeMs);
+                    mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
+                }
+            }
+        }
     }
 
     public void notePhoneOnLocked() {
         if (!mPhoneOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mPhoneOn = true;
-            mPhoneOnTimer.startRunningLocked(this);
+            mPhoneOnTimer.startRunningLocked(elapsedRealtime);
         }
     }
 
     public void notePhoneOffLocked() {
         if (mPhoneOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mPhoneOn = false;
-            mPhoneOnTimer.stopRunningLocked(this);
+            mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
         }
     }
 
     void stopAllSignalStrengthTimersLocked(int except) {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
         for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
             if (i == except) {
                 continue;
             }
             while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
-                mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
+                mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
             }
         }
     }
@@ -2036,26 +2823,29 @@
         return state;
     }
 
-    private void updateAllPhoneStateLocked(int state, int simState, int bin) {
+    private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
         boolean scanning = false;
         boolean newHistory = false;
 
         mPhoneServiceStateRaw = state;
         mPhoneSimStateRaw = simState;
-        mPhoneSignalStrengthBinRaw = bin;
+        mPhoneSignalStrengthBinRaw = strengthBin;
+
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
 
         if (simState == TelephonyManager.SIM_STATE_ABSENT) {
             // In this case we will always be STATE_OUT_OF_SERVICE, so need
             // to infer that we are scanning from other data.
             if (state == ServiceState.STATE_OUT_OF_SERVICE
-                    && bin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
+                    && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
                 state = ServiceState.STATE_IN_SERVICE;
             }
         }
 
         // If the phone is powered off, stop all timers.
         if (state == ServiceState.STATE_POWER_OFF) {
-            bin = -1;
+            strengthBin = -1;
 
         // If we are in service, make sure the correct signal string timer is running.
         } else if (state == ServiceState.STATE_IN_SERVICE) {
@@ -2065,13 +2855,13 @@
         // bin and have the scanning bit set.
         } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
             scanning = true;
-            bin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+            strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
             if (!mPhoneSignalScanningTimer.isRunningLocked()) {
                 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
                 newHistory = true;
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
-                mPhoneSignalScanningTimer.startRunningLocked(this);
+                mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
             }
         }
 
@@ -2082,7 +2872,7 @@
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
                 newHistory = true;
-                mPhoneSignalScanningTimer.stopRunningLocked(this);
+                mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
             }
         }
 
@@ -2095,27 +2885,28 @@
             mPhoneServiceState = state;
         }
 
-        if (mPhoneSignalStrengthBin != bin) {
+        if (mPhoneSignalStrengthBin != strengthBin) {
             if (mPhoneSignalStrengthBin >= 0) {
-                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this);
+                mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
+                        elapsedRealtime);
             }
-            if (bin >= 0) {
-                if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
-                    mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
+            if (strengthBin >= 0) {
+                if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
+                    mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
                 }
                 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_SIGNAL_STRENGTH_MASK)
-                        | (bin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
-                if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: "
+                        | (strengthBin << HistoryItem.STATE_SIGNAL_STRENGTH_SHIFT);
+                if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
                         + Integer.toHexString(mHistoryCur.states));
                 newHistory = true;
             } else {
                 stopAllSignalStrengthTimersLocked(-1);
             }
-            mPhoneSignalStrengthBin = bin;
+            mPhoneSignalStrengthBin = strengthBin;
         }
 
         if (newHistory) {
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
     }
 
@@ -2189,120 +2980,142 @@
         }
         if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
         if (mPhoneDataConnectionType != bin) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
                     | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
             if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             if (mPhoneDataConnectionType >= 0) {
-                mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this);
+                mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
+                        elapsedRealtime);
             }
             mPhoneDataConnectionType = bin;
-            mPhoneDataConnectionsTimer[bin].startRunningLocked(this);
+            mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
         }
     }
 
     public void noteWifiOnLocked() {
         if (!mWifiOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states |= HistoryItem.STATE_WIFI_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mWifiOn = true;
-            mWifiOnTimer.startRunningLocked(this);
+            mWifiOnTimer.startRunningLocked(elapsedRealtime);
         }
     }
 
     public void noteWifiOffLocked() {
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mWifiOn) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mWifiOn = false;
-            mWifiOnTimer.stopRunningLocked(this);
-        }
-        if (mWifiOnUid >= 0) {
-            getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked();
-            mWifiOnUid = -1;
+            mWifiOnTimer.stopRunningLocked(elapsedRealtime);
         }
     }
 
     public void noteAudioOnLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (!mAudioOn) {
             mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mAudioOn = true;
-            mAudioOnTimer.startRunningLocked(this);
+            mAudioOnTimer.startRunningLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteAudioTurnedOnLocked();
+        getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
     }
 
     public void noteAudioOffLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mAudioOn) {
             mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mAudioOn = false;
-            mAudioOnTimer.stopRunningLocked(this);
+            mAudioOnTimer.stopRunningLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteAudioTurnedOffLocked();
+        getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
     }
 
     public void noteVideoOnLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (!mVideoOn) {
-            mHistoryCur.states |= HistoryItem.STATE_VIDEO_ON_FLAG;
+            mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mVideoOn = true;
-            mVideoOnTimer.startRunningLocked(this);
+            mVideoOnTimer.startRunningLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteVideoTurnedOnLocked();
+        getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
     }
 
     public void noteVideoOffLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mVideoOn) {
-            mHistoryCur.states &= ~HistoryItem.STATE_VIDEO_ON_FLAG;
+            mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mVideoOn = false;
-            mVideoOnTimer.stopRunningLocked(this);
+            mVideoOnTimer.stopRunningLocked(elapsedRealtime);
         }
-        getUidStatsLocked(uid).noteVideoTurnedOffLocked();
+        getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
     }
 
     public void noteActivityResumedLocked(int uid) {
-        getUidStatsLocked(uid).noteActivityResumedLocked();
+        uid = mapUid(uid);
+        getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
     }
 
     public void noteActivityPausedLocked(int uid) {
-        getUidStatsLocked(uid).noteActivityPausedLocked();
+        uid = mapUid(uid);
+        getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
     }
 
     public void noteVibratorOnLocked(int uid, long durationMillis) {
+        uid = mapUid(uid);
         getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
     }
 
     public void noteVibratorOffLocked(int uid) {
+        uid = mapUid(uid);
         getUidStatsLocked(uid).noteVibratorOffLocked();
     }
 
     public void noteWifiRunningLocked(WorkSource ws) {
         if (!mGlobalWifiRunning) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states |= HistoryItem.STATE_WIFI_RUNNING_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mGlobalWifiRunning = true;
-            mGlobalWifiRunningTimer.startRunningLocked(this);
+            mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
             int N = ws.size();
             for (int i=0; i<N; i++) {
-                getUidStatsLocked(ws.get(i)).noteWifiRunningLocked();
+                int uid = mapUid(ws.get(i));
+                getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
             }
         } else {
             Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
@@ -2311,13 +3124,16 @@
 
     public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
         if (mGlobalWifiRunning) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             int N = oldWs.size();
             for (int i=0; i<N; i++) {
-                getUidStatsLocked(oldWs.get(i)).noteWifiStoppedLocked();
+                int uid = mapUid(oldWs.get(i));
+                getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
             }
             N = newWs.size();
             for (int i=0; i<N; i++) {
-                getUidStatsLocked(newWs.get(i)).noteWifiRunningLocked();
+                int uid = mapUid(newWs.get(i));
+                getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
             }
         } else {
             Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
@@ -2326,121 +3142,174 @@
 
     public void noteWifiStoppedLocked(WorkSource ws) {
         if (mGlobalWifiRunning) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RUNNING_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mGlobalWifiRunning = false;
-            mGlobalWifiRunningTimer.stopRunningLocked(this);
+            mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
             int N = ws.size();
             for (int i=0; i<N; i++) {
-                getUidStatsLocked(ws.get(i)).noteWifiStoppedLocked();
+                int uid = mapUid(ws.get(i));
+                getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
             }
         } else {
             Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
         }
     }
 
+    public void noteWifiStateLocked(int wifiState, String accessPoint) {
+        if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
+        if (mWifiState != wifiState) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            if (mWifiState >= 0) {
+                mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
+            }
+            mWifiState = wifiState;
+            mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
+        }
+    }
+
     public void noteBluetoothOnLocked() {
         if (!mBluetoothOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mBluetoothOn = true;
-            mBluetoothOnTimer.startRunningLocked(this);
+            mBluetoothOnTimer.startRunningLocked(elapsedRealtime);
         }
     }
 
     public void noteBluetoothOffLocked() {
         if (mBluetoothOn) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
             mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
             mBluetoothOn = false;
-            mBluetoothOnTimer.stopRunningLocked(this);
+            mBluetoothOnTimer.stopRunningLocked(elapsedRealtime);
+        }
+    }
+
+    public void noteBluetoothStateLocked(int bluetoothState) {
+        if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState);
+        if (mBluetoothState != bluetoothState) {
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            if (mBluetoothState >= 0) {
+                mBluetoothStateTimer[mBluetoothState].stopRunningLocked(elapsedRealtime);
+            }
+            mBluetoothState = bluetoothState;
+            mBluetoothStateTimer[bluetoothState].startRunningLocked(elapsedRealtime);
         }
     }
 
     int mWifiFullLockNesting = 0;
 
     public void noteFullWifiLockAcquiredLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mWifiFullLockNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
         mWifiFullLockNesting++;
-        getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
+        getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
     }
 
     public void noteFullWifiLockReleasedLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         mWifiFullLockNesting--;
         if (mWifiFullLockNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
-        getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
+        getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
     }
 
     int mWifiScanNesting = 0;
 
     public void noteWifiScanStartedLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mWifiScanNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
         mWifiScanNesting++;
-        getUidStatsLocked(uid).noteWifiScanStartedLocked();
+        getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
     }
 
     public void noteWifiScanStoppedLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         mWifiScanNesting--;
         if (mWifiScanNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
-        getUidStatsLocked(uid).noteWifiScanStoppedLocked();
+        getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
     }
 
     public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
-        getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph);
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
     }
 
     public void noteWifiBatchedScanStoppedLocked(int uid) {
-        getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked();
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
     }
 
     int mWifiMulticastNesting = 0;
 
     public void noteWifiMulticastEnabledLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         if (mWifiMulticastNesting == 0) {
             mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
         mWifiMulticastNesting++;
-        getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
+        getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
     }
 
     public void noteWifiMulticastDisabledLocked(int uid) {
+        uid = mapUid(uid);
+        final long elapsedRealtime = SystemClock.elapsedRealtime();
+        final long uptime = SystemClock.uptimeMillis();
         mWifiMulticastNesting--;
         if (mWifiMulticastNesting == 0) {
             mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(SystemClock.elapsedRealtime());
+            addHistoryRecordLocked(elapsedRealtime, uptime);
         }
-        getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
+        getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
     }
 
     public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
@@ -2499,16 +3368,45 @@
         }
     }
 
+    private static String[] includeInStringArray(String[] array, String str) {
+        if (ArrayUtils.indexOf(array, str) >= 0) {
+            return array;
+        }
+        String[] newArray = new String[array.length+1];
+        System.arraycopy(array, 0, newArray, 0, array.length);
+        newArray[array.length] = str;
+        return newArray;
+    }
+
+    private static String[] excludeFromStringArray(String[] array, String str) {
+        int index = ArrayUtils.indexOf(array, str);
+        if (index >= 0) {
+            String[] newArray = new String[array.length-1];
+            if (index > 0) {
+                System.arraycopy(array, 0, newArray, 0, index);
+            }
+            if (index < array.length-1) {
+                System.arraycopy(array, index+1, newArray, index, array.length-index-1);
+            }
+            return newArray;
+        }
+        return array;
+    }
+
     public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
         if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
-            mMobileIfaces.add(iface);
+            mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
         } else {
-            mMobileIfaces.remove(iface);
+            mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
         }
         if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
-            mWifiIfaces.add(iface);
+            mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
         } else {
-            mWifiIfaces.remove(iface);
+            mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
+            if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
         }
     }
 
@@ -2516,37 +3414,45 @@
         // 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();
+        updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
     }
 
-    @Override public long getScreenOnTime(long batteryRealtime, int which) {
-        return mScreenOnTimer.getTotalTimeLocked(batteryRealtime, which);
+    @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
+        return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+    }
+
+    @Override public int getScreenOnCount(int which) {
+        return mScreenOnTimer.getCountLocked(which);
     }
 
     @Override public long getScreenBrightnessTime(int brightnessBin,
-            long batteryRealtime, int which) {
+            long elapsedRealtimeUs, int which) {
         return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
-                batteryRealtime, which);
+                elapsedRealtimeUs, which);
     }
 
     @Override public int getInputEventCount(int which) {
         return mInputEventCounter.getCountLocked(which);
     }
 
-    @Override public long getPhoneOnTime(long batteryRealtime, int which) {
-        return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
+    @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
+        return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+    }
+
+    @Override public int getPhoneOnCount(int which) {
+        return mPhoneOnTimer.getCountLocked(which);
     }
 
     @Override public long getPhoneSignalStrengthTime(int strengthBin,
-            long batteryRealtime, int which) {
+            long elapsedRealtimeUs, int which) {
         return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
-                batteryRealtime, which);
+                elapsedRealtimeUs, which);
     }
 
     @Override public long getPhoneSignalScanningTime(
-            long batteryRealtime, int which) {
+            long elapsedRealtimeUs, int which) {
         return mPhoneSignalScanningTimer.getTotalTimeLocked(
-                batteryRealtime, which);
+                elapsedRealtimeUs, which);
     }
 
     @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
@@ -2554,36 +3460,89 @@
     }
 
     @Override public long getPhoneDataConnectionTime(int dataType,
-            long batteryRealtime, int which) {
+            long elapsedRealtimeUs, int which) {
         return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
-                batteryRealtime, which);
+                elapsedRealtimeUs, which);
     }
 
     @Override public int getPhoneDataConnectionCount(int dataType, int which) {
         return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
     }
 
-    @Override public long getWifiOnTime(long batteryRealtime, int which) {
-        return mWifiOnTimer.getTotalTimeLocked(batteryRealtime, which);
+    @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
+        return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
     }
 
-    @Override public long getGlobalWifiRunningTime(long batteryRealtime, int which) {
-        return mGlobalWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
+    @Override public int getMobileRadioActiveCount(int which) {
+        return mMobileRadioActiveTimer.getCountLocked(which);
     }
 
-    @Override public long getBluetoothOnTime(long batteryRealtime, int which) {
-        return mBluetoothOnTimer.getTotalTimeLocked(batteryRealtime, which);
+    @Override public long getMobileRadioActiveAdjustedTime(int which) {
+        return mMobileRadioActiveAdjustedTime.getCountLocked(which);
+    }
+
+    @Override public long getMobileRadioActiveUnknownTime(int which) {
+        return mMobileRadioActiveUnknownTime.getCountLocked(which);
+    }
+
+    @Override public int getMobileRadioActiveUnknownCount(int which) {
+        return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
+    }
+
+    @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
+        return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+    }
+
+    @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
+        return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+    }
+
+    @Override public long getWifiStateTime(int wifiState,
+            long elapsedRealtimeUs, int which) {
+        return mWifiStateTimer[wifiState].getTotalTimeLocked(
+                elapsedRealtimeUs, which);
+    }
+
+    @Override public int getWifiStateCount(int wifiState, int which) {
+        return mWifiStateTimer[wifiState].getCountLocked(which);
+    }
+
+    @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) {
+        return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+    }
+
+    @Override public long getBluetoothStateTime(int bluetoothState,
+            long elapsedRealtimeUs, int which) {
+        return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked(
+                elapsedRealtimeUs, which);
+    }
+
+    @Override public int getBluetoothStateCount(int bluetoothState, int which) {
+        return mBluetoothStateTimer[bluetoothState].getCountLocked(which);
     }
 
     @Override
-    public long getNetworkActivityCount(int type, int which) {
-        if (type >= 0 && type < mNetworkActivityCounters.length) {
-            return mNetworkActivityCounters[type].getCountLocked(which);
+    public long getNetworkActivityBytes(int type, int which) {
+        if (type >= 0 && type < mNetworkByteActivityCounters.length) {
+            return mNetworkByteActivityCounters[type].getCountLocked(which);
         } else {
             return 0;
         }
     }
 
+    @Override
+    public long getNetworkActivityPackets(int type, int which) {
+        if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
+            return mNetworkPacketActivityCounters[type].getCountLocked(which);
+        } else {
+            return 0;
+        }
+    }
+
+    @Override public long getStartClockTime() {
+        return mStartClockTime;
+    }
+
     @Override public boolean getIsOnBattery() {
         return mOnBattery;
     }
@@ -2627,7 +3586,10 @@
 
         Counter[] mUserActivityCounters;
 
-        LongSamplingCounter[] mNetworkActivityCounters;
+        LongSamplingCounter[] mNetworkByteActivityCounters;
+        LongSamplingCounter[] mNetworkPacketActivityCounters;
+        LongSamplingCounter mMobileRadioActiveTime;
+        LongSamplingCounter mMobileRadioActiveCount;
 
         /**
          * The statistics we have collected for this uid's wake locks.
@@ -2657,14 +3619,14 @@
         public Uid(int uid) {
             mUid = uid;
             mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
-                    mWifiRunningTimers, mUnpluggables);
+                    mWifiRunningTimers, mOnBatteryTimeBase);
             mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
-                    mFullWifiLockTimers, mUnpluggables);
+                    mFullWifiLockTimers, mOnBatteryTimeBase);
             mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
-                    mWifiScanTimers, mUnpluggables);
+                    mWifiScanTimers, mOnBatteryTimeBase);
             mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
             mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
-                    mWifiMulticastTimers, mUnpluggables);
+                    mWifiMulticastTimers, mOnBatteryTimeBase);
         }
 
         @Override
@@ -2693,67 +3655,67 @@
         }
 
         @Override
-        public void noteWifiRunningLocked() {
+        public void noteWifiRunningLocked(long elapsedRealtimeMs) {
             if (!mWifiRunning) {
                 mWifiRunning = true;
                 if (mWifiRunningTimer == null) {
                     mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
-                            mWifiRunningTimers, mUnpluggables);
+                            mWifiRunningTimers, mOnBatteryTimeBase);
                 }
-                mWifiRunningTimer.startRunningLocked(BatteryStatsImpl.this);
+                mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteWifiStoppedLocked() {
+        public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
             if (mWifiRunning) {
                 mWifiRunning = false;
-                mWifiRunningTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteFullWifiLockAcquiredLocked() {
+        public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
             if (!mFullWifiLockOut) {
                 mFullWifiLockOut = true;
                 if (mFullWifiLockTimer == null) {
                     mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
-                            mFullWifiLockTimers, mUnpluggables);
+                            mFullWifiLockTimers, mOnBatteryTimeBase);
                 }
-                mFullWifiLockTimer.startRunningLocked(BatteryStatsImpl.this);
+                mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteFullWifiLockReleasedLocked() {
+        public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
             if (mFullWifiLockOut) {
                 mFullWifiLockOut = false;
-                mFullWifiLockTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteWifiScanStartedLocked() {
+        public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
             if (!mWifiScanStarted) {
                 mWifiScanStarted = true;
                 if (mWifiScanTimer == null) {
                     mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
-                            mWifiScanTimers, mUnpluggables);
+                            mWifiScanTimers, mOnBatteryTimeBase);
                 }
-                mWifiScanTimer.startRunningLocked(BatteryStatsImpl.this);
+                mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteWifiScanStoppedLocked() {
+        public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
             if (mWifiScanStarted) {
                 mWifiScanStarted = false;
-                mWifiScanTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteWifiBatchedScanStartedLocked(int csph) {
+        public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
             int bin = 0;
             while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
                 csph = csph >> 3;
@@ -2764,66 +3726,66 @@
 
             if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
                 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
-                        stopRunningLocked(BatteryStatsImpl.this);
+                        stopRunningLocked(elapsedRealtimeMs);
             }
             mWifiBatchedScanBinStarted = bin;
             if (mWifiBatchedScanTimer[bin] == null) {
                 makeWifiBatchedScanBin(bin, null);
             }
-            mWifiBatchedScanTimer[bin].startRunningLocked(BatteryStatsImpl.this);
+            mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
         }
 
         @Override
-        public void noteWifiBatchedScanStoppedLocked() {
+        public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
             if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
                 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
-                        stopRunningLocked(BatteryStatsImpl.this);
+                        stopRunningLocked(elapsedRealtimeMs);
                 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
             }
         }
 
         @Override
-        public void noteWifiMulticastEnabledLocked() {
+        public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
             if (!mWifiMulticastEnabled) {
                 mWifiMulticastEnabled = true;
                 if (mWifiMulticastTimer == null) {
                     mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
-                            mWifiMulticastTimers, mUnpluggables);
+                            mWifiMulticastTimers, mOnBatteryTimeBase);
                 }
-                mWifiMulticastTimer.startRunningLocked(BatteryStatsImpl.this);
+                mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteWifiMulticastDisabledLocked() {
+        public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
             if (mWifiMulticastEnabled) {
                 mWifiMulticastEnabled = false;
-                mWifiMulticastTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
 
         public StopwatchTimer createAudioTurnedOnTimerLocked() {
             if (mAudioTurnedOnTimer == null) {
                 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
-                        null, mUnpluggables);
+                        null, mOnBatteryTimeBase);
             }
             return mAudioTurnedOnTimer;
         }
 
         @Override
-        public void noteAudioTurnedOnLocked() {
+        public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
             if (!mAudioTurnedOn) {
                 mAudioTurnedOn = true;
-                createAudioTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+                createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteAudioTurnedOffLocked() {
+        public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
             if (mAudioTurnedOn) {
                 mAudioTurnedOn = false;
                 if (mAudioTurnedOnTimer != null) {
-                    mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
+                    mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
                 }
             }
         }
@@ -2831,25 +3793,25 @@
         public StopwatchTimer createVideoTurnedOnTimerLocked() {
             if (mVideoTurnedOnTimer == null) {
                 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
-                        null, mUnpluggables);
+                        null, mOnBatteryTimeBase);
             }
             return mVideoTurnedOnTimer;
         }
 
         @Override
-        public void noteVideoTurnedOnLocked() {
+        public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
             if (!mVideoTurnedOn) {
                 mVideoTurnedOn = true;
-                createVideoTurnedOnTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+                createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
             }
         }
 
         @Override
-        public void noteVideoTurnedOffLocked() {
+        public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
             if (mVideoTurnedOn) {
                 mVideoTurnedOn = false;
                 if (mVideoTurnedOnTimer != null) {
-                    mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
+                    mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
                 }
             }
         }
@@ -2857,28 +3819,27 @@
         public StopwatchTimer createForegroundActivityTimerLocked() {
             if (mForegroundActivityTimer == null) {
                 mForegroundActivityTimer = new StopwatchTimer(
-                        Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables);
+                        Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
             }
             return mForegroundActivityTimer;
         }
 
         @Override
-        public void noteActivityResumedLocked() {
+        public void noteActivityResumedLocked(long elapsedRealtimeMs) {
             // We always start, since we want multiple foreground PIDs to nest
-            createForegroundActivityTimerLocked().startRunningLocked(BatteryStatsImpl.this);
+            createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
         }
 
         @Override
-        public void noteActivityPausedLocked() {
+        public void noteActivityPausedLocked(long elapsedRealtimeMs) {
             if (mForegroundActivityTimer != null) {
-                mForegroundActivityTimer.stopRunningLocked(BatteryStatsImpl.this);
+                mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
             }
         }
 
         public BatchTimer createVibratorOnTimerLocked() {
             if (mVibratorOnTimer == null) {
-                mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
-                        mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal);
+                mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
             }
             return mVibratorOnTimer;
         }
@@ -2894,61 +3855,60 @@
         }
 
         @Override
-        public long getWifiRunningTime(long batteryRealtime, int which) {
+        public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
             if (mWifiRunningTimer == null) {
                 return 0;
             }
-            return mWifiRunningTimer.getTotalTimeLocked(batteryRealtime, which);
+            return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
-        public long getFullWifiLockTime(long batteryRealtime, int which) {
+        public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
             if (mFullWifiLockTimer == null) {
                 return 0;
             }
-            return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
+            return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
-        public long getWifiScanTime(long batteryRealtime, int which) {
+        public long getWifiScanTime(long elapsedRealtimeUs, int which) {
             if (mWifiScanTimer == null) {
                 return 0;
             }
-            return mWifiScanTimer.getTotalTimeLocked(batteryRealtime, which);
+            return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
-        public long getWifiBatchedScanTime(int csphBin, long batteryRealtime, int which) {
+        public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
             if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
             if (mWifiBatchedScanTimer[csphBin] == null) {
                 return 0;
             }
-            return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(batteryRealtime, which);
+            return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
-        public long getWifiMulticastTime(long batteryRealtime, int which) {
+        public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
             if (mWifiMulticastTimer == null) {
                 return 0;
             }
-            return mWifiMulticastTimer.getTotalTimeLocked(batteryRealtime,
-                                                          which);
+            return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
-        public long getAudioTurnedOnTime(long batteryRealtime, int which) {
+        public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
             if (mAudioTurnedOnTimer == null) {
                 return 0;
             }
-            return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
+            return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
-        public long getVideoTurnedOnTime(long batteryRealtime, int which) {
+        public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
             if (mVideoTurnedOnTimer == null) {
                 return 0;
             }
-            return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
+            return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
@@ -2997,10 +3957,10 @@
             }
             if (in == null) {
                 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
-                        mUnpluggables);
+                        mOnBatteryTimeBase);
             } else {
                 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
-                        mUnpluggables, in);
+                        mOnBatteryTimeBase, in);
             }
         }
 
@@ -3008,44 +3968,79 @@
         void initUserActivityLocked() {
             mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
             for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
-                mUserActivityCounters[i] = new Counter(mUnpluggables);
+                mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
             }
         }
 
-        void noteNetworkActivityLocked(int type, long delta) {
-            if (mNetworkActivityCounters == null) {
+        void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
+            if (mNetworkByteActivityCounters == null) {
                 initNetworkActivityLocked();
             }
             if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
-                mNetworkActivityCounters[type].addCountLocked(delta);
+                mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
+                mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
             } else {
                 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
                         new Throwable());
             }
         }
 
-        @Override
-        public boolean hasNetworkActivity() {
-            return mNetworkActivityCounters != null;
+        void noteMobileRadioActiveTimeLocked(long batteryUptime) {
+            if (mNetworkByteActivityCounters == null) {
+                initNetworkActivityLocked();
+            }
+            mMobileRadioActiveTime.addCountLocked(batteryUptime);
+            mMobileRadioActiveCount.addCountLocked(1);
         }
 
         @Override
-        public long getNetworkActivityCount(int type, int which) {
-            if (mNetworkActivityCounters != null && type >= 0
-                    && type < mNetworkActivityCounters.length) {
-                return mNetworkActivityCounters[type].getCountLocked(which);
+        public boolean hasNetworkActivity() {
+            return mNetworkByteActivityCounters != null;
+        }
+
+        @Override
+        public long getNetworkActivityBytes(int type, int which) {
+            if (mNetworkByteActivityCounters != null && type >= 0
+                    && type < mNetworkByteActivityCounters.length) {
+                return mNetworkByteActivityCounters[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);
+        @Override
+        public long getNetworkActivityPackets(int type, int which) {
+            if (mNetworkPacketActivityCounters != null && type >= 0
+                    && type < mNetworkPacketActivityCounters.length) {
+                return mNetworkPacketActivityCounters[type].getCountLocked(which);
+            } else {
+                return 0;
             }
         }
 
+        @Override
+        public long getMobileRadioActiveTime(int which) {
+            return mMobileRadioActiveTime != null
+                    ? mMobileRadioActiveTime.getCountLocked(which) : 0;
+        }
+
+        @Override
+        public int getMobileRadioActiveCount(int which) {
+            return mMobileRadioActiveCount != null
+                    ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
+        }
+
+        void initNetworkActivityLocked() {
+            mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+            mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+            for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+                mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+                mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+            }
+            mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
+            mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
+        }
+
         /**
          * Clear all stats for this uid.  Returns true if the uid is completely
          * inactive so can be dropped.
@@ -3054,42 +4049,42 @@
             boolean active = false;
 
             if (mWifiRunningTimer != null) {
-                active |= !mWifiRunningTimer.reset(BatteryStatsImpl.this, false);
+                active |= !mWifiRunningTimer.reset(false);
                 active |= mWifiRunning;
             }
             if (mFullWifiLockTimer != null) {
-                active |= !mFullWifiLockTimer.reset(BatteryStatsImpl.this, false);
+                active |= !mFullWifiLockTimer.reset(false);
                 active |= mFullWifiLockOut;
             }
             if (mWifiScanTimer != null) {
-                active |= !mWifiScanTimer.reset(BatteryStatsImpl.this, false);
+                active |= !mWifiScanTimer.reset(false);
                 active |= mWifiScanStarted;
             }
             if (mWifiBatchedScanTimer != null) {
                 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
                     if (mWifiBatchedScanTimer[i] != null) {
-                        active |= !mWifiBatchedScanTimer[i].reset(BatteryStatsImpl.this, false);
+                        active |= !mWifiBatchedScanTimer[i].reset(false);
                     }
                 }
                 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
             }
             if (mWifiMulticastTimer != null) {
-                active |= !mWifiMulticastTimer.reset(BatteryStatsImpl.this, false);
+                active |= !mWifiMulticastTimer.reset(false);
                 active |= mWifiMulticastEnabled;
             }
             if (mAudioTurnedOnTimer != null) {
-                active |= !mAudioTurnedOnTimer.reset(BatteryStatsImpl.this, false);
+                active |= !mAudioTurnedOnTimer.reset(false);
                 active |= mAudioTurnedOn;
             }
             if (mVideoTurnedOnTimer != null) {
-                active |= !mVideoTurnedOnTimer.reset(BatteryStatsImpl.this, false);
+                active |= !mVideoTurnedOnTimer.reset(false);
                 active |= mVideoTurnedOn;
             }
             if (mForegroundActivityTimer != null) {
-                active |= !mForegroundActivityTimer.reset(BatteryStatsImpl.this, false);
+                active |= !mForegroundActivityTimer.reset(false);
             }
             if (mVibratorOnTimer != null) {
-                if (mVibratorOnTimer.reset(BatteryStatsImpl.this, false)) {
+                if (mVibratorOnTimer.reset(false)) {
                     mVibratorOnTimer.detach();
                     mVibratorOnTimer = null;
                 } else {
@@ -3103,10 +4098,13 @@
                 }
             }
 
-            if (mNetworkActivityCounters != null) {
+            if (mNetworkByteActivityCounters != null) {
                 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                    mNetworkActivityCounters[i].reset(false);
+                    mNetworkByteActivityCounters[i].reset(false);
+                    mNetworkPacketActivityCounters[i].reset(false);
                 }
+                mMobileRadioActiveTime.reset(false);
+                mMobileRadioActiveCount.reset(false);
             }
 
             if (mWakelockStats.size() > 0) {
@@ -3142,10 +4140,12 @@
                 mProcessStats.clear();
             }
             if (mPids.size() > 0) {
-                for (int i=0; !active && i<mPids.size(); i++) {
+                for (int i=mPids.size()-1; i>=0; i--) {
                     Pid pid = mPids.valueAt(i);
-                    if (pid.mWakeStart != 0) {
+                    if (pid.mWakeNesting > 0) {
                         active = true;
+                    } else {
+                        mPids.removeAt(i);
                     }
                 }
             }
@@ -3167,8 +4167,6 @@
                 mPackageStats.clear();
             }
 
-            mPids.clear();
-
             if (!active) {
                 if (mWifiRunningTimer != null) {
                     mWifiRunningTimer.detach();
@@ -3204,29 +4202,31 @@
                         mUserActivityCounters[i].detach();
                     }
                 }
-                if (mNetworkActivityCounters != null) {
+                if (mNetworkByteActivityCounters != null) {
                     for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                        mNetworkActivityCounters[i].detach();
+                        mNetworkByteActivityCounters[i].detach();
+                        mNetworkPacketActivityCounters[i].detach();
                     }
                 }
+                mPids.clear();
             }
 
             return !active;
         }
 
-        void writeToParcelLocked(Parcel out, long batteryRealtime) {
+        void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
             out.writeInt(mWakelockStats.size());
             for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
                 out.writeString(wakelockEntry.getKey());
                 Uid.Wakelock wakelock = wakelockEntry.getValue();
-                wakelock.writeToParcelLocked(out, batteryRealtime);
+                wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
             }
 
             out.writeInt(mSensorStats.size());
             for (Map.Entry<Integer, Uid.Sensor> sensorEntry : mSensorStats.entrySet()) {
                 out.writeInt(sensorEntry.getKey());
                 Uid.Sensor sensor = sensorEntry.getValue();
-                sensor.writeToParcelLocked(out, batteryRealtime);
+                sensor.writeToParcelLocked(out, elapsedRealtimeUs);
             }
 
             out.writeInt(mProcessStats.size());
@@ -3245,57 +4245,57 @@
 
             if (mWifiRunningTimer != null) {
                 out.writeInt(1);
-                mWifiRunningTimer.writeToParcel(out, batteryRealtime);
+                mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
             if (mFullWifiLockTimer != null) {
                 out.writeInt(1);
-                mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
+                mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
             if (mWifiScanTimer != null) {
                 out.writeInt(1);
-                mWifiScanTimer.writeToParcel(out, batteryRealtime);
+                mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
             for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
                 if (mWifiBatchedScanTimer[i] != null) {
                     out.writeInt(1);
-                    mWifiBatchedScanTimer[i].writeToParcel(out, batteryRealtime);
+                    mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
                 } else {
                     out.writeInt(0);
                 }
             }
             if (mWifiMulticastTimer != null) {
                 out.writeInt(1);
-                mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
+                mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
             if (mAudioTurnedOnTimer != null) {
                 out.writeInt(1);
-                mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
+                mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
             if (mVideoTurnedOnTimer != null) {
                 out.writeInt(1);
-                mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
+                mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
             if (mForegroundActivityTimer != null) {
                 out.writeInt(1);
-                mForegroundActivityTimer.writeToParcel(out, batteryRealtime);
+                mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
             if (mVibratorOnTimer != null) {
                 out.writeInt(1);
-                mVibratorOnTimer.writeToParcel(out, batteryRealtime);
+                mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
             } else {
                 out.writeInt(0);
             }
@@ -3307,23 +4307,26 @@
             } else {
                 out.writeInt(0);
             }
-            if (mNetworkActivityCounters != null) {
+            if (mNetworkByteActivityCounters != null) {
                 out.writeInt(1);
                 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                    mNetworkActivityCounters[i].writeToParcel(out);
+                    mNetworkByteActivityCounters[i].writeToParcel(out);
+                    mNetworkPacketActivityCounters[i].writeToParcel(out);
                 }
+                mMobileRadioActiveTime.writeToParcel(out);
+                mMobileRadioActiveCount.writeToParcel(out);
             } else {
                 out.writeInt(0);
             }
         }
 
-        void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
+        void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
             int numWakelocks = in.readInt();
             mWakelockStats.clear();
             for (int j = 0; j < numWakelocks; j++) {
                 String wakelockName = in.readString();
                 Uid.Wakelock wakelock = new Wakelock();
-                wakelock.readFromParcelLocked(unpluggables, in);
+                wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
                 // We will just drop some random set of wakelocks if
                 // the previous run of the system was an older version
                 // that didn't impose a limit.
@@ -3335,7 +4338,7 @@
             for (int k = 0; k < numSensors; k++) {
                 int sensorNumber = in.readInt();
                 Uid.Sensor sensor = new Sensor(sensorNumber);
-                sensor.readFromParcelLocked(mUnpluggables, in);
+                sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
                 mSensorStats.put(sensorNumber, sensor);
             }
 
@@ -3360,21 +4363,21 @@
             mWifiRunning = false;
             if (in.readInt() != 0) {
                 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
-                        mWifiRunningTimers, mUnpluggables, in);
+                        mWifiRunningTimers, mOnBatteryTimeBase, in);
             } else {
                 mWifiRunningTimer = null;
             }
             mFullWifiLockOut = false;
             if (in.readInt() != 0) {
                 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
-                        mFullWifiLockTimers, mUnpluggables, in);
+                        mFullWifiLockTimers, mOnBatteryTimeBase, in);
             } else {
                 mFullWifiLockTimer = null;
             }
             mWifiScanStarted = false;
             if (in.readInt() != 0) {
                 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
-                        mWifiScanTimers, mUnpluggables, in);
+                        mWifiScanTimers, mOnBatteryTimeBase, in);
             } else {
                 mWifiScanTimer = null;
             }
@@ -3389,51 +4392,58 @@
             mWifiMulticastEnabled = false;
             if (in.readInt() != 0) {
                 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
-                        mWifiMulticastTimers, mUnpluggables, in);
+                        mWifiMulticastTimers, mOnBatteryTimeBase, in);
             } else {
                 mWifiMulticastTimer = null;
             }
             mAudioTurnedOn = false;
             if (in.readInt() != 0) {
                 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
-                        null, mUnpluggables, in);
+                        null, mOnBatteryTimeBase, in);
             } else {
                 mAudioTurnedOnTimer = null;
             }
             mVideoTurnedOn = false;
             if (in.readInt() != 0) {
                 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
-                        null, mUnpluggables, in);
+                        null, mOnBatteryTimeBase, in);
             } else {
                 mVideoTurnedOnTimer = null;
             }
             if (in.readInt() != 0) {
                 mForegroundActivityTimer = new StopwatchTimer(
-                        Uid.this, FOREGROUND_ACTIVITY, null, mUnpluggables, in);
+                        Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
             } else {
                 mForegroundActivityTimer = null;
             }
             if (in.readInt() != 0) {
-                mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON,
-                        mUnpluggables, BatteryStatsImpl.this.mOnBatteryInternal, in);
+                mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
             } else {
                 mVibratorOnTimer = null;
             }
             if (in.readInt() != 0) {
                 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
                 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
-                    mUserActivityCounters[i] = new Counter(mUnpluggables, in);
+                    mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
                 }
             } else {
                 mUserActivityCounters = null;
             }
             if (in.readInt() != 0) {
-                mNetworkActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+                mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
+                mNetworkPacketActivityCounters
+                        = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
                 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                    mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables, in);
+                    mNetworkByteActivityCounters[i]
+                            = new LongSamplingCounter(mOnBatteryTimeBase, in);
+                    mNetworkPacketActivityCounters[i]
+                            = new LongSamplingCounter(mOnBatteryTimeBase, in);
                 }
+                mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+                mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
             } else {
-                mNetworkActivityCounters = null;
+                mNetworkByteActivityCounters = null;
+                mNetworkPacketActivityCounters = null;
             }
         }
 
@@ -3464,24 +4474,24 @@
              * return a new Timer, or null.
              */
             private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
-                    ArrayList<Unpluggable> unpluggables, Parcel in) {
+                    TimeBase timeBase, Parcel in) {
                 if (in.readInt() == 0) {
                     return null;
                 }
 
-                return new StopwatchTimer(Uid.this, type, pool, unpluggables, in);
+                return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
             }
 
             boolean reset() {
                 boolean wlactive = false;
                 if (mTimerFull != null) {
-                    wlactive |= !mTimerFull.reset(BatteryStatsImpl.this, false);
+                    wlactive |= !mTimerFull.reset(false);
                 }
                 if (mTimerPartial != null) {
-                    wlactive |= !mTimerPartial.reset(BatteryStatsImpl.this, false);
+                    wlactive |= !mTimerPartial.reset(false);
                 }
                 if (mTimerWindow != null) {
-                    wlactive |= !mTimerWindow.reset(BatteryStatsImpl.this, false);
+                    wlactive |= !mTimerWindow.reset(false);
                 }
                 if (!wlactive) {
                     if (mTimerFull != null) {
@@ -3500,19 +4510,19 @@
                 return !wlactive;
             }
 
-            void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
+            void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
                 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
-                        mPartialTimers, unpluggables, in);
+                        mPartialTimers, screenOffTimeBase, in);
                 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
-                        mFullTimers, unpluggables, in);
+                        mFullTimers, timeBase, in);
                 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
-                        mWindowTimers, unpluggables, in);
+                        mWindowTimers, timeBase, in);
             }
 
-            void writeToParcelLocked(Parcel out, long batteryRealtime) {
-                Timer.writeTimerToParcel(out, mTimerPartial, batteryRealtime);
-                Timer.writeTimerToParcel(out, mTimerFull, batteryRealtime);
-                Timer.writeTimerToParcel(out, mTimerWindow, batteryRealtime);
+            void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
+                Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
+                Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
+                Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
             }
 
             @Override
@@ -3534,8 +4544,7 @@
                 mHandle = handle;
             }
 
-            private StopwatchTimer readTimerFromParcel(ArrayList<Unpluggable> unpluggables,
-                    Parcel in) {
+            private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
                 if (in.readInt() == 0) {
                     return null;
                 }
@@ -3545,23 +4554,23 @@
                     pool = new ArrayList<StopwatchTimer>();
                     mSensorTimers.put(mHandle, pool);
                 }
-                return new StopwatchTimer(Uid.this, 0, pool, unpluggables, in);
+                return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
             }
 
             boolean reset() {
-                if (mTimer.reset(BatteryStatsImpl.this, true)) {
+                if (mTimer.reset(true)) {
                     mTimer = null;
                     return true;
                 }
                 return false;
             }
 
-            void readFromParcelLocked(ArrayList<Unpluggable> unpluggables, Parcel in) {
-                mTimer = readTimerFromParcel(unpluggables, in);
+            void readFromParcelLocked(TimeBase timeBase, Parcel in) {
+                mTimer = readTimerFromParcel(timeBase, in);
             }
 
-            void writeToParcelLocked(Parcel out, long batteryRealtime) {
-                Timer.writeTimerToParcel(out, mTimer, batteryRealtime);
+            void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
+                Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
             }
 
             @Override
@@ -3578,7 +4587,12 @@
         /**
          * The statistics associated with a particular process.
          */
-        public final class Proc extends BatteryStats.Uid.Proc implements Unpluggable {
+        public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
+            /**
+             * Remains true until removed from the stats.
+             */
+            boolean mActive = true;
+
             /**
              * Total time (in 1/100 sec) spent executing in user code.
              */
@@ -3664,26 +4678,27 @@
             ArrayList<ExcessivePower> mExcessivePower;
 
             Proc() {
-                mUnpluggables.add(this);
+                mOnBatteryTimeBase.add(this);
                 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
             }
 
-            public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+            public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
                 mUnpluggedUserTime = mUserTime;
                 mUnpluggedSystemTime = mSystemTime;
                 mUnpluggedForegroundTime = mForegroundTime;
                 mUnpluggedStarts = mStarts;
             }
 
-            public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+            public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             }
 
             void detach() {
-                mUnpluggables.remove(this);
+                mActive = false;
+                mOnBatteryTimeBase.remove(this);
                 for (int i = 0; i < mSpeedBins.length; i++) {
                     SamplingCounter c = mSpeedBins[i];
                     if (c != null) {
-                        mUnpluggables.remove(c);
+                        mOnBatteryTimeBase.remove(c);
                         mSpeedBins[i] = null;
                     }
                 }
@@ -3812,7 +4827,7 @@
                 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
                 for (int i = 0; i < bins; i++) {
                     if (in.readInt() != 0) {
-                        mSpeedBins[i] = new SamplingCounter(mUnpluggables, in);
+                        mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
                     }
                 }
 
@@ -3837,65 +4852,50 @@
             }
 
             @Override
+            public boolean isActive() {
+                return mActive;
+            }
+
+            @Override
             public long getUserTime(int which) {
-                long val;
-                if (which == STATS_LAST) {
-                    val = mLastUserTime;
-                } else {
-                    val = mUserTime;
-                    if (which == STATS_CURRENT) {
-                        val -= mLoadedUserTime;
-                    } else if (which == STATS_SINCE_UNPLUGGED) {
-                        val -= mUnpluggedUserTime;
-                    }
+                long val = mUserTime;
+                if (which == STATS_CURRENT) {
+                    val -= mLoadedUserTime;
+                } else if (which == STATS_SINCE_UNPLUGGED) {
+                    val -= mUnpluggedUserTime;
                 }
                 return val;
             }
 
             @Override
             public long getSystemTime(int which) {
-                long val;
-                if (which == STATS_LAST) {
-                    val = mLastSystemTime;
-                } else {
-                    val = mSystemTime;
-                    if (which == STATS_CURRENT) {
-                        val -= mLoadedSystemTime;
-                    } else if (which == STATS_SINCE_UNPLUGGED) {
-                        val -= mUnpluggedSystemTime;
-                    }
+                long val = mSystemTime;
+                if (which == STATS_CURRENT) {
+                    val -= mLoadedSystemTime;
+                } else if (which == STATS_SINCE_UNPLUGGED) {
+                    val -= mUnpluggedSystemTime;
                 }
                 return val;
             }
 
             @Override
             public long getForegroundTime(int which) {
-                long val;
-                if (which == STATS_LAST) {
-                    val = mLastForegroundTime;
-                } else {
-                    val = mForegroundTime;
-                    if (which == STATS_CURRENT) {
-                        val -= mLoadedForegroundTime;
-                    } else if (which == STATS_SINCE_UNPLUGGED) {
-                        val -= mUnpluggedForegroundTime;
-                    }
+                long val = mForegroundTime;
+                if (which == STATS_CURRENT) {
+                    val -= mLoadedForegroundTime;
+                } else if (which == STATS_SINCE_UNPLUGGED) {
+                    val -= mUnpluggedForegroundTime;
                 }
                 return val;
             }
 
             @Override
             public int getStarts(int which) {
-                int val;
-                if (which == STATS_LAST) {
-                    val = mLastStarts;
-                } else {
-                    val = mStarts;
-                    if (which == STATS_CURRENT) {
-                        val -= mLoadedStarts;
-                    } else if (which == STATS_SINCE_UNPLUGGED) {
-                        val -= mUnpluggedStarts;
-                    }
+                int val = mStarts;
+                if (which == STATS_CURRENT) {
+                    val -= mLoadedStarts;
+                } else if (which == STATS_SINCE_UNPLUGGED) {
+                    val -= mUnpluggedStarts;
                 }
                 return val;
             }
@@ -3907,7 +4907,7 @@
                     if (amt != 0) {
                         SamplingCounter c = mSpeedBins[i];
                         if (c == null) {
-                            mSpeedBins[i] = c = new SamplingCounter(mUnpluggables);
+                            mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
                         }
                         c.addCountAtomic(values[i]);
                     }
@@ -3928,7 +4928,7 @@
         /**
          * The statistics associated with a particular package.
          */
-        public final class Pkg extends BatteryStats.Uid.Pkg implements Unpluggable {
+        public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
             /**
              * Number of times this package has done something that could wake up the
              * device from sleep.
@@ -3959,18 +4959,18 @@
             final HashMap<String, Serv> mServiceStats = new HashMap<String, Serv>();
 
             Pkg() {
-                mUnpluggables.add(this);
+                mOnBatteryScreenOffTimeBase.add(this);
             }
 
-            public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+            public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
                 mUnpluggedWakeups = mWakeups;
             }
 
-            public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+            public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
             }
 
             void detach() {
-                mUnpluggables.remove(this);
+                mOnBatteryScreenOffTimeBase.remove(this);
             }
 
             void readFromParcelLocked(Parcel in) {
@@ -4011,16 +5011,11 @@
 
             @Override
             public int getWakeups(int which) {
-                int val;
-                if (which == STATS_LAST) {
-                    val = mLastWakeups;
-                } else {
-                    val = mWakeups;
-                    if (which == STATS_CURRENT) {
-                        val -= mLoadedWakeups;
-                    } else if (which == STATS_SINCE_UNPLUGGED) {
-                        val -= mUnpluggedWakeups;
-                    }
+                int val = mWakeups;
+                if (which == STATS_CURRENT) {
+                    val -= mLoadedWakeups;
+                } else if (which == STATS_SINCE_UNPLUGGED) {
+                    val -= mUnpluggedWakeups;
                 }
 
                 return val;
@@ -4029,7 +5024,7 @@
             /**
              * The statistics associated with a particular service.
              */
-            public final class Serv extends BatteryStats.Uid.Pkg.Serv implements Unpluggable {
+            public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
                 /**
                  * Total time (ms in battery uptime) the service has been left started.
                  */
@@ -4121,20 +5116,22 @@
                 int mUnpluggedLaunches;
 
                 Serv() {
-                    mUnpluggables.add(this);
+                    mOnBatteryTimeBase.add(this);
                 }
 
-                public void unplug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
-                    mUnpluggedStartTime = getStartTimeToNowLocked(batteryUptime);
+                public void onTimeStarted(long elapsedRealtime, long baseUptime,
+                        long baseRealtime) {
+                    mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
                     mUnpluggedStarts = mStarts;
                     mUnpluggedLaunches = mLaunches;
                 }
 
-                public void plug(long elapsedRealtime, long batteryUptime, long batteryRealtime) {
+                public void onTimeStopped(long elapsedRealtime, long baseUptime,
+                        long baseRealtime) {
                 }
 
                 void detach() {
-                    mUnpluggables.remove(this);
+                    mOnBatteryTimeBase.remove(this);
                 }
 
                 void readFromParcelLocked(Parcel in) {
@@ -4230,51 +5227,33 @@
 
                 @Override
                 public int getLaunches(int which) {
-                    int val;
-
-                    if (which == STATS_LAST) {
-                        val = mLastLaunches;
-                    } else {
-                        val = mLaunches;
-                        if (which == STATS_CURRENT) {
-                            val -= mLoadedLaunches;
-                        } else if (which == STATS_SINCE_UNPLUGGED) {
-                            val -= mUnpluggedLaunches;
-                        }
+                    int val = mLaunches;
+                    if (which == STATS_CURRENT) {
+                        val -= mLoadedLaunches;
+                    } else if (which == STATS_SINCE_UNPLUGGED) {
+                        val -= mUnpluggedLaunches;
                     }
-
                     return val;
                 }
 
                 @Override
                 public long getStartTime(long now, int which) {
-                    long val;
-                    if (which == STATS_LAST) {
-                        val = mLastStartTime;
-                    } else {
-                        val = getStartTimeToNowLocked(now);
-                        if (which == STATS_CURRENT) {
-                            val -= mLoadedStartTime;
-                        } else if (which == STATS_SINCE_UNPLUGGED) {
-                            val -= mUnpluggedStartTime;
-                        }
+                    long val = getStartTimeToNowLocked(now);
+                    if (which == STATS_CURRENT) {
+                        val -= mLoadedStartTime;
+                    } else if (which == STATS_SINCE_UNPLUGGED) {
+                        val -= mUnpluggedStartTime;
                     }
-
                     return val;
                 }
 
                 @Override
                 public int getStarts(int which) {
-                    int val;
-                    if (which == STATS_LAST) {
-                        val = mLastStarts;
-                    } else {
-                        val = mStarts;
-                        if (which == STATS_CURRENT) {
-                            val -= mLoadedStarts;
-                        } else if (which == STATS_SINCE_UNPLUGGED) {
-                            val -= mUnpluggedStarts;
-                        }
+                    int val = mStarts;
+                    if (which == STATS_CURRENT) {
+                        val -= mLoadedStarts;
+                    } else if (which == STATS_SINCE_UNPLUGGED) {
+                        val -= mUnpluggedStarts;
                     }
 
                     return val;
@@ -4369,7 +5348,7 @@
                     t = wl.mTimerPartial;
                     if (t == null) {
                         t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
-                                mPartialTimers, mUnpluggables);
+                                mPartialTimers, mOnBatteryScreenOffTimeBase);
                         wl.mTimerPartial = t;
                     }
                     return t;
@@ -4377,7 +5356,7 @@
                     t = wl.mTimerFull;
                     if (t == null) {
                         t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
-                                mFullTimers, mUnpluggables);
+                                mFullTimers, mOnBatteryTimeBase);
                         wl.mTimerFull = t;
                     }
                     return t;
@@ -4385,7 +5364,7 @@
                     t = wl.mTimerWindow;
                     if (t == null) {
                         t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
-                                mWindowTimers, mUnpluggables);
+                                mWindowTimers, mOnBatteryTimeBase);
                         wl.mTimerWindow = t;
                     }
                     return t;
@@ -4412,34 +5391,36 @@
                 timers = new ArrayList<StopwatchTimer>();
                 mSensorTimers.put(sensor, timers);
             }
-            t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mUnpluggables);
+            t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
             se.mTimer = t;
             return t;
         }
 
-        public void noteStartWakeLocked(int pid, String name, int type) {
+        public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
             StopwatchTimer t = getWakeTimerLocked(name, type);
             if (t != null) {
-                t.startRunningLocked(BatteryStatsImpl.this);
+                t.startRunningLocked(elapsedRealtimeMs);
             }
             if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
                 Pid p = getPidStatsLocked(pid);
-                if (p.mWakeStart == 0) {
-                    p.mWakeStart = SystemClock.elapsedRealtime();
+                if (p.mWakeNesting++ == 0) {
+                    p.mWakeStartMs = elapsedRealtimeMs;
                 }
             }
         }
 
-        public void noteStopWakeLocked(int pid, String name, int type) {
+        public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
             StopwatchTimer t = getWakeTimerLocked(name, type);
             if (t != null) {
-                t.stopRunningLocked(BatteryStatsImpl.this);
+                t.stopRunningLocked(elapsedRealtimeMs);
             }
             if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
                 Pid p = mPids.get(pid);
-                if (p != null && p.mWakeStart != 0) {
-                    p.mWakeSum += SystemClock.elapsedRealtime() - p.mWakeStart;
-                    p.mWakeStart = 0;
+                if (p != null && p.mWakeNesting > 0) {
+                    if (p.mWakeNesting-- == 1) {
+                        p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
+                        p.mWakeStartMs = 0;
+                    }
                 }
             }
         }
@@ -4458,32 +5439,32 @@
             }
         }
 
-        public void noteStartSensor(int sensor) {
+        public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
             StopwatchTimer t = getSensorTimerLocked(sensor, true);
             if (t != null) {
-                t.startRunningLocked(BatteryStatsImpl.this);
+                t.startRunningLocked(elapsedRealtimeMs);
             }
         }
 
-        public void noteStopSensor(int sensor) {
+        public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
             // Don't create a timer if one doesn't already exist
             StopwatchTimer t = getSensorTimerLocked(sensor, false);
             if (t != null) {
-                t.stopRunningLocked(BatteryStatsImpl.this);
+                t.stopRunningLocked(elapsedRealtimeMs);
             }
         }
 
-        public void noteStartGps() {
+        public void noteStartGps(long elapsedRealtimeMs) {
             StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
             if (t != null) {
-                t.startRunningLocked(BatteryStatsImpl.this);
+                t.startRunningLocked(elapsedRealtimeMs);
             }
         }
 
-        public void noteStopGps() {
+        public void noteStopGps(long elapsedRealtimeMs) {
             StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
             if (t != null) {
-                t.stopRunningLocked(BatteryStatsImpl.this);
+                t.stopRunningLocked(elapsedRealtimeMs);
             }
         }
 
@@ -4496,35 +5477,45 @@
         mFile = new JournaledFile(new File(filename), new File(filename + ".tmp"));
         mHandler = new MyHandler(handler.getLooper());
         mStartCount++;
-        mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables);
+        mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mUnpluggables);
+            mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
         }
-        mInputEventCounter = new Counter(mUnpluggables);
-        mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables);
+        mInputEventCounter = new Counter(mOnBatteryTimeBase);
+        mPhoneOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null, mUnpluggables);
+            mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
+                    mOnBatteryTimeBase);
         }
-        mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables);
+        mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
-            mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null, mUnpluggables);
+            mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
+                    mOnBatteryTimeBase);
         }
         for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-            mNetworkActivityCounters[i] = new LongSamplingCounter(mUnpluggables);
+            mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
+            mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
         }
-        mWifiOnTimer = new StopwatchTimer(null, -3, null, mUnpluggables);
-        mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mUnpluggables);
-        mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mUnpluggables);
-        mAudioOnTimer = new StopwatchTimer(null, -6, null, mUnpluggables);
-        mVideoOnTimer = new StopwatchTimer(null, -7, null, mUnpluggables);
+        mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
+        mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
+        mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
+        mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
+        mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
+        mWifiOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
+        mGlobalWifiRunningTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
+        }
+        mBluetoothOnTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase);
+        }
+        mAudioOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase);
+        mVideoOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
         mOnBattery = mOnBatteryInternal = false;
-        initTimes();
-        mTrackBatteryPastUptime = 0;
-        mTrackBatteryPastRealtime = 0;
-        mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
-        mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
-        mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
-        mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
+        long uptime = SystemClock.uptimeMillis() * 1000;
+        long realtime = SystemClock.elapsedRealtime() * 1000;
+        initTimes(uptime, realtime);
         mDischargeStartLevel = 0;
         mDischargeUnplugLevel = 0;
         mDischargeCurrentLevel = 0;
@@ -4557,18 +5548,21 @@
     public boolean startIteratingOldHistoryLocked() {
         if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
                 + " pos=" + mHistoryBuffer.dataPosition());
+        if ((mHistoryIterator = mHistory) == null) {
+            return false;
+        }
         mHistoryBuffer.setDataPosition(0);
         mHistoryReadTmp.clear();
         mReadOverflow = false;
         mIteratingHistory = true;
-        return (mHistoryIterator = mHistory) != null;
+        return true;
     }
 
     @Override
     public boolean getNextOldHistoryLocked(HistoryItem out) {
         boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
         if (!end) {
-            mHistoryReadTmp.readDelta(mHistoryBuffer);
+            readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
             mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
         }
         HistoryItem cur = mHistoryIterator;
@@ -4588,9 +5582,9 @@
                 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);
+                (new HistoryPrinter()).printNextItem(pw, out, now, false, true);
                 pw.println("New history:");
-                (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now);
+                (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, now, false, true);
                 pw.flush();
             }
         }
@@ -4601,16 +5595,60 @@
     public void finishIteratingOldHistoryLocked() {
         mIteratingHistory = false;
         mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
+        mHistoryIterator = null;
+    }
+
+    public int getHistoryTotalSize() {
+        return MAX_HISTORY_BUFFER;
+    }
+
+    public int getHistoryUsedSize() {
+        return mHistoryBuffer.dataSize();
     }
 
     @Override
     public boolean startIteratingHistoryLocked() {
         if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
                 + " pos=" + mHistoryBuffer.dataPosition());
+        if (mHistoryBuffer.dataSize() <= 0) {
+            return false;
+        }
         mHistoryBuffer.setDataPosition(0);
         mReadOverflow = false;
         mIteratingHistory = true;
-        return mHistoryBuffer.dataSize() > 0;
+        mReadHistoryStrings = new String[mHistoryTagPool.size()];
+        mReadHistoryUids = new int[mHistoryTagPool.size()];
+        mReadHistoryChars = 0;
+        for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
+            final HistoryTag tag = ent.getKey();
+            final int idx = ent.getValue();
+            mReadHistoryStrings[idx] = tag.string;
+            mReadHistoryUids[idx] = tag.uid;
+            mReadHistoryChars += tag.string.length() + 1;
+        }
+        return true;
+    }
+
+    @Override
+    public int getHistoryStringPoolSize() {
+        return mReadHistoryStrings.length;
+    }
+
+    @Override
+    public int getHistoryStringPoolBytes() {
+        // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
+        // Each string character is 2 bytes.
+        return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
+    }
+
+    @Override
+    public String getHistoryTagPoolString(int index) {
+        return mReadHistoryStrings[index];
+    }
+
+    @Override
+    public int getHistoryTagPoolUid(int index) {
+        return mReadHistoryUids[index];
     }
 
     @Override
@@ -4624,7 +5662,7 @@
             return false;
         }
 
-        out.readDelta(mHistoryBuffer);
+        readHistoryDelta(mHistoryBuffer, out);
         return true;
     }
 
@@ -4632,6 +5670,7 @@
     public void finishIteratingHistoryLocked() {
         mIteratingHistory = false;
         mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
+        mReadHistoryStrings = null;
     }
 
     @Override
@@ -4652,13 +5691,14 @@
         return mScreenOn;
     }
 
-    void initTimes() {
-        mBatteryRealtime = mTrackBatteryPastUptime = 0;
-        mBatteryUptime = mTrackBatteryPastRealtime = 0;
-        mUptimeStart = mTrackBatteryUptimeStart = SystemClock.uptimeMillis() * 1000;
-        mRealtimeStart = mTrackBatteryRealtimeStart = SystemClock.elapsedRealtime() * 1000;
-        mUnpluggedBatteryUptime = getBatteryUptimeLocked(mUptimeStart);
-        mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(mRealtimeStart);
+    void initTimes(long uptime, long realtime) {
+        mStartClockTime = System.currentTimeMillis();
+        mOnBatteryTimeBase.init(uptime, realtime);
+        mOnBatteryScreenOffTimeBase.init(uptime, realtime);
+        mRealtime = 0;
+        mUptime = 0;
+        mRealtimeStart = realtime;
+        mUptimeStart = uptime;
     }
 
     void initDischarge() {
@@ -4669,31 +5709,69 @@
         mDischargeAmountScreenOff = 0;
         mDischargeAmountScreenOffSinceCharge = 0;
     }
-    
-    public void resetAllStatsLocked() {
+
+    public void resetAllStatsCmdLocked() {
+        resetAllStatsLocked();
+        final long mSecUptime = SystemClock.uptimeMillis();
+        long uptime = mSecUptime * 1000;
+        long mSecRealtime = SystemClock.elapsedRealtime();
+        long realtime = mSecRealtime * 1000;
+        mDischargeStartLevel = mHistoryCur.batteryLevel;
+        pullPendingStateUpdatesLocked();
+        addHistoryRecordLocked(mSecRealtime, mSecUptime);
+        mDischargeCurrentLevel = mDischargeUnplugLevel = mHistoryCur.batteryLevel;
+        mOnBatteryTimeBase.reset(uptime, realtime);
+        mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
+        if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
+            if (mScreenOn) {
+                mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
+                mDischargeScreenOffUnplugLevel = 0;
+            } else {
+                mDischargeScreenOnUnplugLevel = 0;
+                mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
+            }
+            mDischargeAmountScreenOn = 0;
+            mDischargeAmountScreenOff = 0;
+        }
+        initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
+    }
+
+    private void resetAllStatsLocked() {
         mStartCount = 0;
-        initTimes();
-        mScreenOnTimer.reset(this, false);
+        initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
+        mScreenOnTimer.reset(false);
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            mScreenBrightnessTimer[i].reset(this, false);
+            mScreenBrightnessTimer[i].reset(false);
         }
         mInputEventCounter.reset(false);
-        mPhoneOnTimer.reset(this, false);
-        mAudioOnTimer.reset(this, false);
-        mVideoOnTimer.reset(this, false);
+        mPhoneOnTimer.reset(false);
+        mAudioOnTimer.reset(false);
+        mVideoOnTimer.reset(false);
         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            mPhoneSignalStrengthsTimer[i].reset(this, false);
+            mPhoneSignalStrengthsTimer[i].reset(false);
         }
-        mPhoneSignalScanningTimer.reset(this, false);
+        mPhoneSignalScanningTimer.reset(false);
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
-            mPhoneDataConnectionsTimer[i].reset(this, false);
+            mPhoneDataConnectionsTimer[i].reset(false);
         }
         for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-            mNetworkActivityCounters[i].reset(false);
+            mNetworkByteActivityCounters[i].reset(false);
+            mNetworkPacketActivityCounters[i].reset(false);
         }
-        mWifiOnTimer.reset(this, false);
-        mGlobalWifiRunningTimer.reset(this, false);
-        mBluetoothOnTimer.reset(this, false);
+        mMobileRadioActiveTimer.reset(false);
+        mMobileRadioActivePerAppTimer.reset(false);
+        mMobileRadioActiveAdjustedTime.reset(false);
+        mMobileRadioActiveUnknownTime.reset(false);
+        mMobileRadioActiveUnknownCount.reset(false);
+        mWifiOnTimer.reset(false);
+        mGlobalWifiRunningTimer.reset(false);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].reset(false);
+        }
+        mBluetoothOnTimer.reset(false);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].reset(false);
+        }
 
         for (int i=0; i<mUidStats.size(); i++) {
             if (mUidStats.valueAt(i).reset()) {
@@ -4704,16 +5782,41 @@
 
         if (mKernelWakelockStats.size() > 0) {
             for (SamplingTimer timer : mKernelWakelockStats.values()) {
-                mUnpluggables.remove(timer);
+                mOnBatteryScreenOffTimeBase.remove(timer);
             }
             mKernelWakelockStats.clear();
         }
-        
+
+        if (mWakeupReasonStats.size() > 0) {
+            for (LongSamplingCounter timer : mWakeupReasonStats.values()) {
+                mOnBatteryScreenOffTimeBase.remove(timer);
+            }
+            mWakeupReasonStats.clear();
+        }
+
         initDischarge();
 
         clearHistoryLocked();
     }
 
+    private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
+        for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
+            HashMap<String, SparseBooleanArray> active = mActiveEvents[i];
+            if (active == null) {
+                continue;
+            }
+            for (HashMap.Entry<String, SparseBooleanArray> ent : active.entrySet()) {
+                SparseBooleanArray uids = ent.getValue();
+                for (int j=0; j<uids.size(); j++) {
+                    if (uids.valueAt(j)) {
+                        addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
+                                uids.keyAt(j));
+                    }
+                }
+            }
+        }
+    }
+
     void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
         if (oldScreenOn) {
             int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
@@ -4737,45 +5840,48 @@
         }
     }
     
-    void setOnBattery(boolean onBattery, int oldStatus, int level) {
-        synchronized(this) {
-            setOnBatteryLocked(onBattery, oldStatus, level);
+    public void pullPendingStateUpdatesLocked() {
+        updateKernelWakelocksLocked();
+        updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
+        if (mOnBatteryInternal) {
+            updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
         }
     }
 
-    void setOnBatteryLocked(boolean onBattery, int oldStatus, int level) {
+    void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
+            final int oldStatus, final int level) {
         boolean doWrite = false;
         Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
         m.arg1 = onBattery ? 1 : 0;
         mHandler.sendMessage(m);
         mOnBattery = mOnBatteryInternal = onBattery;
 
-        long uptime = SystemClock.uptimeMillis() * 1000;
-        long mSecRealtime = SystemClock.elapsedRealtime();
-        long realtime = mSecRealtime * 1000;
+        final long uptime = mSecUptime * 1000;
+        final long realtime = mSecRealtime * 1000;
         if (onBattery) {
             // We will reset our status if we are unplugging after the
             // battery was last full, or the level is at 100, or
             // we have gone through a significant charge (from a very low
             // level to a now very high level).
+            boolean reset = false;
             if (oldStatus == BatteryManager.BATTERY_STATUS_FULL
                     || level >= 90
                     || (mDischargeCurrentLevel < 20 && level >= 80)) {
                 doWrite = true;
                 resetAllStatsLocked();
                 mDischargeStartLevel = level;
+                reset = true;
             }
-            updateKernelWakelocksLocked();
-            updateNetworkActivityLocked();
+            pullPendingStateUpdatesLocked();
             mHistoryCur.batteryLevel = (byte)level;
             mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(mSecRealtime);
-            mTrackBatteryUptimeStart = uptime;
-            mTrackBatteryRealtimeStart = realtime;
-            mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime);
-            mUnpluggedBatteryRealtime = getBatteryRealtimeLocked(realtime);
+            if (reset) {
+                mRecordingHistory = true;
+                startRecordingHistory(mSecRealtime, mSecUptime, reset);
+            }
+            addHistoryRecordLocked(mSecRealtime, mSecUptime);
             mDischargeCurrentLevel = mDischargeUnplugLevel = level;
             if (mScreenOn) {
                 mDischargeScreenOnUnplugLevel = level;
@@ -4786,24 +5892,21 @@
             }
             mDischargeAmountScreenOn = 0;
             mDischargeAmountScreenOff = 0;
-            doUnplugLocked(realtime, mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
+            updateTimeBasesLocked(true, !mScreenOn, uptime, realtime);
         } else {
-            updateKernelWakelocksLocked();
-            updateNetworkActivityLocked();
+            pullPendingStateUpdatesLocked();
             mHistoryCur.batteryLevel = (byte)level;
             mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
             if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
                     + Integer.toHexString(mHistoryCur.states));
-            addHistoryRecordLocked(mSecRealtime);
-            mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
-            mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
+            addHistoryRecordLocked(mSecRealtime, mSecUptime);
             mDischargeCurrentLevel = level;
             if (level < mDischargeUnplugLevel) {
                 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
                 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
             }
             updateDischargeScreenLevelsLocked(mScreenOn, mScreenOn);
-            doPlugLocked(realtime, getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
+            updateTimeBasesLocked(false, !mScreenOn, uptime, realtime);
         }
         if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
             if (mFile != null) {
@@ -4812,13 +5915,27 @@
         }
     }
 
+    private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
+            boolean reset) {
+        mRecordingHistory = true;
+        mHistoryCur.currentTime = System.currentTimeMillis();
+        addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
+                mHistoryCur);
+        mHistoryCur.currentTime = 0;
+        if (reset) {
+            initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
+        }
+    }
+
     // This should probably be exposed in the API, though it's not critical
     private static final int BATTERY_PLUGGED_NONE = 0;
 
     public void setBatteryState(int status, int health, int plugType, int level,
             int temp, int volt) {
         synchronized(this) {
-            boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
+            final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
+            final long uptime = SystemClock.uptimeMillis();
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
             int oldStatus = mHistoryCur.batteryStatus;
             if (!mHaveBatteryLevel) {
                 mHaveBatteryLevel = true;
@@ -4837,7 +5954,15 @@
             }
             if (onBattery) {
                 mDischargeCurrentLevel = level;
-                mRecordingHistory = true;
+                if (!mRecordingHistory) {
+                    mRecordingHistory = true;
+                    startRecordingHistory(elapsedRealtime, uptime, true);
+                }
+            } else if (level < 96) {
+                if (!mRecordingHistory) {
+                    mRecordingHistory = true;
+                    startRecordingHistory(elapsedRealtime, uptime, true);
+                }
             }
             if (onBattery != mOnBattery) {
                 mHistoryCur.batteryLevel = (byte)level;
@@ -4846,7 +5971,7 @@
                 mHistoryCur.batteryPlugType = (byte)plugType;
                 mHistoryCur.batteryTemperature = (short)temp;
                 mHistoryCur.batteryVoltage = (char)volt;
-                setOnBatteryLocked(onBattery, oldStatus, level);
+                setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
             } else {
                 boolean changed = false;
                 if (mHistoryCur.batteryLevel != level) {
@@ -4876,13 +6001,13 @@
                     changed = true;
                 }
                 if (changed) {
-                    addHistoryRecordLocked(SystemClock.elapsedRealtime());
+                    addHistoryRecordLocked(elapsedRealtime, uptime);
                 }
             }
             if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
                 // We don't record history while we are plugged in and fully charged.
                 // The next time we are unplugged, history will be cleared.
-                mRecordingHistory = false;
+                mRecordingHistory = DEBUG;
             }
         }
     }
@@ -4902,8 +6027,8 @@
 
             SamplingTimer kwlt = mKernelWakelockStats.get(name);
             if (kwlt == null) {
-                kwlt = new SamplingTimer(mUnpluggables, mOnBatteryInternal,
-                        true /* track reported values */);
+                kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
+                        true /* track reported val */);
                 mKernelWakelockStats.put(name, kwlt);
             }
             kwlt.updateCurrentReportedCount(kws.mCount);
@@ -4922,48 +6047,124 @@
         }
     }
 
-    private void updateNetworkActivityLocked() {
+    static final int NET_UPDATE_MOBILE = 1<<0;
+    static final int NET_UPDATE_WIFI = 1<<1;
+    static final int NET_UPDATE_ALL = 0xffff;
+
+    private void updateNetworkActivityLocked(int which, long elapsedRealtimeMs) {
         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 ((which&NET_UPDATE_MOBILE) != 0 && mMobileIfaces.length > 0) {
+            final NetworkStats snapshot;
+            final NetworkStats last = mCurMobileSnapshot;
+            try {
+                snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
+                        mMobileIfaces, NetworkStats.TAG_NONE, mLastMobileSnapshot);
+            } catch (IOException e) {
+                Log.wtf(TAG, "Failed to read mobile network stats", e);
+                return;
+            }
+
+            mCurMobileSnapshot = snapshot;
+            mLastMobileSnapshot = last;
+
+            if (mOnBatteryInternal) {
+                final NetworkStats delta = NetworkStats.subtract(snapshot, last,
+                        null, null, mTmpNetworkStats);
+                mTmpNetworkStats = delta;
+
+                long radioTime = mMobileRadioActivePerAppTimer.checkpointRunningLocked(
+                        elapsedRealtimeMs);
+                long totalPackets = delta.getTotalPackets();
+
+                final int size = delta.size();
+                for (int i = 0; i < size; i++) {
+                    final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
+
+                    if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
+
+                    final Uid u = getUidStatsLocked(mapUid(entry.uid));
+                    u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
+                            entry.rxPackets);
+                    u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
+                            entry.txPackets);
+
+                    if (radioTime > 0) {
+                        // Distribute total radio active time in to this app.
+                        long appPackets = entry.rxPackets + entry.txPackets;
+                        long appRadioTime = (radioTime*appPackets)/totalPackets;
+                        u.noteMobileRadioActiveTimeLocked(appRadioTime);
+                        // Remove this app from the totals, so that we don't lose any time
+                        // due to rounding.
+                        radioTime -= appRadioTime;
+                        totalPackets -= appPackets;
+                    }
+
+                    mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+                            entry.rxBytes);
+                    mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+                            entry.txBytes);
+                    mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
+                            entry.rxPackets);
+                    mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
+                            entry.txPackets);
+                }
+
+                if (radioTime > 0) {
+                    // Whoops, there is some radio time we can't blame on an app!
+                    mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
+                    mMobileRadioActiveUnknownCount.addCountLocked(1);
+                }
+            }
         }
 
-        if (mLastSnapshot == null) {
-            mLastSnapshot = snapshot;
-            return;
-        }
+        if ((which&NET_UPDATE_WIFI) != 0 && mWifiIfaces.length > 0) {
+            final NetworkStats snapshot;
+            final NetworkStats last = mCurWifiSnapshot;
+            try {
+                snapshot = mNetworkStatsFactory.readNetworkStatsDetail(UID_ALL,
+                        mWifiIfaces, NetworkStats.TAG_NONE, mLastWifiSnapshot);
+            } catch (IOException e) {
+                Log.wtf(TAG, "Failed to read wifi network stats", e);
+                return;
+            }
 
-        final NetworkStats delta = snapshot.subtract(mLastSnapshot);
-        mLastSnapshot = snapshot;
+            mCurWifiSnapshot = snapshot;
+            mLastWifiSnapshot = last;
 
-        NetworkStats.Entry entry = null;
-        final int size = delta.size();
-        for (int i = 0; i < size; i++) {
-            entry = delta.getValues(i, entry);
+            if (mOnBatteryInternal) {
+                final NetworkStats delta = NetworkStats.subtract(snapshot, last,
+                        null, null, mTmpNetworkStats);
+                mTmpNetworkStats = delta;
 
-            if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
-            if (entry.tag != NetworkStats.TAG_NONE) continue;
+                final int size = delta.size();
+                for (int i = 0; i < size; i++) {
+                    final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
 
-            final Uid u = getUidStatsLocked(entry.uid);
+                    if (DEBUG) {
+                        final NetworkStats.Entry cur = snapshot.getValues(i, null);
+                        Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
+                                + " tx=" + entry.txBytes + ", cur rx=" + cur.rxBytes
+                                + " tx=" + cur.txBytes);
+                    }
 
-            if (mMobileIfaces.contains(entry.iface)) {
-                u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_BYTES, entry.rxBytes);
-                u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_BYTES, entry.txBytes);
+                    if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
 
-                mNetworkActivityCounters[NETWORK_MOBILE_RX_BYTES].addCountLocked(entry.rxBytes);
-                mNetworkActivityCounters[NETWORK_MOBILE_TX_BYTES].addCountLocked(entry.txBytes);
+                    final Uid u = getUidStatsLocked(mapUid(entry.uid));
+                    u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
+                            entry.rxPackets);
+                    u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
+                            entry.txPackets);
 
-            } 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);
+                    mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+                            entry.rxBytes);
+                    mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+                            entry.txBytes);
+                    mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+                            entry.rxPackets);
+                    mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+                            entry.txPackets);
+                }
             }
         }
     }
@@ -4980,9 +6181,8 @@
     public long computeUptime(long curTime, int which) {
         switch (which) {
             case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
-            case STATS_LAST: return mLastUptime;
             case STATS_CURRENT: return (curTime-mUptimeStart);
-            case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
+            case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
         }
         return 0;
     }
@@ -4991,71 +6191,44 @@
     public long computeRealtime(long curTime, int which) {
         switch (which) {
             case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
-            case STATS_LAST: return mLastRealtime;
             case STATS_CURRENT: return (curTime-mRealtimeStart);
-            case STATS_SINCE_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
+            case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
         }
         return 0;
     }
 
     @Override
     public long computeBatteryUptime(long curTime, int which) {
-        switch (which) {
-            case STATS_SINCE_CHARGED:
-                return mBatteryUptime + getBatteryUptime(curTime);
-            case STATS_LAST:
-                return mBatteryLastUptime;
-            case STATS_CURRENT:
-                return getBatteryUptime(curTime);
-            case STATS_SINCE_UNPLUGGED:
-                return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
-        }
-        return 0;
+        return mOnBatteryTimeBase.computeUptime(curTime, which);
     }
 
     @Override
     public long computeBatteryRealtime(long curTime, int which) {
-        switch (which) {
-            case STATS_SINCE_CHARGED:
-                return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
-            case STATS_LAST:
-                return mBatteryLastRealtime;
-            case STATS_CURRENT:
-                return getBatteryRealtimeLocked(curTime);
-            case STATS_SINCE_UNPLUGGED:
-                return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
-        }
-        return 0;
+        return mOnBatteryTimeBase.computeRealtime(curTime, which);
     }
 
-    long getBatteryUptimeLocked(long curTime) {
-        long time = mTrackBatteryPastUptime;
-        if (mOnBatteryInternal) {
-            time += curTime - mTrackBatteryUptimeStart;
-        }
-        return time;
+    @Override
+    public long computeBatteryScreenOffUptime(long curTime, int which) {
+        return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
+    }
+
+    @Override
+    public long computeBatteryScreenOffRealtime(long curTime, int which) {
+        return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
     }
 
     long getBatteryUptimeLocked() {
-        return getBatteryUptime(SystemClock.uptimeMillis() * 1000);
+        return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
     }
 
     @Override
     public long getBatteryUptime(long curTime) {
-        return getBatteryUptimeLocked(curTime);
-    }
-
-    long getBatteryRealtimeLocked(long curTime) {
-        long time = mTrackBatteryPastRealtime;
-        if (mOnBatteryInternal) {
-            time += curTime - mTrackBatteryRealtimeStart;
-        }
-        return time;
+        return mOnBatteryTimeBase.getUptime(curTime);
     }
 
     @Override
     public long getBatteryRealtime(long curTime) {
-        return getBatteryRealtimeLocked(curTime);
+        return mOnBatteryTimeBase.getRealtime(curTime);
     }
 
     @Override
@@ -5101,7 +6274,18 @@
             return val;
         }
     }
-    
+
+    @Override
+    public int getDischargeAmount(int which) {
+        int dischargeAmount = which == STATS_SINCE_CHARGED
+                ? getHighDischargeAmountSinceCharge()
+                : (getDischargeStartLevel() - getDischargeCurrentLevel());
+        if (dischargeAmount < 0) {
+            dischargeAmount = 0;
+        }
+        return dischargeAmount;
+    }
+
     public int getDischargeAmountScreenOn() {
         synchronized(this) {
             int val = mDischargeAmountScreenOn;
@@ -5175,24 +6359,7 @@
      * if needed.
      */
     public Uid.Proc getProcessStatsLocked(int uid, String name) {
-        Uid u = getUidStatsLocked(uid);
-        return u.getProcessStatsLocked(name);
-    }
-
-    /**
-     * Retrieve the statistics object for a particular process, given
-     * the name of the process.
-     * @param name process name
-     * @return the statistics object for the process
-     */
-    public Uid.Proc getProcessStatsLocked(String name, int pid) {
-        int uid;
-        if (mUidCache.containsKey(name)) {
-            uid = mUidCache.get(name);
-        } else {
-            uid = Process.getUidForPid(pid);
-            mUidCache.put(name, uid);
-        }
+        uid = mapUid(uid);
         Uid u = getUidStatsLocked(uid);
         return u.getProcessStatsLocked(name);
     }
@@ -5202,6 +6369,7 @@
      * if needed.
      */
     public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
+        uid = mapUid(uid);
         Uid u = getUidStatsLocked(uid);
         return u.getPackageStatsLocked(pkg);
     }
@@ -5211,6 +6379,7 @@
      * if needed.
      */
     public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
+        uid = mapUid(uid);
         Uid u = getUidStatsLocked(uid);
         return u.getServiceStatsLocked(pkg, name);
     }
@@ -5251,7 +6420,7 @@
                                     time = (time*uidRunningTime)/totalRunningTime;
                                     SamplingCounter uidSc = uidProc.mSpeedBins[sb];
                                     if (uidSc == null) {
-                                        uidSc = new SamplingCounter(mUnpluggables);
+                                        uidSc = new SamplingCounter(mOnBatteryTimeBase);
                                         uidProc.mSpeedBins[sb] = uidSc;
                                     }
                                     uidSc.mCount.addAndGet((int)time);
@@ -5388,15 +6557,20 @@
             stream.close();
 
             readSummaryFromParcel(in);
-        } catch(java.io.IOException e) {
+        } catch(Exception e) {
             Slog.e("BatteryStats", "Error reading battery statistics", e);
         }
 
-        long now = SystemClock.elapsedRealtime();
-        if (USE_OLD_HISTORY) {
-            addHistoryRecordLocked(now, HistoryItem.CMD_START);
+        if (mHistoryBuffer.dataPosition() > 0) {
+            mRecordingHistory = true;
+            final long elapsedRealtime = SystemClock.elapsedRealtime();
+            final long uptime = SystemClock.uptimeMillis();
+            if (USE_OLD_HISTORY) {
+                addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
+            }
+            addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
+            startRecordingHistory(elapsedRealtime, uptime, false);
         }
-        addHistoryBufferLocked(now, HistoryItem.CMD_START);
     }
 
     public int describeContents() {
@@ -5408,6 +6582,25 @@
 
         mHistoryBuffer.setDataSize(0);
         mHistoryBuffer.setDataPosition(0);
+        mHistoryTagPool.clear();
+        mNextHistoryTagIdx = 0;
+        mNumHistoryTagChars = 0;
+
+        int numTags = in.readInt();
+        for (int i=0; i<numTags; i++) {
+            int idx = in.readInt();
+            String str = in.readString();
+            int uid = in.readInt();
+            HistoryTag tag = new HistoryTag();
+            tag.string = str;
+            tag.uid = uid;
+            tag.poolIdx = idx;
+            mHistoryTagPool.put(tag, idx);
+            if (idx >= mNextHistoryTagIdx) {
+                mNextHistoryTagIdx = idx+1;
+            }
+            mNumHistoryTagChars += tag.string.length() + 1;
+        }
 
         int bufSize = in.readInt();
         int curPos = in.dataPosition();
@@ -5471,11 +6664,18 @@
             StringBuilder sb = new StringBuilder(128);
             sb.append("****************** WRITING mHistoryBaseTime: ");
             TimeUtils.formatDuration(mHistoryBaseTime, sb);
-            sb.append(" mLastHistoryTime: ");
-            TimeUtils.formatDuration(mLastHistoryTime, sb);
+            sb.append(" mLastHistoryElapsedRealtime: ");
+            TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
             Slog.i(TAG, sb.toString());
         }
-        out.writeLong(mHistoryBaseTime + mLastHistoryTime);
+        out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
+        out.writeInt(mHistoryTagPool.size());
+        for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
+            HistoryTag tag = ent.getKey();
+            out.writeInt(ent.getValue());
+            out.writeString(tag.string);
+            out.writeInt(tag.uid);
+        }
         out.writeInt(mHistoryBuffer.dataSize());
         if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
                 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
@@ -5509,10 +6709,11 @@
         readHistory(in, true);
 
         mStartCount = in.readInt();
-        mBatteryUptime = in.readLong();
-        mBatteryRealtime = in.readLong();
         mUptime = in.readLong();
         mRealtime = in.readLong();
+        mStartClockTime = in.readLong();
+        mOnBatteryTimeBase.readSummaryFromParcel(in);
+        mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
         mDischargeUnplugLevel = in.readInt();
         mDischargeCurrentLevel = in.readInt();
         mLowDischargeAmountSinceCharge = in.readInt();
@@ -5538,14 +6739,27 @@
             mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
         }
         for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-            mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
+            mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
+            mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
         }
+        mMobileRadioActive = false;
+        mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
+        mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
+        mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
+        mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
+        mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
         mWifiOn = false;
         mWifiOnTimer.readSummaryFromParcelLocked(in);
         mGlobalWifiRunning = false;
         mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].readSummaryFromParcelLocked(in);
+        }
         mBluetoothOn = false;
         mBluetoothOnTimer.readSummaryFromParcelLocked(in);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
+        }
 
         int NKW = in.readInt();
         if (NKW > 10000) {
@@ -5559,7 +6773,22 @@
             }
         }
 
+        int NWR = in.readInt();
+        if (NWR > 10000) {
+            Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR);
+            return;
+        }
+        for (int iwr = 0; iwr < NWR; iwr++) {
+            if (in.readInt() != 0) {
+                String reasonName = in.readString();
+                getWakeupReasonCounterLocked(reasonName).readSummaryFromParcelLocked(in);
+            }
+        }
+
         sNumSpeedSteps = in.readInt();
+        if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
+            throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
+        }
 
         final int NU = in.readInt();
         if (NU > 10000) {
@@ -5619,12 +6848,15 @@
             }
 
             if (in.readInt() != 0) {
-                if (u.mNetworkActivityCounters == null) {
+                if (u.mNetworkByteActivityCounters == null) {
                     u.initNetworkActivityLocked();
                 }
                 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                    u.mNetworkActivityCounters[i].readSummaryFromParcelLocked(in);
+                    u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
+                    u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
                 }
+                u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
+                u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
             }
 
             int NW = in.readInt();
@@ -5678,7 +6910,7 @@
                 p.mSpeedBins = new SamplingCounter[NSB];
                 for (int i=0; i<NSB; i++) {
                     if (in.readInt() != 0) {
-                        p.mSpeedBins[i] = new SamplingCounter(mUnpluggables);
+                        p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
                         p.mSpeedBins[i].readSummaryFromParcelLocked(in);
                     }
                 }
@@ -5719,50 +6951,59 @@
      * @param out the Parcel to be written to.
      */
     public void writeSummaryToParcel(Parcel out) {
-        // Need to update with current kernel wake lock counts.
-        updateKernelWakelocksLocked();
-        updateNetworkActivityLocked();
+        pullPendingStateUpdatesLocked();
 
         final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
         final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
-        final long NOW = getBatteryUptimeLocked(NOW_SYS);
-        final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
 
         out.writeInt(VERSION);
 
         writeHistory(out, true);
 
         out.writeInt(mStartCount);
-        out.writeLong(computeBatteryUptime(NOW_SYS, STATS_SINCE_CHARGED));
-        out.writeLong(computeBatteryRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
         out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
         out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
+        out.writeLong(mStartClockTime);
+        mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
+        mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
         out.writeInt(mDischargeUnplugLevel);
         out.writeInt(mDischargeCurrentLevel);
         out.writeInt(getLowDischargeAmountSinceCharge());
         out.writeInt(getHighDischargeAmountSinceCharge());
         out.writeInt(getDischargeAmountScreenOnSinceCharge());
         out.writeInt(getDischargeAmountScreenOffSinceCharge());
-        
-        mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+
+        mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
+            mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         }
         mInputEventCounter.writeSummaryFromParcelLocked(out);
-        mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
+            mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         }
-        mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
-            mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
+            mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
         }
         for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-            mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
+            mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
+            mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
         }
-        mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
-        mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
-        mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+        mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
+        mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
+        mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
+        mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        }
+        mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+        }
 
         out.writeInt(mKernelWakelockStats.size());
         for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
@@ -5770,7 +7011,19 @@
             if (kwlt != null) {
                 out.writeInt(1);
                 out.writeString(ent.getKey());
-                ent.getValue().writeSummaryFromParcelLocked(out, NOWREAL);
+                kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+            } else {
+                out.writeInt(0);
+            }
+        }
+
+        out.writeInt(mWakeupReasonStats.size());
+        for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
+            LongSamplingCounter counter = ent.getValue();
+            if (counter != null) {
+                out.writeInt(1);
+                out.writeString(ent.getKey());
+                counter.writeSummaryFromParcelLocked(out);
             } else {
                 out.writeInt(0);
             }
@@ -5785,57 +7038,57 @@
 
             if (u.mWifiRunningTimer != null) {
                 out.writeInt(1);
-                u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
             if (u.mFullWifiLockTimer != null) {
                 out.writeInt(1);
-                u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
             if (u.mWifiScanTimer != null) {
                 out.writeInt(1);
-                u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
             for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
                 if (u.mWifiBatchedScanTimer[i] != null) {
                     out.writeInt(1);
-                    u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
+                    u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
                 } else {
                     out.writeInt(0);
                 }
             }
             if (u.mWifiMulticastTimer != null) {
                 out.writeInt(1);
-                u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
             if (u.mAudioTurnedOnTimer != null) {
                 out.writeInt(1);
-                u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
             if (u.mVideoTurnedOnTimer != null) {
                 out.writeInt(1);
-                u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
             if (u.mForegroundActivityTimer != null) {
                 out.writeInt(1);
-                u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
             if (u.mVibratorOnTimer != null) {
                 out.writeInt(1);
-                u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             } else {
                 out.writeInt(0);
             }
@@ -5849,13 +7102,16 @@
                 }
             }
 
-            if (u.mNetworkActivityCounters == null) {
+            if (u.mNetworkByteActivityCounters == null) {
                 out.writeInt(0);
             } else {
                 out.writeInt(1);
                 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
-                    u.mNetworkActivityCounters[i].writeSummaryFromParcelLocked(out);
+                    u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
+                    u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
                 }
+                u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
+                u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
             }
 
             int NW = u.mWakelockStats.size();
@@ -5867,19 +7123,19 @@
                     Uid.Wakelock wl = ent.getValue();
                     if (wl.mTimerFull != null) {
                         out.writeInt(1);
-                        wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
+                        wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
                     } else {
                         out.writeInt(0);
                     }
                     if (wl.mTimerPartial != null) {
                         out.writeInt(1);
-                        wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
+                        wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
                     } else {
                         out.writeInt(0);
                     }
                     if (wl.mTimerWindow != null) {
                         out.writeInt(1);
-                        wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
+                        wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
                     } else {
                         out.writeInt(0);
                     }
@@ -5895,7 +7151,7 @@
                     Uid.Sensor se = ent.getValue();
                     if (se.mTimer != null) {
                         out.writeInt(1);
-                        se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+                        se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
                     } else {
                         out.writeInt(0);
                     }
@@ -5942,7 +7198,8 @@
                                 : ps.mServiceStats.entrySet()) {
                             out.writeString(sent.getKey());
                             BatteryStatsImpl.Uid.Pkg.Serv ss = sent.getValue();
-                            long time = ss.getStartTimeToNowLocked(NOW);
+                            long time = ss.getStartTimeToNowLocked(
+                                    mOnBatteryTimeBase.getUptime(NOW_SYS));
                             out.writeLong(time);
                             out.writeInt(ss.mStarts);
                             out.writeInt(ss.mLaunches);
@@ -5966,51 +7223,59 @@
         readHistory(in, false);
 
         mStartCount = in.readInt();
-        mBatteryUptime = in.readLong();
-        mBatteryLastUptime = 0;
-        mBatteryRealtime = in.readLong();
-        mBatteryLastRealtime = 0;
-        mScreenOn = false;
-        mScreenOnTimer = new StopwatchTimer(null, -1, null, mUnpluggables, in);
-        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i,
-                    null, mUnpluggables, in);
-        }
-        mInputEventCounter = new Counter(mUnpluggables, in);
-        mPhoneOn = false;
-        mPhoneOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
-        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
-                    null, mUnpluggables, in);
-        }
-        mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mUnpluggables, in);
-        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
-            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;
-        mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
-        mBluetoothOn = false;
-        mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mUnpluggables, in);
+        mStartClockTime = in.readLong();
         mUptime = in.readLong();
         mUptimeStart = in.readLong();
-        mLastUptime = 0;
         mRealtime = in.readLong();
         mRealtimeStart = in.readLong();
-        mLastRealtime = 0;
         mOnBattery = in.readInt() != 0;
         mOnBatteryInternal = false; // we are no longer really running.
-        mTrackBatteryPastUptime = in.readLong();
-        mTrackBatteryUptimeStart = in.readLong();
-        mTrackBatteryPastRealtime = in.readLong();
-        mTrackBatteryRealtimeStart = in.readLong();
-        mUnpluggedBatteryUptime = in.readLong();
-        mUnpluggedBatteryRealtime = in.readLong();
+        mOnBatteryTimeBase.readFromParcel(in);
+        mOnBatteryScreenOffTimeBase.readFromParcel(in);
+
+        mScreenOn = false;
+        mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
+        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
+            mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
+                    in);
+        }
+        mInputEventCounter = new Counter(mOnBatteryTimeBase, in);
+        mPhoneOn = false;
+        mPhoneOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
+        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
+            mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
+                    null, mOnBatteryTimeBase, in);
+        }
+        mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
+        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
+            mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
+                    null, mOnBatteryTimeBase, in);
+        }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
+            mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
+        }
+        mMobileRadioActive = false;
+        mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
+        mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
+                in);
+        mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+        mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
+        mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
+        mWifiOn = false;
+        mWifiOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
+        mGlobalWifiRunning = false;
+        mGlobalWifiRunningTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
+                    null, mOnBatteryTimeBase, in);
+        }
+        mBluetoothOn = false;
+        mBluetoothOnTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
+                    null, mOnBatteryTimeBase, in);
+        }
         mDischargeUnplugLevel = in.readInt();
         mDischargeCurrentLevel = in.readInt();
         mLowDischargeAmountSinceCharge = in.readInt();
@@ -6021,9 +7286,6 @@
         mDischargeAmountScreenOffSinceCharge = in.readInt();
         mLastWriteTime = in.readLong();
 
-        mRadioDataUptime = in.readLong();
-        mRadioDataStart = -1;
-
         mBluetoothPingCount = in.readInt();
         mBluetoothPingStart = -1;
 
@@ -6032,12 +7294,22 @@
         for (int ikw = 0; ikw < NKW; ikw++) {
             if (in.readInt() != 0) {
                 String wakelockName = in.readString();
-                in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
-                SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
+                SamplingTimer kwlt = new SamplingTimer(mOnBatteryTimeBase, in);
                 mKernelWakelockStats.put(wakelockName, kwlt);
             }
         }
 
+        mWakeupReasonStats.clear();
+        int NWR = in.readInt();
+        for (int iwr = 0; iwr < NWR; iwr++) {
+            if (in.readInt() != 0) {
+                String reasonName = in.readString();
+                LongSamplingCounter counter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase,
+                        in);
+                mWakeupReasonStats.put(reasonName, counter);
+            }
+        }
+
         mPartialTimers.clear();
         mFullTimers.clear();
         mWindowTimers.clear();
@@ -6054,7 +7326,7 @@
         for (int i = 0; i < numUids; i++) {
             int uid = in.readInt();
             Uid u = new Uid(uid);
-            u.readFromParcelLocked(mUnpluggables, in);
+            u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
             mUidStats.append(uid, u);
         }
     }
@@ -6070,51 +7342,58 @@
     @SuppressWarnings("unused")
     void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
         // Need to update with current kernel wake lock counts.
-        updateKernelWakelocksLocked();
-        updateNetworkActivityLocked();
+        pullPendingStateUpdatesLocked();
 
         final long uSecUptime = SystemClock.uptimeMillis() * 1000;
         final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
-        final long batteryUptime = getBatteryUptimeLocked(uSecUptime);
-        final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime);
+        final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
+        final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
 
         out.writeInt(MAGIC);
 
         writeHistory(out, false);
 
         out.writeInt(mStartCount);
-        out.writeLong(mBatteryUptime);
-        out.writeLong(mBatteryRealtime);
-        mScreenOnTimer.writeToParcel(out, batteryRealtime);
-        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
-            mScreenBrightnessTimer[i].writeToParcel(out, batteryRealtime);
-        }
-        mInputEventCounter.writeToParcel(out);
-        mPhoneOnTimer.writeToParcel(out, batteryRealtime);
-        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
-            mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
-        }
-        mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
-        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);
+        out.writeLong(mStartClockTime);
         out.writeLong(mUptime);
         out.writeLong(mUptimeStart);
         out.writeLong(mRealtime);
         out.writeLong(mRealtimeStart);
         out.writeInt(mOnBattery ? 1 : 0);
-        out.writeLong(batteryUptime);
-        out.writeLong(mTrackBatteryUptimeStart);
-        out.writeLong(batteryRealtime);
-        out.writeLong(mTrackBatteryRealtimeStart);
-        out.writeLong(mUnpluggedBatteryUptime);
-        out.writeLong(mUnpluggedBatteryRealtime);
+        mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
+        mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
+
+        mScreenOnTimer.writeToParcel(out, uSecRealtime);
+        for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
+            mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
+        }
+        mInputEventCounter.writeToParcel(out);
+        mPhoneOnTimer.writeToParcel(out, uSecRealtime);
+        for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
+            mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
+        }
+        mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
+        for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
+            mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
+        }
+        for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
+            mNetworkByteActivityCounters[i].writeToParcel(out);
+            mNetworkPacketActivityCounters[i].writeToParcel(out);
+        }
+        mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
+        mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
+        mMobileRadioActiveAdjustedTime.writeToParcel(out);
+        mMobileRadioActiveUnknownTime.writeToParcel(out);
+        mMobileRadioActiveUnknownCount.writeToParcel(out);
+        mWifiOnTimer.writeToParcel(out, uSecRealtime);
+        mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
+        for (int i=0; i<NUM_WIFI_STATES; i++) {
+            mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
+        }
+        mBluetoothOnTimer.writeToParcel(out, uSecRealtime);
+        for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+            mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
+        }
         out.writeInt(mDischargeUnplugLevel);
         out.writeInt(mDischargeCurrentLevel);
         out.writeInt(mLowDischargeAmountSinceCharge);
@@ -6125,9 +7404,6 @@
         out.writeInt(mDischargeAmountScreenOffSinceCharge);
         out.writeLong(mLastWriteTime);
 
-        // Write radio uptime for data
-        out.writeLong(getRadioDataUptime());
-
         out.writeInt(getBluetoothPingCount());
 
         if (inclUids) {
@@ -6137,7 +7413,18 @@
                 if (kwlt != null) {
                     out.writeInt(1);
                     out.writeString(ent.getKey());
-                    Timer.writeTimerToParcel(out, kwlt, batteryRealtime);
+                    kwlt.writeToParcel(out, uSecRealtime);
+                } else {
+                    out.writeInt(0);
+                }
+            }
+            out.writeInt(mWakeupReasonStats.size());
+            for (Map.Entry<String, LongSamplingCounter> ent : mWakeupReasonStats.entrySet()) {
+                LongSamplingCounter counter = ent.getValue();
+                if (counter != null) {
+                    out.writeInt(1);
+                    out.writeString(ent.getKey());
+                    counter.writeToParcel(out);
                 } else {
                     out.writeInt(0);
                 }
@@ -6155,7 +7442,7 @@
                 out.writeInt(mUidStats.keyAt(i));
                 Uid uid = mUidStats.valueAt(i);
 
-                uid.writeToParcelLocked(out, batteryRealtime);
+                uid.writeToParcelLocked(out, uSecRealtime);
             }
         } else {
             out.writeInt(0);
@@ -6175,12 +7462,15 @@
 
     public void prepareForDumpLocked() {
         // Need to retrieve current kernel wake lock stats before printing.
-        updateKernelWakelocksLocked();
-        updateNetworkActivityLocked();
+        pullPendingStateUpdatesLocked();
     }
 
-    public void dumpLocked(PrintWriter pw, boolean isUnpluggedOnly, int reqUid) {
+    public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
         if (DEBUG) {
+            pw.println("mOnBatteryTimeBase:");
+            mOnBatteryTimeBase.dump(pw, "  ");
+            pw.println("mOnBatteryScreenOffTimeBase:");
+            mOnBatteryScreenOffTimeBase.dump(pw, "  ");
             Printer pr = new PrintWriterPrinter(pw);
             pr.println("*** Screen timer:");
             mScreenOnTimer.logState(pr, "  ");
@@ -6202,13 +7492,25 @@
                 pr.println("*** Data connection type #" + i + ":");
                 mPhoneDataConnectionsTimer[i].logState(pr, "  ");
             }
+            pr.println("*** Mobile network active timer:");
+            mMobileRadioActiveTimer.logState(pr, "  ");
+            pr.println("*** Mobile network active adjusted timer:");
+            mMobileRadioActiveAdjustedTime.logState(pr, "  ");
             pr.println("*** Wifi timer:");
             mWifiOnTimer.logState(pr, "  ");
             pr.println("*** WifiRunning timer:");
             mGlobalWifiRunningTimer.logState(pr, "  ");
+            for (int i=0; i<NUM_WIFI_STATES; i++) {
+                pr.println("*** Wifi state #" + i + ":");
+                mWifiStateTimer[i].logState(pr, "  ");
+            }
             pr.println("*** Bluetooth timer:");
             mBluetoothOnTimer.logState(pr, "  ");
+            for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
+                pr.println("*** Bluetooth active type #" + i + ":");
+                mBluetoothStateTimer[i].logState(pr, "  ");
+            }
         }
-        super.dumpLocked(pw, isUnpluggedOnly, reqUid);
+        super.dumpLocked(context, pw, flags, reqUid, histStart);
     }
 }
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index c6b3e7c..1766f7b 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -25,7 +25,6 @@
 import java.io.IOException;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import dalvik.system.Zygote;
 
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index bf62745..05c57e8 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -244,9 +244,11 @@
     }
 
     static void preload() {
+        Log.d(TAG, "begin preload");
         preloadClasses();
         preloadResources();
         preloadOpenGL();
+        Log.d(TAG, "end preload");
     }
 
     private static void preloadOpenGL() {
diff --git a/core/java/com/android/internal/preference/YesNoPreference.java b/core/java/com/android/internal/preference/YesNoPreference.java
index cf68a58..7abf416 100644
--- a/core/java/com/android/internal/preference/YesNoPreference.java
+++ b/core/java/com/android/internal/preference/YesNoPreference.java
@@ -31,15 +31,19 @@
  */
 public class YesNoPreference extends DialogPreference {
     private boolean mWasPositiveResult;
-    
-    public YesNoPreference(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+
+    public YesNoPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public YesNoPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
     }
 
     public YesNoPreference(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.yesNoPreferenceStyle);
     }
-    
+
     public YesNoPreference(Context context) {
         this(context, null);
     }
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 97ea7d8..4734712 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -41,11 +41,11 @@
             out List<IBinder> notificationKeys, out List<StatusBarNotification> notifications,
             out int[] switches, out List<IBinder> binders);
     void onPanelRevealed();
-    void onNotificationClick(String pkg, String tag, int id);
+    void onNotificationClick(String pkg, String tag, int id, int userId);
     void onNotificationError(String pkg, String tag, int id,
-            int uid, int initialPid, String message);
-    void onClearAllNotifications();
-    void onNotificationClear(String pkg, String tag, int id);
+            int uid, int initialPid, String message, int userId);
+    void onClearAllNotifications(int userId);
+    void onNotificationClear(String pkg, String tag, int id, int userId);
     void setSystemUiVisibility(int vis, int mask);
     void setHardKeyboardEnabled(boolean enabled);
     void toggleRecentApps();
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
index 25086c5..bee59dc 100644
--- a/core/java/com/android/internal/view/ActionBarPolicy.java
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -19,11 +19,9 @@
 import com.android.internal.R;
 
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.os.Build;
-import android.view.ViewConfiguration;
 
 /**
  * Allows components to query for various configuration policy decisions
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 3724a08..45ca7fc 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -32,7 +32,9 @@
  * this file.
  */
 interface IInputMethodManager {
+    // TODO: Use ParceledListSlice instead
     List<InputMethodInfo> getInputMethodList();
+    // TODO: Use ParceledListSlice instead
     List<InputMethodInfo> getEnabledInputMethodList();
     List<InputMethodSubtype> getEnabledInputMethodSubtypeList(in String imiId,
             boolean allowsImplicitlySelectedSubtypes);
@@ -74,4 +76,6 @@
     boolean shouldOfferSwitchingToNextInputMethod(in IBinder token);
     boolean setInputMethodEnabled(String id, boolean enabled);
     void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
+    int getInputMethodWindowVisibleHeight();
+    oneway void notifyTextCommitted();
 }
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index 6295314..b479cb1 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -18,7 +18,9 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.database.ContentObserver;
+import android.graphics.Point;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Handler;
@@ -26,15 +28,20 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Log;
+import android.view.Display;
 import android.view.IWindowManager;
 import android.view.Surface;
 import android.view.WindowManagerGlobal;
 
+import com.android.internal.R;
+
 /**
  * Provides helper functions for configuring the display rotation policy.
  */
 public final class RotationPolicy {
     private static final String TAG = "RotationPolicy";
+    private static final int CURRENT_ROTATION = -1;
+    private static final int NATURAL_ROTATION = Surface.ROTATION_0;
 
     private RotationPolicy() {
     }
@@ -57,23 +64,33 @@
     }
 
     /**
-     * Returns true if the device supports the rotation-lock toggle feature
-     * in the system UI or system bar.
+     * Returns the orientation that will be used when locking the orientation from system UI
+     * with {@link #setRotationLock}.
      *
-     * When the rotation-lock toggle is supported, the "auto-rotate screen" option in
-     * Display settings should be hidden, but it should remain available in Accessibility
-     * settings.
+     * If the device only supports locking to its natural orientation, this will be either
+     * Configuration.ORIENTATION_PORTRAIT or Configuration.ORIENTATION_LANDSCAPE,
+     * otherwise Configuration.ORIENTATION_UNDEFINED if any orientation is lockable.
      */
-    public static boolean isRotationLockToggleSupported(Context context) {
-        return isRotationSupported(context)
-                && context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
+    public static int getRotationLockOrientation(Context context) {
+        if (!areAllRotationsAllowed(context)) {
+            final Point size = new Point();
+            final IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
+            try {
+                wm.getInitialDisplaySize(Display.DEFAULT_DISPLAY, size);
+                return size.x < size.y ?
+                        Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
+            } catch (RemoteException e) {
+                Log.w(TAG, "Unable to get the display size");
+            }
+        }
+        return Configuration.ORIENTATION_UNDEFINED;
     }
 
     /**
-     * Returns true if the rotation-lock toggle should be shown in the UI.
+     * Returns true if the rotation-lock toggle should be shown in system UI.
      */
     public static boolean isRotationLockToggleVisible(Context context) {
-        return isRotationLockToggleSupported(context) &&
+        return isRotationSupported(context) &&
                 Settings.System.getIntForUser(context.getContentResolver(),
                         Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0,
                         UserHandle.USER_CURRENT) == 0;
@@ -88,50 +105,42 @@
     }
 
     /**
-     * Enables or disables rotation lock.
-     *
-     * Should be used by the rotation lock toggle.
+     * Enables or disables rotation lock from the system UI toggle.
      */
     public static void setRotationLock(Context context, final boolean enabled) {
         Settings.System.putIntForUser(context.getContentResolver(),
                 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0,
                 UserHandle.USER_CURRENT);
 
-        AsyncTask.execute(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
-                    if (enabled) {
-                        wm.freezeRotation(-1);
-                    } else {
-                        wm.thawRotation();
-                    }
-                } catch (RemoteException exc) {
-                    Log.w(TAG, "Unable to save auto-rotate setting");
-                }
-            }
-        });
+        final int rotation = areAllRotationsAllowed(context) ? CURRENT_ROTATION : NATURAL_ROTATION;
+        setRotationLock(enabled, rotation);
     }
 
     /**
-     * Enables or disables rotation lock and adjusts whether the rotation lock toggle
-     * should be hidden for accessibility purposes.
+     * Enables or disables natural rotation lock from Accessibility settings.
      *
-     * Should be used by Display settings and Accessibility settings.
+     * If rotation is locked for accessibility, the system UI toggle is hidden to avoid confusion.
      */
     public static void setRotationLockForAccessibility(Context context, final boolean enabled) {
         Settings.System.putIntForUser(context.getContentResolver(),
                 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0,
                         UserHandle.USER_CURRENT);
 
+        setRotationLock(enabled, NATURAL_ROTATION);
+    }
+
+    private static boolean areAllRotationsAllowed(Context context) {
+        return context.getResources().getBoolean(R.bool.config_allowAllRotations);
+    }
+
+    private static void setRotationLock(final boolean enabled, final int rotation) {
         AsyncTask.execute(new Runnable() {
             @Override
             public void run() {
                 try {
                     IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
                     if (enabled) {
-                        wm.freezeRotation(Surface.ROTATION_0);
+                        wm.freezeRotation(rotation);
                     } else {
                         wm.thawRotation();
                     }
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index 7ca6c1b..ed676bb 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -163,7 +163,7 @@
 
     public MenuItem setIcon(int iconRes) {
         mIconResId = iconRes;
-        mIconDrawable = mContext.getResources().getDrawable(iconRes);
+        mIconDrawable = mContext.getDrawable(iconRes);
         return this;
     }
 
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItemView.java b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
index 238a9c0..3cceebe 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItemView.java
@@ -28,8 +28,11 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
+import android.widget.ActionMenuView;
+import android.widget.ListPopupWindow;
 import android.widget.TextView;
 import android.widget.Toast;
+import android.widget.ListPopupWindow.ForwardingListener;
 
 /**
  * @hide
@@ -43,6 +46,8 @@
     private CharSequence mTitle;
     private Drawable mIcon;
     private MenuBuilder.ItemInvoker mItemInvoker;
+    private ForwardingListener mForwardingListener;
+    private PopupCallback mPopupCallback;
 
     private boolean mAllowTextWithIcon;
     private boolean mExpandedFormat;
@@ -60,13 +65,17 @@
         this(context, attrs, 0);
     }
 
-    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ActionMenuItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         final Resources res = context.getResources();
         mAllowTextWithIcon = res.getBoolean(
                 com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.ActionMenuItemView, 0, 0);
+        final TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.ActionMenuItemView, defStyleAttr, defStyleRes);
         mMinWidth = a.getDimensionPixelSize(
                 com.android.internal.R.styleable.ActionMenuItemView_minWidth, 0);
         a.recycle();
@@ -99,6 +108,7 @@
         return mItemData;
     }
 
+    @Override
     public void initialize(MenuItemImpl itemData, int menuType) {
         mItemData = itemData;
 
@@ -108,8 +118,24 @@
 
         setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
         setEnabled(itemData.isEnabled());
+
+        if (itemData.hasSubMenu()) {
+            if (mForwardingListener == null) {
+                mForwardingListener = new ActionMenuItemForwardingListener();
+            }
+        }
     }
 
+    @Override
+    public boolean onTouchEvent(MotionEvent e) {
+        if (mItemData.hasSubMenu() && mForwardingListener != null
+                && mForwardingListener.onTouch(this, e)) {
+            return true;
+        }
+        return super.onTouchEvent(e);
+    }
+
+    @Override
     public void onClick(View v) {
         if (mItemInvoker != null) {
             mItemInvoker.invokeItem(mItemData);
@@ -120,6 +146,10 @@
         mItemInvoker = invoker;
     }
 
+    public void setPopupCallback(PopupCallback popupCallback) {
+        mPopupCallback = popupCallback;
+    }
+
     public boolean prefersCondensedTitle() {
         return true;
     }
@@ -285,4 +315,42 @@
             super.setPadding((w - dw) / 2, getPaddingTop(), getPaddingRight(), getPaddingBottom());
         }
     }
+
+    private class ActionMenuItemForwardingListener extends ForwardingListener {
+        public ActionMenuItemForwardingListener() {
+            super(ActionMenuItemView.this);
+        }
+
+        @Override
+        public ListPopupWindow getPopup() {
+            if (mPopupCallback != null) {
+                return mPopupCallback.getPopup();
+            }
+            return null;
+        }
+
+        @Override
+        protected boolean onForwardingStarted() {
+            // Call the invoker, then check if the expected popup is showing.
+            if (mItemInvoker != null && mItemInvoker.invokeItem(mItemData)) {
+                final ListPopupWindow popup = getPopup();
+                return popup != null && popup.isShowing();
+            }
+            return false;
+        }
+
+        @Override
+        protected boolean onForwardingStopped() {
+            final ListPopupWindow popup = getPopup();
+            if (popup != null) {
+                popup.dismiss();
+                return true;
+            }
+            return false;
+        }
+    }
+
+    public static abstract class PopupCallback {
+        public abstract ListPopupWindow getPopup();
+    }
 }
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
deleted file mode 100644
index fe1cf72..0000000
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ /dev/null
@@ -1,756 +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.view.menu;
-
-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.Gravity;
-import android.view.MenuItem;
-import android.view.SoundEffectConstants;
-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;
-
-/**
- * MenuPresenter for building action menus as seen in the action bar and action modes.
- */
-public class ActionMenuPresenter extends BaseMenuPresenter
-        implements ActionProvider.SubUiVisibilityListener {
-    private static final String TAG = "ActionMenuPresenter";
-
-    private View mOverflowButton;
-    private boolean mReserveOverflow;
-    private boolean mReserveOverflowSet;
-    private int mWidthLimit;
-    private int mActionItemWidthLimit;
-    private int mMaxItems;
-    private boolean mMaxItemsSet;
-    private boolean mStrictWidthLimit;
-    private boolean mWidthLimitSet;
-    private boolean mExpandedActionViewsExclusive;
-
-    private int mMinCellSize;
-
-    // Group IDs that have been added as actions - used temporarily, allocated here for reuse.
-    private final SparseBooleanArray mActionButtonGroups = new SparseBooleanArray();
-
-    private View mScrapActionButtonView;
-
-    private OverflowPopup mOverflowPopup;
-    private ActionButtonSubmenu mActionButtonPopup;
-
-    private OpenOverflowRunnable mPostedOpenRunnable;
-
-    final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
-    int mOpenSubMenuId;
-
-    public ActionMenuPresenter(Context context) {
-        super(context, com.android.internal.R.layout.action_menu_layout,
-                com.android.internal.R.layout.action_menu_item_layout);
-    }
-
-    @Override
-    public void initForMenu(Context context, MenuBuilder menu) {
-        super.initForMenu(context, menu);
-
-        final Resources res = context.getResources();
-
-        final ActionBarPolicy abp = ActionBarPolicy.get(context);
-        if (!mReserveOverflowSet) {
-            mReserveOverflow = abp.showsOverflowMenuButton();
-        }
-
-        if (!mWidthLimitSet) {
-            mWidthLimit = abp.getEmbeddedMenuWidthLimit();
-        }
-
-        // Measure for initial configuration
-        if (!mMaxItemsSet) {
-            mMaxItems = abp.getMaxActionButtons();
-        }
-
-        int width = mWidthLimit;
-        if (mReserveOverflow) {
-            if (mOverflowButton == null) {
-                mOverflowButton = new OverflowMenuButton(mSystemContext);
-                final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-                mOverflowButton.measure(spec, spec);
-            }
-            width -= mOverflowButton.getMeasuredWidth();
-        } else {
-            mOverflowButton = null;
-        }
-
-        mActionItemWidthLimit = width;
-
-        mMinCellSize = (int) (ActionMenuView.MIN_CELL_SIZE * res.getDisplayMetrics().density);
-
-        // Drop a scrap view as it may no longer reflect the proper context/config.
-        mScrapActionButtonView = null;
-    }
-
-    public void onConfigurationChanged(Configuration newConfig) {
-        if (!mMaxItemsSet) {
-            mMaxItems = mContext.getResources().getInteger(
-                    com.android.internal.R.integer.max_action_buttons);
-        }
-        if (mMenu != null) {
-            mMenu.onItemsChanged(true);
-        }
-    }
-
-    public void setWidthLimit(int width, boolean strict) {
-        mWidthLimit = width;
-        mStrictWidthLimit = strict;
-        mWidthLimitSet = true;
-    }
-
-    public void setReserveOverflow(boolean reserveOverflow) {
-        mReserveOverflow = reserveOverflow;
-        mReserveOverflowSet = true;
-    }
-
-    public void setItemLimit(int itemCount) {
-        mMaxItems = itemCount;
-        mMaxItemsSet = true;
-    }
-
-    public void setExpandedActionViewsExclusive(boolean isExclusive) {
-        mExpandedActionViewsExclusive = isExclusive;
-    }
-
-    @Override
-    public MenuView getMenuView(ViewGroup root) {
-        MenuView result = super.getMenuView(root);
-        ((ActionMenuView) result).setPresenter(this);
-        return result;
-    }
-
-    @Override
-    public View getItemView(final MenuItemImpl item, View convertView, ViewGroup parent) {
-        View actionView = item.getActionView();
-        if (actionView == null || item.hasCollapsibleActionView()) {
-            actionView = super.getItemView(item, convertView, parent);
-        }
-        actionView.setVisibility(item.isActionViewExpanded() ? View.GONE : View.VISIBLE);
-
-        final ActionMenuView menuParent = (ActionMenuView) parent;
-        final ViewGroup.LayoutParams lp = actionView.getLayoutParams();
-        if (!menuParent.checkLayoutParams(lp)) {
-            actionView.setLayoutParams(menuParent.generateLayoutParams(lp));
-        }
-        return actionView;
-    }
-
-    @Override
-    public void bindItemView(final MenuItemImpl item, MenuView.ItemView itemView) {
-        itemView.initialize(item, 0);
-
-        final ActionMenuView menuView = (ActionMenuView) mMenuView;
-        final ActionMenuItemView actionItemView = (ActionMenuItemView) itemView;
-        actionItemView.setItemInvoker(menuView);
-
-        if (item.hasSubMenu()) {
-            actionItemView.setOnTouchListener(new ForwardingListener(actionItemView) {
-                @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 {
-            actionItemView.setOnTouchListener(null);
-        }
-    }
-
-    @Override
-    public boolean shouldIncludeItem(int childIndex, MenuItemImpl item) {
-        return item.isActionButton();
-    }
-
-    @Override
-    public void updateMenuView(boolean cleared) {
-        final ViewGroup menuViewParent = (ViewGroup) ((View) mMenuView).getParent();
-        if (menuViewParent != null) {
-            ActionBarTransition.beginDelayedTransition(menuViewParent);
-        }
-        super.updateMenuView(cleared);
-
-        ((View) mMenuView).requestLayout();
-
-        if (mMenu != null) {
-            final ArrayList<MenuItemImpl> actionItems = mMenu.getActionItems();
-            final int count = actionItems.size();
-            for (int i = 0; i < count; i++) {
-                final ActionProvider provider = actionItems.get(i).getActionProvider();
-                if (provider != null) {
-                    provider.setSubUiVisibilityListener(this);
-                }
-            }
-        }
-
-        final ArrayList<MenuItemImpl> nonActionItems = mMenu != null ?
-                mMenu.getNonActionItems() : null;
-
-        boolean hasOverflow = false;
-        if (mReserveOverflow && nonActionItems != null) {
-            final int count = nonActionItems.size();
-            if (count == 1) {
-                hasOverflow = !nonActionItems.get(0).isActionViewExpanded();
-            } else {
-                hasOverflow = count > 0;
-            }
-        }
-
-        if (hasOverflow) {
-            if (mOverflowButton == null) {
-                mOverflowButton = new OverflowMenuButton(mSystemContext);
-            }
-            ViewGroup parent = (ViewGroup) mOverflowButton.getParent();
-            if (parent != mMenuView) {
-                if (parent != null) {
-                    parent.removeView(mOverflowButton);
-                }
-                ActionMenuView menuView = (ActionMenuView) mMenuView;
-                menuView.addView(mOverflowButton, menuView.generateOverflowButtonLayoutParams());
-            }
-        } else if (mOverflowButton != null && mOverflowButton.getParent() == mMenuView) {
-            ((ViewGroup) mMenuView).removeView(mOverflowButton);
-        }
-
-        ((ActionMenuView) mMenuView).setOverflowReserved(mReserveOverflow);
-    }
-
-    @Override
-    public boolean filterLeftoverView(ViewGroup parent, int childIndex) {
-        if (parent.getChildAt(childIndex) == mOverflowButton) return false;
-        return super.filterLeftoverView(parent, childIndex);
-    }
-
-    public boolean onSubMenuSelected(SubMenuBuilder subMenu) {
-        if (!subMenu.hasVisibleItems()) return false;
-
-        SubMenuBuilder topSubMenu = subMenu;
-        while (topSubMenu.getParentMenu() != mMenu) {
-            topSubMenu = (SubMenuBuilder) topSubMenu.getParentMenu();
-        }
-        View anchor = findViewForItem(topSubMenu.getItem());
-        if (anchor == null) {
-            if (mOverflowButton == null) return false;
-            anchor = mOverflowButton;
-        }
-
-        mOpenSubMenuId = subMenu.getItem().getItemId();
-        mActionButtonPopup = new ActionButtonSubmenu(mContext, subMenu);
-        mActionButtonPopup.setAnchorView(anchor);
-        mActionButtonPopup.show();
-        super.onSubMenuSelected(subMenu);
-        return true;
-    }
-
-    private View findViewForItem(MenuItem item) {
-        final ViewGroup parent = (ViewGroup) mMenuView;
-        if (parent == null) return null;
-
-        final int count = parent.getChildCount();
-        for (int i = 0; i < count; i++) {
-            final View child = parent.getChildAt(i);
-            if (child instanceof MenuView.ItemView &&
-                    ((MenuView.ItemView) child).getItemData() == item) {
-                return child;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Display the overflow menu if one is present.
-     * @return true if the overflow menu was shown, false otherwise.
-     */
-    public boolean showOverflowMenu() {
-        if (mReserveOverflow && !isOverflowMenuShowing() && mMenu != null && mMenuView != null &&
-                mPostedOpenRunnable == null && !mMenu.getNonActionItems().isEmpty()) {
-            OverflowPopup popup = new OverflowPopup(mContext, mMenu, mOverflowButton, true);
-            mPostedOpenRunnable = new OpenOverflowRunnable(popup);
-            // Post this for later; we might still need a layout for the anchor to be right.
-            ((View) mMenuView).post(mPostedOpenRunnable);
-
-            // ActionMenuPresenter uses null as a callback argument here
-            // to indicate overflow is opening.
-            super.onSubMenuSelected(null);
-
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Hide the overflow menu if it is currently showing.
-     *
-     * @return true if the overflow menu was hidden, false otherwise.
-     */
-    public boolean hideOverflowMenu() {
-        if (mPostedOpenRunnable != null && mMenuView != null) {
-            ((View) mMenuView).removeCallbacks(mPostedOpenRunnable);
-            mPostedOpenRunnable = null;
-            return true;
-        }
-
-        MenuPopupHelper popup = mOverflowPopup;
-        if (popup != null) {
-            popup.dismiss();
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Dismiss all popup menus - overflow and submenus.
-     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
-     */
-    public boolean dismissPopupMenus() {
-        boolean result = hideOverflowMenu();
-        result |= hideSubMenus();
-        return result;
-    }
-
-    /**
-     * Dismiss all submenu popups.
-     *
-     * @return true if popups were dismissed, false otherwise. (This can be because none were open.)
-     */
-    public boolean hideSubMenus() {
-        if (mActionButtonPopup != null) {
-            mActionButtonPopup.dismiss();
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @return true if the overflow menu is currently showing
-     */
-    public boolean isOverflowMenuShowing() {
-        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.
-     */
-    public boolean isOverflowReserved() {
-        return mReserveOverflow;
-    }
-
-    public boolean flagActionItems() {
-        final ArrayList<MenuItemImpl> visibleItems = mMenu.getVisibleItems();
-        final int itemsSize = visibleItems.size();
-        int maxActions = mMaxItems;
-        int widthLimit = mActionItemWidthLimit;
-        final int querySpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final ViewGroup parent = (ViewGroup) mMenuView;
-
-        int requiredItems = 0;
-        int requestedItems = 0;
-        int firstActionWidth = 0;
-        boolean hasOverflow = false;
-        for (int i = 0; i < itemsSize; i++) {
-            MenuItemImpl item = visibleItems.get(i);
-            if (item.requiresActionButton()) {
-                requiredItems++;
-            } else if (item.requestsActionButton()) {
-                requestedItems++;
-            } else {
-                hasOverflow = true;
-            }
-            if (mExpandedActionViewsExclusive && item.isActionViewExpanded()) {
-                // Overflow everything if we have an expanded action view and we're
-                // space constrained.
-                maxActions = 0;
-            }
-        }
-
-        // Reserve a spot for the overflow item if needed.
-        if (mReserveOverflow &&
-                (hasOverflow || requiredItems + requestedItems > maxActions)) {
-            maxActions--;
-        }
-        maxActions -= requiredItems;
-
-        final SparseBooleanArray seenGroups = mActionButtonGroups;
-        seenGroups.clear();
-
-        int cellSize = 0;
-        int cellsRemaining = 0;
-        if (mStrictWidthLimit) {
-            cellsRemaining = widthLimit / mMinCellSize;
-            final int cellSizeRemaining = widthLimit % mMinCellSize;
-            cellSize = mMinCellSize + cellSizeRemaining / cellsRemaining;
-        }
-
-        // Flag as many more requested items as will fit.
-        for (int i = 0; i < itemsSize; i++) {
-            MenuItemImpl item = visibleItems.get(i);
-
-            if (item.requiresActionButton()) {
-                View v = getItemView(item, mScrapActionButtonView, parent);
-                if (mScrapActionButtonView == null) {
-                    mScrapActionButtonView = v;
-                }
-                if (mStrictWidthLimit) {
-                    cellsRemaining -= ActionMenuView.measureChildForCells(v,
-                            cellSize, cellsRemaining, querySpec, 0);
-                } else {
-                    v.measure(querySpec, querySpec);
-                }
-                final int measuredWidth = v.getMeasuredWidth();
-                widthLimit -= measuredWidth;
-                if (firstActionWidth == 0) {
-                    firstActionWidth = measuredWidth;
-                }
-                final int groupId = item.getGroupId();
-                if (groupId != 0) {
-                    seenGroups.put(groupId, true);
-                }
-                item.setIsActionButton(true);
-            } else if (item.requestsActionButton()) {
-                // Items in a group with other items that already have an action slot
-                // can break the max actions rule, but not the width limit.
-                final int groupId = item.getGroupId();
-                final boolean inGroup = seenGroups.get(groupId);
-                boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
-                        (!mStrictWidthLimit || cellsRemaining > 0);
-
-                if (isAction) {
-                    View v = getItemView(item, mScrapActionButtonView, parent);
-                    if (mScrapActionButtonView == null) {
-                        mScrapActionButtonView = v;
-                    }
-                    if (mStrictWidthLimit) {
-                        final int cells = ActionMenuView.measureChildForCells(v,
-                                cellSize, cellsRemaining, querySpec, 0);
-                        cellsRemaining -= cells;
-                        if (cells == 0) {
-                            isAction = false;
-                        }
-                    } else {
-                        v.measure(querySpec, querySpec);
-                    }
-                    final int measuredWidth = v.getMeasuredWidth();
-                    widthLimit -= measuredWidth;
-                    if (firstActionWidth == 0) {
-                        firstActionWidth = measuredWidth;
-                    }
-
-                    if (mStrictWidthLimit) {
-                        isAction &= widthLimit >= 0;
-                    } else {
-                        // Did this push the entire first item past the limit?
-                        isAction &= widthLimit + firstActionWidth > 0;
-                    }
-                }
-
-                if (isAction && groupId != 0) {
-                    seenGroups.put(groupId, true);
-                } else if (inGroup) {
-                    // We broke the width limit. Demote the whole group, they all overflow now.
-                    seenGroups.put(groupId, false);
-                    for (int j = 0; j < i; j++) {
-                        MenuItemImpl areYouMyGroupie = visibleItems.get(j);
-                        if (areYouMyGroupie.getGroupId() == groupId) {
-                            // Give back the action slot
-                            if (areYouMyGroupie.isActionButton()) maxActions++;
-                            areYouMyGroupie.setIsActionButton(false);
-                        }
-                    }
-                }
-
-                if (isAction) maxActions--;
-
-                item.setIsActionButton(isAction);
-            } else {
-                // Neither requires nor requests an action button.
-                item.setIsActionButton(false);
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
-        dismissPopupMenus();
-        super.onCloseMenu(menu, allMenusAreClosing);
-    }
-
-    @Override
-    public Parcelable onSaveInstanceState() {
-        SavedState state = new SavedState();
-        state.openSubMenuId = mOpenSubMenuId;
-        return state;
-    }
-
-    @Override
-    public void onRestoreInstanceState(Parcelable state) {
-        SavedState saved = (SavedState) state;
-        if (saved.openSubMenuId > 0) {
-            MenuItem item = mMenu.findItem(saved.openSubMenuId);
-            if (item != null) {
-                SubMenuBuilder subMenu = (SubMenuBuilder) item.getSubMenu();
-                onSubMenuSelected(subMenu);
-            }
-        }
-    }
-
-    @Override
-    public void onSubUiVisibilityChanged(boolean isVisible) {
-        if (isVisible) {
-            // Not a submenu, but treat it like one.
-            super.onSubMenuSelected(null);
-        } else {
-            mMenu.close(false);
-        }
-    }
-
-    private static class SavedState implements Parcelable {
-        public int openSubMenuId;
-
-        SavedState() {
-        }
-
-        SavedState(Parcel in) {
-            openSubMenuId = in.readInt();
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeInt(openSubMenuId);
-        }
-
-        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];
-            }
-        };
-    }
-
-    private class OverflowMenuButton extends ImageButton implements ActionMenuChildView {
-        public OverflowMenuButton(Context context) {
-            super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle);
-
-            setClickable(true);
-            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
-        public boolean performClick() {
-            if (super.performClick()) {
-                return true;
-            }
-
-            playSoundEffect(SoundEffectConstants.CLICK);
-            showOverflowMenu();
-            return true;
-        }
-
-        @Override
-        public boolean needsDividerBefore() {
-            return false;
-        }
-
-        @Override
-        public boolean needsDividerAfter() {
-            return false;
-        }
-
-        @Override
-        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-            if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
-                // Fill available height
-                heightMeasureSpec = MeasureSpec.makeMeasureSpec(
-                        MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
-            }
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-
-        @Override
-        public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
-            super.onInitializeAccessibilityNodeInfo(info);
-            info.setCanOpenPopup(true);
-        }
-    }
-
-    private class OverflowPopup extends MenuPopupHelper {
-        public OverflowPopup(Context context, MenuBuilder menu, View anchorView,
-                boolean overflowOnly) {
-            super(context, menu, anchorView, overflowOnly);
-            setGravity(Gravity.END);
-            setCallback(mPopupPresenterCallback);
-        }
-
-        @Override
-        public void onDismiss() {
-            super.onDismiss();
-            mMenu.close();
-            mOverflowPopup = null;
-        }
-    }
-
-    private class ActionButtonSubmenu extends MenuPopupHelper {
-        private SubMenuBuilder mSubMenu;
-
-        public ActionButtonSubmenu(Context context, SubMenuBuilder subMenu) {
-            super(context, subMenu);
-            mSubMenu = subMenu;
-
-            MenuItemImpl item = (MenuItemImpl) subMenu.getItem();
-            if (!item.isActionButton()) {
-                // Give a reasonable anchor to nested submenus.
-                setAnchorView(mOverflowButton == null ? (View) mMenuView : mOverflowButton);
-            }
-
-            setCallback(mPopupPresenterCallback);
-
-            boolean preserveIconSpacing = false;
-            final int count = subMenu.size();
-            for (int i = 0; i < count; i++) {
-                MenuItem childItem = subMenu.getItem(i);
-                if (childItem.isVisible() && childItem.getIcon() != null) {
-                    preserveIconSpacing = true;
-                    break;
-                }
-            }
-            setForceShowIcon(preserveIconSpacing);
-        }
-
-        @Override
-        public void onDismiss() {
-            super.onDismiss();
-            mActionButtonPopup = null;
-            mOpenSubMenuId = 0;
-        }
-    }
-
-    private class PopupPresenterCallback implements MenuPresenter.Callback {
-
-        @Override
-        public boolean onOpenSubMenu(MenuBuilder subMenu) {
-            if (subMenu == null) return false;
-
-            mOpenSubMenuId = ((SubMenuBuilder) subMenu).getItem().getItemId();
-            final MenuPresenter.Callback cb = getCallback();
-            return cb != null ? cb.onOpenSubMenu(subMenu) : false;
-        }
-
-        @Override
-        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
-            if (menu instanceof SubMenuBuilder) {
-                ((SubMenuBuilder) menu).getRootMenu().close(false);
-            }
-            final MenuPresenter.Callback cb = getCallback();
-            if (cb != null) {
-                cb.onCloseMenu(menu, allMenusAreClosing);
-            }
-        }
-    }
-
-    private class OpenOverflowRunnable implements Runnable {
-        private OverflowPopup mPopup;
-
-        public OpenOverflowRunnable(OverflowPopup popup) {
-            mPopup = popup;
-        }
-
-        public void run() {
-            mMenu.changeMenuMode();
-            final View menuView = (View) mMenuView;
-            if (menuView != null && menuView.getWindowToken() != null && mPopup.tryShow()) {
-                mOverflowPopup = mPopup;
-            }
-            mPostedOpenRunnable = null;
-        }
-    }
-}
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
deleted file mode 100644
index 16a2031..0000000
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ /dev/null
@@ -1,620 +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.internal.view.menu;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewDebug;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
-import android.widget.LinearLayout;
-import com.android.internal.R;
-
-/**
- * @hide
- */
-public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvoker, MenuView {
-    private static final String TAG = "ActionMenuView";
-    
-    static final int MIN_CELL_SIZE = 56; // dips
-    static final int GENERATED_ITEM_PADDING = 4; // dips
-
-    private MenuBuilder mMenu;
-
-    private boolean mReserveOverflow;
-    private ActionMenuPresenter mPresenter;
-    private boolean mFormatItems;
-    private int mFormatItemsWidth;
-    private int mMinCellSize;
-    private int mGeneratedItemPadding;
-    private int mMeasuredExtraWidth;
-    private int mMaxItemHeight;
-
-    public ActionMenuView(Context context) {
-        this(context, null);
-    }
-    
-    public ActionMenuView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setBaselineAligned(false);
-        final float density = context.getResources().getDisplayMetrics().density;
-        mMinCellSize = (int) (MIN_CELL_SIZE * density);
-        mGeneratedItemPadding = (int) (GENERATED_ITEM_PADDING * density);
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionBar,
-                R.attr.actionBarStyle, 0);
-        mMaxItemHeight = a.getDimensionPixelSize(R.styleable.ActionBar_height, 0);
-        a.recycle();
-    }
-
-    public void setPresenter(ActionMenuPresenter presenter) {
-        mPresenter = presenter;
-    }
-
-    public boolean isExpandedFormat() {
-        return mFormatItems;
-    }
-
-    public void setMaxItemHeight(int maxItemHeight) {
-        mMaxItemHeight = maxItemHeight;
-        requestLayout();
-    }
-
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        mPresenter.updateMenuView(false);
-
-        if (mPresenter != null && mPresenter.isOverflowMenuShowing()) {
-            mPresenter.hideOverflowMenu();
-            mPresenter.showOverflowMenu();
-        }
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // If we've been given an exact size to match, apply special formatting during layout.
-        final boolean wasFormatted = mFormatItems;
-        mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
-
-        if (wasFormatted != mFormatItems) {
-            mFormatItemsWidth = 0; // Reset this when switching modes
-        }
-
-        // Special formatting can change whether items can fit as action buttons.
-        // Kick the menu and update presenters when this changes.
-        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) {
-            mFormatItemsWidth = widthSize;
-            mMenu.onItemsChanged(true);
-        }
-
-        if (mFormatItems) {
-            onMeasureExactFormat(widthMeasureSpec, heightMeasureSpec);
-        } else {
-            // Previous measurement at exact format may have set margins - reset them.
-            final int childCount = getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                final View child = getChildAt(i);
-                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-                lp.leftMargin = lp.rightMargin = 0;
-            }
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-    }
-
-    private void onMeasureExactFormat(int widthMeasureSpec, int heightMeasureSpec) {
-        // We already know the width mode is EXACTLY if we're here.
-        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-
-        final int widthPadding = getPaddingLeft() + getPaddingRight();
-        final int heightPadding = getPaddingTop() + getPaddingBottom();
-
-        final int itemHeightSpec = heightMode == MeasureSpec.EXACTLY
-                ? MeasureSpec.makeMeasureSpec(heightSize - heightPadding, MeasureSpec.EXACTLY)
-                : MeasureSpec.makeMeasureSpec(
-                    Math.min(mMaxItemHeight, heightSize - heightPadding), MeasureSpec.AT_MOST);
-
-        widthSize -= widthPadding;
-
-        // Divide the view into cells.
-        final int cellCount = widthSize / mMinCellSize;
-        final int cellSizeRemaining = widthSize % mMinCellSize;
-
-        if (cellCount == 0) {
-            // Give up, nothing fits.
-            setMeasuredDimension(widthSize, 0);
-            return;
-        }
-
-        final int cellSize = mMinCellSize + cellSizeRemaining / cellCount;
-
-        int cellsRemaining = cellCount;
-        int maxChildHeight = 0;
-        int maxCellsUsed = 0;
-        int expandableItemCount = 0;
-        int visibleItemCount = 0;
-        boolean hasOverflow = false;
-
-        // This is used as a bitfield to locate the smallest items present. Assumes childCount < 64.
-        long smallestItemsAt = 0;
-
-        final int childCount = getChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
-            if (child.getVisibility() == GONE) continue;
-
-            final boolean isGeneratedItem = child instanceof ActionMenuItemView;
-            visibleItemCount++;
-
-            if (isGeneratedItem) {
-                // Reset padding for generated menu item views; it may change below
-                // and views are recycled.
-                child.setPadding(mGeneratedItemPadding, 0, mGeneratedItemPadding, 0);
-            }
-
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-            lp.expanded = false;
-            lp.extraPixels = 0;
-            lp.cellsUsed = 0;
-            lp.expandable = false;
-            lp.leftMargin = 0;
-            lp.rightMargin = 0;
-            lp.preventEdgeOffset = isGeneratedItem && ((ActionMenuItemView) child).hasText();
-
-            // Overflow always gets 1 cell. No more, no less.
-            final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining;
-
-            final int cellsUsed = measureChildForCells(child, cellSize, cellsAvailable,
-                    itemHeightSpec, heightPadding);
-
-            maxCellsUsed = Math.max(maxCellsUsed, cellsUsed);
-            if (lp.expandable) expandableItemCount++;
-            if (lp.isOverflowButton) hasOverflow = true;
-
-            cellsRemaining -= cellsUsed;
-            maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight());
-            if (cellsUsed == 1) smallestItemsAt |= (1 << i);
-        }
-
-        // When we have overflow and a single expanded (text) item, we want to try centering it
-        // visually in the available space even though overflow consumes some of it.
-        final boolean centerSingleExpandedItem = hasOverflow && visibleItemCount == 2;
-
-        // Divide space for remaining cells if we have items that can expand.
-        // Try distributing whole leftover cells to smaller items first.
-
-        boolean needsExpansion = false;
-        while (expandableItemCount > 0 && cellsRemaining > 0) {
-            int minCells = Integer.MAX_VALUE;
-            long minCellsAt = 0; // Bit locations are indices of relevant child views
-            int minCellsItemCount = 0;
-            for (int i = 0; i < childCount; i++) {
-                final View child = getChildAt(i);
-                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-                // Don't try to expand items that shouldn't.
-                if (!lp.expandable) continue;
-
-                // Mark indices of children that can receive an extra cell.
-                if (lp.cellsUsed < minCells) {
-                    minCells = lp.cellsUsed;
-                    minCellsAt = 1 << i;
-                    minCellsItemCount = 1;
-                } else if (lp.cellsUsed == minCells) {
-                    minCellsAt |= 1 << i;
-                    minCellsItemCount++;
-                }
-            }
-
-            // Items that get expanded will always be in the set of smallest items when we're done.
-            smallestItemsAt |= minCellsAt;
-
-            if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop.
-
-            // We have enough cells, all minimum size items will be incremented.
-            minCells++;
-
-            for (int i = 0; i < childCount; i++) {
-                final View child = getChildAt(i);
-                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-                if ((minCellsAt & (1 << i)) == 0) {
-                    // If this item is already at our small item count, mark it for later.
-                    if (lp.cellsUsed == minCells) smallestItemsAt |= 1 << i;
-                    continue;
-                }
-
-                if (centerSingleExpandedItem && lp.preventEdgeOffset && cellsRemaining == 1) {
-                    // Add padding to this item such that it centers.
-                    child.setPadding(mGeneratedItemPadding + cellSize, 0, mGeneratedItemPadding, 0);
-                }
-                lp.cellsUsed++;
-                lp.expanded = true;
-                cellsRemaining--;
-            }
-
-            needsExpansion = true;
-        }
-
-        // Divide any space left that wouldn't divide along cell boundaries
-        // evenly among the smallest items
-
-        final boolean singleItem = !hasOverflow && visibleItemCount == 1;
-        if (cellsRemaining > 0 && smallestItemsAt != 0 &&
-                (cellsRemaining < visibleItemCount - 1 || singleItem || maxCellsUsed > 1)) {
-            float expandCount = Long.bitCount(smallestItemsAt);
-
-            if (!singleItem) {
-                // The items at the far edges may only expand by half in order to pin to either side.
-                if ((smallestItemsAt & 1) != 0) {
-                    LayoutParams lp = (LayoutParams) getChildAt(0).getLayoutParams();
-                    if (!lp.preventEdgeOffset) expandCount -= 0.5f;
-                }
-                if ((smallestItemsAt & (1 << (childCount - 1))) != 0) {
-                    LayoutParams lp = ((LayoutParams) getChildAt(childCount - 1).getLayoutParams());
-                    if (!lp.preventEdgeOffset) expandCount -= 0.5f;
-                }
-            }
-
-            final int extraPixels = expandCount > 0 ?
-                    (int) (cellsRemaining * cellSize / expandCount) : 0;
-
-            for (int i = 0; i < childCount; i++) {
-                if ((smallestItemsAt & (1 << i)) == 0) continue;
-
-                final View child = getChildAt(i);
-                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-                if (child instanceof ActionMenuItemView) {
-                    // If this is one of our views, expand and measure at the larger size.
-                    lp.extraPixels = extraPixels;
-                    lp.expanded = true;
-                    if (i == 0 && !lp.preventEdgeOffset) {
-                        // First item gets part of its new padding pushed out of sight.
-                        // The last item will get this implicitly from layout.
-                        lp.leftMargin = -extraPixels / 2;
-                    }
-                    needsExpansion = true;
-                } else if (lp.isOverflowButton) {
-                    lp.extraPixels = extraPixels;
-                    lp.expanded = true;
-                    lp.rightMargin = -extraPixels / 2;
-                    needsExpansion = true;
-                } else {
-                    // If we don't know what it is, give it some margins instead
-                    // and let it center within its space. We still want to pin
-                    // against the edges.
-                    if (i != 0) {
-                        lp.leftMargin = extraPixels / 2;
-                    }
-                    if (i != childCount - 1) {
-                        lp.rightMargin = extraPixels / 2;
-                    }
-                }
-            }
-
-            cellsRemaining = 0;
-        }
-
-        // Remeasure any items that have had extra space allocated to them.
-        if (needsExpansion) {
-            for (int i = 0; i < childCount; i++) {
-                final View child = getChildAt(i);
-                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-                if (!lp.expanded) continue;
-
-                final int width = lp.cellsUsed * cellSize + lp.extraPixels;
-                child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
-                        itemHeightSpec);
-            }
-        }
-
-        if (heightMode != MeasureSpec.EXACTLY) {
-            heightSize = maxChildHeight;
-        }
-
-        setMeasuredDimension(widthSize, heightSize);
-        mMeasuredExtraWidth = cellsRemaining * cellSize;
-    }
-
-    /**
-     * Measure a child view to fit within cell-based formatting. The child's width
-     * will be measured to a whole multiple of cellSize.
-     *
-     * <p>Sets the expandable and cellsUsed fields of LayoutParams.
-     *
-     * @param child Child to measure
-     * @param cellSize Size of one cell
-     * @param cellsRemaining Number of cells remaining that this view can expand to fill
-     * @param parentHeightMeasureSpec MeasureSpec used by the parent view
-     * @param parentHeightPadding Padding present in the parent view
-     * @return Number of cells this child was measured to occupy
-     */
-    static int measureChildForCells(View child, int cellSize, int cellsRemaining,
-            int parentHeightMeasureSpec, int parentHeightPadding) {
-        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-        final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) -
-                parentHeightPadding;
-        final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec);
-        final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode);
-
-        final ActionMenuItemView itemView = child instanceof ActionMenuItemView ?
-                (ActionMenuItemView) child : null;
-        final boolean hasText = itemView != null && itemView.hasText();
-
-        int cellsUsed = 0;
-        if (cellsRemaining > 0 && (!hasText || cellsRemaining >= 2)) {
-            final int childWidthSpec = MeasureSpec.makeMeasureSpec(
-                    cellSize * cellsRemaining, MeasureSpec.AT_MOST);
-            child.measure(childWidthSpec, childHeightSpec);
-
-            final int measuredWidth = child.getMeasuredWidth();
-            cellsUsed = measuredWidth / cellSize;
-            if (measuredWidth % cellSize != 0) cellsUsed++;
-            if (hasText && cellsUsed < 2) cellsUsed = 2;
-        }
-
-        final boolean expandable = !lp.isOverflowButton && hasText;
-        lp.expandable = expandable;
-
-        lp.cellsUsed = cellsUsed;
-        final int targetWidth = cellsUsed * cellSize;
-        child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY),
-                childHeightSpec);
-        return cellsUsed;
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        if (!mFormatItems) {
-            super.onLayout(changed, left, top, right, bottom);
-            return;
-        }
-
-        final int childCount = getChildCount();
-        final int midVertical = (top + bottom) / 2;
-        final int dividerWidth = getDividerWidth();
-        int overflowWidth = 0;
-        int nonOverflowWidth = 0;
-        int nonOverflowCount = 0;
-        int widthRemaining = right - left - getPaddingRight() - getPaddingLeft();
-        boolean hasOverflow = false;
-        final boolean isLayoutRtl = isLayoutRtl();
-        for (int i = 0; i < childCount; i++) {
-            final View v = getChildAt(i);
-            if (v.getVisibility() == GONE) {
-                continue;
-            }
-
-            LayoutParams p = (LayoutParams) v.getLayoutParams();
-            if (p.isOverflowButton) {
-                overflowWidth = v.getMeasuredWidth();
-                if (hasDividerBeforeChildAt(i)) {
-                    overflowWidth += dividerWidth;
-                }
-
-                int height = v.getMeasuredHeight();
-                int r;
-                int l;
-                if (isLayoutRtl) {
-                    l = getPaddingLeft() + p.leftMargin;
-                    r = l + overflowWidth;
-                } else {
-                    r = getWidth() - getPaddingRight() - p.rightMargin;
-                    l = r - overflowWidth;
-                }
-                int t = midVertical - (height / 2);
-                int b = t + height;
-                v.layout(l, t, r, b);
-
-                widthRemaining -= overflowWidth;
-                hasOverflow = true;
-            } else {
-                final int size = v.getMeasuredWidth() + p.leftMargin + p.rightMargin;
-                nonOverflowWidth += size;
-                widthRemaining -= size;
-                if (hasDividerBeforeChildAt(i)) {
-                    nonOverflowWidth += dividerWidth;
-                }
-                nonOverflowCount++;
-            }
-        }
-
-        if (childCount == 1 && !hasOverflow) {
-            // Center a single child
-            final View v = getChildAt(0);
-            final int width = v.getMeasuredWidth();
-            final int height = v.getMeasuredHeight();
-            final int midHorizontal = (right - left) / 2;
-            final int l = midHorizontal - width / 2;
-            final int t = midVertical - height / 2;
-            v.layout(l, t, l + width, t + height);
-            return;
-        }
-
-        final int spacerCount = nonOverflowCount - (hasOverflow ? 0 : 1);
-        final int spacerSize = Math.max(0, spacerCount > 0 ? widthRemaining / spacerCount : 0);
-
-        if (isLayoutRtl) {
-            int startRight = getWidth() - getPaddingRight();
-            for (int i = 0; i < childCount; i++) {
-                final View v = getChildAt(i);
-                final LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                if (v.getVisibility() == GONE || lp.isOverflowButton) {
-                    continue;
-                }
-
-                startRight -= lp.rightMargin;
-                int width = v.getMeasuredWidth();
-                int height = v.getMeasuredHeight();
-                int t = midVertical - height / 2;
-                v.layout(startRight - width, t, startRight, t + height);
-                startRight -= width + lp.leftMargin + spacerSize;
-            }
-        } else {
-            int startLeft = getPaddingLeft();
-            for (int i = 0; i < childCount; i++) {
-                final View v = getChildAt(i);
-                final LayoutParams lp = (LayoutParams) v.getLayoutParams();
-                if (v.getVisibility() == GONE || lp.isOverflowButton) {
-                    continue;
-                }
-
-                startLeft += lp.leftMargin;
-                int width = v.getMeasuredWidth();
-                int height = v.getMeasuredHeight();
-                int t = midVertical - height / 2;
-                v.layout(startLeft, t, startLeft + width, t + height);
-                startLeft += width + lp.rightMargin + spacerSize;
-            }
-        }
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mPresenter.dismissPopupMenus();
-    }
-
-    public boolean isOverflowReserved() {
-        return mReserveOverflow;
-    }
-    
-    public void setOverflowReserved(boolean reserveOverflow) {
-        mReserveOverflow = reserveOverflow;
-    }
-
-    @Override
-    protected LayoutParams generateDefaultLayoutParams() {
-        LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
-                LayoutParams.WRAP_CONTENT);
-        params.gravity = Gravity.CENTER_VERTICAL;
-        return params;
-    }
-    
-    @Override
-    public LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new LayoutParams(getContext(), attrs);
-    }
-
-    @Override
-    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
-        if (p != null) {
-            final LayoutParams result = p instanceof LayoutParams
-                    ? new LayoutParams((LayoutParams) p)
-                    : new LayoutParams(p);
-            if (result.gravity <= Gravity.NO_GRAVITY) {
-                result.gravity = Gravity.CENTER_VERTICAL;
-            }
-            return result;
-        }
-        return generateDefaultLayoutParams();
-    }
-
-    @Override
-    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
-        return p != null && p instanceof LayoutParams;
-    }
-
-    public LayoutParams generateOverflowButtonLayoutParams() {
-        LayoutParams result = generateDefaultLayoutParams();
-        result.isOverflowButton = true;
-        return result;
-    }
-
-    public boolean invokeItem(MenuItemImpl item) {
-        return mMenu.performItemAction(item, 0);
-    }
-
-    public int getWindowAnimations() {
-        return 0;
-    }
-
-    public void initialize(MenuBuilder menu) {
-        mMenu = menu;
-    }
-
-    @Override
-    protected boolean hasDividerBeforeChildAt(int childIndex) {
-        if (childIndex == 0) {
-            return false;
-        }
-        final View childBefore = getChildAt(childIndex - 1);
-        final View child = getChildAt(childIndex);
-        boolean result = false;
-        if (childIndex < getChildCount() && childBefore instanceof ActionMenuChildView) {
-            result |= ((ActionMenuChildView) childBefore).needsDividerAfter();
-        }
-        if (childIndex > 0 && child instanceof ActionMenuChildView) {
-            result |= ((ActionMenuChildView) child).needsDividerBefore();
-        }
-        return result;
-    }
-
-    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
-        return false;
-    }
-
-    public interface ActionMenuChildView {
-        public boolean needsDividerBefore();
-        public boolean needsDividerAfter();
-    }
-
-    public static class LayoutParams extends LinearLayout.LayoutParams {
-        @ViewDebug.ExportedProperty(category = "layout")
-        public boolean isOverflowButton;
-        @ViewDebug.ExportedProperty(category = "layout")
-        public int cellsUsed;
-        @ViewDebug.ExportedProperty(category = "layout")
-        public int extraPixels;
-        @ViewDebug.ExportedProperty(category = "layout")
-        public boolean expandable;
-        @ViewDebug.ExportedProperty(category = "layout")
-        public boolean preventEdgeOffset;
-
-        public boolean expanded;
-
-        public LayoutParams(Context c, AttributeSet attrs) {
-            super(c, attrs);
-        }
-
-        public LayoutParams(ViewGroup.LayoutParams other) {
-            super(other);
-        }
-
-        public LayoutParams(LayoutParams other) {
-            super((LinearLayout.LayoutParams) other);
-            isOverflowButton = other.isOverflowButton;
-        }
-
-        public LayoutParams(int width, int height) {
-            super(width, height);
-            isOverflowButton = false;
-        }
-
-        public LayoutParams(int width, int height, boolean isOverflowButton) {
-            super(width, height);
-            this.isOverflowButton = isOverflowButton;
-        }
-    }
-}
diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java
index 5d0b25f..de5e279 100644
--- a/core/java/com/android/internal/view/menu/IconMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java
@@ -57,8 +57,8 @@
     
     private static String sPrependShortcutLabel;
 
-    public IconMenuItemView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs);
+    public IconMenuItemView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         if (sPrependShortcutLabel == null) {
             /*
@@ -68,10 +68,9 @@
             sPrependShortcutLabel = getResources().getString(
                     com.android.internal.R.string.prepend_shortcut_label);
         }
-        
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.MenuView, defStyleAttr, defStyleRes);
 
         mDisabledAlpha = a.getFloat(
                 com.android.internal.R.styleable.MenuView_itemIconDisabledAlpha, 0.8f);
@@ -81,7 +80,11 @@
         
         a.recycle();
     }
-    
+
+    public IconMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public IconMenuItemView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java
index a2a4acc..692bdac 100644
--- a/core/java/com/android/internal/view/menu/ListMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java
@@ -55,13 +55,13 @@
 
     private boolean mForceShowIcon;
 
-    public ListMenuItemView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs);
-    
-        TypedArray a =
-            context.obtainStyledAttributes(
-                attrs, com.android.internal.R.styleable.MenuView, defStyle, 0);
-        
+    public ListMenuItemView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, com.android.internal.R.styleable.MenuView, defStyleAttr, defStyleRes);
+
         mBackground = a.getDrawable(com.android.internal.R.styleable.MenuView_itemBackground);
         mTextAppearance = a.getResourceId(com.android.internal.R.styleable.
                                           MenuView_itemTextAppearance, -1);
@@ -72,6 +72,10 @@
         a.recycle();
     }
 
+    public ListMenuItemView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
     public ListMenuItemView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index e1bb3621..c476354 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -17,7 +17,6 @@
 package com.android.internal.view.menu;
 
 import android.content.Context;
-import android.database.DataSetObserver;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.util.SparseArray;
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 195a00d..b776226 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -919,7 +919,7 @@
      *            sub menu is about to be shown, <var>allMenusAreClosing</var>
      *            is false.
      */
-    final void close(boolean allMenusAreClosing) {
+    public final void close(boolean allMenusAreClosing) {
         if (mIsClosing) return;
 
         mIsClosing = true;
@@ -946,7 +946,7 @@
      *                         false if only item properties changed.
      *                         (Visibility is a structural property since it affects layout.)
      */
-    void onItemsChanged(boolean structureChanged) {
+    public void onItemsChanged(boolean structureChanged) {
         if (!mPreventDispatchingItemsChanged) {
             if (structureChanged) {
                 mIsVisibleItemsStale = true;
@@ -1000,7 +1000,7 @@
         onItemsChanged(true);
     }
     
-    ArrayList<MenuItemImpl> getVisibleItems() {
+    public ArrayList<MenuItemImpl> getVisibleItems() {
         if (!mIsVisibleItemsStale) return mVisibleItems;
         
         // Refresh the visible items
@@ -1085,12 +1085,12 @@
         mIsActionItemsStale = false;
     }
     
-    ArrayList<MenuItemImpl> getActionItems() {
+    public ArrayList<MenuItemImpl> getActionItems() {
         flagActionItems();
         return mActionItems;
     }
     
-    ArrayList<MenuItemImpl> getNonActionItems() {
+    public ArrayList<MenuItemImpl> getNonActionItems() {
         flagActionItems();
         return mNonActionItems;
     }
@@ -1121,7 +1121,7 @@
             }
             
             if (iconRes > 0) {
-                mHeaderIcon = r.getDrawable(iconRes);
+                mHeaderIcon = getContext().getDrawable(iconRes);
             } else if (icon != null) {
                 mHeaderIcon = icon;
             }
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 4d0a326..61dcaca 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -385,7 +385,7 @@
         }
 
         if (mIconResId != NO_ICON) {
-            Drawable icon =  mMenu.getResources().getDrawable(mIconResId);
+            Drawable icon =  mMenu.getContext().getDrawable(mIconResId);
             mIconResId = NO_ICON;
             mIconDrawable = icon;
             return icon;
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 05e9a66..d664058 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -23,7 +23,6 @@
 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;
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index f3891c7..183478f 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -16,8 +16,8 @@
 package com.android.internal.widget;
 
 import com.android.internal.R;
-import com.android.internal.view.menu.ActionMenuPresenter;
-import com.android.internal.view.menu.ActionMenuView;
+import android.widget.ActionMenuPresenter;
+import android.widget.ActionMenuView;
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
@@ -47,15 +47,20 @@
     private static final int FADE_DURATION = 200;
 
     public AbsActionBarView(Context context) {
-        super(context);
+        this(context, null);
     }
 
     public AbsActionBarView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public AbsActionBarView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public AbsActionBarView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AbsActionBarView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
@@ -95,9 +100,6 @@
 
     public void setContentHeight(int height) {
         mContentHeight = height;
-        if (mMenuView != null) {
-            mMenuView.setMaxItemHeight(mContentHeight);
-        }
         requestLayout();
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java
index 8a49899..c2d22dd 100644
--- a/core/java/com/android/internal/widget/ActionBarContainer.java
+++ b/core/java/com/android/internal/widget/ActionBarContainer.java
@@ -16,10 +16,10 @@
 
 package com.android.internal.widget;
 
-import android.app.ActionBar;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.graphics.ColorFilter;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.ActionMode;
@@ -51,7 +51,8 @@
     public ActionBarContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        setBackgroundDrawable(null);
+        // Set a transparent background so that we project appropriately.
+        setBackground(new ActionBarBackgroundDrawable());
 
         TypedArray a = context.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.ActionBar);
@@ -243,24 +244,6 @@
     }
 
     @Override
-    public void onDraw(Canvas canvas) {
-        if (getWidth() == 0 || getHeight() == 0) {
-            return;
-        }
-
-        if (mIsSplit) {
-            if (mSplitBackground != null) mSplitBackground.draw(canvas);
-        } else {
-            if (mBackground != null) {
-                mBackground.draw(canvas);
-            }
-            if (mStackedBackground != null && mIsStacked) {
-                mStackedBackground.draw(canvas);
-            }
-        }
-    }
-
-    @Override
     public ActionMode startActionModeForChild(View child, ActionMode.Callback callback) {
         // No starting an action mode for an action bar child! (Where would it go?)
         return null;
@@ -291,12 +274,13 @@
     public void onLayout(boolean changed, int l, int t, int r, int b) {
         super.onLayout(changed, l, t, r, b);
 
-        final boolean hasTabs = mTabContainer != null && mTabContainer.getVisibility() != GONE;
+        final View tabContainer = mTabContainer;
+        final boolean hasTabs = tabContainer != null && tabContainer.getVisibility() != GONE;
 
-        if (mTabContainer != null && mTabContainer.getVisibility() != GONE) {
+        if (tabContainer != null && tabContainer.getVisibility() != GONE) {
             final int containerHeight = getMeasuredHeight();
-            final int tabHeight = mTabContainer.getMeasuredHeight();
-            mTabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
+            final int tabHeight = tabContainer.getMeasuredHeight();
+            tabContainer.layout(l, containerHeight - tabHeight, r, containerHeight);
         }
 
         boolean needsInvalidate = false;
@@ -307,13 +291,15 @@
             }
         } else {
             if (mBackground != null) {
-                mBackground.setBounds(mActionBarView.getLeft(), mActionBarView.getTop(),
-                        mActionBarView.getRight(), mActionBarView.getBottom());
+                final ActionBarView actionBarView = mActionBarView;
+                mBackground.setBounds(actionBarView.getLeft(), actionBarView.getTop(),
+                        actionBarView.getRight(), actionBarView.getBottom());
                 needsInvalidate = true;
             }
-            if ((mIsStacked = hasTabs && mStackedBackground != null)) {
-                mStackedBackground.setBounds(mTabContainer.getLeft(), mTabContainer.getTop(),
-                        mTabContainer.getRight(), mTabContainer.getBottom());
+            mIsStacked = hasTabs;
+            if (hasTabs && mStackedBackground != null) {
+                mStackedBackground.setBounds(tabContainer.getLeft(), tabContainer.getTop(),
+                        tabContainer.getRight(), tabContainer.getBottom());
                 needsInvalidate = true;
             }
         }
@@ -322,4 +308,37 @@
             invalidate();
         }
     }
+
+    /**
+     * Dummy drawable so that we don't break background display lists and
+     * projection surfaces.
+     */
+    private class ActionBarBackgroundDrawable extends Drawable {
+        @Override
+        public void draw(Canvas canvas) {
+            if (mIsSplit) {
+                if (mSplitBackground != null) mSplitBackground.draw(canvas);
+            } else {
+                if (mBackground != null) {
+                    mBackground.draw(canvas);
+                }
+                if (mStackedBackground != null && mIsStacked) {
+                    mStackedBackground.draw(canvas);
+                }
+            }
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+        }
+
+        @Override
+        public int getOpacity() {
+            return 0;
+        }
+    }
 }
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 8bc1081..e10070f 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -16,8 +16,8 @@
 package com.android.internal.widget;
 
 import com.android.internal.R;
-import com.android.internal.view.menu.ActionMenuPresenter;
-import com.android.internal.view.menu.ActionMenuView;
+import android.widget.ActionMenuPresenter;
+import android.widget.ActionMenuView;
 import com.android.internal.view.menu.MenuBuilder;
 
 import android.animation.Animator;
@@ -25,7 +25,6 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
@@ -74,10 +73,16 @@
         this(context, attrs, com.android.internal.R.attr.actionModeStyle);
     }
     
-    public ActionBarContextView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActionMode, defStyle, 0);
+    public ActionBarContextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public ActionBarContextView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        final TypedArray a = context.obtainStyledAttributes(
+                attrs, R.styleable.ActionMode, defStyleAttr, defStyleRes);
         setBackgroundDrawable(a.getDrawable(
                 com.android.internal.R.styleable.ActionMode_background));
         mTitleStyleRes = a.getResourceId(
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 5469b63..adb9bf8 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -20,6 +20,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.view.ViewGroup;
+import android.view.WindowInsets;
 import com.android.internal.app.ActionBarImpl;
 
 import android.content.Context;
@@ -96,7 +97,7 @@
             if (mLastSystemUiVisibility != 0) {
                 int newVis = mLastSystemUiVisibility;
                 onWindowSystemUiVisibilityChanged(newVis);
-                requestFitSystemWindows();
+                requestApplyInsets();
             }
         }
     }
@@ -152,7 +153,7 @@
         }
         if ((diff&SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0) {
             if (mActionBar != null) {
-                requestFitSystemWindows();
+                requestApplyInsets();
             }
         }
     }
@@ -190,19 +191,20 @@
     }
 
     @Override
-    protected boolean fitSystemWindows(Rect insets) {
+    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
         pullChildren();
 
         final int vis = getWindowSystemUiVisibility();
         final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
+        final Rect systemInsets = insets.getSystemWindowInsets();
 
         // The top and bottom action bars are always within the content area.
-        boolean changed = applyInsets(mActionBarTop, insets, true, true, false, true);
+        boolean changed = applyInsets(mActionBarTop, systemInsets, true, true, false, true);
         if (mActionBarBottom != null) {
-            changed |= applyInsets(mActionBarBottom, insets, true, false, true, true);
+            changed |= applyInsets(mActionBarBottom, systemInsets, true, false, true, true);
         }
 
-        mBaseInnerInsets.set(insets);
+        mBaseInnerInsets.set(systemInsets);
         computeFitSystemWindows(mBaseInnerInsets, mBaseContentInsets);
         if (!mLastBaseContentInsets.equals(mBaseContentInsets)) {
             changed = true;
@@ -215,9 +217,9 @@
 
         // We don't do any more at this point.  To correctly compute the content/inner
         // insets in all cases, we need to know the measured size of the various action
-        // bar elements.  fitSystemWindows() happens before the measure pass, so we can't
+        // bar elements.  onApplyWindowInsets() happens before the measure pass, so we can't
         // do that here.  Instead we will take this up in onMeasure().
-        return true;
+        return WindowInsets.EMPTY;
     }
 
     @Override
@@ -284,7 +286,7 @@
                     topInset += mActionBarHeight;
                 }
             }
-        } else if (mActionBarTop.getVisibility() == VISIBLE) {
+        } else if (mActionBarTop.getVisibility() != GONE) {
             // This is the space needed on top of the window for all of the action bar
             // and tabs.
             topInset = mActionBarTop.getMeasuredHeight();
@@ -321,7 +323,7 @@
             // the app's fitSystemWindows().  We do this before measuring the content
             // view to keep the same semantics as the normal fitSystemWindows() call.
             mLastInnerInsets.set(mInnerInsets);
-            super.fitSystemWindows(mInnerInsets);
+            mContent.dispatchApplyWindowInsets(new WindowInsets(mInnerInsets));
         }
 
         measureChildWithMargins(mContent, widthMeasureSpec, 0, heightMeasureSpec, 0);
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 786f5cf..1273c4d 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -41,6 +41,8 @@
 import android.view.ViewParent;
 import android.view.Window;
 import android.view.accessibility.AccessibilityEvent;
+import android.widget.ActionMenuPresenter;
+import android.widget.ActionMenuView;
 import android.widget.AdapterView;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -52,8 +54,6 @@
 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;
@@ -430,6 +430,7 @@
             mActionMenuPresenter.setItemLimit(Integer.MAX_VALUE);
             // Span the whole width
             layoutParams.width = LayoutParams.MATCH_PARENT;
+            layoutParams.height = mContentHeight;
             configPresenters(builder);
             menuView = (ActionMenuView) mActionMenuPresenter.getMenuView(this);
             if (mSplitView != null) {
@@ -696,7 +697,7 @@
     }
 
     public void setIcon(int resId) {
-        setIcon(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+        setIcon(resId != 0 ? mContext.getDrawable(resId) : null);
     }
 
     public boolean hasIcon() {
@@ -711,7 +712,7 @@
     }
 
     public void setLogo(int resId) {
-        setLogo(resId != 0 ? mContext.getResources().getDrawable(resId) : null);
+        setLogo(resId != 0 ? mContext.getDrawable(resId) : null);
     }
 
     public boolean hasLogo() {
@@ -1416,7 +1417,7 @@
 
         public void setUpIndicator(int resId) {
             mUpIndicatorRes = resId;
-            mUpView.setImageDrawable(resId != 0 ? getResources().getDrawable(resId) : null);
+            mUpView.setImageDrawable(resId != 0 ? getContext().getDrawable(resId) : null);
         }
 
         @Override
diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java
index b86c438..7ea3d6b 100644
--- a/core/java/com/android/internal/widget/DialogTitle.java
+++ b/core/java/com/android/internal/widget/DialogTitle.java
@@ -28,10 +28,13 @@
  * the text to the available space.
  */
 public class DialogTitle extends TextView {
-    
-    public DialogTitle(Context context, AttributeSet attrs,
-            int defStyle) {
-        super(context, attrs, defStyle);
+
+    public DialogTitle(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    public DialogTitle(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
     }
 
     public DialogTitle(Context context, AttributeSet attrs) {
diff --git a/core/java/com/android/internal/widget/FaceUnlockView.java b/core/java/com/android/internal/widget/FaceUnlockView.java
index e3c1247..121e601 100644
--- a/core/java/com/android/internal/widget/FaceUnlockView.java
+++ b/core/java/com/android/internal/widget/FaceUnlockView.java
@@ -18,8 +18,6 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
 import android.widget.RelativeLayout;
 
 public class FaceUnlockView extends RelativeLayout {
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 91056f1..9501f92 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -28,6 +28,7 @@
     boolean checkPattern(in String pattern, int userId);
     void setLockPassword(in String password, int userId);
     boolean checkPassword(in String password, int userId);
+    boolean checkVoldPassword(int userId);
     boolean havePattern(int userId);
     boolean havePassword(int userId);
     void removeUser(int userId);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 8602260..e5aaf7e 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -24,13 +24,13 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.storage.IMountService;
+import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -313,6 +313,20 @@
     }
 
     /**
+     * Check to see if vold already has the password.
+     * Note that this also clears vold's copy of the password.
+     * @return Whether the vold password matches or not.
+     */
+    public boolean checkVoldPassword() {
+        final int userId = getCurrentOrCallingUserId();
+        try {
+            return getLockSettings().checkVoldPassword(userId);
+        } catch (RemoteException re) {
+            return false;
+        }
+    }
+
+    /**
      * Check to see if a password matches any of the passwords stored in the
      * password history.
      *
@@ -499,6 +513,13 @@
             getLockSettings().setLockPattern(patternToString(pattern), getCurrentOrCallingUserId());
             DevicePolicyManager dpm = getDevicePolicyManager();
             if (pattern != null) {
+
+                int userHandle = getCurrentOrCallingUserId();
+                if (userHandle == UserHandle.USER_OWNER) {
+                    String stringPattern = patternToString(pattern);
+                    updateEncryptionPassword(StorageManager.CRYPT_TYPE_PATTERN, stringPattern);
+                }
+
                 setBoolean(PATTERN_EVER_CHOSEN_KEY, true);
                 if (!isFallback) {
                     deleteGallery();
@@ -566,7 +587,7 @@
     }
 
     /** Update the encryption password if it is enabled **/
-    private void updateEncryptionPassword(String password) {
+    private void updateEncryptionPassword(int type, String password) {
         DevicePolicyManager dpm = getDevicePolicyManager();
         if (dpm.getStorageEncryptionStatus(getCurrentOrCallingUserId())
                 != DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE) {
@@ -581,7 +602,7 @@
 
         IMountService mountService = IMountService.Stub.asInterface(service);
         try {
-            mountService.changeEncryptionPassword(password);
+            mountService.changeEncryptionPassword(type, password);
         } catch (RemoteException e) {
             Log.e(TAG, "Error changing encryption password", e);
         }
@@ -624,12 +645,15 @@
             getLockSettings().setLockPassword(password, userHandle);
             DevicePolicyManager dpm = getDevicePolicyManager();
             if (password != null) {
+                int computedQuality = computePasswordQuality(password);
+
                 if (userHandle == UserHandle.USER_OWNER) {
                     // Update the encryption password.
-                    updateEncryptionPassword(password);
+                    int type = computedQuality == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+                        ? StorageManager.CRYPT_TYPE_PIN : StorageManager.CRYPT_TYPE_PASSWORD;
+                    updateEncryptionPassword(type, password);
                 }
 
-                int computedQuality = computePasswordQuality(password);
                 if (!isFallback) {
                     deleteGallery();
                     setLong(PASSWORD_TYPE_KEY, Math.max(quality, computedQuality), userHandle);
@@ -676,8 +700,7 @@
                             0, 0, 0, 0, 0, 0, 0, userHandle);
                 }
                 // Add the password to the password history. We assume all
-                // password
-                // hashes have the same length for simplicity of implementation.
+                // password hashes have the same length for simplicity of implementation.
                 String passwordHistory = getString(PASSWORD_HISTORY_KEY, userHandle);
                 if (passwordHistory == null) {
                     passwordHistory = new String();
@@ -696,6 +719,11 @@
                 }
                 setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
             } else {
+                if (userHandle == UserHandle.USER_OWNER) {
+                    // Update the encryption password.
+                    updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, password);
+                }
+
                 dpm.setActivePasswordState(
                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 0, 0, 0, 0, 0, 0, 0,
                         userHandle);
@@ -1201,7 +1229,7 @@
 
     private void setLong(String secureSettingKey, long value, int userHandle) {
         try {
-            getLockSettings().setLong(secureSettingKey, value, getCurrentOrCallingUserId());
+            getLockSettings().setLong(secureSettingKey, value, userHandle);
         } catch (RemoteException re) {
             // What can we do?
             Log.e(TAG, "Couldn't write long " + secureSettingKey + re);
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index b066d70..26cb4e5 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -868,12 +868,10 @@
 
         // TODO: the path should be created and cached every time we hit-detect a cell
         // only the last segment of the path should be computed here
-        // draw the path of the pattern (unless the user is in progress, and
-        // we are in stealth mode)
-        final boolean drawPath = (!mInStealthMode || mPatternDisplayMode == DisplayMode.Wrong);
+        // draw the path of the pattern (unless we are in stealth mode)
+        final boolean drawPath = !mInStealthMode;
 
-        // draw the arrows associated with the path (unless the user is in progress, and
-        // we are in stealth mode)
+        // draw the arrows associated with the path (unless we are in stealth mode)
         boolean oldFlag = (mPaint.getFlags() & Paint.FILTER_BITMAP_FLAG) != 0;
         mPaint.setFilterBitmap(true); // draw with higher quality since we render with transforms
         if (drawPath) {
@@ -974,7 +972,7 @@
         Bitmap outerCircle;
         Bitmap innerCircle;
 
-        if (!partOfPattern || (mInStealthMode && mPatternDisplayMode != DisplayMode.Wrong)) {
+        if (!partOfPattern || mInStealthMode) {
             // unselected circle
             outerCircle = mBitmapCircleDefault;
             innerCircle = mBitmapBtnDefault;
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index 3c01c69..7483e75 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.widget;
 
-import java.util.Locale;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
@@ -73,8 +72,8 @@
 
     private void init(Context context) {
         final Resources res = context.getResources();
-        mShiftIcon = res.getDrawable(R.drawable.sym_keyboard_shift);
-        mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
+        mShiftIcon = context.getDrawable(R.drawable.sym_keyboard_shift);
+        mShiftLockIcon = context.getDrawable(R.drawable.sym_keyboard_shift_locked);
         sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
                 R.dimen.password_keyboard_spacebar_vertical_correction);
     }
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index a3df291..b2c9dc5 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -21,9 +21,7 @@
 import android.inputmethodservice.Keyboard;
 import android.inputmethodservice.KeyboardView;
 import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
-import android.os.Handler;
 import android.os.SystemClock;
-import android.os.Vibrator;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.HapticFeedbackConstants;
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
index b37adff..d27346b 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
@@ -29,11 +29,16 @@
     static final int KEYCODE_NEXT_LANGUAGE = -104;
 
     public PasswordEntryKeyboardView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+        this(context, attrs, 0);
     }
 
-    public PasswordEntryKeyboardView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public PasswordEntryKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PasswordEntryKeyboardView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index d82831f..e339c44 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -31,11 +31,13 @@
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.WindowManagerPolicy.PointerEventListener;
 import android.view.MotionEvent.PointerCoords;
 
 import java.util.ArrayList;
 
-public class PointerLocationView extends View implements InputDeviceListener {
+public class PointerLocationView extends View implements InputDeviceListener,
+        PointerEventListener {
     private static final String TAG = "Pointer";
 
     // The system property key used to specify an alternate velocity tracker strategy
@@ -520,7 +522,8 @@
                 .toString());
     }
 
-    public void addPointerEvent(MotionEvent event) {
+    @Override
+    public void onPointerEvent(MotionEvent event) {
         final int action = event.getAction();
         int NP = mPointers.size();
 
@@ -648,7 +651,7 @@
     
     @Override
     public boolean onTouchEvent(MotionEvent event) {
-        addPointerEvent(event);
+        onPointerEvent(event);
 
         if (event.getAction() == MotionEvent.ACTION_DOWN && !isFocused()) {
             requestFocus();
@@ -660,7 +663,7 @@
     public boolean onGenericMotionEvent(MotionEvent event) {
         final int source = event.getSource();
         if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            addPointerEvent(event);
+            onPointerEvent(event);
         } else if ((source & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
             logMotionEvent("Joystick", event);
         } else if ((source & InputDevice.SOURCE_CLASS_POSITION) != 0) {
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index 4e405f4..64ce918 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -24,7 +24,7 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Matrix;
-import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
@@ -35,7 +35,9 @@
 import android.view.VelocityTracker;
 import android.view.ViewConfiguration;
 import android.view.animation.DecelerateInterpolator;
+
 import static android.view.animation.AnimationUtils.currentAnimationTimeMillis;
+
 import com.android.internal.R;
 
 
@@ -677,7 +679,7 @@
                 mVibrator = (android.os.Vibrator) getContext()
                         .getSystemService(Context.VIBRATOR_SERVICE);
             }
-            mVibrator.vibrate(duration);
+            mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/ScrollingTabContainerView.java b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
index fa29e6e1..d6bd1d6f 100644
--- a/core/java/com/android/internal/widget/ScrollingTabContainerView.java
+++ b/core/java/com/android/internal/widget/ScrollingTabContainerView.java
@@ -23,7 +23,6 @@
 import android.app.ActionBar;
 import android.content.Context;
 import android.content.res.Configuration;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.text.TextUtils.TruncateAt;
diff --git a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
index ba113a3..961e471 100644
--- a/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
+++ b/core/java/com/android/internal/widget/SizeAdaptiveLayout.java
@@ -79,17 +79,20 @@
     private int mModestyPanelTop;
 
     public SizeAdaptiveLayout(Context context) {
-        super(context);
-        initialize();
+        this(context, null);
     }
 
     public SizeAdaptiveLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        initialize();
+        this(context, attrs, 0);
     }
 
-    public SizeAdaptiveLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public SizeAdaptiveLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SizeAdaptiveLayout(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
         initialize();
     }
 
@@ -151,6 +154,10 @@
         if (DEBUG) Log.d(TAG, this + " measure spec: " +
                          MeasureSpec.toString(heightMeasureSpec));
         View model = selectActiveChild(heightMeasureSpec);
+        if (model == null) {
+            setMeasuredDimension(0, 0);
+            return;
+        }
         SizeAdaptiveLayout.LayoutParams lp =
           (SizeAdaptiveLayout.LayoutParams) model.getLayoutParams();
         if (DEBUG) Log.d(TAG, "active min: " + lp.minHeight + " max: " + lp.maxHeight);
@@ -239,6 +246,8 @@
         int measureSpec = View.MeasureSpec.makeMeasureSpec(bottom - top,
                                                            View.MeasureSpec.EXACTLY);
         mActiveChild = selectActiveChild(measureSpec);
+        if (mActiveChild == null) return;
+
         mActiveChild.setVisibility(View.VISIBLE);
 
         if (mLastActive != mActiveChild && mLastActive != null) {
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index aebc4f6..deb0fd7 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -21,6 +21,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
@@ -821,7 +822,7 @@
                 mVibrator = (android.os.Vibrator) getContext()
                         .getSystemService(Context.VIBRATOR_SERVICE);
             }
-            mVibrator.vibrate(duration);
+            mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/SubtitleView.java b/core/java/com/android/internal/widget/SubtitleView.java
index 071193c..117463a 100644
--- a/core/java/com/android/internal/widget/SubtitleView.java
+++ b/core/java/com/android/internal/widget/SubtitleView.java
@@ -18,7 +18,6 @@
 
 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;
@@ -33,7 +32,6 @@
 import android.text.TextPaint;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
-import android.util.TypedValue;
 import android.view.View;
 import android.view.accessibility.CaptioningManager.CaptionStyle;
 
@@ -41,6 +39,12 @@
     // Ratio of inner padding to font size.
     private static final float INNER_PADDING_RATIO = 0.125f;
 
+    /** Color used for the shadowed edge of a bevel. */
+    private static final int COLOR_BEVEL_DARK = 0x80000000;
+
+    /** Color used for the illuminated edge of a bevel. */
+    private static final int COLOR_BEVEL_LIGHT = 0x80FFFFFF;
+
     // Styled dimensions.
     private final float mCornerRadius;
     private final float mOutlineWidth;
@@ -79,12 +83,15 @@
         this(context, attrs, 0);
     }
 
-    public SubtitleView(Context context, AttributeSet attrs, int defStyle) {
+    public SubtitleView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public SubtitleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs);
 
-        final Theme theme = context.getTheme();
-        final TypedArray a = theme.obtainStyledAttributes(
-                    attrs, android.R.styleable.TextView, defStyle, 0);
+        final TypedArray a = context.obtainStyledAttributes(
+                    attrs, android.R.styleable.TextView, defStyleAttr, defStyleRes);
 
         CharSequence text = "";
         int textSize = 15;
@@ -112,7 +119,6 @@
         // Set up density-dependent properties.
         // TODO: Move these to a default style.
         final Resources res = getContext().getResources();
-        final DisplayMetrics m = res.getDisplayMetrics();
         mCornerRadius = res.getDimensionPixelSize(com.android.internal.R.dimen.subtitle_corner_radius);
         mOutlineWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.subtitle_outline_width);
         mShadowRadius = res.getDimensionPixelSize(com.android.internal.R.dimen.subtitle_shadow_radius);
@@ -311,7 +317,8 @@
             }
         }
 
-        if (mEdgeType == CaptionStyle.EDGE_TYPE_OUTLINE) {
+        final int edgeType = mEdgeType;
+        if (edgeType == CaptionStyle.EDGE_TYPE_OUTLINE) {
             textPaint.setStrokeJoin(Join.ROUND);
             textPaint.setStrokeWidth(mOutlineWidth);
             textPaint.setColor(mEdgeColor);
@@ -320,8 +327,24 @@
             for (int i = 0; i < lineCount; i++) {
                 layout.drawText(c, i, i);
             }
-        } else if (mEdgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
+        } else if (edgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
             textPaint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mEdgeColor);
+        } else if (edgeType == CaptionStyle.EDGE_TYPE_RAISED
+                || edgeType == CaptionStyle.EDGE_TYPE_DEPRESSED) {
+            final boolean raised = edgeType == CaptionStyle.EDGE_TYPE_RAISED;
+            final int colorUp = raised ? Color.WHITE : mEdgeColor;
+            final int colorDown = raised ? mEdgeColor : Color.WHITE;
+            final float offset = mShadowRadius / 2f;
+
+            textPaint.setColor(mForegroundColor);
+            textPaint.setStyle(Style.FILL);
+            textPaint.setShadowLayer(mShadowRadius, -offset, -offset, colorUp);
+
+            for (int i = 0; i < lineCount; i++) {
+                layout.drawText(c, i, i);
+            }
+
+            textPaint.setShadowLayer(mShadowRadius, offset, offset, colorDown);
         }
 
         textPaint.setColor(mForegroundColor);
diff --git a/core/java/com/android/internal/widget/TextProgressBar.java b/core/java/com/android/internal/widget/TextProgressBar.java
index e898aa4..7ca07d4 100644
--- a/core/java/com/android/internal/widget/TextProgressBar.java
+++ b/core/java/com/android/internal/widget/TextProgressBar.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.os.SystemClock;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -59,9 +58,13 @@
 
     boolean mChronometerFollow = false;
     int mChronometerGravity = Gravity.NO_GRAVITY;
+
+    public TextProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
     
-    public TextProgressBar(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public TextProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
     }
 
     public TextProgressBar(Context context, AttributeSet attrs) {
diff --git a/core/java/com/android/internal/widget/WaveView.java b/core/java/com/android/internal/widget/WaveView.java
index d33d50c..86f14b3 100644
--- a/core/java/com/android/internal/widget/WaveView.java
+++ b/core/java/com/android/internal/widget/WaveView.java
@@ -25,10 +25,10 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
+import android.media.AudioManager;
 import android.os.UserHandle;
 import android.os.Vibrator;
 import android.provider.Settings;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -583,7 +583,7 @@
                 mVibrator = (android.os.Vibrator) getContext()
                         .getSystemService(Context.VIBRATOR_SERVICE);
             }
-            mVibrator.vibrate(duration);
+            mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
index cd1ccd3..772dc5f 100644
--- a/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/GlowPadView.java
@@ -30,6 +30,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.Vibrator;
@@ -234,7 +235,7 @@
         mMagneticTargets = a.getBoolean(R.styleable.GlowPadView_magneticTargets, mMagneticTargets);
 
         int pointId = getResourceId(a, R.styleable.GlowPadView_pointDrawable);
-        Drawable pointDrawable = pointId != 0 ? res.getDrawable(pointId) : null;
+        Drawable pointDrawable = pointId != 0 ? context.getDrawable(pointId) : null;
         mGlowRadius = a.getDimension(R.styleable.GlowPadView_glowRadius, 0.0f);
 
         TypedValue outValue = new TypedValue();
@@ -564,7 +565,7 @@
                 mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
                 UserHandle.USER_CURRENT) != 0;
         if (mVibrator != null && hapticEnabled) {
-            mVibrator.vibrate(mVibrationDuration);
+            mVibrator.vibrate(mVibrationDuration, AudioManager.STREAM_SYSTEM);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index e22d1e8..4648f39 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -31,6 +31,7 @@
 import android.graphics.Canvas;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.Vibrator;
@@ -599,7 +600,7 @@
                 mContext.getContentResolver(), Settings.System.HAPTIC_FEEDBACK_ENABLED, 1,
                 UserHandle.USER_CURRENT) != 0;
         if (mVibrator != null && hapticEnabled) {
-            mVibrator.vibrate(mVibrationDuration);
+            mVibrator.vibrate(mVibrationDuration, AudioManager.STREAM_SYSTEM);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
index 16bec16..5a4c441 100644
--- a/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
+++ b/core/java/com/android/internal/widget/multiwaveview/TargetDrawable.java
@@ -18,7 +18,6 @@
 
 import android.content.res.Resources;
 import android.graphics.Canvas;
-import android.graphics.ColorFilter;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
 import android.util.Log;
diff --git a/core/java/com/android/server/AppWidgetBackupBridge.java b/core/java/com/android/server/AppWidgetBackupBridge.java
new file mode 100644
index 0000000..2ea2f79
--- /dev/null
+++ b/core/java/com/android/server/AppWidgetBackupBridge.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import java.util.List;
+
+/**
+ * Runtime bridge between the Backup Manager Service and the App Widget Service,
+ * since those two modules are intentionally decoupled for modularity.
+ *
+ * @hide
+ */
+public class AppWidgetBackupBridge {
+    private static WidgetBackupProvider sAppWidgetService;
+
+    public static void register(WidgetBackupProvider instance) {
+        sAppWidgetService = instance;
+    }
+
+    public static List<String> getWidgetParticipants(int userId) {
+        return (sAppWidgetService != null)
+                ? sAppWidgetService.getWidgetParticipants(userId)
+                : null;
+    }
+
+    public static byte[] getWidgetState(String packageName, int userId) {
+        return (sAppWidgetService != null)
+                ? sAppWidgetService.getWidgetState(packageName, userId)
+                : null;
+    }
+
+    public static void restoreStarting(int userId) {
+        if (sAppWidgetService != null) {
+            sAppWidgetService.restoreStarting(userId);
+        }
+    }
+
+    public static void restoreWidgetState(String packageName, byte[] restoredState, int userId) {
+        if (sAppWidgetService != null) {
+            sAppWidgetService.restoreWidgetState(packageName, restoredState, userId);
+        }
+    }
+
+    public static void restoreFinished(int userId) {
+        if (sAppWidgetService != null) {
+            sAppWidgetService.restoreFinished(userId);
+        }
+    }
+}
diff --git a/core/java/com/android/server/WidgetBackupProvider.java b/core/java/com/android/server/WidgetBackupProvider.java
new file mode 100644
index 0000000..a2efbdd
--- /dev/null
+++ b/core/java/com/android/server/WidgetBackupProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import java.util.List;
+
+/**
+ * Shim to allow core/backup to communicate with the app widget service
+ * about various important events without needing to be able to see the
+ * implementation of the service.
+ *
+ * @hide
+ */
+public interface WidgetBackupProvider {
+    public List<String> getWidgetParticipants(int userId);
+    public byte[] getWidgetState(String packageName, int userId);
+    public void restoreStarting(int userId);
+    public void restoreWidgetState(String packageName, byte[] restoredState, int userId);
+    public void restoreFinished(int userId);
+}
diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java
index 5502a17..430dd63 100644
--- a/core/java/com/android/server/net/BaseNetworkObserver.java
+++ b/core/java/com/android/server/net/BaseNetworkObserver.java
@@ -57,7 +57,7 @@
     }
 
     @Override
-    public void interfaceClassDataActivityChanged(String label, boolean active) {
+    public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
         // default no-op
     }
 
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index ac70738..51c5a86 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -53,12 +53,14 @@
 	android_view_InputQueue.cpp \
 	android_view_KeyEvent.cpp \
 	android_view_KeyCharacterMap.cpp \
-	android_view_HardwareRenderer.cpp \
 	android_view_GraphicBuffer.cpp \
-	android_view_GLES20DisplayList.cpp \
+	android_view_GLRenderer.cpp \
 	android_view_GLES20Canvas.cpp \
+	android_view_HardwareLayer.cpp \
+	android_view_ThreadedRenderer.cpp \
 	android_view_MotionEvent.cpp \
 	android_view_PointerIcon.cpp \
+	android_view_RenderNode.cpp \
 	android_view_VelocityTracker.cpp \
 	android_text_AndroidCharacter.cpp \
 	android_text_AndroidBidi.cpp \
@@ -74,7 +76,6 @@
 	android_net_LocalSocketImpl.cpp \
 	android_net_NetUtils.cpp \
 	android_net_TrafficStats.cpp \
-	android_net_wifi_WifiNative.cpp \
 	android_nio_utils.cpp \
 	android_text_format_Time.cpp \
 	android_util_AssetManager.cpp \
@@ -117,6 +118,7 @@
 	android/graphics/TextLayout.cpp \
 	android/graphics/TextLayoutCache.cpp \
 	android/graphics/Typeface.cpp \
+	android/graphics/TypefaceImpl.cpp \
 	android/graphics/Utils.cpp \
 	android/graphics/Xfermode.cpp \
 	android/graphics/YuvToJpegEncoder.cpp \
@@ -162,9 +164,8 @@
 	$(TOP)/frameworks/av/include \
 	$(TOP)/system/media/camera/include \
 	external/skia/src/core \
-	external/skia/src/pdf \
+	external/skia/src/effects \
 	external/skia/src/images \
-	external/skia/include/utils \
 	external/sqlite/dist \
 	external/sqlite/android \
 	external/expat/lib \
@@ -191,6 +192,7 @@
 	libui \
 	libgui \
 	libinput \
+	libinputflinger \
 	libcamera_client \
 	libcamera_metadata \
 	libskia \
@@ -217,6 +219,16 @@
 	LOCAL_SHARED_LIBRARIES += libhwui
 endif
 
+ifeq ($(USE_MINIKIN), true)
+	LOCAL_CFLAGS += -DUSE_MINIKIN
+	LOCAL_C_INCLUDES += frameworks/minikin/include \
+		external/freetype/include
+	LOCAL_SRC_FILES += 	android/graphics/MinikinSkia.cpp
+# note: the freetype include is spurious; minikin itself probably
+# shouldn't depend on it
+	LOCAL_SHARED_LIBRARIES += libminikin libstlport
+endif
+
 LOCAL_SHARED_LIBRARIES += \
 	libdl
 # we need to access the private Bionic header
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 649968e..9a7a5f9 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -119,10 +119,12 @@
 extern int register_android_graphics_Xfermode(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
+extern int register_android_view_RenderNode(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);
+extern int register_android_view_GLRenderer(JNIEnv* env);
+extern int register_android_view_HardwareLayer(JNIEnv* env);
+extern int register_android_view_ThreadedRenderer(JNIEnv* env);
 extern int register_android_view_Surface(JNIEnv* env);
 extern int register_android_view_SurfaceControl(JNIEnv* env);
 extern int register_android_view_SurfaceSession(JNIEnv* env);
@@ -146,7 +148,6 @@
 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_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);
@@ -1086,7 +1087,8 @@
     void** args = (void**) malloc(3 * sizeof(void*));   // javaThreadShell must free
     int result;
 
-    assert(threadName != NULL);
+    if (!threadName)
+        threadName = "unnamed thread";
 
     args[0] = (void*) entryFunction;
     args[1] = userData;
@@ -1174,13 +1176,15 @@
     REG_JNI(register_android_os_SystemProperties),
     REG_JNI(register_android_os_Binder),
     REG_JNI(register_android_os_Parcel),
-    REG_JNI(register_android_view_DisplayEventReceiver),
     REG_JNI(register_android_nio_utils),
     REG_JNI(register_android_graphics_Graphics),
+    REG_JNI(register_android_view_DisplayEventReceiver),
+    REG_JNI(register_android_view_RenderNode),
     REG_JNI(register_android_view_GraphicBuffer),
-    REG_JNI(register_android_view_GLES20DisplayList),
     REG_JNI(register_android_view_GLES20Canvas),
-    REG_JNI(register_android_view_HardwareRenderer),
+    REG_JNI(register_android_view_GLRenderer),
+    REG_JNI(register_android_view_HardwareLayer),
+    REG_JNI(register_android_view_ThreadedRenderer),
     REG_JNI(register_android_view_Surface),
     REG_JNI(register_android_view_SurfaceControl),
     REG_JNI(register_android_view_SurfaceSession),
@@ -1238,7 +1242,6 @@
     REG_JNI(register_android_net_LocalSocketImpl),
     REG_JNI(register_android_net_NetworkUtils),
     REG_JNI(register_android_net_TrafficStats),
-    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),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index d97a945..310966c 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -627,7 +627,7 @@
     }

 

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

-            GraphicsJNI::kBitmapCreateFlag_Mutable, NULL, NULL);

+            getPremulBitmapCreateFlags(true), NULL, NULL);

 }

 

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

diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index fc587c0..2b9a5c4 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -115,7 +115,7 @@
         }
     }
 
-    int32_t* yDivs = chunk->getXDivs();
+    int32_t* yDivs = chunk->getYDivs();
     for (int i = 0; i < chunk->numYDivs; i++) {
         yDivs[i] = int32_t(yDivs[i] * scale + 0.5f);
         if (i > 0 && yDivs[i] == yDivs[i - 1]) {
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 0d67b07..098643b 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -107,7 +107,7 @@
         For now we just always copy the array's data if isShareable.
      */
     AutoJavaByteArray ar(env, byteArray);
-    SkStreamRewindable* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
+    SkMemoryStream* stream = new SkMemoryStream(ar.ptr() + offset, length, true);
 
     jobject brd = createBitmapRegionDecoder(env, stream);
     SkSafeUnref(stream); // the decoder now holds a reference
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index f6ab39c..7420055 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -27,8 +27,14 @@
 #include "SkShader.h"
 #include "SkTemplates.h"
 
+#ifdef USE_MINIKIN
+#include <minikin/Layout.h>
+#include "MinikinSkia.h"
+#endif
+
 #include "TextLayout.h"
 #include "TextLayoutCache.h"
+#include "TypefaceImpl.h"
 
 #include "unicode/ubidi.h"
 #include "unicode/ushape.h"
@@ -833,39 +839,89 @@
     }
 
 
-    static void drawText___CIIFFIPaint(JNIEnv* env, jobject, jlong canvasHandle,
-                                      jcharArray text, jint index, jint count,
-                                      jfloat x, jfloat y, jint flags, jlong paintHandle) {
+    static void drawText___CIIFFIPaintTypeface(JNIEnv* env, jobject, jlong canvasHandle,
+                                               jcharArray text, jint index, jint count,
+                                               jfloat x, jfloat y, jint flags,
+                                               jlong paintHandle, jlong typefaceHandle) {
         SkCanvas* canvas = reinterpret_cast<SkCanvas*>(canvasHandle);
         SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
         jchar* textArray = env->GetCharArrayElements(text, NULL);
-        drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint);
+        drawTextWithGlyphs(canvas, textArray + index, 0, count, x, y, flags, paint, typeface);
         env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
     }
 
-    static void drawText__StringIIFFIPaint(JNIEnv* env, jobject,
-                                          jlong canvasHandle, jstring text,
-                                          jint start, jint end,
-                                          jfloat x, jfloat y, jint flags, jlong paintHandle) {
+    static void drawText__StringIIFFIPaintTypeface(JNIEnv* env, jobject,
+                                                   jlong canvasHandle, jstring text,
+                                                   jint start, jint end,
+                                                   jfloat x, jfloat y, jint flags,
+                                                   jlong paintHandle, jlong typefaceHandle) {
         SkCanvas* canvas = reinterpret_cast<SkCanvas*>(canvasHandle);
         SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
         const jchar* textArray = env->GetStringChars(text, NULL);
-        drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint);
+        drawTextWithGlyphs(canvas, textArray, start, end, x, y, flags, paint, typeface);
         env->ReleaseStringChars(text, textArray);
     }
 
+#ifdef USE_MINIKIN
+    static void drawGlyphsToSkia(SkCanvas *canvas, SkPaint *paint, Layout *layout, float x, float y) {
+        size_t nGlyphs = layout->nGlyphs();
+        uint16_t *glyphs = new uint16_t[nGlyphs];
+        SkPoint *pos = new SkPoint[nGlyphs];
+        SkTypeface *lastFace = NULL;
+        SkTypeface *skFace = NULL;
+        size_t start = 0;
+
+        paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+        for (size_t i = 0; i < nGlyphs; i++) {
+            MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i));
+            skFace = mfs->GetSkTypeface();
+            glyphs[i] = layout->getGlyphId(i);
+            pos[i].fX = SkFloatToScalar(x + layout->getX(i));
+            pos[i].fY = SkFloatToScalar(y + layout->getY(i));
+            if (i > 0 && skFace != lastFace) {
+                paint->setTypeface(lastFace);
+                canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint);
+                start = i;
+            }
+            lastFace = skFace;
+        }
+        if (skFace != NULL) {
+            paint->setTypeface(skFace);
+            canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint);
+        }
+        delete[] glyphs;
+        delete[] pos;
+    }
+#endif
+
     static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
             int start, int end,
-            jfloat x, jfloat y, int flags, SkPaint* paint) {
+            jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
 
         jint count = end - start;
-        drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint);
+        drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint, typeface);
     }
 
     static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray,
             int start, int count, int contextCount,
-            jfloat x, jfloat y, int flags, SkPaint* paint) {
+            jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
 
+#ifdef USE_MINIKIN
+        Layout layout;
+        TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
+        layout.setFontCollection(resolvedFace->fFontCollection);
+        FontStyle style = resolvedFace->fStyle;
+        char css[256];
+        sprintf(css, "font-size: %d; font-weight: %d; font-style: %s",
+            (int)paint->getTextSize(),
+            style.getWeight() * 100,
+            style.getItalic() ? "italic" : "normal");
+        layout.setProperties(css);
+        layout.doLayout(textArray + start, count);
+        drawGlyphsToSkia(canvas, paint, &layout, x, y);
+#else
         sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
                 textArray, start, count, contextCount, flags);
         if (value == NULL) {
@@ -881,6 +937,7 @@
         doDrawGlyphsPos(canvas, value->getGlyphs(), value->getPos(), 0, value->getGlyphsCount(), x, y, flags, paint);
         doDrawTextDecorations(canvas, x, y, value->getTotalAdvance(), paint);
         paint->setTextAlign(align);
+#endif
     }
 
 // Same values used by Skia
@@ -937,31 +994,33 @@
         delete[] posPtr;
     }
 
-    static void drawTextRun___CIIIIFFIPaint(
+    static void drawTextRun___CIIIIFFIPaintTypeface(
         JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index,
         jint count, jint contextIndex, jint contextCount,
-        jfloat x, jfloat y, jint dirFlags, jlong paintHandle) {
+        jfloat x, jfloat y, jint dirFlags, jlong paintHandle, jlong typefaceHandle) {
         SkCanvas* canvas = reinterpret_cast<SkCanvas*>(canvasHandle);
         SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
 
         jchar* chars = env->GetCharArrayElements(text, NULL);
         drawTextWithGlyphs(canvas, chars + contextIndex, index - contextIndex,
-                count, contextCount, x, y, dirFlags, paint);
+                count, contextCount, x, y, dirFlags, paint, typeface);
         env->ReleaseCharArrayElements(text, chars, JNI_ABORT);
     }
 
-    static void drawTextRun__StringIIIIFFIPaint(
+    static void drawTextRun__StringIIIIFFIPaintTypeface(
         JNIEnv* env, jobject obj, jlong canvasHandle, jstring text, jint start,
         jint end, jint contextStart, jint contextEnd,
-        jfloat x, jfloat y, jint dirFlags, jlong paintHandle) {
+        jfloat x, jfloat y, jint dirFlags, jlong paintHandle, jlong typefaceHandle) {
         SkCanvas* canvas = reinterpret_cast<SkCanvas*>(canvasHandle);
         SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
 
         jint count = end - start;
         jint contextCount = contextEnd - contextStart;
         const jchar* chars = env->GetStringChars(text, NULL);
         drawTextWithGlyphs(canvas, chars + contextStart, start - contextStart,
-                count, contextCount, x, y, dirFlags, paint);
+                count, contextCount, x, y, dirFlags, paint, typeface);
         env->ReleaseStringChars(text, chars);
     }
 
@@ -1182,14 +1241,14 @@
         (void*)SkCanvasGlue::drawBitmapMesh},
     {"nativeDrawVertices", "(JII[FI[FI[II[SIIJ)V",
         (void*)SkCanvasGlue::drawVertices},
-    {"native_drawText","(J[CIIFFIJ)V",
-        (void*) SkCanvasGlue::drawText___CIIFFIPaint},
-    {"native_drawText","(JLjava/lang/String;IIFFIJ)V",
-        (void*) SkCanvasGlue::drawText__StringIIFFIPaint},
-    {"native_drawTextRun","(J[CIIIIFFIJ)V",
-        (void*) SkCanvasGlue::drawTextRun___CIIIIFFIPaint},
-    {"native_drawTextRun","(JLjava/lang/String;IIIIFFIJ)V",
-        (void*) SkCanvasGlue::drawTextRun__StringIIIIFFIPaint},
+    {"native_drawText","(J[CIIFFIJJ)V",
+        (void*) SkCanvasGlue::drawText___CIIFFIPaintTypeface},
+    {"native_drawText","(JLjava/lang/String;IIFFIJJ)V",
+        (void*) SkCanvasGlue::drawText__StringIIFFIPaintTypeface},
+    {"native_drawTextRun","(J[CIIIIFFIJJ)V",
+        (void*) SkCanvasGlue::drawTextRun___CIIIIFFIPaintTypeface},
+    {"native_drawTextRun","(JLjava/lang/String;IIIIFFIJJ)V",
+        (void*) SkCanvasGlue::drawTextRun__StringIIIIFFIPaintTypeface},
     {"native_drawPosText","(J[CII[FJ)V",
         (void*) SkCanvasGlue::drawPosText___CII_FPaint},
     {"native_drawPosText","(JLjava/lang/String;[FJ)V",
diff --git a/core/jni/android/graphics/ColorFilter.cpp b/core/jni/android/graphics/ColorFilter.cpp
index f9cefd6..09589bd 100644
--- a/core/jni/android/graphics/ColorFilter.cpp
+++ b/core/jni/android/graphics/ColorFilter.cpp
@@ -23,7 +23,6 @@
 #include "SkColorMatrixFilter.h"
 #include "SkPorterDuff.h"
 
-#include <SkiaColorFilter.h>
 #include <Caches.h>
 
 namespace android {
@@ -32,64 +31,9 @@
 
 class SkColorFilterGlue {
 public:
-    static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong fHandle) {
-        SkColorFilter* obj = reinterpret_cast<SkColorFilter *>(objHandle);
-        SkiaColorFilter* f = reinterpret_cast<SkiaColorFilter *>(fHandle);
-        SkSafeUnref(obj);
-        // f == NULL when not !USE_OPENGL_RENDERER, so no need to delete outside the ifdef
-#ifdef USE_OPENGL_RENDERER
-        if (android::uirenderer::Caches::hasInstance()) {
-            android::uirenderer::Caches::getInstance().resourceCache.destructor(f);
-        } else {
-            delete f;
-        }
-#endif
-    }
-
-    static jlong glCreatePorterDuffFilter(JNIEnv* env, jobject, jlong skFilterHandle,
-            jint srcColor, jint modeHandle) {
-        SkColorFilter *skFilter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
-        SkPorterDuff::Mode mode = static_cast<SkPorterDuff::Mode>(modeHandle);
-#ifdef USE_OPENGL_RENDERER
-        return reinterpret_cast<jlong>(new SkiaBlendFilter(skFilter, srcColor, SkPorterDuff::ToXfermodeMode(mode)));
-#else
-        return NULL;
-#endif
-    }
-
-    static jlong glCreateLightingFilter(JNIEnv* env, jobject, jlong skFilterHandle,
-            jint mul, jint add) {
-        SkColorFilter *skFilter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
-#ifdef USE_OPENGL_RENDERER
-        return reinterpret_cast<jlong>(new SkiaLightingFilter(skFilter, mul, add));
-#else
-        return NULL;
-#endif
-    }
-
-    static jlong glCreateColorMatrixFilter(JNIEnv* env, jobject, jlong skFilterHandle,
-            jfloatArray jarray) {
-        SkColorFilter *skFilter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
-#ifdef USE_OPENGL_RENDERER
-        AutoJavaFloatArray autoArray(env, jarray, 20);
-        const float* src = autoArray.ptr();
-
-        float* colorMatrix = new float[16];
-        memcpy(colorMatrix, src, 4 * sizeof(float));
-        memcpy(&colorMatrix[4], &src[5], 4 * sizeof(float));
-        memcpy(&colorMatrix[8], &src[10], 4 * sizeof(float));
-        memcpy(&colorMatrix[12], &src[15], 4 * sizeof(float));
-
-        float* colorVector = new float[4];
-        colorVector[0] = src[4];
-        colorVector[1] = src[9];
-        colorVector[2] = src[14];
-        colorVector[3] = src[19];
-
-        return reinterpret_cast<jlong>(new SkiaColorMatrixFilter(skFilter, colorMatrix, colorVector));
-#else
-        return NULL;
-#endif
+    static void finalizer(JNIEnv* env, jobject clazz, jlong skFilterHandle) {
+        SkColorFilter* filter = reinterpret_cast<SkColorFilter *>(skFilterHandle);
+        if (filter) SkSafeUnref(filter);
     }
 
     static jlong CreatePorterDuffFilter(JNIEnv* env, jobject, jint srcColor,
@@ -119,22 +63,19 @@
 };
 
 static JNINativeMethod colorfilter_methods[] = {
-    {"finalizer", "(JJ)V", (void*) SkColorFilterGlue::finalizer}
+    {"destroyFilter", "(J)V", (void*) SkColorFilterGlue::finalizer}
 };
 
 static JNINativeMethod porterduff_methods[] = {
     { "native_CreatePorterDuffFilter", "(II)J", (void*) SkColorFilterGlue::CreatePorterDuffFilter   },
-    { "nCreatePorterDuffFilter",       "(JII)J", (void*) SkColorFilterGlue::glCreatePorterDuffFilter }
 };
 
 static JNINativeMethod lighting_methods[] = {
     { "native_CreateLightingFilter", "(II)J", (void*) SkColorFilterGlue::CreateLightingFilter   },
-    { "nCreateLightingFilter",       "(JII)J", (void*) SkColorFilterGlue::glCreateLightingFilter },
 };
 
 static JNINativeMethod colormatrix_methods[] = {
     { "nativeColorMatrixFilter", "([F)J", (void*) SkColorFilterGlue::CreateColorMatrixFilter   },
-    { "nColorMatrixFilter",      "(J[F)J", (void*) SkColorFilterGlue::glCreateColorMatrixFilter }
 };
 
 #define REG(env, name, array) \
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 5d951ca..98edbdb 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -461,6 +461,7 @@
 
     // If storageObj is NULL, the memory was NOT allocated on the Java heap
     fOnJavaHeap = (storageObj != NULL);
+
 }
 
 AndroidPixelRef::AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp
index f331af7..5573366 100644
--- a/core/jni/android/graphics/MaskFilter.cpp
+++ b/core/jni/android/graphics/MaskFilter.cpp
@@ -1,5 +1,6 @@
 #include "GraphicsJNI.h"
 #include "SkMaskFilter.h"
+#include "SkBlurMask.h"
 #include "SkBlurMaskFilter.h"
 #include "SkTableMaskFilter.h"
 
@@ -19,8 +20,9 @@
     }
 
     static jlong createBlur(JNIEnv* env, jobject, jfloat radius, jint blurStyle) {
-        SkMaskFilter* filter = SkBlurMaskFilter::Create(SkFloatToScalar(radius),
-                                        (SkBlurMaskFilter::BlurStyle)blurStyle);
+        SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkFloatToScalar(radius));
+        SkMaskFilter* filter = SkBlurMaskFilter::Create(
+                (SkBlurMaskFilter::BlurStyle)blurStyle, sigma);
         ThrowIAE_IfNull(env, filter);
         return reinterpret_cast<jlong>(filter);
     }
@@ -34,10 +36,9 @@
             direction[i] = SkFloatToScalar(values[i]);
         }
 
-        SkMaskFilter* filter =  SkBlurMaskFilter::CreateEmboss(direction,
-                                                      SkFloatToScalar(ambient),
-                                                      SkFloatToScalar(specular),
-                                                      SkFloatToScalar(radius));
+        SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(SkFloatToScalar(radius));
+        SkMaskFilter* filter =  SkBlurMaskFilter::CreateEmboss(sigma,
+                direction, SkFloatToScalar(ambient), SkFloatToScalar(specular));
         ThrowIAE_IfNull(env, filter);
         return reinterpret_cast<jlong>(filter);
     }
diff --git a/core/jni/android/graphics/Matrix.cpp b/core/jni/android/graphics/Matrix.cpp
index a667499..6ae9fea 100644
--- a/core/jni/android/graphics/Matrix.cpp
+++ b/core/jni/android/graphics/Matrix.cpp
@@ -352,7 +352,6 @@
         result = SkScalarToFloat(matrix->mapRadius(SkFloatToScalar(radius)));
         return static_cast<jfloat>(result);
     }
-
     static void getValues(JNIEnv* env, jobject clazz, jlong matrixHandle, jfloatArray values) {
         SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
         AutoJavaFloatArray autoValues(env, values, 9, kRW_JNIAccess);
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
new file mode 100644
index 0000000..622c935
--- /dev/null
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -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.
+ */
+
+#include <SkTypeface.h>
+#include <SkPaint.h>
+#include <SkFP.h>
+
+#define LOG_TAG "Minikin"
+#include <cutils/log.h>
+
+#include <minikin/MinikinFont.h>
+#include "MinikinSkia.h"
+
+namespace android {
+
+MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
+    mTypeface(typeface) {
+}
+
+MinikinFontSkia::~MinikinFontSkia() {
+    SkSafeUnref(mTypeface);
+}
+
+bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const {
+    SkPaint paint;
+    paint.setTypeface(mTypeface);
+    paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
+    uint16_t glyph16;
+    paint.textToGlyphs(&codepoint, sizeof(codepoint), &glyph16);
+    *glyph  = glyph16;
+    return !!glyph;
+}
+
+float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
+    const MinikinPaint &paint) const {
+    SkPaint skpaint;
+    skpaint.setTypeface(mTypeface);
+    skpaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+    // TODO: set more paint parameters from Minikin
+    skpaint.setTextSize(paint.size);
+    uint16_t glyph16 = glyph_id;
+    SkScalar skWidth;
+    SkRect skBounds;
+    skpaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, &skBounds);
+    // TODO: get bounds information
+    return SkScalarToFP(skWidth);
+}
+
+bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
+    if (buf == NULL) {
+        const size_t tableSize = mTypeface->getTableSize(tag);
+        *size = tableSize;
+        return tableSize != 0;
+    } else {
+        const size_t actualSize = mTypeface->getTableData(tag, 0, *size, buf);
+        *size = actualSize;
+        return actualSize != 0;
+    }
+}
+
+SkTypeface *MinikinFontSkia::GetSkTypeface() {
+    return mTypeface;
+}
+
+int32_t MinikinFontSkia::GetUniqueId() const {
+    return mTypeface->uniqueID();
+}
+
+}
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
new file mode 100644
index 0000000..0edb557
--- /dev/null
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -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.
+ */
+
+namespace android {
+
+class MinikinFontSkia : public MinikinFont {
+public:
+    explicit MinikinFontSkia(SkTypeface *typeface);
+
+    ~MinikinFontSkia();
+
+    bool GetGlyph(uint32_t codepoint, uint32_t *glyph) const;
+
+    float GetHorizontalAdvance(uint32_t glyph_id,
+        const MinikinPaint &paint) const;
+
+    // If buf is NULL, just update size
+    bool GetTable(uint32_t tag, uint8_t *buf, size_t *size);
+
+    int32_t GetUniqueId() const;
+
+    SkTypeface *GetSkTypeface();
+
+private:
+    SkTypeface *mTypeface;
+
+};
+
+}  // namespace android
\ No newline at end of file
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index 86ff13c..1793208 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -38,7 +38,7 @@
 #include <utils/Log.h>
 
 static bool getColor(const SkBitmap& bitmap, int x, int y, SkColor* c) {
-    switch (bitmap.getConfig()) {
+    switch (bitmap.config()) {
         case SkBitmap::kARGB_8888_Config:
             *c = SkUnPreMultiply::PMColorToColor(*bitmap.getAddr32(x, y));
             break;
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index dc97c22..51990d5 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -279,9 +279,14 @@
     }
 
     static jlong setTypeface(JNIEnv* env, jobject clazz, jlong objHandle, jlong typefaceHandle) {
+#ifndef USE_MINIKIN
         SkPaint* obj = reinterpret_cast<SkPaint*>(objHandle);
         SkTypeface* typeface = reinterpret_cast<SkTypeface*>(typefaceHandle);
         return reinterpret_cast<jlong>(obj->setTypeface(typeface));
+#else
+        // TODO(raph): not yet implemented
+        return NULL;
+#endif
     }
 
     static jlong setRasterizer(JNIEnv* env, jobject clazz, jlong objHandle, jlong rasterizerHandle) {
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 54b6996..e580d36 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -25,9 +25,11 @@
 #include <android_runtime/AndroidRuntime.h>
 
 #include "SkPath.h"
-#include "pathops/SkPathOps.h"
+#include "SkPathOps.h"
 
 #include <Caches.h>
+#include <vector>
+#include <map>
 
 namespace android {
 
@@ -70,11 +72,16 @@
         *dst = *src;
     }
 
+    static jboolean isConvex(JNIEnv* env, jobject clazz, jlong objHandle) {
+        SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
+        return obj->isConvex();
+    }
+
     static jint getFillType(JNIEnv* env, jobject clazz, jlong objHandle) {
         SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
         return obj->getFillType();
     }
- 
+
     static void setFillType(JNIEnv* env, jobject clazz, jlong pathHandle, jint ftHandle) {
         SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
         SkPath::FillType ft = static_cast<SkPath::FillType>(ftHandle);
@@ -321,6 +328,198 @@
         SkPath* r   = reinterpret_cast<SkPath*>(rHandle);
         return Op(*p1, *p2, op, r);
      }
+
+    typedef SkPoint (*bezierCalculation)(float t, const SkPoint* points);
+
+    static void addMove(std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths,
+            const SkPoint& point) {
+        float length = 0;
+        if (!lengths.empty()) {
+            length = lengths.back();
+        }
+        segmentPoints.push_back(point);
+        lengths.push_back(length);
+    }
+
+    static void addLine(std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths,
+            const SkPoint& toPoint) {
+        if (segmentPoints.empty()) {
+            segmentPoints.push_back(SkPoint::Make(0, 0));
+            lengths.push_back(0);
+        } else if (segmentPoints.back() == toPoint) {
+            return; // Empty line
+        }
+        float length = lengths.back() + SkPoint::Distance(segmentPoints.back(), toPoint);
+        segmentPoints.push_back(toPoint);
+        lengths.push_back(length);
+    }
+
+    static float cubicCoordinateCalculation(float t, float p0, float p1, float p2, float p3) {
+        float oneMinusT = 1 - t;
+        float oneMinusTSquared = oneMinusT * oneMinusT;
+        float oneMinusTCubed = oneMinusTSquared * oneMinusT;
+        float tSquared = t * t;
+        float tCubed = tSquared * t;
+        return (oneMinusTCubed * p0) + (3 * oneMinusTSquared * t * p1)
+                + (3 * oneMinusT * tSquared * p2) + (tCubed * p3);
+    }
+
+    static SkPoint cubicBezierCalculation(float t, const SkPoint* points) {
+        float x = cubicCoordinateCalculation(t, points[0].x(), points[1].x(),
+            points[2].x(), points[3].x());
+        float y = cubicCoordinateCalculation(t, points[0].y(), points[1].y(),
+            points[2].y(), points[3].y());
+        return SkPoint::Make(x, y);
+    }
+
+    static float quadraticCoordinateCalculation(float t, float p0, float p1, float p2) {
+        float oneMinusT = 1 - t;
+        return oneMinusT * ((oneMinusT * p0) + (t * p1)) + t * ((oneMinusT * p1) + (t * p2));
+    }
+
+    static SkPoint quadraticBezierCalculation(float t, const SkPoint* points) {
+        float x = quadraticCoordinateCalculation(t, points[0].x(), points[1].x(), points[2].x());
+        float y = quadraticCoordinateCalculation(t, points[0].y(), points[1].y(), points[2].y());
+        return SkPoint::Make(x, y);
+    }
+
+    // Subdivide a section of the Bezier curve, set the mid-point and the mid-t value.
+    // Returns true if further subdivision is necessary as defined by errorSquared.
+    static bool subdividePoints(const SkPoint* points, bezierCalculation bezierFunction,
+            float t0, const SkPoint &p0, float t1, const SkPoint &p1,
+            float& midT, SkPoint &midPoint, float errorSquared) {
+        midT = (t1 + t0) / 2;
+        float midX = (p1.x() + p0.x()) / 2;
+        float midY = (p1.y() + p0.y()) / 2;
+
+        midPoint = (*bezierFunction)(midT, points);
+        float xError = midPoint.x() - midX;
+        float yError = midPoint.y() - midY;
+        float midErrorSquared = (xError * xError) + (yError * yError);
+        return midErrorSquared > errorSquared;
+    }
+
+    // Divides Bezier curves until linear interpolation is very close to accurate, using
+    // errorSquared as a metric. Cubic Bezier curves can have an inflection point that improperly
+    // short-circuit subdivision. If you imagine an S shape, the top and bottom points being the
+    // starting and end points, linear interpolation would mark the center where the curve places
+    // the point. It is clearly not the case that we can linearly interpolate at that point.
+    // doubleCheckDivision forces a second examination between subdivisions to ensure that linear
+    // interpolation works.
+    static void addBezier(const SkPoint* points,
+            bezierCalculation bezierFunction, std::vector<SkPoint>& segmentPoints,
+            std::vector<float>& lengths, float errorSquared, bool doubleCheckDivision) {
+        typedef std::map<float, SkPoint> PointMap;
+        PointMap tToPoint;
+
+        tToPoint[0] = (*bezierFunction)(0, points);
+        tToPoint[1] = (*bezierFunction)(1, points);
+
+        PointMap::iterator iter = tToPoint.begin();
+        PointMap::iterator next = iter;
+        ++next;
+        while (next != tToPoint.end()) {
+            bool needsSubdivision = true;
+            SkPoint midPoint;
+            do {
+                float midT;
+                needsSubdivision = subdividePoints(points, bezierFunction, iter->first,
+                    iter->second, next->first, next->second, midT, midPoint, errorSquared);
+                if (!needsSubdivision && doubleCheckDivision) {
+                    SkPoint quarterPoint;
+                    float quarterT;
+                    needsSubdivision = subdividePoints(points, bezierFunction, iter->first,
+                        iter->second, midT, midPoint, quarterT, quarterPoint, errorSquared);
+                    if (needsSubdivision) {
+                        // Found an inflection point. No need to double-check.
+                        doubleCheckDivision = false;
+                    }
+                }
+                if (needsSubdivision) {
+                    next = tToPoint.insert(iter, PointMap::value_type(midT, midPoint));
+                }
+            } while (needsSubdivision);
+            iter = next;
+            next++;
+        }
+
+        // Now that each division can use linear interpolation with less than the allowed error
+        for (iter = tToPoint.begin(); iter != tToPoint.end(); ++iter) {
+            addLine(segmentPoints, lengths, iter->second);
+        }
+    }
+
+    static void createVerbSegments(SkPath::Verb verb, const SkPoint* points,
+        std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths, float errorSquared) {
+        switch (verb) {
+            case SkPath::kMove_Verb:
+                addMove(segmentPoints, lengths, points[0]);
+                break;
+            case SkPath::kClose_Verb:
+                addLine(segmentPoints, lengths, points[0]);
+                break;
+            case SkPath::kLine_Verb:
+                addLine(segmentPoints, lengths, points[1]);
+                break;
+            case SkPath::kQuad_Verb:
+                addBezier(points, quadraticBezierCalculation, segmentPoints, lengths,
+                    errorSquared, false);
+                break;
+            case SkPath::kCubic_Verb:
+                addBezier(points, cubicBezierCalculation, segmentPoints, lengths,
+                    errorSquared, true);
+                break;
+            default:
+                // Leave element as NULL, Conic sections are not supported.
+                break;
+        }
+    }
+
+    // Returns a float[] with each point along the path represented by 3 floats
+    // * fractional length along the path that the point resides
+    // * x coordinate
+    // * y coordinate
+    // Note that more than one point may have the same length along the path in
+    // the case of a move.
+    // NULL can be returned if the Path is empty.
+    static jfloatArray approximate(JNIEnv* env, jclass, jlong pathHandle, float acceptableError)
+    {
+        SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
+        SkASSERT(path);
+        SkPath::Iter pathIter(*path, false);
+        SkPath::Verb verb;
+        SkPoint points[4];
+        std::vector<SkPoint> segmentPoints;
+        std::vector<float> lengths;
+        float errorSquared = acceptableError * acceptableError;
+
+        while ((verb = pathIter.next(points)) != SkPath::kDone_Verb) {
+            createVerbSegments(verb, points, segmentPoints, lengths, errorSquared);
+        }
+
+        if (segmentPoints.empty()) {
+            return NULL;
+        }
+
+        size_t numPoints = segmentPoints.size();
+        size_t approximationArraySize = numPoints * 3;
+
+        float* approximation = new float[approximationArraySize];
+        float totalLength = lengths.back();
+
+        int approximationIndex = 0;
+        for (size_t i = 0; i < numPoints; i++) {
+            const SkPoint& point = segmentPoints[i];
+            approximation[approximationIndex++] = lengths[i] / totalLength;
+            approximation[approximationIndex++] = point.x();
+            approximation[approximationIndex++] = point.y();
+        }
+
+        jfloatArray result = env->NewFloatArray(approximationArraySize);
+        env->SetFloatArrayRegion(result, 0, approximationArraySize, approximation);
+        delete[] approximation;
+        return result;
+    }
 };
 
 static JNINativeMethod methods[] = {
@@ -330,6 +529,7 @@
     {"native_reset","(J)V", (void*) SkPathGlue::reset},
     {"native_rewind","(J)V", (void*) SkPathGlue::rewind},
     {"native_set","(JJ)V", (void*) SkPathGlue::assign},
+    {"native_isConvex","(J)Z", (void*) SkPathGlue::isConvex},
     {"native_getFillType","(J)I", (void*) SkPathGlue::getFillType},
     {"native_setFillType","(JI)V", (void*) SkPathGlue::setFillType},
     {"native_isEmpty","(J)Z", (void*) SkPathGlue::isEmpty},
@@ -361,7 +561,8 @@
     {"native_setLastPoint","(JFF)V", (void*) SkPathGlue::setLastPoint},
     {"native_transform","(JJJ)V", (void*) SkPathGlue::transform__MatrixPath},
     {"native_transform","(JJ)V", (void*) SkPathGlue::transform__Matrix},
-    {"native_op","(JJIJ)Z", (void*) SkPathGlue::op}
+    {"native_op","(JJIJ)Z", (void*) SkPathGlue::op},
+    {"native_approximate", "(JF)[F", (void*) SkPathGlue::approximate},
 };
 
 int register_android_graphics_Path(JNIEnv* env) {
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index 3047440..1fe6358 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -520,7 +520,7 @@
     SkiaShader* shaderB = reinterpret_cast<SkiaShader *>(shaderBHandle);
     SkXfermode* mode = reinterpret_cast<SkXfermode *>(modeHandle);
     SkXfermode::Mode skiaMode;
-    if (!SkXfermode::IsMode(mode, &skiaMode)) {
+    if (!SkXfermode::AsMode(mode, &skiaMode)) {
         // TODO: Support other modes
         skiaMode = SkXfermode::kSrcOver_Mode;
     }
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 3116955..b78b131 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -43,7 +43,7 @@
 
 struct fields_t {
     jfieldID  surfaceTexture;
-    jfieldID  bufferQueue;
+    jfieldID  producer;
     jfieldID  frameAvailableListener;
     jmethodID postEvent;
 };
@@ -65,18 +65,18 @@
     env->SetLongField(thiz, fields.surfaceTexture, (jlong)surfaceTexture.get());
 }
 
-static void SurfaceTexture_setBufferQueue(JNIEnv* env, jobject thiz,
-        const sp<BufferQueue>& bq)
+static void SurfaceTexture_setProducer(JNIEnv* env, jobject thiz,
+        const sp<IGraphicBufferProducer>& producer)
 {
-    BufferQueue* const p =
-        (BufferQueue*)env->GetLongField(thiz, fields.bufferQueue);
-    if (bq.get()) {
-        bq->incStrong((void*)SurfaceTexture_setBufferQueue);
+    IGraphicBufferProducer* const p =
+        (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
+    if (producer.get()) {
+        producer->incStrong((void*)SurfaceTexture_setProducer);
     }
     if (p) {
-        p->decStrong((void*)SurfaceTexture_setBufferQueue);
+        p->decStrong((void*)SurfaceTexture_setProducer);
     }
-    env->SetLongField(thiz, fields.bufferQueue, (jlong)bq.get());
+    env->SetLongField(thiz, fields.producer, (jlong)producer.get());
 }
 
 static void SurfaceTexture_setFrameAvailableListener(JNIEnv* env,
@@ -99,7 +99,7 @@
 }
 
 sp<IGraphicBufferProducer> SurfaceTexture_getProducer(JNIEnv* env, jobject thiz) {
-    return (BufferQueue*)env->GetLongField(thiz, fields.bufferQueue);
+    return (IGraphicBufferProducer*)env->GetLongField(thiz, fields.producer);
 }
 
 sp<ANativeWindow> android_SurfaceTexture_getNativeWindow(JNIEnv* env, jobject thiz) {
@@ -141,7 +141,8 @@
     *needsDetach = false;
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     if (env == NULL) {
-        JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
+        JavaVMAttachArgs args = {
+            JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL };
         JavaVM* vm = AndroidRuntime::getJavaVM();
         int result = vm->AttachCurrentThread(&env, (void*) &args);
         if (result != JNI_OK) {
@@ -194,7 +195,7 @@
 
 
 #define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
-#define ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID "mBufferQueue"
+#define ANDROID_GRAPHICS_PRODUCER_JNI_ID "mProducer"
 #define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
                                          "mFrameAvailableListener"
 
@@ -206,11 +207,11 @@
         ALOGE("can't find android/graphics/SurfaceTexture.%s",
                 ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID);
     }
-    fields.bufferQueue = env->GetFieldID(clazz,
-            ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID, "J");
-    if (fields.bufferQueue == NULL) {
+    fields.producer = env->GetFieldID(clazz,
+            ANDROID_GRAPHICS_PRODUCER_JNI_ID, "J");
+    if (fields.producer == NULL) {
         ALOGE("can't find android/graphics/SurfaceTexture.%s",
-                ANDROID_GRAPHICS_BUFFERQUEUE_JNI_ID);
+                ANDROID_GRAPHICS_PRODUCER_JNI_ID);
     }
     fields.frameAvailableListener = env->GetFieldID(clazz,
             ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID, "J");
@@ -229,21 +230,24 @@
 static void SurfaceTexture_init(JNIEnv* env, jobject thiz,
         jint texName, jboolean singleBufferMode, jobject weakThiz)
 {
-    sp<BufferQueue> bq = new BufferQueue();
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer);
 
     if (singleBufferMode) {
-        bq->disableAsyncBuffer();
-        bq->setDefaultMaxBufferCount(1);
+        consumer->disableAsyncBuffer();
+        consumer->setDefaultMaxBufferCount(1);
     }
 
-    sp<GLConsumer> surfaceTexture(new GLConsumer(bq, texName, GL_TEXTURE_EXTERNAL_OES, true, true));
+    sp<GLConsumer> surfaceTexture(new GLConsumer(consumer, 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);
+    SurfaceTexture_setProducer(env, thiz, producer);
 
     jclass clazz = env->GetObjectClass(thiz);
     if (clazz == NULL) {
@@ -264,7 +268,7 @@
     surfaceTexture->setFrameAvailableListener(0);
     SurfaceTexture_setFrameAvailableListener(env, thiz, 0);
     SurfaceTexture_setSurfaceTexture(env, thiz, 0);
-    SurfaceTexture_setBufferQueue(env, thiz, 0);
+    SurfaceTexture_setProducer(env, thiz, 0);
 }
 
 static void SurfaceTexture_setDefaultBufferSize(
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index 8164625..a349a7f 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -1,10 +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.
+ */
+
 #include "jni.h"
 #include <android_runtime/AndroidRuntime.h>
 
 #include "GraphicsJNI.h"
 #include "SkStream.h"
 #include "SkTypeface.h"
-#include "Utils.h"
+#include "TypefaceImpl.h"
 #include <android_runtime/android_util_AssetManager.h>
 #include <androidfw/AssetManager.h>
 
@@ -31,57 +47,49 @@
 static jlong Typeface_create(JNIEnv* env, jobject, jstring name,
                              jint styleHandle) {
     SkTypeface::Style style = static_cast<SkTypeface::Style>(styleHandle);
-    SkTypeface* face = NULL;
+    TypefaceImpl* face = NULL;
 
     if (NULL != name) {
         AutoJavaStringToUTF8    str(env, name);
-        face = SkTypeface::CreateFromName(str.c_str(), style);
-        // Try to find the closest matching font, using the standard heuristic
-        if (NULL == face) {
-            face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)(style ^ SkTypeface::kItalic));
-        }
-        for (int i = 0; NULL == face && i < 4; i++) {
-            face = SkTypeface::CreateFromName(str.c_str(), (SkTypeface::Style)i);
-        }
+        face = TypefaceImpl_createFromName(str.c_str(), style);
     }
 
     // return the default font at the best style if no exact match exists
     if (NULL == face) {
-        face = SkTypeface::CreateFromName(NULL, style);
+        face = TypefaceImpl_createFromName(NULL, style);
     }
     return reinterpret_cast<jlong>(face);
 }
 
 static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) {
     SkTypeface* family = reinterpret_cast<SkTypeface*>(familyHandle);
-    SkTypeface* face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)style);
+    TypefaceImpl* face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)style);
     // Try to find the closest matching font, using the standard heuristic
     if (NULL == face) {
-        face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
+        face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)(style ^ SkTypeface::kItalic));
     }
     for (int i = 0; NULL == face && i < 4; i++) {
-        face = SkTypeface::CreateFromTypeface(family, (SkTypeface::Style)i);
+        face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)i);
     }
     if (NULL == face) {
-        face = SkTypeface::CreateFromName(NULL, (SkTypeface::Style)style);
+        face = TypefaceImpl_createFromName(NULL, (SkTypeface::Style)style);
     }
     return reinterpret_cast<jlong>(face);
 }
 
 static void Typeface_unref(JNIEnv* env, jobject obj, jlong faceHandle) {
-    SkTypeface* face = reinterpret_cast<SkTypeface*>(faceHandle);
-    SkSafeUnref(face);
+    TypefaceImpl* face = reinterpret_cast<TypefaceImpl*>(faceHandle);
+    TypefaceImpl_unref(face);
 }
 
 static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
-    SkTypeface* face = reinterpret_cast<SkTypeface*>(faceHandle);
-    return static_cast<jint>(face->style());
+    TypefaceImpl* face = reinterpret_cast<TypefaceImpl*>(faceHandle);
+    return TypefaceImpl_getStyle(face);
 }
 
 static jlong Typeface_createFromAsset(JNIEnv* env, jobject,
                                       jobject jassetMgr,
                                       jstring jpath) {
-
     NPE_CHECK_RETURN_ZERO(env, jassetMgr);
     NPE_CHECK_RETURN_ZERO(env, jpath);
 
@@ -90,29 +98,20 @@
         return NULL;
     }
 
-    AutoJavaStringToUTF8    str(env, jpath);
+    AutoJavaStringToUTF8 str(env, jpath);
     Asset* asset = mgr->open(str.c_str(), Asset::ACCESS_BUFFER);
     if (NULL == asset) {
         return NULL;
     }
 
-    SkStream* stream = new AssetStreamAdaptor(asset,
-                                              AssetStreamAdaptor::kYes_OwnAsset,
-                                              AssetStreamAdaptor::kYes_HasMemoryBase);
-    SkTypeface* face = SkTypeface::CreateFromStream(stream);
-    // SkTypeFace::CreateFromStream calls ref() on the stream, so we
-    // need to unref it here or it won't be freed later on
-    stream->unref();
-
-    return reinterpret_cast<jlong>(face);
+    return reinterpret_cast<jlong>(TypefaceImpl_createFromAsset(asset));
 }
 
 static jlong Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
     NPE_CHECK_RETURN_ZERO(env, jpath);
 
     AutoJavaStringToUTF8 str(env, jpath);
-
-    return reinterpret_cast<jlong>(SkTypeface::CreateFromFile(str.c_str()));
+    return reinterpret_cast<jlong>(TypefaceImpl_createFromFile(str.c_str()));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
new file mode 100644
index 0000000..f6d3a6e
--- /dev/null
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 implementation of the Typeface object. Historically, it has
+ * just been SkTypeface, but we are migrating to Minikin. For the time
+ * being, that choice is hidden under the USE_MINIKIN compile-time flag.
+ */
+
+#include "SkStream.h"
+#include "SkTypeface.h"
+
+#ifdef USE_MINIKIN
+#include <vector>
+#include <minikin/FontCollection.h>
+#include <minikin/FontFamily.h>
+#include <minikin/Layout.h>
+#include "MinikinSkia.h"
+#endif
+
+#include "TypefaceImpl.h"
+#include "Utils.h"
+
+namespace android {
+
+#ifdef USE_MINIKIN
+
+// Any weight greater than or equal to this is considered "bold" for
+// legacy API.
+static const int kBoldThreshold = 6;
+
+static FontStyle styleFromSkiaStyle(SkTypeface::Style skiaStyle) {
+    int weight = (skiaStyle & SkTypeface::kBold) != 0 ? 7 : 4;
+    bool italic = (skiaStyle & SkTypeface::kItalic) != 0;
+    return FontStyle(weight, italic);
+}
+
+TypefaceImpl* gDefaultTypeface;
+pthread_once_t gDefaultTypefaceOnce = PTHREAD_ONCE_INIT;
+
+// TODO: this currently builds a font collection from hardcoded paths.
+// It will get replaced by an implementation that parses the XML files.
+static FontCollection *makeFontCollection() {
+    std::vector<FontFamily *>typefaces;
+    const char *fns[] = {
+        "/system/fonts/Roboto-Regular.ttf",
+        "/system/fonts/Roboto-Italic.ttf",
+        "/system/fonts/Roboto-BoldItalic.ttf",
+        "/system/fonts/Roboto-Light.ttf",
+        "/system/fonts/Roboto-Thin.ttf",
+        "/system/fonts/Roboto-Bold.ttf",
+        "/system/fonts/Roboto-ThinItalic.ttf",
+        "/system/fonts/Roboto-LightItalic.ttf"
+    };
+
+    FontFamily *family = new FontFamily();
+    for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) {
+        const char *fn = fns[i];
+        SkTypeface *skFace = SkTypeface::CreateFromFile(fn);
+        MinikinFont *font = new MinikinFontSkia(skFace);
+        family->addFont(font);
+    }
+    typefaces.push_back(family);
+
+    family = new FontFamily();
+    const char *fn = "/system/fonts/NotoSansDevanagari-Regular.ttf";
+    SkTypeface *skFace = SkTypeface::CreateFromFile(fn);
+    MinikinFont *font = new MinikinFontSkia(skFace);
+    family->addFont(font);
+    typefaces.push_back(family);
+
+    return new FontCollection(typefaces);
+}
+
+static void getDefaultTypefaceOnce() {
+    Layout::init();
+    gDefaultTypeface = new TypefaceImpl;
+    gDefaultTypeface->fFontCollection = makeFontCollection();
+    gDefaultTypeface->fStyle = FontStyle();
+}
+
+TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src) {
+    if (src == NULL) {
+        pthread_once(&gDefaultTypefaceOnce, getDefaultTypefaceOnce);
+        return gDefaultTypeface;
+    } else {
+        return src;
+    }
+}
+
+TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style) {
+    TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(src);
+    TypefaceImpl* result = new TypefaceImpl;
+    if (result != 0) {
+        result->fFontCollection = resolvedFace->fFontCollection;
+        result->fStyle = styleFromSkiaStyle(style);
+    }
+    return result;
+}
+
+static TypefaceImpl* createFromSkTypeface(SkTypeface* typeface) {
+    MinikinFont* minikinFont = new MinikinFontSkia(typeface);
+    std::vector<FontFamily *> typefaces;
+    FontFamily* family = new FontFamily();
+    family->addFont(minikinFont);
+    typefaces.push_back(family);
+    TypefaceImpl* result = new TypefaceImpl;
+    result->fFontCollection = new FontCollection(typefaces);
+    result->fStyle = FontStyle();  // TODO: improve
+    return result;
+}
+
+TypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style) {
+    // TODO: should create a font collection with all styles corresponding to
+    // the name
+    SkTypeface* face = SkTypeface::CreateFromName(name, style);
+    return createFromSkTypeface(face);
+}
+
+TypefaceImpl* TypefaceImpl_createFromFile(const char* filename) {
+    SkTypeface* face = SkTypeface::CreateFromFile(filename);
+    return createFromSkTypeface(face);
+}
+
+TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) {
+    SkStream* stream = new AssetStreamAdaptor(asset,
+                                              AssetStreamAdaptor::kYes_OwnAsset,
+                                              AssetStreamAdaptor::kYes_HasMemoryBase);
+    SkTypeface* face = SkTypeface::CreateFromStream(stream);
+    // SkTypeFace::CreateFromStream calls ref() on the stream, so we
+    // need to unref it here or it won't be freed later on
+    stream->unref();
+    return createFromSkTypeface(face);
+}
+
+void TypefaceImpl_unref(TypefaceImpl* face) {
+    delete face;
+}
+
+int TypefaceImpl_getStyle(TypefaceImpl* face) {
+    FontStyle style = face->fStyle;
+    int result = style.getItalic() ? SkTypeface::kItalic : 0;
+    if (style.getWeight() >= kBoldThreshold) {
+        result |= SkTypeface::kBold;
+    }
+    return result;
+}
+
+#else  // USE_MINIKIN
+
+/* Just use SkTypeface instead. */
+
+typedef SkTypeface TypefaceImpl;
+
+TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style) {
+    return SkTypeface::CreateFromTypeface(src, style);
+}
+
+TypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style) {
+    return SkTypeface::CreateFromName(name, style);
+}
+
+TypefaceImpl* TypefaceImpl_createFromFile(const char* filename) {
+    return SkTypeface::CreateFromFile(filename);
+}
+
+TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) {
+    SkStream* stream = new AssetStreamAdaptor(asset,
+                                              AssetStreamAdaptor::kYes_OwnAsset,
+                                              AssetStreamAdaptor::kYes_HasMemoryBase);
+    SkTypeface* face = SkTypeface::CreateFromStream(stream);
+    // SkTypeFace::CreateFromStream calls ref() on the stream, so we
+    // need to unref it here or it won't be freed later on
+    stream->unref();
+
+    return face;
+}
+
+void TypefaceImpl_unref(TypefaceImpl* face) {
+    SkSafeUnref(face);
+}
+
+int TypefaceImpl_getStyle(TypefaceImpl* face) {
+    return face->style();
+}
+
+#endif  // USE_MINIKIN
+
+}
diff --git a/core/jni/android/graphics/TypefaceImpl.h b/core/jni/android/graphics/TypefaceImpl.h
new file mode 100644
index 0000000..4c51bec
--- /dev/null
+++ b/core/jni/android/graphics/TypefaceImpl.h
@@ -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.
+ */
+
+
+#ifndef ANDROID_TYPEFACE_IMPL_H
+#define ANDROID_TYPEFACE_IMPL_H
+
+#include <androidfw/AssetManager.h>
+
+#ifdef USE_MINIKIN
+#include <minikin/FontCollection.h>
+#endif
+
+namespace android {
+
+#ifdef USE_MINIKIN
+struct TypefaceImpl {
+    FontCollection *fFontCollection;
+    FontStyle fStyle;
+};
+
+// Note: it would be cleaner if the following functions were member
+// functions (static or otherwise) of the TypefaceImpl class. However,
+// that can't be easily accommodated in the case where TypefaceImpl
+// is just a pointer to SkTypeface, in the non-USE_MINIKIN case.
+// TODO: when #ifdef USE_MINIKIN is removed, move to member functions.
+
+TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src);
+#else
+typedef SkTypeface TypefaceImpl;
+#endif
+
+TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style);
+
+TypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style);
+
+TypefaceImpl* TypefaceImpl_createFromFile(const char* filename);
+
+TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset);
+
+void TypefaceImpl_unref(TypefaceImpl* face);
+
+int TypefaceImpl_getStyle(TypefaceImpl* face);
+
+}
+
+#endif  // ANDROID_TYPEFACE_IMPL_H
\ No newline at end of file
diff --git a/core/jni/android/graphics/Utils.cpp b/core/jni/android/graphics/Utils.cpp
index eb416cb..a134d4b 100644
--- a/core/jni/android/graphics/Utils.cpp
+++ b/core/jni/android/graphics/Utils.cpp
@@ -52,7 +52,6 @@
 }
 
 SkStreamRewindable* AssetStreamAdaptor::duplicate() const {
-    SkASSERT(false);
     // Cannot create a duplicate, since each AssetStreamAdaptor
     // would be modifying the Asset.
     //return new AssetStreamAdaptor(fAsset);
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index a17f328..a91c622 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -27,7 +27,7 @@
 #include <GLES/gl.h>
 #include <ETC1/etc1.h>
 
-#include <core/SkBitmap.h>
+#include <SkBitmap.h>
 
 #include "android_runtime/AndroidRuntime.h"
 
diff --git a/core/jni/android_animation_PropertyValuesHolder.cpp b/core/jni/android_animation_PropertyValuesHolder.cpp
index 1e3ec18..ef1c4ed 100644
--- a/core/jni/android_animation_PropertyValuesHolder.cpp
+++ b/core/jni/android_animation_PropertyValuesHolder.cpp
@@ -47,6 +47,32 @@
     return reinterpret_cast<jlong>(mid);
 }
 
+static jlong getMultiparameterMethod(JNIEnv* env, jclass targetClass, jstring methodName,
+    jint parameterCount, char parameterType)
+{
+    const char *nativeString = env->GetStringUTFChars(methodName, 0);
+    char *signature = new char[parameterCount + 4];
+    signature[0] = '(';
+    memset(&(signature[1]), parameterType, parameterCount);
+    strcpy(&(signature[parameterCount + 1]), ")V");
+    jmethodID mid = env->GetMethodID(targetClass, nativeString, signature);
+    delete[] signature;
+    env->ReleaseStringUTFChars(methodName, nativeString);
+    return reinterpret_cast<jlong>(mid);
+}
+
+static jlong android_animation_PropertyValuesHolder_getMultipleFloatMethod(
+        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
+{
+    return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'F');
+}
+
+static jlong android_animation_PropertyValuesHolder_getMultipleIntMethod(
+        JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName, jint parameterCount)
+{
+    return getMultiparameterMethod(env, targetClass, methodName, parameterCount, 'I');
+}
+
 static void android_animation_PropertyValuesHolder_callIntMethod(
         JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jint arg)
 {
@@ -59,15 +85,85 @@
     env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg);
 }
 
+static void android_animation_PropertyValuesHolder_callTwoFloatMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, float arg1, float arg2)
+{
+    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2);
+}
+
+static void android_animation_PropertyValuesHolder_callFourFloatMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, float arg1, float arg2,
+        float arg3, float arg4)
+{
+    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2, arg3, arg4);
+}
+
+static void android_animation_PropertyValuesHolder_callMultipleFloatMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jfloatArray arg)
+{
+    jsize parameterCount = env->GetArrayLength(arg);
+    jfloat *floatValues = env->GetFloatArrayElements(arg, NULL);
+    jvalue* values = new jvalue[parameterCount];
+    for (int i = 0; i < parameterCount; i++) {
+        values[i].f = floatValues[i];
+    }
+    env->CallVoidMethodA(target, reinterpret_cast<jmethodID>(methodID), values);
+    delete[] values;
+    env->ReleaseFloatArrayElements(arg, floatValues, JNI_ABORT);
+}
+
+static void android_animation_PropertyValuesHolder_callTwoIntMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, int arg1, int arg2)
+{
+    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2);
+}
+
+static void android_animation_PropertyValuesHolder_callFourIntMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, int arg1, int arg2,
+        int arg3, int arg4)
+{
+    env->CallVoidMethod(target, reinterpret_cast<jmethodID>(methodID), arg1, arg2, arg3, arg4);
+}
+
+static void android_animation_PropertyValuesHolder_callMultipleIntMethod(
+        JNIEnv* env, jclass pvhObject, jobject target, jlong methodID, jintArray arg)
+{
+    jsize parameterCount = env->GetArrayLength(arg);
+    jint *intValues = env->GetIntArrayElements(arg, NULL);
+    jvalue* values = new jvalue[parameterCount];
+    for (int i = 0; i < parameterCount; i++) {
+        values[i].i = intValues[i];
+    }
+    env->CallVoidMethodA(target, reinterpret_cast<jmethodID>(methodID), values);
+    delete[] values;
+    env->ReleaseIntArrayElements(arg, intValues, JNI_ABORT);
+}
+
 static JNINativeMethod gMethods[] = {
     {   "nGetIntMethod", "(Ljava/lang/Class;Ljava/lang/String;)J",
             (void*)android_animation_PropertyValuesHolder_getIntMethod },
     {   "nGetFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;)J",
             (void*)android_animation_PropertyValuesHolder_getFloatMethod },
+    {   "nGetMultipleFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;I)J",
+            (void*)android_animation_PropertyValuesHolder_getMultipleFloatMethod },
+    {   "nGetMultipleIntMethod", "(Ljava/lang/Class;Ljava/lang/String;I)J",
+            (void*)android_animation_PropertyValuesHolder_getMultipleIntMethod },
     {   "nCallIntMethod", "(Ljava/lang/Object;JI)V",
             (void*)android_animation_PropertyValuesHolder_callIntMethod },
     {   "nCallFloatMethod", "(Ljava/lang/Object;JF)V",
-            (void*)android_animation_PropertyValuesHolder_callFloatMethod }
+            (void*)android_animation_PropertyValuesHolder_callFloatMethod },
+    {   "nCallTwoFloatMethod", "(Ljava/lang/Object;JFF)V",
+            (void*)android_animation_PropertyValuesHolder_callTwoFloatMethod },
+    {   "nCallFourFloatMethod", "(Ljava/lang/Object;JFFFF)V",
+            (void*)android_animation_PropertyValuesHolder_callFourFloatMethod },
+    {   "nCallMultipleFloatMethod", "(Ljava/lang/Object;J[F)V",
+            (void*)android_animation_PropertyValuesHolder_callMultipleFloatMethod },
+    {   "nCallTwoIntMethod", "(Ljava/lang/Object;JII)V",
+            (void*)android_animation_PropertyValuesHolder_callTwoIntMethod },
+    {   "nCallFourIntMethod", "(Ljava/lang/Object;JIIII)V",
+            (void*)android_animation_PropertyValuesHolder_callFourIntMethod },
+    {   "nCallMultipleIntMethod", "(Ljava/lang/Object;J[I)V",
+            (void*)android_animation_PropertyValuesHolder_callMultipleIntMethod },
 };
 
 int register_android_animation_PropertyValuesHolder(JNIEnv* env)
diff --git a/core/jni/android_hardware_UsbDeviceConnection.cpp b/core/jni/android_hardware_UsbDeviceConnection.cpp
index c10b963f..467a9a1 100644
--- a/core/jni/android_hardware_UsbDeviceConnection.cpp
+++ b/core/jni/android_hardware_UsbDeviceConnection.cpp
@@ -123,20 +123,45 @@
     return (ret == 0) ? JNI_TRUE : JNI_FALSE;
 }
 
-static jint
+static jboolean
 android_hardware_UsbDeviceConnection_release_interface(JNIEnv *env, jobject thiz, jint interfaceID)
 {
     struct usb_device* device = get_device_from_object(env, thiz);
     if (!device) {
         ALOGE("device is closed in native_release_interface");
-        return -1;
+        return JNI_FALSE;
     }
     int ret = usb_device_release_interface(device, interfaceID);
     if (ret == 0) {
         // allow kernel to reconnect its driver
         usb_device_connect_kernel_driver(device, interfaceID, true);
     }
-    return ret;
+    return (ret == 0) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean
+android_hardware_UsbDeviceConnection_set_interface(JNIEnv *env, jobject thiz, jint interfaceID,
+        jint alternateSetting)
+{
+    struct usb_device* device = get_device_from_object(env, thiz);
+    if (!device) {
+        ALOGE("device is closed in native_set_interface");
+        return JNI_FALSE;
+    }
+    int ret = usb_device_set_interface(device, interfaceID, alternateSetting);
+    return (ret == 0) ? JNI_TRUE : JNI_FALSE;
+}
+
+static jboolean
+android_hardware_UsbDeviceConnection_set_configuration(JNIEnv *env, jobject thiz, jint configurationID)
+{
+    struct usb_device* device = get_device_from_object(env, thiz);
+    if (!device) {
+        ALOGE("device is closed in native_set_configuration");
+        return JNI_FALSE;
+    }
+    int ret = usb_device_set_configuration(device, configurationID);
+    return (ret == 0) ? JNI_TRUE : JNI_FALSE;
 }
 
 static jint
@@ -229,6 +254,8 @@
     {"native_get_desc",         "()[B", (void *)android_hardware_UsbDeviceConnection_get_desc},
     {"native_claim_interface",  "(IZ)Z",(void *)android_hardware_UsbDeviceConnection_claim_interface},
     {"native_release_interface","(I)Z", (void *)android_hardware_UsbDeviceConnection_release_interface},
+    {"native_set_interface","(II)Z",    (void *)android_hardware_UsbDeviceConnection_set_interface},
+    {"native_set_configuration","(I)Z", (void *)android_hardware_UsbDeviceConnection_set_configuration},
     {"native_control_request",  "(IIII[BIII)I",
                                         (void *)android_hardware_UsbDeviceConnection_control_request},
     {"native_bulk_request",     "(I[BIII)I",
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 3c7da1e..957f95c 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -19,13 +19,18 @@
 // #define LOG_NNDEBUG 0
 #define LOG_TAG "CameraMetadata-JNI"
 #include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <string.h>
 
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_os_Parcel.h"
 #include "android_runtime/AndroidRuntime.h"
 
+#include <binder/IServiceManager.h>
 #include <camera/CameraMetadata.h>
+#include <camera/ICameraService.h>
+#include <camera/VendorTagDescriptor.h>
 #include <nativehelper/ScopedUtfChars.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 
@@ -112,6 +117,7 @@
 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);
+static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz);
 
 // Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
 static CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) {
@@ -372,6 +378,9 @@
   { "nativeGetTypeFromTag",
     "(I)I",
     (void *)CameraMetadata_getTypeFromTag },
+  { "nativeSetupGlobalVendorTagDescriptor",
+    "()I",
+    (void*)CameraMetadata_setupGlobalVendorTagDescriptor },
 // instance methods
   { "nativeAllocate",
     "()J",
@@ -556,4 +565,34 @@
     return tagType;
 }
 
+static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz) {
+    const String16 NAME("media.camera");
+    sp<ICameraService> cameraService;
+    status_t err = getService(NAME, /*out*/&cameraService);
+
+    if (err != OK) {
+        ALOGE("%s: Failed to get camera service, received error %s (%d)", __FUNCTION__,
+                strerror(-err), err);
+        return err;
+    }
+
+    sp<VendorTagDescriptor> desc;
+    err = cameraService->getCameraVendorTagDescriptor(/*out*/desc);
+
+    if (err == -EOPNOTSUPP) {
+        ALOGW("%s: Camera HAL too old; does not support vendor tags", __FUNCTION__);
+        VendorTagDescriptor::clearGlobalVendorTagDescriptor();
+
+        return OK;
+    } else if (err != OK) {
+        ALOGE("%s: Failed to setup vendor tag descriptors, received error %s (%d)",
+                __FUNCTION__, strerror(-err), err);
+        return err;
+    }
+
+    err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+
+    return err;
+}
+
 } // extern "C"
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
new file mode 100644
index 0000000..f4bab26
--- /dev/null
+++ b/core/jni/android_media_AudioFormat.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIA_AUDIOFORMAT_H
+#define ANDROID_MEDIA_AUDIOFORMAT_H
+
+#include <system/audio.h>
+
+// keep these values in sync with AudioFormat.java
+#define ENCODING_PCM_16BIT 2
+#define ENCODING_PCM_8BIT  3
+
+static inline audio_format_t audioFormatToNative(int audioFormat)
+{
+    switch (audioFormat) {
+    case ENCODING_PCM_16BIT:
+        return AUDIO_FORMAT_PCM_16_BIT;
+    case ENCODING_PCM_8BIT:
+        return AUDIO_FORMAT_PCM_8_BIT;
+    default:
+        return AUDIO_FORMAT_INVALID;
+    }
+}
+
+#endif // ANDROID_MEDIA_AUDIOFORMAT_H
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index ab70f25..0132b5f 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -26,7 +26,7 @@
 #include <utils/Log.h>
 #include <media/AudioRecord.h>
 
-#include <system/audio.h>
+#include "android_media_AudioFormat.h"
 
 // ----------------------------------------------------------------------------
 
@@ -50,10 +50,6 @@
     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;
 
@@ -82,7 +78,6 @@
     }
 }
 
-
 // ----------------------------------------------------------------------------
 static void recorderCallback(int event, void* user, void *info) {
 
@@ -174,25 +169,23 @@
     uint32_t nbChannels = popcount(channelMask);
 
     // compare the format against the Java constants
-    if ((audioFormat != ENCODING_PCM_16BIT)
-        && (audioFormat != ENCODING_PCM_8BIT)) {
-        ALOGE("Error creating AudioRecord: unsupported audio format.");
+    audio_format_t format = audioFormatToNative(audioFormat);
+    if (format == AUDIO_FORMAT_INVALID) {
+        ALOGE("Error creating AudioRecord: unsupported audio format %d.", audioFormat);
         return (jint) AUDIORECORD_ERROR_SETUP_INVALIDFORMAT;
     }
 
-    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;
+    size_t bytesPerSample = audio_bytes_per_sample(format);
 
     if (buffSizeInBytes == 0) {
          ALOGE("Error creating AudioRecord: frameCount is 0.");
         return (jint) AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT;
     }
-    int frameSize = nbChannels * bytesPerSample;
+    size_t frameSize = nbChannels * bytesPerSample;
     size_t frameCount = buffSizeInBytes / frameSize;
 
     if ((uint32_t(source) >= AUDIO_SOURCE_CNT) && (uint32_t(source) != AUDIO_SOURCE_HOTWORD)) {
-        ALOGE("Error creating AudioRecord: unknown source.");
+        ALOGE("Error creating AudioRecord: unknown source %d.", source);
         return (jint) AUDIORECORD_ERROR_SETUP_INVALIDSOURCE;
     }
 
@@ -238,8 +231,10 @@
         true,          // threadCanCallJava
         sessionId);
 
-    if (lpRecorder->initCheck() != NO_ERROR) {
-        ALOGE("Error creating AudioRecord instance: initialization check failed.");
+    const status_t status = lpRecorder->initCheck();
+    if (status != NO_ERROR) {
+        ALOGE("Error creating AudioRecord instance: initialization check failed with status %d.",
+                status);
         goto native_init_failure;
     }
 
@@ -512,10 +507,10 @@
           sampleRateInHertz, nbChannels, audioFormat);
 
     size_t frameCount = 0;
+    audio_format_t format = audioFormatToNative(audioFormat);
     status_t result = AudioRecord::getMinFrameCount(&frameCount,
             sampleRateInHertz,
-            (audioFormat == ENCODING_PCM_16BIT ?
-                AUDIO_FORMAT_PCM_16_BIT : AUDIO_FORMAT_PCM_8_BIT),
+            format,
             audio_channel_in_mask_from_count(nbChannels));
 
     if (result == BAD_VALUE) {
@@ -524,7 +519,7 @@
     if (result != NO_ERROR) {
         return -1;
     }
-    return frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
+    return frameCount * nbChannels * audio_bytes_per_sample(format);
 }
 
 
diff --git a/core/jni/android_media_AudioSystem.cpp b/core/jni/android_media_AudioSystem.cpp
index a19d111..a9a62f8 100644
--- a/core/jni/android_media_AudioSystem.cpp
+++ b/core/jni/android_media_AudioSystem.cpp
@@ -100,7 +100,7 @@
         c_keyValuePairs8 = String8(c_keyValuePairs, env->GetStringLength(keyValuePairs));
         env->ReleaseStringCritical(keyValuePairs, c_keyValuePairs);
     }
-    int status = check_AudioSystem_Command(AudioSystem::setParameters(0, c_keyValuePairs8));
+    int status = check_AudioSystem_Command(AudioSystem::setParameters(c_keyValuePairs8));
     return (jint) status;
 }
 
@@ -113,7 +113,7 @@
         c_keys8 = String8(c_keys, env->GetStringLength(keys));
         env->ReleaseStringCritical(keys, c_keys);
     }
-    return env->NewStringUTF(AudioSystem::getParameters(0, c_keys8).string());
+    return env->NewStringUTF(AudioSystem::getParameters(c_keys8).string());
 }
 
 static void
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index dc8d9d8..3a5b566 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -17,10 +17,12 @@
 
 #define LOG_TAG "AudioTrack-JNI"
 
-#include <jni.h>
 #include <JNIHelp.h>
+#include <JniConstants.h>
 #include <android_runtime/AndroidRuntime.h>
 
+#include "ScopedBytes.h"
+
 #include <utils/Log.h>
 #include <media/AudioSystem.h>
 #include <media/AudioTrack.h>
@@ -28,7 +30,7 @@
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryBase.h>
 
-#include <system/audio.h>
+#include "android_media_AudioFormat.h"
 
 // ----------------------------------------------------------------------------
 
@@ -55,9 +57,6 @@
 // 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 {
@@ -195,7 +194,7 @@
 
 // ----------------------------------------------------------------------------
 static jint
-android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
+android_media_AudioTrack_setup(JNIEnv *env, jobject thiz, jobject weak_this,
         jint streamType, jint sampleRateInHertz, jint javaChannelMask,
         jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession)
 {
@@ -244,7 +243,8 @@
 
     // check the format.
     // This function was called from Java, so we compare the format against the Java constants
-    if ((audioFormat != ENCODING_PCM_16BIT) && (audioFormat != ENCODING_PCM_8BIT)) {
+    audio_format_t format = audioFormatToNative(audioFormat);
+    if (format == AUDIO_FORMAT_INVALID) {
 
         ALOGE("Error creating AudioTrack: unsupported audio format.");
         return (jint) AUDIOTRACK_ERROR_SETUP_INVALIDFORMAT;
@@ -253,21 +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 == ENCODING_PCM_8BIT)
+    if ((format == AUDIO_FORMAT_PCM_8_BIT)
         && (memoryMode == MODE_STATIC)) {
-        ALOGV("android_media_AudioTrack_native_setup(): requesting MODE_STATIC for 8bit \
+        ALOGV("android_media_AudioTrack_setup(): requesting MODE_STATIC for 8bit \
             buff size of %dbytes, switching to 16bit, buff size of %dbytes",
             buffSizeInBytes, 2*buffSizeInBytes);
-        audioFormat = ENCODING_PCM_16BIT;
+        format = AUDIO_FORMAT_PCM_16_BIT;
         // we will need twice the memory to store the data
         buffSizeInBytes *= 2;
     }
 
     // compute the frame count
-    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);
+    const size_t bytesPerSample = audio_bytes_per_sample(format);
+    size_t frameCount = buffSizeInBytes / (nbChannels * bytesPerSample);
 
     jclass clazz = env->GetObjectClass(thiz);
     if (clazz == NULL) {
@@ -465,7 +463,7 @@
 // ----------------------------------------------------------------------------
 
 #define CALLBACK_COND_WAIT_TIMEOUT_MS 1000
-static void android_media_AudioTrack_native_release(JNIEnv *env,  jobject thiz) {
+static void android_media_AudioTrack_release(JNIEnv *env,  jobject thiz) {
     sp<AudioTrack> lpTrack = setAudioTrack(env, thiz, 0);
     if (lpTrack == NULL) {
         return;
@@ -501,32 +499,44 @@
 
 
 // ----------------------------------------------------------------------------
-static void android_media_AudioTrack_native_finalize(JNIEnv *env,  jobject thiz) {
-    //ALOGV("android_media_AudioTrack_native_finalize jobject: %x\n", (int)thiz);
-    android_media_AudioTrack_native_release(env, thiz);
+static void android_media_AudioTrack_finalize(JNIEnv *env,  jobject thiz) {
+    //ALOGV("android_media_AudioTrack_finalize jobject: %x\n", (int)thiz);
+    android_media_AudioTrack_release(env, thiz);
 }
 
 // ----------------------------------------------------------------------------
-jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, jbyte* data,
-                  jint offsetInBytes, jint sizeInBytes) {
+jint writeToTrack(const sp<AudioTrack>& track, jint audioFormat, const jbyte* data,
+                  jint offsetInBytes, jint sizeInBytes, bool blocking = true) {
     // give the data to the native AudioTrack object (the data starts at the offset)
     ssize_t written = 0;
     // regular write() or copy the data to the AudioTrack's shared memory?
     if (track->sharedBuffer() == 0) {
-        written = track->write(data + offsetInBytes, sizeInBytes);
+        written = track->write(data + offsetInBytes, sizeInBytes, blocking);
         // for compatibility with earlier behavior of write(), return 0 in this case
         if (written == (ssize_t) WOULD_BLOCK) {
             written = 0;
         }
     } else {
-        if (audioFormat == ENCODING_PCM_16BIT) {
+        const audio_format_t format = audioFormatToNative(audioFormat);
+        switch (format) {
+
+        default:
+            // TODO Currently the only possible values for format are AUDIO_FORMAT_PCM_16_BIT
+            // and AUDIO_FORMAT_PCM_8_BIT, due to the limited set of values for audioFormat.
+            // The next section of the switch will probably work for more formats, but it has only
+            // been tested for AUDIO_FORMAT_PCM_16_BIT, so that's why the "default" case fails.
+            break;
+
+        case AUDIO_FORMAT_PCM_16_BIT: {
             // 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 == ENCODING_PCM_8BIT) {
+            } break;
+
+        case AUDIO_FORMAT_PCM_8_BIT: {
             // data contains 8bit data we need to expand to 16bit before copying
             // to the shared memory
             // writing to shared memory, check for capacity,
@@ -543,6 +553,8 @@
             // even though we wrote 2*sizeInBytes, we only report sizeInBytes as written to hide
             // the 8bit mixer restriction from the user of this function
             written = sizeInBytes;
+            } break;
+
         }
     }
     return written;
@@ -550,11 +562,12 @@
 }
 
 // ----------------------------------------------------------------------------
-static jint android_media_AudioTrack_native_write_byte(JNIEnv *env,  jobject thiz,
+static jint android_media_AudioTrack_write_byte(JNIEnv *env,  jobject thiz,
                                                   jbyteArray javaAudioData,
                                                   jint offsetInBytes, jint sizeInBytes,
-                                                  jint javaAudioFormat) {
-    //ALOGV("android_media_AudioTrack_native_write_byte(offset=%d, sizeInBytes=%d) called",
+                                                  jint javaAudioFormat,
+                                                  jboolean isWriteBlocking) {
+    //ALOGV("android_media_AudioTrack_write_byte(offset=%d, sizeInBytes=%d) called",
     //    offsetInBytes, sizeInBytes);
     sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
     if (lpTrack == NULL) {
@@ -580,7 +593,8 @@
         return 0;
     }
 
-    jint written = writeToTrack(lpTrack, javaAudioFormat, cAudioData, offsetInBytes, sizeInBytes);
+    jint written = writeToTrack(lpTrack, javaAudioFormat, cAudioData, offsetInBytes, sizeInBytes,
+            isWriteBlocking == JNI_TRUE /* blocking */);
 
     env->ReleaseByteArrayElements(javaAudioData, cAudioData, 0);
 
@@ -591,14 +605,40 @@
 
 
 // ----------------------------------------------------------------------------
-static jint android_media_AudioTrack_native_write_short(JNIEnv *env,  jobject thiz,
+static jint android_media_AudioTrack_write_native_bytes(JNIEnv *env,  jobject thiz,
+        jbyteArray javaBytes, jint byteOffset, jint sizeInBytes,
+        jint javaAudioFormat, jboolean isWriteBlocking) {
+    //ALOGV("android_media_AudioTrack_write_native_bytes(offset=%d, sizeInBytes=%d) called",
+    //    offsetInBytes, sizeInBytes);
+    sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+    if (lpTrack == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException",
+                "Unable to retrieve AudioTrack pointer for write()");
+        return 0;
+    }
+
+    ScopedBytesRO bytes(env, javaBytes);
+    if (bytes.get() == NULL) {
+        ALOGE("Error retrieving source of audio data to play, can't play");
+        return AUDIOTRACK_ERROR_BAD_VALUE;
+    }
+
+    jint written = writeToTrack(lpTrack, javaAudioFormat, bytes.get(), byteOffset,
+            sizeInBytes, isWriteBlocking == JNI_TRUE /* blocking */);
+
+    return written;
+}
+
+// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_write_short(JNIEnv *env,  jobject thiz,
                                                   jshortArray javaAudioData,
                                                   jint offsetInShorts, jint sizeInShorts,
                                                   jint javaAudioFormat) {
-    jint written = android_media_AudioTrack_native_write_byte(env, thiz,
+    jint written = android_media_AudioTrack_write_byte(env, thiz,
                                                  (jbyteArray) javaAudioData,
                                                  offsetInShorts*2, sizeInShorts*2,
-                                                 javaAudioFormat);
+                                                 javaAudioFormat,
+                                                 JNI_TRUE /*blocking write, legacy behavior*/);
     if (written > 0) {
         written /= 2;
     }
@@ -795,7 +835,7 @@
         jint javaStreamType) {
     uint32_t afSamplingRate;
     // convert the stream type from Java to native value
-    // FIXME: code duplication with android_media_AudioTrack_native_setup()
+    // FIXME: code duplication with android_media_AudioTrack_setup()
     audio_stream_type_t nativeStreamType;
     switch (javaStreamType) {
     case AUDIO_STREAM_VOICE_CALL:
@@ -829,12 +869,17 @@
 static jint android_media_AudioTrack_get_min_buff_size(JNIEnv *env,  jobject thiz,
     jint sampleRateInHertz, jint nbChannels, jint audioFormat) {
 
-    size_t frameCount = 0;
-    if (AudioTrack::getMinFrameCount(&frameCount, AUDIO_STREAM_DEFAULT,
-            sampleRateInHertz) != NO_ERROR) {
+    size_t frameCount;
+    const status_t status = AudioTrack::getMinFrameCount(&frameCount, AUDIO_STREAM_DEFAULT,
+            sampleRateInHertz);
+    if (status != NO_ERROR) {
+        ALOGE("AudioTrack::getMinFrameCount() for sample rate %d failed with status %d",
+                sampleRateInHertz, status);
         return -1;
     }
-    return frameCount * nbChannels * (audioFormat == ENCODING_PCM_16BIT ? 2 : 1);
+    const audio_format_t format = audioFormatToNative(audioFormat);
+    const size_t bytesPerSample = audio_bytes_per_sample(format);
+    return frameCount * nbChannels * bytesPerSample;
 }
 
 // ----------------------------------------------------------------------------
@@ -872,11 +917,14 @@
     {"native_pause",         "()V",      (void *)android_media_AudioTrack_pause},
     {"native_flush",         "()V",      (void *)android_media_AudioTrack_flush},
     {"native_setup",         "(Ljava/lang/Object;IIIIII[I)I",
-                                         (void *)android_media_AudioTrack_native_setup},
-    {"native_finalize",      "()V",      (void *)android_media_AudioTrack_native_finalize},
-    {"native_release",       "()V",      (void *)android_media_AudioTrack_native_release},
-    {"native_write_byte",    "([BIII)I", (void *)android_media_AudioTrack_native_write_byte},
-    {"native_write_short",   "([SIII)I", (void *)android_media_AudioTrack_native_write_short},
+                                         (void *)android_media_AudioTrack_setup},
+    {"native_finalize",      "()V",      (void *)android_media_AudioTrack_finalize},
+    {"native_release",       "()V",      (void *)android_media_AudioTrack_release},
+    {"native_write_byte",    "([BIIIZ)I",(void *)android_media_AudioTrack_write_byte},
+    {"native_write_native_bytes",
+                             "(Ljava/lang/Object;IIIZ)I",
+                                         (void *)android_media_AudioTrack_write_native_bytes},
+    {"native_write_short",   "([SIII)I", (void *)android_media_AudioTrack_write_short},
     {"native_setVolume",     "(FF)V",    (void *)android_media_AudioTrack_set_volume},
     {"native_get_native_frame_count",
                              "()I",      (void *)android_media_AudioTrack_get_native_frame_count},
diff --git a/core/jni/android_net_wifi_WifiNative.cpp b/core/jni/android_net_wifi_WifiNative.cpp
deleted file mode 100644
index 6e11192..0000000
--- a/core/jni/android_net_wifi_WifiNative.cpp
+++ /dev/null
@@ -1,173 +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 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_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 591ff77..e72aff9 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -42,14 +42,13 @@
 #include <SkTemplates.h>
 #include <SkXfermode.h>
 
-#include <DisplayList.h>
 #include <DisplayListRenderer.h>
 #include <LayerRenderer.h>
 #include <OpenGLRenderer.h>
 #include <SkiaShader.h>
-#include <SkiaColorFilter.h>
 #include <Stencil.h>
 #include <Rect.h>
+#include <RenderNode.h>
 
 #include <TextLayout.h>
 #include <TextLayoutCache.h>
@@ -81,7 +80,6 @@
 
 #define MODIFIER_SHADOW 1
 #define MODIFIER_SHADER 2
-#define MODIFIER_COLOR_FILTER 4
 
 // ----------------------------------------------------------------------------
 
@@ -138,8 +136,8 @@
 }
 
 static void android_view_GLES20Canvas_destroyRenderer(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     RENDERER_LOGD("Destroy OpenGLRenderer");
     delete renderer;
 }
@@ -149,27 +147,27 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_setViewport(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint width, jint height) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jint width, jint height) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->setViewport(width, height);
 }
 
-static jint android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jboolean opaque) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+static int android_view_GLES20Canvas_prepare(JNIEnv* env, jobject clazz,
+        jlong rendererPtr, jboolean opaque) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     return renderer->prepare(opaque);
 }
 
-static jint android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint left, jint top, jint right, jint bottom,
+static int android_view_GLES20Canvas_prepareDirty(JNIEnv* env, jobject clazz,
+        jlong rendererPtr, jint left, jint top, jint right, jint bottom,
         jboolean opaque) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     return renderer->prepareDirty(left, top, right, bottom, opaque);
 }
 
 static void android_view_GLES20Canvas_finish(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->finish();
 }
 
@@ -177,28 +175,22 @@
     return Stencil::getStencilSize();
 }
 
-static void android_view_GLES20Canvas_setName(JNIEnv* env,
-        jobject clazz, jlong rendererHandle, jstring name) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    if (name != NULL) {
-        const char* textArray = env->GetStringUTFChars(name, NULL);
-        renderer->setName(textArray);
-        env->ReleaseStringUTFChars(name, textArray);
-    } else {
-        renderer->setName(NULL);
+static void android_view_GLES20Canvas_setProperty(JNIEnv* env,
+        jobject clazz, jstring name, jstring value) {
+    if (!Caches::hasInstance()) {
+        ALOGW("can't set property, no Caches instance");
+        return;
     }
-}
 
-static void android_view_GLES20Canvas_setCountOverdrawEnabled(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jboolean enabled) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    renderer->setCountOverdrawEnabled(enabled);
-}
+    if (name == NULL || value == NULL) {
+        ALOGW("can't set prop, null passed");
+    }
 
-static jfloat android_view_GLES20Canvas_getOverdraw(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    return renderer->getOverdraw();
+    const char* nameCharArray = env->GetStringUTFChars(name, NULL);
+    const char* valueCharArray = env->GetStringUTFChars(value, NULL);
+    Caches::getInstance().setTempProperty(nameCharArray, valueCharArray);
+    env->ReleaseStringUTFChars(name, nameCharArray);
+    env->ReleaseStringUTFChars(name, valueCharArray);
 }
 
 // ----------------------------------------------------------------------------
@@ -206,9 +198,9 @@
 // ----------------------------------------------------------------------------
 
 static jint android_view_GLES20Canvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong functorHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    Functor* functor = reinterpret_cast<Functor*>(functorHandle);
+        jlong rendererPtr, jlong functorPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
     android::uirenderer::Rect dirty;
     return renderer->callDrawGLFunction(functor, dirty);
 }
@@ -221,15 +213,15 @@
 }
 
 static void android_view_GLES20Canvas_attachFunctor(JNIEnv* env,
-        jobject clazz, jlong rendererHandle, jlong functorHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    Functor* functor = reinterpret_cast<Functor*>(functorHandle);
+        jobject clazz, jlong rendererPtr, jlong functorPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
     renderer->attachFunctor(functor);
 }
 
 static jint android_view_GLES20Canvas_invokeFunctors(JNIEnv* env,
-        jobject clazz, jlong rendererHandle, jobject dirty) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jobject clazz, jlong rendererPtr, jobject dirty) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     android::uirenderer::Rect bounds;
     status_t status = renderer->invokeFunctors(bounds);
     if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
@@ -255,27 +247,27 @@
 // State
 // ----------------------------------------------------------------------------
 
-static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererHandle,
+static jint android_view_GLES20Canvas_save(JNIEnv* env, jobject clazz, jlong rendererPtr,
         jint flags) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     return renderer->save(flags);
 }
 
 static jint android_view_GLES20Canvas_getSaveCount(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     return renderer->getSaveCount();
 }
 
 static void android_view_GLES20Canvas_restore(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->restore();
 }
 
 static void android_view_GLES20Canvas_restoreToCount(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint saveCount) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jint saveCount) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->restoreToCount(saveCount);
 }
 
@@ -284,32 +276,32 @@
 // ----------------------------------------------------------------------------
 
 static jint android_view_GLES20Canvas_saveLayer(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
-        jlong paintHandle, jint saveFlags) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
+        jlong paintPtr, jint saveFlags) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     return renderer->saveLayer(left, top, right, bottom, paint, saveFlags);
 }
 
 static jint android_view_GLES20Canvas_saveLayerClip(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong paintHandle, jint saveFlags) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jlong paintPtr, jint saveFlags) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     const android::uirenderer::Rect& bounds(renderer->getClipBounds());
     return renderer->saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
             paint, saveFlags);
 }
 
 static jint android_view_GLES20Canvas_saveLayerAlpha(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
         jint alpha, jint saveFlags) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     return renderer->saveLayerAlpha(left, top, right, bottom, alpha, saveFlags);
 }
 
 static jint android_view_GLES20Canvas_saveLayerAlphaClip(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint alpha, jint saveFlags) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jint alpha, jint saveFlags) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     const android::uirenderer::Rect& bounds(renderer->getClipBounds());
     return renderer->saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom,
             alpha, saveFlags);
@@ -320,50 +312,50 @@
 // ----------------------------------------------------------------------------
 
 static jboolean android_view_GLES20Canvas_quickReject(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    bool result = renderer->quickRejectNoScissor(left, top, right, bottom);
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    const bool result = renderer->quickRejectConservative(left, top, right, bottom);
     return result ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean android_view_GLES20Canvas_clipRectF(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
-        jint opHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
-    bool result;
-    result = renderer->clipRect(left, top, right, bottom, op);
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
+        jint op) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    const bool result = renderer->clipRect(left, top, right, bottom,
+                                           static_cast<SkRegion::Op>(op));
     return result ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean android_view_GLES20Canvas_clipRect(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint left, jint top, jint right, jint bottom,
-        jint opHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
-    bool result = renderer->clipRect(float(left), float(top), float(right), float(bottom), op);
+        jlong rendererPtr, jint left, jint top, jint right, jint bottom,
+        jint op) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    const bool result = renderer->clipRect(float(left), float(top), float(right),
+                                           float(bottom),
+                                           static_cast<SkRegion::Op>(op));
     return result ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean android_view_GLES20Canvas_clipPath(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong pathHandle, jint opHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
-    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
-    return renderer->clipPath(path, op) ? JNI_TRUE : JNI_FALSE;
+        jlong rendererPtr, jlong pathPtr, jint op) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
+    const bool result = renderer->clipPath(path, static_cast<SkRegion::Op>(op));
+    return result ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean android_view_GLES20Canvas_clipRegion(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong regionHandle, jint opHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
-    SkRegion::Op op = static_cast<SkRegion::Op>(opHandle);
-    return renderer->clipRegion(region, op) ? JNI_TRUE : JNI_FALSE;
+        jlong rendererPtr, jlong regionPtr, jint op) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
+    const bool result = renderer->clipRegion(region, static_cast<SkRegion::Op>(op));
+    return result ? JNI_TRUE : JNI_FALSE;
 }
 
 static jboolean android_view_GLES20Canvas_getClipBounds(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jobject rect) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jobject rect) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     const android::uirenderer::Rect& bounds(renderer->getClipBounds());
 
     env->CallVoidMethod(rect, gRectClassInfo.set,
@@ -377,47 +369,47 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_translate(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat dx, jfloat dy) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jfloat dx, jfloat dy) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->translate(dx, dy);
 }
 
 static void android_view_GLES20Canvas_rotate(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat degrees) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jfloat degrees) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->rotate(degrees);
 }
 
 static void android_view_GLES20Canvas_scale(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat sx, jfloat sy) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jfloat sx, jfloat sy) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->scale(sx, sy);
 }
 
 static void android_view_GLES20Canvas_skew(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat sx, jfloat sy) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jfloat sx, jfloat sy) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->skew(sx, sy);
 }
 
 static void android_view_GLES20Canvas_setMatrix(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong matrixHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
+        jlong rendererPtr, jlong matrixPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     renderer->setMatrix(matrix);
 }
 
 static void android_view_GLES20Canvas_getMatrix(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong matrixHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
+        jlong rendererPtr, jlong matrixPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     renderer->getMatrix(matrix);
 }
 
 static void android_view_GLES20Canvas_concatMatrix(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong matrixHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
+        jlong rendererPtr, jlong matrixPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
     renderer->concatMatrix(matrix);
 }
 
@@ -426,49 +418,47 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_drawBitmap(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong bitmapHandle, jbyteArray buffer,
-        jfloat left, jfloat top, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
+        jfloat left, jfloat top, jlong paintPtr) {
+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawBitmap(bitmap, left, top, paint);
 }
 
 static void android_view_GLES20Canvas_drawBitmapRect(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong bitmapHandle, jbyteArray buffer,
-        jfloat srcLeft, jfloat srcTop, jfloat srcRight, jfloat srcBottom,
-        jfloat dstLeft, jfloat dstTop, jfloat dstRight, jfloat dstBottom, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
+        float srcLeft, float srcTop, float srcRight, float srcBottom,
+        float dstLeft, float dstTop, float dstRight, float dstBottom, jlong paintPtr) {
+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
             dstLeft, dstTop, dstRight, dstBottom, paint);
 }
 
 static void android_view_GLES20Canvas_drawBitmapMatrix(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong bitmapHandle, jbyteArray buffer,
-        jlong matrixHandle, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
+        jlong matrixPtr, jlong paintPtr) {
+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawBitmap(bitmap, matrix, paint);
 }
 
 static void android_view_GLES20Canvas_drawBitmapData(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jintArray colors, jint offset, jint stride,
-        jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jintArray colors, jint offset, jint stride,
+        jfloat left, jfloat top, jint width, jint height, jboolean hasAlpha, jlong paintPtr) {
     SkBitmap* bitmap = new SkBitmap;
     bitmap->setConfig(hasAlpha ? SkBitmap::kARGB_8888_Config : SkBitmap::kRGB_565_Config,
             width, height);
@@ -483,27 +473,29 @@
         return;
     }
 
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawBitmapData(bitmap, left, top, paint);
 
     // If the renderer is a deferred renderer it will own the bitmap
-    if (!renderer->isDeferred()) {
+    if (!renderer->isRecording()) {
         delete bitmap;
     }
 }
 
 static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong bitmapHandle, jbyteArray buffer,
+        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer,
         jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset, jintArray colors,
-        jint colorOffset, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jint colorOffset, jlong paintPtr) {
+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
     jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
     jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
 
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint);
 
     if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0);
@@ -511,70 +503,68 @@
 }
 
 static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong bitmapHandle, jbyteArray buffer, jlong patchHandle,
-        jfloat left, jfloat top, jfloat right, jfloat bottom, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
-    Res_png_9patch* patch  = reinterpret_cast<Res_png_9patch*>(patchHandle);
-    SkPaint* paint  = reinterpret_cast<SkPaint*>(paintHandle);
-
+        jlong rendererPtr, jlong bitmapPtr, jbyteArray buffer, jlong patchPtr,
+        float left, float top, float right, float bottom, jlong paintPtr) {
+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
     // This object allows the renderer to allocate a global JNI ref to the buffer object.
     JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
 
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    Res_png_9patch* patch = reinterpret_cast<Res_png_9patch*>(patchPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawPatch(bitmap, patch, left, top, right, bottom, paint);
 }
 
 static void android_view_GLES20Canvas_drawColor(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint color, SkXfermode::Mode mode) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    renderer->drawColor(color, mode);
+        jlong rendererPtr, jint color, jint mode) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    renderer->drawColor(color, static_cast<SkXfermode::Mode>(mode));
 }
 
 static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
-        jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
+        jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawRect(left, top, right, bottom, paint);
 }
 
 static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
-        jfloat rx, jfloat ry, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
+        jfloat rx, jfloat ry, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
 }
 
 static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat x, jfloat y, jfloat radius, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloat x, jfloat y, jfloat radius, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawCircle(x, y, radius, paint);
 }
 
 static void android_view_GLES20Canvas_drawOval(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
-        jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
+        jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawOval(left, top, right, bottom, paint);
 }
 
 static void android_view_GLES20Canvas_drawArc(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat left, jfloat top, jfloat right, jfloat bottom,
-        jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloat left, jfloat top, jfloat right, jfloat bottom,
+        jfloat startAngle, jfloat sweepAngle, jboolean useCenter, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawArc(left, top, right, bottom, startAngle, sweepAngle, useCenter, paint);
 }
 
 static void android_view_GLES20Canvas_drawRegionAsRects(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong regionHandle, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
-
+        jlong rendererPtr, jlong regionPtr, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkRegion* region = reinterpret_cast<SkRegion*>(regionPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     if (paint->getStyle() != SkPaint::kFill_Style ||
             (paint->isAntiAlias() && !renderer->isCurrentTransformSimple())) {
         SkRegion::Iterator it(*region);
@@ -601,36 +591,36 @@
 }
 
 static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloatArray rects, jint count, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloatArray rects, jint count, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     jfloat* storage = env->GetFloatArrayElements(rects, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawRects(storage, count, paint);
     env->ReleaseFloatArrayElements(rects, storage, 0);
 }
 
 static void android_view_GLES20Canvas_drawPoints(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloatArray points, jint offset, jint count, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     jfloat* storage = env->GetFloatArrayElements(points, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawPoints(storage + offset, count, paint);
     env->ReleaseFloatArrayElements(points, storage, 0);
 }
 
 static void android_view_GLES20Canvas_drawPath(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong pathHandle, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jlong pathPtr, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawPath(path, paint);
 }
 
 static void android_view_GLES20Canvas_drawLines(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloatArray points, jint offset, jint count, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jfloatArray points, jint offset, jint count, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     jfloat* storage = env->GetFloatArrayElements(points, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
     renderer->drawLines(storage + offset, count, paint);
     env->ReleaseFloatArrayElements(points, storage, 0);
 }
@@ -640,30 +630,23 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_resetModifiers(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint modifiers) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jint modifiers) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     if (modifiers & MODIFIER_SHADOW) renderer->resetShadow();
     if (modifiers & MODIFIER_SHADER) renderer->resetShader();
-    if (modifiers & MODIFIER_COLOR_FILTER) renderer->resetColorFilter();
 }
 
 static void android_view_GLES20Canvas_setupShader(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong shaderHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkiaShader* shader = reinterpret_cast<SkiaShader*>(shaderHandle);
+        jlong rendererPtr, jlong shaderPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    SkiaShader* shader = reinterpret_cast<SkiaShader*>(shaderPtr);
     renderer->setupShader(shader);
 }
 
-static void android_view_GLES20Canvas_setupColorFilter(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong filterHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkiaColorFilter* filter = reinterpret_cast<SkiaColorFilter*>(filterHandle);
-    renderer->setupColorFilter(filter);
-}
 
 static void android_view_GLES20Canvas_setupShadow(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jfloat radius, jfloat dx, jfloat dy, jint color) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jfloat radius, jfloat dx, jfloat dy, jint color) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->setupShadow(radius, dx, dy, color);
 }
 
@@ -672,14 +655,14 @@
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_setupPaintFilter(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jint clearBits, jint setBits) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr, jint clearBits, jint setBits) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->setupPaintFilter(clearBits, setBits);
 }
 
 static void android_view_GLES20Canvas_resetPaintFilter(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->resetPaintFilter();
 }
 
@@ -759,70 +742,76 @@
 }
 
 static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jcharArray text, jint index, jint count,
-        jfloat x, jfloat y, jint flags, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jcharArray text, jint index, jint count,
+        jfloat x, jfloat y, jint flags, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     jchar* textArray = env->GetCharArrayElements(text, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+
     renderText(renderer, textArray + index, count, x, y, flags, paint);
     env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
 }
 
 static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jstring text, jint start, jint end,
-        jfloat x, jfloat y, jint flags, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jstring text, jint start, jint end,
+        jfloat x, jfloat y, jint flags, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     const jchar* textArray = env->GetStringChars(text, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+
     renderText(renderer, textArray + start, end - start, x, y, flags, paint);
     env->ReleaseStringChars(text, textArray);
 }
 
 static void android_view_GLES20Canvas_drawTextArrayOnPath(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jcharArray text, jint index, jint count,
-        jlong pathHandle, jfloat hOffset, jfloat vOffset, jint flags, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jcharArray text, jint index, jint count,
+        jlong pathPtr, jfloat hOffset, jfloat vOffset, jint flags, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     jchar* textArray = env->GetCharArrayElements(text, NULL);
+    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+
     renderTextOnPath(renderer, textArray + index, count, path,
             hOffset, vOffset, flags, paint);
     env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
 }
 
 static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jstring text, jint start, jint end,
-        jlong pathHandle, jfloat hOffset, jfloat vOffset, jint flags, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jstring text, jint start, jint end,
+        jlong pathPtr, jfloat hOffset, jfloat vOffset, jint flags, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     const jchar* textArray = env->GetStringChars(text, NULL);
+    SkPath* path = reinterpret_cast<SkPath*>(pathPtr);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+
     renderTextOnPath(renderer, textArray + start, end - start, path,
             hOffset, vOffset, flags, paint);
     env->ReleaseStringChars(text, textArray);
 }
 
 static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jcharArray text, jint index, jint count,
+        jlong rendererPtr, jcharArray text, jint index, jint count,
         jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
-        jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     jchar* textArray = env->GetCharArrayElements(text, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+
     renderTextRun(renderer, textArray + contextIndex, index - contextIndex,
             count, contextCount, x, y, dirFlags, paint);
     env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
  }
 
 static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jstring text, jint start, jint end,
-        jint contextStart, jint contextEnd, jfloat x, jfloat y, jint dirFlags,
-        jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jstring text, jint start, jint end,
+        jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags,
+        jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     const jchar* textArray = env->GetStringChars(text, NULL);
     jint count = end - start;
     jint contextCount = contextEnd - contextStart;
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+
     renderTextRun(renderer, textArray + contextStart, start - contextStart,
             count, contextCount, x, y, dirFlags, paint);
     env->ReleaseStringChars(text, textArray);
@@ -844,12 +833,12 @@
 }
 
 static void android_view_GLES20Canvas_drawPosTextArray(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jcharArray text, jint index, jint count,
-        jfloatArray pos, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jcharArray text, jint index, jint count,
+        jfloatArray pos, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     jchar* textArray = env->GetCharArrayElements(text, NULL);
     jfloat* positions = env->GetFloatArrayElements(pos, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
 
     renderPosText(renderer, textArray + index, count, positions, kBidi_LTR, paint);
 
@@ -858,12 +847,12 @@
 }
 
 static void android_view_GLES20Canvas_drawPosText(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jstring text, jint start, jint end,
-        jfloatArray pos, jlong paintHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
+        jlong rendererPtr, jstring text, jint start, jint end,
+        jfloatArray pos, jlong paintPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     const jchar* textArray = env->GetStringChars(text, NULL);
     jfloat* positions = env->GetFloatArrayElements(pos, NULL);
+    SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
 
     renderPosText(renderer, textArray + start, end - start, positions, kBidi_LTR, paint);
 
@@ -875,31 +864,22 @@
 // Display lists
 // ----------------------------------------------------------------------------
 
-static jlong android_view_GLES20Canvas_getDisplayList(JNIEnv* env,
-        jobject clazz, jlong rendererHandle, jlong displayListHandle) {
-    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererHandle);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    DisplayList* list = renderer->getDisplayList(displayList);
-    return reinterpret_cast<jlong>(list);
+static jlong android_view_GLES20Canvas_finishRecording(JNIEnv* env,
+        jobject clazz, jlong rendererPtr) {
+    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererPtr);
+    return reinterpret_cast<jlong>(renderer->finishRecording());
 }
 
 static jlong android_view_GLES20Canvas_createDisplayListRenderer(JNIEnv* env,
         jobject clazz) {
-    OpenGLRenderer* renderer = new DisplayListRenderer;
-    return reinterpret_cast<jlong>(renderer);
-}
-
-static void android_view_GLES20Canvas_resetDisplayListRenderer(JNIEnv* env,
-        jobject clazz, jlong rendererHandle) {
-    DisplayListRenderer* renderer = reinterpret_cast<DisplayListRenderer*>(rendererHandle);
-    renderer->reset();
+    return reinterpret_cast<jlong>(new DisplayListRenderer);
 }
 
 static jint android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
-        jobject clazz, jlong rendererHandle, jlong displayListHandle,
+        jobject clazz, jlong rendererPtr, jlong displayListPtr,
         jobject dirty, jint flags) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
     android::uirenderer::Rect bounds;
     status_t status = renderer->drawDisplayList(displayList, bounds, flags);
     if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
@@ -909,207 +889,59 @@
     return status;
 }
 
-static void android_view_GLES20Canvas_outputDisplayList(JNIEnv* env,
-        jobject clazz, jlong rendererHandle, jlong displayListHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    renderer->outputDisplayList(displayList);
-}
-
 // ----------------------------------------------------------------------------
 // Layers
 // ----------------------------------------------------------------------------
 
 static void android_view_GLES20Canvas_interrupt(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->interrupt();
 }
 
 static void android_view_GLES20Canvas_resume(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->resume();
 }
 
-static jlong android_view_GLES20Canvas_createLayerRenderer(JNIEnv* env,
-        jobject clazz, jlong layerHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    if (layer) {
-        OpenGLRenderer* renderer = new LayerRenderer(layer);
-        renderer->initProperties();
-        return reinterpret_cast<jlong>(renderer);
-    }
-    return NULL;
-}
-
-static jlong android_view_GLES20Canvas_createTextureLayer(JNIEnv* env, jobject clazz,
-        jboolean isOpaque, jintArray layerInfo) {
-    Layer* layer = LayerRenderer::createTextureLayer(isOpaque);
-
-    if (layer) {
-        jint* storage = env->GetIntArrayElements(layerInfo, NULL);
-        storage[0] = layer->getTexture();
-        env->ReleaseIntArrayElements(layerInfo, storage, 0);
-    }
-
-    return reinterpret_cast<jlong>(layer);
-}
-
-static jlong android_view_GLES20Canvas_createLayer(JNIEnv* env, jobject clazz,
-        jint width, jint height, jboolean isOpaque, jintArray layerInfo) {
-    Layer* layer = LayerRenderer::createLayer(width, height, isOpaque);
-
-    if (layer) {
-        jint* storage = env->GetIntArrayElements(layerInfo, NULL);
-        storage[0] = layer->getWidth();
-        storage[1] = layer->getHeight();
-        env->ReleaseIntArrayElements(layerInfo, storage, 0);
-    }
-
-    return reinterpret_cast<jlong>(layer);
-}
-
-static jboolean android_view_GLES20Canvas_resizeLayer(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jint width, jint height, jintArray layerInfo) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    if (LayerRenderer::resizeLayer(layer, width, height)) {
-        jint* storage = env->GetIntArrayElements(layerInfo, NULL);
-        storage[0] = layer->getWidth();
-        storage[1] = layer->getHeight();
-        env->ReleaseIntArrayElements(layerInfo, storage, 0);
-        return JNI_TRUE;
-    }
-    return JNI_FALSE;
-}
-
-static void android_view_GLES20Canvas_setLayerPaint(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jlong paintHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
-    if (layer) {
-        layer->setPaint(paint);
-    }
-}
-
-static void android_view_GLES20Canvas_setLayerColorFilter(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jlong colorFilterHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    SkiaColorFilter* colorFilter = reinterpret_cast<SkiaColorFilter*>(colorFilterHandle);
-    if (layer) {
-        layer->setColorFilter(colorFilter);
-    }
-}
-
-static void android_view_GLES20Canvas_setOpaqueLayer(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jboolean isOpaque) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    if (layer) {
-        layer->setBlend(!isOpaque);
-    }
-}
-
-static void android_view_GLES20Canvas_updateTextureLayer(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jint width, jint height, jboolean isOpaque, jobject surface) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    float transform[16];
-    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
-
-    if (surfaceTexture->updateTexImage() == NO_ERROR) {
-        int64_t frameNumber = surfaceTexture->getFrameNumber();
-        // If the GLConsumer queue is in synchronous mode, need to discard all
-        // but latest frame, using the frame number to tell when we no longer
-        // have newer frames to target. Since we can't tell which mode it is in,
-        // do this unconditionally.
-        int dropCounter = 0;
-        while (surfaceTexture->updateTexImage() == NO_ERROR) {
-            int64_t newFrameNumber = surfaceTexture->getFrameNumber();
-            if (newFrameNumber == frameNumber) break;
-            frameNumber = newFrameNumber;
-            dropCounter++;
-        }
-        #if DEBUG_RENDERER
-        if (dropCounter > 0) {
-            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
-        }
-        #endif
-        surfaceTexture->getTransformMatrix(transform);
-        GLenum renderTarget = surfaceTexture->getCurrentTextureTarget();
-
-        LayerRenderer::updateTextureLayer(layer, width, height, isOpaque, renderTarget, transform);
-    }
-}
-
-static void android_view_GLES20Canvas_updateRenderLayer(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jlong rendererHandle, jlong displayListHandle,
-        jint left, jint top, jint right, jint bottom) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    layer->updateDeferred(renderer, displayList, left, top, right, bottom);
-}
-
-static void android_view_GLES20Canvas_clearLayerTexture(JNIEnv* env, jobject clazz,
-        jlong layerHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    layer->clearTexture();
-}
-
-static void android_view_GLES20Canvas_setTextureLayerTransform(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jlong matrixHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
-    layer->getTransform().load(*matrix);
-}
-
-static void android_view_GLES20Canvas_destroyLayer(JNIEnv* env, jobject clazz, jlong layerHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    LayerRenderer::destroyLayer(layer);
-}
-
-static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env,
-        jobject clazz, jlong layerHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    LayerRenderer::destroyLayerDeferred(layer);
-}
-
 static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong layerHandle, jfloat x, jfloat y) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
+        jlong rendererPtr, jlong layerPtr, jfloat x, jfloat y) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    Layer* layer = reinterpret_cast<Layer*>(layerPtr);
     renderer->drawLayer(layer, x, y);
 }
 
 static jboolean android_view_GLES20Canvas_copyLayer(JNIEnv* env, jobject clazz,
-        jlong layerHandle, jlong bitmapHandle) {
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
-    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle);
+        jlong layerPtr, jlong bitmapPtr) {
+    Layer* layer = reinterpret_cast<Layer*>(layerPtr);
+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
     return LayerRenderer::copyLayer(layer, bitmap);
 }
 
 static void android_view_GLES20Canvas_pushLayerUpdate(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong layerHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
+        jlong rendererPtr, jlong layerPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    Layer* layer = reinterpret_cast<Layer*>(layerPtr);
     renderer->pushLayerUpdate(layer);
 }
 
 static void android_view_GLES20Canvas_cancelLayerUpdate(JNIEnv* env, jobject clazz,
-        jlong rendererHandle, jlong layerHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
-    Layer* layer = reinterpret_cast<Layer*>(layerHandle);
+        jlong rendererPtr, jlong layerPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
+    Layer* layer = reinterpret_cast<Layer*>(layerPtr);
     renderer->cancelLayerUpdate(layer);
 }
 
 static void android_view_GLES20Canvas_clearLayerUpdates(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->clearLayerUpdates();
 }
 
 static void android_view_GLES20Canvas_flushLayerUpdates(JNIEnv* env, jobject clazz,
-        jlong rendererHandle) {
-    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererHandle);
+        jlong rendererPtr) {
+    OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
     renderer->flushLayerUpdates();
 }
 
@@ -1143,7 +975,7 @@
 android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
 #ifdef USE_OPENGL_RENDERER
     int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
-    android::uirenderer::DisplayList::outputLogBuffer(fd);
+    android::uirenderer::RenderNode::outputLogBuffer(fd);
 #endif // USE_OPENGL_RENDERER
 }
 
@@ -1170,11 +1002,9 @@
     { "nPrepare",           "(JZ)I",           (void*) android_view_GLES20Canvas_prepare },
     { "nPrepareDirty",      "(JIIIIZ)I",       (void*) android_view_GLES20Canvas_prepareDirty },
     { "nFinish",            "(J)V",            (void*) android_view_GLES20Canvas_finish },
-    { "nSetName",           "(JLjava/lang/String;)V",
-            (void*) android_view_GLES20Canvas_setName },
+    { "nSetProperty",           "(Ljava/lang/String;Ljava/lang/String;)V",
+            (void*) android_view_GLES20Canvas_setProperty },
 
-    { "nSetCountOverdrawEnabled", "(JZ)V",     (void*) android_view_GLES20Canvas_setCountOverdrawEnabled },
-    { "nGetOverdraw",             "(J)F",      (void*) android_view_GLES20Canvas_getOverdraw },
 
     { "nGetStencilSize",    "()I",             (void*) android_view_GLES20Canvas_getStencilSize },
 
@@ -1233,7 +1063,6 @@
 
     { "nResetModifiers",    "(JI)V",           (void*) android_view_GLES20Canvas_resetModifiers },
     { "nSetupShader",       "(JJ)V",           (void*) android_view_GLES20Canvas_setupShader },
-    { "nSetupColorFilter",  "(JJ)V",           (void*) android_view_GLES20Canvas_setupColorFilter },
     { "nSetupShadow",       "(JFFFI)V",        (void*) android_view_GLES20Canvas_setupShadow },
 
     { "nSetupPaintFilter",  "(JII)V",          (void*) android_view_GLES20Canvas_setupPaintFilter },
@@ -1258,30 +1087,15 @@
     { "nGetClipBounds",     "(JLandroid/graphics/Rect;)Z",
             (void*) android_view_GLES20Canvas_getClipBounds },
 
-    { "nGetDisplayList",         "(JJ)J",      (void*) android_view_GLES20Canvas_getDisplayList },
-    { "nOutputDisplayList",      "(JJ)V",      (void*) android_view_GLES20Canvas_outputDisplayList },
+    { "nFinishRecording",        "(J)J",      (void*) android_view_GLES20Canvas_finishRecording },
     { "nDrawDisplayList",        "(JJLandroid/graphics/Rect;I)I",
             (void*) android_view_GLES20Canvas_drawDisplayList },
 
     { "nCreateDisplayListRenderer", "()J",     (void*) android_view_GLES20Canvas_createDisplayListRenderer },
-    { "nResetDisplayListRenderer",  "(J)V",    (void*) android_view_GLES20Canvas_resetDisplayListRenderer },
 
     { "nInterrupt",              "(J)V",       (void*) android_view_GLES20Canvas_interrupt },
     { "nResume",                 "(J)V",       (void*) android_view_GLES20Canvas_resume },
 
-    { "nCreateLayerRenderer",    "(J)J",       (void*) android_view_GLES20Canvas_createLayerRenderer },
-    { "nCreateLayer",            "(IIZ[I)J",   (void*) android_view_GLES20Canvas_createLayer },
-    { "nResizeLayer",            "(JII[I)Z" ,  (void*) android_view_GLES20Canvas_resizeLayer },
-    { "nSetLayerPaint",          "(JJ)V",      (void*) android_view_GLES20Canvas_setLayerPaint },
-    { "nSetLayerColorFilter",    "(JJ)V",      (void*) android_view_GLES20Canvas_setLayerColorFilter },
-    { "nSetOpaqueLayer",         "(JZ)V",      (void*) android_view_GLES20Canvas_setOpaqueLayer },
-    { "nCreateTextureLayer",     "(Z[I)J",     (void*) android_view_GLES20Canvas_createTextureLayer },
-    { "nUpdateTextureLayer",     "(JIIZLandroid/graphics/SurfaceTexture;)V",
-            (void*) android_view_GLES20Canvas_updateTextureLayer },
-    { "nUpdateRenderLayer",      "(JJJIIII)V", (void*) android_view_GLES20Canvas_updateRenderLayer },
-    { "nClearLayerTexture",      "(J)V",       (void*) android_view_GLES20Canvas_clearLayerTexture },
-    { "nDestroyLayer",           "(J)V",       (void*) android_view_GLES20Canvas_destroyLayer },
-    { "nDestroyLayerDeferred",   "(J)V",       (void*) android_view_GLES20Canvas_destroyLayerDeferred },
     { "nDrawLayer",              "(JJFF)V",    (void*) android_view_GLES20Canvas_drawLayer },
     { "nCopyLayer",              "(JJ)Z",      (void*) android_view_GLES20Canvas_copyLayer },
     { "nClearLayerUpdates",      "(J)V",       (void*) android_view_GLES20Canvas_clearLayerUpdates },
@@ -1289,8 +1103,6 @@
     { "nPushLayerUpdate",        "(JJ)V",      (void*) android_view_GLES20Canvas_pushLayerUpdate },
     { "nCancelLayerUpdate",      "(JJ)V",      (void*) android_view_GLES20Canvas_cancelLayerUpdate },
 
-    { "nSetTextureLayerTransform", "(JJ)V",    (void*) android_view_GLES20Canvas_setTextureLayerTransform },
-
     { "nGetMaximumTextureWidth",  "()I",       (void*) android_view_GLES20Canvas_getMaxTextureWidth },
     { "nGetMaximumTextureHeight", "()I",       (void*) android_view_GLES20Canvas_getMaxTextureHeight },
 
diff --git a/core/jni/android_view_GLES20DisplayList.cpp b/core/jni/android_view_GLES20DisplayList.cpp
deleted file mode 100644
index 8e19efd..0000000
--- a/core/jni/android_view_GLES20DisplayList.cpp
+++ /dev/null
@@ -1,424 +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 "OpenGLRenderer"
-
-#include <EGL/egl.h>
-
-#include "jni.h"
-#include "GraphicsJNI.h"
-#include <nativehelper/JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <DisplayList.h>
-#include <DisplayListRenderer.h>
-
-namespace android {
-
-using namespace uirenderer;
-
-/**
- * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
- *       devices. This means all the logic must be compiled only when the
- *       preprocessor variable USE_OPENGL_RENDERER is defined.
- */
-#ifdef USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// DisplayList view properties
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20DisplayList_reset(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->reset();
-}
-
-static jint android_view_GLES20DisplayList_getDisplayListSize(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getSize();
-}
-
-static void android_view_GLES20DisplayList_setDisplayListName(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jstring name) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    if (name != NULL) {
-        const char* textArray = env->GetStringUTFChars(name, NULL);
-        displayList->setName(textArray);
-        env->ReleaseStringUTFChars(name, textArray);
-    }
-}
-
-static void android_view_GLES20DisplayList_destroyDisplayList(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    DisplayList::destroyDisplayListDeferred(displayList);
-}
-
-// ----------------------------------------------------------------------------
-// DisplayList view properties
-// ----------------------------------------------------------------------------
-
-static void android_view_GLES20DisplayList_setCaching(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jboolean caching) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setCaching(caching);
-}
-
-//serban
-static void android_view_GLES20DisplayList_setStaticMatrix(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jlong matrixHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
-    displayList->setStaticMatrix(matrix);
-}
-
-static void android_view_GLES20DisplayList_setAnimationMatrix(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jlong matrixHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
-    displayList->setAnimationMatrix(matrix);
-}
-
-static void android_view_GLES20DisplayList_setClipToBounds(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jboolean clipToBounds) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setClipToBounds(clipToBounds);
-}
-
-static void android_view_GLES20DisplayList_setAlpha(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat alpha) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setAlpha(alpha);
-}
-
-static void android_view_GLES20DisplayList_setHasOverlappingRendering(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jboolean hasOverlappingRendering) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setHasOverlappingRendering(hasOverlappingRendering);
-}
-
-static void android_view_GLES20DisplayList_setTranslationX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat tx) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setTranslationX(tx);
-}
-
-static void android_view_GLES20DisplayList_setTranslationY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat ty) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setTranslationY(ty);
-}
-
-static void android_view_GLES20DisplayList_setRotation(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat rotation) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setRotation(rotation);
-}
-
-static void android_view_GLES20DisplayList_setRotationX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat rx) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setRotationX(rx);
-}
-
-static void android_view_GLES20DisplayList_setRotationY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat ry) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setRotationY(ry);
-}
-
-static void android_view_GLES20DisplayList_setScaleX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat sx) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setScaleX(sx);
-}
-
-static void android_view_GLES20DisplayList_setScaleY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat sy) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setScaleY(sy);
-}
-
-static void android_view_GLES20DisplayList_setTransformationInfo(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat alpha,
-        jfloat translationX, jfloat translationY, jfloat rotation, jfloat rotationX, jfloat rotationY,
-        jfloat scaleX, jfloat scaleY) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setAlpha(alpha);
-    displayList->setTranslationX(translationX);
-    displayList->setTranslationY(translationY);
-    displayList->setRotation(rotation);
-    displayList->setRotationX(rotationX);
-    displayList->setRotationY(rotationY);
-    displayList->setScaleX(scaleX);
-    displayList->setScaleY(scaleY);
-}
-
-static void android_view_GLES20DisplayList_setPivotX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat px) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setPivotX(px);
-}
-
-static void android_view_GLES20DisplayList_setPivotY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat py) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setPivotY(py);
-}
-
-static void android_view_GLES20DisplayList_setCameraDistance(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat distance) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setCameraDistance(distance);
-}
-
-static void android_view_GLES20DisplayList_setLeft(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jint left) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setLeft(left);
-}
-
-static void android_view_GLES20DisplayList_setTop(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jint top) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setTop(top);
-}
-
-static void android_view_GLES20DisplayList_setRight(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jint right) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setRight(right);
-}
-
-static void android_view_GLES20DisplayList_setBottom(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jint bottom) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setBottom(bottom);
-}
-
-static void android_view_GLES20DisplayList_setLeftTopRightBottom(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jint left, jint top,
-        int right, int bottom) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->setLeftTopRightBottom(left, top, right, bottom);
-}
-
-static void android_view_GLES20DisplayList_offsetLeftAndRight(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat offset) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->offsetLeftRight(offset);
-}
-
-static void android_view_GLES20DisplayList_offsetTopAndBottom(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jfloat offset) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    displayList->offsetTopBottom(offset);
-}
-
-static void android_view_GLES20DisplayList_getMatrix(JNIEnv* env,
-        jobject clazz, jlong displayListHandle, jlong matrixHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
-    SkMatrix* source = displayList->getStaticMatrix();
-    if (source) {
-        matrix->setConcat(SkMatrix::I(), *source);
-    } else {
-        matrix->setIdentity();
-    }
-}
-
-static jboolean android_view_GLES20DisplayList_hasOverlappingRendering(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->hasOverlappingRendering();
-}
-
-static jfloat android_view_GLES20DisplayList_getAlpha(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getAlpha();
-}
-
-static jfloat android_view_GLES20DisplayList_getLeft(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getLeft();
-}
-
-static jfloat android_view_GLES20DisplayList_getTop(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getTop();
-}
-
-static jfloat android_view_GLES20DisplayList_getRight(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getRight();
-}
-
-static jfloat android_view_GLES20DisplayList_getBottom(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getBottom();
-}
-
-static jfloat android_view_GLES20DisplayList_getCameraDistance(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getCameraDistance();
-}
-
-static jfloat android_view_GLES20DisplayList_getScaleX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getScaleX();
-}
-
-static jfloat android_view_GLES20DisplayList_getScaleY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getScaleY();
-}
-
-static jfloat android_view_GLES20DisplayList_getTranslationX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getTranslationX();
-}
-
-static jfloat android_view_GLES20DisplayList_getTranslationY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getTranslationY();
-}
-
-static jfloat android_view_GLES20DisplayList_getRotation(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getRotation();
-}
-
-static jfloat android_view_GLES20DisplayList_getRotationX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getRotationX();
-}
-
-static jfloat android_view_GLES20DisplayList_getRotationY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getRotationY();
-}
-
-static jfloat android_view_GLES20DisplayList_getPivotX(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getPivotX();
-}
-
-static jfloat android_view_GLES20DisplayList_getPivotY(JNIEnv* env,
-        jobject clazz, jlong displayListHandle) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListHandle);
-    return displayList->getPivotY();
-}
-
-#endif // USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// JNI Glue
-// ----------------------------------------------------------------------------
-
-const char* const kClassPathName = "android/view/GLES20DisplayList";
-
-static JNINativeMethod gMethods[] = {
-#ifdef USE_OPENGL_RENDERER
-    { "nDestroyDisplayList",   "(J)V",   (void*) android_view_GLES20DisplayList_destroyDisplayList },
-    { "nGetDisplayListSize",   "(J)I",   (void*) android_view_GLES20DisplayList_getDisplayListSize },
-    { "nSetDisplayListName",   "(JLjava/lang/String;)V",
-            (void*) android_view_GLES20DisplayList_setDisplayListName },
-
-    { "nReset",                "(J)V",   (void*) android_view_GLES20DisplayList_reset },
-    { "nSetCaching",           "(JZ)V",  (void*) android_view_GLES20DisplayList_setCaching },
-    { "nSetStaticMatrix",      "(JJ)V",  (void*) android_view_GLES20DisplayList_setStaticMatrix },
-    { "nSetAnimationMatrix",   "(JJ)V",  (void*) android_view_GLES20DisplayList_setAnimationMatrix },
-    { "nSetClipToBounds",      "(JZ)V",  (void*) android_view_GLES20DisplayList_setClipToBounds },
-    { "nSetAlpha",             "(JF)V",  (void*) android_view_GLES20DisplayList_setAlpha },
-    { "nSetHasOverlappingRendering", "(JZ)V",
-            (void*) android_view_GLES20DisplayList_setHasOverlappingRendering },
-    { "nSetTranslationX",      "(JF)V",  (void*) android_view_GLES20DisplayList_setTranslationX },
-    { "nSetTranslationY",      "(JF)V",  (void*) android_view_GLES20DisplayList_setTranslationY },
-    { "nSetRotation",          "(JF)V",  (void*) android_view_GLES20DisplayList_setRotation },
-    { "nSetRotationX",         "(JF)V",  (void*) android_view_GLES20DisplayList_setRotationX },
-    { "nSetRotationY",         "(JF)V",  (void*) android_view_GLES20DisplayList_setRotationY },
-    { "nSetScaleX",            "(JF)V",  (void*) android_view_GLES20DisplayList_setScaleX },
-    { "nSetScaleY",            "(JF)V",  (void*) android_view_GLES20DisplayList_setScaleY },
-    { "nSetTransformationInfo","(JFFFFFFFF)V",
-            (void*) android_view_GLES20DisplayList_setTransformationInfo },
-    { "nSetPivotX",            "(JF)V",  (void*) android_view_GLES20DisplayList_setPivotX },
-    { "nSetPivotY",            "(JF)V",  (void*) android_view_GLES20DisplayList_setPivotY },
-    { "nSetCameraDistance",    "(JF)V",  (void*) android_view_GLES20DisplayList_setCameraDistance },
-    { "nSetLeft",              "(JI)V",  (void*) android_view_GLES20DisplayList_setLeft },
-    { "nSetTop",               "(JI)V",  (void*) android_view_GLES20DisplayList_setTop },
-    { "nSetRight",             "(JI)V",  (void*) android_view_GLES20DisplayList_setRight },
-    { "nSetBottom",            "(JI)V",  (void*) android_view_GLES20DisplayList_setBottom },
-    { "nSetLeftTopRightBottom","(JIIII)V",
-            (void*) android_view_GLES20DisplayList_setLeftTopRightBottom },
-    { "nOffsetLeftAndRight",   "(JF)V",  (void*) android_view_GLES20DisplayList_offsetLeftAndRight },
-    { "nOffsetTopAndBottom",   "(JF)V",  (void*) android_view_GLES20DisplayList_offsetTopAndBottom },
-
-
-    { "nGetMatrix",               "(JJ)V", (void*) android_view_GLES20DisplayList_getMatrix },
-    { "nHasOverlappingRendering", "(J)Z",  (void*) android_view_GLES20DisplayList_hasOverlappingRendering },
-    { "nGetAlpha",                "(J)F",  (void*) android_view_GLES20DisplayList_getAlpha },
-    { "nGetLeft",                 "(J)F",  (void*) android_view_GLES20DisplayList_getLeft },
-    { "nGetTop",                  "(J)F",  (void*) android_view_GLES20DisplayList_getTop },
-    { "nGetRight",                "(J)F",  (void*) android_view_GLES20DisplayList_getRight },
-    { "nGetBottom",               "(J)F",  (void*) android_view_GLES20DisplayList_getBottom },
-    { "nGetCameraDistance",       "(J)F",  (void*) android_view_GLES20DisplayList_getCameraDistance },
-    { "nGetScaleX",               "(J)F",  (void*) android_view_GLES20DisplayList_getScaleX },
-    { "nGetScaleY",               "(J)F",  (void*) android_view_GLES20DisplayList_getScaleY },
-    { "nGetTranslationX",         "(J)F",  (void*) android_view_GLES20DisplayList_getTranslationX },
-    { "nGetTranslationY",         "(J)F",  (void*) android_view_GLES20DisplayList_getTranslationY },
-    { "nGetRotation",             "(J)F",  (void*) android_view_GLES20DisplayList_getRotation },
-    { "nGetRotationX",            "(J)F",  (void*) android_view_GLES20DisplayList_getRotationX },
-    { "nGetRotationY",            "(J)F",  (void*) android_view_GLES20DisplayList_getRotationY },
-    { "nGetPivotX",               "(J)F",  (void*) android_view_GLES20DisplayList_getPivotX },
-    { "nGetPivotY",               "(J)F",  (void*) android_view_GLES20DisplayList_getPivotY },
-#endif
-};
-
-#ifdef USE_OPENGL_RENDERER
-    #define FIND_CLASS(var, className) \
-            var = env->FindClass(className); \
-            LOG_FATAL_IF(! var, "Unable to find class " className);
-
-    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
-            var = env->GetMethodID(clazz, methodName, methodDescriptor); \
-            LOG_FATAL_IF(! var, "Unable to find method " methodName);
-#else
-    #define FIND_CLASS(var, className)
-    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
-#endif
-
-int register_android_view_GLES20DisplayList(JNIEnv* env) {
-    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
-}
-
-};
-
diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
new file mode 100644
index 0000000..00d92fc
--- /dev/null
+++ b/core/jni/android_view_GLRenderer.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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 "GLRenderer"
+
+#include "jni.h"
+#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>
+#include <LayerRenderer.h>
+#include <RenderNode.h>
+
+#ifdef USE_OPENGL_RENDERER
+    EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
+#endif
+
+namespace android {
+
+/**
+ * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
+ *       devices. This means all the logic must be compiled only when the
+ *       preprocessor variable USE_OPENGL_RENDERER is defined.
+ */
+#ifdef USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// Defines
+// ----------------------------------------------------------------------------
+
+// Debug
+#define DEBUG_RENDERER 0
+
+// Debug
+#if DEBUG_RENDERER
+    #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
+#else
+    #define RENDERER_LOGD(...)
+#endif
+
+// ----------------------------------------------------------------------------
+// Surface and display management
+// ----------------------------------------------------------------------------
+
+static jboolean android_view_GLRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) {
+    EGLDisplay display = eglGetCurrentDisplay();
+    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
+
+    eglGetError();
+    eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
+
+    EGLint error = eglGetError();
+    if (error != EGL_SUCCESS) {
+        RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
+    }
+
+    return error == EGL_SUCCESS;
+}
+
+static jboolean android_view_GLRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
+    EGLDisplay display = eglGetCurrentDisplay();
+    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
+    EGLint value;
+
+    eglGetError();
+    eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value);
+
+    EGLint error = eglGetError();
+    if (error != EGL_SUCCESS) {
+        RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error);
+    }
+
+    return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED;
+}
+
+// ----------------------------------------------------------------------------
+// Tracing and debugging
+// ----------------------------------------------------------------------------
+
+static bool android_view_GLRenderer_loadProperties(JNIEnv* env, jobject clazz) {
+    if (uirenderer::Caches::hasInstance()) {
+        return uirenderer::Caches::getInstance().initProperties();
+    }
+    return false;
+}
+
+static void android_view_GLRenderer_beginFrame(JNIEnv* env, jobject clazz,
+        jintArray size) {
+
+    EGLDisplay display = eglGetCurrentDisplay();
+    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
+
+    if (size) {
+        EGLint value;
+        jint* storage = env->GetIntArrayElements(size, NULL);
+
+        eglQuerySurface(display, surface, EGL_WIDTH, &value);
+        storage[0] = value;
+
+        eglQuerySurface(display, surface, EGL_HEIGHT, &value);
+        storage[1] = value;
+
+        env->ReleaseIntArrayElements(size, storage, 0);
+    }
+
+    eglBeginFrame(display, surface);
+}
+
+static jlong android_view_GLRenderer_getSystemTime(JNIEnv* env, jobject clazz) {
+    if (uirenderer::Extensions::getInstance().hasNvSystemTime()) {
+        return eglGetSystemTimeNV();
+    }
+    return systemTime(SYSTEM_TIME_MONOTONIC);
+}
+
+static void android_view_GLRenderer_destroyLayer(JNIEnv* env, jobject clazz,
+        jlong layerPtr) {
+    using namespace android::uirenderer;
+    Layer* layer = reinterpret_cast<Layer*>(layerPtr);
+    LayerRenderer::destroyLayer(layer);
+}
+
+static void android_view_GLRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
+        jlong displayListPtr, jlong newDataPtr) {
+    using namespace android::uirenderer;
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
+    displayList->setData(newData);
+}
+
+#endif // USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// Shaders
+// ----------------------------------------------------------------------------
+
+static void android_view_GLRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
+        jstring diskCachePath) {
+
+    const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
+    egl_cache_t::get()->setCacheFilename(cacheArray);
+    env->ReleaseStringUTFChars(diskCachePath, cacheArray);
+}
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/GLRenderer";
+
+static JNINativeMethod gMethods[] = {
+#ifdef USE_OPENGL_RENDERER
+    { "isBackBufferPreserved", "()Z",   (void*) android_view_GLRenderer_isBackBufferPreserved },
+    { "preserveBackBuffer",    "()Z",   (void*) android_view_GLRenderer_preserveBackBuffer },
+    { "loadProperties",        "()Z",   (void*) android_view_GLRenderer_loadProperties },
+
+    { "beginFrame",            "([I)V", (void*) android_view_GLRenderer_beginFrame },
+
+    { "getSystemTime",         "()J",   (void*) android_view_GLRenderer_getSystemTime },
+    { "nDestroyLayer",         "(J)V",  (void*) android_view_GLRenderer_destroyLayer },
+    { "nSetDisplayListData",  "(JJ)V", (void*) android_view_GLRenderer_setDisplayListData },
+#endif
+
+    { "setupShadersDiskCache", "(Ljava/lang/String;)V",
+            (void*) android_view_GLRenderer_setupShadersDiskCache },
+};
+
+int register_android_view_GLRenderer(JNIEnv* env) {
+    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
new file mode 100644
index 0000000..4bf5f78
--- /dev/null
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/JNIHelp.h>
+
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
+
+#include <gui/GLConsumer.h>
+
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
+#include <SkXfermode.h>
+
+#include <DeferredLayerUpdater.h>
+#include <LayerRenderer.h>
+#include <SkiaShader.h>
+#include <Rect.h>
+#include <RenderNode.h>
+
+namespace android {
+
+using namespace uirenderer;
+
+#ifdef USE_OPENGL_RENDERER
+
+static jlong android_view_HardwareLayer_createTextureLayer(JNIEnv* env, jobject clazz) {
+    Layer* layer = LayerRenderer::createTextureLayer();
+    if (!layer) return 0;
+
+    return reinterpret_cast<jlong>( new DeferredLayerUpdater(layer) );
+}
+
+static jlong android_view_HardwareLayer_createRenderLayer(JNIEnv* env, jobject clazz,
+        jint width, jint height) {
+    Layer* layer = LayerRenderer::createRenderLayer(width, height);
+    if (!layer) return 0;
+
+    OpenGLRenderer* renderer = new LayerRenderer(layer);
+    renderer->initProperties();
+    return reinterpret_cast<jlong>( new DeferredLayerUpdater(layer, renderer) );
+}
+
+static void android_view_HardwareLayer_onTextureDestroyed(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    layer->backingLayer()->clearTexture();
+}
+
+static jlong android_view_HardwareLayer_detachBackingLayer(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    return reinterpret_cast<jlong>( layer->detachBackingLayer() );
+}
+
+static void android_view_HardwareLayer_destroyLayerUpdater(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    delete layer;
+}
+
+static jboolean android_view_HardwareLayer_prepare(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr, jint width, jint height, jboolean isOpaque) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    bool changed = false;
+    changed |= layer->setSize(width, height);
+    changed |= layer->setBlend(!isOpaque);
+    return changed;
+}
+
+static void android_view_HardwareLayer_setLayerPaint(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr, jlong paintPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    if (layer) {
+        SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
+        layer->setPaint(paint);
+    }
+}
+
+static void android_view_HardwareLayer_setTransform(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr, jlong matrixPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
+    layer->setTransform(matrix);
+}
+
+static void android_view_HardwareLayer_setSurfaceTexture(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr, jobject surface, jboolean isAlreadyAttached) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    sp<GLConsumer> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, surface));
+    layer->setSurfaceTexture(surfaceTexture, !isAlreadyAttached);
+}
+
+static void android_view_HardwareLayer_updateSurfaceTexture(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    layer->updateTexImage();
+}
+
+static void android_view_HardwareLayer_updateRenderLayer(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr, jlong displayListPtr,
+        jint left, jint top, jint right, jint bottom) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    layer->setDisplayList(displayList, left, top, right, bottom);
+}
+
+static jboolean android_view_HardwareLayer_flushChanges(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    return layer->apply();
+}
+
+static jlong android_view_HardwareLayer_getLayer(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    return reinterpret_cast<jlong>( layer->backingLayer() );
+}
+
+static jint android_view_HardwareLayer_getTexName(JNIEnv* env, jobject clazz,
+        jlong layerUpdaterPtr) {
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
+    return layer->backingLayer()->getTexture();
+}
+
+#endif // USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/HardwareLayer";
+
+static JNINativeMethod gMethods[] = {
+#ifdef USE_OPENGL_RENDERER
+
+    { "nCreateTextureLayer",     "()J",        (void*) android_view_HardwareLayer_createTextureLayer },
+    { "nCreateRenderLayer",      "(II)J",      (void*) android_view_HardwareLayer_createRenderLayer },
+    { "nOnTextureDestroyed",     "(J)V",       (void*) android_view_HardwareLayer_onTextureDestroyed },
+    { "nDetachBackingLayer",     "(J)J",       (void*) android_view_HardwareLayer_detachBackingLayer },
+    { "nDestroyLayerUpdater",    "(J)V",       (void*) android_view_HardwareLayer_destroyLayerUpdater },
+
+    { "nPrepare",                "(JIIZ)Z",    (void*) android_view_HardwareLayer_prepare },
+    { "nSetLayerPaint",          "(JJ)V",      (void*) android_view_HardwareLayer_setLayerPaint },
+    { "nSetTransform",           "(JJ)V",      (void*) android_view_HardwareLayer_setTransform },
+    { "nSetSurfaceTexture",      "(JLandroid/graphics/SurfaceTexture;Z)V",
+            (void*) android_view_HardwareLayer_setSurfaceTexture },
+    { "nUpdateSurfaceTexture",   "(J)V",       (void*) android_view_HardwareLayer_updateSurfaceTexture },
+    { "nUpdateRenderLayer",      "(JJIIII)V",  (void*) android_view_HardwareLayer_updateRenderLayer },
+
+    { "nFlushChanges",           "(J)Z",       (void*) android_view_HardwareLayer_flushChanges },
+
+    { "nGetLayer",               "(J)J",       (void*) android_view_HardwareLayer_getLayer },
+    { "nGetTexName",             "(J)I",       (void*) android_view_HardwareLayer_getTexName },
+#endif
+};
+
+int register_android_view_HardwareLayer(JNIEnv* env) {
+    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
diff --git a/core/jni/android_view_HardwareRenderer.cpp b/core/jni/android_view_HardwareRenderer.cpp
deleted file mode 100644
index 479fbe2..0000000
--- a/core/jni/android_view_HardwareRenderer.cpp
+++ /dev/null
@@ -1,173 +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 "HardwareRenderer"
-
-#include "jni.h"
-#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);
-#endif
-
-namespace android {
-
-/**
- * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
- *       devices. This means all the logic must be compiled only when the
- *       preprocessor variable USE_OPENGL_RENDERER is defined.
- */
-#ifdef USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// Defines
-// ----------------------------------------------------------------------------
-
-// Debug
-#define DEBUG_RENDERER 0
-
-// Debug
-#if DEBUG_RENDERER
-    #define RENDERER_LOGD(...) ALOGD(__VA_ARGS__)
-#else
-    #define RENDERER_LOGD(...)
-#endif
-
-// ----------------------------------------------------------------------------
-// Surface and display management
-// ----------------------------------------------------------------------------
-
-static jboolean android_view_HardwareRenderer_preserveBackBuffer(JNIEnv* env, jobject clazz) {
-    EGLDisplay display = eglGetCurrentDisplay();
-    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
-
-    eglGetError();
-    eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED);
-
-    EGLint error = eglGetError();
-    if (error != EGL_SUCCESS) {
-        RENDERER_LOGD("Could not enable buffer preserved swap behavior (%x)", error);
-    }
-
-    return error == EGL_SUCCESS;
-}
-
-static jboolean android_view_HardwareRenderer_isBackBufferPreserved(JNIEnv* env, jobject clazz) {
-    EGLDisplay display = eglGetCurrentDisplay();
-    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
-    EGLint value;
-
-    eglGetError();
-    eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &value);
-
-    EGLint error = eglGetError();
-    if (error != EGL_SUCCESS) {
-        RENDERER_LOGD("Could not query buffer preserved swap behavior (%x)", error);
-    }
-
-    return error == EGL_SUCCESS && value == EGL_BUFFER_PRESERVED;
-}
-
-// ----------------------------------------------------------------------------
-// Tracing and debugging
-// ----------------------------------------------------------------------------
-
-static bool android_view_HardwareRenderer_loadProperties(JNIEnv* env, jobject clazz) {
-    if (uirenderer::Caches::hasInstance()) {
-        return uirenderer::Caches::getInstance().initProperties();
-    }
-    return false;
-}
-
-static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz,
-        jintArray size) {
-
-    EGLDisplay display = eglGetCurrentDisplay();
-    EGLSurface surface = eglGetCurrentSurface(EGL_DRAW);
-
-    if (size) {
-        EGLint value;
-        jint* storage = env->GetIntArrayElements(size, NULL);
-
-        eglQuerySurface(display, surface, EGL_WIDTH, &value);
-        storage[0] = value;
-
-        eglQuerySurface(display, surface, EGL_HEIGHT, &value);
-        storage[1] = value;
-
-        env->ReleaseIntArrayElements(size, storage, 0);
-    }
-
-    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
-
-// ----------------------------------------------------------------------------
-// Shaders
-// ----------------------------------------------------------------------------
-
-static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, jobject clazz,
-        jstring diskCachePath) {
-
-    const char* cacheArray = env->GetStringUTFChars(diskCachePath, NULL);
-    egl_cache_t::get()->setCacheFilename(cacheArray);
-    env->ReleaseStringUTFChars(diskCachePath, cacheArray);
-}
-
-// ----------------------------------------------------------------------------
-// JNI Glue
-// ----------------------------------------------------------------------------
-
-const char* const kClassPathName = "android/view/HardwareRenderer";
-
-static JNINativeMethod gMethods[] = {
-#ifdef USE_OPENGL_RENDERER
-    { "nIsBackBufferPreserved", "()Z",   (void*) android_view_HardwareRenderer_isBackBufferPreserved },
-    { "nPreserveBackBuffer",    "()Z",   (void*) android_view_HardwareRenderer_preserveBackBuffer },
-    { "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",
-            (void*) android_view_HardwareRenderer_setupShadersDiskCache },
-};
-
-int register_android_view_HardwareRenderer(JNIEnv* env) {
-    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
-}
-
-};
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
new file mode 100644
index 0000000..f96be22
--- /dev/null
+++ b/core/jni/android_view_RenderNode.cpp
@@ -0,0 +1,459 @@
+/*
+ * 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 "OpenGLRenderer"
+
+#include <EGL/egl.h>
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <DisplayListRenderer.h>
+#include <RenderNode.h>
+
+namespace android {
+
+using namespace uirenderer;
+
+/**
+ * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
+ *       devices. This means all the logic must be compiled only when the
+ *       preprocessor variable USE_OPENGL_RENDERER is defined.
+ */
+#ifdef USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// DisplayList view properties
+// ----------------------------------------------------------------------------
+
+static void android_view_RenderNode_setDisplayListName(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jstring name) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    if (name != NULL) {
+        const char* textArray = env->GetStringUTFChars(name, NULL);
+        displayList->setName(textArray);
+        env->ReleaseStringUTFChars(name, textArray);
+    }
+}
+
+static void android_view_RenderNode_output(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->output();
+}
+
+static jlong android_view_RenderNode_create(JNIEnv* env, jobject clazz) {
+    RenderNode* displayList = new RenderNode();
+    return reinterpret_cast<jlong>(displayList);
+}
+
+static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    RenderNode::destroyDisplayListDeferred(displayList);
+}
+
+// ----------------------------------------------------------------------------
+// RenderProperties
+// ----------------------------------------------------------------------------
+
+static void android_view_RenderNode_setCaching(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean caching) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setCaching(caching);
+}
+
+static void android_view_RenderNode_setStaticMatrix(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jlong matrixPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
+    displayList->properties().setStaticMatrix(matrix);
+}
+
+static void android_view_RenderNode_setAnimationMatrix(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jlong matrixPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
+    displayList->properties().setAnimationMatrix(matrix);
+}
+
+static void android_view_RenderNode_setClipToBounds(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean clipToBounds) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setClipToBounds(clipToBounds);
+}
+
+static void android_view_RenderNode_setProjectBackwards(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean shouldProject) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setProjectBackwards(shouldProject);
+}
+
+static void android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean shouldRecieve) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setProjectionReceiver(shouldRecieve);
+}
+
+static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jint left, jint top,
+        jint right, jint bottom, jfloat radius) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().outline().setRoundRect(left, top, right, bottom, radius);
+}
+static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
+    displayList->properties().outline().setConvexPath(outlinePath);
+}
+static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().outline().setEmpty();
+}
+
+static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().outline().setShouldClip(clipToOutline);
+}
+
+static void android_view_RenderNode_setAlpha(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float alpha) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setAlpha(alpha);
+}
+
+static void android_view_RenderNode_setHasOverlappingRendering(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, bool hasOverlappingRendering) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setHasOverlappingRendering(hasOverlappingRendering);
+}
+
+static void android_view_RenderNode_setTranslationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float tx) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTranslationX(tx);
+}
+
+static void android_view_RenderNode_setTranslationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float ty) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTranslationY(ty);
+}
+
+static void android_view_RenderNode_setTranslationZ(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float tz) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTranslationZ(tz);
+}
+
+static void android_view_RenderNode_setRotation(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float rotation) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRotation(rotation);
+}
+
+static void android_view_RenderNode_setRotationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float rx) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRotationX(rx);
+}
+
+static void android_view_RenderNode_setRotationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float ry) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRotationY(ry);
+}
+
+static void android_view_RenderNode_setScaleX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float sx) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setScaleX(sx);
+}
+
+static void android_view_RenderNode_setScaleY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float sy) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setScaleY(sy);
+}
+
+static void android_view_RenderNode_setTransformationInfo(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float alpha,
+        float translationX, float translationY, float translationZ,
+        float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setAlpha(alpha);
+    displayList->properties().setTranslationX(translationX);
+    displayList->properties().setTranslationY(translationY);
+    displayList->properties().setTranslationZ(translationZ);
+    displayList->properties().setRotation(rotation);
+    displayList->properties().setRotationX(rotationX);
+    displayList->properties().setRotationY(rotationY);
+    displayList->properties().setScaleX(scaleX);
+    displayList->properties().setScaleY(scaleY);
+}
+
+static void android_view_RenderNode_setPivotX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float px) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setPivotX(px);
+}
+
+static void android_view_RenderNode_setPivotY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float py) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setPivotY(py);
+}
+
+static void android_view_RenderNode_setCameraDistance(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float distance) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setCameraDistance(distance);
+}
+
+static void android_view_RenderNode_setLeft(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int left) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setLeft(left);
+}
+
+static void android_view_RenderNode_setTop(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int top) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTop(top);
+}
+
+static void android_view_RenderNode_setRight(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int right) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRight(right);
+}
+
+static void android_view_RenderNode_setBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int bottom) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setBottom(bottom);
+}
+
+static void android_view_RenderNode_setLeftTopRightBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int left, int top,
+        int right, int bottom) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setLeftTopRightBottom(left, top, right, bottom);
+}
+
+static void android_view_RenderNode_offsetLeftAndRight(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float offset) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().offsetLeftRight(offset);
+}
+
+static void android_view_RenderNode_offsetTopAndBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float offset) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().offsetTopBottom(offset);
+}
+
+static jboolean android_view_RenderNode_hasOverlappingRendering(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().hasOverlappingRendering();
+}
+
+static jfloat android_view_RenderNode_getAlpha(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getAlpha();
+}
+
+static jfloat android_view_RenderNode_getLeft(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getLeft();
+}
+
+static jfloat android_view_RenderNode_getTop(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getTop();
+}
+
+static jfloat android_view_RenderNode_getRight(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRight();
+}
+
+static jfloat android_view_RenderNode_getBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getBottom();
+}
+
+static jfloat android_view_RenderNode_getCameraDistance(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getCameraDistance();
+}
+
+static jfloat android_view_RenderNode_getScaleX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getScaleX();
+}
+
+static jfloat android_view_RenderNode_getScaleY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getScaleY();
+}
+
+static jfloat android_view_RenderNode_getTranslationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getTranslationX();
+}
+
+static jfloat android_view_RenderNode_getTranslationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getTranslationY();
+}
+
+static jfloat android_view_RenderNode_getRotation(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRotation();
+}
+
+static jfloat android_view_RenderNode_getRotationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRotationX();
+}
+
+static jfloat android_view_RenderNode_getRotationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRotationY();
+}
+
+static jfloat android_view_RenderNode_getPivotX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getPivotX();
+}
+
+static jfloat android_view_RenderNode_getPivotY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getPivotY();
+}
+
+#endif // USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/RenderNode";
+
+static JNINativeMethod gMethods[] = {
+#ifdef USE_OPENGL_RENDERER
+    { "nCreate",               "()J",    (void*) android_view_RenderNode_create },
+    { "nDestroyDisplayList",   "(J)V",   (void*) android_view_RenderNode_destroyDisplayList },
+    { "nSetDisplayListName",   "(JLjava/lang/String;)V",
+            (void*) android_view_RenderNode_setDisplayListName },
+    { "nOutput",               "(J)V",  (void*) android_view_RenderNode_output },
+
+    { "nSetCaching",           "(JZ)V",  (void*) android_view_RenderNode_setCaching },
+    { "nSetStaticMatrix",      "(JJ)V",  (void*) android_view_RenderNode_setStaticMatrix },
+    { "nSetAnimationMatrix",   "(JJ)V",  (void*) android_view_RenderNode_setAnimationMatrix },
+    { "nSetClipToBounds",      "(JZ)V",  (void*) android_view_RenderNode_setClipToBounds },
+    { "nSetProjectBackwards",  "(JZ)V",  (void*) android_view_RenderNode_setProjectBackwards },
+    { "nSetProjectionReceiver","(JZ)V",  (void*) android_view_RenderNode_setProjectionReceiver },
+
+    { "nSetOutlineRoundRect",  "(JIIIIF)V", (void*) android_view_RenderNode_setOutlineRoundRect },
+    { "nSetOutlineConvexPath", "(JJ)V",  (void*) android_view_RenderNode_setOutlineConvexPath },
+    { "nSetOutlineEmpty",      "(J)V",   (void*) android_view_RenderNode_setOutlineEmpty },
+    { "nSetClipToOutline",     "(JZ)V",  (void*) android_view_RenderNode_setClipToOutline },
+
+    { "nSetAlpha",             "(JF)V",  (void*) android_view_RenderNode_setAlpha },
+    { "nSetHasOverlappingRendering", "(JZ)V",
+            (void*) android_view_RenderNode_setHasOverlappingRendering },
+    { "nSetTranslationX",      "(JF)V",  (void*) android_view_RenderNode_setTranslationX },
+    { "nSetTranslationY",      "(JF)V",  (void*) android_view_RenderNode_setTranslationY },
+    { "nSetTranslationZ",      "(JF)V",  (void*) android_view_RenderNode_setTranslationZ },
+    { "nSetRotation",          "(JF)V",  (void*) android_view_RenderNode_setRotation },
+    { "nSetRotationX",         "(JF)V",  (void*) android_view_RenderNode_setRotationX },
+    { "nSetRotationY",         "(JF)V",  (void*) android_view_RenderNode_setRotationY },
+    { "nSetScaleX",            "(JF)V",  (void*) android_view_RenderNode_setScaleX },
+    { "nSetScaleY",            "(JF)V",  (void*) android_view_RenderNode_setScaleY },
+    { "nSetTransformationInfo","(JFFFFFFFFF)V",
+            (void*) android_view_RenderNode_setTransformationInfo },
+    { "nSetPivotX",            "(JF)V",  (void*) android_view_RenderNode_setPivotX },
+    { "nSetPivotY",            "(JF)V",  (void*) android_view_RenderNode_setPivotY },
+    { "nSetCameraDistance",    "(JF)V",  (void*) android_view_RenderNode_setCameraDistance },
+    { "nSetLeft",              "(JI)V",  (void*) android_view_RenderNode_setLeft },
+    { "nSetTop",               "(JI)V",  (void*) android_view_RenderNode_setTop },
+    { "nSetRight",             "(JI)V",  (void*) android_view_RenderNode_setRight },
+    { "nSetBottom",            "(JI)V",  (void*) android_view_RenderNode_setBottom },
+    { "nSetLeftTopRightBottom","(JIIII)V", (void*) android_view_RenderNode_setLeftTopRightBottom },
+    { "nOffsetLeftAndRight",   "(JF)V",  (void*) android_view_RenderNode_offsetLeftAndRight },
+    { "nOffsetTopAndBottom",   "(JF)V",  (void*) android_view_RenderNode_offsetTopAndBottom },
+
+    { "nHasOverlappingRendering", "(J)Z",  (void*) android_view_RenderNode_hasOverlappingRendering },
+    { "nGetAlpha",                "(J)F",  (void*) android_view_RenderNode_getAlpha },
+    { "nGetLeft",                 "(J)F",  (void*) android_view_RenderNode_getLeft },
+    { "nGetTop",                  "(J)F",  (void*) android_view_RenderNode_getTop },
+    { "nGetRight",                "(J)F",  (void*) android_view_RenderNode_getRight },
+    { "nGetBottom",               "(J)F",  (void*) android_view_RenderNode_getBottom },
+    { "nGetCameraDistance",       "(J)F",  (void*) android_view_RenderNode_getCameraDistance },
+    { "nGetScaleX",               "(J)F",  (void*) android_view_RenderNode_getScaleX },
+    { "nGetScaleY",               "(J)F",  (void*) android_view_RenderNode_getScaleY },
+    { "nGetTranslationX",         "(J)F",  (void*) android_view_RenderNode_getTranslationX },
+    { "nGetTranslationY",         "(J)F",  (void*) android_view_RenderNode_getTranslationY },
+    { "nGetRotation",             "(J)F",  (void*) android_view_RenderNode_getRotation },
+    { "nGetRotationX",            "(J)F",  (void*) android_view_RenderNode_getRotationX },
+    { "nGetRotationY",            "(J)F",  (void*) android_view_RenderNode_getRotationY },
+    { "nGetPivotX",               "(J)F",  (void*) android_view_RenderNode_getPivotX },
+    { "nGetPivotY",               "(J)F",  (void*) android_view_RenderNode_getPivotY },
+#endif
+};
+
+#ifdef USE_OPENGL_RENDERER
+    #define FIND_CLASS(var, className) \
+            var = env->FindClass(className); \
+            LOG_FATAL_IF(! var, "Unable to find class " className);
+
+    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+            var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+            LOG_FATAL_IF(! var, "Unable to find method " methodName);
+#else
+    #define FIND_CLASS(var, className)
+    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
+#endif
+
+int register_android_view_RenderNode(JNIEnv* env) {
+    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
+
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index ed84a64..c5ab284 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -117,18 +117,25 @@
 }
 
 static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
-        jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
+        jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
+        bool useIdentityTransform) {
     sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
     if (displayToken == NULL) {
         return NULL;
     }
 
     ScreenshotClient* screenshot = new ScreenshotClient();
-    status_t res = (width > 0 && height > 0)
-            ? (allLayers
-                    ? screenshot->update(displayToken, width, height)
-                    : screenshot->update(displayToken, width, height, minLayer, maxLayer))
-            : screenshot->update(displayToken);
+    status_t res;
+    if (width > 0 && height > 0) {
+        if (allLayers) {
+            res = screenshot->update(displayToken, width, height, useIdentityTransform);
+        } else {
+            res = screenshot->update(displayToken, width, height, minLayer, maxLayer,
+                    useIdentityTransform);
+        }
+    } else {
+        res = screenshot->update(displayToken, useIdentityTransform);
+    }
     if (res != NO_ERROR) {
         delete screenshot;
         return NULL;
@@ -162,10 +169,11 @@
 
     // takes ownership of ScreenshotClient
     ScreenshotPixelRef* pixels = new ScreenshotPixelRef(screenshotInfo, screenshot);
-    ssize_t rowBytes = screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
+    const ssize_t rowBytes =
+            screenshot->getStride() * android::bytesPerPixel(screenshot->getFormat());
 
     SkBitmap* bitmap = new SkBitmap();
-    bitmap->setConfig(screenshotInfo, rowBytes);
+    bitmap->setConfig(screenshotInfo, (size_t)rowBytes);
     if (screenshotInfo.fWidth > 0 && screenshotInfo.fHeight > 0) {
         bitmap->setPixelRef(pixels)->unref();
         bitmap->lockPixels();
@@ -181,7 +189,8 @@
 
 static void nativeScreenshot(JNIEnv* env, jclass clazz,
         jobject displayTokenObj, jobject surfaceObj,
-        jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
+        jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
+        bool useIdentityTransform) {
     sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
     if (displayToken != NULL) {
         sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
@@ -192,7 +201,8 @@
             }
             ScreenshotClient::capture(
                     displayToken, consumer->getIGraphicBufferProducer(),
-                    width, height, uint32_t(minLayer), uint32_t(maxLayer));
+                    width, height, uint32_t(minLayer), uint32_t(maxLayer),
+                    useIdentityTransform);
         }
     }
 }
@@ -396,9 +406,9 @@
             (void*)nativeRelease },
     {"nativeDestroy", "(J)V",
             (void*)nativeDestroy },
-    {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;",
+    {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZZ)Landroid/graphics/Bitmap;",
             (void*)nativeScreenshotBitmap },
-    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZ)V",
+    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZZ)V",
             (void*)nativeScreenshot },
     {"nativeOpenTransaction", "()V",
             (void*)nativeOpenTransaction },
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
new file mode 100644
index 0000000..28cee4b
--- /dev/null
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -0,0 +1,216 @@
+/*
+ * 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 "ThreadedRenderer"
+
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <utils/StrongPointer.h>
+#include <android_runtime/android_view_Surface.h>
+#include <system/window.h>
+
+#include <renderthread/RenderProxy.h>
+#include <renderthread/RenderTask.h>
+#include <renderthread/RenderThread.h>
+
+namespace android {
+
+#ifdef USE_OPENGL_RENDERER
+
+using namespace android::uirenderer;
+using namespace android::uirenderer::renderthread;
+
+static jmethodID gRunnableMethod;
+
+class JavaTask : public RenderTask {
+public:
+    JavaTask(JNIEnv* env, jobject jrunnable) {
+        env->GetJavaVM(&mVm);
+        mRunnable = env->NewGlobalRef(jrunnable);
+    }
+
+    virtual void run() {
+        env()->CallVoidMethod(mRunnable, gRunnableMethod);
+        env()->DeleteGlobalRef(mRunnable);
+        delete this;
+    };
+
+private:
+    JNIEnv* env() {
+        JNIEnv* env;
+        if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+            return 0;
+        }
+        return env;
+    }
+
+    JavaVM* mVm;
+    jobject mRunnable;
+};
+
+static void android_view_ThreadedRenderer_postToRenderThread(JNIEnv* env, jobject clazz,
+        jobject jrunnable) {
+    RenderTask* task = new JavaTask(env, jrunnable);
+    RenderThread::getInstance().queue(task);
+}
+
+static jlong android_view_ThreadedRenderer_createProxy(JNIEnv* env, jobject clazz,
+        jboolean translucent) {
+    return (jlong) new RenderProxy(translucent);
+}
+
+static void android_view_ThreadedRenderer_deleteProxy(JNIEnv* env, jobject clazz,
+        jlong proxyPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    delete proxy;
+}
+
+static jboolean android_view_ThreadedRenderer_initialize(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jobject jsurface) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    sp<ANativeWindow> window = android_view_Surface_getNativeWindow(env, jsurface);
+    return proxy->initialize(window.get());
+}
+
+static void android_view_ThreadedRenderer_updateSurface(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jobject jsurface) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    sp<ANativeWindow> window;
+    if (jsurface) {
+        window = android_view_Surface_getNativeWindow(env, jsurface);
+    }
+    proxy->updateSurface(window.get());
+}
+
+static void android_view_ThreadedRenderer_setup(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jint width, jint height) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    proxy->setup(width, height);
+}
+
+static void android_view_ThreadedRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jlong displayListPtr, jlong newDataPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
+    proxy->setDisplayListData(displayList, newData);
+}
+
+static void android_view_ThreadedRenderer_drawDisplayList(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jlong displayListPtr, jint dirtyLeft, jint dirtyTop,
+        jint dirtyRight, jint dirtyBottom) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    proxy->drawDisplayList(displayList, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
+}
+
+static void android_view_ThreadedRenderer_destroyCanvas(JNIEnv* env, jobject clazz,
+        jlong proxyPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    proxy->destroyCanvas();
+}
+
+static void android_view_ThreadedRenderer_attachFunctor(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jlong functorPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
+    proxy->attachFunctor(functor);
+}
+
+static void android_view_ThreadedRenderer_detachFunctor(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jlong functorPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    Functor* functor = reinterpret_cast<Functor*>(functorPtr);
+    proxy->detachFunctor(functor);
+}
+
+static void android_view_ThreadedRenderer_runWithGlContext(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jobject jrunnable) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    RenderTask* task = new JavaTask(env, jrunnable);
+    proxy->runWithGlContext(task);
+}
+
+static jlong android_view_ThreadedRenderer_createDisplayListLayer(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jint width, jint height) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    DeferredLayerUpdater* layer = proxy->createDisplayListLayer(width, height);
+    return reinterpret_cast<jlong>(layer);
+}
+
+static jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobject clazz,
+        jlong proxyPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    DeferredLayerUpdater* layer = proxy->createTextureLayer();
+    return reinterpret_cast<jlong>(layer);
+}
+
+static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jlong layerPtr, jlong bitmapPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
+    SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
+    return proxy->copyLayerInto(layer, bitmap);
+}
+
+static void android_view_ThreadedRenderer_destroyLayer(JNIEnv* env, jobject clazz,
+        jlong proxyPtr, jlong layerPtr) {
+    RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerPtr);
+    proxy->destroyLayer(layer);
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/ThreadedRenderer";
+
+static JNINativeMethod gMethods[] = {
+#ifdef USE_OPENGL_RENDERER
+    { "postToRenderThread", "(Ljava/lang/Runnable;)V",   (void*) android_view_ThreadedRenderer_postToRenderThread },
+    { "nCreateProxy", "(Z)J", (void*) android_view_ThreadedRenderer_createProxy },
+    { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
+    { "nInitialize", "(JLandroid/view/Surface;)Z", (void*) android_view_ThreadedRenderer_initialize },
+    { "nUpdateSurface", "(JLandroid/view/Surface;)V", (void*) android_view_ThreadedRenderer_updateSurface },
+    { "nSetup", "(JII)V", (void*) android_view_ThreadedRenderer_setup },
+    { "nSetDisplayListData", "(JJJ)V", (void*) android_view_ThreadedRenderer_setDisplayListData },
+    { "nDrawDisplayList", "(JJIIII)V", (void*) android_view_ThreadedRenderer_drawDisplayList },
+    { "nDestroyCanvas", "(J)V", (void*) android_view_ThreadedRenderer_destroyCanvas },
+    { "nAttachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_attachFunctor },
+    { "nDetachFunctor", "(JJ)V", (void*) android_view_ThreadedRenderer_detachFunctor },
+    { "nRunWithGlContext", "(JLjava/lang/Runnable;)V", (void*) android_view_ThreadedRenderer_runWithGlContext },
+    { "nCreateDisplayListLayer", "(JII)J", (void*) android_view_ThreadedRenderer_createDisplayListLayer },
+    { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
+    { "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
+    { "nDestroyLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_destroyLayer },
+#endif
+};
+
+int register_android_view_ThreadedRenderer(JNIEnv* env) {
+#ifdef USE_OPENGL_RENDERER
+    jclass cls = env->FindClass("java/lang/Runnable");
+    gRunnableMethod = env->GetMethodID(cls, "run", "()V");
+    env->DeleteLocalRef(cls);
+#endif
+    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 0b9ad9b..c84a466 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -37,6 +37,7 @@
 
 static struct {
     jfieldID size;
+    jfieldID capacity;
     jfieldID iface;
     jfieldID uid;
     jfieldID set;
@@ -49,7 +50,6 @@
 } gNetworkStatsClassInfo;
 
 struct stats_line {
-    int32_t idx;
     char iface[32];
     int32_t uid;
     int32_t set;
@@ -60,8 +60,41 @@
     int64_t txPackets;
 };
 
+static jobjectArray get_string_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jobjectArray array = (jobjectArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewObjectArray(size, gStringClass, NULL);
+}
+
+static jintArray get_int_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jintArray array = (jintArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewIntArray(size);
+}
+
+static jlongArray get_long_array(JNIEnv* env, jobject obj, jfieldID field, int size, bool grow)
+{
+    if (!grow) {
+        jlongArray array = (jlongArray)env->GetObjectField(obj, field);
+        if (array != NULL) {
+            return array;
+        }
+    }
+    return env->NewLongArray(size);
+}
+
 static int readNetworkStatsDetail(JNIEnv* env, jclass clazz, jobject stats,
-        jstring path, jint limitUid) {
+        jstring path, jint limitUid, jobjectArray limitIfacesObj, jint limitTag) {
     ScopedUtfChars path8(env, path);
     if (path8.c_str() == NULL) {
         return -1;
@@ -72,50 +105,146 @@
         return -1;
     }
 
+    Vector<String8> limitIfaces;
+    if (limitIfacesObj != NULL && env->GetArrayLength(limitIfacesObj) > 0) {
+        int num = env->GetArrayLength(limitIfacesObj);
+        limitIfaces.setCapacity(num);
+        for (int i=0; i<num; i++) {
+            jstring string = (jstring)env->GetObjectArrayElement(limitIfacesObj, i);
+            ScopedUtfChars string8(env, string);
+            if (string8.c_str() != NULL) {
+                limitIfaces.add(String8(string8.c_str()));
+            }
+        }
+    }
+
     Vector<stats_line> lines;
 
     int lastIdx = 1;
+    int idx;
     char buffer[384];
     while (fgets(buffer, sizeof(buffer), fp) != NULL) {
         stats_line s;
         int64_t rawTag;
-        if (sscanf(buffer, "%d %31s 0x%llx %u %u %llu %llu %llu %llu", &s.idx,
-                s.iface, &rawTag, &s.uid, &s.set, &s.rxBytes, &s.rxPackets,
-                &s.txBytes, &s.txPackets) == 9) {
-            if (s.idx != lastIdx + 1) {
-                ALOGE("inconsistent idx=%d after lastIdx=%d", s.idx, lastIdx);
-                return -1;
+        char* pos = buffer;
+        char* endPos;
+        // First field is the index.
+        idx = (int)strtol(pos, &endPos, 10);
+        //ALOGI("Index #%d: %s", idx, buffer);
+        if (pos == endPos) {
+            // Skip lines that don't start with in index.  In particular,
+            // this will skip the initial header line.
+            continue;
+        }
+        if (idx != lastIdx + 1) {
+            ALOGE("inconsistent idx=%d after lastIdx=%d: %s", idx, lastIdx, buffer);
+            fclose(fp);
+            return -1;
+        }
+        lastIdx = idx;
+        pos = endPos;
+        // Skip whitespace.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Next field is iface.
+        int ifaceIdx = 0;
+        while (*pos != ' ' && *pos != 0 && ifaceIdx < (int)(sizeof(s.iface)-1)) {
+            s.iface[ifaceIdx] = *pos;
+            ifaceIdx++;
+            pos++;
+        }
+        if (*pos != ' ') {
+            ALOGE("bad iface: %s", buffer);
+            fclose(fp);
+            return -1;
+        }
+        s.iface[ifaceIdx] = 0;
+        if (limitIfaces.size() > 0) {
+            // Is this an iface the caller is interested in?
+            int i = 0;
+            while (i < (int)limitIfaces.size()) {
+                if (limitIfaces[i] == s.iface) {
+                    break;
+                }
+                i++;
             }
-            lastIdx = s.idx;
-
-            s.tag = rawTag >> 32;
+            if (i >= (int)limitIfaces.size()) {
+                // Nothing matched; skip this line.
+                //ALOGI("skipping due to iface: %s", buffer);
+                continue;
+            }
+        }
+        // Skip whitespace.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Next field is tag.
+        rawTag = strtoll(pos, &endPos, 16);
+        //ALOGI("Index #%d: %s", idx, buffer);
+        if (pos == endPos) {
+            ALOGE("bad tag: %s", pos);
+            fclose(fp);
+            return -1;
+        }
+        s.tag = rawTag >> 32;
+        if (limitTag != -1 && s.tag != limitTag) {
+            //ALOGI("skipping due to tag: %s", buffer);
+            continue;
+        }
+        pos = endPos;
+        // Skip whitespace.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Parse remaining fields.
+        if (sscanf(pos, "%u %u %llu %llu %llu %llu",
+                &s.uid, &s.set, &s.rxBytes, &s.rxPackets,
+                &s.txBytes, &s.txPackets) == 6) {
+            if (limitUid != -1 && limitUid != s.uid) {
+                //ALOGI("skipping due to uid: %s", buffer);
+                continue;
+            }
             lines.push_back(s);
+        } else {
+            //ALOGI("skipping due to bad remaining fields: %s", pos);
         }
     }
 
     if (fclose(fp) != 0) {
+        ALOGE("Failed to close netstats file");
         return -1;
     }
 
     int size = lines.size();
+    bool grow = size > env->GetIntField(stats, gNetworkStatsClassInfo.capacity);
 
-    ScopedLocalRef<jobjectArray> iface(env, env->NewObjectArray(size, gStringClass, NULL));
+    ScopedLocalRef<jobjectArray> iface(env, get_string_array(env, stats,
+            gNetworkStatsClassInfo.iface, size, grow));
     if (iface.get() == NULL) return -1;
-    ScopedIntArrayRW uid(env, env->NewIntArray(size));
+    ScopedIntArrayRW uid(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.uid, size, grow));
     if (uid.get() == NULL) return -1;
-    ScopedIntArrayRW set(env, env->NewIntArray(size));
+    ScopedIntArrayRW set(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.set, size, grow));
     if (set.get() == NULL) return -1;
-    ScopedIntArrayRW tag(env, env->NewIntArray(size));
+    ScopedIntArrayRW tag(env, get_int_array(env, stats,
+            gNetworkStatsClassInfo.tag, size, grow));
     if (tag.get() == NULL) return -1;
-    ScopedLongArrayRW rxBytes(env, env->NewLongArray(size));
+    ScopedLongArrayRW rxBytes(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.rxBytes, size, grow));
     if (rxBytes.get() == NULL) return -1;
-    ScopedLongArrayRW rxPackets(env, env->NewLongArray(size));
+    ScopedLongArrayRW rxPackets(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.rxPackets, size, grow));
     if (rxPackets.get() == NULL) return -1;
-    ScopedLongArrayRW txBytes(env, env->NewLongArray(size));
+    ScopedLongArrayRW txBytes(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.txBytes, size, grow));
     if (txBytes.get() == NULL) return -1;
-    ScopedLongArrayRW txPackets(env, env->NewLongArray(size));
+    ScopedLongArrayRW txPackets(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.txPackets, size, grow));
     if (txPackets.get() == NULL) return -1;
-    ScopedLongArrayRW operations(env, env->NewLongArray(size));
+    ScopedLongArrayRW operations(env, get_long_array(env, stats,
+            gNetworkStatsClassInfo.operations, size, grow));
     if (operations.get() == NULL) return -1;
 
     for (int i = 0; i < size; i++) {
@@ -132,15 +261,18 @@
     }
 
     env->SetIntField(stats, gNetworkStatsClassInfo.size, size);
-    env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray());
-    env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray());
+    if (grow) {
+        env->SetIntField(stats, gNetworkStatsClassInfo.capacity, size);
+        env->SetObjectField(stats, gNetworkStatsClassInfo.iface, iface.get());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.uid, uid.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.set, set.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.tag, tag.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.rxBytes, rxBytes.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.rxPackets, rxPackets.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.txBytes, txBytes.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.txPackets, txPackets.getJavaArray());
+        env->SetObjectField(stats, gNetworkStatsClassInfo.operations, operations.getJavaArray());
+    }
 
     return 0;
 }
@@ -157,7 +289,7 @@
 
 static JNINativeMethod gMethods[] = {
         { "nativeReadNetworkStatsDetail",
-                "(Landroid/net/NetworkStats;Ljava/lang/String;I)I",
+                "(Landroid/net/NetworkStats;Ljava/lang/String;I[Ljava/lang/String;I)I",
                 (void*) readNetworkStatsDetail }
 };
 
@@ -170,6 +302,7 @@
 
     jclass clazz = env->FindClass("android/net/NetworkStats");
     gNetworkStatsClassInfo.size = env->GetFieldID(clazz, "size", "I");
+    gNetworkStatsClassInfo.capacity = env->GetFieldID(clazz, "capacity", "I");
     gNetworkStatsClassInfo.iface = env->GetFieldID(clazz, "iface", "[Ljava/lang/String;");
     gNetworkStatsClassInfo.uid = env->GetFieldID(clazz, "uid", "[I");
     gNetworkStatsClassInfo.set = env->GetFieldID(clazz, "set", "[I");
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 3035d15..3d421d5 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -107,7 +107,7 @@
 
 static jint* beginNativeAttribList(JNIEnv *_env, jintArray attrib_list) {
     if (attrib_list != NULL) {
-        return (jint *)_env->GetPrimitiveArrayCritical(attrib_list, (jboolean *)0);
+        return _env->GetIntArrayElements(attrib_list, (jboolean *)0);
     } else {
         return(jint*) gNull_attrib_base;
     }
@@ -115,7 +115,7 @@
 
 static void endNativeAttributeList(JNIEnv *_env, jintArray attrib_list, jint* attrib_base) {
     if (attrib_list != NULL) {
-        _env->ReleasePrimitiveArrayCritical(attrib_list, attrib_base, JNI_ABORT);
+        _env->ReleaseIntArrayElements(attrib_list, attrib_base, JNI_ABORT);
     }
 }
 
@@ -154,9 +154,9 @@
     EGLBoolean success = EGL_FALSE;
     int len = _env->GetArrayLength(value);
     if (len) {
-        jint* base = (jint *)_env->GetPrimitiveArrayCritical(value, (jboolean *)0);
+        jint* base = _env->GetIntArrayElements(value, (jboolean *)0);
         success = eglQueryContext(dpy, ctx, attribute, base);
-        _env->ReleasePrimitiveArrayCritical(value, base, JNI_ABORT);
+        _env->ReleaseIntArrayElements(value, base, JNI_ABORT);
     }
     return EglBoolToJBool(success);
 }
@@ -174,9 +174,9 @@
     EGLBoolean success = EGL_FALSE;
     int len = _env->GetArrayLength(value);
     if (len) {
-        jint* base = (jint *)_env->GetPrimitiveArrayCritical(value, (jboolean *)0);
+        jint* base = _env->GetIntArrayElements(value, (jboolean *)0);
         success = eglQuerySurface(dpy, sur, attribute, base);
-        _env->ReleasePrimitiveArrayCritical(value, base, JNI_ABORT);
+        _env->ReleaseIntArrayElements(value, base, JNI_ABORT);
     }
     return EglBoolToJBool(success);
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 0d14efc..2168bd1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -83,6 +83,8 @@
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_DELETED" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_DISABLED" />
     <protected-broadcast android:name="android.appwidget.action.APPWIDGET_ENABLED" />
+    <protected-broadcast android:name="android.appwidget.action.APPWIDGET_HOST_RESTORED" />
+    <protected-broadcast android:name="android.appwidget.action.APPWIDGET_RESTORED" />
 
     <protected-broadcast android:name="android.backup.intent.RUN" />
     <protected-broadcast android:name="android.backup.intent.CLEAR" />
@@ -583,7 +585,7 @@
     <!-- =============================================================== -->
     <eat-comment />
 
-    <!-- Used for permissions that provide access to the user voicemail box. -->
+    <!-- Used for permissions that provide access to device alarms. -->
     <permission-group android:name="android.permission-group.DEVICE_ALARMS"
         android:label="@string/permgrouplab_deviceAlarms"
         android:icon="@drawable/perm_group_device_alarms"
@@ -815,8 +817,15 @@
     <!-- Allows access to the loop radio (Android@Home mesh network) device.
 	@hide -->
     <permission android:name="android.permission.LOOP_RADIO"
-	android:permissionGroup="android.permission-group.NETWORK"
-	android:protectionLevel="signature|system" />
+	    android:permissionGroup="android.permission-group.NETWORK"
+	    android:protectionLevel="signature|system" />
+
+    <!-- Allows for the NFC process to unlock the device
+         @hide This should only be used by the Nfc apk
+    -->
+    <permission android:name="android.permission.NFC_UNLOCK"
+        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+        android:protectionLevel="signature" />
 
     <!-- ================================== -->
     <!-- Permissions for accessing accounts -->
@@ -988,6 +997,14 @@
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
         android:protectionLevel="signature" />
 
+    <!-- Allows an application to communicate with a SIM card using logical
+         channels. -->
+    <permission android:name="android.permission.SIM_COMMUNICATION"
+        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+        android:label="@string/permlab_sim_communication"
+        android:description="@string/permdesc_sim_communication"
+        android:protectionLevel="dangerous" />
+
     <!-- =========================================== -->
     <!-- Permissions associated with audio capture -->
     <!-- =========================================== -->
@@ -1052,7 +1069,7 @@
     <!-- =========================================== -->
     <eat-comment />
 
-    <!-- Used for permissions that are associated with accessing and modifyign
+    <!-- Used for permissions that are associated with accessing and modifying
          telephony state: placing calls, intercepting outgoing calls, reading
          and modifying the phone state. -->
     <permission-group android:name="android.permission-group.PHONE_CALLS"
@@ -1062,8 +1079,9 @@
         android:permissionGroupFlags="personalInfo"
         android:priority="370" />
 
-    <!-- Allows an application to modify or abort outgoing
-         calls. -->
+    <!-- Allows an application to see the number being dialed during an outgoing
+         call with the option to redirect the call to a different number or
+         abort the call altogether. -->
     <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
         android:permissionGroup="android.permission-group.PHONE_CALLS"
         android:protectionLevel="dangerous"
@@ -1261,9 +1279,10 @@
     <!-- @hide Fuller form of {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
          that removes restrictions on where broadcasts can be sent and allows other
          types of interactions. -->
+    <!-- TODO: Remove the system protection level.-->
     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="signature"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_interactAcrossUsersFull"
         android:description="@string/permdesc_interactAcrossUsersFull" />
 
@@ -1718,6 +1737,21 @@
         android:label="@string/permlab_manageCaCertificates"
         android:description="@string/permdesc_manageCaCertificates" />
 
+    <!-- Allows an application to do certain operations needed for
+         interacting with the recovery (system update) system. -->
+    <permission android:name="android.permission.RECOVERY"
+        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+        android:protectionLevel="signature|system"
+        android:label="@string/permlab_recovery"
+        android:description="@string/permdesc_recovery" />
+
+    <!-- Allows the system to bind to an application's idle services
+         @hide -->
+    <permission android:name="android.permission.BIND_IDLE_SERVICE"
+        android:protectionLevel="signature"
+        android:label="@string/permlab_bindIdleService"
+        android:description="@string/permdesc_bindIdleService" />
+
     <!-- ========================================= -->
     <!-- Permissions for special development tools -->
     <!-- ========================================= -->
@@ -1887,24 +1921,12 @@
         android:description="@string/permdesc_filter_events"
         android:protectionLevel="signature" />
 
-    <!-- @hide Allows an application to retrieve info for a window from the window manager. -->
-    <permission android:name="android.permission.RETRIEVE_WINDOW_INFO"
-        android:label="@string/permlab_retrieve_window_info"
-        android:description="@string/permdesc_retrieve_window_info"
-        android:protectionLevel="signature" />
-
     <!-- @hide Allows an application to temporary enable accessibility on the device. -->
     <permission android:name="android.permission.TEMPORARY_ENABLE_ACCESSIBILITY"
         android:label="@string/permlab_temporary_enable_accessibility"
         android:description="@string/permdesc_temporary_enable_accessibility"
         android:protectionLevel="signature" />
 
-    <!-- @hide Allows an application to magnify the content of a display. -->
-    <permission android:name="android.permission.MAGNIFY_DISPLAY"
-        android:label="@string/permlab_magnify_display"
-        android:description="@string/permdesc_magnify_display"
-        android:protectionLevel="signature" />
-
     <!-- Allows an application to watch and control how activities are
          started globally in the system.  Only for is in debugging
          (usually the monkey command).
@@ -2044,6 +2066,14 @@
         android:description="@string/permdesc_setPointerSpeed"
         android:protectionLevel="signature" />
 
+    <!-- Allows low-level access to setting input device calibration.
+         <p>Not for use by normal applications.
+         @hide -->
+    <permission android:name="android.permission.SET_INPUT_CALIBRATION"
+        android:label="@string/permlab_setInputCalibration"
+        android:description="@string/permdesc_setInputCalibration"
+        android:protectionLevel="signature" />
+
     <!-- Allows low-level access to setting the keyboard layout.
          <p>Not for use by third-party applications.
          @hide -->
@@ -2116,6 +2146,13 @@
         android:description="@string/permdesc_readFrameBuffer"
         android:protectionLevel="signature|system" />
 
+    <!-- Allows an application to use InputFlinger's low level features.
+    <p>Not for use by third-party applications. -->
+    <permission android:name="android.permission.ACCESS_INPUT_FLINGER"
+        android:label="@string/permlab_accessInputFlinger"
+        android:description="@string/permdesc_accessInputFlinger"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to configure and connect to Wifi displays
          @hide -->
     <permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY"
@@ -2359,6 +2396,12 @@
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
         android:protectionLevel="signature" />
 
+    <!-- Internal permission to allows an application to read indexable data.
+        @hide -->
+    <permission android:name="android.permission.READ_SEARCH_INDEXABLES"
+        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+        android:protectionLevel="signature|system" />
+
     <!-- Allows applications to set a live wallpaper.
          @hide XXX Change to signature once the picker is moved to its
          own apk as Ghod Intended. -->
@@ -2712,6 +2755,14 @@
             </intent-filter>
         </service>
 
+        <service android:name="com.android.server.MountServiceIdler"
+                 android:exported="false"
+                 android:permission="android.permission.BIND_IDLE_SERVICE" >
+            <intent-filter>
+                <action android:name="android.service.idle.IdleService" />
+            </intent-filter>
+        </service>
+
     </application>
 
 </manifest>
diff --git a/core/res/res/color/primary_text_disable_only_quantum_dark.xml b/core/res/res/color/primary_text_disable_only_quantum_dark.xml
new file mode 100644
index 0000000..60a91f2
--- /dev/null
+++ b/core/res/res/color/primary_text_disable_only_quantum_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_quantum_dark"/>
+    <item android:color="@android:color/bright_foreground_quantum_dark"/>
+</selector>
diff --git a/core/res/res/color/primary_text_disable_only_quantum_light.xml b/core/res/res/color/primary_text_disable_only_quantum_light.xml
new file mode 100644
index 0000000..ced9051
--- /dev/null
+++ b/core/res/res/color/primary_text_disable_only_quantum_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:alpha="0.5" android:color="@android:color/bright_foreground_quantum_light"/>
+    <item android:color="@android:color/bright_foreground_quantum_light"/>
+</selector>
diff --git a/core/res/res/color/search_url_text_quantum_dark.xml b/core/res/res/color/search_url_text_quantum_dark.xml
new file mode 100644
index 0000000..5263fd7
--- /dev/null
+++ b/core/res/res/color/search_url_text_quantum_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:color="@android:color/search_url_text_pressed"/>
+    <item android:state_selected="true" android:color="@android:color/search_url_text_selected"/>
+    <item android:color="@android:color/search_url_text_normal"/>
+</selector>
diff --git a/core/res/res/color/search_url_text_quantum_light.xml b/core/res/res/color/search_url_text_quantum_light.xml
new file mode 100644
index 0000000..5263fd7
--- /dev/null
+++ b/core/res/res/color/search_url_text_quantum_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:color="@android:color/search_url_text_pressed"/>
+    <item android:state_selected="true" android:color="@android:color/search_url_text_selected"/>
+    <item android:color="@android:color/search_url_text_normal"/>
+</selector>
diff --git a/core/res/res/drawable-hdpi/ab_solid_shadow_qntm.9.png b/core/res/res/drawable-hdpi/ab_solid_shadow_qntm.9.png
new file mode 100644
index 0000000..717ec1a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_solid_shadow_qntm.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-hdpi/ab_transparent_qntm_alpha.9.png
new file mode 100644
index 0000000..5fa4ec4
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ab_transparent_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_off_qntm_alpha.png
new file mode 100644
index 0000000..5bc1d90
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_check_on_qntm_alpha.png
new file mode 100644
index 0000000..e5de2c1
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_check_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-hdpi/btn_qntm_alpha.9.png
new file mode 100644
index 0000000..171688f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..7bef530
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_off_qntm_alpha.png
new file mode 100644
index 0000000..ae50dd5
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..0678dbb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_radio_on_qntm_alpha.png
new file mode 100644
index 0000000..f332925
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_radio_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-hdpi/btn_star_qntm_alpha.png
new file mode 100644
index 0000000..e11896f6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_star_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-hdpi/expander_close_qntm_alpha.9.png
new file mode 100644
index 0000000..7bf9d90
--- /dev/null
+++ b/core/res/res/drawable-hdpi/expander_close_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-hdpi/expander_open_qntm_alpha.9.png
new file mode 100644
index 0000000..d427a20
--- /dev/null
+++ b/core/res/res/drawable-hdpi/expander_open_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-hdpi/fastscroll_thumb_qntm_alpha.png
new file mode 100644
index 0000000..2000422d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/fastscroll_thumb_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-hdpi/fastscroll_track_qntm_alpha.9.png
new file mode 100644
index 0000000..61ef6f6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/fastscroll_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-hdpi/ic_ab_back_qntm_am_alpha.png
new file mode 100644
index 0000000..f0910d8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_ab_back_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_cab_done_qntm_alpha.png
new file mode 100644
index 0000000..5635459
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_cab_done_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_dialog_alert_qntm_alpha.png
new file mode 100644
index 0000000..95cfb32
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_dialog_alert_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_find_next_qntm_alpha.png
new file mode 100644
index 0000000..6d5edac
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_find_next_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_find_previous_qntm_alpha.png
new file mode 100644
index 0000000..a5921af
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_find_previous_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-hdpi/ic_menu_copy_qntm_am_alpha.png
new file mode 100644
index 0000000..d6d1f2f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_copy_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_cut_qntm_alpha.png
new file mode 100644
index 0000000..ec8db6f6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_cut_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_find_qntm_alpha.png
new file mode 100644
index 0000000..0f9d41f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_find_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_qntm_alpha.png
new file mode 100644
index 0000000..1ba1295
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_moreoverflow_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-hdpi/ic_menu_paste_qntm_am_alpha.png
new file mode 100644
index 0000000..bf44722
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_paste_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_search_qntm_alpha.png
new file mode 100644
index 0000000..a0501b3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_search_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_selectall_qntm_alpha.png
new file mode 100644
index 0000000..8539741
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_selectall_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-hdpi/ic_menu_share_qntm_alpha.png
new file mode 100644
index 0000000..0eacedd
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_menu_share_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-hdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..8d529b8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_search_api_holo_light.png b/core/res/res/drawable-hdpi/ic_search_api_holo_light.png
index 72e207b..8b15ecb 100644
--- a/core/res/res/drawable-hdpi/ic_search_api_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..32062a6
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png
index 3481c98..d2b2d21 100644
--- a/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png
+++ b/core/res/res/drawable-hdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-hdpi/list_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..77845df
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-hdpi/list_section_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..20baf2a
--- /dev/null
+++ b/core/res/res/drawable-hdpi/list_section_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/core/res/res/drawable-hdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index 6f37a22..0000000
--- a/core/res/res/drawable-hdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-hdpi/progress_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..a278ed7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/progress_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-hdpi/progress_qntm_alpha.9.png
new file mode 100644
index 0000000..b11de9e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/progress_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
index 6eddc3f..fb9e7aa 100644
--- a/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-hdpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-hdpi/scrollbar_handle_qntm_alpha.9.png
new file mode 100644
index 0000000..a5166f2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrollbar_handle_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..10ce2bc
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_control_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_off_qntm_alpha.png
new file mode 100644
index 0000000..f1023ea
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_control_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..0678dbb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_control_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-hdpi/scrubber_control_on_qntm_alpha.png
new file mode 100644
index 0000000..15ceeee
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_control_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-hdpi/scrubber_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..4cfb1a7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/scrubber_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-hdpi/spinner_qntm_am_alpha.9.png
new file mode 100644
index 0000000..66673d3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/spinner_qntm_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-hdpi/switch_off_qntm_alpha.9.png
new file mode 100644
index 0000000..90b1498
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_off_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-hdpi/switch_on_qntm_alpha.9.png
new file mode 100644
index 0000000..b535758
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_on_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png
new file mode 100644
index 0000000..b11de9e
--- /dev/null
+++ b/core/res/res/drawable-hdpi/switch_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png
new file mode 100644
index 0000000..233d409
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png
new file mode 100644
index 0000000..68b1dd7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-hdpi/text_cursor_qntm_alpha.9.png
new file mode 100644
index 0000000..0179433
--- /dev/null
+++ b/core/res/res/drawable-hdpi/text_cursor_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-hdpi/textfield_activated_qntm_alpha.9.png
new file mode 100644
index 0000000..7c77a45
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_activated_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-hdpi/textfield_default_qntm_alpha.9.png
new file mode 100644
index 0000000..bc6da21
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_default_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ab_solid_shadow_qntm.9.png b/core/res/res/drawable-ldpi/ab_solid_shadow_qntm.9.png
new file mode 100644
index 0000000..098a315
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ab_solid_shadow_qntm.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-ldpi/ab_transparent_qntm_alpha.9.png
new file mode 100644
index 0000000..4d4cb4f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ab_transparent_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_check_off_qntm_alpha.png
new file mode 100644
index 0000000..fbe176f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_check_on_qntm_alpha.png
new file mode 100644
index 0000000..5fd18e5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_qntm_alpha.9.png b/core/res/res/drawable-ldpi/btn_qntm_alpha.9.png
new file mode 100644
index 0000000..1b648db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..ac27576
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_off_qntm_alpha.png
new file mode 100644
index 0000000..d17081f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..458abaf
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_radio_on_qntm_alpha.png
new file mode 100644
index 0000000..f31d37f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_qntm_alpha.png b/core/res/res/drawable-ldpi/btn_star_qntm_alpha.png
new file mode 100644
index 0000000..ae665fd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-ldpi/expander_close_qntm_alpha.9.png
new file mode 100644
index 0000000..19ac6f5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/expander_close_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-ldpi/expander_open_qntm_alpha.9.png
new file mode 100644
index 0000000..e51f018
--- /dev/null
+++ b/core/res/res/drawable-ldpi/expander_open_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-ldpi/fastscroll_thumb_qntm_alpha.png
new file mode 100644
index 0000000..c901730
--- /dev/null
+++ b/core/res/res/drawable-ldpi/fastscroll_thumb_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-ldpi/fastscroll_track_qntm_alpha.9.png
new file mode 100644
index 0000000..833dac9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/fastscroll_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-ldpi/ic_ab_back_qntm_am_alpha.png
new file mode 100644
index 0000000..96e86b6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_ab_back_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_cab_done_qntm_alpha.png
new file mode 100644
index 0000000..8ee0546
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_cab_done_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_dialog_alert_qntm_alpha.png
new file mode 100644
index 0000000..f604e8b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_alert_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_find_next_qntm_alpha.png
new file mode 100644
index 0000000..dd6fe20
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_find_next_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_find_previous_qntm_alpha.png
new file mode 100644
index 0000000..d4598ba
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_find_previous_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-ldpi/ic_menu_copy_qntm_am_alpha.png
new file mode 100644
index 0000000..565280b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_copy_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_cut_qntm_alpha.png
new file mode 100644
index 0000000..dbedece
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_cut_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_find_qntm_alpha.png
new file mode 100644
index 0000000..c828577
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_find_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_moreoverflow_qntm_alpha.png
new file mode 100644
index 0000000..d47f81e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_moreoverflow_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-ldpi/ic_menu_paste_qntm_am_alpha.png
new file mode 100644
index 0000000..430141b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_paste_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_search_qntm_alpha.png
new file mode 100644
index 0000000..ec759fb
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_search_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_selectall_qntm_alpha.png
new file mode 100644
index 0000000..7b520bc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_selectall_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-ldpi/ic_menu_share_qntm_alpha.png
new file mode 100644
index 0000000..db1e146
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_share_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-ldpi/list_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..77845df
--- /dev/null
+++ b/core/res/res/drawable-ldpi/list_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-ldpi/list_section_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..f1a0362
--- /dev/null
+++ b/core/res/res/drawable-ldpi/list_section_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-ldpi/progress_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..eb0933b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/progress_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progress_qntm_alpha.9.png b/core/res/res/drawable-ldpi/progress_qntm_alpha.9.png
new file mode 100644
index 0000000..a58128f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/progress_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
index 0562c03..a4ca3e0 100644
--- a/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-ldpi/scrollbar_handle_qntm_alpha.9.png
new file mode 100644
index 0000000..3e301ef
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrollbar_handle_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..df88c4e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrubber_control_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_off_qntm_alpha.png
new file mode 100644
index 0000000..bf6ce6c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrubber_control_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..458abaf
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrubber_control_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-ldpi/scrubber_control_on_qntm_alpha.png
new file mode 100644
index 0000000..85a06b9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrubber_control_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-ldpi/scrubber_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..6f99790
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrubber_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-ldpi/spinner_qntm_am_alpha.9.png
new file mode 100644
index 0000000..368a9b0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_qntm_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-ldpi/switch_off_qntm_alpha.9.png
new file mode 100644
index 0000000..9cd2df3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/switch_off_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-ldpi/switch_on_qntm_alpha.9.png
new file mode 100644
index 0000000..f9b287a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/switch_on_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-ldpi/switch_track_qntm_alpha.9.png
new file mode 100644
index 0000000..a58128f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/switch_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png
new file mode 100644
index 0000000..2244362
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png
new file mode 100644
index 0000000..22ea80e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-ldpi/text_cursor_qntm_alpha.9.png
new file mode 100644
index 0000000..4aaa79f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/text_cursor_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-ldpi/textfield_activated_qntm_alpha.9.png
new file mode 100644
index 0000000..d12ec06
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_activated_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-ldpi/textfield_default_qntm_alpha.9.png
new file mode 100644
index 0000000..6f0c57f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_default_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_solid_shadow_qntm.9.png b/core/res/res/drawable-mdpi/ab_solid_shadow_qntm.9.png
new file mode 100644
index 0000000..c00c545
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_solid_shadow_qntm.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-mdpi/ab_transparent_qntm_alpha.9.png
new file mode 100644
index 0000000..2e42386
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ab_transparent_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_off_qntm_alpha.png
new file mode 100644
index 0000000..2ab6b7f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_check_on_qntm_alpha.png
new file mode 100644
index 0000000..2211d83
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_check_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-mdpi/btn_qntm_alpha.9.png
new file mode 100644
index 0000000..fc51595
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..713fee8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_off_qntm_alpha.png
new file mode 100644
index 0000000..dcb90d0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..3c304bf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_radio_on_qntm_alpha.png
new file mode 100644
index 0000000..04a8edb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_radio_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-mdpi/btn_star_qntm_alpha.png
new file mode 100644
index 0000000..7ce950d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_star_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-mdpi/expander_close_qntm_alpha.9.png
new file mode 100644
index 0000000..6070397
--- /dev/null
+++ b/core/res/res/drawable-mdpi/expander_close_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-mdpi/expander_open_qntm_alpha.9.png
new file mode 100644
index 0000000..29a3a1a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/expander_open_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-mdpi/fastscroll_thumb_qntm_alpha.png
new file mode 100644
index 0000000..4984f9c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/fastscroll_thumb_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-mdpi/fastscroll_track_qntm_alpha.9.png
new file mode 100644
index 0000000..4041808
--- /dev/null
+++ b/core/res/res/drawable-mdpi/fastscroll_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-mdpi/ic_ab_back_qntm_am_alpha.png
new file mode 100644
index 0000000..e196bbe
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_ab_back_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_cab_done_qntm_alpha.png
new file mode 100644
index 0000000..541184a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_cab_done_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_dialog_alert_qntm_alpha.png
new file mode 100644
index 0000000..8a882f90
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_dialog_alert_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_find_next_qntm_alpha.png
new file mode 100644
index 0000000..1cfdb3f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_find_next_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_find_previous_qntm_alpha.png
new file mode 100644
index 0000000..0d3c009
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_find_previous_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-mdpi/ic_menu_copy_qntm_am_alpha.png
new file mode 100644
index 0000000..3fae32d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_copy_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_cut_qntm_alpha.png
new file mode 100644
index 0000000..61ff631
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_cut_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_find_qntm_alpha.png
new file mode 100644
index 0000000..6be897d
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_find_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_qntm_alpha.png
new file mode 100644
index 0000000..8415096
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_moreoverflow_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-mdpi/ic_menu_paste_qntm_am_alpha.png
new file mode 100644
index 0000000..112c268
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_paste_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_search_qntm_alpha.png
new file mode 100644
index 0000000..c5de768
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_search_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_selectall_qntm_alpha.png
new file mode 100644
index 0000000..6414956
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_selectall_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-mdpi/ic_menu_share_qntm_alpha.png
new file mode 100644
index 0000000..e0d5ac4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_menu_share_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_search.png b/core/res/res/drawable-mdpi/ic_search.png
index 4be72f1..66145e0 100644
--- a/core/res/res/drawable-mdpi/ic_search.png
+++ b/core/res/res/drawable-mdpi/ic_search.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-mdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..4771a56
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_search_api_holo_light.png b/core/res/res/drawable-mdpi/ic_search_api_holo_light.png
index f2e26f8..60a55f8 100644
--- a/core/res/res/drawable-mdpi/ic_search_api_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_voice_search.png b/core/res/res/drawable-mdpi/ic_voice_search.png
index 73c6be6..b2535fb 100644
--- a/core/res/res/drawable-mdpi/ic_voice_search.png
+++ b/core/res/res/drawable-mdpi/ic_voice_search.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..fcc2105
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png
index 71d838e..b516b95 100644
--- a/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png
+++ b/core/res/res/drawable-mdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-mdpi/list_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..77845df
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-mdpi/list_section_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..11ae4f4
--- /dev/null
+++ b/core/res/res/drawable-mdpi/list_section_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/core/res/res/drawable-mdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index c286875..0000000
--- a/core/res/res/drawable-mdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-mdpi/progress_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..07cbed8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/progress_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-mdpi/progress_qntm_alpha.9.png
new file mode 100644
index 0000000..8991421
--- /dev/null
+++ b/core/res/res/drawable-mdpi/progress_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png
index 766e4c0..6d83bb4 100644
--- a/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-mdpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-mdpi/scrollbar_handle_qntm_alpha.9.png
new file mode 100644
index 0000000..1834b2e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrollbar_handle_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..1f4b46a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_control_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_off_qntm_alpha.png
new file mode 100644
index 0000000..1833704
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_control_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..3c304bf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_control_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-mdpi/scrubber_control_on_qntm_alpha.png
new file mode 100644
index 0000000..e64d3f2
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_control_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-mdpi/scrubber_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..a4ab0a1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/scrubber_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-mdpi/spinner_qntm_am_alpha.9.png
new file mode 100644
index 0000000..5e245bc
--- /dev/null
+++ b/core/res/res/drawable-mdpi/spinner_qntm_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-mdpi/switch_off_qntm_alpha.9.png
new file mode 100644
index 0000000..ffd6c39
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_off_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-mdpi/switch_on_qntm_alpha.9.png
new file mode 100644
index 0000000..15faff0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_on_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png
new file mode 100644
index 0000000..8991421
--- /dev/null
+++ b/core/res/res/drawable-mdpi/switch_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png
new file mode 100644
index 0000000..fd668ee
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png
new file mode 100644
index 0000000..ace579f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-mdpi/text_cursor_qntm_alpha.9.png
new file mode 100644
index 0000000..e5760be
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_cursor_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-mdpi/textfield_activated_qntm_alpha.9.png
new file mode 100644
index 0000000..7a72295
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_activated_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-mdpi/textfield_default_qntm_alpha.9.png
new file mode 100644
index 0000000..483931f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_default_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_solid_shadow_qntm.9.png b/core/res/res/drawable-xhdpi/ab_solid_shadow_qntm.9.png
new file mode 100644
index 0000000..1443b7f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_solid_shadow_qntm.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/ab_transparent_qntm_alpha.9.png
new file mode 100644
index 0000000..c37ba9e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ab_transparent_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_off_qntm_alpha.png
new file mode 100644
index 0000000..5d820ae
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_check_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_check_on_qntm_alpha.png
new file mode 100644
index 0000000..019c92e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_check_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/btn_qntm_alpha.9.png
new file mode 100644
index 0000000..30d732a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..2fd964e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_radio_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_off_qntm_alpha.png
new file mode 100644
index 0000000..8873cd6
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_radio_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..a7ed0f8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_radio_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_radio_on_qntm_alpha.png
new file mode 100644
index 0000000..be4aaf3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_radio_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-xhdpi/btn_star_qntm_alpha.png
new file mode 100644
index 0000000..a85bc06
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/btn_star_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/expander_close_qntm_alpha.9.png
new file mode 100644
index 0000000..43dccf3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/expander_close_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/expander_open_qntm_alpha.9.png
new file mode 100644
index 0000000..181be1a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/expander_open_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-xhdpi/fastscroll_thumb_qntm_alpha.png
new file mode 100644
index 0000000..9534f78
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_thumb_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/fastscroll_track_qntm_alpha.9.png
new file mode 100644
index 0000000..02f0174
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/fastscroll_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-xhdpi/ic_ab_back_qntm_am_alpha.png
new file mode 100644
index 0000000..4385b2b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_ab_back_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_cab_done_qntm_alpha.png
new file mode 100644
index 0000000..3d6d734
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_cab_done_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_dialog_alert_qntm_alpha.png
new file mode 100644
index 0000000..2229bf3
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_dialog_alert_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_find_next_qntm_alpha.png
new file mode 100644
index 0000000..9038282
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_find_next_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_find_previous_qntm_alpha.png
new file mode 100644
index 0000000..579347f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_find_previous_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_copy_qntm_am_alpha.png
new file mode 100644
index 0000000..b690d7c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_copy_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_cut_qntm_alpha.png
new file mode 100644
index 0000000..10c2067
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_cut_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_find_qntm_alpha.png
new file mode 100644
index 0000000..dd5460f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_find_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_qntm_alpha.png
new file mode 100644
index 0000000..f91b718
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_moreoverflow_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_paste_qntm_am_alpha.png
new file mode 100644
index 0000000..4024627
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_paste_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_search_qntm_alpha.png
new file mode 100644
index 0000000..4602b35
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_search_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_selectall_qntm_alpha.png
new file mode 100644
index 0000000..f7c0261
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_selectall_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-xhdpi/ic_menu_share_qntm_alpha.png
new file mode 100644
index 0000000..7accf52
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_menu_share_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search.png b/core/res/res/drawable-xhdpi/ic_search.png
index 998f91b..738a392 100644
--- a/core/res/res/drawable-xhdpi/ic_search.png
+++ b/core/res/res/drawable-xhdpi/ic_search.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-xhdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..b0d7acf
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png b/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png
index a4cdf1c..c9626a0 100644
--- a/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_search_category_default.png b/core/res/res/drawable-xhdpi/ic_search_category_default.png
index 7d5170e..351cfe0 100644
--- a/core/res/res/drawable-xhdpi/ic_search_category_default.png
+++ b/core/res/res/drawable-xhdpi/ic_search_category_default.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_voice_search.png b/core/res/res/drawable-xhdpi/ic_voice_search.png
index c625a36..3f0518b 100644
--- a/core/res/res/drawable-xhdpi/ic_voice_search.png
+++ b/core/res/res/drawable-xhdpi/ic_voice_search.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..eb6e5fa
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png
index c332ba0..c6b40bb 100644
--- a/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png
+++ b/core/res/res/drawable-xhdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/list_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..77845df
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/list_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/list_section_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..e053b39
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/list_section_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/notify_panel_notification_icon_bg.png b/core/res/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
deleted file mode 100644
index 9128e62..0000000
--- a/core/res/res/drawable-xhdpi/notify_panel_notification_icon_bg.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/progress_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..5c7e5cd
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/progress_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/progress_qntm_alpha.9.png
new file mode 100644
index 0000000..4970f56
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/progress_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png
index 3cf84a5..70856c0 100644
--- a/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png
+++ b/core/res/res/drawable-xhdpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/scrollbar_handle_qntm_alpha.9.png
new file mode 100644
index 0000000..3c816c7
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrollbar_handle_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..754b321
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_control_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_off_qntm_alpha.png
new file mode 100644
index 0000000..ad72f06
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_control_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..a7ed0f8
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_control_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-xhdpi/scrubber_control_on_qntm_alpha.png
new file mode 100644
index 0000000..7aceed1
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_control_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/scrubber_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..2b4734d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/scrubber_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-xhdpi/spinner_qntm_am_alpha.9.png
new file mode 100644
index 0000000..79a260b
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/spinner_qntm_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/switch_off_qntm_alpha.9.png
new file mode 100644
index 0000000..309b528
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/switch_off_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/switch_on_qntm_alpha.9.png
new file mode 100644
index 0000000..139795e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/switch_on_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png
new file mode 100644
index 0000000..4970f56
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/switch_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png
new file mode 100644
index 0000000..a677f9a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png
new file mode 100644
index 0000000..7de791d
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/text_cursor_qntm_alpha.9.png
new file mode 100644
index 0000000..3939214
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/text_cursor_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_activated_qntm_alpha.9.png
new file mode 100644
index 0000000..16c376a
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_activated_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/textfield_default_qntm_alpha.9.png
new file mode 100644
index 0000000..e3bd904
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/textfield_default_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm.9.png b/core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm.9.png
new file mode 100644
index 0000000..e89c9fe
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_solid_shadow_qntm.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png
new file mode 100644
index 0000000..f220168
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ab_transparent_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png
new file mode 100644
index 0000000..2a17861
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png
new file mode 100644
index 0000000..61067ac
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_check_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png
new file mode 100644
index 0000000..7d29d18
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..fdbbbce
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png
new file mode 100644
index 0000000..0ec2ee6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..b46ee1c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png
new file mode 100644
index 0000000..8737156
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_radio_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png b/core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png
new file mode 100644
index 0000000..7488ff9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/btn_star_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png
new file mode 100644
index 0000000..e78fff6
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_close_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png
new file mode 100644
index 0000000..a3d09657
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/expander_open_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png b/core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png
new file mode 100644
index 0000000..55a73e7
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_thumb_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png
new file mode 100644
index 0000000..be64a94
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/fastscroll_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png
new file mode 100644
index 0000000..ca15853
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_ab_back_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png
new file mode 100644
index 0000000..1f9c734
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_cab_done_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png
new file mode 100644
index 0000000..10e0756
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_dialog_alert_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png
new file mode 100644
index 0000000..e3a7e9e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_find_next_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png
new file mode 100644
index 0000000..f9cf16c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_find_previous_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png
new file mode 100644
index 0000000..7c3a58b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_copy_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png
new file mode 100644
index 0000000..2200642
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_cut_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png
new file mode 100644
index 0000000..d35b337
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_find_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png
new file mode 100644
index 0000000..ff1759b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_moreoverflow_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png
new file mode 100644
index 0000000..28c0ae0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_paste_qntm_am_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png
new file mode 100644
index 0000000..cb295a3
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_search_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png
new file mode 100644
index 0000000..6430d45
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_selectall_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png b/core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png
new file mode 100644
index 0000000..66f7d16
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_menu_share_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_search_api_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_search_api_holo_dark.png
new file mode 100644
index 0000000..eb30465
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_search_api_holo_light.png b/core/res/res/drawable-xxhdpi/ic_search_api_holo_light.png
new file mode 100644
index 0000000..bc14415
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_dark.png b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_dark.png
new file mode 100644
index 0000000..813048c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_dark.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_light.png b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_light.png
new file mode 100644
index 0000000..8addde0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/ic_voice_search_api_holo_light.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..0fafd1a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png
new file mode 100644
index 0000000..491fab9
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/list_section_divider_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..2d4eb3f
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png
new file mode 100644
index 0000000..74a259b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/progress_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png
new file mode 100644
index 0000000..c1c0622
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrollbar_handle_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png
new file mode 100644
index 0000000..0319bd8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_off_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png
new file mode 100644
index 0000000..c11b0ae
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_off_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png
new file mode 100644
index 0000000..b46ee1c
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_on_pressed_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png b/core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png
new file mode 100644
index 0000000..cde797e
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_control_on_qntm_alpha.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png
new file mode 100644
index 0000000..6a82af5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/scrubber_primary_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png b/core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png
new file mode 100644
index 0000000..b8c78b5
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/spinner_qntm_am_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png
new file mode 100644
index 0000000..9e234af
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_off_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png
new file mode 100644
index 0000000..b371eab
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_on_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png
new file mode 100644
index 0000000..74a259b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/switch_track_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
new file mode 100644
index 0000000..0a14025
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
new file mode 100644
index 0000000..20e291a
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png
new file mode 100644
index 0000000..432c385
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/text_cursor_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png
new file mode 100644
index 0000000..a22f352
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_activated_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png
new file mode 100644
index 0000000..b0504e0
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/textfield_default_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable/ab_transparent_quantum_dark.xml b/core/res/res/drawable/ab_transparent_quantum_dark.xml
new file mode 100644
index 0000000..9ac2fc0
--- /dev/null
+++ b/core/res/res/drawable/ab_transparent_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ab_transparent_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ab_transparent_quantum_light.xml b/core/res/res/drawable/ab_transparent_quantum_light.xml
new file mode 100644
index 0000000..bc49848
--- /dev/null
+++ b/core/res/res/drawable/ab_transparent_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ab_transparent_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/activated_background_quantum_dark.xml b/core/res/res/drawable/activated_background_quantum_dark.xml
new file mode 100644
index 0000000..a9e3fea
--- /dev/null
+++ b/core/res/res/drawable/activated_background_quantum_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_activated="true" android:drawable="@color/control_activated_foreground_quantum_dark" />
+    <item android:drawable="@color/transparent" />
+</selector>
diff --git a/core/res/res/drawable/activated_background_quantum_light.xml b/core/res/res/drawable/activated_background_quantum_light.xml
new file mode 100644
index 0000000..5d10ea2
--- /dev/null
+++ b/core/res/res/drawable/activated_background_quantum_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_activated="true" android:drawable="@color/control_activated_foreground_quantum_light" />
+    <item android:drawable="@color/transparent" />
+</selector>
diff --git a/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml b/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
new file mode 100644
index 0000000..ab66501
--- /dev/null
+++ b/core/res/res/drawable/background_cache_hint_selector_quantum_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_accelerated="false" android:color="@android:color/background_quantum_dark" />
+    <item android:color="@android:color/transparent" />
+</selector>
diff --git a/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml b/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
new file mode 100644
index 0000000..fb940a9
--- /dev/null
+++ b/core/res/res/drawable/background_cache_hint_selector_quantum_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_accelerated="false" android:color="@android:color/background_quantum_light" />
+    <item android:color="@android:color/transparent" />
+</selector>
diff --git a/core/res/res/drawable/btn_borderless_quantum_dark.xml b/core/res/res/drawable/btn_borderless_quantum_dark.xml
new file mode 100644
index 0000000..2c0d3b7
--- /dev/null
+++ b/core/res/res/drawable/btn_borderless_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/btn_default_pressed_quantum_dark"
+    android:mask="@drawable/btn_qntm_alpha" />
diff --git a/core/res/res/drawable/btn_borderless_quantum_light.xml b/core/res/res/drawable/btn_borderless_quantum_light.xml
new file mode 100644
index 0000000..2faec20
--- /dev/null
+++ b/core/res/res/drawable/btn_borderless_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/btn_default_pressed_quantum_light"
+    android:mask="@drawable/btn_qntm_alpha" />
diff --git a/core/res/res/drawable/btn_check_quantum_dark.xml b/core/res/res/drawable/btn_check_quantum_dark.xml
new file mode 100644
index 0000000..a35bec4
--- /dev/null
+++ b/core/res/res/drawable/btn_check_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_check_quantum_light.xml b/core/res/res/drawable/btn_check_quantum_light.xml
new file mode 100644
index 0000000..8588fce
--- /dev/null
+++ b/core/res/res/drawable/btn_check_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_check_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_check_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_color_quantum_dark.xml b/core/res/res/drawable/btn_color_quantum_dark.xml
new file mode 100644
index 0000000..0507755
--- /dev/null
+++ b/core/res/res/drawable/btn_color_quantum_dark.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/theme_color_300">
+    <selector>
+        <item android:state_enabled="false">
+            <nine-patch android:src="@drawable/btn_qntm_alpha"
+                android:tint="@color/btn_default_normal_quantum_dark" />
+        </item>
+        <item>
+            <nine-patch android:src="@drawable/btn_qntm_alpha"
+                android:tint="@color/theme_color_500" />
+        </item>
+    </selector>
+</touch-feedback>
diff --git a/core/res/res/drawable/btn_color_quantum_light.xml b/core/res/res/drawable/btn_color_quantum_light.xml
new file mode 100644
index 0000000..9166b8d
--- /dev/null
+++ b/core/res/res/drawable/btn_color_quantum_light.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/theme_color_700">
+    <selector>
+        <item android:state_enabled="false">
+            <nine-patch android:src="@drawable/btn_qntm_alpha"
+                android:tint="@color/btn_default_normal_quantum_dark" />
+        </item>
+        <item>
+            <nine-patch android:src="@drawable/btn_qntm_alpha"
+                android:tint="@color/theme_color_500" />
+        </item>
+    </selector>
+</touch-feedback>
diff --git a/core/res/res/drawable/btn_default_quantum_dark.xml b/core/res/res/drawable/btn_default_quantum_dark.xml
new file mode 100644
index 0000000..29c3e24
--- /dev/null
+++ b/core/res/res/drawable/btn_default_quantum_dark.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/btn_default_pressed_quantum_dark">
+    <nine-patch android:src="@drawable/btn_qntm_alpha"
+        android:tint="@color/btn_default_normal_quantum_dark" />
+</touch-feedback>
diff --git a/core/res/res/drawable/btn_default_quantum_light.xml b/core/res/res/drawable/btn_default_quantum_light.xml
new file mode 100644
index 0000000..c6e828c
--- /dev/null
+++ b/core/res/res/drawable/btn_default_quantum_light.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/btn_default_pressed_quantum_light">
+    <nine-patch android:src="@drawable/btn_qntm_alpha"
+        android:tint="@color/btn_default_normal_quantum_light" />
+</touch-feedback>
diff --git a/core/res/res/drawable/btn_radio_quantum_dark.xml b/core/res/res/drawable/btn_radio_quantum_dark.xml
new file mode 100644
index 0000000..54f4f9a
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_radio_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_off_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_radio_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_radio_quantum_light.xml b/core/res/res/drawable/btn_radio_quantum_light.xml
new file mode 100644
index 0000000..c1ace70
--- /dev/null
+++ b/core/res/res/drawable/btn_radio_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_radio_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_radio_off_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_radio_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_star_quantum_dark.xml b/core/res/res/drawable/btn_star_quantum_dark.xml
new file mode 100644
index 0000000..7b26a3c
--- /dev/null
+++ b/core/res/res/drawable/btn_star_quantum_dark.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/btn_star_quantum_light.xml b/core/res/res/drawable/btn_star_quantum_light.xml
new file mode 100644
index 0000000..df2cc91
--- /dev/null
+++ b/core/res/res/drawable/btn_star_quantum_light.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/btn_star_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/edit_text_quantum_dark.xml b/core/res/res/drawable/edit_text_quantum_dark.xml
new file mode 100644
index 0000000..ea3fc52
--- /dev/null
+++ b/core/res/res/drawable/edit_text_quantum_dark.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_window_focused="false" android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item android:state_window_focused="false" android:state_enabled="false">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true" android:state_activated="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/edit_text_quantum_light.xml b/core/res/res/drawable/edit_text_quantum_light.xml
new file mode 100644
index 0000000..dd7fe53
--- /dev/null
+++ b/core/res/res/drawable/edit_text_quantum_light.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_window_focused="false" android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item android:state_window_focused="false" android:state_enabled="false">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true" android:state_activated="true">
+        <nine-patch android:src="@drawable/textfield_activated_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_enabled="true">
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/textfield_default_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/expander_group_quantum_dark.xml b/core/res/res/drawable/expander_group_quantum_dark.xml
new file mode 100644
index 0000000..7250e01
--- /dev/null
+++ b/core/res/res/drawable/expander_group_quantum_dark.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_expanded="true">
+        <nine-patch android:src="@drawable/expander_close_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/expander_open_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/expander_group_quantum_light.xml b/core/res/res/drawable/expander_group_quantum_light.xml
new file mode 100644
index 0000000..62af983
--- /dev/null
+++ b/core/res/res/drawable/expander_group_quantum_light.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_expanded="true">
+        <nine-patch android:src="@drawable/expander_close_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/expander_open_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/fastscroll_thumb_quantum_dark.xml b/core/res/res/drawable/fastscroll_thumb_quantum_dark.xml
new file mode 100644
index 0000000..53c7fdd
--- /dev/null
+++ b/core/res/res/drawable/fastscroll_thumb_quantum_dark.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/fastscroll_thumb_quantum_light.xml b/core/res/res/drawable/fastscroll_thumb_quantum_light.xml
new file mode 100644
index 0000000..3bc87e9
--- /dev/null
+++ b/core/res/res/drawable/fastscroll_thumb_quantum_light.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/fastscroll_thumb_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/fastscroll_track_quantum_dark.xml b/core/res/res/drawable/fastscroll_track_quantum_dark.xml
new file mode 100644
index 0000000..0ae57d2
--- /dev/null
+++ b/core/res/res/drawable/fastscroll_track_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/fastscroll_track_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/fastscroll_track_quantum_light.xml b/core/res/res/drawable/fastscroll_track_quantum_light.xml
new file mode 100644
index 0000000..627c079
--- /dev/null
+++ b/core/res/res/drawable/fastscroll_track_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/fastscroll_track_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_ab_back_quantum_dark.xml b/core/res/res/drawable/ic_ab_back_quantum_dark.xml
new file mode 100644
index 0000000..628d53e
--- /dev/null
+++ b/core/res/res/drawable/ic_ab_back_quantum_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_ab_back_qntm_am_alpha"
+    android:autoMirrored="true"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_ab_back_quantum_light.xml b/core/res/res/drawable/ic_ab_back_quantum_light.xml
new file mode 100644
index 0000000..01f5362
--- /dev/null
+++ b/core/res/res/drawable/ic_ab_back_quantum_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_ab_back_qntm_am_alpha"
+    android:autoMirrored="true"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_cab_done_quantum_dark.xml b/core/res/res/drawable/ic_cab_done_quantum_dark.xml
new file mode 100644
index 0000000..472996e
--- /dev/null
+++ b/core/res/res/drawable/ic_cab_done_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_cab_done_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_cab_done_quantum_light.xml b/core/res/res/drawable/ic_cab_done_quantum_light.xml
new file mode 100644
index 0000000..d70a3f1
--- /dev/null
+++ b/core/res/res/drawable/ic_cab_done_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_cab_done_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml b/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml
new file mode 100644
index 0000000..8b8cb0c
--- /dev/null
+++ b/core/res/res/drawable/ic_dialog_alert_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_dialog_alert_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_dialog_alert_quantum_light.xml b/core/res/res/drawable/ic_dialog_alert_quantum_light.xml
new file mode 100644
index 0000000..8b8cb0c
--- /dev/null
+++ b/core/res/res/drawable/ic_dialog_alert_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_dialog_alert_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_find_next_quantum_dark.xml b/core/res/res/drawable/ic_find_next_quantum_dark.xml
new file mode 100644
index 0000000..929bea3
--- /dev/null
+++ b/core/res/res/drawable/ic_find_next_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_find_next_quantum_light.xml b/core/res/res/drawable/ic_find_next_quantum_light.xml
new file mode 100644
index 0000000..9c20327
--- /dev/null
+++ b/core/res/res/drawable/ic_find_next_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_next_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_find_previous_quantum_dark.xml b/core/res/res/drawable/ic_find_previous_quantum_dark.xml
new file mode 100644
index 0000000..e944223
--- /dev/null
+++ b/core/res/res/drawable/ic_find_previous_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_previous_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_find_previous_quantum_light.xml b/core/res/res/drawable/ic_find_previous_quantum_light.xml
new file mode 100644
index 0000000..b037094
--- /dev/null
+++ b/core/res/res/drawable/ic_find_previous_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_find_previous_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_copy_quantum_dark.xml b/core/res/res/drawable/ic_menu_copy_quantum_dark.xml
new file mode 100644
index 0000000..285b752
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_copy_quantum_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_copy_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark"
+    android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_copy_quantum_light.xml b/core/res/res/drawable/ic_menu_copy_quantum_light.xml
new file mode 100644
index 0000000..a40b219
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_copy_quantum_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_copy_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light"
+    android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_cut_quantum_dark.xml b/core/res/res/drawable/ic_menu_cut_quantum_dark.xml
new file mode 100644
index 0000000..563400b
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_cut_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_cut_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_menu_cut_quantum_light.xml b/core/res/res/drawable/ic_menu_cut_quantum_light.xml
new file mode 100644
index 0000000..36c9442
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_cut_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_cut_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_find_quantum_dark.xml b/core/res/res/drawable/ic_menu_find_quantum_dark.xml
new file mode 100644
index 0000000..8803463
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_find_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_find_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_menu_find_quantum_light.xml b/core/res/res/drawable/ic_menu_find_quantum_light.xml
new file mode 100644
index 0000000..9b3bd73
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_find_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_find_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml b/core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml
new file mode 100644
index 0000000..9f39a68
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_moreoverflow_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_moreoverflow_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml b/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml
new file mode 100644
index 0000000..e15eaec
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_moreoverflow_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_moreoverflow_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_paste_quantum_dark.xml b/core/res/res/drawable/ic_menu_paste_quantum_dark.xml
new file mode 100644
index 0000000..7033404
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_paste_quantum_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_paste_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark"
+    android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_paste_quantum_light.xml b/core/res/res/drawable/ic_menu_paste_quantum_light.xml
new file mode 100644
index 0000000..155ec34
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_paste_quantum_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_paste_qntm_am_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light"
+    android:autoMirrored="true" />
diff --git a/core/res/res/drawable/ic_menu_search_quantum_dark.xml b/core/res/res/drawable/ic_menu_search_quantum_dark.xml
new file mode 100644
index 0000000..1c6efcd
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_search_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_search_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_menu_search_quantum_light.xml b/core/res/res/drawable/ic_menu_search_quantum_light.xml
new file mode 100644
index 0000000..ba6efb6
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_search_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_search_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_selectall_quantum_dark.xml b/core/res/res/drawable/ic_menu_selectall_quantum_dark.xml
new file mode 100644
index 0000000..c1d3e69
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_selectall_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_selectall_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_menu_selectall_quantum_light.xml b/core/res/res/drawable/ic_menu_selectall_quantum_light.xml
new file mode 100644
index 0000000..4de8962
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_selectall_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_selectall_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/ic_menu_share_quantum_dark.xml b/core/res/res/drawable/ic_menu_share_quantum_dark.xml
new file mode 100644
index 0000000..a7c5afc
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_share_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_share_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/ic_menu_share_quantum_light.xml b/core/res/res/drawable/ic_menu_share_quantum_light.xml
new file mode 100644
index 0000000..9257c25
--- /dev/null
+++ b/core/res/res/drawable/ic_menu_share_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_menu_share_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/item_background_borderless_quantum_dark.xml b/core/res/res/drawable/item_background_borderless_quantum_dark.xml
new file mode 100644
index 0000000..3f32850
--- /dev/null
+++ b/core/res/res/drawable/item_background_borderless_quantum_dark.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/lighter_gray" />
diff --git a/core/res/res/drawable/item_background_borderless_quantum_light.xml b/core/res/res/drawable/item_background_borderless_quantum_light.xml
new file mode 100644
index 0000000..09f6ae9
--- /dev/null
+++ b/core/res/res/drawable/item_background_borderless_quantum_light.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/darker_gray" />
diff --git a/core/res/res/drawable/item_background_quantum_dark.xml b/core/res/res/drawable/item_background_quantum_dark.xml
new file mode 100644
index 0000000..3f32850
--- /dev/null
+++ b/core/res/res/drawable/item_background_quantum_dark.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/lighter_gray" />
diff --git a/core/res/res/drawable/item_background_quantum_light.xml b/core/res/res/drawable/item_background_quantum_light.xml
new file mode 100644
index 0000000..09f6ae9
--- /dev/null
+++ b/core/res/res/drawable/item_background_quantum_light.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<touch-feedback xmlns:android="http://schemas.android.com/apk/res/android"
+    android:tint="@color/darker_gray" />
diff --git a/core/res/res/drawable/list_divider_quantum_dark.xml b/core/res/res/drawable/list_divider_quantum_dark.xml
new file mode 100644
index 0000000..9d05b2f
--- /dev/null
+++ b/core/res/res/drawable/list_divider_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/list_divider_quantum_light.xml b/core/res/res/drawable/list_divider_quantum_light.xml
new file mode 100644
index 0000000..d312e2d
--- /dev/null
+++ b/core/res/res/drawable/list_divider_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/list_section_divider_quantum_dark.xml b/core/res/res/drawable/list_section_divider_quantum_dark.xml
new file mode 100644
index 0000000..6344c7e
--- /dev/null
+++ b/core/res/res/drawable/list_section_divider_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_section_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/list_section_divider_quantum_light.xml b/core/res/res/drawable/list_section_divider_quantum_light.xml
new file mode 100644
index 0000000..98ede38
--- /dev/null
+++ b/core/res/res/drawable/list_section_divider_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/list_section_divider_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/notification_quantum_background.xml b/core/res/res/drawable/notification_quantum_background.xml
new file mode 100644
index 0000000..f33e2e3
--- /dev/null
+++ b/core/res/res/drawable/notification_quantum_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#ffffffff" />
+    <corners android:radius="2dp" />
+</shape>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_quantum_bg.xml b/core/res/res/drawable/notification_quantum_bg.xml
new file mode 100644
index 0000000..608115e
--- /dev/null
+++ b/core/res/res/drawable/notification_quantum_bg.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true"  android:drawable="@drawable/notification_quantum_press" />
+    <item android:state_pressed="false" android:drawable="@drawable/notification_quantum_background" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable/notification_quantum_press.xml b/core/res/res/drawable/notification_quantum_press.xml
new file mode 100644
index 0000000..4999f55
--- /dev/null
+++ b/core/res/res/drawable/notification_quantum_press.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#ffcccccc" />
+    <corners android:radius="2dp" />
+</shape>
\ No newline at end of file
diff --git a/core/res/res/drawable/notify_panel_notification_icon_bg_tile.xml b/core/res/res/drawable/notify_panel_notification_icon_bg_tile.xml
deleted file mode 100644
index fa3c398..0000000
--- a/core/res/res/drawable/notify_panel_notification_icon_bg_tile.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="@android:drawable/notify_panel_notification_icon_bg"
-    />
diff --git a/core/res/res/drawable/progress_horizontal_quantum_dark.xml b/core/res/res/drawable/progress_horizontal_quantum_dark.xml
new file mode 100644
index 0000000..fb4b67e
--- /dev/null
+++ b/core/res/res/drawable/progress_horizontal_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@id/background">
+        <nine-patch android:src="@drawable/progress_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+    <item android:id="@id/secondaryProgress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_dark" />
+        </scale>
+    </item>
+    <item android:id="@id/progress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_primary_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_dark" />
+        </scale>
+    </item>
+</layer-list>
diff --git a/core/res/res/drawable/progress_horizontal_quantum_light.xml b/core/res/res/drawable/progress_horizontal_quantum_light.xml
new file mode 100644
index 0000000..1ceb2e2
--- /dev/null
+++ b/core/res/res/drawable/progress_horizontal_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@id/background">
+        <nine-patch android:src="@drawable/progress_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+    <item android:id="@id/secondaryProgress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_light" />
+        </scale>
+    </item>
+    <item android:id="@id/progress">
+        <scale android:scaleWidth="100%">
+            <nine-patch android:src="@drawable/progress_primary_qntm_alpha"
+                android:tint="@color/control_activated_foreground_quantum_light" />
+        </scale>
+    </item>
+</layer-list>
diff --git a/core/res/res/drawable/scrollbar_handle_quantum_dark.xml b/core/res/res/drawable/scrollbar_handle_quantum_dark.xml
new file mode 100644
index 0000000..2d4e37d
--- /dev/null
+++ b/core/res/res/drawable/scrollbar_handle_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/scrollbar_handle_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/scrollbar_handle_quantum_light.xml b/core/res/res/drawable/scrollbar_handle_quantum_light.xml
new file mode 100644
index 0000000..d4d4b8d
--- /dev/null
+++ b/core/res/res/drawable/scrollbar_handle_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/scrollbar_handle_qntm_alpha"
+    android:tint="@color/control_normal_foreground_quantum_light" />
diff --git a/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml b/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml
new file mode 100644
index 0000000..521bcca
--- /dev/null
+++ b/core/res/res/drawable/scrubber_control_selector_quantum_dark.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_control_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_control_on_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/scrubber_control_selector_quantum_light.xml b/core/res/res/drawable/scrubber_control_selector_quantum_light.xml
new file mode 100644
index 0000000..8d009b7
--- /dev/null
+++ b/core/res/res/drawable/scrubber_control_selector_quantum_light.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true" android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_control_on_pressed_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_control_on_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml b/core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml
new file mode 100644
index 0000000..fa0d631
--- /dev/null
+++ b/core/res/res/drawable/scrubber_progress_horizontal_quantum_dark.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml b/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml
new file mode 100644
index 0000000..053f542
--- /dev/null
+++ b/core/res/res/drawable/scrubber_progress_horizontal_quantum_light.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true">
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <bitmap android:src="@drawable/scrubber_primary_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/spinner_background_quantum_dark.xml b/core/res/res/drawable/spinner_background_quantum_dark.xml
new file mode 100644
index 0000000..d1e7407
--- /dev/null
+++ b/core/res/res/drawable/spinner_background_quantum_dark.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:autoMirrored="true">
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/spinner_background_quantum_light.xml b/core/res/res/drawable/spinner_background_quantum_light.xml
new file mode 100644
index 0000000..b01628d
--- /dev/null
+++ b/core/res/res/drawable/spinner_background_quantum_light.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:autoMirrored="true">
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/spinner_qntm_am_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/switch_inner_quantum_dark.xml b/core/res/res/drawable/switch_inner_quantum_dark.xml
new file mode 100644
index 0000000..927a55e
--- /dev/null
+++ b/core/res/res/drawable/switch_inner_quantum_dark.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/switch_inner_quantum_light.xml b/core/res/res/drawable/switch_inner_quantum_light.xml
new file mode 100644
index 0000000..b5aa47b
--- /dev/null
+++ b/core/res/res/drawable/switch_inner_quantum_light.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_on_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_off_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/switch_track_quantum_dark.xml b/core/res/res/drawable/switch_track_quantum_dark.xml
new file mode 100644
index 0000000..c018bd2
--- /dev/null
+++ b/core/res/res/drawable/switch_track_quantum_dark.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/switch_track_quantum_light.xml b/core/res/res/drawable/switch_track_quantum_light.xml
new file mode 100644
index 0000000..ab87a57
--- /dev/null
+++ b/core/res/res/drawable/switch_track_quantum_light.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_checked="true">
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/switch_track_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/tab_indicator_quantum_dark.xml b/core/res/res/drawable/tab_indicator_quantum_dark.xml
new file mode 100644
index 0000000..9b57c33
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_quantum_dark.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_selected="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_selected="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_dark" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_dark" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/tab_indicator_quantum_light.xml b/core/res/res/drawable/tab_indicator_quantum_light.xml
new file mode 100644
index 0000000..371322a
--- /dev/null
+++ b/core/res/res/drawable/tab_indicator_quantum_light.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_selected="true" android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_selected="true" android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_selected="true">
+        <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+
+    <item android:state_pressed="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item android:state_focused="true">
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_activated_foreground_quantum_light" />
+    </item>
+    <item>
+        <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+            android:tint="@color/control_normal_foreground_quantum_light" />
+    </item>
+</selector>
diff --git a/core/res/res/drawable/text_cursor_quantum_dark.xml b/core/res/res/drawable/text_cursor_quantum_dark.xml
new file mode 100644
index 0000000..bd0d66f
--- /dev/null
+++ b/core/res/res/drawable/text_cursor_quantum_dark.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/text_cursor_qntm_alpha"
+    android:tint="@color/control_activated_foreground_quantum_dark" />
diff --git a/core/res/res/drawable/text_cursor_quantum_light.xml b/core/res/res/drawable/text_cursor_quantum_light.xml
new file mode 100644
index 0000000..0ec7f01
--- /dev/null
+++ b/core/res/res/drawable/text_cursor_quantum_light.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/text_cursor_qntm_alpha"
+    android:tint="@color/control_activated_foreground_quantum_light" />
diff --git a/core/res/res/layout-land/time_picker_holo.xml b/core/res/res/layout-land/time_picker_holo.xml
new file mode 100644
index 0000000..f5ce1ec
--- /dev/null
+++ b/core/res/res/layout-land/time_picker_holo.xml
@@ -0,0 +1,70 @@
+<?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="horizontal"
+        android:focusable="true"
+        android:layout_marginLeft="@dimen/timepicker_minimum_margin_sides"
+        android:layout_marginRight="@dimen/timepicker_minimum_margin_sides"
+        android:layout_marginTop="@dimen/timepicker_minimum_margin_top_bottom"
+        android:layout_marginBottom="@dimen/timepicker_minimum_margin_top_bottom">
+    <LinearLayout
+            android:layout_width="@dimen/timepicker_left_side_width"
+            android:layout_height="match_parent"
+            android:orientation="vertical">
+        <FrameLayout
+                android:layout_width="match_parent"
+                android:layout_height="0dip"
+                android:layout_weight="1"
+                android:background="?android:attr/timePickerHeaderBackgroundColor">
+            <include
+                    layout="@layout/time_header_label"
+                    android:layout_width="match_parent"
+                    android:layout_height="@dimen/timepicker_header_height"
+                    android:layout_gravity="center" />
+        </FrameLayout>
+        <LinearLayout
+                android:id="@+id/layout_buttons"
+                style="?android:attr/buttonBarStyle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:background="?android:attr/timePickerHeaderBackgroundColor"
+                android:divider="?android:attr/dividerHorizontal"
+                android:showDividers="beginning">
+            <Button
+                    android:id="@+id/done_button"
+                    style="?android:attr/buttonBarButtonStyle"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:minHeight="48dp"
+                    android:text="@string/done_label"
+                    android:textSize="@dimen/timepicker_done_label_size" />
+        </LinearLayout>
+    </LinearLayout>
+    <android.widget.RadialTimePickerView
+            android:id="@+id/radial_picker"
+            android:layout_width="@dimen/timepicker_radial_picker_dimen"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:focusable="true"
+            android:focusableInTouchMode="true" />
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout-xlarge/screen_action_bar.xml b/core/res/res/layout-xlarge/screen_action_bar.xml
index e495e53..d2fe9fa 100644
--- a/core/res/res/layout-xlarge/screen_action_bar.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar.xml
@@ -34,6 +34,7 @@
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         style="?android:attr/actionBarStyle"
+        android:sharedElementName="android:action_bar"
         android:gravity="top">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
diff --git a/core/res/res/layout/action_menu_layout.xml b/core/res/res/layout/action_menu_layout.xml
index c401fec..abf3300c 100644
--- a/core/res/res/layout/action_menu_layout.xml
+++ b/core/res/res/layout/action_menu_layout.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<com.android.internal.view.menu.ActionMenuView
+<ActionMenuView
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
diff --git a/core/res/res/layout/notification_quantum_action.xml b/core/res/res/layout/notification_quantum_action.xml
new file mode 100644
index 0000000..775182f
--- /dev/null
+++ b/core/res/res/layout/notification_quantum_action.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+    style="?android:attr/borderlessButtonStyle" 
+    android:id="@+id/action0"
+    android:layout_width="0dp"
+    android:layout_height="48dp"
+    android:layout_weight="1"
+    android:gravity="start|center_vertical"
+    android:drawablePadding="8dp"
+    android:paddingStart="8dp"
+    android:textColor="#555555"
+    android:textSize="14dp"
+    android:singleLine="true"
+    android:ellipsize="end"
+    />
diff --git a/core/res/res/layout/notification_quantum_action_list.xml b/core/res/res/layout/notification_quantum_action_list.xml
new file mode 100644
index 0000000..a8aef97
--- /dev/null
+++ b/core/res/res/layout/notification_quantum_action_list.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/actions"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:visibility="gone"
+    android:layout_marginBottom="8dp"
+    android:showDividers="middle"
+    android:divider="?android:attr/listDivider"
+    android:dividerPadding="12dp"
+    >
+    <!-- actions will be added here -->
+</LinearLayout>
diff --git a/core/res/res/layout/notification_quantum_action_tombstone.xml b/core/res/res/layout/notification_quantum_action_tombstone.xml
new file mode 100644
index 0000000..9104991
--- /dev/null
+++ b/core/res/res/layout/notification_quantum_action_tombstone.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+    style="?android:attr/borderlessButtonStyle" 
+    android:id="@+id/action0"
+    android:layout_width="0dp"
+    android:layout_height="48dp"
+    android:layout_weight="1"
+    android:gravity="start|center_vertical"
+    android:drawablePadding="8dp"
+    android:paddingStart="8dp"
+    android:textColor="#555555"
+    android:textSize="14dp"
+    android:singleLine="true"
+    android:ellipsize="end"
+    android:alpha="0.5"
+    android:enabled="false"
+    />
diff --git a/core/res/res/layout/notification_template_quantum_base.xml b/core/res/res/layout/notification_template_quantum_base.xml
new file mode 100644
index 0000000..3e97b2a
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_base.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+    android:background="@android:drawable/notification_quantum_bg"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="64dp"
+    internal:layout_minHeight="64dp"
+    internal:layout_maxHeight="64dp"
+    >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:scaleType="center"
+        />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+
+        android:layout_gravity="fill_vertical"
+        android:layout_marginStart="@dimen/notification_large_icon_width"
+        android:minHeight="@dimen/notification_large_icon_height"
+        android:orientation="vertical"
+        android:paddingEnd="8dp"
+        android:paddingTop="2dp"
+        android:paddingBottom="2dp"
+        android:gravity="top"
+        >
+        <LinearLayout
+            android:id="@+id/line1"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingTop="6dp"
+            android:layout_marginStart="8dp"
+            android:orientation="horizontal"
+            >
+            <TextView android:id="@+id/title"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:fadingEdge="horizontal"
+                android:layout_weight="1"
+                />
+            <ViewStub android:id="@+id/time"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:visibility="gone"
+                android:layout="@layout/notification_template_part_time"
+                />
+            <ViewStub android:id="@+id/chronometer"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:visibility="gone"
+                android:layout="@layout/notification_template_part_chronometer"
+                />
+        </LinearLayout>
+        <TextView android:id="@+id/text2"
+            android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="-2dp"
+            android:layout_marginBottom="-2dp"
+            android:layout_marginStart="8dp"
+            android:singleLine="true"
+            android:fadingEdge="horizontal"
+            android:ellipsize="marquee"
+            android:visibility="gone"
+            />
+        <ProgressBar
+            android:id="@android:id/progress"
+            android:layout_width="match_parent"
+            android:layout_height="12dp"
+            android:layout_marginStart="8dp"
+            android:visibility="gone"
+            style="?android:attr/progressBarStyleHorizontal"
+            />
+        <LinearLayout
+            android:id="@+id/line3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal"
+            android:gravity="center_vertical"
+            android:layout_marginStart="8dp"
+            >
+            <TextView android:id="@+id/text"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_gravity="center"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:fadingEdge="horizontal"
+                />
+            <TextView android:id="@+id/info"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:singleLine="true"
+                android:gravity="center"
+                android:paddingStart="8dp"
+                />
+            <ImageView android:id="@+id/right_icon"
+                android:layout_width="16dp"
+                android:layout_height="16dp"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:layout_marginStart="8dp"
+                android:scaleType="centerInside"
+                android:visibility="gone"
+                android:drawableAlpha="153"
+                />
+        </LinearLayout>
+    </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_big_base.xml b/core/res/res/layout/notification_template_quantum_big_base.xml
new file mode 100644
index 0000000..d860045
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_big_base.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+    android:background="@android:drawable/notification_quantum_bg"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    internal:layout_minHeight="65dp"
+    internal:layout_maxHeight="unbounded"
+    >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:scaleType="center"
+        />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="fill_vertical"
+        android:minHeight="@dimen/notification_large_icon_height"
+        android:orientation="vertical"
+        android:gravity="top"
+        >
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/notification_large_icon_width"
+            android:minHeight="@dimen/notification_large_icon_height"
+            android:paddingTop="2dp"
+            android:orientation="vertical"
+            >
+            <LinearLayout
+                android:id="@+id/line1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="6dp"
+                android:layout_marginEnd="8dp"
+                android:layout_marginStart="8dp"
+                android:orientation="horizontal"
+                >
+                <TextView android:id="@+id/title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    android:layout_weight="1"
+                    />
+                <ViewStub android:id="@+id/time"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_time"
+                    />
+                <ViewStub android:id="@+id/chronometer"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_chronometer"
+                    />
+            </LinearLayout>
+            <TextView android:id="@+id/text2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="-2dp"
+                android:layout_marginBottom="-2dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:fadingEdge="horizontal"
+                android:ellipsize="marquee"
+                android:visibility="gone"
+                />
+            <TextView android:id="@+id/big_text"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="false"
+                android:visibility="gone"
+                />
+            <LinearLayout
+                android:id="@+id/line3"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:orientation="horizontal"
+                android:gravity="center_vertical"
+                >
+                <TextView android:id="@+id/text"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                    android:layout_width="0dp"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:layout_gravity="center"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    />
+                <TextView android:id="@+id/info"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center"
+                    android:layout_weight="0"
+                    android:singleLine="true"
+                    android:gravity="center"
+                    android:paddingStart="8dp"
+                    />
+                <ImageView android:id="@+id/right_icon"
+                    android:layout_width="16dp"
+                    android:layout_height="16dp"
+                    android:layout_gravity="center"
+                    android:layout_weight="0"
+                    android:layout_marginStart="8dp"
+                    android:scaleType="centerInside"
+                    android:visibility="gone"
+                    android:drawableAlpha="153"
+                    />
+            </LinearLayout>
+            <ProgressBar
+                android:id="@android:id/progress"
+                android:layout_width="match_parent"
+                android:layout_height="12dp"
+                android:layout_marginBottom="8dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:visibility="gone"
+                style="?android:attr/progressBarStyleHorizontal"
+                />
+        </LinearLayout>
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:id="@+id/action_divider"
+            android:visibility="gone"
+            android:background="?android:attr/dividerHorizontal" />
+        <include
+            layout="@layout/notification_quantum_action_list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/notification_large_icon_width"
+            />
+    </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_big_picture.xml b/core/res/res/layout/notification_template_quantum_big_picture.xml
new file mode 100644
index 0000000..e49c3bd
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_big_picture.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+    android:background="@android:drawable/notification_quantum_bg"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    internal:layout_minHeight="65dp"
+    internal:layout_maxHeight="unbounded"
+    >
+    <ImageView
+        android:id="@+id/big_picture"
+        android:layout_width="match_parent"
+        android:layout_height="192dp"
+        android:layout_marginTop="64dp"
+        android:layout_gravity="bottom"
+        android:scaleType="centerCrop"
+        />
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="6dp"
+        android:layout_marginTop="64dp"
+        android:scaleType="fitXY"
+        android:src="@drawable/title_bar_shadow"
+        />
+    <include layout="@layout/notification_template_quantum_base"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        />
+  <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="208dp"
+        android:paddingStart="64dp"
+        android:layout_gravity="bottom"
+        android:background="#CCEEEEEE"
+        >
+        <include
+            layout="@layout/notification_quantum_action_list"
+            android:id="@+id/actions"
+            android:layout_gravity="bottom"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            />
+    </FrameLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_big_text.xml b/core/res/res/layout/notification_template_quantum_big_text.xml
new file mode 100644
index 0000000..585be80
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_big_text.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+    android:background="@android:drawable/notification_quantum_bg"
+    android:id="@+id/status_bar_latest_event_content"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    internal:layout_minHeight="65dp"
+    internal:layout_maxHeight="unbounded"
+    >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:scaleType="center"
+        />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="fill_vertical"
+        android:layout_marginStart="@dimen/notification_large_icon_width"
+        android:orientation="vertical"
+        android:paddingTop="0dp"
+        android:paddingBottom="2dp"
+        android:gravity="top"
+        >
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:minHeight="@dimen/notification_large_icon_height"
+            android:orientation="vertical"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_weight="1"
+            >
+            <LinearLayout
+                android:id="@+id/line1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="8dp"
+                android:orientation="horizontal"
+                android:layout_gravity="top"
+                android:layout_weight="0"
+                >
+                <TextView android:id="@+id/title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    android:layout_weight="1"
+                    />
+                <ViewStub android:id="@+id/time"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_time"
+                    />
+                <ViewStub android:id="@+id/chronometer"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_chronometer"
+                    />
+            </LinearLayout>
+            <TextView android:id="@+id/text2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="-2dp"
+                android:layout_marginBottom="-2dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:fadingEdge="horizontal"
+                android:ellipsize="marquee"
+                android:layout_weight="0"
+                android:visibility="gone"
+                />
+            <ProgressBar
+                android:id="@android:id/progress"
+                android:layout_width="match_parent"
+                android:layout_height="12dp"
+                android:layout_marginBottom="8dp"
+                android:layout_marginEnd="8dp"
+                android:visibility="gone"
+                android:layout_weight="0"
+                style="?android:attr/progressBarStyleHorizontal"
+                />
+            <TextView android:id="@+id/big_text"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginBottom="10dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="false"
+                android:visibility="gone"
+                android:maxLines="8"
+                android:ellipsize="end"
+                android:layout_weight="1"
+                />
+        </LinearLayout>
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:id="@+id/action_divider"
+            android:visibility="gone"
+            android:background="?android:attr/dividerHorizontal" />
+        <include
+            layout="@layout/notification_quantum_action_list"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:visibility="gone"
+            android:layout_weight="1"
+            />
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dp"
+            android:id="@+id/overflow_divider"
+            android:layout_marginBottom="8dp"
+            android:visibility="visible"
+            android:background="?android:attr/dividerHorizontal" />
+        <LinearLayout
+            android:id="@+id/line3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="8dp"
+            android:layout_marginBottom="8dp"
+            android:layout_marginEnd="8dp"
+            android:orientation="horizontal"
+            android:layout_weight="0"
+            android:gravity="center_vertical"
+            >
+            <TextView android:id="@+id/text"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_gravity="center"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:fadingEdge="horizontal"
+                />
+            <TextView android:id="@+id/info"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:singleLine="true"
+                android:gravity="center"
+                android:paddingStart="8dp"
+                />
+            <ImageView android:id="@+id/right_icon"
+                android:layout_width="16dp"
+                android:layout_height="16dp"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:layout_marginStart="8dp"
+                android:scaleType="centerInside"
+                android:visibility="gone"
+                android:drawableAlpha="153"
+                />
+        </LinearLayout>
+    </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/notification_template_quantum_inbox.xml b/core/res/res/layout/notification_template_quantum_inbox.xml
new file mode 100644
index 0000000..31ed508
--- /dev/null
+++ b/core/res/res/layout/notification_template_quantum_inbox.xml
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:internal="http://schemas.android.com/apk/prv/res/android"
+    android:id="@+id/status_bar_latest_event_content"
+    android:background="@android:drawable/notification_quantum_bg"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    internal:layout_minHeight="65dp"
+    internal:layout_maxHeight="unbounded"
+    >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:scaleType="center"
+        />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="fill_vertical"
+        android:layout_marginStart="@dimen/notification_large_icon_width"
+        android:minHeight="@dimen/notification_large_icon_height"
+        android:orientation="vertical"
+        android:paddingTop="0dp"
+        android:paddingBottom="2dp"
+        android:gravity="top"
+        >
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:minHeight="@dimen/notification_large_icon_height"
+            android:paddingTop="2dp"
+            android:orientation="vertical"
+            >
+            <LinearLayout
+                android:id="@+id/line1"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:paddingTop="6dp"
+                android:orientation="horizontal"
+                android:layout_weight="0"
+                >
+                <TextView android:id="@+id/title"
+                    android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Title"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:fadingEdge="horizontal"
+                    android:layout_weight="1"
+                    />
+                <ViewStub android:id="@+id/time"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_time"
+                    />
+                <ViewStub android:id="@+id/chronometer"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0"
+                    android:visibility="gone"
+                    android:layout="@layout/notification_template_part_chronometer"
+                    />
+            </LinearLayout>
+            <TextView android:id="@+id/text2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Line2"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="-2dp"
+                android:layout_marginBottom="-2dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:fadingEdge="horizontal"
+                android:ellipsize="marquee"
+                android:visibility="gone"
+                android:layout_weight="0"
+                />
+            <ProgressBar
+                android:id="@android:id/progress"
+                android:layout_width="match_parent"
+                android:layout_height="12dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:visibility="gone"
+                android:layout_weight="0"
+                style="?android:attr/progressBarStyleHorizontal"
+                />
+            <TextView android:id="@+id/inbox_text0"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                />
+            <TextView android:id="@+id/inbox_text1"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                />
+            <TextView android:id="@+id/inbox_text2"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                />
+            <TextView android:id="@+id/inbox_text3"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                />
+            <TextView android:id="@+id/inbox_text4"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                />
+            <TextView android:id="@+id/inbox_text5"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                />
+            <TextView android:id="@+id/inbox_text6"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                />
+            <TextView android:id="@+id/inbox_more"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="match_parent"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:visibility="gone"
+                android:layout_weight="1"
+                android:text="@android:string/ellipsis"
+                />
+            <FrameLayout
+                android:id="@+id/inbox_end_pad"
+                android:layout_width="match_parent"
+                android:layout_height="8dip"
+                android:visibility="gone"
+                android:layout_weight="0"
+            />
+        </LinearLayout>
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:id="@+id/action_divider"
+            android:visibility="gone"
+            android:background="?android:attr/dividerHorizontal" />
+        <include
+            layout="@layout/notification_quantum_action_list"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            />
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="1dip"
+            android:id="@+id/overflow_divider"
+            android:visibility="visible"
+            android:background="?android:attr/dividerHorizontal" />
+        <LinearLayout
+            android:id="@+id/line3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="8dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginBottom="8dp"
+            android:layout_marginEnd="8dp"
+            android:orientation="horizontal"
+            android:layout_weight="0"
+            android:gravity="center_vertical"
+            >
+            <TextView android:id="@+id/text"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:layout_gravity="center"
+                android:singleLine="true"
+                android:ellipsize="marquee"
+                android:fadingEdge="horizontal"
+                />
+            <TextView android:id="@+id/info"
+                android:textAppearance="@style/TextAppearance.StatusBar.Quantum.EventContent.Info"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:singleLine="true"
+                android:gravity="center"
+                android:paddingStart="8dp"
+                />
+            <ImageView android:id="@+id/right_icon"
+                android:layout_width="16dp"
+                android:layout_height="16dp"
+                android:layout_gravity="center"
+                android:layout_weight="0"
+                android:layout_marginStart="8dp"
+                android:scaleType="centerInside"
+                android:visibility="gone"
+                android:drawableAlpha="153"
+                />
+        </LinearLayout>
+    </LinearLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index b1889a2..3265736 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -23,7 +23,8 @@
     android:id="@+id/action_bar_overlay_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:splitMotionEvents="false">
+    android:splitMotionEvents="false"
+    android:theme="?attr/actionBarTheme">
     <FrameLayout android:id="@android:id/content"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
@@ -33,6 +34,7 @@
         android:layout_height="wrap_content"
         android:layout_alignParentTop="true"
         style="?android:attr/actionBarStyle"
+        android:sharedElementName="android:action_bar"
         android:gravity="top">
         <com.android.internal.widget.ActionBarView
             android:id="@+id/action_bar"
diff --git a/core/res/res/layout/screen_custom_title.xml b/core/res/res/layout/screen_custom_title.xml
index e3364d1..d02cc8b 100644
--- a/core/res/res/layout/screen_custom_title.xml
+++ b/core/res/res/layout/screen_custom_title.xml
@@ -31,6 +31,7 @@
     <FrameLayout android:id="@android:id/title_container" 
         android:layout_width="match_parent" 
         android:layout_height="?android:attr/windowTitleSize"
+        android:sharedElementName="android:title"
         style="?android:attr/windowTitleBackgroundStyle">
     </FrameLayout>
     <FrameLayout android:id="@android:id/content"
diff --git a/core/res/res/layout/time_header_label.xml b/core/res/res/layout/time_header_label.xml
new file mode 100644
index 0000000..f5f4a04
--- /dev/null
+++ b/core/res/res/layout/time_header_label.xml
@@ -0,0 +1,59 @@
+<?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:id="@+id/time_header"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center" >
+
+    <TextView
+            android:id="@+id/hours"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toLeftOf="@+id/separator"
+            android:layout_alignBaseline="@+id/separator"
+            android:textAppearance="?android:attr/timePickerHeaderTimeLabelTextAppearance"/>
+
+    <TextView
+            android:id="@+id/separator"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="@dimen/timepicker_separator_padding"
+            android:paddingRight="@dimen/timepicker_separator_padding"
+            android:layout_centerInParent="true"
+            android:textAppearance="?android:attr/timePickerHeaderTimeLabelTextAppearance"
+            android:importantForAccessibility="no" />
+
+    <TextView
+            android:id="@+id/minutes"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_toRightOf="@+id/separator"
+            android:layout_alignBaseline="@+id/separator"
+            android:textAppearance="?android:attr/timePickerHeaderTimeLabelTextAppearance" />
+
+    <TextView
+            android:id="@+id/ampm_label"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingLeft="@dimen/timepicker_ampm_left_padding"
+            android:paddingRight="@dimen/timepicker_ampm_left_padding"
+            android:layout_toRightOf="@+id/separator"
+            android:layout_alignBaseline="@+id/separator"
+            android:textAppearance="?android:attr/timePickerHeaderAmPmLabelTextAppearance" />
+
+</RelativeLayout>
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
index c6b7d3a..0890fe5 100644
--- a/core/res/res/layout/time_picker_holo.xml
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 **
-** Copyright 2011, The Android Open Source Project
+** 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.
@@ -17,70 +17,38 @@
 */
 -->
 
-<!-- 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: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 -->
-        <NumberPicker
-            android:id="@+id/hour"
+          android:layout_width="wrap_content"
+          android:layout_height="match_parent"
+          android:orientation="vertical"
+          android:focusable="true" >
+    <include
+            layout="@layout/time_header_label"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/timepicker_header_height"
+            android:layout_gravity="center" />
+    <android.widget.RadialTimePickerView
+            android:id="@+id/radial_picker"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="16dip"
-            android:layout_marginBottom="16dip"
+            android:layout_height="@dimen/timepicker_radial_picker_dimen"
+            android:layout_gravity="center"
             android:focusable="true"
-            android:focusableInTouchMode="true"
-            />
-
-        <!-- divider -->
-        <TextView
-            android:id="@+id/divider"
-            android:layout_width="wrap_content"
+            android:focusableInTouchMode="true" />
+    <LinearLayout
+            android:id="@+id/layout_buttons"
+            style="?android:attr/buttonBarStyle"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginStart="6dip"
-            android:layout_marginEnd="6dip"
-            android:layout_gravity="center_vertical"
-            android:importantForAccessibility="no"
-            />
-
-        <!-- minute -->
-        <NumberPicker
-            android:id="@+id/minute"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="16dip"
-            android:layout_marginBottom="16dip"
-            android:focusable="true"
-            android:focusableInTouchMode="true"
-            />
-
+            android:orientation="vertical"
+            android:divider="?android:attr/dividerHorizontal"
+            android:showDividers="beginning">
+        <Button
+                android:id="@+id/done_button"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:minHeight="48dp"
+                android:text="@string/done_label"
+                android:textSize="@dimen/timepicker_done_label_size"
+                style="?android:attr/buttonBarButtonStyle" />
     </LinearLayout>
-
-    <!-- AM / PM -->
-    <NumberPicker
-        android:id="@+id/amPm"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="16dip"
-        android:layout_marginBottom="16dip"
-        android:layout_marginStart="8dip"
-        android:layout_marginEnd="8dip"
-        android:focusable="true"
-        android:focusableInTouchMode="true"
-        />
-
 </LinearLayout>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker_legacy.xml
similarity index 100%
rename from core/res/res/layout/time_picker.xml
rename to core/res/res/layout/time_picker_legacy.xml
diff --git a/core/res/res/layout/time_picker_legacy_holo.xml b/core/res/res/layout/time_picker_legacy_holo.xml
new file mode 100644
index 0000000..c6b7d3a
--- /dev/null
+++ b/core/res/res/layout/time_picker_legacy_holo.xml
@@ -0,0 +1,86 @@
+<?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.
+*/
+-->
+
+<!-- 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: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 -->
+        <NumberPicker
+            android:id="@+id/hour"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="16dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+        <!-- divider -->
+        <TextView
+            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"
+            />
+
+        <!-- minute -->
+        <NumberPicker
+            android:id="@+id/minute"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="16dip"
+            android:layout_marginBottom="16dip"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            />
+
+    </LinearLayout>
+
+    <!-- AM / PM -->
+    <NumberPicker
+        android:id="@+id/amPm"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dip"
+        android:layout_marginBottom="16dip"
+        android:layout_marginStart="8dip"
+        android:layout_marginEnd="8dip"
+        android:focusable="true"
+        android:focusableInTouchMode="true"
+        />
+
+</LinearLayout>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 1a9acd3..5cb5709 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Voer \'n PUK van 8 syfers of langer in."</string>
     <string name="needPuk" msgid="919668385956251611">"Jou SIM-kaart is PUK-gesluit. Voer die PUK-kode in om dit te ontsluit."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Sleutel PUK2 in om SIM-kaart oop te sluit."</string>
+    <string name="enablePin" msgid="209412020907207950">"Onsuksesvol, aktiveer SIM-/RUIM-slot."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Jy het <xliff:g id="NUMBER">%d</xliff:g> oorblywende poging voordat SIM gesluit word."</item>
+    <item quantity="other" msgid="7530597808358774740">"Jy het <xliff:g id="NUMBER">%d</xliff:g> oorblywende pogings voordat SIM gesluit word."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Inkomender beller-ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"deïnstalleer kortpaaie"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Laat die program toe om Tuisskerm-kortpaaie te verwyder sonder gebruikerinmenging."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"herlei uitgaande oproepe"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Laat die program toe om uitgaande oproepe te verwerk en die nommer wat geskakel moet word te verander. Hierdie toestemming laat die program toe om uitgaande oproepe te monitor, herlei, of te voorkom."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Laat die program toe om te sien watter nommer tydens \'n uitgaande oproep geskakel word, met die opsie om die oproep na \'n ander nommer te herlei of die oproep heeltemal te beëindig."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"ontvang teksboodskappe (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Laat die program toe om SMS-boodskappe te ontvang en te verwerk. Dit beteken dat die program boodskappe wat na jou toestel gestuur is, kan monitor of uitvee, sonder dat jy dit gesien het."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"ontvang teksboodskappe (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n VPN-diens te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"bind aan \'n muurpapier"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Dit laat die houer toe om aan die topvlak-koppelvlak van \'n muurpapier te bind. Dit moet nooit vir normale programme nodig wees nie."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"koppel aan \'n afstandskerm"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Dit laat die houer toe om aan die top-koppelvlak van \'n afstandskerm te koppel. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind aan \'n legstukdiens"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"laat program gedurende ledige tyd loop"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Met hierdie toestemming kan die Android-stelsel die program in die agtergrond laat loop terwyl die toestel nie gebruik word nie."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Laat die program toe om SurfaceFlinger se laevlak-kenmerke te gebruik."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lees raambuffer"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Laat die program toe om die inhoud van die raambuffer te lees."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"kry toegang tot InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Laat die program toe om InputFlinger se laevlak-kenmerke te gebruik."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"stel Wi-Fi-skerms op"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Laat die program toe om klank met die mikrofoon op te neem. Hierdie toestemming laat die program toe om klank te eniger tyd, sonder jou bevestiging, op te neem."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"sim-kommunikasie"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Laat die program toe om bevele na die SIM te stuur. Dit is baie gevaarlik."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"neem foto\'s en video\'s"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Laat die program toe om foto\'s en video\'s met die kamera te neem. Hierdie toestemming laat die program toe om die kamera te eniger tyd sonder jou bevestiging te gebruik."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"deaktiveer LED wat oordrag aandui wanneer kamera gebruik word"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Laat die program toe om die foonkenmerke van die toestel te beheer. \'n Program met hierdie toestemming kan tussen netwerke wissel, die foonradio aan en af skakel, en dies meer, sonder om jou ooit te laat weet."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lees foonstatus en identiteit"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Laat die program toe om toegang tot die foonfunksies van die toestel te verkry. Hierdie toestemming laat die program toe om te bepaal wat die foonnommer en toestel-IDs is, of die oproep aan die gang is, en die afgeleë nommer wat deur \'n oproep verbind word."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"lees presiese foonstate"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gee die program toegang tot presiese foonstate. Hierdie toestemming laat die program toe om die werklike oproepstatus te bepaal, of \'n oproep aktief is en of dit in die agtergrond is. Dit kan ook mislukte oproepe, presiese dataverbindingstatus en mislukte dataverbindings bepaal."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"verhoed dat tablet slaap"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"verander invoertoestelkalibrasie"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Laat die program toe om die kalibrasieparameters van die raakskerm te wysig. Dit behoort nooit vir normale programme nodig te wees 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Tuis"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Werk"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Ander"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Geen program gekry om hierdie kontak te bekyk nie."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Tree in wisselwerking met opdatering- en terugstellingstelsel"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Laat \'n program met die terugstellingstelsel en stelselopdaterings in wisselwerking tree."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invoersleutel"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Kies \'n program"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Kon <xliff:g id="APPLICATION_NAME">%s</xliff:g> nie begin nie"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Deel met"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Deel met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Skyfievatsel. Raak en hou."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Sleep om te ontsluit."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Prop \'n kopfoon in om te hoor hoe wagwoordsleutels hardop gesê word."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punt."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Stelsel"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-oudio"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Draadlose skerm"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klaar"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Media-uitvoer"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Koppel aan toestel"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Saai skerm uit na toestel"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Soek tans vir toestelle…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Instellings"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Ontkoppel"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Skandeer tans..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Koppel tans..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Beskikbaar"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Skerm word tans uitgesaai"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Koppel tans aan <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Skerm word tans uitgesaai"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Gekoppel aan <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Ontkoppel"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK-kode moet 8 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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Sleep van bo af na onder om volskerm te verlaat."</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swiep van bo af na onder om volskerm te verlaat."</string>
+    <string name="done_label" msgid="2093726099505892398">"Klaar"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ure se sirkelglyer"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minute se sirkelglyer"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Kies ure"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Kies minute"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Maandrooster van dae"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Jaarlys"</string>
+    <string name="select_day" msgid="7774759604701773332">"Kies maand en dag"</string>
+    <string name="select_year" msgid="7952052866994196170">"Kies jaar"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> gekies"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> uitgevee"</string>
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index e64b6f5..5509121 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -46,10 +46,15 @@
     <string name="badPin" msgid="9015277645546710014">"የተየበከው የድሮ ፒን ትክክል አይደለም።"</string>
     <string name="badPuk" msgid="5487257647081132201">"የተየብከው PUK ትክክል  አይደለም።"</string>
     <string name="mismatchPin" msgid="609379054496863419">"ያስገባሃቸው ፒኖች አይዛመዱም"</string>
-    <string name="invalidPin" msgid="3850018445187475377">"ከ4 እስከ 8 ቁጥሮች የያዘ PIN ተይብ"</string>
+    <string name="invalidPin" msgid="3850018445187475377">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን  ተይብ"</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="enablePin" msgid="209412020907207950">"አልተሳካም፣ የሲም/RUIM ቁልፍን አንቃ።"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"ሲምዎ ከመቆለፉ በፊት <xliff:g id="NUMBER">%d</xliff:g> ሙከራ ይቀርዎታል።"</item>
+    <item quantity="other" msgid="7530597808358774740">"ሲምዎ ከመቆለፉ በፊት <xliff:g id="NUMBER">%d</xliff:g> ሙከራዎች ይቀሩዎታል።"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"የገቢ ደዋይID"</string>
@@ -175,7 +180,7 @@
     <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="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>
@@ -205,7 +210,7 @@
     <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="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>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"አቋራጮችን ያራግፋል"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"መተግበሪያው ያለተጠቃሚ ጣልቃ-ገብነት የመነሻ ማያ ገጽ አቋራጮችን እንዲያስወግድ ያስችለዋል።"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"የወጪ ጥሪዎች አቅጣጫ ቀይር"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"መተግበሪያው ወጪ ጥሪዎችን እንዲያስኬድና የሚደወለውን ቁጥር እንዲቀይር ይፈቅድለታል። ይህ ፈቃድ መተግበሪያው ወጪ ጥሪዎችን እንዲቆጣጠር፣ አቅጣጫ እንዲየስቀይር ወይም እንዲያግድ ይፈቅድለታል።"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"በወጪ ጥሪ ጊዜ ጥሪውን ወደተለየ ቁጥር ከማዞር ወይም ጥሪውን በአጠቃላይ ከመተው አማራጭ ጋር እየተደወለለት ያለውን ቁጥር እንዲያይ ያስችለዋል።"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"የፅሁፍ መልዕክቶችን ተቀበል (ኤስ.ኤም.ኤስ.)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"መተግበሪያው የኤስ.ኤም.ኤስ. መልእክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ማለት መተግበሪያው ወደ መሳሪያህ የተላኩ መልእክቶችን ላንተ ሳያሳይህ ሊቆጣጠር ወይም ሊሰርዝ ይችላል።"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"የፅሁፍ መልዕክቶችን ተቀበል (ኤም.ኤም.ኤስ.)"</string>
@@ -264,15 +269,15 @@
     <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">"የጽሑፍ መልዕክቶችህን አንብብ (ኤስ.ኤም.ኤስ. ወይም ኤም.ኤም.ኤስ.)"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"የጽሑፍ መልዕክቶችዎን ያንብቡ (ኤስ.ኤም.ኤስ. ወይም ኤም.ኤም.ኤስ.)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"መገለጫው በጡባዊ ቱኮህ ወይም በSIM ካርድህ የተከማቹ የኤስ.ኤም.ኤስ. መልእክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልእክቶች እንዲያነብ ይፈቅድለታል።"</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"መገለጫው በስልክህ ወይም በSIM ካርድህ የተከማቹ የኤስ.ኤም.ኤስ. መልእክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልእክቶች እንዲያነብ ይፈቅድለታል።"</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"መገለጫው በስልክዎ ወይም በSIM ካርድዎ የተከማቹ የኤስ.ኤም.ኤስ. መልዕክቶችን እንዲያነብ ይፈቅድለታል። ይህ መተግበሪያው ይዘት ወይም ሚስጥራዊነትን ከግምት ሳያስገባ ሁሉንም የኤስ.ኤም.ኤስ. መልዕክቶች እንዲያነብ ይፈቅድለታል።"</string>
     <string name="permlab_writeSms" msgid="3216950472636214774">"የጽሑፍ መልዕክቶችህን አርትዕ (ኤስ.ኤም.ኤስ. ወይም ኤም.ኤም.ኤስ.)"</string>
     <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"በጡባዊ ተኮህ ወይም ሲም ካርድህ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ፡፡መልዕክቶችህን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ፡፡"</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"በስልክህ ወይም ሲም ካርድህ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ፡፡መልዕክቶችህን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ፡፡"</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"በስልክዎ ወይም ሲም ካርድዎ ላይ ኤስ ኤም ኤስ መልዕክቶችን ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። መልዕክቶችዎን ተንኮል አዘል መተግበሪያዎች ሊሰርዙ ይችላሉ።"</string>
     <string name="permlab_receiveWapPush" msgid="5991398711936590410">"የፅሁፍ መልዕክቶችን ተቀበል (WAP)"</string>
     <string name="permdesc_receiveWapPush" msgid="748232190220583385">"መተግበሪያው የWAP መልእክቶችን እንዲያነብ እና እንዲያካሂድ ይፈቅዳል። ይህ ፈቃድ የተላኩልህን መልእክቶች ላንተ ሳያሳይህ የመቆጣጠር ወይም የመሰረዝ ብቃትን ያጠቃልላል።"</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"አሂድ መተግበሪያዎችን ሰርስረህ አውጣ"</string>
+    <string name="permlab_getTasks" msgid="6466095396623933906">"አሂድ መተግበሪያዎችን ሰርስረው ያውጡ"</string>
     <string name="permdesc_getTasks" msgid="7454215995847658102">"መተግበሪያው በአሁኑ ጊዜና በቅርቡ እየተካሄዱ ስላሉ ተግባሮችን መረጃ ሰርስሮ እንዲያወጣ ይፈቅድለታል። ይህ መተግበሪያው በመሳሪያው ላይ የትኛዎቹ መተግበሪያዎች ጥቅም ላይ ስለመዋላቸው መረጃ እንዲያገኝ ሊፈቅድለት ይችላል።"</string>
     <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"በተለያዩ ተጠቃሚዎች መካከል መስተጋብር መፍጠር"</string>
     <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"መተግበሪያው በመሣሪያው ላይ በተለያዩ ተጠቃሚዎች ላይ እርምጃዎችን እንዲፈጽም ይፈቅድለታል። ተንኮል-አዘል መተግበሪያዎች ይህንን ተጠቅመው በተጠቃሚዎች መካከል ያለውን ጥበቃ ሊጥሱ ይችላሉ።"</string>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"ከአንድ የርቀት ማሳያ ጋር ይጠርዛል"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ያዢው ከአንድ የርቀት ማሳያ ከፍተኛ-ደረጃ በይነገጽ ጋር እንዲጠርዝ ይፈቅድለታል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ወደ ፍርግም አገልግሎት አያይዝ"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ያዡ ግቤት ስልቱን ወደ ከፍተኛ-ደረጃ ፍርግም አገልግሎት ለመጠረዝ  ይፈቅዳሉ። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ከመሣሪያ አስተዳደር ጋር ተገናኝ"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"ስራ በተፈታበት ጊዜ ላይ መተግበሪያውን አሂድ"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"ይህ ፍቃድ መሣሪያው ስራ ላይ ባልሆነ ጊዜ የAndroid ስርዓቱ መተግበሪያውን በጀርባ ውስጥ እንዲያሂደው ያስችለዋል።"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"በdiag ባለቤትነት ያሉ ንብረቶችን አንብብ/ፃፍ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"በዲያግ ቡድን ባለቤትነት ወደ አለ ማንኛውም ንብረት ለምሳሌ በ/dev ያሉ ፋይሎች ለማንበብ እና ለመፃፍ ለመተግበሪያው ይፈቅዳሉ። ይህ በመሰረቱ የስርዓት መረጋጋትን እና ደህንነትን ሊጎዳ ይችላል። ይህ ውስን የሀርድዌር-ተኮር ዲያግኖስቲክስ በአምራቹ ወይም ከዋኙ ብቻ መሆን አለበት።"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"የመተግበሪያ ምንዝሮችን አንቃ ወይም አቦዝን"</string>
@@ -437,12 +446,12 @@
     <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="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="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="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>
@@ -450,19 +459,19 @@
     <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="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="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_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>
@@ -477,6 +486,8 @@
     <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>
@@ -493,9 +504,11 @@
     <string name="permdesc_mediaContentControl" msgid="1637478200272062">"መተግበሪያው የሚዲያ መልሰህ አጫውትን እንዲቆጣጠር እና የሚዲያ መረጃውን (ርእስ፣ ደራሲ...) እንዲደርስ ይፈቅድለታል።"</string>
     <string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"የድምፅ ቅንብሮችን ለውጥ"</string>
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"መተግበሪያው አንደ የድምጽ መጠን እና ለውጽአት የትኛውን የድምጽ ማጉያ ጥቅም ላይ እንደዋለ የመሳሰሉ ሁለንተናዊ የድምጽ ቅንብሮችን እንዲያስተካክል ይፈቅድለታል።"</string>
-    <string name="permlab_recordAudio" msgid="3876049771427466323">"ኦዲዮ ቅዳ"</string>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"ኦዲዮ ይቅዱ"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"መተግበሪያው ድምጽን በማይክሮፎን እንዲቀዳ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያው ያላንተ ማረጋገጫ በማንኛውም ጊዜ ድምጽ እንዲቀዳ ይፈቅድለታል።"</string>
-    <string name="permlab_camera" msgid="3616391919559751192">"ፎቶዎች እና ቪዲዮዎች አንሳ"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"የሲም ግንኙነት"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"መተግበሪያው ትዕዛዞችን ወደ ሲሙ እንዲልክ ያስችለዋል። ይሄ በጣማ አደገኛ ነው።"</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>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"የመገልገያ መሳሪያውን የስልክ ባህሪያት ለመቆጣጠር ለመተግበሪያው ይፈቅዳል፡፡ ከዚህ ፍቃድ ጋር መተግበሪያ አውታረ መረቦችን ሊለውጥ ይችላል፤አንተን ምንም ሳያሳውቅ የስልኩን ሬድዮ አብራ እና አጥፋ እና የመሳሰሉትን ሊያበራ ይችላል፡፡"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"የስልክ ሁኔታና ማንነት አንብብ"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"መተግበሪያው የመሳሪያውን የስልክ ባህሪያት ላይ እንዲደርስ ይፈቅድለታል። ይህ ፈቃድ መተግበሪያው የስልክ ቁጥሩን እና የመሳሪያውን መታወቂያዎች፣ ጥሪ የነቃ እንደሆነ፣ እና በጥሪ የተገናኘውን የሩቅ ቁጥር እንዲወስን ይፈቅድለታል።"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ትክክለኛዎቹን የስልክ ሁኔታዎች ያነብባል"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"መተግበሪያው ትክክለኛዎቹ የስልክ ሁኔታዎችን እንዲደርስባቸው ያስችለዋል። ይህ ፍቃድ መተግበሪያው የእውነተኛ ጥሪው ሁኔታ፣ አንድ ጥሪ ገባሪ ወይም ጀርባ ላይ ይሁን፣ ያልተሳኩ ጥሪዎች፣ ትክክለኛው የውሂብ ግንኙነት ሁኔታ እና የውሂብ ግንኙነት አለመሳካቶችን እንዲያውቅ ያስችለዋል።"</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>
@@ -578,16 +593,16 @@
     <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="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="permlab_manageAccounts" msgid="4983126304757177305">"መለያዎችን ያክሉ ወይም ያስወግዱ"</string>
     <string name="permdesc_manageAccounts" msgid="8698295625488292506">"መለያዎችን እንደ ማከል እና ማስወገድ ክወናዎችን እና የይለፍ ቃልን መሰረዝ ለማከናወን ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
-    <string name="permlab_useCredentials" msgid="235481396163877642">"በመሣሪያው ላይ ያሉ መለያዎችን ተጠቀም"</string>
+    <string name="permlab_useCredentials" msgid="235481396163877642">"በመሣሪያው ላይ ያሉ መለያዎችን ይጠቀሙ"</string>
     <string name="permdesc_useCredentials" msgid="7984227147403346422">"የማረጋገጫ የምስጋና የምስክር ወረቀትን ለመጠየቅ ለመተግበሪያው ይፈቅዳሉ፡፡"</string>
-    <string name="permlab_accessNetworkState" msgid="4951027964348974773">"የአውታረ መረብ ግኑኝነቶችን እይ"</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>
@@ -638,7 +653,7 @@
     <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="367275095159405468">"የUSB ማከማቻህን ይዘቶች አንብብ"</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"የUSB ማከማቻዎን ይዘቶች ያንብቡ"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"የSD ካርድህን ይዘቶች አንብብ"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"መተግበሪያው የእርስዎ USB ማከማቻ ይዘቶችን እንዲያነብ ያስችለዋል።"</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"መተግበሪያው የእርስዎ SD ካርድ ይዘቶችን እንዲያነብ ያስችለዋል።"</string>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ያዢው በድምጸ-ተያያዥ ሞደም የቀረበው የውቅር መተግበሪያውን እንዲጠራው ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን ያዳምጣል"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"አንድ መተግበሪያ በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን እንዲያዳምጥ ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አስፈላጊ ሊሆን አይገባም።"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"የግቤት መሣሪያ ማስተካከያ ቀይር"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"መተግበሪያው የማያ ንካ የማስተካከያ ልኬቶቹን እንዲቀይር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"መነሻ"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"ስራ"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"ሌላ"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"ምንም መተግበሪያ ይህንን እውቂያ ለመመልከት አልተገኘም።"</string>
     <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>
@@ -816,7 +834,7 @@
     <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_password_wrong_pin_code" msgid="2422225591006134936">"ትክክል ያልሆነ ፒን  ኮድ።"</string>
     <string name="keyguard_label_text" msgid="861796461028298424">"ለመክፈት፣ምናሌ ተጫን ከዛ 0"</string>
     <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"የአደጋ ጊዜቁጥር"</string>
     <string name="lockscreen_carrier_default" msgid="8963839242565653192">"ከአገልግሎት መስጫ ክልል ውጪ"</string>
@@ -959,7 +977,7 @@
     <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="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>
@@ -978,8 +996,8 @@
     <string name="searchview_description_submit" msgid="2688450133297983542">"ጥያቄ አስረክብ"</string>
     <string name="searchview_description_voice" msgid="2453203695674994440">"የድምፅ ፍለጋ"</string>
     <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"በመንካት አስስ ይንቃ?"</string>
-    <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>  ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከጡባዊ ተኮው ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g>  ማሰስን በንኪ ማንቃት ይፈልጋል። አስስ በንኪ በሚበራበት ጊዜ፣ ከስልኩ ጋር ለመግባባት ምን በጣትህ ስር ወይም ምልክቶችን ማከናወን እንዳለብህ ማብራሪያ ልታይ ወይም ልትሰማ ትችላለህ።"</string>
+    <string name="enable_explore_by_touch_warning_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">
@@ -1107,9 +1125,9 @@
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> እያሄደ ነው"</string>
     <string name="app_running_notification_text" msgid="4653586947747330058">"ተጨማሪ መረጃ ለማግኘት ወይም መተግበሪያውን ለማቆም ይንኩ።"</string>
     <string name="ok" msgid="5970060430562524910">"እሺ"</string>
-    <string name="cancel" msgid="6442560571259935130">"ሰርዝ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
     <string name="yes" msgid="5362982303337969312">"እሺ"</string>
-    <string name="no" msgid="5141531044935541497">"ሰርዝ"</string>
+    <string name="no" msgid="5141531044935541497">"ይቅር"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"ትኩረት"</string>
     <string name="loading" msgid="7933681260296021180">"በመጫን ላይ…"</string>
     <string name="capital_on" msgid="1544682755514494298">"በ"</string>
@@ -1211,7 +1229,7 @@
     <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_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>
@@ -1225,7 +1243,7 @@
     <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="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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"ከዝማኔዎች እና ከመልሶ ማግኛ ስርዓቶች ጋር ይገናኙ"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"መተግበሪያው ከመልሶ ማግኛ ስርዓት እና ከስርዓት ማዘመኛዎች ጋር እንዲገናኝ ይፈቅድለታል።"</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>
@@ -1407,25 +1427,17 @@
     <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_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="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>ን ማስጀመር አልተቻለም"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ተጋራ ከ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ከ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ጋር ተጋራ"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ባለስላይድ መያዣ፡፡ ዳስ&amp;ያዝ፡፡"</string>
-    <string name="description_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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"ከመሳሪያ ጋር ያገናኙ"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ማያ ገጽን ወደ መሣሪያ ይውሰዱ"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"መሳሪያዎችን በመፈለግ ላይ…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"ቅንብሮች"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"ግንኙነት አቋርጥ"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"በመቃኘት ላይ..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"በማገናኘት ላይ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"የሚገኙ"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"ማያ ገጽን በመውሰድ ላይ"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"ከ<xliff:g id="NAME">%1$s</xliff:g> ጋር በመገናኘት ላይ"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"ማያ ገጽን በመውሰድ ላይ"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"ከ<xliff:g id="NAME">%1$s</xliff:g> ጋር ተገናኝቷል"</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>
@@ -1514,7 +1532,7 @@
     <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ሲም ካርዱን በመክፈት ላይ…"</string>
     <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ትክክል ያልሆነ ፒን ኮድ።"</string>
     <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"ከ4 እስከ 8 ቁጥሮች የያዘ ፒን ይተይቡ።"</string>
-    <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"የPUK ኮድ 8 ወይም ከዚያ በላይ ቁጥሮች ሊኖረው ይገባል።"</string>
+    <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"የፒዩኬ ኮድ 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"ቆይተው እንደገና ይሞክሩ"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ከሙሉ ገጽ ማያ ለመውጣት ጣትዎን ከላይ ወደታች ያንሸራትቱ።"</string>
+    <string name="done_label" msgid="2093726099505892398">"ተከናውኗል"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"የሰዓታት ክብ ተንሸራታች"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"የደቂቃዎች ክብ ተንሸራታች"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ሰዓታትን ይምረጡ"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"ደቂቃዎችን ይምረጡ"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"የቀናት የወር ፍርግርግ"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"የዓመት ዝርዝር"</string>
+    <string name="select_day" msgid="7774759604701773332">"ወር እና ቀን ይምረጡ"</string>
+    <string name="select_year" msgid="7952052866994196170">"ዓመት ይምረጡ"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ተመርጧል"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ተሰርዟል"</string>
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 2d91e28..d17b1d1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -27,14 +27,14 @@
     <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="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="mmiError" msgid="5154499457739052907">"‏حدثت مشكلة في الاتصال أو أن كود MMI غير صحيح."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"تم تقييد التشغيل لأرقام الاتصال الثابت فقط."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"تم تمكين الخدمة."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"تم تمكين الخدمة لـ:"</string>
@@ -42,23 +42,28 @@
     <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="mmiComplete" msgid="8232527495411698359">"‏اكتمل MMI."</string>
+    <string name="badPin" msgid="9015277645546710014">"‏رمز PIN القديم الذي كتبته غير صحيح."</string>
+    <string name="badPuk" msgid="5487257647081132201">"‏رمز PUK الذي كتبته غير صحيح."</string>
     <string name="mismatchPin" msgid="609379054496863419">"أرقام التعريف الشخصية التي كتبتها غير مطابقة."</string>
     <string name="invalidPin" msgid="3850018445187475377">"اكتب رقم تعريف شخصيًا مكونًا من 4 إلى ثمانية أعداد."</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="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="enablePin" msgid="209412020907207950">"‏محاولة غير ناجحة، مكّن قفل SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"‏يتبقى لديك محاولة واحدة (<xliff:g id="NUMBER">%d</xliff:g>) يتم بعدها قفل بطاقة SIM."</item>
+    <item quantity="other" msgid="7530597808358774740">"‏يتبقى لديك <xliff:g id="NUMBER">%d</xliff:g> من المحاولات يتم بعدها قفل بطاقة SIM."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"معرف المتصل الوارد"</string>
     <string name="ClirMmi" msgid="7784673673446833091">"معرف المتصل الصادر"</string>
-    <string name="CfMmi" msgid="5123218989141573515">"إعادة توجيه الاتصال"</string>
+    <string name="CfMmi" msgid="5123218989141573515">"اعادة توجيه المكالمة"</string>
     <string name="CwMmi" msgid="9129678056795016867">"انتظار المكالمة"</string>
     <string name="BaMmi" msgid="455193067926770581">"حظر الاتصال"</string>
     <string name="PwdMmi" msgid="7043715687905254199">"تغيير كلمة المرور"</string>
-    <string name="PinMmi" msgid="3113117780361190304">"تغيير رقم التعريف الشخصي"</string>
+    <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>
@@ -76,14 +81,14 @@
     <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="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="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="serviceClassSMS" msgid="2015460373701527489">"‏الرسائل القصيرة SMS"</string>
     <string name="serviceClassDataAsync" msgid="4523454783498551468">"غير متزامنة"</string>
     <string name="serviceClassDataSync" msgid="7530000519646054776">"مزامنة"</string>
     <string name="serviceClassPacket" msgid="6991006557993423453">"الحزمة"</string>
@@ -111,7 +116,7 @@
     <string name="fcError" msgid="3327560126588500777">"حدثت مشكلة بالاتصال أو أن كود الميزة غير صحيح."</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"موافق"</string>
     <string name="httpError" msgid="7956392511146698522">"حدث خطأ في الشبكة."</string>
-    <string name="httpErrorLookup" msgid="4711687456111963163">"تعذر العثور على عنوان URL."</string>
+    <string name="httpErrorLookup" msgid="4711687456111963163">"‏تعذر العثور على عنوان URL."</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"نظام مصادقة الموقع غير معتمد."</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"تعذرت المصادقة."</string>
     <string name="httpErrorProxyAuth" msgid="1788207010559081331">"لم تتم المصادقة عبر الخادم الوكيل بنجاح."</string>
@@ -121,7 +126,7 @@
     <string name="httpErrorRedirectLoop" msgid="8679596090392779516">"تحتوي هذه الصفحة على عمليات إعادة توجيه خادم كثيرة للغاية."</string>
     <string name="httpErrorUnsupportedScheme" msgid="5015730812906192208">"البروتوكول غير معتمد."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"تعذر إنشاء اتصال آمن."</string>
-    <string name="httpErrorBadUrl" msgid="3636929722728881972">"تعذر فتح الصفحة لأن عنوان URL غير صالح."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"‏تعذر فتح الصفحة لأن عنوان URL غير صالح."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"تعذر الدخول إلى الملف."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"تعذر العثور على الملف المطلوب."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"تتم الآن معالجة طلبات كثيرة للغاية. حاول مرة أخرى في وقت لاحق."</string>
@@ -168,11 +173,11 @@
     <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="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="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>
@@ -228,8 +233,8 @@
     <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="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>
@@ -251,27 +256,27 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"إزالة الاختصارات"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"للسماح للتطبيق بإزالة اختصارات من الشاشة الرئيسية بدون تدخل المستخدم."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"إعادة توجيه المكالمات الصادرة"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"للسماح للتطبيق بمعالجة المكالمات الصادرة وتغيير الرقم المطلوب. يتيح هذا الإذن للتطبيق مراقبة المكالمات الصادرة أو إعادة توجيهها أو منعها."</string>
-    <string name="permlab_receiveSms" msgid="8673471768947895082">"تلقي رسائل نصية (رسائل قصيرة SMS)"</string>
-    <string name="permdesc_receiveSms" msgid="6424387754228766939">"للسماح للتطبيق بتلقي ومعالجة الرسائل القصيرة SMS. وهذا يعني أنه يمكن للتطبيق مراقبة الرسائل التي يتم إرسالها إلى جهازك أو حذفها بدون عرضها لك."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"للسماح للتطبيق بالاطلاع على الرقم الذي يتم الاتصال به عند إجراء مكالمة صادرة مع وجود الخيار لإعادة توجيه المكالمة إلى رقم آخر أو إنهاء المكالمة تمامًا."</string>
+    <string name="permlab_receiveSms" msgid="8673471768947895082">"‏تلقي رسائل نصية (رسائل قصيرة SMS)"</string>
+    <string name="permdesc_receiveSms" msgid="6424387754228766939">"‏للسماح للتطبيق بتلقي ومعالجة الرسائل القصيرة SMS. وهذا يعني أنه يمكن للتطبيق مراقبة الرسائل التي يتم إرسالها إلى جهازك أو حذفها بدون عرضها لك."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"تلقي رسائل نصية (رسائل وسائط متعددة)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"للسماح للتطبيق بتلقي ومعالجة رسائل الوسائط المتعددة. وهذا يعني أنه يمكن للتطبيق مراقبة الرسائل التي يتم إرسالها لجهازك أو حذفها بدون عرضها لك."</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="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 أو رسائل الوسائط المتعددة)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"للسماح للتطبيق بقراءة الرسائل القصيرة SMS المخزنة على الجهاز اللوحي أو على بطاقة SIM. ويتيح هذا للتطبيق قراءة جميع الرسائل القصيرة SMS، بغض النظر عن المحتوى أو مدى السرية."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"للسماح للتطبيق بقراءة الرسائل القصيرة SMS المخزنة على هاتفك أو على بطاقة SIM. ويتيح هذا للتطبيق قراءة جميع الرسائل القصيرة SMS، بغض النظر عن المحتوى أو مدى السرية."</string>
-    <string name="permlab_writeSms" msgid="3216950472636214774">"تعديل الرسائل النصية (الرسائل القصيرة SMS أو رسائل الوسائط المتعددة)"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"للسماح للتطبيق بالكتابة إلى الرسائل القصيرة SMS المخزّنة على الجهاز اللوحي أو بطاقة SIM. قد تحذف التطبيقات الضارة رسائلك."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"للسماح للتطبيق بالكتابة إلى الرسائل القصيرة SMS المخزّنة على الهاتف أو بطاقة SIM. قد تحذف التطبيقات الضارة رسائلك."</string>
-    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"تلقي رسائل نصية (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"للسماح للتطبيق بتلقي رسائل WAP ومعالجتها. ويتضمن هذا الإذن إمكانية مراقبة الرسائل التي يتم إرسالها إليك أو حذفها بدون عرضها لك."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"‏قراءة الرسائل النصية (الرسائل القصيرة SMS أو رسائل الوسائط المتعددة)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"‏للسماح للتطبيق بقراءة الرسائل القصيرة SMS المخزنة على الجهاز اللوحي أو على بطاقة SIM. ويتيح هذا للتطبيق قراءة جميع الرسائل القصيرة SMS، بغض النظر عن المحتوى أو مدى السرية."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"‏للسماح للتطبيق بقراءة الرسائل القصيرة SMS المخزنة على هاتفك أو على بطاقة SIM. ويتيح هذا للتطبيق قراءة جميع الرسائل القصيرة SMS، بغض النظر عن المحتوى أو مدى السرية."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"‏تعديل الرسائل النصية (الرسائل القصيرة SMS أو رسائل الوسائط المتعددة)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"‏للسماح للتطبيق بالكتابة إلى الرسائل القصيرة SMS المخزّنة على الجهاز اللوحي أو بطاقة SIM. قد تحذف التطبيقات الضارة رسائلك."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"‏للسماح للتطبيق بالكتابة إلى الرسائل القصيرة SMS المخزّنة على الهاتف أو بطاقة 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>
@@ -326,10 +331,10 @@
     <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. يمكن أن تستخدم التطبيقات الضارة هذا لتزيف استلام رسالة وسائط متعددة أو لاستبدال محتوى أي صفحة ويب بمتغيرات ضارة بشكل غير ملحوظ."</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. يمكن أن تستخدم التطبيقات الضارة هذا لتزيف استلام رسالة وسائط متعددة أو لاستبدال محتوى أي صفحة ويب بمتغيرات ضارة بشكل غير ملحوظ."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"تحديد عدد العمليات قيد التشغيل"</string>
     <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"للسماح للتطبيق بالتحكم في الحد الأقصى لعدد العمليات التي سيتم تشغيلها. غير مطلوب على الإطلاق للتطبيقات العادية."</string>
     <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"فرض إغلاق تطبيقات الخلفية"</string>
@@ -353,7 +358,7 @@
     <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_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>
@@ -369,14 +374,16 @@
     <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_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="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_bindRemoteDisplay" msgid="1782923938029941960">"الربط بالشاشة عن بُعد"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"للسماح للمالك بالالتزام بواجهة المستوى العلوي للعرض عن بُعد. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"الالتزام بخدمة أداة"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"للسماح للمالك بالالتزام بواجهة المستوى العلوي لخدمة الأداة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"التفاعل مع مشرف الجهاز"</string>
@@ -389,13 +396,13 @@
     <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="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="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>
@@ -403,7 +410,7 @@
     <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="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>
@@ -415,9 +422,11 @@
     <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="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏السماح للتطبيق بتثبيت شهادات CA وإلغاء تثبيتها باعتبارها بيانات اعتماد محل ثقة."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"تشغيل التطبيق أثناء وقت الخمول"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"‏يتيح هذا الإذن لنظام Android تشغيل التطبيق في الخلفية في حين أن الجهاز ليس قيد الاستخدام."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"قراءة/كتابة إلى الموارد المملوكة بواسطة التشخيص"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"للسماح للتطبيق بالقراءة والكتابة إلى أي مورد مملوك بواسطة مجموعة التشخيصات؛ على سبيل المثال، الملفات في /dev. من المحتمل أن يؤثر ذلك في استقرار النظام وأمانه. يجب ألا يستخدم ذلك سوى للتشخيصات الخاصة بالنظام من قِبل المصنِّع أو المشغِّل."</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>
@@ -429,8 +438,8 @@
     <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_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>
@@ -464,23 +473,25 @@
     <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">"الموقع الدقيق (مستند إلى نظام تحديد المواقع العالمي والشبكة)"</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="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"الدخول إلى SurfaceFlinger"</string>
-    <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"للسماح للتطبيق باستخدام ميزات SurfaceFlinger ذات المستوى المنخفض."</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">"تهيئة شاشات Wi-Fi"</string>
-    <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_accessInputFlinger" msgid="5348635270689553857">"‏الدخول إلى InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"‏للسماح للتطبيق باستخدام ميزات InputFlinger ذات المستوى المنخفض."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"‏تهيئة شاشات Wi-Fi"</string>
+    <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>
@@ -495,10 +506,12 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"للسماح للتطبيق بتعديل إعدادات الصوت العامة مثل مستوى الصوت وأي السماعات يتم استخدامها للاستماع."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"تسجيل الصوت"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"للسماح للتطبيق بتسجيل الصوت باستخدام الميكروفون. ويتيح هذا الإذن للتطبيق تسجيل الصوت في أي وقت وبدون موافقة منك."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"‏اتصالات SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"‏السماح للتطبيق بإرسال أوامر إلى بطاقة SIM. وهذا أمر بالغ الخطورة."</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_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>
@@ -507,11 +520,11 @@
     <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="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="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>
@@ -527,19 +540,19 @@
     <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_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_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>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"للسماح للتطبيق بالتحكم في ميزات الهاتف بالجهاز. يمكن لأحد التطبيقات بهذا الإذن تبديل الشبكات وتشغيل لاسلكي الهاتف وإيقاف تشغيله وما إلى ذلك بدون إعلامك على الإطلاق."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"قراءة حالة الهاتف والهوية"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"للسماح للتطبيق بالدخول إلى ميزات الهاتف في الجهاز. ويتيح هذا الإذن للتطبيق تحديد رقم الهاتف ومعرّفات الجهاز، وما إذا كانت هناك مكالمة نشطة والرقم البعيد الذي تم الاتصال به في المكالمة."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"قراءة حالات الهاتف الدقيقة"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"للسماح للتطبيق بالوصول إلى حالات الهاتف الدقيقة. يتيح هذا الإذن للتطبيق تحديد حالة المكالمة الفعلية، سواء أكانت مكالمة نشطة أم في الخلفية، وإخفاق الاتصال، وحالة اتصال البيانات الدقيقة، وإخفاق اتصال البيانات."</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>
@@ -582,7 +597,7 @@
     <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="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>
@@ -592,36 +607,36 @@
     <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="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_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_bluetoothPriv" msgid="4009494246009513828">"السماح بإقران البلوتوث مع التطبيق"</string>
     <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"للسماح بإقران لتطبيق مع الأجهزة البعيدة بدون تدخل المستخدم."</string>
     <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"للسماح بإقران لتطبيق مع الأجهزة البعيدة بدون تدخل المستخدم."</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_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="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>
@@ -638,14 +653,14 @@
     <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="367275095159405468">"قراءة محتويات وحدة تخزين USB"</string>
-    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"قراءة محتويات بطاقة SD"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"للسماح للتطبيق بقراءة محتويات وحدة تخزين USB."</string>
-    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"للسماح للتطبيق بقراءة محتويات بطاقة SD."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"تعديل محتويات وحدة تخزين USB أو حذفها"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"تعديل محتويات بطاقة SD أو حذفها"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"للسماح للتطبيق بالكتابة إلى وحدة تخزين USB."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"للسماح للتطبيق بالكتابة إلى بطاقة SD."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"‏قراءة محتويات وحدة تخزين USB"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"‏قراءة محتويات بطاقة SD"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"‏للسماح للتطبيق بقراءة محتويات وحدة تخزين USB."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"‏للسماح للتطبيق بقراءة محتويات بطاقة SD."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"‏تعديل محتويات وحدة تخزين USB أو حذفها"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"‏تعديل محتويات بطاقة SD أو حذفها"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"‏للسماح للتطبيق بالكتابة إلى وحدة تخزين USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"‏للسماح للتطبيق بالكتابة إلى بطاقة SD."</string>
     <string name="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>
@@ -655,7 +670,7 @@
     <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="permdesc_use_sip" msgid="4717632000062674294">"‏للسماح للتطبيق باستخدام خدمة SIP لإجراء/تلقي مكالمات عبر الإنترنت."</string>
     <string name="permlab_bind_call_service" msgid="6724009726671246551">"التفاعل مع الشاشة أثناء الاتصال"</string>
     <string name="permdesc_bind_call_service" msgid="8732547662442572435">"للسماح للتطبيق بالتحكم في وقت وكيفية مشاهدة المستخدم للشاشة أثناء الاتصال."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"قراءة بيانات الاستخدام السابقة للشبكة"</string>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"للسماح للمالك باستدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"الاستماع إلى ملاحظات حول أحوال الشبكة"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"للسماح للتطبيق بالاستماع إلى ملاحظات حول أحوال الشبكة. لا حاجة إلى هذا مع التطبيقات العادية."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"تغيير معايرة أجهزة الإدخال"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"يتيح للتطبيق إمكانية تعديل معلمات المعايرة في شاشة اللمس. يجب عدم اللجوء إليه مع التطبيقات العادية."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
@@ -809,14 +826,15 @@
     <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">"اكتب رمز رقم التعريف الشخصي"</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="quick_contacts_not_available" msgid="746098007828579688">"لم يتم العثور على تطبيق لعرض جهة الاتصال هذه."</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">"اكتب رقم التعريف الشخصي لإلغاء التأمين"</string>
-    <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"رقم التعريف الشخصي غير صحيح."</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>
@@ -834,13 +852,13 @@
     <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_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>
@@ -848,15 +866,15 @@
     <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_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_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_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>
@@ -865,12 +883,12 @@
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"هل نسيت النمط؟"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"إلغاء تأمين الحساب"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"محاولات النقش كثيرة جدًا"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"لإلغاء التأمين، سجّل الدخول بحسابك في Google."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"‏لإلغاء التأمين، سجّل الدخول بحسابك في Google."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"اسم المستخدم (البريد إلكتروني)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"كلمة المرور"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"تسجيل الدخول"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"اسم المستخدم غير صحيح أو كلمة المرور غير صحيحة."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"هل نسيت اسم المستخدم أو كلمة المرور؟\nانتقل إلى "<b>"google.com/accounts/recovery"</b></string>
+    <string name="lockscreen_glogin_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>
@@ -879,7 +897,7 @@
     <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_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>
@@ -896,7 +914,7 @@
     <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_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>
@@ -910,8 +928,8 @@
     <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_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>
@@ -940,7 +958,7 @@
     <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>
@@ -977,9 +995,9 @@
     <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">"هل تريد تمكين ميزة 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> تمكين ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الجهاز اللوحي."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تمكين ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الهاتف."</string>
+    <string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"‏هل تريد تمكين ميزة 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> تمكين ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الجهاز اللوحي."</string>
+    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"‏يريد <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> تمكين ميزة Explore by Touch. عند تشغيل ميزة Explore by Touch، سيكون بإمكانك سماع أو مشاهدة أوصاف لما تحت إصبعك أو إجراء إيماءات للتفاعل مع الهاتف."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"قبل شهر واحد"</string>
     <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"قبل شهر واحد"</string>
   <plurals name="num_seconds_ago">
@@ -1095,7 +1113,7 @@
     <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="copyUrl" msgid="2538211579596067402">"‏نسخ عنوان URL"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"تحديد نص"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"تحديد النص"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"إضافة إلى القاموس"</string>
@@ -1117,9 +1135,9 @@
     <string name="whichApplication" msgid="4533185947064773386">"إكمال الإجراء باستخدام"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"تحديد تطبيق الشاشة الرئيسية"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"الاستخدام بشكل افتراضي لهذا الإجراء."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"يمكنك محو الإعدادات الافتراضية في إعدادات النظام &gt; التطبيقات &gt; ما تم تنزيله."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"‏يمكنك محو الإعدادات الافتراضية في إعدادات النظام &gt; التطبيقات &gt; ما تم تنزيله."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"اختيار إجراء"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"اختيار أحد التطبيقات لجهاز USB"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"‏اختيار أحد التطبيقات لجهاز USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"ليست هناك تطبيقات يمكنها تنفيذ هذا الإجراء."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
     <string name="aerr_application" msgid="932628488013092776">"للأسف، توقف <xliff:g id="APPLICATION">%1$s</xliff:g>."</string>
@@ -1138,10 +1156,10 @@
     <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="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>
@@ -1174,23 +1192,23 @@
     <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>
+    <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>
+    <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="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" 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 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 المباشر"</string>
+    <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"‏اتصال Wi-Fi مباشر"</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 المباشر"</string>
     <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"المس للحصول على الإعدادات"</string>
     <string name="accept" msgid="1645267259272829559">"قبول"</string>
     <string name="decline" msgid="2112225451706137894">"رفض"</string>
@@ -1198,28 +1216,28 @@
     <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">"اكتب رقم التعريف الشخصي المطلوب:"</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="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_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_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_remember_undo_instruction" msgid="4960944133052287484">"‏يمكنك تغيير ذلك لاحقًا من إعدادات &gt; تطبيقات"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"السماح دومًا"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"عدم السماح مطلقًا"</string>
-    <string name="sim_removed_title" msgid="6227712319223226185">"تمت إزالة بطاقة SIM"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"لن تكون شبكة الجوال متاحة حتى تتم إعادة التشغيل وإدخال بطاقة SIM صالحة."</string>
+    <string name="sim_removed_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_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>
@@ -1230,38 +1248,38 @@
     <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 لـ 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 لتخزين كبير السعة عبر USB."</string>
-    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB متصل"</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 لـ 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 لتخزين كبير السعة عبر 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، الغ تحميل (\"أخرج\") وحدة تخزين USB لـ Android من الكمبيوتر."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"قبل إيقاف وحدة تخزين USB، الغ تحميل (\"أخرج\") بطاقة SD لـ Android من الكمبيوتر."</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="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 لـ Android من الكمبيوتر."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"‏قبل إيقاف وحدة تخزين USB، الغ تحميل (\"أخرج\") بطاقة SD لـ Android من الكمبيوتر."</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="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="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>
@@ -1271,29 +1289,29 @@
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</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_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="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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"التفاعل مع نظام التحديث والاسترداد"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"للسماح للتطبيق بالتفاعل مع نظام الاسترداد وتحديثات النظام."</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>
@@ -1329,13 +1349,13 @@
     <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_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_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>
@@ -1359,18 +1379,18 @@
     <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="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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"العالي"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"اختيار تطبيق"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"تعذر تشغيل <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"مشاركة مع"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"مشاركة مع <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"مقبض التمرير. المس مع الاستمرار."</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>
@@ -1435,20 +1447,20 @@
     <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="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">"تم تعطيل بيانات شبكات الجيل الثاني والجيل الثالث"</string>
     <string name="data_usage_4g_limit_title" msgid="7636489436819470761">"تم تعطيل بيانات شبكة الجيل الرابع"</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_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_3g_limit_snoozed_title" msgid="7026739121138005231">"‏تم تجاوز حد بيانات شبكات 2G-3G"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"‏تم تجاوز حد بيانات 4G"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"تم تجاوز حد بيانات الجوال"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"تم تجاوز حد بيانات شبكة Wi-Fi"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"‏تم تجاوز حد بيانات شبكة 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>
@@ -1464,8 +1476,8 @@
     <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="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>
@@ -1483,20 +1495,26 @@
     <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_chooser_title" msgid="1751618554539087622">"الاتصال بجهاز"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"بث الشاشة على الجهاز"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"جارٍ البحث عن الأجهزة…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"الإعدادات"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"قطع الاتصال"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"جارٍ الفحص..."</string>
     <string name="media_route_status_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_hdmi_display_name" msgid="1555264559227470109">"‏شاشة HDMI"</string>
     <string name="display_manager_overlay_display_name" msgid="5142365982271620716">"المركب #<xliff:g id="ID">%1$d</xliff:g>"</string>
-    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>، <xliff:g id="DPI">%4$d</xliff:g> نقطة لكل بوصة"</string>
+    <string name="display_manager_overlay_display_title" msgid="652124517672257172">"‏<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>، <xliff:g id="DPI">%4$d</xliff:g> نقطة لكل بوصة"</string>
     <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">"آمن"</string>
-    <string name="wifi_display_notification_title" msgid="2223050649240326557">"تم التوصيل بشاشة لاسلكية"</string>
-    <string name="wifi_display_notification_message" msgid="4498802012464170685">"يتم عرض هذه الشاشة على جهاز آخر"</string>
+    <string name="wifi_display_notification_connecting_title" msgid="2838646471050359706">"جارٍ بث الشاشة"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"جارٍ الاتصال بـ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"جارٍ بث الشاشة"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"متصل بـ <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1505,27 +1523,27 @@
     <string name="kg_wrong_pin" msgid="1131306510833563801">"رقم تعريف شخصي خاطئ"</string>
     <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"حاول مرة أخرى خلال <xliff:g id="NUMBER">%1$d</xliff:g> ثانية."</string>
     <string name="kg_pattern_instructions" msgid="398978611683075868">"ارسم نقشك"</string>
-    <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"أدخل رقم التعريف الشخصي لبطاقة SIM"</string>
-    <string name="kg_pin_instructions" msgid="2377242233495111557">"أدخل رقم التعريف الشخصي"</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">"إدخال رمز رقم التعريف الشخصي المراد"</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_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="6025069204539532000">"‏يجب أن يتكون رمز 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_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_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_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>
@@ -1635,19 +1653,30 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"خدمة الطباعة ليست ممكّنة"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"تم تثبيت خدمة <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"انقر للتمكين."</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"أدخل رقم التعريف الشخصي للمشرف"</string>
-    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"إدخال رقم التعريف الشخصي"</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">"رقم التعريف الشخصي الحالي"</string>
-    <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"رقم التعريف الشخصي الجديد"</string>
-    <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"تأكيد رقم التعريف الشخصي الجديد"</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">"إنشاء رقم تعريف شخصي لتعديل القيود"</string>
     <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"أرقام التعريف الشخصية لا تتطابق، أعد المحاولة."</string>
-    <string name="restr_pin_error_too_short" msgid="8173982756265777792">"رقم التعريف الشخصي أقصر مما يلزم، يجب ألا يقل عن 4 أرقام. "</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="immersive_mode_confirmation" msgid="7227416894979047467">"مرر بسرعة من أعلى لأسفل للخروج من وضع ملء الشاشة."</string>
+    <string name="done_label" msgid="2093726099505892398">"تم"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"شريط التمرير الدائري للساعات"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"شريط التمرير الدائري للدقائق"</string>
+    <string name="select_hours" msgid="6043079511766008245">"تحديد الساعات"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"تحديد الدقائق"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"شبكة الشهر مكونة من الأيام"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"قائمة الأعوام"</string>
+    <string name="select_day" msgid="7774759604701773332">"تحديد الشهر واليوم"</string>
+    <string name="select_year" msgid="7952052866994196170">"تحديد العام"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"تم تحديد <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"تم حذف <xliff:g id="KEY">%1$s</xliff:g>"</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..479cfcf
--- /dev/null
+++ b/core/res/res/values-az-rAZ/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">"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_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_accessInputFlinger" msgid="5348635270689553857">"InputFlinger keçidi"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Tətbiqə aşağı səviyyəli InputFlinger funksiyalarını istifadə etməyə icazə 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..08e79bb
--- /dev/null
+++ b/core/res/res/values-az/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">"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_accessInputFlinger" msgid="5348635270689553857">"InputFlinger keçidi"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Tətbiqə aşağı səviyyəli InputFlinger funksiyalarını istifadə etməyə icazə 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/donottranslate-cldr.xml b/core/res/res/values-be/donottranslate-cldr.xml
deleted file mode 100755
index cb74942..0000000
--- a/core/res/res/values-be/donottranslate-cldr.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="numeric_date_template">"%s.%s.%s"</string>
-    <string name="month_day_year">%-e %B %Y</string>
-    <string name="time_of_day">%H.%M.%S</string>
-    <string name="date_and_time">%H.%M.%S %-e.%-m.%Y</string>
-    <string name="date_time">%2$s %1$s</string>
-</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
deleted file mode 100644
index ccc2986..0000000
--- a/core/res/res/values-be/strings.xml
+++ /dev/null
@@ -1,1801 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under 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">"Пб"</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">"Ідэнтыфікатар АВН"</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">"Вы не можаце змяніць налады ідэнтыфікатара абанента, якi тэлефануе."</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">"Роўмінг: прэмiум-партнёр"</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">"Памылка ўваходу ва ўлiковы запiс <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>
-    <!-- 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>
-    <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">"Хочаце перазагрузіцца ў бяспечным рэжыме? Гэта дазволіць адключыць усе іншыя ўсталяваныя прыкладанні. Пасля перазагрузкi iх праца будзе адноўлена."</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">"Будзе збiрацца iнфармацыя пра бягучы стан прылады, якая будзе адпраўляцца на электронную пошту. Стварэнне справаздачы пра памылкi зойме некаторы час."</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">"Магчымасць уплываць на паводзіны экрана блакіроўкi на вашай прыладзе."</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">"Функцыi, патрэбныя толькі для распрацоўшчыкаў прыкладанняў."</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-назапашвальнiка."</string>
-    <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Доступ да SD-карты."</string>
-    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Спецыяльныя магчымасці"</string>
-    <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Функцыі, якія могуць запытаць дадатковыя тэхналогii."</string>
-    <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Атрымайце змесцiва акна"</string>
-    <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Вывучыце змесцiва акна, з якiм вы працуеце."</string>
-    <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Уключыце Explore by Touch"</string>
-    <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Элемент, да якiх дакраналiся, могуць быць агучаны, а экран будзе працаваць з жэстамi."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Уключыце паляпшэнне вэб-даступнасці"</string>
-    <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Сцэнарыi могуць быць усталяваны, каб зрабіць змесцiва прыкладання больш даступным."</string>
-    <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Глядзiце, што набiраеце"</string>
-    <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Уключае ў сябе асабістыя дадзеныя, такія як нумары крэдытных карт і паролі."</string>
-    <string name="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>
-    <!-- no translation found for permlab_install_shortcut (4279070216371564234) -->
-    <skip />
-    <!-- no translation found for permdesc_install_shortcut (8341295916286736996) -->
-    <skip />
-    <!-- no translation found for permlab_uninstall_shortcut (4729634524044003699) -->
-    <skip />
-    <!-- no translation found for permdesc_uninstall_shortcut (6745743474265057975) -->
-    <skip />
-    <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"перанакіраванне зыходзячых выклікіаў"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Дазваляе прыкладанням апрацоўваць выходныя выклікі і змяняць набіраны нумар. Дзякуючы гэтаму дазволу прыкладаннi могуць адсочваць, перанакіроўваць ці прадухіляць выходныя выклікі."</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-паведамленнi. Гэта значыць, што прыкладанне можа кантраляваць або выдаляць паведамленні, адпраўленыя на прыладу, не паказваючы іх вам."</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">"адправiць мерапрыемства \"адказ праз паведамленне\""</string>
-    <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"Прыкладанне зможа адпраўляць запыты ў іншыя прыкладанні для апрацоўкі паведамленняў пра мерапрыемствы туы \"рэагаваць-праз-паведамленне\" для ўваходных выклікаў."</string>
-    <string name="permlab_readSms" msgid="8745086572213270480">"чытанне сваiх тэкставых паведамленняў (SMS ці MMS)"</string>
-    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Дазваляе прыкладанню чытаць SMS-паведамленнi, якія захоўваюцца на планшэце ці SIM-карце. Гэта дазваляе прыкладанням чытаць ўсе SMS-паведамленні, незалежна ад змесцiва або прыватнасці."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Дазваляе прыкладанню чытаць SMS-паведамленні, якія захоўваюцца ў тэлефоне або на SIM-карце. Гэта дазваляе прыкладанням чытаць ўсе SMS-паведамленні, незалежна ад змесцiва або прыватнасці."</string>
-    <string name="permlab_writeSms" msgid="3216950472636214774">"рэдагаванне тэкставых паведамленняў (SMS ці MMS)"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"Дазваляе прыкладанню запісваць дадзеныя ў SMS-паведамленні, якія захоўваюцца на планшэце або на SIM-карце. Шкоднасныя прыкладанні могуць выдаляць вашы паведамленні."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"Дазваляе прыкладанням запісваць дадзеныя ў SMS-паведамленні, якія захоўваюцца ў тэлефоне або на 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">"Дазваляе прыкладанню атрымлiваць звесткi пра прыкладаннi, запушчаныя зараз i нядаўна. Прыкладанне можа знайсцi iнфармацыю пра тое, якiя прыкладаннi выкарыстоўваюцца на прыладзе."</string>
-    <string name="permlab_interactAcrossUsers" msgid="7114255281944211682">"узаемадзеянне паміж карыстальнікамі"</string>
-    <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Дазваляе прыкладанню выконваць дзеяннi сярод розных карыстальнiкаў прылады. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб парушыць абарону памiж карыстальнiкамi."</string>
-    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"поўная ліцэнзія для ўзаемадзеяння паміж карыстальнiкамi"</string>
-    <string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Дазваляе ўсе магчымыя ўзаемадзеяннi паміж карыстальнікамі."</string>
-    <string name="permlab_manageUsers" msgid="1676150911672282428">"кіраванне дадзенымi карыстальнікаў"</string>
-    <string name="permdesc_manageUsers" msgid="8409306667645355638">"Дазваляе прыкладанням кіраваць звесткамi карыстальнікаў на прыладзе, у тым ліку запытамi, працэсамi стварэння і выдалення."</string>
-    <string name="permlab_getDetailedTasks" msgid="6229468674753529501">"атрымаць падрабязныя дадзеныя пра запушчаныя прыкладаннi"</string>
-    <string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Дазваляе прыкладанню атрымліваць падрабязную інфармацыю пра бягучыя і нядаўна запушчаныя задачы. Шкоднасныя прыкладанні могуць атрымліваць асабістую інфармацыю пра іншыя прыкладаннi."</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">"Дазваляе прыкладанням выдаляць заданні і спыняць прыкладанні, якія іх выкарыстоўваюць. Шкоднасныя прыкладанн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>
-    <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Дазваляе прыкладанню кіраваць рэжымам сумяшчальнасці экранаў іншых прыкладанняў. Шкоднаснае ПЗ можа перашкодзiць працы іншых прыкладанняў."</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">"Дазваляе прыкладанням змяняць бягучую канфігурацыю, напрыклад мову цi агульны памер шрыфта."</string>
-    <string name="permlab_enableCarMode" msgid="5684504058192921098">"дазваляць рэжым \"У аўтамабілі\""</string>
-    <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Дазваляе прыкладанню ўключаць рэжым гучнай сувязi."</string>
-    <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"закрыццё іншых прыкладанняў"</string>
-    <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Дазваляе прыкладанню завяршаць фонавыя працэсы іншых прыкладанняў. Гэта можа спынiць працу iншых прыкладанняў."</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">"Дазваляе прыкладанню часова ўключаць даступнасць прылады. Шкоднасныя прыкладаннi могуць уключыць даступнасць без згоды карыстальніка."</string>
-    <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"атрымаць звесткi пра акно"</string>
-    <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Дазваляе прыкладанням вымаць iнфармацыю пра вокны з iнструмента кiравання вокнамi. Шкоднасныя прыкладаннi могуць вымаць iнфармацыю, якая прызначана для ўнутранага выкарыстання ў сiстэме."</string>
-    <string name="permlab_filter_events" msgid="8675535648807427389">"фільтр падзей"</string>
-    <string name="permdesc_filter_events" msgid="8006236315888347680">"Дазваляе прыкладанню рэгiстраваць фiльтр уводу, якi перадае паток усiх дзеянняў карыстальнiка, перш чым будуць адпраўленыя звесткi пра iх. Шкоднасныя прыкладаннi могуць кантраляваць iнтэрфейс без умяшальнiцтва."</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">"Дазваляе ўладальніку атрымлiваць асабістую інфармацыю аб бягучым прыкладаннi на пярэднім плане экрана."</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-received"</string>
-    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Дазваляе прыкладанням перадаваць апавяшчэнне, што паведамленне WAP PUSH не было атрымана. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб падрабляць атрыманне MMS-паведамлення або непрыкметна замяняць змесціва любой вэб-старонкі на шкоднасную версiю."</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">"Прыкладанне можа счытваць бягучыя звесткi пры нiзкi зарад акумулятара. Прыкладанне можа знайсцi падрабязную iнфармацы. пра прыкладаннi, якiя вы выкарыстоўваеце."</string>
-    <string name="permlab_updateBatteryStats" msgid="3719689764536379557">"змяняць статыстыку батарэі"</string>
-    <string name="permdesc_updateBatteryStats" msgid="6862817857178025002">"Дазваляе прыкладанням змяняць сабраную статыстыку батарэi. Не патрабуецца для звычайных прыкладанняў."</string>
-    <string name="permlab_getAppOpsStats" msgid="1508779687436585744">"атрымлiваць статыстыку выкарыстання прыкладання"</string>
-    <string name="permdesc_getAppOpsStats" msgid="6243887041577912877">"Дазваляе прыкладанню атрымлiваць сабраную статыстыку выкарыстання прыкладання. Не для выкарыстання звычайнымі прыкладаннямі."</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">"Прыкладанне можа з\'яўляцца паверх iншых прыкладанняў. Яны могуць шкодзiць адно аднаму падчас працы iнтэрфейсаў або змяняць тое, што вы бачыце ў iншых прыкладаннях."</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>
-    <!-- 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>
-    <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>
-    <!-- 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>
-    <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">"Дазваляе прыкладанням запытваць адпраўку падаваемага сігнала для ўсiх пастаянных працэсаў."</string>
-    <string name="permlab_persistentActivity" msgid="8841113627955563938">"прымусіць прыкладанне працаваць заўсёды"</string>
-    <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Дазваляе прыкладанню захоўваць некаторыя пастаянныя часткi ў памяцi. Гэта можа абмежаваць аб\'ём памяці, даступнай для іншых прыкладанняў, i запаволiць працу планшэта."</string>
-    <string name="permdesc_persistentActivity" product="default" msgid="4384760047508278272">"Дазваляе прыкладанню захоўваць некаторыя пастаянныя часткi ў памяцi. Гэта можа абмежаваць аб\'ём памяці, даступнай для іншых прыкладанняў, i запаволiць працу тэлефона."</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. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта, каб дадаваць новыя прыкладаннi з дазволамі адвольнай ступені."</string>
-    <string name="permlab_clearAppCache" msgid="7487279391723526815">"выдаліць усе дадзеныя з кэш-памяці прыкладання"</string>
-    <string name="permdesc_clearAppCache" product="tablet" msgid="8974640871945434565">"Прыкладанне дазваляе вызваляць сховiшча планшэта, выдаляючы файлы з дырэкторый кэша iншых прыкладанняў. Гэта можа прывесцi да таго, што iншыя прыкладаннi пачнуць працаваць павольней, таму што iм трэба будзе паўторна атрымлiваць свае дадзеныя."</string>
-    <string name="permdesc_clearAppCache" product="default" msgid="2459441021956436779">"Прыкладанне дазваляе вызваляць сховiшча тэлефона, выдаляючы файлы з дырэкторый кэша iншых прыкладанняў. Гэта можа прывесцi да таго, што iншыя прыкладаннi пачнуць працаваць павольней, таму што iм трэба будзе паўторна атрымлiваць свае дадзеныя."</string>
-    <string name="permlab_movePackage" msgid="3289890271645921411">"перамясціць рэсурсы прыкладання"</string>
-    <string name="permdesc_movePackage" msgid="319562217778244524">"Дазваляе прыкладанням перамяшчаць рэсурсы прыкладання з унутраных на знешнія носьбіты і наадварот."</string>
-    <string name="permlab_readLogs" msgid="6615778543198967614">"чытаць канфідэнцыйныя дадзеныя дзённiка"</string>
-    <string name="permdesc_readLogs" product="tablet" msgid="82061313293455151">"Дазваляе прыкладанням счытваць розныя файлы сiстэмнай гiсторыi. Такiм чынам, можна выявiць агульную інфармацыю пра тое, што вы робіце з планшэтам, у тым ліку, магчыма, асабістыя або канфiдэнцыйныя звесткi."</string>
-    <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>
-    <string name="permdesc_changeComponentState" product="tablet" msgid="8887435740982237294">"Дазваляе прыкладанням змяняць вызначэнне таго, будзе ўключаны кампанент іншага прыкладання ці не. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў планшэта. З гэтым дазволам трэба быць уважлівым, бо можна прывесці кампаненты прыкладання ў непрыдатны, супярэчлівы або няўстойлівы стан."</string>
-    <string name="permdesc_changeComponentState" product="default" msgid="1827232484416505615">"Дазваляе прыкладанням змяняць вызначэнне таго, будзе ўключаны кампанент іншага прыкладання ці не. Шкоднасныя прыкладанні могуць выкарыстоўваць гэта для адключэння важных магчымасцяў тэлефона. З гэтым дазволам трэба быць уважлівым, бо можна прывесці кампаненты прыкладання ў непрыдатны, супярэчлівы або няўстойлівы стан."</string>
-    <string name="permlab_grantRevokePermissions" msgid="4627315351093508795">"прадаставiць або адмяніць дазвол"</string>
-    <string name="permdesc_grantRevokePermissions" msgid="4088642654085850662">"Дазваляе прыкладанню прадастаўляць або адмяняць пэўныя дазволы для гэтага або іншых прыкладанняў. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб атрымаць доступ да функцый, якiя вы iм не прадаставiлi."</string>
-    <string name="permlab_setPreferredApplications" msgid="8463181628695396391">"усталяваць пажаданыя прыкладанні"</string>
-    <string name="permdesc_setPreferredApplications" msgid="4973986762241783712">"Дазваляе прыкладанням змяняць вашы пажаданыя прыкладанні. Шкоднасныя прыкладанні могуць непрыкметна змяняць запушчаныя прыкладанні, падмяняючы існуючыя прыкладанні, каб збiраць вашы асабістыя дадзеныя."</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">"адпраўляць нетэрмiновую рассылку"</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">"Дазваляе прыкладанням счытваць дадзеныя аб кантактах, якія захоўваюцца на планшэце, у тым ліку звесткi пра тое, як часта вы выклiкалi канкрэтных абанентаў, пiсалi iм па электроннай пошце або кантактавалi іншымi спосабамі. Дзякуючы гэтаму дазволу прыкладаннi могуць захоўваць дадзеныя гiсторыi выклiкаў, а шкоднасныя прыкладаннi могуць адпраўляць кантактныя дадзеныя без вашага ведама."</string>
-    <string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"Дазваляе прыкладанням счытваць дадзеныя аб кантактах, якія захоўваюцца на тэлефоне, у тым ліку звесткi пра частату, з якой вы выклiкалi iх, пiсалi iм па электроннай пошце ці кантактавалi іншым спосабам. Дзякуючы гэтаму дазволу прыкладаннi могуць захоўваць дадзеныя гiсторыi выклiкаў, а шкоднасныя прыкладаннi могуць адпраўляць кантактныя дадзеныя без вашага ведама."</string>
-    <string name="permlab_writeContacts" msgid="5107492086416793544">"змена кантактаў"</string>
-    <string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"Дазваляе прыкладанням змяняць дадзеныя аб кантактах, якія захоўваюцца на планшэце, у тым ліку частата, з якой вы выклiкалi асоб, пiсалi па электроннай пошце ці іншым спосабам кантактавалi з iмі. З гэтым дазволам прыкладаннi змогуць выдаляць кантактныя дадзеныя."</string>
-    <string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"Дазваляе прыкладанням змяняць дадзеныя аб кантактах, якія захоўваюцца на тэлефоне, у тым ліку частата, з якой вы выклiкалi асоб, пiсалi па электроннай пошце ці іншым спосабам кантактавалi з iмі. З гэтым дазволам прыкладаннi змогуць выдаляць кантактныя дадзеныя."</string>
-    <string name="permlab_readCallLog" msgid="3478133184624102739">"чытанне гiсторыi выклікаў"</string>
-    <string name="permdesc_readCallLog" product="tablet" msgid="3700645184870760285">"Дазваляе прыкладанням чытаць гiсторыю выклiкаў планшэта, у тым лiку дадзеныя пра ўваходныя i выходныя выклiкi. Дзякуючы гэтаму дазволу прыкладаннi могуць захоўваць дадзеныя гiсторыi выклiкаў, а шкоднасныя прыкладаннi могуць адпраўляць гiсторыю выклiкаў без вашага ведама."</string>
-    <string name="permdesc_readCallLog" product="default" msgid="5777725796813217244">"Дазваляе прыкладанням чытаць гiсторыю выклiкаў тэлефона, у тым лiку дадзеныя пра ўваходныя i выходныя выклiкi. Дзякуючы гэтаму дазволу прыкладаннi могуць захоўваць дадзеныя гiсторыi выклiкаў, а шкоднасныя прыкладаннi могуць адпраўляць гiсторыю выклiкаў без вашага ведама."</string>
-    <string name="permlab_writeCallLog" msgid="8552045664743499354">"запіс гiсторыi выклікаў"</string>
-    <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Дазваляе прыкладанню змяняць гiсторыю выклiкаў планшэта, у тым лiку дадзеныя пра ўваходныя i зыходныя выклiкi. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб выдаляць або змяняць гiсторыю выклікаў."</string>
-    <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Дазваляе прыкладанням змяняць гiсторыю выклiкаў тэлефону, у тым лiку дадзеныя пра ўваходныя і зыходныя выклiкi. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб выдаляць або змяняць гiсторыю выклікаў."</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">"Дазваляе прыкладанню атрымлiваць доступ да абнаўленняў у сацыяльных службах ад вас і вашых сяброў. Будзьце асцярожны падчас адпраўкi iнфармацыi – гэта дазваляе прыкладанню чытаць сувязі паміж вамі і вашымі сябрамі ў сацыяльных сетках, незалежна ад прыватнасці. Увага: гэты дазвол не распаўсюджваецца на ўсе сацыяльныя сеткi."</string>
-    <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"запісаць у мой паток абнаўленняў"</string>
-    <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Дазваляе прыкладанню адлюстроўваць абнаўленнi  ад вашых сяброў у сацыяльных службах. Будзьце асцярожны падчас абмену iнфармацыяй: гэта прыкладанне адпраўляе паведамленнi, якiя падобны на тое, што iх даслалi сябры. Увага: гэты дазвол не распаўсюджваееца на ўсе сацыяльныя сеткi."</string>
-    <string name="permlab_readCalendar" msgid="5972727560257612398">"чытаць падзеі календара, а таксама прыватную інфармацыю"</string>
-    <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Дазваляе прыкладанню чытаць усе мерапрыемствы з календара, захаваныя на вашым планшэце, у тым ліку з сябрамi або калегамi. Гэта дазваляе прыкладанню адпраўляць дадзеныя календара, нягледзячы на прыватнасць i адчувальнасць."</string>
-    <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Дазваляе прыкладанню чытаць усе мерапрыемствы з календара, захаваныя на вашым тэлефоне, у тым ліку з сябрамi або калегамi. Гэта дазваляе прыкладанню адпраўляць дадзеныя календара, нягледзячы на прыватнасць i адчувальнасць."</string>
-    <string name="permlab_writeCalendar" msgid="8438874755193825647">"дадаваць ці змяняць падзеі календара і адпраўляць электронную пошту да гасцей без ведама ўладальнікаў"</string>
-    <string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"Дазваляе прыкладанню дадаваць, выдаляць, змяняць мерапрыемствы, якія можна рэдагаваць на планшэце, у тым ліку сустрэчы с сябрамi i калегамi. Гэта дазваляе прыкладанню адпраўляць паведамленні ад уладальнiкаў календароў або змяняць мерапрыемствы без ведама уладальнiкаў."</string>
-    <string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"Дазваляе прыкладанню дадаваць, выдаляць, змяняць мерапрыемствы, якія можна рэдагаваць на тэлефоне, у тым ліку сустрэчы с сябрамi i калегамi. Гэта дазваляе прыкладанню адпраўляць паведамленні ад уладальнiкаў календароў або змяняць мерапрыемствы без ведама уладальнiкаў."</string>
-    <string name="permlab_accessMockLocation" msgid="8688334974036823330">"макет крыніц месцазнаходжання для тэставання"</string>
-    <string name="permdesc_accessMockLocation" msgid="5808711039482051824">"Стварыць макет крыніц месцазнаходжання для тэставання і ўсталёўкі новага правайдара месцазнаходжання. Гэта дазваляе прыкладанню перавызначыць месцазнаходжанне і/або статус, вернуты іншымi крыніцамi, напрыклад геапазiцыйнай службай i правайдарамi месцазнаходжання."</string>
-    <string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"доступ да дадатковых камандаў пастаўшчыка месцазнаходжання"</string>
-    <string name="permdesc_accessLocationExtraCommands" msgid="5945166642335800763">"Дазваляе прыкладанням атрымліваць доступ да дадатковых каманд правайдара месцазнаходжання. Гэта можа дазволiць прыкладанню ўмешвацца ў працу GPS або іншых крыніц месцазнаходжання."</string>
-    <string name="permlab_installLocationProvider" msgid="6578101199825193873">"дазвол на ўсталяванне пастаўшчыка месцазнаходжання"</string>
-    <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Стварыць макет крыніц месцазнаходжання для тэставання і ўсталёўкі новага правайдара месцазнаходжання. Гэта дазваляе прыкладанню перавызначыць месцазнаходжанне і/або статус, вернуты іншымi крыніцамi, напрыклад геапазiцыйнай службай i правайдарамi месцазнаходжання."</string>
-    <string name="permlab_accessFineLocation" msgid="1191898061965273372">"дакладнае месцазнаходжанне (на аснове GPS і сеткі)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Дазваляе прыкладанню вызначаць дакладнае месцазнаходжанне з дапамогай GPS або сеткавых крынiц месцазнаходжання, напрыклад веж сотавай сувязi i Wi-Fi. Гэтыя службы вызначэння месцазнаходжання павiнны быць уключаны i даступныя для вашай прылады i прыкладання. Прыкладаннi могуць выкарыстоўваць гэта, каб вызначаць ваша прыблiзнае месцазнаходжанне, а таксама спажываць дадатковае сiлкаванне."</string>
-    <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"прыблізнае месцазнаходжанне (па дадзеных сеткі)"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Дазваляе прыкладанню вызначаць прыблiзнае месцазнаходжанне. Гэта месцазнаходжанне вызначаецца спецыяльнымi службамi з выкарыстаннем сеткавых крынiц месцазнаходжання, напрыклад веж сотавай сувязi i Wi-Fi. Службы вызначэння месцазнаходжання павiнны быць уключаны i даступныя для вашай прылады i прыкладання. Прыкладаннi могуць выкарыстоўваць гэта, каб вызначаць ваша прыблiзнае месцазнаходжанне."</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">"налада дысплеяў Wi-Fi"</string>
-    <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 />
-    <!-- no translation found for permlab_mediaContentControl (8749790560720562511) -->
-    <skip />
-    <!-- no translation found for permdesc_mediaContentControl (1637478200272062) -->
-    <skip />
-    <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">"Дазваляе прыкладанню запісваць аўдыё з дапамогай мікрафона. Дзякуючы гэтаму дазволу прыкладаннi могуць запiсваць аўдыё ў любы час без вашага пацвярджэння."</string>
-    <string name="permlab_camera" msgid="3616391919559751192">"рабіць фатаграфіі і відэа"</string>
-    <string name="permdesc_camera" msgid="8497216524735535009">"Дазваляе прыкладанню рабiць фотаздымкi і здымаць відэа з дапамогай камеры. Дзякуючы ггэтаму дазволу прыкладанне можа ў любы час выкарыстоўваць камеру без вашага пацверджання."</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">"Дазваляе прыкладанням фарматаваць здымны назапашвальнiк."</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">"Дазваляе прыкладанням падлучаць i адлучаць унутраную памяць."</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">"Дазваляе прыкладанням званiць на тэлефонныя нумары без вашага ўмяшання. Гэта можа прывесці да нечаканага спагнання сродкаў або званкоў. Звярніце ўвагу, што прыкладанне не можа рабiць экстраныя выклікi. Шкоднасныя прыкладаннi могуць спаганяць з вас сродкi, робячы званкі без вашага пацверджання."</string>
-    <string name="permlab_callPrivileged" msgid="4198349211108497879">"непасрэдна выклікаць любыя тэлефонныя нумары"</string>
-    <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Дазваляе прыкладанню тэлефанаваць на любы тэлефонны нумар, у тым лiку на экстраныя нумары, без вашага ведама. Шкоднасныя прыкладанні могуць рабіць непатрэбныя і незаконныя экстраныя выклікі."</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">"Дазваляе прыкладанням уключаць i адключаць апавяшчэннi аб абнаўленні месцазнаходжання ад радыё. Не для выкарыстання звычайнымі прыкладаннямі."</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">"Дазваляе прыкладанням атрымлiваць доступ да функцый тэлефона на прыладзе. Дзякуючы гэтаму дазволу прыкладанне можа вызначаць iдэнтыфiкатары нумару тэлефона i прылады, незалежна ад таго, цi актыўны выклiк, i аддалены нумар, на якi робiцца выклiк."</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">"Дазваляе прыкладанням ксталёўваць сiстэмныя шпалеры."</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">"Дазваляе прыкладанню атрымлiваць спіс уліковых запісаў, вядомых планшэту. Сярод iх могуць быць улiковыя запiсы, створаныя прыкладаннямi, якiя вы ўсталявалi."</string>
-    <string name="permdesc_getAccounts" product="default" msgid="3448316822451807382">"Дазваляе прыкладанню атрымлiваць спіс уліковых запісаў, вядомых тэлефону. Сярод iх могуць быць улiковыя запiсы, створаныя прыкладаннямi, якiя вы ўсталявалi."</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">"Дазваляе прыкладанню праглядаць звесткi пра падключэннi да сеткi, напрыклад пра тое, якiя сеткi iснуюць i з якiмi ёсць сувязь."</string>
-    <string name="permlab_createNetworkSockets" msgid="8018758136404323658">"поўны доступ да сеткі"</string>
-    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"Дазваляе прыкладанням ствараць сеткавыя сокеты і выкарыстоўваць уласныя сеткавыя пратаколы. браўзер і іншыя прыкладаннi прадастаўляюць сродкі для перадачы дадзеных у Iнтэрнэт, так што гэты дазвол для перадачы дадзеных у Iнтэрнэце не патрабуецца."</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">"Дазваляе прыкладанню праглядаць звесткi пра падключэннi да сеткi, напрыклад пра тое, дзе ёсць сеткi Wi-Fi i якiя прылады Wi-Fi да iх падключаны."</string>
-    <string name="permlab_changeWifiState" msgid="6550641188749128035">"падключэнне да сеткі Wi-Fi і адключэнне ад яе"</string>
-    <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Дазваляе прыкладанням падключацца да кропак доступу Wi-Fi і адключацца ад iх, а таксама ўносіць змяненні ў канфiгурацыю прылад сеткі Wi-Fi."</string>
-    <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"дазваляе прыём Wi-Fi Multicast"</string>
-    <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Дазваляе прыкладанням атрымліваць пакеты, адпраўленыя на ўсе прылады з сеткi Wi-Fi з дапамогай групавых адрасоў, а не толькі на ваш планшэт. Будзе выкарыстоўвацца больш энергіі, чым у рэжыме нешматадраснай перадачы."</string>
-    <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Дазваляе прыкладанням атрымліваць пакеты, адпраўленыя на ўсе прылады з сеткi 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, а таксама знаходзіць выдаленыя прылады i падлучацца да ix."</string>
-    <!-- no translation found for permlab_bluetoothPriv (4009494246009513828) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetoothPriv (8045735193417468857) -->
-    <skip />
-    <!-- no translation found for permdesc_bluetoothPriv (8045735193417468857) -->
-    <skip />
-    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"падключаць да WiMAX i адключаць ад яго"</string>
-    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"Дазваляе прыкладанню вызначаць, ці ўключаны WiMAX, і інфармацыю пра любую сетку WiMAX, якая спалучана з iншымi."</string>
-    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"Змяніць стан WiMAX"</string>
-    <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Дазваляе прыкладанням падключаць планшэт да сеткі WiMAX i адключаць яго ад яе."</string>
-    <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Дазваляе прыкладанням падключацца да сетак WiMAX і адключацца ад iх."</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">"Дазваляе прыкладаннzv спалучацца з тэгамі, картамі і счытваючымі прыладамі Near Field Communication (NFC)."</string>
-    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"адключэнне блакiроўкi экрана"</string>
-    <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дазваляе прыкладанням адключаць блакiроўку клавіятуры і любыя сродкі абароны, звязаныя з паролем. Прыкладам гэтага з\'яўляецца адключэнне тэлефонам блакiроўкi клавіятуры пры атрыманні ўваходнага выкліку і паўторнае ўключэнне блакiроўкi клавіятуры, калі выклік завершаны."</string>
-    <string name="permlab_readSyncSettings" msgid="6201810008230503052">"чытаць параметры сінхранізацыі"</string>
-    <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Дазваляе прыкладанням чытаць параметры сінхранізацыі для ўліковага запісу. Напрыклад, яны могуць вызначыць, цi сiнхранiзавана з улiковым запiсам прыкладанне \"Кантакты\"."</string>
-    <string name="permlab_writeSyncSettings" msgid="5408694875793945314">"уключэнне ці адключэнне сінхранізацыi"</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">"Дазваляе прыкладанням змяняць бягучыя каналы сінхранізавання. Шкоднасныя прыкладанні могуць змяняць вашы каналы сінхранізацыi."</string>
-    <string name="permlab_readDictionary" msgid="4107101525746035718">"чытанне тэрмінаў, дададзеных у слоўнік"</string>
-    <string name="permdesc_readDictionary" msgid="659614600338904243">"Дазваляе прыкладанням счытваць любыя словы, імёны і фразы, якія карыстальнік можа захоўваць у карыстальніцкім слоўніку."</string>
-    <string name="permlab_writeDictionary" msgid="2183110402314441106">"Даданне слоў у карыстальнiцкі слоўнік"</string>
-    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Дазваляе прыкладанням запісваць новыя словы ў карыстальніцкі слоўнік."</string>
-    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"чытанне змесціва USB-назапашв."</string>
-    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"чытанне змесціва SD-карты"</string>
-    <!-- no translation found for permdesc_sdcardRead (3446988712598386079) -->
-    <skip />
-    <!-- no translation found for permdesc_sdcardRead (2607362473654975411) -->
-    <skip />
-    <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">"Дазваляе ўсiм карыстальнiкам прыкладання атрымлiваць доступ да знешнега сховiшча"</string>
-    <string name="permlab_cache_filesystem" msgid="5656487264819669824">"доступ да файлавай сістэмы кэша"</string>
-    <string name="permdesc_cache_filesystem" msgid="5578967642265550955">"Дазваляе прыкладанню счытваць і выконваць запіс у файлавую сістэму кэш-памяці."</string>
-    <string name="permlab_use_sip" msgid="5986952362795870502">"рабіць/прымаць iнтэрнэт-выклікі"</string>
-    <string name="permdesc_use_sip" msgid="4717632000062674294">"Дазваляе прыкладанням выкарыстоўваць службу SIP, каб прымаць/рабіць Інтэрнэт-выклікі."</string>
-    <!-- no translation found for permlab_bind_call_service (6724009726671246551) -->
-    <skip />
-    <!-- no translation found for permdesc_bind_call_service (8732547662442572435) -->
-    <skip />
-    <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>
-    <!-- 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>
-    <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">"Усталяваць глабальны проксі-cервер прылады, які будзе выкарыстоўвацца, калі палітыка актыўная. Толькі першы адміністратар прылады ўсталёўвае эфектыўныя глабальныя проксі-серверы."</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">"Адключэнне функцыі блакiроўкi клавiятуры"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Прадухіленне выкарыстання некаторых функцый падчас блакiроўкi."</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>
-    <!-- no translation found for imProtocolGoogleTalk (493902321140277304) -->
-    <skip />
-    <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">"Кнопка папярэдняй кампазiцыi"</string>
-    <string name="lockscreen_transport_next_description" msgid="6089297650481292363">"Кнопка наступнай кампазiцыi"</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">"Глядзіце \"Інструкцыю для карыстальніка\" або звяжыцеся са службай тэхн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_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>
-    <string name="lockscreen_failed_attempts_now_wiping" product="default" msgid="3025504721764922246">"Вы няправільна спрабавалі разблакаваць тэлефон некалькi разоў (<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. В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="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Вы ўпэўнены, што хочаце пак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>
-    <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">"чытанне вэб-закладак і гісторыi"</string>
-    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"Дазваляе прыкладанню счытваць усе URL-адрасы, якiя былi наведаны ў браўзеры, а таксама ўсе закладкi. Увага: гэты дазвол нельга ажыццяўляць пабочнымi браўзерамi або iншымi прыкладаннямi з уласцiвасцямi браўзера."</string>
-    <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"запіс вэб-закладак і гісторыi"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"Дазваляе прыкладанням змяняць гісторыю браўзера або закладкі, якiя захоўваюцца на планшэце. Гэта можа дазволіць прыкладанню выдаляць або змяняць дадзеныя браўзера. Увага: гэты дазвол не распаўсюджваецца на пабочныя браўзеры i iншыя прыкладаннi з функцыямi браўзера."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"Дазваляе прыкладанню змяняць гісторыю браўзера, і закладкі, захаваныя ў тэлефоне. Гэта дазволіць прыкладанню выдаляць або змяняць дадзеныя браўзера. Увага: гэты дазвол можа не дзейнiчаць для іншых браўзераў і іншых прыкладанняў з магчымасцямі вэб-браўзера."</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 SerialManager."</string>
-    <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"знешнi доступ да кантэнт-правайдэраў"</string>
-    <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Дае ўладальніку доступ да кантэнт-правайдэраў з абалонкi. Не патрабуецца для звычайных прыкладанняў."</string>
-    <string name="permlab_updateLock" msgid="3527558366616680889">"адмянiць аўтаматычнае абнаўленне прылад"</string>
-    <string name="permdesc_updateLock" msgid="1655625832166778492">"Дазваляе ўладальніку адпраўляць у сiстэму звесткi пра тое, калі будзе зручны час для неінтерактыўнага перазапуску ў мэтах абнаўлення прылады."</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">"Уключыць функцыю 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> запытвае ўключэнне функцыі Explore by Touch. Калі функцыя Explore by Touch будзе ўключаная, вы зможаце пачуць або ўбачыць апісанні таго, што знаходзіцца пад вашым пальцам, або выконваць жэсты для ўзаемадзеяння з планшэтам."</string>
-    <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"Служба доступу <xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> запытвае ўключэнне функцыі Explore by Touch. Калі функцыя Explore by Touch будзе ўключаная, вы зможаце пачуць або ўбачыць апісанні таго, што знаходзіцца пад вашым пальцам, або выконваць жэсты для ўзаемадзеяння з тэлефонам."</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 хвiлiну таму"</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">"Выдалiць"</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>
-    <!-- no translation found for whichHomeApplication (4616420172727326782) -->
-    <skip />
-    <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">"Рынгтон па змаўчаннi"</string>
-    <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Рынгтон па змаўчаннi (<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">"Увайдзіце ў сетку Wi-Fi"</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">"Тэлефон будзе часова адключаны ад сеткі 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; хоча адправiць паведамленне на адрас &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">"можа прывесцi да дадатковых выдаткаванняў"</font>" з вашага мабiльнага ўлiковага запiсу."</string>
-    <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Гэта стане прычынай дадатковага спагнання сродкаў з вашага мабiльнага ўлiковага запiсу."</font></string>
-    <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Адправiць"</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">"Пазней гэта можна змянiць у раздзеле \"Налады &gt; Прыкладаннi\""</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">"Унiверсальны 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-карту прылады Android і наадварот."</string>
-    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Уключыць USB-назапашвальнiк"</string>
-    <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Паўстала праблема з выкарыстаннем USB-назапашвальнiка ва ўнiверсальным USB-назапашвальнiку."</string>
-    <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Паўстала праблема выкарыстання SD-карты ва ўнiверсальным USB-назапашвальнiку."</string>
-    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB падключаны"</string>
-    <string name="usb_storage_notification_message" msgid="939822783828183763">"Дакраніцеся, каб капіяваць файлы з камп\'ютара цi на яго."</string>
-    <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Выключыць USB-назапашвальнiк"</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-назапашвальнік, адключыце(\"вымiце\") USB-назапашвальнік прылады Android ад камп\'ютара."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Перш чым адключыць USB-назапашвальнік, адключыце(\"вымiце\") SD-карту вашай прылады Android з камп\'ютара."</string>
-    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Адключыць USB-назапашвальнiк"</string>
-    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Памылка адключэння USB-назапашвальніка. Пераканайцеся, што вы адключылі хост USB, а потым паўтарыце спробу."</string>
-    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Падключыць USB-назапашвальнiк"</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-назапашвальнiк?"</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-назапашвальнiка"</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-назапашвальнiк"</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-назапашвальнiк"</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-назапашвальнiк нечакана быў выдалены"</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-назапашвальнiк, перш чым выцягваць яго, каб пазбегнуць страты дадзеных."</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">"Вы можаце бяспечна выдалiць USB-назапашвальнiк."</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-назапашвальнiк выдалены"</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-назапашвальнiк выдалены. Уставіць новыя носьбіты."</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">"Дазваляе прыкладанням маршрутызаваць мультымедыйны выхад на 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>
-    <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>\". Дакраніцеся, каб кiраваць сеткай."</string>
-    <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Падключэнне заўсёды ўключанага VPN..."</string>
-    <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Заўсёды ўключаны i падключаны 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">"USB-мадэм або кропка доступу Wi-Fi актыўныя"</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">"Націсніце, каб атрымаць дадатковыя звесткі аб выкарыстанні мабiльнай перадачы дадзеных."</string>
-    <string name="throttled_notification_title" msgid="6269541897729781332">"Ліміт мабільнай перадачы дадзеных перавышаны"</string>
-    <string name="throttled_notification_message" msgid="5443457321354907181">"Націсніце, каб атрымаць дадатковыя звесткі аб выкарыстанні мабiльнай перадачы дадзеных."</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-назапашвальнiка..."</string>
-    <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Адключэнне SD-карты..."</string>
-    <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Выдаленне дадзеных з USB-назапашвальнiка..."</string>
-    <string name="progress_erasing" product="default" msgid="6596988875507043042">"Выдаленне дадзеных з SD-карты..."</string>
-    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Немагчыма ачысцiць USB-назапашвальнік."</string>
-    <string name="format_error" product="default" msgid="7315248696644510935">"Немагчыма ачысцiць SD-карту."</string>
-    <string name="media_bad_removal" msgid="7960864061016603281">"SD-карта была вынутая да адключэння"</string>
-    <string name="media_checking" product="nosdcard" msgid="418188720009569693">"Зараз USB-назапашвальнiк правяраецца."</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-назапашвальнiк выкарыстоўваецца кампутарам."</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">"Знайсці нiжэй"</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">"Запыт ад карыстальнiка <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">"Выдалена элементаў для тыпу сінхранiзацыi \"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>\": <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</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">"Усталяваць час пасля паўдня"</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">"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">"Адправiць з дапамогай прыкладання <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">"Каб праслухаць паролi, падключыце гарнiтуру."</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">"Запусцiць браўзер?"</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">"Дынамікі станцыi"</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">"Сканiраванне..."</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>
-    <!-- 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>
-    <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">%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>
-    <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="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="5739463249673727736">"Гэта прыкладанне не падтрымлівае ўліковыя запісы для профiляў з абмежаваннямі"</string>
-    <string name="app_not_found" msgid="3429141853498927379">"Прыкладанне для гэтага дзеяння не знойдзенае"</string>
-    <string name="revoke" msgid="5404479185228271586">"Ануляваць"</string>
-    <!-- no translation found for mediasize_iso_a0 (1994474252931294172) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a1 (3333060421529791786) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a2 (3097535991925798280) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a3 (3023213259314236123) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a4 (231745325296873764) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a5 (3484327407340865411) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a6 (4861908487129577530) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a7 (5890208588072936130) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a8 (4319425041085816612) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a9 (4882220529506432008) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_a10 (2382866026365359391) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b0 (3651827147402009675) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b1 (6072859628278739957) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b2 (1348731852150380378) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b3 (2612510181259261379) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b4 (695151378838115434) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b5 (4863754285582212487) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b6 (5305816292139647241) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b7 (531673542602786624) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b8 (9164474595708850034) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b9 (282102976764774160) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_b10 (4517141714407898976) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c0 (3103521357901591100) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c1 (1231954105985048595) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c2 (927702816980087462) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c3 (835154173518304159) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c4 (5095951985108194011) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c5 (1985397450332305739) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c6 (8147421924174693013) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c7 (8993994925276122950) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c8 (6871178104139598957) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c9 (7983532635227561362) -->
-    <skip />
-    <!-- no translation found for mediasize_iso_c10 (5040764293406765584) -->
-    <skip />
-    <!-- no translation found for mediasize_na_letter (2841414839888344296) -->
-    <skip />
-    <!-- no translation found for mediasize_na_gvrnmt_letter (5295836838862962809) -->
-    <skip />
-    <!-- no translation found for mediasize_na_legal (8621364037680465666) -->
-    <skip />
-    <!-- no translation found for mediasize_na_junior_legal (3309324162155085904) -->
-    <skip />
-    <!-- no translation found for mediasize_na_ledger (5567030340509075333) -->
-    <skip />
-    <!-- no translation found for mediasize_na_tabloid (4571735038501661757) -->
-    <skip />
-    <!-- no translation found for mediasize_na_index_3x5 (5182901917818625126) -->
-    <skip />
-    <!-- no translation found for mediasize_na_index_4x6 (7687620625422312396) -->
-    <skip />
-    <!-- no translation found for mediasize_na_index_5x8 (8834215284646872800) -->
-    <skip />
-    <!-- no translation found for mediasize_na_monarch (213639906956550754) -->
-    <skip />
-    <!-- no translation found for mediasize_na_quarto (835778493593023223) -->
-    <skip />
-    <!-- no translation found for mediasize_na_foolscap (1573911237983677138) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_roc_8k (3626855847189438896) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_roc_16k (9182191577022943355) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_1 (4793232644980170500) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_2 (5404109730975720670) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_3 (1335092253339363526) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_4 (9167997800486569834) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_5 (845875168823541497) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_6 (3220325667692648789) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_7 (1776792138507038527) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_8 (1417176642687456692) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_9 (4785983473123798365) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_10 (7847982299391851899) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_prc_16k (262793383539980677) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_om_pa_kai (5256815579447959814) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_om_dai_pa_kai (7336412963441354407) -->
-    <skip />
-    <!-- no translation found for mediasize_chinese_om_jurro_ku_kai (6324465444100490742) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b10 (1787262845627694376) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b9 (3336035783663287470) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b8 (6195398299104345731) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b7 (1674621886902828884) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b6 (4170576286062657435) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b5 (4899297958100032533) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b4 (4213158129126666847) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b3 (8513715307410310696) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b2 (4777690211897131190) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b1 (4608142385457034603) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_b0 (7587108366572243991) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_jis_exec (5244075432263649068) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_chou4 (4941652015032631361) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_chou3 (6387319169263957010) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_chou2 (1299112025415343982) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_hagaki (8070115620644254565) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_oufuku (6049065587307896564) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_kahu (6872696027560065173) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_kaku2 (2359077233775455405) -->
-    <skip />
-    <!-- no translation found for mediasize_japanese_you4 (2091777168747058008) -->
-    <skip />
-    <!-- no translation found for mediasize_unknown_portrait (3088043641616409762) -->
-    <skip />
-    <!-- no translation found for mediasize_unknown_landscape (4876995327029361552) -->
-    <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 reason_service_unavailable (7824008732243903268) -->
-    <skip />
-    <!-- no translation found for print_service_installed_title (2246317169444081628) -->
-    <skip />
-    <!-- no translation found for print_service_installed_message (5897362931070459152) -->
-    <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 immersive_mode_confirmation (7227416894979047467) -->
-    <!-- no translation found for immersive_mode_confirmation (8554991488096662508) -->
-    <skip />
-</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 99ba922..691aff26 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Въведете PUK код с поне осем цифри."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM картата ви е заключена с PUK. Въведете PUK кода, за да я отключите."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Въведете PUK2, за да отблокирате SIM картата."</string>
+    <string name="enablePin" msgid="209412020907207950">"Неуспешно – активирайте заключването на SIM/RUIM картата."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Остава ви <xliff:g id="NUMBER">%d</xliff:g> опит, преди SIM картата да бъде заключена."</item>
+    <item quantity="other" msgid="7530597808358774740">"Остават ви <xliff:g id="NUMBER">%d</xliff:g> опита, преди SIM картата да бъде заключена."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Идентификация на вх. обаждания"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"деинсталиране на преки пътища"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Разрешава на приложението да премахва преки пътища от началния екран без намеса на потребителя."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"пренасочване на изходящите обаждания"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Разрешава на приложението да обработва изходящите обаждания и да променя номера, който да се набере. Това разрешение му позволява да наблюдава, пренасочва или не допуска изходящи обаждания."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Разрешава на приложението да вижда набирания номер по време на изходящо обаждане и му дава възможност да пренасочи обаждането към друг номер или да го прекрати изцяло."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"свързване с отдалечен екран"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Разрешава на притежателя да се свърже с интерфейса от първо ниво на отдалечен екран. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"обвързване с услуга за приспособления"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Разрешава на притежателя да се обвърже с интерфейса от най-високото ниво на услуга за приспособления. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаимодействие с администратор на устройството"</string>
@@ -416,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Разрешава на приложението да използва всеки инсталиран медиен декодер с цел декодиране за възпроизвеждане."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"управление на надеждните идентификационни данни"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Разрешава на приложението да инсталира и деинсталира сертификати от сертифициращи органи като надеждни идентификационни данни."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"изпълняване на приложението по време на неактивност"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Това разрешение позволява на системата Android да изпълнява приложението на заден план, докато устройството не се използва."</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>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Разрешава на приложението да променя глобалните настройки за звука, като например силата и това, кой високоговорител се използва за изход."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"запис на звук"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Разрешава на приложението да записва звук с микрофона. Това разрешение му позволява да го прави по всяко време без потвърждение от ваша страна."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"комуникация със SIM картата"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Разрешава на приложението да изпраща команди до SIM картата. Това е много опасно."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"правене на снимки и видеоклипове"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Разрешава на приложението да прави снимки и видеоклипове с камерата. Това разрешение му позволява да я използва по всяко време без потвърждение от ваша страна."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"деактивиране на светодиодния индикатор за предаване, когато камерата се използва"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Разрешава на приложението да контролира телефонните функции на устройството. Приложение с такова разрешение може да превключва между мрежи, да включва и изключва радиомодула на телефона и други подобни, без изобщо да ви известява."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"четене на състоянието и идентификационните данни на телефона"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Разрешава на приложението достъп до телефонните функции на устройството. Това разрешение позволява на приложението да определя телефонния номер и идентификационния номер на устройството, дали се води разговор и отдалечения номер, до който е установена връзка с обаждането."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"четене на точните състояния на телефона"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Позволява на приложението да осъществява достъп до точните състояния на телефона. С това разрешение то може да определи действителното състояние на обаждането – дали е активно, или е на заден план, дали е неуспешно, точното състояние на връзката за пренос на данни и неуспешната връзка за пренос."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Разрешава на притежателя да извиква предоставеното от оператора приложение за конфигуриране. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"слушане за наблюдения на мрежовите условия"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Разрешава на приложението да слуша за наблюдения на мрежовите условия. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"промяна на калибрирането на устройството за въвеждане"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Разрешава на приложението да променя параметрите на калибриране на сензорния екран. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Домашен"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Служебен"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Друг"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Няма намерено приложение, с което да се отвори този контакт."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Взаимодействие със системата за актуализации и възстановяване"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Разрешава на приложението да взаимодейства със системата за възстановяване и системните актуализации."</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> не можа да се стартира"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Споделяне със"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Споделяне със: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Плъзгаща се дръжка. Докоснете и задръжте."</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Свързване с устройство"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Екран за предаване към устройството"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Търсят се устройства…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Настройки"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Прекратяване на връзката"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Сканира се..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Установява се връзка..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Налице"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Екранът се предава"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Установява се връзка с/ъс „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Екранът се предава"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Установена е връзка с/ъс „<xliff:g id="NAME">%1$s</xliff:g>“"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK кодът трябва да е с осем цифри."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Опитайте отново по-късно"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"За изход от цял екран прекарайте пръст отгоре надолу."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Кръгов плъзгач за часовете"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Кръгов плъзгач за минутите"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Избиране на часове"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Избиране на минути"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Месечна таблица на дните"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Списък с години"</string>
+    <string name="select_day" msgid="7774759604701773332">"Избиране на месец и ден"</string>
+    <string name="select_year" msgid="7952052866994196170">"Избиране на година"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Избрахте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Изтрихте <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 8b46e84..0330b7b 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Introdueix un PUK compost com a mínim de 8 nombres."</string>
     <string name="needPuk" msgid="919668385956251611">"La targeta SIM està bloquejada pel PUK. Escriviu el codi PUK per desbloquejar-la."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Escriviu el PUK2 per desbloquejar la targeta SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"No és correcte; activa el bloqueig de RUIM/SIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Et queda <xliff:g id="NUMBER">%d</xliff:g> intent; si no l\'encertes, la SIM es bloquejarà."</item>
+    <item quantity="other" msgid="7530597808358774740">"Et queden <xliff:g id="NUMBER">%d</xliff:g> intents; si no l\'encertes, la SIM es bloquejarà."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Identificació de trucada entrant"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstal·la dreceres"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permet que l\'aplicació suprimeixi les dreceres de la pantalla d\'inici sense la intervenció de l\'usuari."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"desviació de les trucades sortints"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Permet que l\'aplicació processi les trucades sortints i que canviï el número que es marcarà. Aquest permís permet que l\'aplicació supervisi, redirigeixi o bloquegi les trucades sortints."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permet que l\'aplicació vegi el número que s\'està marcant durant una trucada sortint, amb l\'opció de redirigir la trucada a un altre número o bé de cancel·lar-la completament."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"recepció de missatges de text (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permet que l\'aplicació rebi i processi missatges SMS. Això vol dir que l\'aplicació pot controlar o suprimir missatges que s\'han enviat al teu dispositiu sense mostrar-te\'ls."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"recepció de missatges de text (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permet que el titular vinculi a la interfície de nivell superior d\'un servei de VPN. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"enllaça amb un fons de pantalla"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permet que el titular vinculi a la interfície de nivell superior d\'un fons de pantalla. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"vincula a una pantalla remota"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permet que el titular es vinculi a la interfície de nivell superior d\'una pantalla remota. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincula a un servei de widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"executar l\'aplicació durant el temps d\'inactivitat"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Aquest permís permet que el sistema Android executi l\'aplicació en segon pla mentre el dispositiu no està en ús."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permet que l\'aplicació utilitzi funcions SurfaceFlinger de baix nivell."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"llegir la memòria intermèdia de marcs"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permet que l\'aplicació llegeixi el contingut de la memòria intermèdia de marcs."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"accedeix a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet que l\'aplicació utilitzi funcions de baix nivell d\'InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configuració de les pantalles Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permet que l\'aplicació enregistri àudio amb el micròfon. Aquest permís permet que l\'aplicació enregistri àudio en qualsevol moment sense la teva confirmació."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"comunicació SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permet que l\'aplicació enviï ordres a la SIM. Això és molt perillós."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"fes fotos i vídeos"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Permet que l\'aplicació faci fotos i vídeos amb la càmera. Aquest permís permet que l\'aplicació utilitzi la càmera en qualsevol moment sense la teva confirmació."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"desactiva la transmissió del LED indicador en fer servir la càmera"</string>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"llegeix els estats exactes del telèfon"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permet que l\'aplicació accedeixi als estats exactes del telèfon. Amb aquest permís, l\'aplicació pot determinar l\'estat real de la trucada, si la trucada està activa o en segon pla, si s\'ha produït algun error, l\'estat exacte de la connexió de dades i els errors de la connexió de dades."</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>
@@ -668,12 +683,14 @@
     <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_bindNotificationListenerService" msgid="7057764742211656654">"vincula a un servei oient de notificacions"</string>
+    <string name="permdesc_bindNotificationListenerService" msgid="985697918576902986">"Permet que el titular vinculi la interfície de nivell superior d\'un servei oient 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="permlab_setInputCalibration" msgid="4902620118878467615">"canviar el calibratge del dispositiu d\'entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permet que l\'aplicació modifiqui els paràmetres de calibratge de la pantalla tàctil. No ha de ser mai necessari per a aplicacions normals."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir 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">"Controlar intents de desbloqueig de pantalla"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Feina"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Altres"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"No hem trobat cap aplicació per mostrar aquest contacte."</string>
     <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>
@@ -981,10 +999,10 @@
     <string name="enable_explore_by_touch_warning_message" product="tablet" msgid="8655887539089910577">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'exploració tàctil. Quan l\'exploració tàctil està activada, pots escoltar o veure les descripcions del contingut seleccionat o utilitzar gestos per interactuar amb la tauleta."</string>
     <string name="enable_explore_by_touch_warning_message" product="default" msgid="2708199672852373195">"<xliff:g id="ACCESSIBILITY_SERVICE_NAME">%1$s</xliff:g> vol activar l\'exploració tàctil. Quan l\'exploració per tàctil està activada, pots escoltar o veure les descripcions del contingut seleccionat o utilitzar gestos per interactuar amb el telèfon."</string>
     <string name="oneMonthDurationPast" msgid="7396384508953779925">"Fa 1 mes"</string>
-    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Fa menys d\'1 mes"</string>
+    <string name="beforeOneMonthDurationPast" msgid="909134546836499826">"Fa més d\'1 mes"</string>
   <plurals name="num_seconds_ago">
     <item quantity="one" msgid="4869870056547896011">"Fa 1 segon"</item>
-    <item quantity="other" msgid="3903706804349556379">"fa <xliff:g id="COUNT">%d</xliff:g> segons"</item>
+    <item quantity="other" msgid="3903706804349556379">"Fa <xliff:g id="COUNT">%d</xliff:g> segons"</item>
   </plurals>
   <plurals name="num_minutes_ago">
     <item quantity="one" msgid="3306787433088810191">"Fa 1 minut"</item>
@@ -1000,7 +1018,7 @@
     <string name="last_month" msgid="3959346739979055432">"El mes passat"</string>
     <string name="older" msgid="5211975022815554840">"Més antigues"</string>
   <plurals name="num_days_ago">
-    <item quantity="one" msgid="861358534398115820">"ahir"</item>
+    <item quantity="one" msgid="861358534398115820">"Ahir"</item>
     <item quantity="other" msgid="2479586466153314633">"Fa <xliff:g id="COUNT">%d</xliff:g> dies"</item>
   </plurals>
   <plurals name="in_num_seconds">
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interacciona amb el sistema de recuperació i amb les actualitzacions"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permet que una aplicació interaccioni amb el sistema de recuperació i amb les actualitzacions del sistema."</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>
@@ -1328,7 +1348,7 @@
     <string name="accessibility_binding_label" msgid="4148120742096474641">"Accessibilitat"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fons de pantalla"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Canvia el fons de pantalla"</string>
-    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Processador de notificacions"</string>
+    <string name="notification_listener_binding_label" msgid="2014162835481906429">"Oient de notificacions"</string>
     <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string>
     <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ha activat VPN"</string>
     <string name="vpn_text" msgid="3011306607126450322">"Toca per gestionar la xarxa."</string>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maj"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retorn"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Selecciona una aplicació"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"No s\'ha pogut iniciar <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Comparteix amb"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Comparteix amb <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Llisca el dit. Mantén premut."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Llisca el dit per desbloquejar."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Connecta un auricular per escoltar les claus de la contrasenya en veu alta."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punt."</string>
@@ -1483,9 +1495,13 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Àudio per Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Pantalla sense fil"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fet"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Sortida de contingut multimèdia"</string>
-    <string name="media_route_status_scanning" msgid="7279908761758293783">"S\'està explorant..."</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Connexió al dispositiu"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Emissió de pantalla al dispositiu"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"S\'estan cercant dispositius…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Configuració"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Desconnecta"</string>
+    <string name="media_route_status_scanning" msgid="7279908761758293783">"S\'està cercant…"</string>
     <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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Emissió de pantalla"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"S\'està connectant a <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Emissió de pantalla"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Connectat a <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconnecta"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"El codi PUK ha de tenir 8 números."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"Torna a introduir el codi PUK correcte. Els intents repetits faran que es desactivi la SIM de manera permanent."</string>
     <string name="kg_invalid_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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Torna-ho a provar més tard"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Fes lliscar el dit cap avall per sortir de la pantalla completa."</string>
+    <string name="done_label" msgid="2093726099505892398">"Fet"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Control circular de les hores"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Control circular dels minuts"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selecciona les hores"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selecciona els minuts"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Graella mensual de dies"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Llista anual"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selecciona un mes i un dia"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selecciona un any"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionat"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> suprimit"</string>
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 73ca02b..37e228c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Zadejte osmimístný nebo delší kód PUK."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM karta je blokována pomocí kódu PUK. Odblokujete ji zadáním kódu PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Chcete-li odblokovat SIM kartu, zadejte kód PUK2."</string>
+    <string name="enablePin" msgid="209412020907207950">"Operace nebyla úspěšná, povolte zámek SIM/RUIM karty."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Máte ještě <xliff:g id="NUMBER">%d</xliff:g> pokus. Poté bude SIM karta uzamčena."</item>
+    <item quantity="other" msgid="7530597808358774740">"Počet zbývajících pokusů, po jejichž vyčerpání bude SIM karta uzamčena: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Příchozí identifikace volajícího"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"odinstalace zástupců"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Umožňuje aplikaci odebrat zástupce z plochy bez zásahu uživatele."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"přesměrování odchozích hovorů"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Umožňuje aplikaci zpracovávat odchozí hovory a měnit vytáčené číslo. Toto oprávnění umožňuje sledovat či přesměrovat odchozí hovory nebo jim zabránit."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Umožňuje aplikaci sledovat při odchozích hovorech volaná čísla a přesměrovat hovor na jiné číslo nebo jej zcela zrušit."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"příjem textových zpráv (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Umožňuje aplikaci přijmout a zpracovat zprávy SMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"příjem textových zpráv (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Umožňuje držiteli navázat se na nejvyšší úroveň služby VPN. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"vazba na tapetu"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Umožňuje držiteli navázat se na nejvyšší úroveň rozhraní tapety. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"připojit se ke vzdálenému displeji"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Umožňuje držiteli připojit se k vysokoúrovňovému rozhraní vzdáleného displeje. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"navázat se na službu widgetu"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"spustit aplikaci během nečinnosti"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Toto oprávnění umožňuje systému Android spustit aplikaci na pozadí, když zařízení není používáno."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Umožňuje aplikaci používat nízkoúrovňové funkce SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"čtení vyrovnávací paměti snímků"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Umožňuje aplikaci číst obsah vyrovnávací paměti snímků."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"přístup k funkci InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Umožňuje aplikaci používat nízkoúrovňové funkce InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurovat displeje přes Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Umožňuje aplikaci zaznamenat zvuk pomocí mikrofonu. Toto oprávnění umožňuje aplikaci kdykoliv zaznamenat zvuk bez vašeho svolení."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"komunikace s kartou SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Umožňuje aplikaci odesílat příkazy na kartu SIM. Toto oprávnění je velmi nebezpečné."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"pořizování fotografií a videí"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Umožňuje aplikaci pořizovat fotografie a videa pomocí fotoaparátu. Toto oprávnění umožňuje aplikaci používat fotoaparát kdykoliv i bez vašeho svolení."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"vypnutí indikátoru LED přenosu při použití fotoaparátu"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje aplikaci ovládat telefonní funkce zařízení. Aplikace s tímto oprávněním smí bez upozornění přepínat sítě, zapínat a vypínat bezdrátový modul telefonu a podobně."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čtení stavu a identity telefonu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikaci získat přístup k telefonním funkcím zařízení. Toto oprávnění umožňuje aplikaci zjistit telefonní číslo telefonu, identifikační čísla zařízení, zda zrovna probíhá hovor, a vzdálené číslo, ke kterému je hovor připojen."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čtení přesného stavu telefonování"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikaci zjišťovat přesný stav telefonování a mobilních dat. Toto oprávnění aplikaci umožňuje zjistit skutečný stav volání, zda je volání aktivní nebo na pozadí, zda volání selhalo, přesný stav datového připojení a zda datové připojení selhalo."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"bránění přechodu tabletu do režimu spánku"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"měnit kalibraci vstupního zařízení"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Umožňuje aplikaci měnit parametry kalibrace dotykové obrazovky. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Domů"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Práce"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Jiné"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nebyla nalezena žádná aplikace, pomocí které by tento kontakt bylo možné zobrazit."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interakce se systémem aktualizací a obnovení"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Umožňuje aplikaci interakci se systémem obnovení a s aktualizacemi systému."</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>
@@ -1414,18 +1434,10 @@
     <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">"Vybrat aplikaci"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Aplikaci <xliff:g id="APPLICATION_NAME">%s</xliff:g> nelze spustit."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Sdílet s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Sdílet s aplikací <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvník. Dotkněte se a podržte."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Odemknete posunutím prstu."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Chcete-li slyšet, které klávesy jste při zadávání hesla stiskli, připojte sluchátka."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Tečka."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth Audio"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bezdrátový displej"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Připojení k zařízení"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Odesílání obsahu obrazovky do zařízení"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Vyhledávání zařízení…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Nastavení"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Odpojit"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Vyhledávání…"</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Připojování…"</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Dostupná"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Odesílání obsahu obrazovky"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Připojování k obrazovce <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Odesílání obsahu obrazovky"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Připojeno k obrazovce <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojit"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Kód PUK by měl obsahovat 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Zkuste to znovu později"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Režim celé obrazovky ukončíte přejetím dolů."</string>
+    <string name="done_label" msgid="2093726099505892398">"Hotovo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kruhový posuvník hodin"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kruhový posuvník minut"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Zvolte hodiny"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Zvolte minuty"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Dny uspořádané po měsících"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Seznam roků"</string>
+    <string name="select_day" msgid="7774759604701773332">"Vyberte měsíc a den"</string>
+    <string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Vybrána položka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Číslice <xliff:g id="KEY">%1$s</xliff:g> byla smazána"</string>
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 0cf5bc5..5acf558 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Angiv en PUK-kode på 8 eller flere cifre."</string>
     <string name="needPuk" msgid="919668385956251611">"Dit SIM-kort er låst med PUK-koden. Indtast PUK-koden for at låse den op."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Indtast PUK2-koden for at låse op for SIM-kortet."</string>
+    <string name="enablePin" msgid="209412020907207950">"Mislykkedes. Aktivér SIM-/RUIM-lås."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Du har <xliff:g id="NUMBER">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver låst."</item>
+    <item quantity="other" msgid="7530597808358774740">"Du har <xliff:g id="NUMBER">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver låst."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI-nummer"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Indgående opkalds-id"</string>
@@ -230,13 +235,13 @@
     <string name="permgrouplab_storage" msgid="1971118770546336966">"Lagring"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Få adgang til USB-lager."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Få adgang til SD-kortet."</string>
-    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Tilgængelighedsfunktioner"</string>
+    <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Hjælpefunktioner"</string>
     <string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"Funktioner, som hjælpeteknologier kan anmode om."</string>
     <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"hente indholdet i vinduet"</string>
     <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"undersøge indholdet i et vindue, du interagerer med."</string>
     <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"aktivere Udforsk ved berøring"</string>
     <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"De emner, der trykkes på, læses højt, og skærmen kan udforskes ved hjælp af bevægelser."</string>
-    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"aktivere forbedret webtilgængelighed"</string>
+    <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"aktivere forbedret webhjælpefunktioner"</string>
     <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Der installeres muligvis scripts for at gøre appindhold mere tilgængeligt."</string>
     <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"observere tekst, du skriver"</string>
     <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Dette omfatter personlige data såsom kreditkortnumre og adgangskoder."</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"afinstaller genveje"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Tillader, at applikationen fjerner genveje på startskærmen uden brugerindgriben."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Tillader, at appen kan se det nummer, der ringes op til under et udgående opkald, og giver mulighed for at omdirigere opkaldet til et andet nummer eller afbryde opkaldet helt."</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>
@@ -308,8 +313,8 @@
     <string name="permdesc_dump" msgid="1778299088692290329">"Tillader, at appen kan hente systemets interne tilstand. Ondsindede apps kan hente en lang række fortrolige og beskyttede oplysninger, som de normalt aldrig ville have brug for."</string>
     <string name="permlab_retrieve_window_content" msgid="8022588608994589938">"hente skærmindhold"</string>
     <string name="permdesc_retrieve_window_content" msgid="3193269069469700265">"Tillader, at appen kan hente indholdet i det aktive vindue. Ondsindede apps kan hente al indholdet i vinduet og undersøge al dens tekst med undtagelse af adgangskoder."</string>
-    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"aktivér tilgængelighed midlertidigt"</string>
-    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Tillader, at en applikation midlertidigt kan aktivere tilgængelighed på enheden. Skadelige apps kan muligvis aktivere tilgængelighed uden brugerens samtykke."</string>
+    <string name="permlab_temporary_enable_accessibility" msgid="2312612135127310254">"aktivere hjælpefunktioner midlertidigt"</string>
+    <string name="permdesc_temporary_enable_accessibility" msgid="8079456293182975464">"Tillader, at en app midlertidigt kan aktivere hjælpefunktioner på enheden. Skadelige apps kan muligvis aktivere hjælpefunktioner uden brugerens samtykke."</string>
     <string name="permlab_retrieve_window_info" msgid="8532295199112519378">"hent oplysninger om vinduer"</string>
     <string name="permdesc_retrieve_window_info" msgid="4998836370424186849">"Tillader, at en applikation henter oplysninger om vinduerne i vinduesadministratoren. Skadelige apps kan muligvis hente oplysninger, der er beregnet til intern systembrug."</string>
     <string name="permlab_filter_events" msgid="8675535648807427389">"filtrer begivenheder"</string>
@@ -325,11 +330,11 @@
     <string name="permlab_runSetActivityWatcher" msgid="892239094867182656">"overvåge og kontrollere åbning af alle apps"</string>
     <string name="permdesc_runSetActivityWatcher" msgid="6003603162578577406">"Tillader, at appen kan overvåge og kontrollere, hvordan systemet starter aktiviteter. Ondsindede apps kan fuldstændig kompromittere systemet. Denne tilladelse er kun nødvendig til udvikling, aldrig til normal brug."</string>
     <string name="permlab_broadcastPackageRemoved" msgid="2576333434893532475">"send udsendelse om fjernet pakke"</string>
-    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Tillader, at appen kan udsende en meddelelse om, at en apppakke er fjernet. Ondsindede apps kan bruge dette til at dræbe andre kørende apps."</string>
+    <string name="permdesc_broadcastPackageRemoved" msgid="6621901216207931089">"Tillader, at appen kan udsende en underretning om, at en app-pakke er fjernet. Ondsindede apps kan bruge dette til at lukke andre kørende apps."</string>
     <string name="permlab_broadcastSmsReceived" msgid="5689095009030336593">"send sms-modtaget udsendelse"</string>
-    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Tillader, at appen kan udsende en meddelelse om, at der er modtaget en sms-besked. Ondsindede apps kan bruge dette til at forfalske indgående sms-beskeder."</string>
+    <string name="permdesc_broadcastSmsReceived" msgid="4152037720034365492">"Tillader, at appen kan udsende en underretning om, at der er modtaget en sms-besked. Ondsindede apps kan bruge dette til at simulere indgående sms-beskeder."</string>
     <string name="permlab_broadcastWapPush" msgid="3145347413028582371">"send WAP-PUSH-modtaget udsendelse"</string>
-    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Tillader, at appen kan udsende en meddelelse om, at der er modtaget en WAP PUSH-besked. Ondsindede apps kan bruge dette til at forfalske modtagelse af mms-beskeder eller i det skjulte erstatte indholdet på en webside med ondsindede varianter."</string>
+    <string name="permdesc_broadcastWapPush" msgid="4783402525039442729">"Tillader, at appen kan udsende en underretning om, at der er modtaget en WAP PUSH-besked. Ondsindede apps kan bruge dette til at simulere modtagelse af mms-beskeder eller i det skjulte erstatte indholdet på en webside med ondsindede varianter."</string>
     <string name="permlab_setProcessLimit" msgid="2451873664363662666">"begræns antallet af kørende processer"</string>
     <string name="permdesc_setProcessLimit" msgid="7318061314040879542">"Tillader, at appen kan kontrollere det maksimale antal kørende processer. Dette er aldrig nødvendigt til normale apps."</string>
     <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"tvinge baggrundsapps til at lukke"</string>
@@ -348,7 +353,7 @@
     <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Tillader, at appen kan åbne brugergrænsefladen til bekræftelse af komplet sikkerhedskopiering. Må ikke anvendes af nogen app."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"vis uautoriserede vinduer"</string>
     <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Tillader, at appen kan oprette vinduer, der er beregnet til brugergrænsefladen i det interne system. Anvendes ikke af normale apps."</string>
-    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"trække over andre apps"</string>
+    <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"ignorere andre apps"</string>
     <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Tillader, at appen trækkes oven på andre applikationer eller dele af brugergrænsefladen. De kan forstyrre din brug af grænsefladen i en applikation eller ændre det, du tror, du ser i andre applikationer."</string>
     <string name="permlab_setAnimationScale" msgid="2805103241153907174">"rediger global animationshastighed"</string>
     <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Tillader, at appen til enhver tid kan ændre den globale animationshastighed (hurtigere eller langsommere animationer)."</string>
@@ -363,8 +368,8 @@
     <string name="permdesc_readInputState" msgid="8387754901688728043">"Tillader, at appen kan se de taster, som du trykker på, selv i en anden app (såsom indtastning af adgangskode). Dette bør aldrig være nødvendigt for normale apps."</string>
     <string name="permlab_bindInputMethod" msgid="3360064620230515776">"forpligt til en inputmetode"</string>
     <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_bindAccessibilityService" msgid="5357733942556031593">"binde dig til en hjælpetjeneste"</string>
+    <string name="permdesc_bindAccessibilityService" msgid="7034615928609331368">"Tillader, at appen kan binde sig til en grænseflade for en hjælpetjeneste 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>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Tillader, at brugeren forpligter sig til en VPN-tjenestes grænseflade på øverste niveau. Bør aldrig være nødvendigt i almindelige apps."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"forpligt til et tapet"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Tillader, at indehaveren kan binde en baggrunds grænseflade på øverste niveau. Dette bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"bind til en ekstern skærm"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Tillader, at brugeren kan foretage en binding til grænsefladens øverste niveau på en ekstern skærm. Bør aldrig være nødvendigt til almindelige apps."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"forpligt til en widgettjeneste"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"kør applikation, mens enheden er i dvale"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Med denne tilladelse kan Android-systemet køre applikationen i baggrunden, mens enheden ikke er i brug."</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>
@@ -434,7 +443,7 @@
     <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"køre ved opstart"</string>
     <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Tillader, at appen kan starte af sig selv, så snart systemet er færdig med at starte. Dette kan gøre tablettens opstartstid længere og give appen tilladelse til at gøre tabletten langsommere ved altid at lade appen køre."</string>
     <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Tillader, at appen kan åbne sig selv, når systemet er færdig med at starte op. Dette kan gøre opstarten af telefonen langsommere og generelt gøre systemet langsommere, når appen altid kører."</string>
-    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"send klæbende udsendelse"</string>
+    <string name="permlab_broadcastSticky" msgid="7919126372606881614">"sende klæbende udsendelse"</string>
     <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Tillader, at appen kan sende klæbende udsendelser, der forbliver tilbage, når udsendelsen er slut. Overdreven brug kan gøre din tablet langsom eller ustabil ved at tvinge den til at bruge for meget hukommelse."</string>
     <string name="permdesc_broadcastSticky" product="default" msgid="2825803764232445091">"Tillader, at appen kan sende klæbende udsendelser, der forbliver tilbage, når udsendelsen er slut. Overdreven brug kan gøre din telefon langsom eller ustabil ved at tvinge den til at bruge for meget hukommelse."</string>
     <string name="permlab_readContacts" msgid="8348481131899886131">"læse dine kontaktpersoner"</string>
@@ -457,7 +466,7 @@
     <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tillader, at appen kan få adgang til og synkronisere sociale opdateringer fra dig og dine venner. Vær forsigtig, når du deler oplysninger – med denne tilladelse kan appen læse kommunikation mellem dig og dine venner på sociale netværk, uanset fortrolighed. Bemærk! Denne tilladelse håndhæves muligvis ikke på alle sociale netværk."</string>
     <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skriv i din sociale strøm"</string>
     <string name="permdesc_writeSocialStream" product="default" msgid="3086557552204114849">"Tillader, at appen kan vise sociale opdateringer fra dine venner. Vær forsigtig, når du deler oplysninger – med denne tilladelse kan appen producere meddelelser, der kan synes at komme fra en ven. Bemærk! Denne tilladelse håndhæves muligvis ikke på alle sociale netværk."</string>
-    <string name="permlab_readCalendar" msgid="5972727560257612398">"læs kalenderbegivenheder plus fortrolige oplysninger"</string>
+    <string name="permlab_readCalendar" msgid="5972727560257612398">"læse kalenderbegivenheder og fortrolige oplysninger"</string>
     <string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"Tillader, at appen kan læse alle de kalenderbegivenheder, der er gemt på din tablet, f.eks. venners eller kollegers. Med denne tilladelse kan appen dele eller gemme dine kalenderdata, uanset fortrolighed eller følsomhed."</string>
     <string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"Tillader, at appen kan læse alle de kalenderbegivenheder, der er gemt på din telefon, f.eks. venners eller kollegers. Med denne tilladelse kan appen dele eller gemme dine kalenderdata, uanset fortrolighed eller følsomhed."</string>
     <string name="permlab_writeCalendar" msgid="8438874755193825647">"tilføje eller ændre kalenderbegivenheder og sende e-mail til gæster uden ejerens viden"</string>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tillader, at appen kan bruge SurfaceFlinger-funktioner på lavt niveau."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"læs rammebuffer"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tillader, at appen kan læse indholdet fra rammebufferen."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"få adgang til InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Giver appen tilladelse til at bruge SurfaceFlinger-funktioner på lavt niveau."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurer Wi-Fi-skærme"</string>
     <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>
@@ -495,7 +506,9 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Tillader, at appen kan optage lyd med mikrofonen. Med denne tilladelse kan appen til enhver tid optage lyd uden din bekræftelse."</string>
-    <string name="permlab_camera" msgid="3616391919559751192">"tag billeder og optag video"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM-kommunikation"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Tillader, at appen sender kommandoer til SIM-kortet. Dette er meget farligt."</string>
+    <string name="permlab_camera" msgid="3616391919559751192">"tage billeder og optage video"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Tillader, at appen kan tage billeder og videoer med kameraet. Med denne tilladelse kan appen til enhver tid bruge kameraet uden din bekræftelse."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"deaktiver sendelysdioden, når kameraet er i brug"</string>
     <string name="permdesc_cameraDisableTransmitLed" msgid="4764585465480295341">"Tillader, at en forudinstalleret systemapplikation deaktiverer lysdioden for brug af kameraet."</string>
@@ -533,15 +546,15 @@
     <string name="permdesc_accessMtp" msgid="6532961200486791570">"Tillader adgang til kerne-MTP-driveren for at implementere MTB USB-protokollen."</string>
     <string name="permlab_hardware_test" msgid="4148290860400659146">"test hardware"</string>
     <string name="permdesc_hardware_test" msgid="6597964191208016605">"Tillader, at appen kan kontrollere forskellige perifere enheder til at teste hardwaren."</string>
-    <string name="permlab_callPhone" msgid="3925836347681847954">"ring direkte op til telefonnumre"</string>
+    <string name="permlab_callPhone" msgid="3925836347681847954">"ringe direkte op til telefonnumre"</string>
     <string name="permdesc_callPhone" msgid="3740797576113760827">"Tillader, at appen kan ringe til telefonnumre uden din indgriben. Dette kan resultere i uventede opkrævninger eller opkald. Bemærk, at appen med denne tilladelse ikke kan ringe til nødopkaldsnumre. Skadelige apps kan koste dig penge ved at foretage opkald uden din bekræftelse."</string>
-    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ring direkte op til alle telefonnumre"</string>
+    <string name="permlab_callPrivileged" msgid="4198349211108497879">"ringe direkte op til alle telefonnumre"</string>
     <string name="permdesc_callPrivileged" msgid="1689024901509996810">"Tillader, at appen kan ringe til et hvilket som helst nummer, bl.a. nødopkald uden din indgriben. Ondsindede apps kan foretage unødvendige og ulovlige opkald til nødtjenester."</string>
     <string name="permlab_performCdmaProvisioning" product="tablet" msgid="4842576994144604821">"start CDMA-opsætning af tabletcomputeren direkte"</string>
     <string name="permlab_performCdmaProvisioning" product="default" msgid="5604848095315421425">"start CDMA-telefonopsætning direkte"</string>
     <string name="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"Tillader, at appen kan starte CDMA-levering. Ondsindede apps kan starte unødvendig CDMA-levering."</string>
-    <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontroller meddelelser om placeringsopdatering"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Tillader, at appen kan aktivere/deaktivere meddelelser om placeringsopdatering fra senderen. Anvendes ikke i almindelige apps."</string>
+    <string name="permlab_locationUpdates" msgid="7785408253364335740">"kontroller underretninger om placeringsopdatering"</string>
+    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Tillader, at appen kan aktivere/deaktivere underretninger om placeringsopdatering fra senderen. Anvendes ikke i almindelige apps."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"egenskaber for adgangskontrol"</string>
     <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Tillader, at appen kan få læse/skrive-adgang til egenskaber, der er uploadet af kontroltjenesten. Anvendes ikke af almindelige apps."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"vælg widgets"</string>
@@ -550,7 +563,9 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Tillader, at appen kan styre enhedens telefonfunktioner. En app med denne tilladelse kan skifte netværk, slå telefonsenderen til og fra og lignende uden at underrette dig."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"læse telefonens status og identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillader, at appen kan få adgang til telefonfunktionerne på enheden. Med denne tilladelse kan appen fastslå telefonnummeret og enheds-id\'erne, hvorvidt et opkald er aktivt samt det eksterne nummer, der oprettes forbindelse til via et opkald."</string>
-    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"afhold tabletcomputeren fra at gå i dvale"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"læse nøjagtig status for telefonen"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Tillader, at appen får adgang til den nøjagtige status for telefonen. Denne tilladelse giver appen mulighed for at fastlægge den rigtige opkaldsstatus – om et opkald er aktivt eller kører i baggrunden, om opkaldet mislykkes, hvad den nøjagtige status for dataforbindelsen er, og om dataforbindelsen mislykkes."</string>
+    <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"afholde tabletcomputeren fra at gå i dvale"</string>
     <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>
@@ -674,16 +689,18 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"skift kalibrering for inputenheden"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Tillader, at appen ændrer kalibreringsparametrene for berøringsskærmen. Dette 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>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Overvåg antallet af forkert indtastede adgangskoder, når du låser skærmen op, og lås din tablet, eller slet alle data i den, hvis der er indtastet for mange forkerte adgangskoder."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Overvåg antallet af forkerte adgangskoder ved oplåsning af skærmen, og lås telefonen eller slet alle data på telefonen, hvis der er indtastet for mange forkerte adgangskoder."</string>
-    <string name="policylab_resetPassword" msgid="2620077191242688955">"Skift adgangskode til oplåsning af skærm"</string>
-    <string name="policydesc_resetPassword" msgid="605963962301904458">"Skift adgangskode til oplåsning af skærmen."</string>
+    <string name="policylab_resetPassword" msgid="2620077191242688955">"Skifte adgangskode til oplåsning af skærm"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Skifter adgangskode til oplåsning af skærmen."</string>
     <string name="policylab_forceLock" msgid="2274085384704248431">"Lås skærmen"</string>
-    <string name="policydesc_forceLock" msgid="1141797588403827138">"Kontroller, hvordan og hvornår skærmen låses."</string>
-    <string name="policylab_wipeData" msgid="3910545446758639713">"Slet alle data"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Kontrollerer, hvordan og hvornår skærmen låses."</string>
+    <string name="policylab_wipeData" msgid="3910545446758639713">"Slette alle data"</string>
     <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Slet din tablets data uden varsel ved at gendanne fabriksindstillingerne."</string>
     <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Slet telefonens data uden varsel ved at gendanne fabriksindstillingerne."</string>
     <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Angiv enhedens globale proxy"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Hjem"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbejde"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Andet"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Der blev ikke fundet nogen applikation, som kan vise denne kontaktperson."</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>
@@ -1114,8 +1132,8 @@
     <string name="loading" msgid="7933681260296021180">"Indlæser…"</string>
     <string name="capital_on" msgid="1544682755514494298">"TIL"</string>
     <string name="capital_off" msgid="6815870386972805832">"FRA"</string>
-    <string name="whichApplication" msgid="4533185947064773386">"Fuldfør handling ved hjælp af"</string>
-    <string name="whichHomeApplication" msgid="4616420172727326782">"Vælg en startsideapp"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"Brug"</string>
+    <string name="whichHomeApplication" msgid="4616420172727326782">"Vælg en startapp"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Brug som standard til denne handling."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Ryd standard i Systemindstillinger &gt; Apps &gt; Downloadet."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Vælg en handling"</string>
@@ -1234,20 +1252,20 @@
     <string name="usb_storage_title" msgid="5901459041398751495">"USB er tilsluttet"</string>
     <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Du har fået forbindelse til din computer via USB. Tryk på knappen nedenfor, hvis du vil kopiere filer mellem din computer og din Androids USB-lager."</string>
     <string name="usb_storage_message" product="default" msgid="805351000446037811">"Du har fået forbindelse til din computer via USB. Tryk på knappen nedenfor, hvis du vil kopiere filer mellem din computer og din Androids SD-kort."</string>
-    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Slå USB-lagring til"</string>
+    <string name="usb_storage_button_mount" msgid="1052259930369508235">"Slå USB-lager til"</string>
     <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Der er et problem med at bruge dit USB-lager som USB-masselager."</string>
     <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Der er et problem med at bruge dit SD-kort som USB-masselager."</string>
     <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB er tilsluttet"</string>
     <string name="usb_storage_notification_message" msgid="939822783828183763">"Tryk for at kopiere filer til/fra din computer."</string>
     <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Slå USB-lagringen fra"</string>
-    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Tryk for at slå USB-lagring fra."</string>
+    <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Tryk for at slå USB-lager fra."</string>
     <string name="usb_storage_stop_title" msgid="660129851708775853">"USB-lager i brug"</string>
-    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Før du slår USB-lagring fra, skal du demontere din Androids USB-lager (\"skubbe enheden ud\") fra din computer."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Før du slår USB-lagring fra, skal du demontere din Androids SD-kort (\"skubbe enheden ud\") fra din computer."</string>
-    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Slå USB-lagring fra"</string>
-    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Der opstod et problem med at slå USB-lagring fra. Kontroller, at du har demonteret USB-værten, og prøv derefter igen."</string>
-    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Slå USB-lagring til"</string>
-    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Hvis du slår USB-lagring til, stoppes nogle af de apps, som du bruger, og de kan være utilgængelige, indtil du slår USB-lagring fra igen."</string>
+    <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Før du slår USB-lager fra, skal du demontere din Androids USB-lager (\"skubbe enheden ud\") fra din computer."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Før du slår USB-lager fra, skal du demontere din Androids SD-kort (\"skubbe enheden ud\") fra din computer."</string>
+    <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Slå USB-lager fra"</string>
+    <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Der opstod et problem med at slå USB-lager fra. Kontroller, at du har demonteret USB-værten, og prøv derefter igen."</string>
+    <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Slå USB-lager til"</string>
+    <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"Hvis du slår USB-lager til, stoppes nogle af de apps, som du bruger, og de kan være utilgængelige, indtil du slår USB-lager fra igen."</string>
     <string name="dlg_error_title" msgid="7323658469626514207">"USB-handlingen mislykkedes"</string>
     <string name="dlg_ok" msgid="7376953167039865701">"OK"</string>
     <string name="usb_mtp_notification_title" msgid="3699913097391550394">"Tilsluttet som en medieenhed"</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interager med opdaterings- og gendannelsessystemet"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Giver en applikation tilladelse til at interagere med gendannelsessystemet og systemopdateringerne."</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>
@@ -1325,7 +1345,7 @@
     <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>
+    <string name="accessibility_binding_label" msgid="4148120742096474641">"Hjælpefunktioner"</string>
     <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapet"</string>
     <string name="chooser_wallpaper" msgid="7873476199295190279">"Skift tapet"</string>
     <string name="notification_listener_binding_label" msgid="2014162835481906429">"Underretningslytter"</string>
@@ -1363,7 +1383,7 @@
     <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Demonterer SD-kortet..."</string>
     <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Sletter USB-lageret..."</string>
     <string name="progress_erasing" product="default" msgid="6596988875507043042">"Sletter SD-kortet..."</string>
-    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Kunne ikke slette USB-lagring."</string>
+    <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Kunne ikke slette USB-lager."</string>
     <string name="format_error" product="default" msgid="7315248696644510935">"Kunne ikke slette SD-kort."</string>
     <string name="media_bad_removal" msgid="7960864061016603281">"SD-kortet blev fjernet, før det blev demonteret."</string>
     <string name="media_checking" product="nosdcard" msgid="418188720009569693">"USB-lager bliver kontrolleret."</string>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Angiv"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Vælg en app"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> kunne ikke startes"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Glidende håndtag. Tryk og hold nede."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Glid hurtigt henover for at låse op."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Tilslut et headset for at høre tasterne blive læst højt ved angivelse af adgangskode."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Trådløs skærm"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Udfør"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Medieudgang"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Opret forbindelse til enheden"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Send skærm til enhed"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Søger efter enheder…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Indstillinger"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Afbryd forbindelsen"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Søger..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Opretter forbindelse..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Tilgængelig"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Skærm sendes"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Der oprettes forbindelse til <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Skærm sendes"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Forbundet til <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Afbryd forbindelsen"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK-koden skal være på 8 tal."</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>
@@ -1537,9 +1555,9 @@
     <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?\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="continue_to_enable_accessibility" msgid="1626427372316070258">"Bliv ved med at holde to fingre nede for at aktivere hjælpefunktioner."</string>
+    <string name="accessibility_enabled" msgid="1381972048564547685">"Hjælpefunktioner er aktiveret."</string>
+    <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Hjælpefunktioner 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Prøv igen senere"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Stryg ned fra toppen for at afslutte fuld skærm"</string>
+    <string name="done_label" msgid="2093726099505892398">"Udfør"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Cirkulær timevælger"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Cirkulær minutvælger"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Vælg timer"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Vælg minutter"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Månedsgitter med dage"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Liste over år"</string>
+    <string name="select_day" msgid="7774759604701773332">"Vælg måned og dag"</string>
+    <string name="select_year" msgid="7952052866994196170">"Vælg år"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> er valgt"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string>
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f799be4..f87865d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Geben Sie eine mindestens achtstellige PUK ein."</string>
     <string name="needPuk" msgid="919668385956251611">"Ihre SIM-Karte ist mit einem PUK gesperrt. Geben Sie zum Entsperren den PUK-Code ein."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Geben Sie zum Entsperren der SIM-Karte den PUK2 ein."</string>
+    <string name="enablePin" msgid="209412020907207950">"Fehler. SIM-/RUIM-Sperre aktivieren."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Sie haben noch <xliff:g id="NUMBER">%d</xliff:g> Versuch, bevor Ihre SIM-Karte gesperrt wird."</item>
+    <item quantity="other" msgid="7530597808358774740">"Sie haben noch <xliff:g id="NUMBER">%d</xliff:g> Versuche, bevor Ihre SIM-Karte gesperrt wird."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Anrufer-ID für eingehenden Anruf"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"Verknüpfungen deinstallieren"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Ermöglicht einer App das Entfernen von Verknüpfungen vom Startbildschirm ohne Eingriff des Nutzers"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"Ausgehende Anrufe umleiten"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Ermöglicht der App, ausgehende Anrufe zu verarbeiten und die zu wählende Nummer zu ändern. Die Berechtigung erlaubt der App, ausgehende Anrufe zu überwachen, umzuleiten und zu unterbinden."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Ermöglicht der App die Erkennung der während eines ausgehenden Anrufs gewählten Nummer und gibt ihr die Möglichkeit, den Anruf an eine andere Nummer umzuleiten oder den Anruf ganz abzubrechen"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"SMS empfangen"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ermöglicht der App, SMS zu empfangen und zu verarbeiten. Das bedeutet, dass die App an Ihr Gerät gesendete Nachrichten überwachen und löschen kann, ohne sie Ihnen anzuzeigen."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"MMS empfangen"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Ermöglicht dem Halter, sich an die Oberfläche eines VPN-Dienstes auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"An einen Hintergrund binden"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Ermöglicht dem Halter, sich an die Oberfläche eines Hintergrunds auf oberster Ebene zu binden. Sollte nie für normale Apps benötigt werden."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"An Remote-Display binden"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Ermöglicht dem Halter, sich an die Oberfläche eines Remote-Displays auf oberster Ebene zu binden. Sollte für normale Apps nie benötigt werden."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"An einen Widget-Dienst binden"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"App bei Inaktivität ausführen"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Diese Berechtigung ermöglicht es dem Android-System, die App im Hintergrund auszuführen, wenn das Gerät nicht verwendet wird."</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>
@@ -449,9 +458,9 @@
     <string name="permlab_writeCallLog" msgid="8552045664743499354">"Anrufliste bearbeiten"</string>
     <string name="permdesc_writeCallLog" product="tablet" msgid="6661806062274119245">"Ermöglicht der App, die Anrufliste Ihres Tablets zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
     <string name="permdesc_writeCallLog" product="default" msgid="683941736352787842">"Ermöglicht der App, die Anrufliste Ihres Telefons zu ändern, einschließlich der Daten über ein- und ausgehende Anrufe. Schädliche Apps können so Ihre Anrufliste löschen oder ändern."</string>
-    <string name="permlab_readProfile" msgid="4701889852612716678">"Meine Kontaktkarten lesen"</string>
+    <string name="permlab_readProfile" msgid="4701889852612716678">"Ihre Kontaktkarten lesen"</string>
     <string name="permdesc_readProfile" product="default" msgid="5462475151849888848">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu lesen, einschließlich Ihres Namens und Ihrer Kontaktdaten. Die App kann Sie somit identifizieren und Ihre Profildaten an andere senden."</string>
-    <string name="permlab_writeProfile" msgid="907793628777397643">"Meine Kontaktkarten ändern"</string>
+    <string name="permlab_writeProfile" msgid="907793628777397643">"Ihre Kontaktkarten ändern"</string>
     <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu ändern, einschließlich Ihres Namens und Ihrer Kontaktdaten, sowie Daten hinzuzufügen. Die App kann Sie so identifizieren und Ihre Profildaten an andere senden."</string>
     <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"In sozialem Stream lesen"</string>
     <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ermöglicht der App, auf Updates aus sozialen Netzwerken von Ihnen und Ihren Freunden zuzugreifen und diese zu synchronisieren. Seien Sie vorsichtig, wenn Sie Informationen teilen: Der App wird erlaubt, die Kommunikation zwischen Ihnen und Ihren Freunden in sozialen Netzwerken zu lesen, unabhängig von der Vertraulichkeit der kommunizierten Informationen. Hinweis: Diese Berechtigung kann möglicherweise nicht in allen sozialen Netzwerken erzwungen werden."</string>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Ermöglicht der App, die systemnahen SurfaceFlinger-Funktionen zu verwenden"</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"Frame-Puffer lesen"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ermöglicht der App, den Inhalt des Frame-Puffers zu lesen"</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"Auf InputFlinger zugreifen"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ermöglicht der App, die systemnahen InputFlinger-Funktionen zu verwenden"</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"WLAN-Anzeigen konfigurieren"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Ermöglicht der App, Ton mithilfe des Mikrofons aufzunehmen. Die Berechtigung erlaubt der App, Tonaufnahmen jederzeit und ohne Ihre Bestätigung durchzuführen."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM-Kommunikation"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Ermöglicht der App das Senden von Befehlen an die SIM-Karte. Dies ist äußerst risikoreich."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Bilder und Videos aufnehmen"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Ermöglicht der App, Bilder und Videos mit der Kamera aufzunehmen. Die Berechtigung erlaubt der App, die Kamera jederzeit und ohne Ihre Bestätigung zu nutzen."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"LED-Anzeige für Übertragung bei Kameranutzung deaktivieren"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ermöglicht der App, die Telefonfunktionen des Geräts zu steuern. Eine App mit dieser Berechtigung kann das Netzwerk wechseln oder das Radio des Telefons ein- und ausschalten, ohne Sie darüber zu informieren."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"Telefonstatus und Identität abrufen"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ermöglicht der App, auf die Telefonfunktionen des Geräts zuzugreifen. Die Berechtigung erlaubt der App, die Telefonnummer und Geräte-IDs zu erfassen, festzustellen, ob gerade ein Gespräch geführt wird, und die Rufnummer verbundener Anrufer zu lesen."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Genaue Telefonstatusangaben abrufen"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Ermöglicht der App, auf die genauen Telefonstatusangaben zuzugreifen. Diese Erlaubnis ermöglicht der App, den tatsächlichen Rufstatus zu ermitteln, das bedeutet, ob ein Anruf aktiv ist oder im Hintergrund abläuft, ob bei einem Anruf ein Fehler aufgetreten ist, wie der genaue Datenverbindungsstatus lautet oder ob bei der Datenverbindung ein Fehler aufgetreten ist."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"Ruhezustand des Tablets deaktivieren"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"Kalibrierung für Eingabegerät ändern"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ermöglicht der App, die Kalibrierungsparameter des Touchscreens zu ändern. Für normale Apps sollte dies nie erforderlich sein."</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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Privat"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Geschäftlich"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Sonstige"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Es wurde keine App zum Anzeigen dieses Kontakts gefunden."</string>
     <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>
@@ -830,7 +848,7 @@
     <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Erneut versuchen"</string>
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Erneut versuchen"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Die maximal zulässige Anzahl an Face Unlock-Versuchen wurde überschritten."</string>
-    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Wird geladen... (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+    <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Wird aufgeladen... (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
     <string name="lockscreen_charged" msgid="321635745684060624">"Aufgeladen"</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">"Ladegerät anschließen"</string>
@@ -1198,7 +1216,7 @@
     <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"Einladung zum Aufbau einer Verbindung"</string>
     <string name="wifi_p2p_from_message" msgid="570389174731951769">"Von:"</string>
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"An:"</string>
-    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Geben Sie die erforderliche PIN ein:"</string>
+    <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"Geben Sie die PIN ein:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string>
     <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"Das Tablet wird vorübergehend vom WLAN getrennt, während eine Verbindung mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> besteht."</string>
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Das Telefon wird vorübergehend vom WLAN getrennt, während eine Verbindung mit <xliff:g id="DEVICE_NAME">%1$s</xliff:g> hergestellt wird."</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Mit Update- und Wiederherstellungssystem interagieren"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Ermöglicht einer App die Interaktion mit dem Wiederherstellungssystem und den Systemupdates"</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>
@@ -1411,21 +1431,13 @@
     <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_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Eingabetaste"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"App auswählen"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> konnte nicht gestartet werden."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Teilen mit"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Mit <xliff:g id="APPLICATION_NAME">%s</xliff:g> teilen"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Schieberegler: Berühren und halten"</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="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_target_unlock_tablet" msgid="3833195335629795055">"Zum Entsperren den Finger über den Bildschirm ziehen"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Schließen Sie ein Headset an, um das Passwort gesprochen zu hören."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
@@ -1483,8 +1495,12 @@
     <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">"Kabellose Übertragung (WiDi)"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fertig"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Medienausgabe"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Mit Gerät verbinden"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Bildschirm auf Gerät übertragen"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Geräte werden gesucht…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Einstellungen"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Verbindung trennen"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Wird gescannt..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Verbindung wird hergestellt..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Verfügbar"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Bildschirm wird übertragen"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Verbindung mit <xliff:g id="NAME">%1$s</xliff:g> wird hergestellt."</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Bildschirm wird übertragen"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Verbunden mit <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Verbindung trennen"</string>
     <string name="kg_emergency_call_label" msgid="684946192523830531">"Notruf"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Muster vergessen"</string>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Der PUK-Code muss 8 Ziffern aufweisen."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Später erneut versuchen"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Zum Schließen des Vollbilds von oben nach unten wischen"</string>
+    <string name="done_label" msgid="2093726099505892398">"Fertig"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kreisförmiger Schieberegler für Stunden"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kreisförmiger Schieberegler für Minuten"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Stunden auswählen"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Minuten auswählen"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Monatsraster mit einzelnen Tagen"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Jahresliste"</string>
+    <string name="select_day" msgid="7774759604701773332">"Monat und Tag auswählen"</string>
+    <string name="select_year" msgid="7952052866994196170">"Jahr auswählen"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ausgewählt"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> gelöscht"</string>
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 605d845..e144e9d 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Ανεπιτυχής προσπάθεια. Ενεργοποιήστε το Κλείδωμα SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Απομένει άλλη <xliff:g id="NUMBER">%d</xliff:g> προσπάθεια προτού η κάρτα SIM κλειδωθεί."</item>
+    <item quantity="other" msgid="7530597808358774740">"Απομένουν <xliff:g id="NUMBER">%d</xliff:g> προσπάθειες προτού η κάρτα SIM κλειδωθεί."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Εισερχόμενη αναγνώριση κλήσης"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"κατάργηση εγκατάστασης συντομεύσεων"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Επιτρέπει στην εφαρμογή την κατάργηση συντομεύσεων από την Αρχική οθόνη χωρίς την παρέμβαση του χρήστη."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"αναδρομολόγηση εξερχόμενων κλήσεων"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Επιτρέπει στην εφαρμογή την επεξεργασία εξερχόμενων κλήσεων και την αλλαγή του αριθμού που πρόκειται να κληθεί. Αυτό δίνει τη δυνατότητα στην εφαρμογή να παρακολουθεί, να ανακατευθύνει ή να παρεμποδίζει εξερχόμενες κλήσεις:"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Επιτρέπει στην εφαρμογή να βλέπει τον αριθμό που καλέσατε κατά τη διάρκεια μιας εξερχόμενης κλήσης με επιλογή ανακατεύθυνσης της κλήσης σε έναν διαφορετικό αριθμό ή διακοπής της κλήσης."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"μεταφορά σε μια απομακρυσμένη οθόνη"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας απομακρυσμένης οθόνης. Δεν απαιτείται ποτέ για κανονικές εφαρμογές."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"δέσμευση σε υπηρεσία γραφικών στοιχείων"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Επιτρέπει στον κάτοχο τη δέσμευση στη διεπαφή ανωτάτου επιπέδου μιας υπηρεσίας γραφικών στοιχείων. Δεν απαιτείται για κανονικές εφαρμογές."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"επικοινωνία με έναν διαχειριστή συσκευής"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"εκτέλεση εφαρμογής κατά τη λειτουργία αδράνειας"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Αυτή η άδεια επιτρέπει στο σύστημα Android να εκτελεί την εφαρμογή στο παρασκήνιο όταν δεν χρησιμοποιείται η συσκευή."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ανάγνωση/εγγραφή σε πόρους που ανήκουν στο διαγνωστικό"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Επιτρέπει στην εφαρμογή την ανάγνωση και την εγγραφή σε οποιονδήποτε πόρο που ανήκει στην ομάδα διαγνωστικού (π.χ. αρχεία στον κατάλογο /dev). Αυτό ενδέχεται να επηρεάσει την σταθερότητα και την ασφάλεια του συστήματος. Θα πρέπει να χρησιμοποιείται ΜΟΝΟ για διαγνωστικά υλικού από τον κατασκευαστή ή τον χειριστή."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ενεργοποίηση ή απενεργοποίηση στοιχείων εφαρμογής"</string>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Επιτρέπει στην εφαρμογή την τροποποίηση καθολικών ρυθμίσεων ήχου, όπως η ένταση και ποιο ηχείο χρησιμοποιείται για έξοδο."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"εγγραφή ήχου"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Επιτρέπει στην εφαρμογή την εγγραφή ήχου με το μικρόφωνο. Αυτή η άδεια δίνει τη δυνατότητα στην εφαρμογή να εγγράφει ήχο ανά πάσα στιγμή χωρίς την έγκρισή σας."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"επικοινωνία με κάρτα sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Επιτρέπει στην εφαρμογή την αποστολή εντολών στην κάρτα SIM. Αυτό είναι εξαιρετικά επικίνδυνο."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"λήψη φωτογραφιών και βίντεο"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Επιτρέπει στην εφαρμογή τη λήψη φωτογραφιών και βίντεο με τη φωτογραφική μηχανή. Αυτή η άδεια δίνει τη δυνατότητα στην εφαρμογή να χρησιμοποιεί τη φωτογραφική μηχανή ανά πάσα στιγμή χωρίς την έγκρισή σας."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"απενεργοποίηση ένδειξης LED μετάδοσης όταν χρησιμοποιείται η φωτογραφική μηχανή"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Επιτρέπει στην εφαρμογή να ελέγχει τις λειτουργίες τηλεφώνου της συσκευής. Μια εφαρμογή η οποία διαθέτει αυτήν την άδεια μπορεί να κάνει εναλλαγή μεταξύ δικτύων, να ενεργοποιεί και να απενεργοποιεί το ραδιόφωνο του τηλεφώνου και άλλα, χωρίς να ειδοποιείστε."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ανάγνωση κατάστασης και ταυτότητας τηλεφώνου"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Επιτρέπει στην εφαρμογή την πρόσβαση στις λειτουργίες τηλεφώνου της συσκευής. Αυτή η άδεια δίνει τη δυνατότητα στην εφαρμογή να καθορίζει τον αριθμό τηλεφώνου και τα αναγνωριστικά συσκευών, εάν μια κλήση είναι ενεργή, καθώς και τον απομακρυσμένο αριθμό που συνδέεται από μια κλήση."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ανάγνωση ακριβούς κατάστασης τηλεφώνου"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση στην ακριβή κατάσταση του τηλεφώνου. Αυτή η άδεια επιτρέπει στην εφαρμογή να καθορίσει την πραγματική κατάσταση της κλήσης, εάν η κλήση είναι ενεργή ή πραγματοποιείται στο παρασκήνιο, αποτυχίες κλήσεων, ακριβή δεδομένα κατάστασης σύνδεσης και αποτυχίες σύνδεσης δεδομένων."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"παρεμπόδιση μετάβασης του tablet σε κατάσταση αδράνειας"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"παρεμπόδιση μετάβασης του τηλεφώνου σε κατάσταση αδράνειας"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Επιτρέπει στην εφαρμογή την παρεμπόδιση της μετάβασης του tablet σε κατάσταση αδράνειας."</string>
@@ -642,7 +657,7 @@
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"ανάγνωση του περιεχομένου της κάρτας SD"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Επιτρέπει στην εφαρμογή την ανάγνωση του περιεχομένου του αποθηκευτικού σας χώρου USB."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Επιτρέπει στην εφαρμογή την ανάγνωση του περιεχομένου της κάρτας SD."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"τροπ. ή διαγρ. του USB"</string>
+    <string name="permlab_sdcardWrite" product="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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Επιτρέπει στον κάτοχο την κλήση της εφαρμογής διαμόρφωσης που παρέχεται από την εταιρεία κινητής τηλεφωνίας. Δεν απαιτείται για κανονικές εφαρμογές."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"λήψη παρατηρήσεων σχετικά με την κατάσταση δικτύου"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Επιτρέπει σε μια εφαρμογή να λαμβάνει παρατηρήσεις σχετικά με την κατάσταση δικτύου. Δεν θα πρέπει να απαιτείται ποτέ για κανονικές εφαρμογές."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"αλλαγή βαθμονόμησης της συσκευής εισόδου"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Επιτρέπει στην εφαρμογή να τροποποιεί τις παραμέτρους βαθμονόμησης της οθόνης αφής. Δεν απαιτείται για τις κανονικές εφαρμογές."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Αρχική σελίδα"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Εργασία"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Άλλο"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Δεν βρέθηκε καμία εφαρμογή για την προβολή αυτής της επαφής."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Αλληλεπίδραση με το σύστημα ενημέρωσης και ανάκτησης"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Επιτρέπει σε μια εφαρμογή να αλληλεπιδρά με το σύστημα ανάκτησης και ενημερώσεων συστήματος."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Δεν ήταν δυνατή η εκκίνηση του <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="shareactionprovider_share_with" msgid="806688056141131819">"Κοινοποίηση με"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Κοινοποίηση με <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Στοιχείο χειρισμού με δυνατότητα ολίσθησης. Αγγίξτε και πατήστε παρατεταμένα."</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>
@@ -1468,7 +1480,7 @@
     <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="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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Σύνδεση με τη συσκευή"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Μετάδοση οθόνης σε συσκευή"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Αναζήτηση συσκευών…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Ρυθμίσεις"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Αποσύνδεση"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Σάρωση…"</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Σύνδεση…"</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Διαθέσιμη"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Μετάδοση οθόνης"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Γίενται σύνδεση με το <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Μετάδοση οθόνης"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Συνδέθηκε με το <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Ο κωδικός 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Δοκιμάστε ξανά αργότερα"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Σάρωση προς τα κάτω για έξοδο από πλήρη οθόνη"</string>
+    <string name="done_label" msgid="2093726099505892398">"Τέλος"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Κυκλικό ρυθμιστικό ωρών"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Κυκλικό ρυθμιστικό λεπτών"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Επιλογή ωρών"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Επιλογή λεπτών"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Πλέγμα ημερών του μήνα"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Λίστα ετών"</string>
+    <string name="select_day" msgid="7774759604701773332">"Επιλογή μήνα και ημέρας"</string>
+    <string name="select_year" msgid="7952052866994196170">"Επιλογή έτους"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Επιλέχτηκε το στοιχείο <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> διαγράφηκε"</string>
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index ca8509a..19ea67b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Unsuccessful, enable SIM/RUIM Lock."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"You have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM is locked."</item>
+    <item quantity="other" msgid="7530597808358774740">"You have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM is locked."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Incoming Caller ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"uninstall shortcuts"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Allows the application to remove Home screen shortcuts without user intervention."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Allows the app to see the number being dialled during an outgoing call with the option to redirect the call to a different number or abort the call altogether."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"bind to a remote display"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Allows the holder to bind to the top-level interface of a remote display. Should never be needed for normal apps."</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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"run application during idle time"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"This permission allows the Android system to run the application in the background while the device is not in use."</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>
@@ -477,6 +486,8 @@
     <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_accessInputFlinger" msgid="5348635270689553857">"access InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Allows the app to use InputFlinger low-level features."</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>
@@ -495,6 +506,8 @@
     <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_sim_communication" msgid="1180265879464893029">"SIM communication"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Allows the app to send commands to the SIM. This is very dangerous."</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>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"read precise phone states"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Allows the app to access the precise phone states. This permission allows the app to determine the real call status, whether a call is active or in the background, call fails, precise data connection status and data connection fails."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"No application found to view this contact."</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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interact with update and recovery system"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Allows an application to interact with the recovery system and system updates."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Couldn\'t launch <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Connect to device"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Cast screen to device"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Searching for devices…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Settings"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Disconnect"</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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Casting screen"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Connecting to <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Casting screen"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Connected to <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK code should be 8 numbers."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swipe down from the top to exit full screen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Finished"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Hours circular slider"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
+    <string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
+    <string name="select_year" msgid="7952052866994196170">"Select year"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index ca8509a..19ea67b 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Unsuccessful, enable SIM/RUIM Lock."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"You have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM is locked."</item>
+    <item quantity="other" msgid="7530597808358774740">"You have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM is locked."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Incoming Caller ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"uninstall shortcuts"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Allows the application to remove Home screen shortcuts without user intervention."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Allows the app to see the number being dialled during an outgoing call with the option to redirect the call to a different number or abort the call altogether."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"bind to a remote display"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Allows the holder to bind to the top-level interface of a remote display. Should never be needed for normal apps."</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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"run application during idle time"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"This permission allows the Android system to run the application in the background while the device is not in use."</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>
@@ -477,6 +486,8 @@
     <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_accessInputFlinger" msgid="5348635270689553857">"access InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Allows the app to use InputFlinger low-level features."</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>
@@ -495,6 +506,8 @@
     <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_sim_communication" msgid="1180265879464893029">"SIM communication"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Allows the app to send commands to the SIM. This is very dangerous."</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>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"read precise phone states"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Allows the app to access the precise phone states. This permission allows the app to determine the real call status, whether a call is active or in the background, call fails, precise data connection status and data connection fails."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Work"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Other"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"No application found to view this contact."</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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interact with update and recovery system"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Allows an application to interact with the recovery system and system updates."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Couldn\'t launch <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Connect to device"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Cast screen to device"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Searching for devices…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Settings"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Disconnect"</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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Casting screen"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Connecting to <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Casting screen"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Connected to <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK code should be 8 numbers."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Try again later"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swipe down from the top to exit full screen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Finished"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Hours circular slider"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minutes circular slider"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Select hours"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Select minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Month grid of days"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Year list"</string>
+    <string name="select_day" msgid="7774759604701773332">"Select month and day"</string>
+    <string name="select_year" msgid="7952052866994196170">"Select year"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selected"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index eb731a3..2c9599c 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ingresa un código PUK de ocho números o más."</string>
     <string name="needPuk" msgid="919668385956251611">"Tu tarjeta SIM está bloqueada con PUK. Escribe el código PUK para desbloquearla."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Escribir PUK2 para desbloquear la tarjeta SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Error; habilita el bloqueo de SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Te queda <xliff:g id="NUMBER">%d</xliff:g> intento antes de que se bloquee la tarjeta SIM."</item>
+    <item quantity="other" msgid="7530597808358774740">"Te quedan <xliff:g id="NUMBER">%d</xliff:g> intentos antes de que se bloquee la tarjeta SIM."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Identificador de llamadas entrantes"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstalar accesos directos"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite que la aplicación elimine accesos directos de la pantalla principal sin que el usuario intervenga."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redireccionar llamadas salientes"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Permite que la aplicación procese las llamadas salientes y cambie el número que se va a marcar. La aplicación puede utilizar este permiso para controlar o desviar llamadas salientes o para impedir que se realicen."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite que la aplicación vea el número marcado al realizar una llamada, con la opción de redirigir esta llamada a un número distinto o cancelarla completamente."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"recibir mensajes de texto (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que la aplicación reciba y procese mensajes SMS, lo que significa que podría controlar o eliminar mensajes enviados al dispositivo sin mostrártelos."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"recibir mensajes de texto (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permite al titular vincularse a la interfaz de nivel superior de un servicio de VPN. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"vincular a un fondo de pantalla"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permite al propietario vincularse a la interfaz de nivel superior de un fondo de pantalla. Las aplicaciones normales no deben utilizar este permiso."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"vincular a una pantalla remota"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite al propietario vincularse a la interfaz de nivel superior de una pantalla remota. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a un servicio de widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"ejecutar la aplicación durante el tiempo de inactividad"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Con este permiso, el sistema Android puede ejecutar la aplicación en segundo plano mientras el dispositivo no está en uso."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite que la aplicación utilice funciones de SurfaceFlinger de bajo nivel."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leer el búfer de tramas"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite que la aplicación lea el contenido del búfer de tramas."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acceder a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que la aplicación utilice funciones de InputFlinger de bajo nivel."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar pantallas Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permite que la aplicación grabe audio con el micrófono. La aplicación puede utilizar este permiso para grabar audio en cualquier momento sin tener tu confirmación."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"Comunicación con tarjeta SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite que la aplicación envíe comandos a la tarjeta SIM. Usar este permiso es peligroso."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"tomar fotografías y grabar videos"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Permite que la aplicación saque fotos o grabe videos con la cámara. Este permiso autoriza a la aplicación a utilizar la cámara en cualquier momento sin tu confirmación."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"Inhabilitar el indicador LED de transmisión mientras se utiliza la cámara"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Una aplicación con este permiso puede cambiar redes, encender y apagar la radio del teléfono y tareas similares sin siquiera notificártelo."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"leer la identidad y el estado del dispositivo"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"leer estados precisos del teléfono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que la aplicación acceda a los estados precisos del teléfono y determine el estado real de la llamada, si hay una llamada activa o en segundo plano, si se produjeron fallos en la llamada, el estado preciso de la conexión de datos y si hubo fallos relacionados con la conexión de datos."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"evitar que el tablet entre en estado de inactividad"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"cambiar la calibración del dispositivo de entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabajo"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Otro"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"No se encontró ninguna aplicación para ver este contacto."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interaccionar con el sistema de recuperación y las actualizaciones"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permite que una aplicación interaccione con el sistema de recuperación y las actualizaciones del sistema."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayúscula"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Ingresar"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Elige una aplicación."</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"No se pudo abrir <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mantén presionado el controlador deslizante."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Desliza el dedo para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecta un auricular para escuchar las contraseñas."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto"</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Pantalla inalámbrica"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Listo"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Salida multimedia"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Conectar al dispositivo"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Transmitir pantalla a dispositivo"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Buscando dispositivos…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Configuración"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Desconectar"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Examinando..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Transmitiendo pantalla"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Estableciendo conexión con <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Transmitiendo pantalla"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Se estableció conexión con <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"El código PUK debe tener 8 números."</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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Salir de pantalla completa: deslizar abajo"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Desliza el dedo hacia abajo para salir de la pantalla completa."</string>
+    <string name="done_label" msgid="2093726099505892398">"Listo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Control deslizante circular de horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Control deslizante circular de minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Seleccionar horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Seleccionar minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Cuadrícula mensual de días"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de años"</string>
+    <string name="select_day" msgid="7774759604701773332">"Seleccionar mes y día"</string>
+    <string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> borrado"</string>
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index a89f35a..cb68b67 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Escribe un código PUK de ocho caracteres o más."</string>
     <string name="needPuk" msgid="919668385956251611">"La tarjeta SIM está bloqueada con el código PUK. Introduce el código PUK para desbloquearla."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Introduce el código PUK2 para desbloquear la tarjeta SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Error, habilitar bloqueo de SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Te queda <xliff:g id="NUMBER">%d</xliff:g> intento para bloquear la tarjeta SIM."</item>
+    <item quantity="other" msgid="7530597808358774740">"Quedan <xliff:g id="NUMBER">%d</xliff:g> intentos para bloquear la tarjeta SIM."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID de emisor de llamada entrante"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstalar accesos directos"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite que la aplicación elimine accesos directos de la pantalla de inicio sin la intervención del usuario."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redireccionar llamadas salientes"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Permite que la aplicación procese las llamadas salientes y cambie el número que se va a marcar. La aplicación puede utilizar este permiso para controlar, desviar o impedir que se realicen llamadas salientes."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite que la aplicación vea el número que se marca al realizar una llamada con la opción de redirigir la llamada a otro número o cancelar la llamada."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"recibir mensajes de texto (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que la aplicación reciba y procese mensajes MMS, lo que significa que podría utilizar este permiso para controlar o eliminar mensajes enviados al dispositivo sin mostrárselos al usuario."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"recibir mensajes de texto (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permite enlazar con la interfaz de nivel superior de un servicio de VPN. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"enlazar con un fondo de pantalla"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permite enlazar con la interfaz de nivel superior de un fondo de pantalla. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"enlazar a una pantalla remota"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite enlazar con la interfaz de nivel superior de una pantalla remota. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"enlazar con un servicio de widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"ejecutar la aplicación durante el tiempo de inactividad"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Esto permite que el sistema Android ejecute la aplicación en segundo plano mientras el dispositivo no se utiliza."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite que la aplicación use funciones de SurfaceFlinger de nivel inferior."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leer memoria de almacenamiento intermedio"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite que la aplicación lea el contenido de la memoria de almacenamiento intermedio."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acceder a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que la aplicación utilice funciones de bajo nivel de SurfaceFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar pantallas Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permite que la aplicación grabe audio con el micrófono. La aplicación puede utilizar este permiso para grabar audio en cualquier momento sin tener la confirmación del usuario."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"comunicación con la tarjeta SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite que la aplicación envíe comandos a la tarjeta SIM. Este permiso es muy peligroso."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"realizar fotografías y vídeos"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Permite que la aplicación haga fotos o grabe vídeos con la cámara. Este permiso autoriza a la aplicación a utilizar la cámara en cualquier momento sin tu confirmación."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"inhabilitar el indicador LED de transmisión mientras se utiliza la cámara"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que la aplicación controle las funciones de teléfono del dispositivo. Las aplicaciones que tengan este permiso pueden cambiar de red, desactivar la señal móvil, etc., sin necesidad de informar al usuario."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"consultar la identidad y el estado del teléfono"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que la aplicación acceda a las funciones de teléfono del dispositivo. La aplicación puede utilizar este permiso para descubrir identificadores de dispositivos y números de teléfono, para saber si una llamada está activa y para conocer el número remoto con el que se ha establecido conexión mediante una llamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"leer estados precisos del teléfono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que la aplicación acceda a estados precisos del teléfono y que pueda determinar el estado real de la llamada, si una llamada está activa o en segundo plano, si se ha producido un error en la llamada, el estado de conexión de datos preciso y si se ha producido un error en la conexión de datos."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir que el tablet entre en modo de suspensión"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"cambiar la calibración del dispositivo de entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. No debe ser necesario para las 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>
@@ -783,7 +800,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo!"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Conversaciones"</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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabajo"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Otro"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"No se ha encontrado ninguna aplicación para ver este contacto."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interactuar con el sistema de recuperación y las actualizaciones"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permite que una aplicación interactúe con el sistema de recuperación y las actualizaciones del sistema."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Mayús"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Intro"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Seleccionar una aplicación"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"No se ha podido abrir <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartir con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartir con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mantén pulsado el icono de desbloqueo y deslízalo."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Desliza el dedo para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecta un auricular para escuchar las contraseñas."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto"</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Pantalla inalámbrica"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fin"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Salida multimedia"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Conectar a dispositivo"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Enviar pantalla a dispositivo"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Buscando dispositivos…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Ajustes"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Desconectar"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Analizando..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponible"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Enviando pantalla"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Conectando a <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Enviando pantalla"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Conectado a <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"El código PUK debe tener 8 números."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Volver a intentar más tarde"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Desliza el dedo hacia abajo para salir de la pantalla completa"</string>
+    <string name="done_label" msgid="2093726099505892398">"Listo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Control deslizante circular de horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Control deslizante circular de minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Seleccionar horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Seleccionar minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Cuadrícula mensual de días"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de años"</string>
+    <string name="select_day" msgid="7774759604701773332">"Seleccionar mes y día"</string>
+    <string name="select_year" msgid="7952052866994196170">"Seleccionar año"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
 </resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 742d3da..039fa9c 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Ebaõnnestus, SIM-i/RUIM-i lukustuse lubamine."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Teil on enne SIM-i lukustumist jäänud veel <xliff:g id="NUMBER">%d</xliff:g> katse."</item>
+    <item quantity="other" msgid="7530597808358774740">"Teil on enne SIM-i lukustumist jäänud veel <xliff:g id="NUMBER">%d</xliff:g> katset."</item>
+  </plurals>
     <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>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"otseteede desinstallimine"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Lubab rakendusel eemaldada avaekraani otseteid ilma kasutaja sekkumiseta."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Lubab rakendusel näha, mis number valitakse väljahelistamisel, ning laseb suunata kõne teisele numbrile või selle üldse katkestada."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"kaugekraaniga sidumine"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Lubab omanikul siduda rakenduse kaugekraani ü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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"rakenduse käitamine tegevusetul ajal"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"See luba võimaldab Android-süsteemil käitada rakendust taustal siis, kui seadet ei kasutata."</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>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <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_sim_communication" msgid="1180265879464893029">"side SIM-kaardiga"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Lubab rakendusel saata käske SIM-kaardile. See on väga ohtlik."</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>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"telefoni täpsete olekute lugemine"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Lubab rakendusel hankida juurdepääsu telefoni täpsetele olekutele. Selle loa korral saab rakendus tuvastada kõne tõelise oleku, kas kõne on aktiivne või taustal, kõnede ebaõnnestumised, täpse andmesideühenduse oleku ja andmesideühenduse ebaõnnestumised."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"sisendseadme kalibreerimise muutmine"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lubab rakendusel muuta puuteekraani kalibreerimisparameetreid. Ei tohiks kunagi olla 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Kodu"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Töö"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Muu"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Selle kontakti kuvamiseks ei leitud ühtegi rakendust."</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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Suhtlemine värskenduse ja taastesüsteemiga"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Lubab rakendusel suhelda taastesüsteemi ja süsteemivärskendustega."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Rakendust <xliff:g id="APPLICATION_NAME">%s</xliff:g> ei õnnestunud käivitada"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Seadmega ühendamine"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Ekraanikuva ülekandmine seadmesse"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Seadmete otsimine …"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Seaded"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Katkesta ühendus"</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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Ekraanikuva ülekandmine"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Ühendamine ekraaniga <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Ekraanikuva ülekandmine"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Ühendatud ekraaniga <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK-kood peab koosnema 8 numbrist."</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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Täisekraani sulgemiseks pühkige ülevalt alla"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Täisekraanilt väljumiseks pühkige ülevalt alla."</string>
+    <string name="done_label" msgid="2093726099505892398">"Valmis"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ringikujuline tunniliugur"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Ringikujuline minutiliugur"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Tundide valimine"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Minutite valimine"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Päevad kuu ruudustikus"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Aastate loend"</string>
+    <string name="select_day" msgid="7774759604701773332">"Kuu ja päeva valimine"</string>
+    <string name="select_year" msgid="7952052866994196170">"Aasta valimine"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valitud"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> on kustutatud"</string>
 </resources>
diff --git a/core/res/res/values-et/donottranslate-cldr.xml b/core/res/res/values-et/donottranslate-cldr.xml
deleted file mode 100755
index 49db240..0000000
--- a/core/res/res/values-et/donottranslate-cldr.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="numeric_date_template">"%s.%s.%s"</string>
-    <string name="month_day_year">%-e %B %Y</string>
-    <string name="time_of_day">%-k:%M:%S</string>
-    <string name="date_and_time">%-k:%M:%S %d.%m.%Y</string>
-    <string name="date_time">%2$s %1$s</string>
-</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
deleted file mode 100644
index 71832c8..0000000
--- a/core/res/res/values-et/strings.xml
+++ /dev/null
@@ -1,1584 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under 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="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_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 kasutajal luua seosed rakendustega, mis jäljendavad 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_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_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>
-    <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
-    <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">"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>
-    <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="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="status_bar_device_locked" msgid="3092703448690669768">"Seade lukustatud."</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="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>
-</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 92d687f..308ea59 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -27,14 +27,14 @@
     <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="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="mmiError" msgid="5154499457739052907">"‏مشکل در اتصال یا کد MMI نامعتبر."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"عملکرد فقط به شماره‌های شماره گیری ثابت محدود است."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"سرویس فعال شد."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"سرویس فعال شد برای:"</string>
@@ -42,14 +42,19 @@
     <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">"پین‎هایی که وارد کرده‎اید با یکدیگر مطابقت ندارند."</string>
+    <string name="mmiComplete" msgid="8232527495411698359">"‏MMI کامل شد."</string>
+    <string name="badPin" msgid="9015277645546710014">"‏پین قدیمی که نوشته‎اید صحیح نیست."</string>
+    <string name="badPuk" msgid="5487257647081132201">"‏PUK که نوشته‌اید صحیح نیست."</string>
+    <string name="mismatchPin" msgid="609379054496863419">"‏پین‎هایی که وارد کرده‎اید با یکدیگر مطابقت ندارند."</string>
     <string name="invalidPin" msgid="3850018445187475377">"یک پین بنویسید که 4 تا 8 رقم باشد."</string>
-    <string name="invalidPuk" msgid="8761456210898036513">"یک PUK با 8 رقم یا بیشتر تایپ کنید."</string>
-    <string name="needPuk" msgid="919668385956251611">"سیم کارت شما با PUK قفل شده است. کد PUK را برای بازگشایی آن بنویسید."</string>
-    <string name="needPuk2" msgid="4526033371987193070">"PUK2 را برای بازگشایی قفل سیم کارت بنویسید."</string>
+    <string name="invalidPuk" msgid="8761456210898036513">"‏یک PUK با 8 رقم یا بیشتر تایپ کنید."</string>
+    <string name="needPuk" msgid="919668385956251611">"‏سیم کارت شما با PUK قفل شده است. کد PUK را برای بازگشایی آن بنویسید."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"‏PUK2 را برای بازگشایی قفل سیم کارت بنویسید."</string>
+    <string name="enablePin" msgid="209412020907207950">"‏ناموفق بود، قفل سیم/RUIM را فعال کنید."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"<xliff:g id="NUMBER">%d</xliff:g> بار دیگر می‌توانید تلاش کنید و پس از آن سیم کارت قفل می‌شود."</item>
+    <item quantity="other" msgid="7530597808358774740">"<xliff:g id="NUMBER">%d</xliff:g> بار دیگر می‌توانید تلاش کنید و پس از آن سیم کارت قفل می‌شود."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"شناسه تماس گیرنده ورودی"</string>
@@ -70,14 +75,14 @@
     <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="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="RestrictedOnAllVoice" msgid="3396963652108151260">"‏تمام سرویس‎های صدا مسدود هستند."</string>
     <string name="RestrictedOnSms" msgid="8314352327461638897">"سرویس پیامک مسدود شده است."</string>
-    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"سرویس‎‎های صدا/داده مسدود شدند."</string>
+    <string name="RestrictedOnVoiceData" msgid="996636487106171320">"‏سرویس‎‎های صدا/داده مسدود شدند."</string>
     <string name="RestrictedOnVoiceSms" msgid="1888588152792023873">"سرویس‌های صوتی/پیامک مسدود شده‌اند"</string>
     <string name="RestrictedOnAll" msgid="5643028264466092821">"تمام سرویس‌های صدا/داده/ پیامک مسدود هستند."</string>
     <string name="serviceClassVoice" msgid="1258393812335258019">"صوتی"</string>
@@ -111,17 +116,17 @@
     <string name="fcError" msgid="3327560126588500777">"مشکل در اتصال یا کد ویژگی نامعتبر."</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"تأیید"</string>
     <string name="httpError" msgid="7956392511146698522">"خطایی در شبکه وجود داشت."</string>
-    <string name="httpErrorLookup" msgid="4711687456111963163">"URL پیدا نشد."</string>
-    <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"طرح کلی تأیید اعتبار سایت پشتیبانی نمی‎شود."</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="httpErrorUnsupportedScheme" msgid="5015730812906192208">"‏پروتکل پشتیبانی نمی‎شود."</string>
     <string name="httpErrorFailedSslHandshake" msgid="96549606000658641">"اتصال امن ایجاد نشد."</string>
-    <string name="httpErrorBadUrl" msgid="3636929722728881972">"بدلیل نامعتبر بودن URL، باز کردن صفحه ممکن نیست."</string>
+    <string name="httpErrorBadUrl" msgid="3636929722728881972">"‏بدلیل نامعتبر بودن URL، باز کردن صفحه ممکن نیست."</string>
     <string name="httpErrorFile" msgid="2170788515052558676">"دسترسی به فایل انجام نشد."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"فایل درخواستی پیدا نشد."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"درخواست‌های زیادی در حال پردازش است. بعداً دوباره امتحان کنید."</string>
@@ -129,7 +134,7 @@
     <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="tablet" msgid="6494019234102154896">"‏حافظه رایانهٔ لوحی پر است! برخی از فایل‎ها را حذف کنید تا فضا آزاد شود."</string>
     <string name="low_memory" product="default" msgid="3475999286680000541">"حافظه تلفن پر است. بعضی از فایل‌ها را حذف کنید تا فضا آزاد شود."</string>
     <string name="ssl_ca_cert_warning" msgid="5848402127455021714">"ممکن است شبکه نظارت شده باشد"</string>
     <string name="ssl_ca_cert_noti_by_unknown" msgid="4475437862189850602">"توسط یک شخص ثالث ناشناس"</string>
@@ -148,11 +153,11 @@
     <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="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="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>
@@ -168,7 +173,7 @@
     <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="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>
@@ -180,7 +185,7 @@
     <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="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>
@@ -228,8 +233,8 @@
     <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="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>
@@ -241,38 +246,38 @@
     <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_install_shortcut" msgid="4279070216371564234">"نصب میان‌برها"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"به برنامه اجازه می‌دهد میان‌برهای صفحه اصلی را بدون دخالت کاربر اضافه کند."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"حذف نصب میان‌برها"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"به برنامه اجازه می‌دهد میان‌برهای صفحه اصلی را بدون دخالت کاربر حذف کند."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ترسیم مجدد مسیر تماس‌های خروجی"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"به برنامه اجازه می‎دهد تماس‌های خروجی را پردازش کند و شماره‎هایی که باید گرفته شوند را تغییر دهد. این مجوز به برنامه امکان می‌دهد به کنترل، هدایت مجدد یا جلوگیری از تماس‌های خروجی بپردازد."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"به برنامه اجازه می‌دهد عددی را که در طی یک تماس خروجی شماره‌گیری شده، ببیند و این اختیار را دارد که تماس را به شماره دیگری هدایت کند یا کلاً تماس را قطع کند."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"دریافت پیام‌های نوشتاری (پیامک)"</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_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="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">"ارسال پیامک ها"</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">"خواندن پیام‌های نوشتاری شما (پیامک یا MMS)"</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"‏خواندن پیام‌های نوشتاری شما (پیامک یا MMS)"</string>
     <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"به برنامه اجازه می‌دهد پیامک‌های ذخیره شده در رایانهٔ لوحی یا سیم کارت شما را بخواند. این ویژگی به برنامه امکان می‌دهد همه پیامک‌ها را صرفنظر از محتوا یا محرمانه بودن آن‌ها بخواند."</string>
     <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"به برنامه اجازه می‌دهد پیامک‌های ذخیره شده در تلفن یا سیم کارت شما را بخواند. این ویژگی به برنامه امکان می‌دهد همه پیامک‌ها را صرفنظر از محتوا یا محرمانه بودن آن‌ها بخواند."</string>
-    <string name="permlab_writeSms" msgid="3216950472636214774">"ویرایش پیام‌های نوشتاری شما (پیامک یا MMS)"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"به برنامه اجازه می‎دهد تا در پیام‌های کوتاه ذخیره شده در رایانهٔ لوحی یا سیم کارت بنویسد. برنامه‎های مخرب پیام‌های شما را حذف می‎کنند."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"به برنامه اجازه می‎دهد تا در پیام‌های کوتاه ذخیره شده در تلفن یا سیم کارت بنویسد. برنامه‎های مخرب می‎توانند پیام‌های شما را حذف کنند."</string>
-    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"دریافت پیام‌های نوشتاری (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"به برنامه اجازه می‌دهد پیام‌های WAP را دریافت و پردازش کند. این مجوز می‌تواند پیام‌های ارسالی به شما را بدون نمایش آن‌ها به شما حذف یا کنترل کند."</string>
-    <string name="permlab_getTasks" msgid="6466095396623933906">"بازیابی برنامه‎های در حال اجرا"</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"‏ویرایش پیام‌های نوشتاری شما (پیامک یا MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"‏به برنامه اجازه می‎دهد تا در پیام‌های کوتاه ذخیره شده در رایانهٔ لوحی یا سیم کارت بنویسد. برنامه‎های مخرب پیام‌های شما را حذف می‎کنند."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"‏به برنامه اجازه می‎دهد تا در پیام‌های کوتاه ذخیره شده در تلفن یا سیم کارت بنویسد. برنامه‎های مخرب می‎توانند پیام‌های شما را حذف کنند."</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>
@@ -281,33 +286,33 @@
     <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_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_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="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_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_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="permlab_retrieve_window_info" msgid="8532295199112519378">"بازیابی اطلاعات پنجره"</string>
@@ -319,124 +324,128 @@
     <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="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="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">"ارسال پخش دریافت شده توسط پیامک"</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="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="permdesc_setProcessLimit" msgid="7318061314040879542">"‏به برنامه اجازه می‎دهد تا حداکثر تعداد پردازشهایی را که اجرا خواهد شد کنترل کند. هرگز برای برنامه‎های عادی لازم نیست."</string>
     <string name="permlab_setAlwaysFinish" msgid="550958507798796965">"بستن اجباری برنامه‌های پس‌زمینه"</string>
-    <string name="permdesc_setAlwaysFinish" msgid="7471310652868841499">"به برنامه اجازه می‎دهد تا به محض اینکه فعالیتها به پس‌زمینه رفتند تمام شوند. برای برنامه‎های عادی نیازی نیست."</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="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="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="permdesc_confirm_full_backup" msgid="1748762171637699562">"‏به برنامه اجازه می‎دهد تا رابط کاربر تایید نسخه کامل پشتیبان را راه‌اندازی کند. هر برنامه‌ای نمی‎تواند از آن استفاده کند."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"نمایش پنجره‌های غیرمجاز"</string>
-    <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"به برنامه اجازه می‎دهد پنجره‎هایی را ایجاد کند که می‎خواهد توسط رابط کاربر سیستم داخلی استفاده شود. برای استفاده برنامه‎های عادی نیست."</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="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="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_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="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="permdesc_bindWallpaper" msgid="7108428692595491668">"‏به دارنده اجازه می‎دهد تا به رابط سطح بالای تصویر زمینه متصل شود. برنامه‎های معمولی هرگز به این ویژگی نیاز ندارند."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"اتصال به نمایشگر راه دور"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"به دارنده ام‍ک‍ان می‌دهد تا به رابط سطح بالای نمایشگر راه دور وصل شود. نباید هرگز برای برنامه‌های عادی لازم باشد."</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="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_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_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="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_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_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="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="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏به برنامه امکان می‌دهد گواهینامه‌های CA را به عنوان اطلاعات کاربری مورد اعتماد نصب یا حذف نصب کند."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"اجرای برنامه در هنگام بدون فعالیت بودن دستگاه"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"‏این مجوز به سیستم Android امکان می‌دهد تا وقتی دستگاه استفاده نمی‌شود برنامه را در پس‌زمینه اجرا کند."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"خواندن/نوشتن منابع متعلق به تشخیص"</string>
-    <string name="permdesc_diagnostic" msgid="6608295692002452283">"به برنامه اجازه می‌دهد هر منبعی را که متعلق به گروه تشخیص است بخواند و در آن بنویسد؛ به‌عنوان مثال، فایل‌های /dev. این امر به‌صورت بالقوه می‌تواند بر پایدار بودن و امنیت سیستم تأثیر بگذارد. این تنها باید برای تشخیص‎‌های مختص سخت‌افزار توسط تولیدکننده یا اپراتور استفاده شود."</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="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_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>
@@ -447,12 +456,12 @@
     <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="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"نوشتن در جریان اجتماعی شما"</string>
@@ -464,23 +473,25 @@
     <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="permlab_accessFineLocation" msgid="1191898061965273372">"موقعیت مکانی دقیق (مبتنی بر GPS و شبکه)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"به برنامه اجازه می‌دهد که موقعیت مکانی دقیق شما را با استفاده از سیستم موقعیت‌یاب جهانی (GPS) یا منابع موقعیت مکانی شبکه‌ای مانند برج‌های سلولی یا Wi-Fi دریافت کند. این سرویس‌های موقعیت مکانی باید در دستگاه شما برای برنامه‌ای که از آنها استفاده می‌کند، فعال و در دسترس باشد. برنامه‌ها ممکن است از آن برای تعیین جایی که هستید، استفاده کنند و ممکن است نیروی باتری بیشتری مصرف کنند."</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="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">"پیکربندی صفحه نمایش‌های Wi‑Fi"</string>
-    <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="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">"‏پیکربندی صفحه نمایش‌های Wi‑Fi"</string>
+    <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>
@@ -495,133 +506,137 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"به برنامه امکان می‌دهد تنظیمات صوتی کلی مانند میزان صدا و بلندگوی مورد استفاده برای پخش صدا را اصلاح کند."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ضبط صدا"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"به برنامه اجازه می‌دهد صدا را با میکروفن ضبط کند. این مجوز به برنامه اجازه می‌دهد صدا را در هر زمان که بخواهید بدون تأیید شما ضبط کند."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"ارتباطات سیم کارت"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"به برنامه اجازه ارسال دستورات به سیم کارت را می‌دهد. این بسیار خطرناک است."</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_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="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="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="permdesc_asec_access" msgid="3094563844593878548">"‏به برنامه اجازه می‎دهد تا اطلاعات مربوط به حافظهٔ داخلی را دریافت کند."</string>
     <string name="permlab_asec_create" msgid="6414757234789336327">"ایجاد حافظهٔ داخلی"</string>
-    <string name="permdesc_asec_create" msgid="4558869273585856876">"به برنامه اجازه می‎دهد تا حافظهٔ داخلی ایجاد کند."</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="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="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_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="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="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="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="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_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="permlab_readPrecisePhoneState" msgid="5476483020282007597">"خواندن وضعیت‌های دقیق تلفن"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"به برنامه امکان می‌دهد به وضعیت‌های دقیق تلفن دسترسی داشته باشد. این مجوز به برنامه امکان می‌دهد وضعیت واقعی تماس، اینکه آیا تماس فعال است یا در پس‌زمینه قرار دارد، تماس‌های ناموفق، وضعیت دقیق اتصال داده و اتصال‌های ناموفق داده را تعیین کند."</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>
     <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>
-    <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="permlab_accountManagerService" msgid="4829262349691386986">"عملکرد به‌عنوان AccountManagerService"</string>
-    <string name="permdesc_accountManagerService" msgid="1948455552333615954">"به برنامه اجازه می‎دهد با AccountAuthenticators تماس برقرار کند."</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="permdesc_authenticateAccounts" msgid="5472124296908977260">"‏به برنامه اجازه می‎دهد از امکانات تأیید کننده اعتبار حساب AccountManager از جمله ایجاد حساب و دریافت و تنظیم گذرواژه‎ها استفاده کند."</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="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="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="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="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="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"‏به برنامه اجازه می‎دهد تا رایانهٔ لوحی بلوتوث محلی را پیکربندی کرده، دستگاه‌های راه دور را شناسایی کرده و با آن‌ها جفت شود."</string>
+    <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"‏به برنامه اجازه می‎دهد تا تلفن بلوتوث محلی را پیکربندی کند و دستگاه‌های راه دور را پیدا کند و با آن‌ها جفت شود."</string>
     <string name="permlab_bluetoothPriv" msgid="4009494246009513828">"اجازه ارتباط با بلوتوث از طریق برنامه"</string>
     <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"به برنامه امکان می‌دهد بدون تعامل کاربر با دستگاه‌های راه دور مرتبط شود."</string>
     <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"به برنامه امکان می‌دهد بدون تعامل کاربر با دستگاه‌های راه دور مرتبط شود."</string>
-    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"اتصال و قطع اتصال از WiMAX"</string>
+    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"‏اتصال و قطع اتصال از WiMAX"</string>
     <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"به برنامه امکان می‌دهد فعال بودن وایمکس و اطلاعات مربوط به هر یک از شبکه‌های وایمکس متصل را مشخص کند."</string>
-    <string name="permlab_changeWimaxState" msgid="2405042267131496579">"تغییر وضعیت WiMAX"</string>
+    <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="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="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="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>
@@ -631,39 +646,39 @@
     <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="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"‏به برنامه اجازه می‎دهد تا جزئیات مربوط به فیدهای همگام شده کنونی را دریافت کند."</string>
     <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"نوشتن فیدهای مشترک"</string>
-    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"به برنامه اجازه می‎دهد تا فیدهای همگام شده کنونی را تغییر دهد. برنامه‎های مخرب می‎توانند فیدهای همگام شده را تغییر دهند."</string>
+    <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"‏به برنامه اجازه می‎دهد تا فیدهای همگام شده کنونی را تغییر دهد. برنامه‎های مخرب می‎توانند فیدهای همگام شده را تغییر دهند."</string>
     <string name="permlab_readDictionary" msgid="4107101525746035718">"خواندن واژه‌هایی که به فرهنگ‌ لغت اضافه کردید"</string>
-    <string name="permdesc_readDictionary" msgid="659614600338904243">"به برنامه اجازه می‎دهد همه کلمه، نام و عباراتی را که کاربر در فرهنگ لغت خود ذخیره کرده است بخواند."</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="367275095159405468">"خواندن محتویات حافظهٔ USB شما"</string>
-    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"خواندن محتویات کارت SD شما"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"به برنامه اجازه می‌دهد محتواهای فضای ذخیره USB را بخواند."</string>
-    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"به برنامه اجازه می‌دهد محتواهای کارت SD شما را بخواند."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"اصلاح یا حذف محتویات حافظهٔ USB شما"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"محتوای کارت SD شما را اصلاح کرده یا تغییر دهد"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"به برنامه اجازه می‎دهد تا در حافظهٔ USB بنویسد."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"به برنامه اجازه می‎دهد تا در کارت SD بنویسد."</string>
+    <string name="permdesc_writeDictionary" msgid="8185385716255065291">"‏به برنامه اجازه می‎دهد تا کلمات جدید را در فهرست کاربر بنویسد."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"‏خواندن محتویات حافظهٔ USB شما"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"‏خواندن محتویات کارت SD شما"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"‏به برنامه اجازه می‌دهد محتواهای فضای ذخیره USB را بخواند."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"‏به برنامه اجازه می‌دهد محتواهای کارت SD شما را بخواند."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"‏اصلاح یا حذف محتویات حافظهٔ USB شما"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"‏محتوای کارت SD شما را اصلاح کرده یا تغییر دهد"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"‏به برنامه اجازه می‎دهد تا در حافظهٔ USB بنویسد."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"‏به برنامه اجازه می‎دهد تا در کارت SD بنویسد."</string>
     <string name="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="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_bind_call_service" msgid="6724009726671246551">"تعامل با صفحه‌نمایش هنگام تماس"</string>
     <string name="permdesc_bind_call_service" msgid="8732547662442572435">"به برنامه امکان می‌دهد کنترل کند که کاربر چه زمانی و چگونه صفحه‌نمایش هنگام تماس را مشاهده کند."</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>
@@ -674,11 +689,13 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"به دارنده اجازه می‌دهد که تنظیمات برنامه شرکت مخابراتی را لغو کند. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"گوش دادن برای بررسی شرایط شبکه"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"به برنامه امکان می‌دهد برای بررسی شرایط شبکه گوش دهد. این امکان هرگز نباید برای برنامه‌های معمولی مورد نیاز باشد."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"تغییر کالیبراسیون دستگاه ورودی"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"به برنامه امکان می‌دهد پارامترهای کالیبراسیون صفحه لمسی را تغییر دهد. هرگز نباید برای برنامه‌های عادی مورد نیاز باشد."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
-    <string name="policydesc_limitPassword" msgid="3252114203919510394">"طول و نویسه‎های مجاز در گذرواژه‌های بازکردن قفل صفحه را کنترل کنید."</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="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>
@@ -693,7 +710,7 @@
     <string name="policylab_encryptedStorage" msgid="8901326199909132915">"تنظیم رمزگذاری حافظه"</string>
     <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"باید اطلاعات ذخیره شده برنامه رمزگذاری شود."</string>
     <string name="policylab_disableCamera" msgid="6395301023152297826">"غیر فعال کردن دوربین ها"</string>
-    <string name="policydesc_disableCamera" msgid="2306349042834754597">"از استفاده از تمام دوربین‎های دستگاه جلوگیری کنید."</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"جلوگیری از استفاده از همه دوربین‌های دستگاه."</string>
     <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"غیرفعال کردن ویژگی‌‌ها در محافظ کلید"</string>
     <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"از استفاده از برخی ویژگی‌ها در محافظ کلید جلوگیری شود."</string>
   <string-array name="phoneTypes">
@@ -809,9 +826,10 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"صفحهٔ اصلی"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"محل کار"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"سایر موارد"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"هیچ برنامه‌ای برای مشاهده این مخاطب پیدا نشد."</string>
     <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_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>
@@ -829,7 +847,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">"دفعات تلاش برای Face Unlock از حداکثر مجاز بیشتر شد"</string>
+    <string name="faceunlock_multiple_failures" msgid="754137583022792429">"‏دفعات تلاش برای Face Unlock از حداکثر مجاز بیشتر شد"</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>
@@ -840,7 +858,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>
@@ -848,15 +866,15 @@
     <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_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_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_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>
@@ -864,13 +882,13 @@
     <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_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_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>
@@ -879,7 +897,7 @@
     <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_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>
@@ -910,10 +928,10 @@
     <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_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" 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>
@@ -945,17 +963,17 @@
     <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="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="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>
@@ -1095,7 +1113,7 @@
     <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="copyUrl" msgid="2538211579596067402">"‏کپی URL"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"انتخاب متن"</string>
     <string name="textSelectionCABTitle" msgid="5236850394370820357">"انتخاب متن"</string>
     <string name="addToDictionary" msgid="4352161534510057874">"افزودن به فرهنگ‌لغت"</string>
@@ -1117,18 +1135,18 @@
     <string name="whichApplication" msgid="4533185947064773386">"تکمیل عملکرد با استفاده از"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"انتخاب یک برنامه صفحه اصلی"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"استفاده به صورت پیش‌فرض برای این عملکرد."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"پیش‌فرض را در تنظیمات سیستم&gt; برنامه‎ها&gt; مورد دانلود شده پاک کنید."</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="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="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>
@@ -1138,9 +1156,9 @@
     <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="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>
@@ -1174,23 +1192,23 @@
     <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>
+    <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>
+    <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="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" 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_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>
@@ -1200,20 +1218,20 @@
     <string name="wifi_p2p_to_message" msgid="248968974522044099">"به:"</string>
     <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"پین لازم را تایپ کنید:"</string>
     <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"پین:"</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"در حین اتصال به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ارتباط این رایانه لوحی با Wi-Fi موقتاً قطع خواهد شد."</string>
-    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"این گوشی به‌طور موقت از Wi-Fi قطع خواهد شد، در حالی که به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> وصل است"</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"‏در حین اتصال به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ارتباط این رایانه لوحی با Wi-Fi موقتاً قطع خواهد شد."</string>
+    <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"‏این گوشی به‌طور موقت از Wi-Fi قطع خواهد شد، در حالی که به <xliff:g id="DEVICE_NAME">%1$s</xliff:g> وصل است"</string>
     <string name="select_character" msgid="3365550120617701745">"درج نویسه"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"ارسال پیامک ها"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; در حال ارسال تعداد زیادی پیامک است. آیا اجازه می‌دهید این برنامه همچنان پیامک ارسال کند؟"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; در حال ارسال تعداد زیادی پیامک است. آیا اجازه می‌دهید این برنامه همچنان پیامک ارسال کند؟"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"اجازه دادن"</string>
     <string name="sms_control_no" msgid="625438561395534982">"ردکردن"</string>
-    <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; مایل است پیامی به &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ارسال کند."</string>
+    <string name="sms_short_code_confirm_message" msgid="1645436466285310855">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; مایل است پیامی به &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt; ارسال کند."</string>
     <string name="sms_short_code_details" msgid="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_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>
@@ -1230,38 +1248,38 @@
     <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 در 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 برای حافظه ذخیره انبوه USB مشکلی بوجود آمد."</string>
-    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB متصل شد"</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 در 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 برای حافظه ذخیره انبوه 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، حافظهٔ USB مربوط به Android را در رایانهٔ خود لغو نصب کنید (\"خارج کنید\")."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"قبل از غیرفعال کردن حافظهٔ USB، کارت SD مربوط به Android را در رایانه لغو نصب کنید (\"خارج کنید\")."</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="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 مربوط به Android را در رایانهٔ خود لغو نصب کنید (\"خارج کنید\")."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"‏قبل از غیرفعال کردن حافظهٔ USB، کارت SD مربوط به Android را در رایانه لغو نصب کنید (\"خارج کنید\")."</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="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="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>
@@ -1271,40 +1289,42 @@
     <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_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="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="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="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="permlab_recovery" msgid="3157024487744125846">"تعامل با سیستم به‌روزرسانی و بازیابی"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"به یک برنامه کاربردی اجازه می‌دهد با سیستم بازیابی و به‌روزرسانی‌های سیستم تعامل داشته باشد."</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>
@@ -1329,13 +1349,13 @@
     <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_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_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>
@@ -1359,18 +1379,18 @@
     <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="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">"حافظه در حال حاضر توسط رایانه دیگری استفاده می‌شود."</string>
-    <string name="media_shared" product="default" msgid="5706130568133540435">"کارت 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>
@@ -1383,7 +1403,7 @@
     <string name="gpsVerifYes" msgid="2346566072867213563">"بله"</string>
     <string name="gpsVerifNo" msgid="1146564937346454865">"خیر"</string>
     <string name="sync_too_many_deletes" msgid="5296321850662746890">"از حد مجاز حذف فراتر رفت"</string>
-    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. می‎خواهید چه کاری انجام دهید؟"</string>
+    <string name="sync_too_many_deletes_desc" msgid="496551671008694245">"‏<xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> مورد حذف شده برای <xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>، حساب <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> وجود دارد. می‎خواهید چه کاری انجام دهید؟"</string>
     <string name="sync_really_delete" msgid="2572600103122596243">"حذف موارد"</string>
     <string name="sync_undo_deletes" msgid="2941317360600338602">"لغو موارد حذف شده"</string>
     <string name="sync_do_nothing" msgid="3743764740430821845">"اکنون کاری انجام نشود"</string>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"راه‌اندازی <xliff:g id="APPLICATION_NAME">%s</xliff:g> انجام نشد"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"اشتراک‌گذاری با"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"اشتراک‌گذاری با <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"اهرم کنترل حرکت. لمس کرده و نگهدارید."</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>
@@ -1435,20 +1447,20 @@
     <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="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_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_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_3g_limit_snoozed_title" msgid="7026739121138005231">"‏اطلاعات 2G-3G بیش از حد مجاز است"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"‏بیش از حد مجاز 4G است"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"داده‌های تلفن همراه از مقدار مجاز بیشتر است"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"از محدوده مجاز داده‌های Wi-Fi بیشتر شد"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"‏از محدوده مجاز داده‌های 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>
@@ -1464,8 +1476,8 @@
     <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="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>
@@ -1483,20 +1495,26 @@
     <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_chooser_title" msgid="1751618554539087622">"برقراری ارتباط با دستگاه"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"فرستادن صفحه نمایش به دستگاه"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"در حال جستجو برای دستگاه‌ها..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"تنظیمات"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"قطع ارتباط"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"در حال اسکن کردن…"</string>
     <string name="media_route_status_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_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_connecting_title" msgid="2838646471050359706">"درحال فرستادن صفحه نمایش"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"درحال اتصال به <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"درحال فرستادن صفحه نمایش"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"به <xliff:g id="NAME">%1$s</xliff:g> متصل شد"</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>
@@ -1514,16 +1532,16 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"‏کد PUK باید ۸ عدد داشته باشد."</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_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_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>
@@ -1532,8 +1550,8 @@
     <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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"برای خروج از تمام صفحه از بالا به پایین بکشید"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"برای خروج از حالت تمام صفحه، انگشت خود را به تندی از بالای صفحه به پایین بکشید."</string>
+    <string name="done_label" msgid="2093726099505892398">"انجام شد"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"لغزنده دایره‌ای ساعت"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"لغزنده دایره‌ای دقیقه"</string>
+    <string name="select_hours" msgid="6043079511766008245">"انتخاب ساعت"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"انتخاب دقیقه"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"جدول روزها براساس ماه"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"لیست سال‌ها"</string>
+    <string name="select_day" msgid="7774759604701773332">"انتخاب ماه و روز"</string>
+    <string name="select_year" msgid="7952052866994196170">"انتخاب سال"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> انتخاب شد"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> حذف شد"</string>
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 3130cba..fe3c4617 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Kirjoita vähintään 8 numeron pituinen PUK-koodi."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-korttisi on PUK-lukittu. Poista lukitus antamalla PUK-koodi."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Pura SIM-kortin esto antamalla PUK2-koodi."</string>
+    <string name="enablePin" msgid="209412020907207950">"Epäonnistui, ota SIM-/RUIM-lukitus käyttöön."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Sinulla on <xliff:g id="NUMBER">%d</xliff:g> yritys jäljellä, ennen kuin SIM-kortti lukitaan."</item>
+    <item quantity="other" msgid="7530597808358774740">"Sinulla on <xliff:g id="NUMBER">%d</xliff:g> yritystä jäljellä, ennen kuin SIM-kortti lukitaan."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI-koodi"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Soittajan tunnus"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"poista pikakuvakkeita"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Antaa sovelluksen poistaa aloitusruudun pikakuvakkeita ilman käyttäjän toimia."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ohjaa uudelleen lähtevät puhelut"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Antaa sovelluksen käsitellä lähteviä puheluita ja muuttaa kohdenumeroita. Sovellus voi valvoa, uudelleenohjata tai estää lähteviä puheluita."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Sallii sovelluksen nähdä numeron, joka valitaan lähtevää puhelua soitettaessa, ja antaa mahdollisuuden ohjata puhelun eri numeroon tai keskeyttää puhelun kokonaan."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"vastaanota tekstiviestejä (teksti)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Antaa sovelluksen vastaanottaa ja käsitellä tekstiviestejä. Sovellus voi valvoa tai poistaa laitteeseesi lähetettyjä viestejä näyttämättä niitä sinulle."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"vastaanota tekstiviestejä (multimedia)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Antaa sovelluksen sitoutua VPN-palvelun ylemmän tason käyttöliittymään. Ei tavallisten sovellusten käyttöön."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"sido taustakuvaan"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Antaa sovelluksen sitoutua taustakuvan ylätason käyttöliittymään. Ei tavallisten sovellusten käyttöön."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"etänäyttöön sitoutuminen"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Antaa sovelluksen sitoutua etänäytön ylemmän tason käyttöliittymään. Ei tavallisten sovelluksien käyttöön."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sitoudu widget-palveluun"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"suorita sovellus laitteen ollessa käyttämättömänä"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Tämä oikeus sallii Android-järjestelmän siirtää sovelluksen suorituksen taustalle, kun laite ei ole käytössä."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Antaa sovelluksen käyttää SurfaceFlingerin matalan tason ominaisuuksia."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lue kehyspuskuria"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Antaa sovelluksen lukea kehyspuskurin sisältöä."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlingerin käyttäminen"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Antaa sovelluksen käyttää InputFlingerin matalan tason ominaisuuksia."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"määritä wifi-näyttöjen asetukset"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Antaa sovelluksen tallentaa ääntä mikrofonin avulla. Sovellus voi tallentaa ääntä milloin tahansa pyytämättä sinulta lupaa."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM-viestintä"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Antaa sovelluksen lähettää komentoja SIM-kortille. Tämä ei ole turvallista."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ota kuvia ja videoita"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Antaa sovelluksen ottaa kuvia ja kuvata videoita kameralla. Sovellus voi käyttää kameraa milloin tahansa ilman lupaasi."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"poista lähetyksen merkkivalo käytöstä, kun kameraa käytetään"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Antaa sovelluksen hallita laitteen puhelinominaisuuksia. Jos sovelluksella on tämä oikeus, se voi esimerkiksi vaihtaa verkkoa tai ottaa puhelinradion käyttöön tai poistaa sen käytöstä ilmoittamatta käyttäjälle."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lue puhelimen tila ja identiteetti"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Antaa sovelluksen käyttää laitteen puhelinominaisuuksia. Sovellus voi määrittää puhelinnumeron ja laitteen tunnuksen, puhelun tilan sekä soitetun numeron."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"lue puhelimen tarkat tilat"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Antaa sovelluksen käyttää puhelimen tarkkoja tiloja. Tämän oikeus antaa sovelluksen määrittää puhelun todellisen tilan, eli onko puhelu aktiivinen vai taustalla, puhelujen epäonnistumiset, tietoliikenneyhteyden tarkan tilan ja tietoliikenneyhteyden muodostuksen epäonnistumiset."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"estä tablet-laitetta menemästä virransäästötilaan"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"Muuttaa syöttölaitteen kalibrointia."</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Antaa sovelluksen muokata kosketusnäytön kalibrointiparametreja. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Koti"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Työ"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Muu"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Tämän kontaktin katselemiseen ei löydy sovellusta."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Vuorovaikutus päivitys- ja palautusjärjestelmän kanssa"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Sallii sovelluksen vuorovaikutuksen palautusjärjestelmän ja järjestelmäpäivitysten kanssa."</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>
@@ -1414,18 +1434,10 @@
     <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">"Valitse sovellus"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ei käynnisty"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Jaa seuraavien kanssa:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Jaa sovelluksessa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Liukuva valitsin. Kosketa pitkään."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Poista lukitus liu\'uttamalla."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Liitä kuulokkeet kuullaksesi, mitä näppäimiä painat kirjoittaessasi salasanaa."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Piste."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Järjestelmä"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ääni"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Langaton näyttö"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Median äänentoisto"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Yhdistä laitteeseen"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Lähetä näyttö laitteeseen"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Etsitään laitteita…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Asetukset"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Katkaise yhteys"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Etsitään..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Yhdistetään..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Käytettävissä"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Lähetetään näyttöä"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Yhdistetään näyttöön <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Lähetetään näyttöä"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Yhdistetty näyttöön <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Katkaise yhteys"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK-koodissa tulee olla 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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Poistu koko näytön tilasta liu\'uttamalla alas."</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Poistu koko näytön tilasta pyyhkäisemällä alas."</string>
+    <string name="done_label" msgid="2093726099505892398">"Valmis"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Tuntien ympyränmuotoinen liukusäädin"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minuuttien ympyränmuotoinen liukusäädin"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Valitse tunnit"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Valitse minuutit"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Päiväruudukko kuukausittain"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Vuosiluettelo"</string>
+    <string name="select_day" msgid="7774759604701773332">"Valitse kuukausi ja päivä"</string>
+    <string name="select_year" msgid="7952052866994196170">"Valitse vuosi"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valittu"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> poistettiin"</string>
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 385ed4b..acf58ca 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Opération infructueuse. Activez le verrouillage SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative avant que votre carte SIM soit verrouillée."</item>
+    <item quantity="other" msgid="7530597808358774740">"Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative(s) avant que votre carte SIM soit verrouillée."</item>
+  </plurals>
     <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>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"désinstaller des raccourcis"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permet à l\'application de supprimer des raccourcis de la page d\'accueil sans intervention de l\'utilisateur."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permet à l\'application de lire le numéro composé lors d\'un appel sortant et lui donne la possibilité de rediriger l\'appel vers un autre numéro ou d\'abandonner l\'appel."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"lier à un écran distant"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un écran distant. 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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"exécuter l\'application lorsque l\'appareil est inactif"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Cette autorisation permet au système Android d\'exécuter l\'application en arrière-plan lorsque l\'appareil est inactif."</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>
@@ -477,6 +486,8 @@
     <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_accessInputFlinger" msgid="5348635270689553857">"accéder à InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet à l\'application d\'utiliser les fonctionnalités de bas niveau de SurfaceFlinger."</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>
@@ -495,6 +506,8 @@
     <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_sim_communication" msgid="1180265879464893029">"Communication avec la carte SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permet à l\'application d\'envoyer des commandes à la carte SIM. Cette fonctionnalité est très dangereuse."</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>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"Accéder aux états précis du téléphone"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permet à l\'application d\'accéder aux états précis du téléphone. Cette autorisation lui permet de déterminer le statut d\'appel réel, si un appel est actif ou en arrière-plan, si des appels ont échoué, l\'état précis de la connexion et si cette dernière a échoué."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"modifier le calibrage du périphérique d\'entrée"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permet à l\'application de modifier les paramètres de calibrage de l\'écran tactile. 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>
@@ -783,7 +800,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Conversations"</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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Domicile"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Travail"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Autre"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Aucune application permettant d\'afficher ce contact n\'a été trouvée."</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>
@@ -1112,8 +1130,8 @@
     <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="capital_on" msgid="1544682755514494298">"OUI"</string>
+    <string name="capital_off" msgid="6815870386972805832">"NON"</string>
     <string name="whichApplication" msgid="4533185947064773386">"Continuer avec"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"Sélectionnez une application de l\'écran d\'accueil"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Utiliser cette application par défaut pour cette action"</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interagir avec le système de récupération et de mise à jour"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permet à une application d\'interagir avec le système de récupération et les mises à jour système."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Impossible de lancer l\'application <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Connexion à l\'appareil"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Diffuser l\'écran sur l\'appareil"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Recherche d\'appareils en cours…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Paramètres"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Déconnecter"</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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Connexion à l\'écran en cours"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Connexion au réseau <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Diffusion de l\'écran en cours"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Connecté à <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Le code PUK doit contenir 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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Balayez vers le bas pour quitter plein écran"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Balayez vers le bas pour quitter le mode plein écran"</string>
+    <string name="done_label" msgid="2093726099505892398">"Terminé"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Curseur circulaire des heures"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Curseur circulaire des minutes"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Sélectionnez les heures"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Sélectionnez les minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Calendrier mensuel sous forme de grille"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Liste des années"</string>
+    <string name="select_day" msgid="7774759604701773332">"Sélectionnez un mois et un jour"</string>
+    <string name="select_year" msgid="7952052866994196170">"Sélectionnez une année"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"« <xliff:g id="ITEM">%1$s</xliff:g> » a été sélectionné"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"« <xliff:g id="KEY">%1$s</xliff:g> » a été supprimé"</string>
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 9a44a31..bcba168 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Saisissez un code 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="enablePin" msgid="209412020907207950">"Échec de l\'opération. Veuillez activer le verrouillage de la carte SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative avant que votre carte SIM ne soit verrouillée."</item>
+    <item quantity="other" msgid="7530597808358774740">"Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentatives avant que votre carte SIM ne soit verrouillée."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"Code IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"Code MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Numéro de l\'appelant (entrant)"</string>
@@ -225,7 +230,7 @@
     <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 développement"</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="permgrouplab_display" msgid="4279909676036402636">"Interface des autres applis"</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>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"désinstaller des raccourcis"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permettre à l\'application de supprimer des raccourcis de l\'écran d\'accueil sans l\'intervention de l\'utilisateur"</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permettre à l\'application de lire le numéro composé lors d\'un appel sortant, et lui donner la possibilité de rediriger l\'appel vers un autre numéro ou d\'abandonner l\'appel"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"recevoir des messages texte (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permet à l\'application de recevoir et de traiter les SMS. Cette autorisation lui donne la possibilité de surveiller ou supprimer les messages envoyés à votre appareil sans vous les montrer."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"recevoir des messages texte (MMS)"</string>
@@ -348,7 +353,7 @@
     <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 permission."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"Affichage de 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="permlab_systemAlertWindow" msgid="3543347980839518613">"S\'afficher en surimpression dans les autres applis"</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">"Réglage de 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>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permet à l\'application autorisée de s\'associer à l\'interface de plus haut niveau d\'un service VPN. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"Se fixer sur 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_bindRemoteDisplay" msgid="1782923938029941960">"s\'associer à un écran à distance"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permettre à l\'application autorisée de s\'associer à l\'interface de niveau supérieur d\'un écran à distance. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"associer à un service 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 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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"exécuter l\'application lorsque l\'appareil est inactif"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Cette autorisation permet au système Android d\'exécuter l\'application en arrière-plan lorsque l\'appareil est inactif."</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>
@@ -477,6 +486,8 @@
     <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">"Lecture de 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_accessInputFlinger" msgid="5348635270689553857">"accéder à InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permet à l\'application d\'utiliser les fonctionnalités de base d\'InputFlinger."</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>
@@ -493,8 +504,10 @@
     <string name="permdesc_mediaContentControl" msgid="1637478200272062">"Permet à l\'application de contrôler la lecture des contenus multimédias et d\'accéder aux informations associées, telles que le titre ou l\'auteur."</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>
+    <string name="permlab_recordAudio" msgid="3876049771427466323">"enregistrer des fichiers 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_sim_communication" msgid="1180265879464893029">"Communication avec la carte SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Autoriser l\'envoi de commandes à la carte SIM via l\'application. Cette fonctionnalité est très risquée."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"prendre des photos et enregistrer 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>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"Accéder aux états précis du téléphone"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permet à l\'application d\'accéder aux états précis du téléphone. Cette autorisation lui permet de déterminer le statut d\'appel réel, si un appel est actif ou en arrière-plan, si des appels ont échoué, l\'état précis de la connexion et si cette dernière a échoué."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"modifier le calibrage du périphérique d\'entrée"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permettre à l\'application de modifier les paramètres de calibrage de l\'écran tactile. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Domicile"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Professionnelle"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Autre"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Aucune application permettant d\'afficher ce contact n\'a été trouvée."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interagir avec le système de récupération et de mise à jour"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permet à une application d\'interagir avec le système de récupération et les mises à jour du système."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Impossible de lancer l\'application <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partager 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">"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="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_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>
@@ -1483,8 +1495,12 @@
     <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">"OK"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Sortie multimédia"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Connexion à l\'appareil"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Caster l\'écran sur l\'appareil"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Recherche d\'appareils en cours…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Paramètres"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Déconnecter"</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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Diffusion de l\'écran en cours"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Connexion à <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Diffusion de l\'écran en cours"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Connecté à <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"La clé PUK doit contenir 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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Balayer vers le bas pour quitter le plein écran"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Faites glisser le doigt vers le bas pour quitter le mode plein écran."</string>
+    <string name="done_label" msgid="2093726099505892398">"OK"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Curseur circulaire des heures"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Curseur circulaire des minutes"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Sélectionner une heure"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Sélectionner des minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Calendrier mensuel sous forme de grille"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Liste des années"</string>
+    <string name="select_day" msgid="7774759604701773332">"Sélectionner un mois et un jour"</string>
+    <string name="select_year" msgid="7952052866994196170">"Sélectionner une année"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"\"<xliff:g id="ITEM">%1$s</xliff:g>\" sélectionné"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"\"<xliff:g id="KEY">%1$s</xliff:g>\" supprimé"</string>
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 73575bd..05e5941 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"ऐसा PUK लिखें जो 8 अंकों या अधिक का हो."</string>
     <string name="needPuk" msgid="919668385956251611">"आपका सिम कार्ड PUK लॉक किया गया है. इसे अनलॉक करने के लिए PUK कोड लिखें."</string>
     <string name="needPuk2" msgid="4526033371987193070">"सिम कार्ड अनब्‍लॉक करने के लिए PUK2 लिखें."</string>
+    <string name="enablePin" msgid="209412020907207950">"असफल, सिम//RUIM लॉक सक्षम करें."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"सिम के लॉक हो जाने से पहले आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष है."</item>
+    <item quantity="other" msgid="7530597808358774740">"सिम के लॉक हो जाने से पहले आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष हैं."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"इनकमिंग कॉलर ID"</string>
@@ -150,9 +155,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>
@@ -205,8 +210,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>
@@ -224,9 +229,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>
@@ -237,443 +242,455 @@
     <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_install_shortcut" msgid="4279070216371564234">"शॉर्टकट इंस्‍टॉल करें"</string>
     <string name="permdesc_install_shortcut" msgid="8341295916286736996">"एप्‍लिकेशन को उपयोगकर्ता के हस्‍तक्षेप के बिना होमस्‍क्रीन शॉर्टकट जोड़ने की अनुमति देता है."</string>
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"शॉर्टकट अनइंस्टॉल करें"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"एप्‍लिकेशन को उपयोगकर्ता के हस्‍तक्षेप के बिना होमस्‍क्रीन शॉर्टकट निकालने की अनुमति देता है."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"आउटगोइंग कॉल को कहीं और भेजें"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"एप्‍स को आउटगोइंग कॉल संसाधित करने और डायल किए जाने वाला नंबर बदलने देता है. यह अनुमति एप्‍स को आउटगोइंग कॉल की निगरानी करने, रीडायरेक्‍ट करने, या उन्‍हें रोकने देती है."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"ऐप्स को किसी कॉल को भिन्न नंबर पर रिडायरेक्ट करने या पूरी तरह से कॉल निरस्त करने के विकल्प के साथ आउटगोइंग कॉल के दौरान डायल किए जा रहे नंबर को देखने की अनुमति देती है."</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="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="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="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_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="permdesc_bindPrintService" msgid="7960067623209111135">"धारक को किसी प्रिंट सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य ऐप्स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_bindPrintSpoolerService" msgid="6807762783744125954">"प्रिंट स्पूलर सेवा से आबद्ध करें"</string>
-    <string name="permdesc_bindPrintSpoolerService" msgid="3680552285933318372">"धारक को प्रिंट स्पूलर सेवा के शीर्ष-स्‍तर इंटरफ़ेस से आबद्ध होने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</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="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_bindRemoteDisplay" msgid="1782923938029941960">"रिमोट डिस्प्ले से आबद्ध करें"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"धारक को किसी रिमोट डिस्प्ले के शीर्ष-स्‍तरीय इंटरफ़ेस से आबद्ध होने देती है. सामान्‍य ऐप्स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</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="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="permdesc_manageCaCertificates" msgid="4015644047196937014">"ऐप्स  को CA प्रमाणपत्रों को विश्वसनीय क्रेडेंशियल के रूप में इंस्टॉल और अनइंस्टॉल करने दें"</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"निष्क्रिय समय के दौरान एप्लिकेशन चलाएं"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"यह अनुमति Android सिस्टम को उपकरण के उपयोग में नहीं रहने पर एप्लिकेशन को पृष्ठभूमि में चलाने देती है."</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="permdesc_writeSecureSettings" msgid="8159535613020137391">"ऐप्स  को सिस्टम के सुरक्षित सेटिंग डेटा को संशोधित करने देता है. सामान्‍य ऐप्स द्वारा उपयोग करने के लिए नहीं."</string>
     <string name="permlab_writeGservices" msgid="2149426664226152185">"Google सेवाएं नक्शा बदलें"</string>
-    <string name="permdesc_writeGservices" msgid="1287309437638380229">"एप्‍स को 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="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="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_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_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="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>
+    <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="permdesc_captureVideoOutput" msgid="359481658034149860">"ऐप्स को वीडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
     <string name="permlab_captureSecureVideoOutput" msgid="7815398969303382016">"सुरक्षित वीडियो आउटपुट को कैप्‍चर करें"</string>
-    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"एप्‍स को सुरक्षित वीडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
+    <string name="permdesc_captureSecureVideoOutput" msgid="2779793064709350289">"ऐप्स को सुरक्षित वीडियो आउटपुट को कैप्‍चर और रीडायरेक्‍ट करने देता है."</string>
     <string name="permlab_mediaContentControl" msgid="8749790560720562511">"मीडिया प्लेबैक और मेटाडेटा एक्सेस नियंत्रित करें"</string>
     <string name="permdesc_mediaContentControl" msgid="1637478200272062">"एप्लिकेशन को मीडिया प्लेबैक नियंत्रित करने देती है और मीडिया जानकारी (शीर्षक, लेखक...) एक्सेस करने देती है."</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_sim_communication" msgid="1180265879464893029">"सिम संचार"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"ऐप्स को सिम में आदेश भेजने देती है. यह बहुत ही खतरनाक है."</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="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="permdesc_asec_access" msgid="3094563844593878548">"ऐप्स  को मोबाइल संग्रहण की जानकारी प्राप्‍त करने देता है."</string>
     <string name="permlab_asec_create" msgid="6414757234789336327">"मोबाइल संग्रहण बनाएं"</string>
-    <string name="permdesc_asec_create" msgid="4558869273585856876">"एप्‍स को मोबाइल संग्रहण बनाने देता है."</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="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="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_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="permdesc_performCdmaProvisioning" msgid="1994193538802314186">"ऐप्स को CDMA प्रावधान प्रारंभ करने देता है. दुर्भावनापूर्ण ऐप्स अनावश्‍यक रूप से CDMA प्रावधान प्रारंभ कर सकते हैं."</string>
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"स्‍थान के बारे में नई जानकारी की सूचनाओं को नियंत्रित करें"</string>
-    <string name="permdesc_locationUpdates" msgid="1120741557891438876">"एप को रेडियो से स्‍थान के बारे में नई जानकारी की सूचनाएं सक्षम/अक्षम करने देता है. सामान्‍य एप्‍स द्वारा उपयोग करने के लिए नहीं."</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_readPrecisePhoneState" msgid="5476483020282007597">"सटीक फ़ोन स्थितियों को पढ़ना"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ऐप्स को सटीक फ़ोन स्थितियों की एक्सेस देती है. यह अनुमति ऐप्स को कॉल की वास्तविक स्थिति, चाहे वह कॉल सक्रिय हो या पृष्ठभूमि में हो, कॉल विफलताओं, सटीक डेटा कनेक्शन की स्थिति और डेटा कनेक्शन विफलताओं का पता लगाने देती है."</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>
     <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>
-    <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_bluetoothPriv" msgid="4009494246009513828">"एप्‍लिकेशन के द्वारा Bluetooth युग्‍मन करने देती है"</string>
     <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"एप्‍लिकेशन को उपयोगकर्ता के इंटरैक्शन के बिना दूरस्‍थ उपकरणों के साथ युग्‍मित करने देती है."</string>
     <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"एप्‍लिकेशन को उपयोगकर्ता के इंटरैक्शन के बिना दूरस्‍थ उपकरणों के साथ युग्‍मित करने देती है."</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="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"ऐप्स  को आपके वर्तमान समन्वयित फ़ीड को संशोधित करने देता है. दुर्भावनापूर्ण ऐप्स  आपके समन्वयित फ़ीड को बदल सकते है."</string>
     <string name="permlab_readDictionary" msgid="4107101525746035718">"शब्दकोश में आपके द्वारा जोड़े गए शब्‍दों को पढ़ें"</string>
-    <string name="permdesc_readDictionary" msgid="659614600338904243">"एप्‍स को ऐसे सभी शब्‍दों, नामों और वाक्यांशों को पढ़ने देता है जो संभवत: उपयोगकर्ता द्वारा उपयोगकर्ता ‍शब्दकोश में संग्रहीत किए गए हों."</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_writeDictionary" msgid="8185385716255065291">"ऐप्स  को उपयोगकर्ता शब्दकोश में नए शब्द लिखने देता है."</string>
     <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"अपने USB संग्रहण की सामग्री पढ़ें"</string>
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"अपने SD कार्ड की सामग्री पढ़ें"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"एप्‍लिकेशन को आपके USB संग्रहण की सामग्री पढ़ने की अनुमति देता है."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"एप्‍लिकेशन को आपके SD कार्ड की सामग्री पढ़ने की अनुमति देता है."</string>
     <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"अपने USB संग्रहण की सामग्री बदलें या हटाएं"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"अपने SD कार्ड की सामग्री बदलें या हटाएं"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"एप्लि. को USB संग्रहण में लिखने देता है."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"एप्स को SD कार्ड पर लिखने देता है."</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"ऐप्स को USB संग्रहण में लिखने देता है."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"ऐप्स  को SD कार्ड पर लिखने देता है."</string>
     <string name="permlab_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="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_bind_call_service" msgid="6724009726671246551">"इन-कॉल स्क्रीन से सहभागिता करें"</string>
     <string name="permdesc_bind_call_service" msgid="8732547662442572435">"एप्लिकेशन को यह नियंत्रित करने देती है कि उपयोगकर्ता को इन-कॉल स्क्रीन कब और कैसी दिखाई देती है."</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="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="permlab_invokeCarrierSetup" msgid="3699600833975117478">"वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन एप्स प्रारंभ करें"</string>
-    <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन एप्स प्रारंभ करने देता है. सामान्‍य एप्‍स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</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="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ऐप्स  को नेटवर्क स्थितियों के अवलोकनों को सुनने देता है. सामान्य ऐप्स  के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट उपकरण कैलिब्रेशन बदलें"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ऐप्स को टच स्क्रीन के कैलिब्रेशन पैरामीटर को बदलने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्‍क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्‍क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
@@ -691,7 +708,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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"घर"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"कार्यालय"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"अन्य"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"इस संपर्क को देखने के लिए कोई एप्लिकेशन नहीं मिला."</string>
     <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>
@@ -940,24 +958,24 @@
     <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="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>
@@ -1105,7 +1123,7 @@
     <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="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>
@@ -1119,8 +1137,8 @@
     <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>
@@ -1139,20 +1157,20 @@
     <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>
@@ -1204,7 +1222,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>
@@ -1213,7 +1231,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>
@@ -1247,7 +1265,7 @@
     <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="usb_mtp_notification_title" msgid="3699913097391550394">"किसी मीडिया उपकरण के रूप में कनेक्‍ट किया गया"</string>
@@ -1296,15 +1314,17 @@
     <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="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="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="permdesc_control_keyguard" msgid="3043732290518629061">"ऐप्स  को कीगार्ड नियंत्रित करने देती है."</string>
+    <string name="permlab_recovery" msgid="3157024487744125846">"अपडेट और पुनर्प्राप्ति सिस्टम के साथ सहभागिता करें"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"एप्लिकेशन को पुनर्प्राप्ति सिस्टम और सिस्टम अपडेट के साथ सहभागिता करने देती है."</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>
@@ -1316,7 +1336,7 @@
     <string name="ime_action_default" msgid="2840921885558045721">"निष्‍पादित करें"</string>
     <string name="dial_number_using" msgid="5789176425167573586">"<xliff:g id="NUMBER">%s</xliff:g> के उपयोग द्वारा \n नंबर डायल करें"</string>
     <string name="create_contact_using" msgid="4947405226788104538">"<xliff:g id="NUMBER">%s</xliff:g> का उपयोग करके\n संपर्क बनाएं"</string>
-    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"निम्‍न एक या अधिक एप्‍स अभी और भविष्‍य में आपके खाते में पहुंच की अनुमति का अनुरोध करते हैं."</string>
+    <string name="grant_credentials_permission_message_header" msgid="2106103817937859662">"निम्‍न एक या अधिक ऐप्स अभी और भविष्‍य में आपके खाते में पहुंच की अनुमति का अनुरोध करते हैं."</string>
     <string name="grant_credentials_permission_message_footer" msgid="3125211343379376561">"क्या आप इस अनुरोध को अनुमति देना चाहते हैं?"</string>
     <string name="grant_permissions_header_text" msgid="6874497408201826708">"पहुंच अनुरोध"</string>
     <string name="allow" msgid="7225948811296386551">"अनुमति दें"</string>
@@ -1413,19 +1433,11 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> को लॉन्च नहीं किया जा सका"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"इसके साथ साझा करें:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> के साथ साझा करें"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"स्लाइडिंग हैंडल. स्पर्श करके रखें."</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"उपकरण से कनेक्ट करें"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"स्क्रीन को उपकरण में कास्ट करें"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"उपकरण खोजे जा रहे हैं…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"सेटिंग"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"डिस्कनेक्ट करें"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"स्‍कैन कर रहा है..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"कनेक्ट हो रहा है..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"उपलब्ध"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"स्क्रीन कास्ट हो रही है"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"<xliff:g id="NAME">%1$s</xliff:g> से कनेक्ट हो रहा है"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"स्क्रीन कास्ट हो रही है"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"<xliff:g id="NAME">%1$s</xliff:g> से कनेक्ट है"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK कोड 8 अंकों का होना चाहिए."</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"सही PUK कोड पुन: डालें. बार-बार प्रयास करने से सिम स्थायी रूप से अक्षम हो जाएगी."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"पिन कोड का मिलान नहीं होता"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"बहुत अधिक आकार प्रयास"</string>
@@ -1543,8 +1561,8 @@
     <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="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="1994474252931294172">"ISO A0"</string>
     <string name="mediasize_iso_a1" msgid="3333060421529791786">"ISO A1"</string>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"बाद में पुनः प्रयास करें"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"पूर्ण स्क्रीन से बाहर आने के लिए ऊपर से नीचे स्वाइप करें."</string>
+    <string name="done_label" msgid="2093726099505892398">"पूर्ण"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"घंटो का चक्राकार स्लाइडर"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"मिनटों का चक्राकार स्लाइडर"</string>
+    <string name="select_hours" msgid="6043079511766008245">"घंटे चुनें"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"मिनट चुनें"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"दिनों की माह ग्रिड"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"वर्ष की सूची"</string>
+    <string name="select_day" msgid="7774759604701773332">"माह और दिन चुनें"</string>
+    <string name="select_year" msgid="7952052866994196170">"वर्ष चुनें"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> चयनित"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> को हटा दिया गया"</string>
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 37dc141..19afc6c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Upišite PUK koji se sastoji od barem 8 brojeva."</string>
     <string name="needPuk" msgid="919668385956251611">"Vaša je SIM kartica zaključana PUK-om. Unesite PUK kôd da biste je otključali."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Unesite PUK2 da biste odblokirali SIM karticu."</string>
+    <string name="enablePin" msgid="209412020907207950">"Neuspješno; omogući zaključavanje SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Imate još <xliff:g id="NUMBER">%d</xliff:g> pokušaj prije zaključavanja SIM kartice."</item>
+    <item quantity="other" msgid="7530597808358774740">"Imate još nekoliko preostalih pokušaja (<xliff:g id="NUMBER">%d</xliff:g>) prije zaključavanja SIM kartice."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID dolaznog pozivatelja"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"deinstaliranje prečaca"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Aplikaciji omogućuje uklanjanje prečaca početnog zaslona bez intervencije korisnika."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"preusmjeravanje odlaznih poziva"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Aplikaciji omogućuje obradu odlaznih poziva i promjenu broja za biranje. Ta dozvola aplikaciji omogućuje nadziranje, preusmjeravanje ili sprječavanje odlaznih poziva."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Omogućuje aplikaciji da vidi broj koji se bira prilikom odlaznog poziva uz opciju preusmjeravanja poziva na neki drugi broj ili prekidanja poziva."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"primanje tekstnih poruka (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Aplikaciji omogućuje primanje i obradu SMS poruka. To znači da aplikacija može nadzirati ili izbrisati poruke poslane na vaš uređaj, a da vam ih ne prikaže."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"primanje tekstnih poruka (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Nositelju omogućuje vezanje uz sučelje najviše razine VPN usluge. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"povezano s pozadinskom slikom"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Nositelju omogućuje povezivanje sa sučeljem pozadinske slike najviše razine. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"vezanje uz udaljeni zaslon"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Nositelju omogućuje vezanje uza sučelje najviše razine udaljenog zaslona. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vezanje na uslugu widgeta"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"izvodi aplikaciju tijekom mirovanja"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dopuštenje omogućuje sustavu Android da izvodi aplikaciju u pozadini dok se uređaj ne upotrebljava."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Aplikaciji omogućuje upotrebu značajki niske razine SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"čitanje međuspremnika okvira"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Aplikaciji omogućuje čitanje sadržaja međuspremnika okvira."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"pristupi InputFlingeru"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Dopušta aplikaciji upotrebu značajki niske razine InputFlingera."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfiguriraj Wifi zaslone"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Aplikaciji omogućuje snimanje zvuka mikrofonom. Ta dozvola aplikaciji omogućuje snimanje zvuka u bilo kojem trenutku bez vašeg odobrenja."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"komunikacija sa SIM-om"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Omogućuje aplikaciji slanje naredbi SIM-u. To je vrlo opasno."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"snimi fotografije i videozapise"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Aplikaciji omogućuje snimanje slika i videozapisa fotoaparatom. Ta dozvola aplikaciji omogućuje upotrebu fotoaparata u bilo kojem trenutku bez vašeg odobrenja."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"onemogućavanje lampice pokazivača prijenosa kada je fotoaparat u upotrebi"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Omogućuje aplikaciji upravljanje telefonskim značajkama uređaja. Aplikacija s tom dozvolom može izmjenjivati mreže, uključiti i isključiti radiouređaj telefona i tome slično, a da vas o tome uopće ne obavijesti."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čitanje statusa i identiteta telefona"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Aplikaciji omogućuje pristup telefonskim značajkama uređaja. Ta dozvola aplikaciji omogućuje utvrđivanje telefonskog broja i ID-ova uređaja, je li poziv aktivan te udaljeni broj koji je povezan pozivom."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čitaj precizna stanja telefona"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Omogućuje aplikaciji pristup preciznim stanjima telefona. To dopuštenje omogućuje aplikaciji da odredi stvarni status poziva, je li poziv aktivan ili u pozadini, neuspjele pozive, precizne podatke o statusu veze te neuspjela uspostavljanja podatkovnih veza."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"spriječi mirovanje tabletnog uređaja"</string>
     <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>
@@ -620,7 +635,7 @@
     <string name="permlab_bluetooth" msgid="6127769336339276828">"uparivanje s Bluetooth uređajima"</string>
     <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na tabletnom računalu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Aplikaciji omogućuje pregled konfiguracije Bluetootha na telefonu te uspostavljanje i prihvaćanje veza s uparenim uređajima."</string>
-    <string name="permlab_nfc" msgid="4423351274757876953">"upravljaj beskontaktnom (NFC) komunikacijom"</string>
+    <string name="permlab_nfc" msgid="4423351274757876953">"upravljanje beskontaktnom komunikacijom (NFC)"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Aplikaciji omogućuje komunikaciju s oznakama, karticama i čitačima komunikacije kratkog dometa (NFC)."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"onemogućavanje zaključavanja zaslona"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Aplikaciji omogućuje onemogućavanje zaključavanja tipkovnice i svih pripadajućih sigurnosnih zaporki. Na primjer, telefon onemogućuje zaključavanje tipkovnice kod primanja dolaznog telefonskog poziva, nakon kojeg se zaključavanje tipkovnice ponovo omogućuje."</string>
@@ -642,7 +657,7 @@
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čitanje sadržaja SD kartice"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Aplikaciji omogućuje čitanje sadržaja vaše USB pohrane."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Aplikaciji omogućuje čitanje sadržaja vaše SD kartice."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"izmjena/brisanje sadrž. USB-a"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"izmjena/brisanje sadržaja USB-a"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"izmjena ili brisanje sadržaja SD kartice"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Dopušta pisanje u USB pohranu."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Aplikaciji omogućuje pisanje na SD karticu."</string>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"promjena kalibracije uređaja za unos"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Omogućuje aplikaciji izmjenu parametara kalibracije dodirnog zaslona. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Početna"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Posao"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Drugo"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nema aplikacije za prikazivanje tog kontakta."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interakcija s ažuriranjem i sustavom za oporavak"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Omogućuje aplikaciji interakciju sa sustavom za oporavak i ažuriranjima sustava."</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>
@@ -1414,18 +1434,10 @@
     <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">"Odabir aplikacije"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nije moguće pokrenuti aplikaciju <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dijeljenje sa"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dijeli s aplikacijom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Klizna ručka. Dodirnite i držite."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Prijeđite prstima da biste otključali."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Priključite slušalice kako biste čuli izgovaranje tipki zaporke."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Točka."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sustav"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth zvuk"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bežični prikaz"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotovo"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Medijski izlaz"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Povezivanje s uređajem"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Emitiranje zaslona na uređaj"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Traženje uređaja…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Postavke"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Prekini vezu"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Skeniranje..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Povezivanje..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Dostupno"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Emitiranje zaslona"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Povezivanje sa zaslonom <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Emitiranje zaslona"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Povezan sa zaslonom <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Isključi"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK kôd mora se sastojati od 8 brojeva."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Pokušajte ponovo kasnije"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Prijeđite prstom s vrha prema dolje za izlaz iz cijelog zaslona."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gotovo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kružni klizač sati"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kružni klizač minuta"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Odaberite sate"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Odaberite minute"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Mreža dana u mjesecu"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Popis godina"</string>
+    <string name="select_day" msgid="7774759604701773332">"Odaberite mjesec i dan"</string>
+    <string name="select_year" msgid="7952052866994196170">"Odaberite godinu"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Odabrana je stavka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Izbrisan je broj <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4ae5938..b40117b 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -48,8 +48,13 @@
     <string name="mismatchPin" msgid="609379054496863419">"A beírt PIN kódok nem egyeznek."</string>
     <string name="invalidPin" msgid="3850018445187475377">"Írjon be egy 4-8 számjegyű PIN-kódot."</string>
     <string name="invalidPuk" msgid="8761456210898036513">"8 számjegyű vagy hosszabb PUK kódot írjon be."</string>
-    <string name="needPuk" msgid="919668385956251611">"A SIM-kártya le van zárva a PUK-kóddal. A feloldáshoz adja meg a PUK-kódot."</string>
-    <string name="needPuk2" msgid="4526033371987193070">"A SIM-kártya feloldásához adja meg a PUK2-kódot."</string>
+    <string name="needPuk" msgid="919668385956251611">"A SIM kártya le van zárva a PUK kóddal. A feloldáshoz adja meg a PUK kódot."</string>
+    <string name="needPuk2" msgid="4526033371987193070">"A SIM kártya feloldásához adja meg a PUK2 kódot."</string>
+    <string name="enablePin" msgid="209412020907207950">"Sikertelen, engedélyezze a SIM-/RUIM-zárolást."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Még <xliff:g id="NUMBER">%d</xliff:g> próbálkozása van, mielőtt zároljuk a SIM kártyát."</item>
+    <item quantity="other" msgid="7530597808358774740">"Még <xliff:g id="NUMBER">%d</xliff:g> próbálkozása van, mielőtt zároljuk a SIM kártyát."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Beérkező hívóazonosító"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"parancsikonok eltávolítása"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Lehetővé teszi egy alkalmazás számára, hogy felhasználói beavatkozás nélkül távolítson el parancsikonokat a kezdőképernyőről."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"kimenő hívások átirányítása"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Lehetővé teszi az alkalmazás számára a kimenő hívások kezdeményezését, és a tárcsázandó szám módosítását. Az engedéllyel rendelkező alkalmazás felügyelheti, átirányíthatja vagy megakadályozhatja a kimenő hívásokat."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Lehetővé teszi, hogy az alkalmazás kimenő híváskor lássa a tárcsázott számot, valamint a hívást átirányítsa egy másik számra, vagy megszakítsa."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"szöveges üzenetek (SMS) fogadása"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Lehetővé teszi az alkalmazás számára, hogy SMS-eket fogadjon és dolgozzon fel. Ez azt jelenti, hogy az alkalmazás megfigyelheti vagy törölheti a beérkező üzeneteket anélkül, hogy Ön látná azokat."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"szöveges üzenetek (MMS) fogadása"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Lehetővé teszi a használó számára, hogy csatlakozzon egy VPN-szolgáltatás legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szüksége."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"összekapcsolás háttérképpel"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Lehetővé teszi, hogy a tulajdonos kötelezővé tegye egy háttérkép legfelső szintű felületét. A normál alkalmazásoknak erre soha nincs szüksége."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"csatlakozás egy távoli kijelzőhöz"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Lehetővé teszi a használó számára, hogy csatlakozzon egy távoli kijelző legfelső szintű kezelőfelületéhez. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"csatlakozás modulszolgáltatáshoz"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"alkalmazás futtatása tétlen időszakban"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ezzel az engedéllyel az Android a háttérben futtathatja az alkalmazást, amikor az eszközt nem használják."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Lehetővé teszi az alkalmazás számára a SurfaceFlinger alacsony szintű funkciók használatát."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"keretpuffer olvasása"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Lehetővé teszi az alkalmazás számára a keretpuffer tartalmának olvasását."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"hozzáférés az InputFlingerhez"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lehetővé teszi az alkalmazás számára az InputFlinger alacsony szintű funkciók használatát."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi kijelzők konfigurálása"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Lehetővé teszi az alkalmazás számára a mikrofonnal való hangfelvételt.Az engedéllyel rendelkező alkalmazás az Ön jóváhagyása nélkül, bármikor rögzíthet hanganyagot."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM-kommunikáció"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Engedélyezi, hogy az alkalmazás parancsokat küldjön a SIM kártyára. Ez rendkívül veszélyes lehet."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"fotók és videók készítése"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Lehetővé teszi az alkalmazás számára, hogy a fényképezőgéppel fotókat és videókat készítsen. Az engedéllyel rendelkező alkalmazás bármikor, az Ön jóváhagyása nélkül használhatja a fényképezőgépet."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"átviteljelző LED letiltása, ha a kamera használatban van"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Lehetővé teszi az alkalmazás számára, hogy az eszköz telefonálási funkcióit vezérelje. Egy ilyen engedéllyel rendelkező alkalmazás váltani tud a hálózatok között, be- és kikapcsolhatja a telefon rádióját, és hasonlókat tehet anélkül, hogy valaha értesítené Önt."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefonállapot és azonosító olvasása"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen az eszköz telefonálási funkcióihoz. Az engedéllyel rendelkező alkalmazás meghatározhatja a telefonszámot és eszközazonosítókat, hogy egy hívás aktív-e, valamint híváskor a másik fél telefonszámát."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"pontos telefonállapot megállapítása"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Engedélyezi, hogy az alkalmazás hozzáférjen a pontos telefonállapothoz. Az ilyen engedéllyel rendelkező alkalmazás képes meghatározni a valós hívási állapotot, azt, hogy egy hívás aktív-e vagy a háttérben van, a hívás meghiúsult-e, illetve képes meghatározni az adatkapcsolat pontos állapotát és az adatkapcsolati műveletek meghiúsulását."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"táblagép alvás üzemmódjának megakadályozása"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"beviteli eszköz kalibrációjának módosítása"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lehetővé teszi, hogy az alkalmazás módosítsa az érintőképernyő kalibrációs paramétereit. A normál alkalmazásoknál erre elvileg soha nincs szükség."</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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Otthoni"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Munkahely"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Egyéb"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nem található alkalmazás a névjegy megtekintéshez."</string>
     <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>
@@ -835,8 +853,8 @@
     <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">"Csatlakoztassa a töltőt."</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Nincs SIM kártya."</string>
-    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Nincs SIM-kártya a táblagépben."</string>
-    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Nincs SIM-kártya a telefonban."</string>
+    <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Nincs SIM kártya a táblagépben."</string>
+    <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Nincs SIM kártya a telefonban."</string>
     <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>
@@ -850,8 +868,8 @@
     <string name="lockscreen_network_locked_message" msgid="143389224986028501">"A hálózat lezárva"</string>
     <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"A SIM-kártya le van zárva a PUK-kóddal."</string>
     <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_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\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>
@@ -865,7 +883,7 @@
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Elfelejtette a mintát?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Fiók feloldása"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"Túl sok mintarajzolási próbálkozás"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"A feloldáshoz jelentkezzen be Google Fiókjával."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"A feloldáshoz jelentkezzen be Google-fiókjával."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Felhasználónév (e-mail cím)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Jelszó"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Bejelentkezés"</string>
@@ -1216,10 +1234,10 @@
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Módosítás: Beállítások &gt; Alkalmazások"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Engedélyezés mindig"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Soha nem engedélyezem"</string>
-    <string name="sim_removed_title" msgid="6227712319223226185">"SIM-kártya eltávolítva"</string>
+    <string name="sim_removed_title" msgid="6227712319223226185">"SIM kártya eltávolítva"</string>
     <string name="sim_removed_message" msgid="2333164559970958645">"A mobilhálózat nem lesz elérhető, amíg újra nem indítja egy érvényes SIM kártya behelyezése után."</string>
     <string name="sim_done_button" msgid="827949989369963775">"Kész"</string>
-    <string name="sim_added_title" msgid="3719670512889674693">"SIM-kártya hozzáadva"</string>
+    <string name="sim_added_title" msgid="3719670512889674693">"SIM kártya hozzáadva"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"A mobilhálózathoz eléréséhez indítsa újra az eszközt."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Újraindítás"</string>
     <string name="time_picker_dialog_title" msgid="8349362623068819295">"Idő beállítása"</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Kapcsolatfelvétel a frissítési és helyreállítási rendszerrel"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Lehetővé teszi egy alkalmazás számára, hogy kapcsolatba lépjen a helyreállítási rendszerrel és a rendszerfrissítésekkel."</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>
@@ -1414,18 +1434,10 @@
     <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">"Válasszon ki egy alkalmazást"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"A(z) <xliff:g id="APPLICATION_NAME">%s</xliff:g> alkalmazást indítása nem sikerült"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Megosztás a következővel:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ossza meg a következő alkalmazással: <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Csúsztatható fogantyú. Érintse meg és tartsa."</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="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_target_unlock_tablet" msgid="3833195335629795055">"A feloldásához húzza végig az ujját."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Csatlakoztasson egy fülhallgatót, ha hallani szeretné a jelszó betűit felolvasva."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pont."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Rendszer"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth hang"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Vezeték nélküli kijelző"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kész"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Médiakimenet"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Csatlakozás adott eszközhöz"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Képernyő átküldése az eszközre"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Eszközkeresés…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Beállítások"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Leválasztás"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Keresés..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Kapcsolódás..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Elérhető"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Képernyő átküldése…"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Csatlakozás a következőhöz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Képernyő átküldése…"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Csatlakozva a következőhöz: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Szétkapcsol"</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>
@@ -1514,11 +1532,11 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"A PUK kód 8 karakter hosszú kell, hogy legyen."</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_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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"A teljes képernyős nézetből való kilépéshez húzza ujját a tetejétől lefelé."</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"A teljes képernyős nézetből való kilépéshez húzza ujját a képernyő tetejétől lefelé."</string>
+    <string name="done_label" msgid="2093726099505892398">"Kész"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Óra kör alakú csúszkája"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Perc kör alakú csúszkája"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Óra kiválasztása"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Perc kiválasztása"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Napok havi leosztásban"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Évek listája"</string>
+    <string name="select_day" msgid="7774759604701773332">"Válassza ki a hónapot és a napot"</string>
+    <string name="select_year" msgid="7952052866994196170">"Válassza ki az évet"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> kiválasztva"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"A(z) <xliff:g id="KEY">%1$s</xliff:g> érték törölve"</string>
 </resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 96ff31e..62464ba 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Ձախողվեց: Միացրեք SIM/RUIM կողպումը:"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Մնաց <xliff:g id="NUMBER">%d</xliff:g> փորձ՝ մինչև SIM-ի արգելափակումը:"</item>
+    <item quantity="other" msgid="7530597808358774740">"Մնաց <xliff:g id="NUMBER">%d</xliff:g> փորձ՝ մինչև SIM-ի արգելափակումը:"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Մուտքային զանգողի ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ապատեղադրել դյուրանցումները"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Հավելվածին թույլ է տալիս հեռացնել գլխավոր էկրանի դյուրանցումները՝ առանց օգտագործողի միջամտության:"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"վերաուղղել ելքային զանգերը"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Թույլ է տալիս հավելվածին մշակել ելքային զանգերը և փոխել համարհավաքումը: Վնասարար հավելվածները կարող են վերահսկել, վերահասցեավորել կամ կանխել ելքային զանգերը:"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Թույլ է տալիս ծրագրին ելքային զանգի ընթացքում տեսնել արդեն հավաքած համարը՝ հնարավորություն տալով վերահղել կամ անջատել զանգը։"</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"միանալ հեռակա էկրանին"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Թույլ է տալիս սեփականատիրոջը միանալ հեռակա էկրանի վերին մակարդակի ինտերֆեյսին: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"միանալ վիջեթ ծառայությանը"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Թույլ է տալիս սեփականատիրոջը միանալ վիջեթ ծառայության վերին մակարդակի ինտերֆեյսին: Սովորական հավելվածների համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"փոխգործակցել սարքի կառավարչի հետ"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"գործադրել ծրագրեր պարապուրդի ժամանակ"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Այս թույլտվությունը հնարավորություն է տալիս, որ Android համակարգը ծրագրեր գործադրի ֆոնային ռեժիմում, երբ սարքը չի օգտագործվում:"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"կարդալ կամ գրել ախտորոշիչին պատկանող ռեսուրսները"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Թույլ է տալիս հավելվածին կարդալ և գրել ախտորոշիչ խմբին պատկանող ցանկացած ռեսուրսում, ինչպես օրինակ ֆայլերը /dev-ում: Դա կարող է ազդել համակարգի կայունության և անվտանգության վրա: Սա պետք է օգտագործել միայն արտադրողի կամ օպերատորի կողմից սարքին հատուկ ախտորոշման համար:"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"միացնել կամ անջատել հավելվածի բաղադրիչները"</string>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Թույլ է տալիս հավելվածին փոփոխել ձայնանյութի գլոբալ կարգավորումները, ինչպես օրինակ` ձայնը և թե որ խոսափողն է օգտագործված արտածման համար:"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ձայնագրել ձայնանյութ"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Թույլ է տալիս հավելվածին բարձրախոսով ձայնագրել ձայնանյութ: Այս թույլտվությունը հնարավորություն է տալիս հավելվածին ձայնանյութ ձայնագրել ցանկացած ժամանակ` առանց ձեր հաստատման:"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM հաղորդակցում"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Թույլ է տալիս հավելվածին հրամաններ ուղարկել SIM-ին: Սա շատ վտանգավոր է:"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"լուսանկարել և տեսանկարել"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Թույլ է տալիս հավելվածին ֆոտոխցիկով լուսանկարել և տեսանկարել: Այս թույլտվությունը հնարավորություն է տալիս հավելվածին օգտագործել ֆոտոխցիկը ցանկացած ժամանակ` առանց ձեր հաստատման:"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"անջատել փոխանցող LED ցուցիչը, երբ ֆոտոխցիկը օգտագործվում է"</string>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"դիտել հեռախոսի ճշգրիտ կարգավիճակները"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Թույլ է տալիս ծրագրին մուտք ունենալ հեռախոսի ճշգրիտ կարգավիճակներին: Այս թույլատվության շնորհիվ ծրագիրը կարող է որոշել զանգի իրական կարգավիճակը, արդյոք զանգը ակտիվ է, թե հետին պլանում է, զանգերի ժամանակ տեղի ունեցած սխալները, տվյալների միացման ճշգրիտ կարգավիճակը և տվյալների միացման ժամանակ տեղի ունեցած սխալները:"</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Թույլ է տալիս սեփականատիրոջը գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"լսել դիտարկումներ ցանցային պայմանների վերաբերյալ"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Հավելվածին թույլ է տալիս լսել դիտարկումներ ցանցային պայմանների վերաբերյալ: Սովորական հավելվածների համար երբեք պետք չի գալիս:"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"փոփոխել մուտքի սարքի չափաբերումը"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Թույլ է տալիս ծրագրին փոփոխել հպէկրանի չափաբերման կարգավորումները: Սովորական ծրագրերի համար երբեք պետք չի գալու:"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Տնային"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Աշխատանքային"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Այլ"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Այս կոնտակտը դիտելու համար համապատասխան ծրագիր չկա:"</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Փոխազդել թարմացման և վերականգնման համակարգի հետ"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Թույլ է տալիս ծրագրին փոխազդել վերականգնման համակարգի և համակարգի թարմացումների հետ:"</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Չհաջողվեց գործարկել <xliff:g id="APPLICATION_NAME">%s</xliff:g> ծրագիրը"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Տարածել"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Համօգտագործել <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ի հետ"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Սահող բռնակ: Հպել &amp; պահել:"</string>
-    <string name="description_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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Միանալ սարքին"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Հեռարձակել էկրանը սարքի վրա"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Որոնվում են սարքեր..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Կարգավորումներ"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Անջատել"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Սկանավորում..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Միանում է..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Հասանելի է"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Էկրանի հեռարձակում"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Միանում է <xliff:g id="NAME">%1$s</xliff:g>-ին"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Էկրանը հեռարձակվում է"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Միացված է <xliff:g id="NAME">%1$s</xliff:g>-ին"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Կրկին փորձեք մի փոքր ուշ"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Սահահարվածեք վերից վար՝ ամբողջական էկրանից դուրս գալու համար:"</string>
+    <string name="done_label" msgid="2093726099505892398">"Պատրաստ է"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ժամերի ընտրություն թվատախտակից"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Րոպեների ընտրություն թվատախտակից"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Ընտրեք ժամը"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Ընտրեք րոպեն"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Ամսաթվի ընտրության պատուհան"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Տարիների ցանկ"</string>
+    <string name="select_day" msgid="7774759604701773332">"Ընտրեք ամիսն ու օրը"</string>
+    <string name="select_year" msgid="7952052866994196170">"Ընտրեք տարին"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Ընտրված է <xliff:g id="ITEM">%1$s</xliff:g> տարրը"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> թիվը ջնջված է"</string>
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 417c18e..b3b0d2b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ketik PUK yang terdiri dari 8 angka atau lebih."</string>
     <string name="needPuk" msgid="919668385956251611">"Kartu SIM Anda dikunci PUK. Ketikkan kode PUK untuk membukanya."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ketikkan PUK2 untuk membuka kartu SIM"</string>
+    <string name="enablePin" msgid="209412020907207950">"Gagal, aktifkan Kunci SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Sisa <xliff:g id="NUMBER">%d</xliff:g> percobaan sebelum SIM terkunci."</item>
+    <item quantity="other" msgid="7530597808358774740">"Sisa <xliff:g id="NUMBER">%d</xliff:g> percobaan sebelum SIM terkunci."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Nomor Penelepon Masuk"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"mencopot pemasangan pintasan"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Mengizinkan aplikasi menghapus pintasan Layar Utama tanpa tindakan dari pengguna."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ubah rute panggilan keluar"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Memungkinkan aplikasi memproses panggilan keluar dan mengubah nomor yang akan dipanggil. Izin ini memungkinkan aplikasi memantau, mengalihkan, atau mencegah panggilan keluar."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Memungkinkan aplikasi melihat nomor yang dihubungi saat melakukan panggilan keluar dengan opsi untuk mengalihkan panggilan ke nomor lain atau membatalkan panggilan sepenuhnya."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"terima pesan teks (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Memungkinkan aplikasi menerima dan memproses pesan SMS. Ini artinya aplikasi dapat memantau atau menghapus pesan yang dikirim ke perangkat Anda tanpa menunjukkannya kepada Anda."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"terima pesan teks (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu layanan Vpn. Tidak pernah diperlukan oleh apl normal."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"mengikat ke wallpaper"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Mengizinkan pemegang mengikat antarmuka tingkat tinggi dari suatu wallpaper. Tidak pernah diperlukan oleh apl normal."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"mengikat ke layar jarak jauh"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Mengizinkan pemegang mengikat ke antarmuka tingkat atas dari layar jarak jauh. Tidak pernah diperlukan untuk aplikasi normal."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"mengikat ke layanan widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"menjalankan aplikasi selama waktu nganggur"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Izin ini memungkinkan sistem Android menjalankan aplikasi di latar belakang saat perangkat tidak digunakan."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Mengizinkan apl menggunakan fitur tingkat rendah SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"baca buffer frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Mengizinkan apl membaca konten penyangga frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"mengakses InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Memungkinkan aplikasi menggunakan fitur tingkat rendah InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"mengonfigurasi tampilan Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Memungkinkan aplikasi merekam audio dengan mikrofon. Izin ini memungkinkan aplikasi merekam audio kapan saja tanpa konfirmasi Anda."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"komunikasi sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Mengizinkan aplikasi mengirim perintah ke SIM. Ini sangat berbahaya."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ambil gambar dan video"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Memungkinkan aplikasi mengambil gambar dan video dengan kamera. Izin ini memungkinkan aplikasi menggunakan kamera kapan saja tanpa konfirmasi Anda."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"nonaktifkan LED indikator transmisi saat kamera digunakan"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Mengizinkan apl mengontrol fitur telepon perangkat. Apl dengan izin ini dapat mengalihkan jaringan, menyalakan dan mematikan radio ponsel, dan melakukan hal serupa lainnya tanpa pernah memberi tahu Anda."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"baca identitas dan status ponsel"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Memungkinkan aplikasi mengakses fitur telepon perangkat. Izin ini memungkinkan aplikasi menentukan nomor telepon dan ID perangkat, apakah suatu panggilan aktif atau tidak, dan nomor jarak jauh yang tersambung oleh sebuah panggilan."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"membaca keadaan ponsel dengan akurat"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Memungkinkan aplikasi mengakses keadaan ponsel dengan akurat. Izin ini memungkinkan aplikasi menentukan status panggilan yang sebenarnya, apakah panggilan sedang aktif atau di latar belakang, kegagalan panggilan, status sambungan data yang akurat, dan kegagalan sambungan data."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"cegah tablet dari tidur"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"mengubah kalibrasi perangkat masukan"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Memungkinkan aplikasi mengubah parameter kalibrasi layar sentuh. Tidak diperlukan 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Beranda"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerjaan"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Lainnya"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Tidak ada aplikasi yang ditemukan untuk melihat kontak ini."</string>
     <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>
@@ -1142,15 +1160,15 @@
     <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 kebijakan StrictMode yang diberlakukannya sendiri."</string>
     <string name="smv_process" msgid="5120397012047462446">"Proses <xliff:g id="PROCESS">%1$s</xliff:g> telah melanggar kebijakan StrictMode yang diberlakukan secara otomatis."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Android sedang meningkatkan versi..."</string>
-    <string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimalkan apl <xliff:g id="NUMBER_0">%1$d</xliff:g> dari <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
-    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulai apl."</string>
+    <string name="android_upgrading_apk" msgid="7904042682111526169">"Mengoptimalkan aplikasi <xliff:g id="NUMBER_0">%1$d</xliff:g> dari <xliff:g id="NUMBER_1">%2$d</xliff:g>."</string>
+    <string name="android_upgrading_starting_apps" msgid="451464516346926713">"Memulai aplikasi."</string>
     <string name="android_upgrading_complete" msgid="1405954754112999229">"Menyelesaikan boot."</string>
     <string name="heavy_weight_notification" msgid="9087063985776626166">"<xliff:g id="APP">%1$s</xliff:g> berjalan"</string>
     <string name="heavy_weight_notification_detail" msgid="1721681741617898865">"Sentuh untuk beralih ke apl"</string>
     <string name="heavy_weight_switcher_title" msgid="7153167085403298169">"Beralih apl?"</string>
     <string name="heavy_weight_switcher_text" msgid="7022631924534406403">"Apl lain sudah berjalan dan harus dihentikan agar Anda dapat memulai yang baru."</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 memulai apl baru."</string>
+    <string name="old_app_description" msgid="2082094275580358049">"Jangan memulai aplikasi baru."</string>
     <string name="new_app_action" msgid="5472756926945440706">"Mulai <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Berinteraksi dengan sistem pemulihan dan pembaruan"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Mengizinkan aplikasi berinteraksi dengan sistem pemulihan dan pembaruan sistem."</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>
@@ -1414,18 +1434,10 @@
     <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">"Pilih apl"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Tidak dapat meluncurkan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Berbagi dengan"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Berbagi dengan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Gagang geser. Sentuh &amp; tahan."</string>
-    <string name="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="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_target_unlock_tablet" msgid="3833195335629795055">"Gesek untuk membuka kunci."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pasang headset untuk mendengar tombol sandi yang diucapkan."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Titik."</string>
@@ -1483,8 +1495,12 @@
     <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">"Layar nirkabel"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Keluaran media"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Sambungkan ke perangkat"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Transmisi layar ke perangkat"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Menelusuri perangkat…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Setelan"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Putuskan sambungan"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Memindai..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Menyambung..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Tersedia"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Transmisi layar"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Menyambung ke <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Transmisi layar"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Tersambung ke <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Putuskan sambungan"</string>
     <string name="kg_emergency_call_label" msgid="684946192523830531">"Panggilan darurat"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Lupa Pola?"</string>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Kode PUK seharusnya terdiri dari 8 angka."</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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Gesek ke bawah untuk keluar dari layar penuh"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Gesek dari atas ke bawah untuk keluar dari layar penuh."</string>
+    <string name="done_label" msgid="2093726099505892398">"Selesai"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Penggeser putar jam"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Penggeser putar menit"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pilih jam"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pilih menit"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Kisi hari pada bulan"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Daftar tahun"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pilih bulan dan hari"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dihapus"</string>
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index d2dbfc3..3faca1a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Digita un PUK formato da almeno 8 numeri."</string>
     <string name="needPuk" msgid="919668385956251611">"La SIM è bloccata tramite PUK. Digita il codice PUK per sbloccarla."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Digita il PUK2 per sbloccare la SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Operazione non riuscita; attiva blocco SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Hai ancora <xliff:g id="NUMBER">%d</xliff:g> tentativo a disposizione prima che la SIM venga bloccata."</item>
+    <item quantity="other" msgid="7530597808358774740">"Hai ancora <xliff:g id="NUMBER">%d</xliff:g> tentativi a disposizione prima che la SIM venga bloccata."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID chiamante in entrata"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"eliminazione di scorciatoie"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Consente all\'applicazione di rimuovere le scorciatoie della schermata Home automaticamente."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"reindirizzamento chiamate in uscita"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Consente all\'applicazione di elaborare le chiamate in uscita e di modificare il numero da comporre. Questa autorizzazione consente all\'applicazione di monitorare, reindirizzare o impedire le chiamate in uscita."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Consente all\'app di rilevare il numero digitato durante una chiamata in uscita, con la possibilità di reindirizzare la telefonata a un numero diverso o interromperla del tutto."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"ricezione messaggi di testo (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Consente all\'applicazione di ricevere ed elaborare messaggi SMS. Significa che l\'applicazione potrebbe monitorare o eliminare i messaggi inviati al tuo dispositivo senza mostrarteli."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"ricezione messaggi di testo (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Consente l\'associazione all\'interfaccia principale di un servizio VPN. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"associazione a sfondo"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Consente l\'associazione di uno sfondo all\'interfaccia principale. Non dovrebbe mai essere necessaria per le normali applicazioni."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"collega a un display remoto"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Consente al titolare di collegarsi all\'interfaccia di primo livello di un display remoto. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"associazione a un servizio widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"esegui l\'applicazione nel tempo di inattività del sistema"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Questa autorizzazione consente al sistema Android di eseguire l\'applicazione in background mentre il dispositivo non è in uso."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Consente all\'applicazione l\'utilizzo di funzioni di basso livello SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lettura buffer di frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Consente all\'applicazione di leggere i contenuti del buffer di frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"accesso a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Consente all\'applicazione di utilizzare funzioni di basso livello InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurazione di schermi Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Consente all\'applicazione di registrare audio con il microfono. Questa autorizzazione consente all\'applicazione di registrare audio in qualsiasi momento senza la tua conferma."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"comunicazione SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Consente all\'app di inviare comandi alla SIM. Questo è molto pericoloso."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"acquisizione di foto e video"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Consente all\'applicazione di scattare foto e riprendere video con la fotocamera. Questa autorizzazione consente all\'applicazione di utilizzare la fotocamera in qualsiasi momento senza la tua conferma."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"disabilitazione del LED di indicazione della trasmissione quando la fotocamera è in uso"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Consente all\'applicazione di controllare le funzioni telefoniche del dispositivo. Un\'applicazione con questa autorizzazione può cambiare rete, attivare/disattivare il segnale radio del telefono e così via a tua insaputa."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lettura stato e identità telefono"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Consente all\'applicazione di accedere alle funzioni telefoniche del dispositivo. Questa autorizzazione consente all\'applicazione di determinare il numero di telefono e gli ID dei dispositivi, se una chiamata è attiva e il numero remoto connesso da una chiamata."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"rileva gli stati esatti del telefono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Consente all\'app di accedere allo stato esatto del telefono. Questa autorizzazione consente all\'app di determinare il reale stato della chiamata: se una chiamata è attiva, in sottofondo o non riuscita. Inoltre, rileva l\'esatto stato della connessione dati nonché le connessioni dati non riuscite."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"disattivazione stand-by del tablet"</string>
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"disattivazione stand-by del telefono"</string>
     <string name="permdesc_wakeLock" product="tablet" msgid="7311319824400447868">"Consente all\'applicazione di impedire lo stand-by del tablet."</string>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"modifica calibrazione del dispositivo di immissione"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Consente all\'app di modificare i parametri di calibrazione del touch screen. Questa opzione non deve essere utilizzata per le app normali."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Impostazione 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">"Controllo tentativi di sblocco dello schermo"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Lavoro"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Altro"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nessuna applicazione trovata per la visualizzazione di questo contatto."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interazione con il sistema di ripristino e aggiornamento"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Consente a un\'applicazione di interagire con il sistema di ripristino e con gli aggiornamenti di sistema."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Maiuscolo"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Invio"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Scegli un\'applicazione"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Impossibile avviare l\'applicazione <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Condividi con"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Condividi con <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Maniglia scorrevole. Tocca e tieni premuto."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Fai scorrere per sbloccare."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Collega gli auricolari per ascoltare la pronuncia dei tasti premuti per la password."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punto."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Visualizzazione wireless"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fine"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Uscita media"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Connetti al dispositivo"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Trasmetti schermo al dispositivo"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Ricerca di dispositivi in corso…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Impostazioni"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Disconnetti"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Ricerca in corso..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Connessione..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponibile"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Trasmissione schermo"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Collegamento a <xliff:g id="NAME">%1$s</xliff:g> in corso"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Trasmissione schermo attiva"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Collegato a <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Disconnetti"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Il codice PUK deve essere di 8 cifre."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Riprova più tardi"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Scorri dall\'alto verso il basso per uscire dalla modalità schermo intero."</string>
+    <string name="done_label" msgid="2093726099505892398">"Fine"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Dispositivo di scorrimento circolare per le ore"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Dispositivo di scorrimento circolare per i minuti"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Seleziona le ore"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Seleziona i minuti"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Griglia di giorni per mese"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Elenco degli anni"</string>
+    <string name="select_day" msgid="7774759604701773332">"Seleziona mese e giorno"</string>
+    <string name="select_year" msgid="7952052866994196170">"Seleziona anno"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Elemento selezionato: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminato"</string>
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 51f3889..f330aaa 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -23,18 +23,18 @@
     <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="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">"&gt;ללא כותרת&lt;"</string>
+    <string name="untitled" msgid="4638956954852782576">"‏&gt;ללא כותרת&lt;"</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="mmiError" msgid="5154499457739052907">"‏בעיה בחיבור או קוד MMI לא חוקי."</string>
     <string name="mmiFdnError" msgid="5224398216385316471">"הפעולה מוגבלת למספרי חיוג קבועים בלבד."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"השירות הופעל."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"השירות הופעל עבור:"</string>
@@ -42,14 +42,19 @@
     <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="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="enablePin" msgid="209412020907207950">"‏לא הצלחת. הפעל נעילת SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"‏נותר לך ניסיון <xliff:g id="NUMBER">%d</xliff:g> לפני נעילת כרטיס ה-SIM."</item>
+    <item quantity="other" msgid="7530597808358774740">"‏נותרו לך <xliff:g id="NUMBER">%d</xliff:g> ניסיונות לפני נעילת כרטיס ה-SIM."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"זיהוי מתקשר של שיחה נכנסת"</string>
@@ -58,7 +63,7 @@
     <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="PinMmi" msgid="3113117780361190304">"‏שנה את ה-PIN"</string>
     <string name="CnipMmi" msgid="3110534680557857162">"מספר מתקשר נמצא"</string>
     <string name="CnirMmi" msgid="3062102121430548731">"מספר מתקשר חסוי"</string>
     <string name="ThreeWCMmi" msgid="9051047170321190368">"שיחה עם שלושה משתתפים"</string>
@@ -76,10 +81,10 @@
     <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="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="RestrictedOnVoiceSms" msgid="1888588152792023873">"‏שירותי קול/SMS חסומים."</string>
+    <string name="RestrictedOnAll" msgid="5643028264466092821">"‏כל השירותים של קול/נתונים/SMS חסומים."</string>
     <string name="serviceClassVoice" msgid="1258393812335258019">"Google Voice"</string>
     <string name="serviceClassData" msgid="872456782077937893">"Google Data"</string>
     <string name="serviceClassFAX" msgid="5566624998840486475">"פקס"</string>
@@ -114,7 +119,7 @@
     <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="httpErrorProxyAuth" msgid="1788207010559081331">"‏האימות דרך שרת ה-Proxy נכשל."</string>
     <string name="httpErrorConnect" msgid="8714273236364640549">"לא ניתן להתחבר לשרת."</string>
     <string name="httpErrorIO" msgid="2340558197489302188">"לא ניתן לתקשר עם השרת. נסה שוב מאוחר יותר."</string>
     <string name="httpErrorTimeout" msgid="4743403703762883954">"חלף הזמן הקצוב של החיבור לשרת."</string>
@@ -168,11 +173,11 @@
     <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="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="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>
@@ -182,7 +187,7 @@
     <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="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>
@@ -228,8 +233,8 @@
     <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="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>
@@ -251,27 +256,27 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"הסר התקנה של קיצורי דרך"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"מאפשר לאפליקציה להסיר קיצורי דרך במסך דף הבית ללא התערבות המשתמש."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ניתוב מחדש של שיחות יוצאות"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"מאפשרת לאפליקציה לראות את המספר המחויג במהלך ביצוע שיחה יוצאת, עם האפשרות להפנות את השיחה למספר אחר או לבטל את השיחה לחלוטין."</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_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. דבר זה מתיר לאפליקציה לקרוא את כל הודעות ה-SMS, ללא התחשבות בתוכן או בסודיות."</string>
-    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"מאפשר לאפליקציה לקרוא הודעות SMS המאוחסנות בטלפון או בכרטיס ה-SIM. דבר זה מתיר לאפליקציה לקרוא את כל הודעות ה-SMS, ללא התחשבות בתוכן או בסודיות."</string>
-    <string name="permlab_writeSms" msgid="3216950472636214774">"עריכת הודעות הטקסט שלך (SMS או MMS)"</string>
-    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"מאפשר לאפליקציה לכתוב להודעות SMS המאוחסנות בטאבלט או בכרטיס ה-SIM שלך. אפליקציות זדוניות עלולות למחוק את ההודעות שלך."</string>
-    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"מאפשר לאפליקציה לכתוב להודעות SMS המאוחסנות בטלפון או בכרטיס ה-SIM שלך. אפליקציות זדוניות עלולות למחוק את ההודעות שלך."</string>
-    <string name="permlab_receiveWapPush" msgid="5991398711936590410">"קבלת הודעות טקסט (WAP)"</string>
-    <string name="permdesc_receiveWapPush" msgid="748232190220583385">"מאפשר לאפליקציה לקבל ולעבד הודעות WAP. אישור זה כולל את היכולת לעקוב אחר הודעות שנשלחו אליך ולמחוק אותן מבלי להציג לך אותן."</string>
+    <string name="permlab_readSms" msgid="8745086572213270480">"‏קריאת הודעות הטקסט שלך (SMS או MMS)"</string>
+    <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"‏מאפשר לאפליקציה לקרוא הודעות SMS המאוחסנות בטאבלט או בכרטיס ה-SIM. דבר זה מתיר לאפליקציה לקרוא את כל הודעות ה-SMS, ללא התחשבות בתוכן או בסודיות."</string>
+    <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"‏מאפשר לאפליקציה לקרוא הודעות SMS המאוחסנות בטלפון או בכרטיס ה-SIM. דבר זה מתיר לאפליקציה לקרוא את כל הודעות ה-SMS, ללא התחשבות בתוכן או בסודיות."</string>
+    <string name="permlab_writeSms" msgid="3216950472636214774">"‏עריכת הודעות הטקסט שלך (SMS או MMS)"</string>
+    <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"‏מאפשר לאפליקציה לכתוב להודעות SMS המאוחסנות בטאבלט או בכרטיס ה-SIM שלך. אפליקציות זדוניות עלולות למחוק את ההודעות שלך."</string>
+    <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"‏מאפשר לאפליקציה לכתוב להודעות SMS המאוחסנות בטלפון או בכרטיס ה-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>
@@ -313,7 +318,7 @@
     <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="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>
@@ -326,10 +331,10 @@
     <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_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>
@@ -353,7 +358,7 @@
     <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_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>
@@ -369,16 +374,18 @@
     <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_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="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">"הכפפה לשירות Widget"</string>
-    <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"מאפשר למשתמש לבצע איגוד לממשק הרמה העליונה של שירות Widget. הרשאה זו לעולם אינה נחוצה לאפליקציות רגילים."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"איגוד לצג מרוחק"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"הרשאה זו מאפשרת למשתמש לבצע איגוד לממשק הרמה העליונה של צג רחוק. לעולם אינה אמורה להיות נחוצה לאפליקציות רגילות."</string>
+    <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"‏הכפפה לשירות Widget"</string>
+    <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>
@@ -389,13 +396,13 @@
     <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="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="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>
@@ -403,7 +410,7 @@
     <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="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>
@@ -415,9 +422,11 @@
     <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="permdesc_manageCaCertificates" msgid="4015644047196937014">"‏מאפשרת לאפליקציה להתקין ולהסיר אישורי CA כפרטי כניסה מהימנים."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"הרצת אפליקציה בזמן מצב לא פעיל"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"‏ההרשאה הזו מאפשרת למערכת Android להריץ את האפליקציה ברקע כשהמכשיר אינו בשימוש."</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>
@@ -429,8 +438,8 @@
     <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_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>
@@ -464,23 +473,25 @@
     <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="permlab_accessFineLocation" msgid="1191898061965273372">"מיקום מדויק (מבוסס GPS ורשת)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"מאפשר לאפליקציה לקבל את המיקום המדויק שלך באמצעות מערכת המיקום הגלובלית (GPS) או מקורות מיקום ברשת כגון אנטנות סלולריות ו-Wi-Fi. שירותי מיקום אלה חייבים להיות מופעלים ונגישים למכשיר שלך כדי שהאפליקציה תשתמש בהם. ייתכן שאפליקציות יעשו בכך שימוש כדי לקבוע היכן אתה נמצא ולגרום לצריכת סוללה מוגברת."</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="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">"הגדר תצוגות Wi-Fi"</string>
-    <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_accessInputFlinger" msgid="5348635270689553857">"‏גישה אל InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"‏מאפשרת לאפליקציה להשתמש בתכונות ברמה נמוכה של InputFlinger."</string>
+    <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"‏הגדר תצוגות Wi-Fi"</string>
+    <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"מאפשר לאפליקציה לשנות הגדרות אודיו גלובליות כמו עוצמת קול ובחירת הרמקול המשמש לפלט."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"הקלט אודיו"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"מאפשר לאפליקציה להקליט אודיו באמצעות המיקרופון. אישור זה מתיר לאפליקציה להקליט אודיו בכל עת ללא אישורך."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"‏תקשורת SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"‏מאפשרת ליישום לשלוח פקודות ל-SIM. זוהי הרשאה מסוכנת מאוד."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"צלם תמונות וסרטונים"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"מאפשר לאפליקציה לצלם תמונות וסרטונים באמצעות המצלמה. אישור זה מאפשר לאפליקציה להשתמש במצלמה בכל עת ללא אישורך."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"השבת את נורית מצב השידור כשהמצלמה בשימוש"</string>
@@ -507,11 +520,11 @@
     <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="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="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>
@@ -527,29 +540,31 @@
     <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_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_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">"בחר רכיבי Widget"</string>
-    <string name="permdesc_bindGadget" msgid="8261326938599049290">"מאפשר לאפליקציה ליידע את המערכת באילו פריטי Widget יכול להשתמש כל אפליקציה. אפליקציה בעלת הרשאה זו יכול לספק לאפליקציות אחרות גישה לנתונים אישיים. לא מיועד לשימוש על ידי אפליקציות רגילות."</string>
+    <string name="permlab_bindGadget" msgid="776905339015863471">"‏בחר רכיבי Widget"</string>
+    <string name="permdesc_bindGadget" msgid="8261326938599049290">"‏מאפשר לאפליקציה ליידע את המערכת באילו פריטי Widget יכול להשתמש כל אפליקציה. אפליקציה בעלת הרשאה זו יכול לספק לאפליקציות אחרות גישה לנתונים אישיים. לא מיועד לשימוש על ידי אפליקציות רגילות."</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_readPrecisePhoneState" msgid="5476483020282007597">"קריאת מצבי טלפון מדויקים"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"מאפשר לאפליקציה לגשת למצבי הטלפון המדויקים. ההרשאה הזו מאפשרית לאפליקציה לדעת מה סטטוס השיחה בפועל, האם שיחה פעילה או ברקע, כשלי שיחות, סטטוס מדויק על חיבור נתונים וכשלים בחיבור נתונים."</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>
@@ -576,8 +591,8 @@
     <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_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>
@@ -590,37 +605,37 @@
     <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">"מאפשר לאפליקציה ליצור Sockets ולהשתמש בפרוטוקולי רשת מותאמים אישית. הדפדפן ואפליקציות  אחרות מספקות אמצעים לשליחת נתונים לאינטרנט, כך שאישור זה אינו נחוץ לשליחת נתונים לאינטרנט."</string>
+    <string name="permdesc_createNetworkSockets" msgid="3403062187779724185">"‏מאפשר לאפליקציה ליצור Sockets ולהשתמש בפרוטוקולי רשת מותאמים אישית. הדפדפן, כמו אפליקציות  אחרות, מספק אמצעים לשליחת נתונים לאינטרנט, כך שאישור זה אינו נחוץ לשליחת נתונים לאינטרנט."</string>
     <string name="permlab_writeApnSettings" msgid="505660159675751896">"שנה/עכב הגדרות רשת ותנועה"</string>
-    <string name="permdesc_writeApnSettings" msgid="5333798886412714193">"מאפשר לאפליקציה לשנות את הגדרות הרשת ולעכב ולבדוק את כל תנועת הרשת, לדוגמה, לשנות את ה-proxy והיציאה של כל רשת APN. אפליקציות זדוניות עלולות לעקוב אחר חבילות רשת, לבצע הפניה מחדש שלהן או לשנות אותן, ללא ידיעתך."</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, למשל, האם 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_bluetoothPriv" msgid="4009494246009513828">"אפשר התאמת Bluetooth על ידי האפליקציה"</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_bluetoothPriv" msgid="4009494246009513828">"‏אפשר התאמת Bluetooth על ידי האפליקציה"</string>
     <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"מאפשרת לאפליקציה לבצע התאמה עם מכשירים מרוחקים ללא התערבות המשתמש."</string>
     <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"מאפשרת לאפליקציה לבצע התאמה עם מכשירים מרוחקים ללא התערבות המשתמש."</string>
-    <string name="permlab_accessWimaxState" msgid="4195907010610205703">"התחברות והתנתקות מ-WiMAX"</string>
-    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"מאפשר לאפליקציה לדעת האם WiNMAX מופעל, כמו גם לקבל מידע האם רשתות WiNMAX כלשהן מחוברות."</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="permlab_accessWimaxState" msgid="4195907010610205703">"‏התחברות והתנתקות מ-WiMAX"</string>
+    <string name="permdesc_accessWimaxState" msgid="6360102877261978887">"‏מאפשר לאפליקציה לדעת האם WiNMAX מופעל, כמו גם לקבל מידע האם רשתות WiNMAX כלשהן מחוברות."</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">"מאפשר לאפליקציה נהל תקשורת עם תגים, כרטיסים וקוראים מסוג \'תקשורת מטווח קצר\'."</string>
     <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ביטול נעילת המסך שלך"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"מאפשר לאפליקציה להשבית את נעילת המקשים וכל אמצעי אבטחה משויך המבוסס על סיסמה. לדוגמה, הטלפון משבית את נעילת המקשים בעת קבלה של שיחת טלפון נכנסת, ולאחר מכן מפעיל מחדש את נעילת המקשים עם סיום השיחה."</string>
@@ -638,14 +653,14 @@
     <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="367275095159405468">"קריאת התוכן של אחסון ה-USB שלך"</string>
-    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"קריאת התוכן של כרטיס ה-SD שלך"</string>
-    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"מאפשר לאפליקציה לקרוא את תוכן אחסון ה-USB שלך."</string>
-    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"מאפשר לאפליקציה לקרוא את תוכן כרטיס ה-SD שלך."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"שינוי או מחיקה של תוכן אחסון ה-USB שלך"</string>
-    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"שינוי או מחיקה של תוכן כרטיס ה-SD שלך"</string>
-    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"מאפשר לאפליקציה לכתוב להתקן האחסון מסוג USB."</string>
-    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"מאפשר לאפליקציה לכתוב לכרטיס ה-SD."</string>
+    <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"‏קריאת התוכן של אחסון ה-USB שלך"</string>
+    <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"‏קריאת התוכן של כרטיס ה-SD שלך"</string>
+    <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"‏מאפשר לאפליקציה לקרוא את תוכן אחסון ה-USB שלך."</string>
+    <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"‏מאפשר לאפליקציה לקרוא את תוכן כרטיס ה-SD שלך."</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"‏שינוי או מחיקה של תוכן אחסון ה-USB שלך"</string>
+    <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"‏שינוי או מחיקה של תוכן כרטיס ה-SD שלך"</string>
+    <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"‏מאפשר לאפליקציה לכתוב להתקן האחסון מסוג USB."</string>
+    <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"‏מאפשר לאפליקציה לכתוב לכרטיס ה-SD."</string>
     <string name="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>
@@ -655,7 +670,7 @@
     <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="permdesc_use_sip" msgid="4717632000062674294">"‏מאפשר לאפליקציה להשתמש בשירות SIP כדי לבצע/לקבל שיחות אינטרנט."</string>
     <string name="permlab_bind_call_service" msgid="6724009726671246551">"צור אינטראקציה עם מסך שיחה נכנסת"</string>
     <string name="permdesc_bind_call_service" msgid="8732547662442572435">"מאפשר לאפליקציה לקבוע מתי ואיך המשתמש יראה שיחה נכנסת על המסך."</string>
     <string name="permlab_readNetworkUsageHistory" msgid="7862593283611493232">"קריאת נתוני שימוש היסטוריים ברשת"</string>
@@ -664,8 +679,8 @@
     <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">"שינוי של סימני Socket"</string>
-    <string name="permdesc_markNetworkSocket" msgid="7655568433696356578">"ההרשאה הזו מאפשרת לאפליקציה לשנות סימני Socket עבור ניתוב"</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ההרשאה הזו מאפשרת לבעלים להפעיל את אפליקציית התצורה שסופקה על ידי ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"קליטת מעקב אחר תנאי רשת"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"מאפשרת לאפליקציה לקלוט מעקב אחר תנאי רשת. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"שינוי הכיול של מכשיר קלט"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"מאפשרת לאפליקציה לשנות את פרמטרי הכיול של מסך המגע. לעולם לא אמורה להיות נחוצה לאפליקציות רגילות."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
@@ -686,16 +703,16 @@
     <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">"הגדר שימוש בשרת ה-Proxy הגלובלי של המכשיר כאשר המדיניות מופעלת. רק מנהל המכשיר הראשון מגדיר את שרת ה-Proxy הגלובלי הפעיל."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"‏הגדר את שרת ה-Proxy הכללי של המכשיר"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"‏הגדר שימוש בשרת ה-Proxy הגלובלי של המכשיר כאשר המדיניות מופעלת. רק מנהל המכשיר הראשון מגדיר את שרת ה-Proxy הגלובלי הפעיל."</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">"השבת תכונות ב-Keyguard"</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"מנע שימוש בתכונות מסוימות ב-Keyguard."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"‏השבת תכונות ב-Keyguard"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"‏מנע שימוש בתכונות מסוימות ב-Keyguard."</string>
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"בית"</item>
     <item msgid="869923650527136615">"נייד"</item>
@@ -809,14 +826,15 @@
     <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="quick_contacts_not_available" msgid="746098007828579688">"לא נמצאה אפליקציה להצגת התוכן הזה."</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_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>
@@ -834,13 +852,13 @@
     <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_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>
@@ -848,15 +866,15 @@
     <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_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_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_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>
@@ -865,12 +883,12 @@
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"שכחת את הקו?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"ביטול נעילת חשבון"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"בוצעו ניסיונות רבים מדי לשרטוט קו ביטול נעילה."</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"כדי לבטל את הנעילה, היכנס באמצעות חשבון Google שלך."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"‏כדי לבטל את הנעילה, היכנס באמצעות חשבון Google שלך."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"שם משתמש (דוא\"ל)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"סיסמה"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"כניסה"</string>
     <string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"שם משתמש או סיסמה לא חוקיים."</string>
-    <string name="lockscreen_glogin_account_recovery_hint" msgid="1696924763690379073">"שכחת את שם המשתמש או הסיסמה?\nבקר בכתובת "<b>"google.com/accounts/recovery"</b></string>
+    <string name="lockscreen_glogin_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>
@@ -879,24 +897,24 @@
     <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. Widget %2$d מתוך %3$d."</string>
-    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"הוסף Widget."</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_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_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_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>
@@ -910,8 +928,8 @@
     <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_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>
@@ -940,10 +958,10 @@
     <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">"מאפשר לאפליקציה לקרוא את ההיסטוריה של כל כתובות האתרים שבהן הדפדפן ביקר, ואת כל ה-Bookmarks של הדפדפן. שים לב: דפדפני צד שלישי או אפליקציות אחרות עם יכולות לדפדוף באינטרנט אינם יכולים לאכוף אישור זה."</string>
+    <string name="permdesc_readHistoryBookmarks" msgid="8462378226600439658">"‏מאפשר לאפליקציה לקרוא את ההיסטוריה של כל כתובות האתרים שבהן הדפדפן ביקר, ואת כל ה-Bookmarks של הדפדפן. שים לב: דפדפני צד שלישי או אפליקציות אחרות עם יכולות לדפדוף באינטרנט אינם יכולים לאכוף אישור זה."</string>
     <string name="permlab_writeHistoryBookmarks" msgid="3714785165273314490">"כתיבת סימניות והיסטוריית אינטרנט"</string>
-    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"מאפשר לאפליקציה לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטאבלט. הדבר עשוי לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
-    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"מאפשר לאפליקציה לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטלפון. הדבר עשוי לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="6825527469145760922">"‏מאפשר לאפליקציה לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטאבלט. הדבר עשוי לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
+    <string name="permdesc_writeHistoryBookmarks" product="default" msgid="8497389531014185509">"‏מאפשר לאפליקציה לשנות את ההיסטוריה או ה-Bookmarks של הדפדפן המאוחסנים בטלפון. הדבר עשוי לאפשר לאפליקציה למחוק או לשנות נתוני דפדפן. שים לב: אישור זה אינו ניתן לאכיפה על ידי דפדפני צד שלישי או אפליקציות אחרות בעלות יכולות גלישה באינטרנט."</string>
     <string name="permlab_setAlarm" msgid="1379294556362091814">"הגדרת התראה"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"מאפשר לאפליקציה להגדיר התראה באפליקציה מותקנת של שעון מעורר. אפליקציות מסוימות של שעון מעורר אינן מיישמות תכונה זו."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"הוסף דואר קולי"</string>
@@ -955,7 +973,7 @@
     <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 של SerialManager."</string>
+    <string name="permdesc_serialPort" msgid="2991639985224598193">"‏מאפשר לבעלים לגשת ליציאות טוריות באמצעות ממשק ה- API של SerialManager."</string>
     <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"גישה לספקי תוכן באופן חיצוני"</string>
     <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"מאפשר לבעלים לגשת לספקי תוכן מהמעטפת. לעולם לא אמור להיות צורך עבור אפליקציות רגילות."</string>
     <string name="permlab_updateLock" msgid="3527558366616680889">"דחה עדכוני מכשיר אוטומטיים"</string>
@@ -1093,7 +1111,7 @@
     <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="replace" msgid="5781686059063148930">"החלף..."</string>
     <string name="delete" msgid="6098684844021697789">"מחק"</string>
     <string name="copyUrl" msgid="2538211579596067402">"העתק כתובת אתר"</string>
     <string name="selectTextMode" msgid="1018691815143165326">"בחר טקסט"</string>
@@ -1117,9 +1135,9 @@
     <string name="whichApplication" msgid="4533185947064773386">"השלמת פעולה באמצעות"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"בחר אפליקציה לדף הבית"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"השתמש כברירת מחדל עבור פעולה זו."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"נקה את הגדרת המחדל ב\'הגדרות מערכת\' &lt;‏ Google Apps‏ &lt; \'הורדות\'."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"‏נקה את הגדרת המחדל ב\'הגדרות מערכת\' &lt;‏ Google Apps‏ &lt; \'הורדות\'."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"בחירת פעולה"</string>
-    <string name="chooseUsbActivity" msgid="6894748416073583509">"בחר אפליקציה עבור התקן ה-USB"</string>
+    <string name="chooseUsbActivity" msgid="6894748416073583509">"‏בחר אפליקציה עבור התקן ה-USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"אין אפליקציות שיכולות לבצע פעולה זו."</string>
     <string name="aerr_title" msgid="1905800560317137752"></string>
     <string name="aerr_application" msgid="932628488013092776">"לצערנו, פעולת <xliff:g id="APPLICATION">%1$s</xliff:g> הופסקה."</string>
@@ -1138,9 +1156,9 @@
     <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">"אפשר תכונה זו מחדש ב\'הגדרות מערכת\' &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="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_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>
@@ -1156,14 +1174,14 @@
     <string name="sendText" msgid="5209874571959469142">"בחירת פעולה לביצוע עם טקסט"</string>
     <string name="volume_ringtone" msgid="6885421406845734650">"עוצמת קול של צלצול"</string>
     <string name="volume_music" msgid="5421651157138628171">"עוצמת קול של מדיה"</string>
-    <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"הפעלה באמצעות Bluetooth"</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_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_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>
@@ -1174,23 +1192,23 @@
     <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>
+    <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>
+    <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="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" 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_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>
@@ -1198,28 +1216,28 @@
     <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_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="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_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_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_remember_undo_instruction" msgid="4960944133052287484">"‏ניתן לשנות זאת מאוחר יותר ב\'הגדרות\' &gt; \'אפליקציות\'"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"אפשר תמיד"</string>
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"לעולם אל תאפשר"</string>
-    <string name="sim_removed_title" msgid="6227712319223226185">"כרטיס ה-SIM הוסר"</string>
-    <string name="sim_removed_message" msgid="2333164559970958645">"הרשת הסלולרית לא תהיה זמינה עד שתפעיל מחדש לאחר הכנסת כרטיס SIM חוקי."</string>
+    <string name="sim_removed_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_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>
@@ -1230,38 +1248,38 @@
     <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 של מכשיר ה-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 שלך לאחסון בנפח גדול ב-USB."</string>
-    <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB מחובר"</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 של מכשיר ה-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 שלך לאחסון בנפח גדול ב-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, בטל את הטעינה (\"הוצא\") של אחסון ה-USB של ה-Android שלך מהמחשב."</string>
-    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"לפני שתכבה את אחסון ה-USB, ודא שביטלת את הטעינה (\"הוצאת\") של כרטיס ה-SD של ה-Android שלך מהמחשב."</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="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 של ה-Android שלך מהמחשב."</string>
+    <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"‏לפני שתכבה את אחסון ה-USB, ודא שביטלת את הטעינה (\"הוצאת\") של כרטיס ה-SD של ה-Android שלך מהמחשב."</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="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="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>
@@ -1271,29 +1289,29 @@
     <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_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="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>
@@ -1305,8 +1323,10 @@
     <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="permlab_recovery" msgid="3157024487744125846">"אינטראקציה עם מערכת שחזור ועדכונים"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"מאפשרת לאפליקציה ליצור אינטראקציה עם מערכת השחזור ועדכוני מערכת."</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="gadget_host_error_inflating" msgid="4882004314906466162">"‏לא ניתן להוסיף widget."</string>
     <string name="ime_action_go" msgid="8320845651737369027">"התחל"</string>
     <string name="ime_action_search" msgid="658110271822807811">"חפש"</string>
     <string name="ime_action_send" msgid="2316166556349314424">"שלח"</string>
@@ -1329,13 +1349,13 @@
     <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_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_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>
@@ -1343,7 +1363,7 @@
     <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_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>
@@ -1359,18 +1379,18 @@
     <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="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>
@@ -1398,8 +1418,8 @@
     <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="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>
@@ -1414,41 +1434,33 @@
     <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_error" msgid="8624618365481126668">"לא ניתן היה להפעיל את <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"שתף עם"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"שתף עם <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ידית להחלקה. גע והחזק."</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="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="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_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_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_3g_limit_snoozed_title" msgid="7026739121138005231">"‏אירעה חריגה ממגבלת הנתונים של 2G-3G"</string>
+    <string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"‏אירעה חריגה ממגבלת הנתונים של 4G"</string>
     <string name="data_usage_mobile_limit_snoozed_title" msgid="279240572165412168">"אירעה חריגה ממגבלת הנתונים לנייד"</string>
-    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"אירעה חריגה ממגבלת הנתונים של Wi-Fi"</string>
+    <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"‏אירעה חריגה ממגבלת הנתונים של 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>
@@ -1464,8 +1476,8 @@
     <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="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>
@@ -1481,51 +1493,57 @@
     <string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"רמקולים של מעגן"</string>
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"מערכת"</string>
-    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"אודיו Bluetooth"</string>
+    <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"‏אודיו 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_chooser_title" msgid="1751618554539087622">"התחברות למכשיר"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"העברת מסך אל מכשיר"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"מחפש מכשירים…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"הגדרות"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"התנתק"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"סורק..."</string>
     <string name="media_route_status_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_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_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_connecting_title" msgid="2838646471050359706">"העברת מסך מתבצעת"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"מתחבר אל <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"העברת מסך מתבצעת"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"מחובר אל <xliff:g id="NAME">%1$s</xliff:g>"</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_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 ל-SIM"</string>
-    <string name="kg_pin_instructions" msgid="2377242233495111557">"הזן מספר PIN"</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_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="6025069204539532000">"‏קוד 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_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_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_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>
@@ -1585,9 +1603,9 @@
     <string name="mediasize_na_junior_legal" msgid="3309324162155085904">"Junior Legal"</string>
     <string name="mediasize_na_ledger" msgid="5567030340509075333">"Ledger"</string>
     <string name="mediasize_na_tabloid" msgid="4571735038501661757">"Tabloid"</string>
-    <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"כרטיס אינדקס 3x5"</string>
-    <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"כרטיס אינדקס 4x6"</string>
-    <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"כרטיס אינדקס 5x8"</string>
+    <string name="mediasize_na_index_3x5" msgid="5182901917818625126">"‏כרטיס אינדקס 3x5"</string>
+    <string name="mediasize_na_index_4x6" msgid="7687620625422312396">"‏כרטיס אינדקס 4x6"</string>
+    <string name="mediasize_na_index_5x8" msgid="8834215284646872800">"‏כרטיס אינדקס 5x8"</string>
     <string name="mediasize_na_monarch" msgid="213639906956550754">"Monarch"</string>
     <string name="mediasize_na_quarto" msgid="835778493593023223">"Quarto"</string>
     <string name="mediasize_na_foolscap" msgid="1573911237983677138">"Foolscap"</string>
@@ -1635,19 +1653,30 @@
     <string name="reason_service_unavailable" msgid="7824008732243903268">"שירות ההדפסה לא הופעל"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"שירות <xliff:g id="NAME">%s</xliff:g> מותקן"</string>
     <string name="print_service_installed_message" msgid="5897362931070459152">"הקש כדי להפעיל"</string>
-    <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"הזן את מספר ה-PIN של מנהל המערכת"</string>
-    <string name="restr_pin_enter_pin" msgid="3395953421368476103">"הזן מספר PIN"</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>
+    <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="immersive_mode_confirmation" msgid="7227416894979047467">"החלק מטה מהחלק העליון כדי לצאת ממסך מלא."</string>
+    <string name="done_label" msgid="2093726099505892398">"בוצע"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"מחוון שעות מעגלי"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"מחוון דקות מעגלי"</string>
+    <string name="select_hours" msgid="6043079511766008245">"בחר שעות"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"בחר דקות"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"בחירת ימים בחודש בתצוגת רשת"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"רשימת שנים"</string>
+    <string name="select_day" msgid="7774759604701773332">"בחר חודש ויום"</string>
+    <string name="select_year" msgid="7952052866994196170">"בחר שנה"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> נבחר"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> נמחק"</string>
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 246a82e..4a26208 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"PUKは8桁以上で入力してください。"</string>
     <string name="needPuk" msgid="919668385956251611">"SIMカードはPUKでロックされています。ロックを解除するにはPUKコードを入力してください。"</string>
     <string name="needPuk2" msgid="4526033371987193070">"SIMカードのロック解除のためPUK2を入力します。"</string>
+    <string name="enablePin" msgid="209412020907207950">"SIM/RUIMロックを有効にしてください。"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"入力できるのはあと<xliff:g id="NUMBER">%d</xliff:g>回です。この回数を超えるとSIMがロックされます。"</item>
+    <item quantity="other" msgid="7530597808358774740">"入力できるのはあと<xliff:g id="NUMBER">%d</xliff:g>回です。この回数を超えるとSIMがロックされます。"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"着信時の発信者番号"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ショートカットのアンインストール"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"ユーザー操作なしでホーム画面のショートカットを削除することをアプリに許可します。"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"発信先の変更"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"通話の発信とダイヤルする番号の変更をアプリに許可します。これにより、アプリが発信を監視、転送、阻止できるようになります。"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"発信を別の番号に転送するか完全に中止するオプションで、発信中にダイヤルされた番号にアクセスすることをアプリに許可します。"</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"リモートディスプレイへのバインド"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"リモートディスプレイのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ウィジェットサービスにバインド"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ウィジェットサービスのトップレベルインターフェースにバインドすることを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"デバイス管理者との通信"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"アイドル状態でのアプリの実行"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"この権限により、端末が使用中でない場合でもAndroidシステムがバックグラウンドでアプリを実行できるようになります。"</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>
@@ -477,6 +486,8 @@
     <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">"Wi-Fiディスプレイの設定"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wi-Fiディスプレイを設定して接続することをアプリに許可します。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fiディスプレイの制御"</string>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"音声全般の設定(音量、出力に使用するスピーカーなど)の変更をアプリに許可します。"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"録音"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"マイクを使った録音をアプリに許可します。これにより、アプリがいつでも確認なしで録音できるようになります。"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM通信"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"SIMにコマンドを送信することをアプリに許可します。この許可は非常に危険です。"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"写真と動画の撮影"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"カメラでの写真と動画の撮影をアプリに許可します。これにより、アプリが確認なしでいつでもカメラを使用できるようになります。"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"カメラの使用中に通信インジケータLEDを無効にする"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"端末の電話機能の制御をアプリに許可します。許可すると、アプリではユーザーに通知なくネットワークの切り替え、無線通信のON/OFFなどを行えるようになります。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"端末のステータスとIDの読み取り"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"端末の電話機能へのアクセスをアプリに許可します。これにより、電話番号、端末ID、通話中かどうか、通話相手の電話番号をアプリから特定できるようになります。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"正確な電話ステータスの読み取り"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"正確な電話ステータスにアクセスすることをアプリに許可します。これにより、実際の発信ステータス(発信がアクティブか、バックグラウンドか)、発信エラー、正確なデータ接続ステータス、データ接続エラーをアプリから特定できるようになります。"</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"携帯通信会社が提供する設定アプリを呼び出すことを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ネットワーク状況監視のためのリッスン"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ネットワーク状況を監視するためリッスンすることをアプリに許可します。通常のアプリで必要になることはありません。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"入力デバイスの調整を変更"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"タッチスクリーンの調整パラメータの変更をアプリに許可します。通常のアプリでは必要ありません。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"自宅"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"勤務先"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"その他"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"この連絡先を表示するアプリが見つかりません。"</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"アップデートと回復システムへのアクセス"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"回復システムとシステムアップデートへのアクセスをアプリに許可します。"</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>を起動できませんでした"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"共有"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>と共有"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"スライダーハンドルです。押し続けます。"</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">"サウンドON"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"端末に接続"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"端末への画面のキャスト"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"端末を検索しています…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"設定"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"接続を解除"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"スキャン中..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"接続中..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"利用できます"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"画面のキャスト中"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"<xliff:g id="NAME">%1$s</xliff:g>に接続しています"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"画面のキャスト中"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"<xliff:g id="NAME">%1$s</xliff:g>に接続しました"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"しばらくしてから再試行"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"全画面表示を終了するには、上から下にスワイプ"</string>
+    <string name="done_label" msgid="2093726099505892398">"完了"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"円形スライダー(時)"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"円形スライダー(分)"</string>
+    <string name="select_hours" msgid="6043079511766008245">"時間を選択"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"分を選択"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"日グリッド(月別)"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年リスト"</string>
+    <string name="select_day" msgid="7774759604701773332">"月と日を選択"</string>
+    <string name="select_year" msgid="7952052866994196170">"年を選択"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>を選択しました"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g>を削除しました"</string>
 </resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index a8025d8..5dbb83f 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"წარუმატებელი მცდელობა. ჩართეთ SIM/RUIM ჩაკეტვა."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"თქვენ დაგრჩათ <xliff:g id="NUMBER">%d</xliff:g> მცდელობა, სანამ SIM დაიბლოკებოდეს."</item>
+    <item quantity="other" msgid="7530597808358774740">"თქვენ დაგრჩათ <xliff:g id="NUMBER">%d</xliff:g> მცდელობა, სანამ SIM დაიბლოკებოდეს."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"შემომავალი ზარის აბონენტის ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"მალსახმობების წაშლა"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"მთავარ ეკრანზე აპლიკაციისთვის მალსახმობების დამოუკიდებლად წაშლის უფლების მიცემა."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"გამავალი ზარების გადამისამართება"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"აპს შეეძლება გამავალი ზარების დამუშავება და ასაკრეფი ნომრის შეცვლა. ეს უფლება აპს აძლევს შესაძლებლობას აკონტროლოს, გადაამისამართოს ან აღკვეთოს გამავალი ზარები."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"საშუალებას აძლევს აპს გამავალი ზარის დროს დაინახონ ზარის მიმღების ნომერი, ზარის სხვა მისამართზე გადამისამართებით ან ზარის საერთოდ შეწყვეტის საშუალებით."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"დისტანციურ მონიტორზე მიბმა"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"მფლობელს შეეძლება მიებას დისტანციურ მონიტორის ზედა დონის ინტერფეისს. ჩვეულებრივ აპს ეს წესით არასოდეს უნდა დაჭირდეს."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ვიჯეტ სერვისთან დაკავშირება"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"აპს შეეძლება ზედა დონის ინტერფეისის ვიჯეტთან დაკავშირება. არასდროს გამოიყენება ჩვეულებრივ აპებში."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"მოწყობილობის ადმინთან ინტერაქცია"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"უქმე მდგომარეობისას აპლიკაციის გაშვება"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"ეს უფლება Android-ის სისტემას უფლებას ანიჭებს ფონურად გაუშვას აპლიკაცია, როდესაც მოწყობილობა არ გამოიყენება."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"სისტემის დიაგნოსტიკის რესურსებში წაკითხვა/ჩაწერის უფლება"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"აპს შეეძლება, წაიკითხოს ან ჩაწეროს ნებისმიერ რესურსში, რომელიც დიაგნოსტიკის ჯგუფს ეკუთვნის, მაგალითად, ფაილები /dev-ში. ამან შესაძლოა იმოქმედოს სისტემის სტაბილურობასა და უსაფრთხოებაზე. მისი გამოყენება მხოლოდ მწარმოებლის ან ოპერატორის მიერ ტექნიკის სპეციფიკური დიაგნოსტიკისთვის უნდა მოხდეს."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"აპის კომპონენტების ჩართვა ან გამორთვა"</string>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"აპს შეეძლება აუდიოს გლობალური პარამეტრების შეცვლა. მაგ.: ხმის სიმაღლე და რომელი დინამიკი გამოიყენება სიგნალის გამოსტანად."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"აუდიოს ჩაწერა"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"აპს შეეძლება აუდიო ჩაწერა მიკროფონით. ნებართვა აპს აუდიო ჩაწერის უფლებას აძლევს ნებისმიერ დროს, თქვენი თანხმობის გარეშე."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"კომუნიკაცია SIM-თან"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"აპისთვის ნების დართვა გაუგზავნოს ბრძანებები SIM-ბარათს. ეს ძალიან საშიშია."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"სურათებისა და ვიდეოების გადაღება"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"აპს შეეძლება კამერით სურათისა და ვიდეოს გადაღება. ეს ნებართვა აპს უფლებას აძლევს, ნებისმიერ დროს გამოიყენოს კამერა თქვენი დადასტურების გარეშე."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"კამერის გამოყენებისას გადამცემი ინდიკატორის LED გათიშვა"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"აპს შეეძლება აკონტროლოს მოწყობილობაზე ტელეფონის ფუნქციები. ამ უფლების მქონე აპს შეუძლია ქსელების გადართვა, ტელეფონის რადიოს ჩართვა და გამორთვა, მომხმარებლისათვის შეტყობინების გარეშე."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ტელეფონის სტატუსისა და იდენტობის წაკითხვა"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"აპს შეეძლება ჰქონდეს წვდომა მოწყობილობის სატელეფონო ფუნქციებზე. აპმა მსგავსი უფლებით შეძლებს დაადგინოს ტელეფონის ნომერი, მისი სერიული გამოცემა, აქტიური ზარი, დაკავშირებული ნომერი და მსგავსი."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ტელეფონის ზუსტი მდგომარეობების დადგენა"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ანიჭებს აპს ტელეფონის ზუსტ მდგომარეობაზე წვდომას. ეს უფლება საშუალებას აძლევს აპს შეიტყოს ინფორმაცია ზარის რეალურ სტატუსზე, აქტიურია ზარი თუ უკანა ფონზეა, ვერ განხორციელებული ზარები, მონაცემთა გადაცემის ზუსტი სტატუსი და ვერ განხორციელებული მონაცემთა კავშირები."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"საშუალებას აძლევს მფლობელს გამოიწვიოს ოპერატორის მიერ მოწოდებული კონფიგურაციის აპი. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"განხორციელდეს ქსელის მდგომარეობის მონიტორინგი"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"საშუალებას აძლევს აპლიკაციებს განახორციელოს ქსელის მდგომარეობის მონიტორინგი. ეს ფუნქცია ჩვეულებრივ აპებს არ ჭირდება."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"შეყვანის მოწყობილობის კალიბრაციის ცვლილება"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"საშუალებას აძლევს აპს შეცვალოს სენსორული ეკრანის კალიბრაციის პარამეტრები. ჩვეულებრივ აპებს წესით არ უნდა დაჭირდეს."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"სახლი"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"სამსახური"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"სხვა"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"ამ კონტაქტის მნახველი აპლიკაცია ვერ მოიძებნა."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"განახლებასთან და აღდგენის სისტემასთან ინტერაქცია"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"საშუალებას აძლევს აპლიკაციას მოახდინოს აღდგენის სისტემასთან და სისტემის განახლებასთან ინტერაქცია."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ვერ გაეშვა"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"გაზიარება"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"გაუზიარეთ <xliff:g id="APPLICATION_NAME">%s</xliff:g>-ს"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"გასრიალებით მართვა. შეეხეთ &amp; არ აუშვათ."</string>
-    <string name="description_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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"მოწყობილობასთან დაკავშირება"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ეკრანის მოწყობილობაზე გადაცემა"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"მოწყობილობების ძიება…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"პარამეტრები"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"კავშირის გაწყვეტა"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"სკანირება..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"დაკავშირება..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"ხელმისაწვდომი"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"მიმდინარეობს ეკრანის გადაცემა"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"<xliff:g id="NAME">%1$s</xliff:g>-თან დაკავშირება"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"მიმდინარეობს ეკრანის გადაცემა"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"დაკავშირებულია <xliff:g id="NAME">%1$s</xliff:g>-თან"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"ჩამოასრიალეთ ზევიდან სრული ეკრანის დასახურად"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ჩამოასრიალეთ ზევიდან სრული ეკრანის დასახურად."</string>
+    <string name="done_label" msgid="2093726099505892398">"დასრულდა"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"საათების წრიული სლაიდერი"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"წუთების წრიული სლაიდერი"</string>
+    <string name="select_hours" msgid="6043079511766008245">"აირჩიეთ საათები"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"აირჩიეთ წუთები"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"დღეების ბადე თვეზე"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"წლის სია"</string>
+    <string name="select_day" msgid="7774759604701773332">"აირჩიეთ თვე და რიცხვი"</string>
+    <string name="select_year" msgid="7952052866994196170">"აირჩიეთ წელი"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"არჩეულია <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> წაიშალა"</string>
 </resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 6dace3c..21a7746 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"បញ្ចូល​កូដ PUK ដែល​មាន​ពី​ ៨ លេខ​ ឬ​វែង​ជាង​នេះ។"</string>
     <string name="needPuk" msgid="919668385956251611">"ស៊ីមកាត​​របស់​អ្នក​ជាប់​កូដ PUK ។ បញ្ចូល​កូដ PUK ដើម្បី​ដោះ​សោ។"</string>
     <string name="needPuk2" msgid="4526033371987193070">"បញ្ចូល​កូដ PUK2 ដើម្បី​ដោះ​សោ​ស៊ីម​កាត។"</string>
+    <string name="enablePin" msgid="209412020907207950">"បរាជ័យ, បើក​ការ​ចាក់សោ​ស៊ី​ម / RUIM ។"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"អ្នក​មាន <xliff:g id="NUMBER">%d</xliff:g> ការ​ព្យាយាម​ដែល​នៅសល់​មុន​ពេល​ស៊ី​ម​ត្រូវ​បាន​ចាក់សោ​។"</item>
+    <item quantity="other" msgid="7530597808358774740">"អ្នក​មាន <xliff:g id="NUMBER">%d</xliff:g> ការ​ព្យាយាម​ដែល​នៅសល់​មុន​ពេល​ស៊ី​ម​ត្រូវ​បាន​ចាក់សោ​។"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"លេខ​សម្គាល់​អ្នក​ហៅ​​ចូល"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"លុប​ផ្លូវកាត់"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"ឲ្យ​កម្មវិធី​លុប​ផ្លូវកាត់​អេក្រង់​ដើម​ដោយ​គ្មាន​អំពើ​ពី​អ្នកប្រើ។"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"នាំ​ផ្លូវ​ការ​ហៅ​ចេញ​ឡើងវិញ"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"ឲ្យ​កម្មវិធី​ដំណើរការ​ការ​ហៅ​ចេញ និង​ប្ដូរ​លេខ​ត្រូវ​ហៅ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​តាមដាន ប្ដូរ​ទិស ឬ​ការពារ​ការ​ហៅ​ចេញ។"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"ឲ្យ​កម្មវិធី​ឃើញ​លេខ​ដែល​កំពុង​ត្រូវ​បាន​ហៅ​អំឡុង​ពេល​ហៅ​ចេញ​​ដោយ​ប្រើ​​ជម្រើស​ ដើម្បី​បញ្ជូន​​ការ​ហៅ​បន្ត​ទៅ​លេខ​ផ្សេង ឬ​បោះបង់​ការ​ហៅ​រួម​គ្នា។"</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"ភ្ជាប់​ទៅ​ការ​បង្ហាញ​ពី​ចម្ងាយ"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ភ្ជាប់​​ទៅ​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​ការ​បង្ហាញ​ពី​ចម្ងាយ។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ចង​សេវា​កម្ម​ធាតុ​ក្រាហ្វិក"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ឲ្យ​ម្ចាស់​ចង​ចំណុច​ប្រទាក់​កម្រិត​កំពូល​នៃ​សេវាកម្ម​ធាតុ​ក្រាហ្វិក។ មិន​គួរ​​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ទាក់ទង​ជា​មួយ​អ្នកគ្រប់គ្រង​ឧបករណ៍"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"ដំណើរការ​កម្មវិធី​អំឡុង​ពេល​ទំនេរ"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​ប្រព័ន្ធ Android ដំណើរការ​កម្មវិធី​ក្នុង​ផ្ទៃ​ខាង​ក្រោយ ខណៈ​ដែល​ឧបករណ៍​មិន​កំពុង​ប្រើ។"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"អាន/សរសេរ​ធនធាន​គ្រប់គ្រង​ប្រអប់"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ឲ្យ​កម្មវិធី​អាន និង​សរសេរ​ប្រភព​ណាមួយ​ដែល​គ្រប់គ្រង​ដោយ​ក្រុម​អ្នក​វិនិច្ឆ័យ ឧទាហរណ៍ ឯកសារ​នៅ​ក្នុង /dev ។ វា​អាច​ប៉ះពាល់​យ៉ាង​ខ្លាំង​ដល់​ស្ថេរ​ភាព​ និង​សុវត្ថិភាព​ប្រព័ន្ធ។ វា​គួរ​ត្រូវ​បាន​ប្រើ​សម្រាប់​វិនិច្ឆ័យ​ផ្នែក​រឹង​ជាក់​លាក់​ដោយ​ក្រុមហ៊ុន​ផលិត ឬ​ប្រតិបត្តិ​ករ។"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"បិទ ឬ​បើក​សមាសធាតុ​កម្មវិធី"</string>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ឲ្យ​កម្មវិធី​កែ​ការ​កំណត់​សំឡេង​សកល ដូច​ជា​កម្រិត​សំឡេង និង​អូប៉ាល័រ​ដែល​បាន​ប្រើ​សម្រាប់​លទ្ធផល។"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ថត​សំឡេង"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"​ឱ្យ​កម្មវិធី​ថត​សំឡេង​​ជាមួយ​មីក្រូហ្វូន​​​។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​ថត​សំឡេង​​នៅ​ពេល​ណា​មួយ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"ការ​ភ្ជាប់​ស៊ីមកាត"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"ឲ្យ​កម្មវិធី​ផ្ញើ​ពាក្យ​បញ្ជា​ទៅ​ស៊ីម​កាត។ វា​គ្រោះ​ថ្នាក់​ណាស់។"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ថត​រូប និងវីដេអូ"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"ឲ្យ​កម្មវិធី​ថត​រូប និង​វីដេអូ​ដោយ​ប្រើ​ម៉ាស៊ីន​ថត។ វា​ឲ្យ​កម្មវិធី​​ប្រើ​ម៉ាស៊ីន​ថត​នៅ​ពេល​​ណាមួយ​ដោយ​គ្មាន​ការ​បញ្ជាក់​របស់​អ្នក។"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"បិទ​​ពន្លឺ​បង្ហាញ​ការ​បញ្ជូន​​ពេល​ម៉ាស៊ីន​ថត​កំពុង​ប្រើ"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"ឲ្យ​កម្មវិធី​ពិនិត្យ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ កម្មវិធី​ដែល​មាន​សិទ្ធិ​នេះ​អាច​ប្ដូរ​បណ្ដាញ បិទ និង​បើកវិទ្យុ​ក្នុង​ទូរស័ព្ទ​ដោយ​មិន​ជូន​ដំណឹង​អ្នក។"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"អាន​ស្ថានភាព និង​អត្តសញ្ញាណ​ទូរស័ព្ទ"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរការ​លក្ខណៈ​ទូរស័ព្ទ​នៃ​ឧបករណ៍។ សិទ្ធិ​នេះ​​ឲ្យ​កម្មវិធី​កំណត់​លេខ​ទូរស័ព្ទ និង​លេខ​សម្គាល់​ឧបករណ៍ ថា​តើ​ការ​ហៅ​សកម្ម និង​លេខ​ពី​ចម្ងាយ​បាន​ភ្ជាប់​ដោយ​ការ​ហៅ។"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"អាន​ស្ថានភាព​ទូរស័ព្ទ​ត្រឹមត្រូវ"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ឲ្យ​កម្មវិធី​ចូល​ដំណើរ​ការ​ស្ថានភាព​ទូរស័ព្ទ​​​ត្រឹមត្រូវ។ សិទ្ធិ​នេះ​អនុញ្ញាត​ឲ្យ​កម្មវិធី​កំណត់​ស្ថានភាព​ហៅ​ជាក់ស្ដែង ថា​តើ​ការ​ហៅ​សកម្ម ឬ​ស្ថិត​ក្នុង​ផ្ទៃ​ខាងក្រោយ ការ​ហៅ​បរាជ័យ ស្ថានភាព​ភ្ជាប់​ទិន្នន័យ​ត្រឹមត្រូវ និង​ការ​ភ្ជាប់​ទិន្នន័យ​បរាជ័យ។"</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ដក​ហូត​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ដែល​បាន​ផ្ដល់​ដោយ​ក្រុមហ៊ុន​បញ្ជូន។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"សង្កេត​មើល​លើ​លក្ខខណ្ឌ​បណ្ដាញ"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ឲ្យ​កម្មវិធី​សង្កេត​មើល​​លើ​លក្ខខណ្ឌ​បណ្ដាញ​។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ប្ដូរ​​ចំណុច​ឧបករណ៍​បញ្ចូល"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ឲ្យ​​កម្មវិធី​កែ​ប៉ារ៉ាម៉ែត្រ​កែ​ចំណុច​​នៃ​ការ​ប៉ះ​អេក្រង់។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់​ក្បួន​ពាក្យ​សម្ងាត់"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យ​ប្រវែង និង​តួអក្សរ​ដែល​បាន​អនុញ្ញាត​ក្នុង​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់។"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យ​ការ​ព្យាយាម​ដោះ​សោ​អេក្រង់"</string>
@@ -783,7 +800,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"ការ​ជជែក"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"គេហ​ទំព័រ"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"កន្លែង​ធ្វើការ"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"ផ្សេងៗ"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"រក​មិន​ឃើញ​កម្មវិធី ដើម្បី​មើល​ទំនាក់ទំនង​នេះ​ទេ។"</string>
     <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>
@@ -1123,14 +1141,14 @@
     <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="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="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>
@@ -1188,7 +1206,7 @@
     <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_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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"អន្តរកម្ម​ជា​មួយ​បច្ចុប្បន្នភាព និង​ប្រព័ន្ធ​សង្គ្រោះ"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"ឲ្យ​កម្មវិធី​មាន​អន្តរកម្ម​ជា​មួយ​ប្រព័ន្ធ​សង្គ្រោះ និង​បច្ចុប្បន្នភាព​ប្រព័ន្ធ។"</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>
@@ -1343,7 +1363,7 @@
     <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_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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"មិន​អាច​ចាប់ផ្ដើម <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ចែករំលែក​ជា​មួយ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ចែក​រំលែក​ជា​មួយ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"គ្រប់គ្រង​ការ​រុញ។ ប៉ះ &amp; សង្កត់។"</string>
-    <string name="description_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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"ភ្ជាប់​ឧបករណ៍"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ចាត់​ថ្នាក់​អេក្រង់​ទៅ​ឧបករណ៍"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"កំពុង​ស្វែងរក​ឧបករណ៍..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"ការ​កំណត់"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"ផ្ដាច់"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"កំពុង​វិភាគ​រក…"</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"កំពុង​​​ភ្ជាប់​…"</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"ទំនេរ"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"ចាត់​ថ្នាក់​អេក្រង់"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"កំពុង​តភ្ជាប់​ទៅ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"ចាត់​ថ្នាក់​អេក្រង់"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"តភ្ជាប់​ទៅ <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"លេខ​កូដ 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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"អូស​​​ចុះក្រោម ដើម្បី​ចេញ​ពី​ការ​បង្ហាញ​ពេញ​អេក្រង់"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"អូស​​​​ពីលើ​ចុះក្រោម ដើម្បី​ចេញ​ពី​ការ​បង្ហាញ​ពេញ​អេក្រង់។"</string>
+    <string name="done_label" msgid="2093726099505892398">"រួចរាល់"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"គ្រាប់​រំកិល​រង្វង់​ម៉ោង"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"គ្រាប់​រំកិល​រង្វង់​នាទី"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ជ្រើស​ម៉ោង"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"ជ្រើស​នាទី"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"ក្រឡា​​​ខែ​នៃ​ថ្ងៃ"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"បញ្ជី​ឆ្នាំ"</string>
+    <string name="select_day" msgid="7774759604701773332">"ជ្រើស​ខែ និង​ថ្ងៃ"</string>
+    <string name="select_year" msgid="7952052866994196170">"ជ្រើស​ឆ្នាំ"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"បាន​ជ្រើស <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"បាន​លុប <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 1a0b2d9..9e46527 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"실패했습니다. SIM/RUIM 잠금을 사용 설정하세요."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"<xliff:g id="NUMBER">%d</xliff:g>회 이상 실패할 경우 SIM이 잠깁니다."</item>
+    <item quantity="other" msgid="7530597808358774740">"<xliff:g id="NUMBER">%d</xliff:g>회 이상 실패할 경우 SIM이 잠깁니다."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"발신자 번호"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"바로가기 제거"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"애플리케이션이 사용자의 작업 없이 홈 화면 바로가기를 삭제할 수 있도록 허용합니다."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"발신전화 경로 전환"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"앱이 발신 전화를 처리하고 전화를 걸 번호를 변경할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 발신 전화를 모니터링, 리디렉션 또는 차단할 수도 있습니다."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"통화를 다른 번호로 리디렉션하거나 통화를 완전히 중단하는 옵션을 사용하여, 앱에서 발신 통화 중에 전화를 거는 번호를 볼 수 있게 허용합니다."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"원격 디스플레이에 연결"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"권한을 가진 프로그램이 원격 디스플레이에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"위젯 서비스와 연결"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"권한을 가진 프로그램이 위젯 서비스에 대한 최상위 인터페이스를 사용하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"기기 관리자와 상호 작용"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"유휴 시간 동안 애플리케이션 실행"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"이 권한을 부여하면 기기를 사용하지 않는 동안 Android 시스템이 백그라운드에서 애플리케이션을 실행할 수 있게 됩니다."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"진단 그룹 소유의 리소스 읽기/쓰기"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"앱이 진단 그룹 소유의 리소스(예: /dev에 있는 파일)를 읽고 쓸 수 있도록 허용합니다. 이 기능은 시스템 안정성 및 보안에 영향을 미칠 수 있으므로 제조업체 또는 사업자가 하드웨어 관련 진단을 수행하는 경우에만 사용해야 합니다."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"앱 구성요소 사용 또는 사용 안함"</string>
@@ -460,7 +469,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>
@@ -477,6 +486,8 @@
     <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">"Wi-Fi 디스플레이 설정"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"앱이 Wi-Fi 디스플레이를 설정하고 연결하도록 허용합니다."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wi-Fi 디스플레이 제어"</string>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"앱이 음량이나 출력을 위해 사용하는 스피커 등 전체 오디오 설정을 변경할 수 있도록 허용합니다."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"오디오 녹음"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"앱이 마이크로 오디오를 녹음할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 사용자의 확인 없이 언제든지 오디오를 녹음할 수 있습니다."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM 통신"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"앱이 SIM에 명령어를 전송할 수 있도록 허용합니다. 이 기능은 매우 위험합니다."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"사진과 동영상 찍기"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"앱이 카메라로 사진과 동영상을 찍을 수 있도록 허용합니다. 이 권한을 사용하면 앱이 언제든지 사용자의 확인 없이 카메라를 사용할 수 있습니다."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"카메라를 사용할 때 전송 표시 LED 사용 중지"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"앱이 기기의 휴대전화 기능을 관리할 수 있도록 허용합니다. 이 권한을 갖는 앱은 사용자에게 알리지 않고 네트워크를 전환하거나 무선 기능을 켜고 끄는 등의 작업을 수행할 수 있습니다."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"휴대전화 상태 및 ID 읽기"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"앱이 기기의 휴대전화 기능에 액세스할 수 있도록 허용합니다. 이 권한을 사용하면 앱이 전화번호 및 기기의 ID, 활성 통화인지 여부, 통화가 연결된 원격 번호 등을 확인할 수 있습니다."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"정확한 전화 상태 읽기"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"앱이 정확한 전화 상태에 액세스할 수 있도록 허용합니다. 이 권한을 부여하면 앱이 실제 통화 상태, 활성 통화 또는 백그라운드 상태인지 여부, 통화 실패, 정확한 데이터 연결 상태 및 데이터 연결 실패 등을 판단합니다."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"권한을 가진 프로그램이 이동통신사에서 제공한 구성 앱을 호출하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"네트워크 상태에 대한 관측 보고 수신"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"애플리케이션이 네트워크 상태에 대한 관측 보고를 수신하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"입력 기기 보정 변경"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"앱이 터치 스크린의 보정 매개변수를 수정할 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"집"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"직장"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"기타"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"이 주소록을 표시할 수 있는 애플리케이션이 없습니다."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"업데이트 및 복구 시스템과 상호작용"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"애플리케이션이 복구 시스템 및 시스템 업데이트와 상호작용할 수 있도록 허용합니다."</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>을(를) 실행할 수 없습니다."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"공유 대상:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>와(과) 공유"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"슬라이딩 핸들을 길게 터치하세요."</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"기기에 연결"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"기기로 화면 전송"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"기기 검색 중…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"설정"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"연결 해제"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"검색 중..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"연결 중..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"사용 가능"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"화면 전송 중"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"<xliff:g id="NAME">%1$s</xliff:g>에 연결 중"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"화면 전송 중"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"<xliff:g id="NAME">%1$s</xliff:g>에 연결됨"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"전체화면을 종료하려면 위에서 아래로 스와이프"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"전체화면을 종료하려면 위에서 아래로 스와이프하세요."</string>
+    <string name="done_label" msgid="2093726099505892398">"완료"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"시간 원형 슬라이더"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"분 원형 슬라이더"</string>
+    <string name="select_hours" msgid="6043079511766008245">"시간 선택"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"분 선택"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"월별 바둑판식 날짜 표시"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"년"</string>
+    <string name="select_day" msgid="7774759604701773332">"월/일 선택"</string>
+    <string name="select_year" msgid="7952052866994196170">"연도 선택"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>이(가) 선택됨"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 삭제됨"</string>
 </resources>
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index dc59f61..640ca1e 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -61,6 +61,10 @@
     Landscape's layout allows this to be smaller than for portrait. -->
     <dimen name="kg_squashed_layout_threshold">400dp</dimen>
 
+    <!-- New TimePicker dimensions. -->
+    <dimen name="timepicker_left_side_width">250dip</dimen>
+
     <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
     <dimen name="immersive_mode_cling_width">380dp</dimen>
+
 </resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 003b3f9..56a05c3 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"ບໍ່ສຳເລັດ, ເປີດນໍາໃຊ້ການລັອກຂອງ SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຂອງທ່ານຈະຖືກລັອກ."</item>
+    <item quantity="other" msgid="7530597808358774740">"ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຂອງທ່ານຈະຖືກລັອກ."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ໝາຍເລກຜູ່ໂທເຂົ້າ"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ຖອນທາງລັດ"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນລຶບທາງລັດໃນໜ້າຫຼັກໄດ້ ໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ປ່ຽນເສັ້ນທາງການໂທອອກ"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"ອະນຸຍາດໃຫ້ແອັບຯປະມວນຜົນສາຍທີ່ໂທອອກ ແລະປ່ຽນໝາຍເລກທີ່ຈະໂທອອກ. ແອັບຯທີ່ເປັນອັນຕະລາຍອາດກວດສອບ, ໂອນສາຍ ຫຼືຂັດຂວາງບໍ່ໃຫ້ໂທອອກໄດ້."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ເບິ່ງ​​ໝາຍ​ເລກເບີ​ໂທ ໃນ​ລະ​ຫວ່າງ​ການ​ໂທ​ອອກ ພ້ອມ​ທັງ​ໂຕ​ເລືອກ​ໃນ​ການ​ປ່ຽນ​ເສັ້ນ​ທາງ​ການ​ໂທ​ໄປ​ຫາ​ເບີ​ອື່ນ ຫຼື ລາຍ​ລະ​ອຽດກ່ຽວ​ກັບ​ເບີ​ໂທ​ລະ​ສັບ."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"ຜູກກັນເພື່ອສະແດງຜົນທາງໄກ."</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບສ່ວນຕິດຕໍ່ລະດັບສູງສຸດ ຂອງການສະແດງຜົນທາງໄກ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"ເຊື່ອມໂຍງໄປຫາບໍລິການວິດເຈັດ"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"ອະນຸຍາດໃຫ້ຜູ່ຖືຜູກກັບອິນເຕີເຟດລະດັບສູງສຸດ ຂອງບໍລິການວິເຈັດ. ບໍ່ຈຳເປັນສຳລັບແອັບຯທົ່ວໄປ."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ຕິດຕໍ່ກັບຜູ່ເບິ່ງແຍງອຸປະກອນ"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"ເປີດ​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ໃນ​ເວ​ລາ​ທີ່​ບໍ່​ເຮັດ​ວຽກ"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"ນີ້​ຈະ​ເປັນ​ການອ​ະ​ນຸ​ຍາດ​​ໃຫ້​ລະ​ບົບ Android ສາ​ມາດ​ເປີດ​ແອັບ​ພ​ລິ​ເຄ​ຊັນ​ໃນ​ພື້ນຫຼັງໄດ້​ໃນ​ຂະ​ນະ​ທີ່​ອຸ​ປະ​ກອນບໍ່​​ຖືກ​ນຳ​ໃຊ້."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"ອ່ານ/ຂຽນ ໃສ່ຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິໄຈ"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນອ່ານ ແລະຂຽນ ໃສ່ທຸກຊັບພະຍາກອນທີ່ເປັນຂອງກຸ່ມວິນິໄສ; ຕົວຢ່າງ: ໄຟລ໌ໃນ /dev. ສິ່ງນີ້ອາດສົ່ງຜົນກະທົບຕໍ່ຄວາມສະຖຽນ ແລະຄວາມປອດໄພຂອງລະບົບ. ສິ່ງນີ້ຄວນໃຊ້ສຳຫຼັບການວິເຄາະບັນຫາຈຳເພາະ ຂອງບາງຮາດແວໂດຍຜູ່ຜະລິດ ຫຼືຜູ່ປະຕິບັດການເທົ່ານັ້ນ."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"ເປີດ ຫຼືປິດນຳໃຊ້ອົງປະກອບຂອງແອັບຯ"</string>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ອະນຸຍາດໃຫ້ແອັບຯແກ້ໄຂການຕັ້ງຄ່າສຽງສ່ວນກາງ ເຊັ່ນ: ລະດັບສຽງ ແລະລຳໂພງໃດທີ່ຖືກໃຊ້ສົ່ງສຽງອອກ."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"ບັນທຶກສຽງ"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"ອະນຸຍາດໃຫ້ແອັບຯບັນທຶກສຽງດ້ວຍໄມໂຄຣໂຟນໄດ້. ການອະນຸຍາດນີ້ຈະເຮັດໃຫ້ແອັບຯ ສາມາດບັນທຶກສຽງໄດ້ຕະຫລອດເວລາ ໂດຍບໍ່ຕ້ອງຖ້າການຢືນຢັນຈາກທ່ານ."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"ການສື່ສານຂອງ SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"ອະນຸຍາດໃຫ້ແອັບຯສົ່ງຄຳສັ່ງຫາ SIM. ສິ່ງນີ້ອັນຕະລາຍຫຼາຍ."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ຖ່າຍຮູບ ແລະວິດີໂອ"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"ອະນຸຍາດໃຫ້ແອັບຯຖ່າຍຮູບ ແລະວິດີໂອດ້ວຍກ້ອງຖ່າຍຮູບ. ການອະນຸຍາດນີ້ຈະອານຸຍາດໃຫ້ແອັບຯ ສາມາດໃຊ້ກ້ອງຖ່າຍຮູບໄດ້ຕະຫລອດເວລາ ໂດຍບໍ່ຕ້ອງຖ້າການຢືນຢັນຈາກທ່ານ."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"ປິດໄຟສັນຍານ LED ເມື່ອນຳໃຊ້ກ້ອງ"</string>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"ອ່ານ​ຄ່າ​ສະ​ຖາ​ນະ​ລະ​ອຽດ​ຂອງ​ໂທ​ລະ​ສັບ"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ເຂົ້າ​ເຖິງ​ສະ​ຖາ​ນະ​ໂດຍ​ລະ​ອຽດ​ຂອງ​ໂທ​ລະ​ສັບ. ການ​ອະ​ນຸ​ຍາດ​ນີ້​ຈະ​ຍິນຍອມ​ໃຫ້​ແອັບຯ​ກວດ​ສອບ​ສະ​ຖານ​ະ​ການ​ໂທ​ແທ້ໆ ວ່າ​ກຳ​ລັງ​ດຳ​ເນີນ​ຢູ່ ຫຼື​ຢູ່​ໃນ​ແບັກ​ກ​ຣາວ, ຄວາມລົ້ມ​ເຫລວ​ຂອງ​ການ​ໂທ, ສະ​ຖາ​ນະ​ການ​ເຊື່ອມ​ຕໍ່​ຂໍ້​ມູນ​ແບບ​ລະ​ອຽດ ແລະ​ຄວາມ​ລົ້ມ​ເຫລວ​ຂອງ​ການ​ເຊື່ອມ​ຕໍ່​ຂໍ້​ມູນ."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ອະ​ນຸ​ຍາດ​ໃຫ້​ເຈົ້າຂອງຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັ່ນຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ. ປົກກະຕິແລ້ວແອັບຯທຳມະດາຈະບໍ່ຕ້ອງການໃຊ້."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ປ່ຽນ​ການ​ວັດ​ແທ້​ອຸ​ປະ​ກອນ​ປ້ອນ​ຂໍ້​ມູນ"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ແກ້​ໄຂ​ຄ່າ​ການວັດ​ແທ້​ໜ້າ​ຈ​ໍ​ສຳ​ຜັດ. ​ແອັບຯ​ທຳ​ມະ​ດາບໍ່​ຄວນ​ໃຊ້."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"ເຮືອນ"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"ບ່ອນເຮັດວຽກ"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"ອື່ນໆ"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"ບໍ່ພົບແອັບຯທີ່​ຕິດ​ຕໍ່​ນີ້​."</string>
     <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>
@@ -1114,7 +1132,7 @@
     <string name="loading" msgid="7933681260296021180">"ກຳລັງໂຫລດ..."</string>
     <string name="capital_on" msgid="1544682755514494298">"ເປີດ"</string>
     <string name="capital_off" msgid="6815870386972805832">"ປິດ"</string>
-    <string name="whichApplication" msgid="4533185947064773386">"ເຮັດວຽກໃຫ້ສຳເລັດໂດຍໃຊ້"</string>
+    <string name="whichApplication" msgid="4533185947064773386">"ດຳເນີນການໂດຍໃຊ້"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"ເລືອກແອັບຯ Home"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"ໃຊ້ໂດຍຄ່າເລີ່ມຕົນສຳລັບການເຮັດວຽກນີ້."</string>
     <string name="clearDefaultHintMsg" msgid="3252584689512077257">"ລຶບລ້າງຄ່າເລີ່ມຕົ້ນ ໃນ ການຕັ້ງຄ່າລະບົບ &gt; ແອັບຯ &gt; ດາວໂຫລດແລ້ວ."</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"ຕິດຕໍ່ກັບລະບົບອັບເດດ ແລະລະບົບກູ້ຂໍ້ມູນ."</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັນຕິດຕໍ່ກັບລະບົບກູ້ຂໍ້ມູນ ແລະການອັບເດດລະບົບ."</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"ບໍ່​ສາ​ມາດ​ເປີດ <xliff:g id="APPLICATION_NAME">%s</xliff:g> ໄດ້"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"ແບ່ງປັນກັບ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"ແບ່ງປັນໃຫ້ <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ເລື່ອນບ່ອນຖື ແລ້ວແຕະຄ້າງໄວ້."</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"ເຊື່ອມຕໍ່ຫາອຸປະກອນ"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ສົ່ງພາບໜ້າຈໍໄປຫາອຸປະກອນ"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"ກຳລັງຊອກຫາອຸປະກອນ..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"ການຕັ້ງຄ່າ"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"ຕັດການເຊື່ອມຕໍ່"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"ກຳລັງສະແກນ..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"ກຳລັງເຊື່ອມຕໍ່..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"ສາມາດໃຊ້ໄດ້"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"ກຳລັງສົ່ງພາບໜ້າຈໍ"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"ກຳລັງເຊື່ອມຕໍ່ຫາ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"ການສົ່ງພາບໜ້າຈໍ"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"ເຊື່ອມຕໍ່ກັບ <xliff:g id="NAME">%1$s</xliff:g> ແລ້ວ"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"ລະຫັດ PUK ຄວນມີ 8 ໂຕເລກ"</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"ປ້ອນລະຫັດ PUK ທີ່ຖືກຕ້ອງຄືນໃໝ່. ການພະຍາຍາມໃສ່ຫຼາຍເທື່ອຈະເຮັດໃຫ້ຊິມກາດໃຊ້ບໍ່ໄດ້ຖາວອນ."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ລະຫັດ PIN ບໍ່ກົງກັນ"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ແຕ້ມຮູບແບບປົດລັອກຫຼາຍເກີນໄປ"</string>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"ລອງໃໝ່ອີກຄັ້ງໃນພາຍຫລັງ."</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"ປັດລົງມາຈາກທາງເທິງເພື່ອອອກຈາກໂໝດເຕັມໜ້າຈໍ."</string>
+    <string name="done_label" msgid="2093726099505892398">"ແລ້ວໆ"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"ໂຕໝຸນປັບຊົ່ວໂມງ"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"ໂຕໝຸນປັບນາທີ"</string>
+    <string name="select_hours" msgid="6043079511766008245">"ເລືອກ​ຊົ່ວ​ໂມງ"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"ເລືອກນາ​ທີ"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"ຕາຕາລາງວັນທີເດືອນປີ"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"ລາຍການປີ"</string>
+    <string name="select_day" msgid="7774759604701773332">"ເລືອກເດືອນ ແລະ ວັນ"</string>
+    <string name="select_year" msgid="7952052866994196170">"ເລືອກ​ປີ"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ຖືກເລືອກແລ້ວ"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ຖືກລຶບແລ້ວ"</string>
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 9fa41c9..4284032 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Įveskite 8 skaitmenų ar ilgesnį PUK kodą."</string>
     <string name="needPuk" msgid="919668385956251611">"Jūsų SIM kortelė yra užrakinta PUK kodu. Jei norite ją atrakinti, įveskite PUK kodą."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Įveskite PUK2 kodą, kad panaikintumėte SIM kortelės blokavimą."</string>
+    <string name="enablePin" msgid="209412020907207950">"Nepavyko. Įgalinti SIM / RUIM užraktą."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Liko <xliff:g id="NUMBER">%d</xliff:g> band. Paskui SIM kortelė bus užrakinta."</item>
+    <item quantity="other" msgid="7530597808358774740">"Liko <xliff:g id="NUMBER">%d</xliff:g> band. Paskui SIM kortelė bus užrakinta."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Įeinančio skambintojo ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"pašalinti sparčiuosius klavišus"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Programai leidžiama pašalinti sparčiuosius klavišus iš pagrindinio ekrano be naudotojo įsikišimo."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"peradresuoti išsiunčiamuosius skambučius"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Leidžiama programai atlikti išsiunčiamuosius skambučius ir keisti renkamą numerį. Šis leidimas suteikia teisę programai stebėti, peradresuoti ar neleisti išsiunčiamųjų skambučių."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Leidžiama programai peržiūrėti renkamą numerį išsiunčiamojo skambučio metu suteikiant galimybę peradresuoti skambutį kitu numeriu arba visiškai nutraukti skambutį."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"gauti teksto pranešimus (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Leidžiama programai gauti ir apdoroti SMS pranešimus. Tai reiškia, kad programa gali stebėti ir ištrinti į jūsų įrenginį siunčiamus pranešimus jums jų neparodžiusi."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"gauti teksto pranešimus (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Leidžiama savininkui susisaistyti su aukščiausio lygio VPN paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"susaistyti su darbalaukio fonu"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Leidžiama savininką susaistyti su aukščiausio lygio darbalaukio fono sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"susisaistyti su nuotoliniu ekranu"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Leidžiama savininkui susisaistyti su aukščiausiojo lygio nuotolinio ekrano sąsaja. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"susaistyti su valdiklio paslauga"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"paleisti programą, kai įrenginys yra neaktyvus"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Šiuo leidimu sistemai „Android“ leidžiama fone paleisti programą, kai įrenginys yra nenaudojamas."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Leidžiama programai naudoti „SurfaceFlinger“ žemo lygio funkcijas."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"skaityti kadrų buferį"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Leidžiama programai skaityti rėmelio buferio turinį."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"pasiekti „InputFlinger“"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Programai leidžiama naudoti „InputFlinger“ žemo lygio funkcijas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigūruoti „Wi-Fi“ pateiktis"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Leidžiama programai įrašyti garsą naudojant mikrofoną. Šis leidimas suteikia galimybę programai įrašyti garsą bet kada be jūsų patvirtinimo."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM kortelės ryšys"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Programai leidžiama siųsti komandas į SIM kortelę. Tai labai pavojinga."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"fotografuoti ir filmuoti"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Leidžiama programai fotografuoti ir filmuoti kamera. Šis leidimas suteikia teisę programai naudoti kamerą bet kada be jūsų patvirtinimo."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"neleisti perduoti LED indikatoriaus, kai naudojamas fotoaparatas"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Leidžiama programai valdyti įrenginio telefono funkcijas. Šį leidimą turinti programa gali perjungti tinklus, įjungti ir išjungti telefono radiją ir atlikti panašius veiksmus jūsų neįspėdama."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"skaityti telefono būseną ir tapatybę"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Leidžiama programai pasiekti telefono funkcijas įrenginyje. Šis leidimas suteikia teisę programai nustatyti telefono numerį ir įrenginio ID, tai, ar skambutis aktyvus, ir skambučiu prijungtą nuotolinį numerį."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"skaityti tikslias telefono būsenas"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Programai leidžiama pasiekti tikslias telefono būsenas. Šiuo leidimu programai leidžiama nustatyti tikrą skambučio būseną, ar skambutis yra aktyvus, ar vyksta fone, ar paskambinti nepavyksta, tikslią duomenų ryšio būseną ir ar nepavyksta užmegzti duomenų ryšio."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"neleisti planšetiniam kompiuteriui užmigti"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"keisti įvesties įrenginio kalibravimą"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Leidžiama programai keisti jutiklinio ekrano kalibravimo parametrus. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Pagrindinis"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Darbas"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Kita"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nerasta jokių programų šiam kontaktui peržiūrėti."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Sąveikauti su naujiniu ir atkūrimo sistema"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Programai leidžiama sąveikauti su atkūrimo sistema ir sistemos naujiniais."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Įvesti"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Pasirinkite programą"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nepavyko paleisti „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Bendrinti su"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Bendrinti su „<xliff:g id="APPLICATION_NAME">%s</xliff:g>“"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Slydimo valdymas. Palieskite ir laikykite."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Perbraukite pirštu, kad atrakintumėte."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Prijunkite ausines, kad išgirstumėte sakomus slaptažodžio klavišus."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Taškas."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"„Bluetooth“ garsas"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Belaidis rodymas"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Atlikta"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Medijos išvestis"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Prijungimas prie įrenginio"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Perduoti ekraną į įrenginį"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Ieškoma įrenginių…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Nustatymai"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Atjungti"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Nuskaitoma..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Jungiama..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Pasiekiama"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Perduodamas ekranas"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Prisijungiama prie „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Perduodamas ekranas"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Prisijungta prie „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Atjungti"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK kodą turi sudaryti 8 skaičiai."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Vėliau bandykite dar kartą"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Perbraukite nuo viršaus žemyn, kad išeitumėte iš viso ekrano režimo"</string>
+    <string name="done_label" msgid="2093726099505892398">"Atlikta"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Apskritas valandų slankiklis"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Apskritas minučių slankiklis"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pasirinkite valandas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pasirinkite minutes"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Mėnesio dienų tinklelis"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Metų sąrašas"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pasirinkite mėnesį ir dieną"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pasirinkite metus"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Pasirinkta: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Ištrinta: <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 036d5d6..4a207d9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ierakstiet PUK kodu, kas sastāv no 8 vai vairāk cipariem."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM karte ir bloķēta ar PUK kodu. Ierakstiet PUK kodu, lai to atbloķētu."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ierakstiet PUK2 kodu, lai atbloķētu SIM karti."</string>
+    <string name="enablePin" msgid="209412020907207950">"Neizdevās. Iespējojiet SIM/RUIM bloķēšanu."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Varat mēģināt vēl <xliff:g id="NUMBER">%d</xliff:g> reizi, pirms SIM karte tiks bloķēta."</item>
+    <item quantity="other" msgid="7530597808358774740">"Varat mēģināt vēl <xliff:g id="NUMBER">%d</xliff:g> reizi(-es), pirms SIM karte tiks bloķēta."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Ienākošā zvana zvanītāja ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"atinstalēt saīsnes"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Ļauj lietojumprogrammai noņemt saīsnes no sākuma ekrāna, nejautājot lietotājam."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"pārmaršrutēt izejošos zvanus"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Ļauj lietotnei apstrādāt izejošos zvanus un mainīt numuru, uz kuru tiks zvanīts. Ar šo atļauju lietotne var pārraudzīt, novirzīt vai neatļaut izejošos zvanus."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Ļauj lietotnei skatīt ievadīto tālruņa numuru izejošā zvana laikā un piedāvā iespēju šo zvanu pāradresēt uz citu numuru vai vispār pārtraukt zvanu."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"saņemt īsziņas (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ļauj lietotnei saņemt un apstrādāt īsziņas. Tas nozīmē, ka lietotne var pārraudzīt vai dzēst uz jūsu ierīci nosūtītos ziņojumus, neparādot tos jums."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"saņemt ziņojumus (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Ļauj īpašniekam izveidot saiti ar VPN pakalpojuma augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"saistīt ar tapeti"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Ļauj īpašniekam piesaistīt tapetes augstākā līmeņa lietotāja saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"Saites izveide ar attālu displeju"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Ļauj īpašniekam izveidot saiti ar attāla displeja augšējā līmeņa saskarni. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"saistīt ar logrīka pakalpojumu"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"Lietojumprogrammas darbība dīkstāves laikā"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ar šo atļauju Android sistēmā lietojumprogramma darbojas fonā, kad ierīce netiek lietota."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Ļauj lietotnei lietot SurfaceFlinger zema līmeņa funkcijas."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"lasīt kadru buferi"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Ļauj lietotnei lasīt kadru bufera saturu."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"Piekļuve InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ļauj lietotnei izmantot InputFlinger zema līmeņa funkcijas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wi-Fi displeju konfigurēšana"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Ļauj lietotnei ierakstīt audio, izmantojot mikrofonu. Šī atļauja ļauj lietotnei ierakstīt audio jebkurā brīdī bez jūsu apstiprinājuma."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM saziņa"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Ļauj lietotnei sūtīt komandas uz SIM karti. Tas ir ļoti bīstami!"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"uzņemt attēlus un videoklipus"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Ļauj lietotnei uzņemt attēlus un videoklipus ar kameru. Ar šo atļauju lietotne var jebkurā brīdī izmantot kameru bez jūsu apstiprinājuma."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"Atspējot pārraidīšanas LED indikatoru, kad kamera tiek izmantota"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Ļauj lietotnei kontrolēt ierīces tālruņa funkcijas. Lietotne, kurai ir šī atļauja, var pārslēgt tīklus, ieslēgt un izslēgt tālruņa radio un veikt tamlīdzīgas darbības, nebrīdinot jūs."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"lasīt tālruņa statusu un identitāti"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Ļauj lietotnei piekļūt ierīces tālruņa funkcijām. Ar šo atļauju lietotne var noteikt tālruņa numuru un ierīču ID, zvana statusu un attālo numuru, ar ko ir izveidots savienojums, veicot zvanu."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"precīzu tālruņa statusa datu lasīšana"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Ļauj lietotnei piekļūt precīziem datiem par tālruņa statusu. Izmantojot šo atļauju, lietotne var noteikt zvana faktisko statusu, vai zvans ir aktīvs vai notiek fonā, vai zvans nav izdevies, kā arī precīzu datu savienojuma statusu un neizdevušos datu savienojumus."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"novērst planšetdatora pāriešanu miega režīmā"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"mainīt ievadierīces kalibrēšanu"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ļauj lietotnei pārveidot skārienekrāna kalibrēšanas parametrus. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Mājās"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Darbs"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Cits"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Netika atrasta neviena lietojumprogramma, ar kuru skatīt šo kontaktpersonu."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Mijiedarbošanās ar atjauninājumu un atkopšanas sistēmu"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Ļauj lietojumprogrammai mijiedarboties ar atkopšanas sistēmu un sistēmas atjauninājumiem."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application" msgid="2125168057199941199">"Izvēlieties lietotni"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nevarēja palaist lietotni <xliff:g id="APPLICATION_NAME">%s</xliff:g>."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Kopīgot ar:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Kopīgot ar lietojumprogrammu <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Bīdāms turis. Pieskarieties tam un turiet to nospiestu."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Velciet ar pirkstu, lai atbloķētu."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Pievienojiet austiņas, lai dzirdētu paroles taustiņu nosaukumus."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkts."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistēma"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bezvadu attēlošana"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gatavs"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Multivides izeja"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Savienojuma izveide ar ierīci"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Ekrāna apraide uz ierīci"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Notiek ierīču meklēšana…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Iestatījumi"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Atvienot"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Notiek meklēšana..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Notiek savienojuma izveide..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Pieejams"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Ekrāna apraidīšana"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Notiek savienojuma izveide ar: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Ekrāna apraidīšana"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Izveidots savienojums ar: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Pārtraukt savienojumu"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK kodā ir jābūt 8 cipariem."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Vēlāk mēģiniet vēlreiz."</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Lai izietu no pilnekrāna režīma, velciet no augšas uz leju."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gatavs"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Stundu apļveida slīdnis"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Minūšu apļveida slīdnis"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Atlasiet stundas."</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Atlasiet minūtes."</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Režģis ar mēneša dienām"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Gadu saraksts"</string>
+    <string name="select_day" msgid="7774759604701773332">"Atlasiet mēnesi un dienu."</string>
+    <string name="select_year" msgid="7952052866994196170">"Atlasiet gadu."</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Atlasīts: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> tika dzēsts."</string>
 </resources>
diff --git a/core/res/res/values-mcc440-mnc20/config.xml b/core/res/res/values-mcc440-mnc20/config.xml
index ba709fa..62001d9 100644
--- a/core/res/res/values-mcc440-mnc20/config.xml
+++ b/core/res/res/values-mcc440-mnc20/config.xml
@@ -23,6 +23,6 @@
 
     <!-- Configure mobile network MTU. Carrier specific value is set here.
     -->
-    <integer name="config_mobile_mtu">1340</integer>
+    <integer name="config_mobile_mtu">1422</integer>
 
 </resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index fe3d78b..5e60ce3 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Амжилтгүй боллоо, СИМ/РҮИМ түгжээг идэвхжүүлнэ үү."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Таны СИМ түгжигдэхээс өмнө танд <xliff:g id="NUMBER">%d</xliff:g> оролдлого хийх боломж үлдлээ."</item>
+    <item quantity="other" msgid="7530597808358774740">"СИМ түгжигдэхээс өмнө танд <xliff:g id="NUMBER">%d</xliff:g> оролдлого хийх боломж үлдлээ."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Дуудлага хийгчийн ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"товчлолыг устгах"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Аппликешн нь хэрэглэгчийн оролцоогүйгээр Нүүр дэлгэцний товчлолыг устгаж чадна."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"гарсан дуудлагыг чиглэлийг өөрчлөх"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Апп нь дуудлага хийх болон залгаж байгаа дугаарыг өөрчлөх боломжтой. Энэ зөвшөөрөл нь апп-г залгасан дуудлагыг хаах, хянах болон дахин чиглүүлэх боломжтой болгодог."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Гадагш дуудлага хийх үед залгасан дугаарыг харах, дуудлагыг өөр дугаар руу шилжүүлэх, таслах боломжтой болгоно."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"алсын дэлгэцтэй холбогдох"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Эзэмшигчид алсын дэлгэц дэх дээд давхаргын интерфэйстэй холбогдох боломж олгоно. Энгийн апп-д шаардагдахгүй."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"виджет үйлчилгээтэй холбох"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Эзэмшигч нь виджет үйлчилгээний дээд-төвшиний интерфейстэй холбох боломжтой. Энгийн апп-д шаардлагагүй."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"төхөөрөмжийн админтай харилцан үйлчлэх"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"Сул зогсолтын хугацаанд аппликешнийг ажиллуулна"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Энэ зөвшөөрөл нь Андройд системд төхөөрөмжийг ашиглахгүй байгаа үед аппликешныг далд ажиллуулах боломж олгоно."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"оношлох грүпийн эзэмшдэг нөөцрүү унших/бичих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Апп нь оношлох грүпийн эзэмшдэг, жишээ нь /dev доторх файлууд, дурын  нөөцийг унших бичих боломжтой.Энэ нь системийн тогвортой байдал болон аюулгүй байдалд бодитоор нөлөөлнө. Энэ нь үйлдвэрлэгч болон операторын хардверт-зориулсан оношлогоонд ашиглагдана."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"апп компонентыг идэвхжүүлэх эсвэл идэвхгүй болгох"</string>
@@ -477,6 +486,8 @@
     <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">"Апп-д SurfaceFlinger доод-түвшний функцуудыг ашиглах боломж олгоно."</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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Апп нь дууны хэмжээ, спикерын гаралтад ашиглагдах глобал аудио тохиргоог өөрчлөх боломжтой."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"аудио бичих"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Апп нь микрофоноор аудио бичих боломжтой. Энэ зөвшөөрөл нь апп-д ямар ч үед таны зөвшөөрөлгүйгээр аудио бичих боломжийг олгоно."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"сим холбоо"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Апп-д SIM рүү комманд илгээхийг зөвшөөрнө. Энэ маш аюултай."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"зураг авах болон видео бичих"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Апп нь камераар зураг авах болон видео бичих боломжтой. Энэ зөвшөөрөл нь апп-д ямар ч үед таны зөвшөөрөлгүйгээр камер ашиглах боломжийг олгоно."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"камер ашиглаж байх үед дамжууллыг заагч LED-г идэвхгүй болгох"</string>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"утасны байдлыг нарийн унших"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Апп-д утасны тодорхой байдалд хандах боломжийг олгодог. Энэ зөвшөөрөл апп-д дуудлагын бодит статус, дуудлага идэвхтэй эсхүл ар талд тавигдсан эсэх, амжилтгүй дуудлага болон дата холболтын нарийн статус болон дата холболтын алдааг тодорхойлох боломж олгоно."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Эзэмшигчид үүрэн компанийн нийлүүлсэн тохируулах апп-г өдөөх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Сүлжээний байдлын талаар ажиглалтуудыг хүлээн авах"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Аппликешнд сүлжээний байдлын талаар ажиглалтуудыг хүлээн авахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"оролтын төхөөрөмжийн калибрешныг өөрчлөх"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Мэдрэгчтэй дэлгэцний калибрешн параметрийг өөрчлөхийг апп-д зөвшөөрнө. Энгийн апп-д шаардлагагүй."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
@@ -783,7 +800,7 @@
     <string name="imProtocolYahoo" msgid="8271439408469021273">"Yahoo"</string>
     <string name="imProtocolSkype" msgid="9019296744622832951">"Skype"</string>
     <string name="imProtocolQq" msgid="8887484379494111884">"QQ"</string>
-    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Цугларалт"</string>
+    <string name="imProtocolGoogleTalk" msgid="493902321140277304">"Hangouts"</string>
     <string name="imProtocolIcq" msgid="1574870433606517315">"ICQ"</string>
     <string name="imProtocolJabber" msgid="2279917630875771722">"Jabber"</string>
     <string name="imProtocolNetMeeting" msgid="8287625655986827971">"NetMeeting"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Гэрийн"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Ажлын"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Бусад"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Энэ харилцагчийг харах аппликешн олдсонгүй."</string>
     <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>
@@ -947,7 +965,7 @@
     <string name="permlab_setAlarm" msgid="1379294556362091814">"сэрүүлэг тохируулах"</string>
     <string name="permdesc_setAlarm" msgid="316392039157473848">"Апп нь суулгагдсан сэрүүлэгний апп дээр сэрүүлэг тохируулах боломжтой. Зарим сэрүүлэгний апп нь энэ функцийг дэмжихгүй байж болзошгүй."</string>
     <string name="permlab_addVoicemail" msgid="5525660026090959044">"дуут шуудан нэмэх"</string>
-    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Апп нь таны дуут шуудангийн ирсэн мэйлд мессеж нэмэх боломжтой."</string>
+    <string name="permdesc_addVoicemail" msgid="6604508651428252437">"Таны дуут шуудангийн ирсэн мэйлд зурвас нэмэхийг апп-д зөвшөөрөх."</string>
     <string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"Хөтчийн геобайршлын зөвшөөрлийг өөрчлөх"</string>
     <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Апп нь Хөтчийн гео байршлын зөвшөөрлийг өөрчлөх боломжтой. Хортой апп нь энийг ашиглан дурын веб хуудасруу байршлын мэдээллийг илгээх боломжтой."</string>
     <string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"багцийг тулгах"</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Шинэчлэлт болон сэргээх системтэй харилцах"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Аппликешнд сэргээх систем болон системийн шинэчлэлтэй харилцах боломж олгоно."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Шифт"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Оруулах"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Апп сонгох"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g>-г эхлүүлж чадсангүй"</string>
     <string name="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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Төхөөрөмжтэй холбох"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Дэлгэцийг төхөөрөмж рүү дамжуулах"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Төхөөрөмжүүдийг хайж байна…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Тохиргоо"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Салгах"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Скан хийж байна..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Холбогдож байна..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Боломжтой"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Дэлгэцийг дамжуулж байна"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"<xliff:g id="NAME">%1$s</xliff:g> руу холбогдож байна"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Дэлгэцийг дамжуулж байна"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"<xliff:g id="NAME">%1$s</xliff:g> руу холбогдсон"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Бүтэн дэлгэцээс гарахын тулд дээрээс нь эхлэн доош шудрана уу."</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Бүтэн дэлгэцээс гарахын тулд дээрээс нь доош шудрана уу."</string>
+    <string name="done_label" msgid="2093726099505892398">"Дууссан"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Цаг гүйлгэгч"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Минут гүйлгэгч"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Цаг сонгоно уу"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Минут сонгоно уу"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Өдрүүдийг сараар"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Жилийн жагсаалт"</string>
+    <string name="select_day" msgid="7774759604701773332">"Сар болон өдрийг сонгоно уу"</string>
+    <string name="select_year" msgid="7952052866994196170">"Жилийг сонгоно уу"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> сонгогдсон"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> устсан"</string>
 </resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 88d76e7..c1b7cdb 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Tidak berjaya, dayakan Kunci SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Anda mempunyai <xliff:g id="NUMBER">%d</xliff:g> percubaan lagi sebelum SIM dikunci."</item>
+    <item quantity="other" msgid="7530597808358774740">"Anda mempunyai <xliff:g id="NUMBER">%d</xliff:g> percubaan lagi sebelum SIM dikunci."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID Pemanggil Masuk"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"nyahpasang pintasan"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Membenarkan aplikasi mengalih keluar pintasan Skrin Laman Utama tanpa campur tangan pengguna."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Membenarkan apl melihat nombor yang didail semasa panggilan keluar dengan pilihan untuk mengubah hala panggilan ke nombor lain atau membatalkan terus panggilan."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"terikat kepada paparan jauh"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Membenarkan pemegang terikat dengan antara muka peringkat tertinggi bagi paparan jauh. 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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"jalankan aplikasi pada masa melahu"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Kebenaran ini membolehkan sistem Android menjalankan aplikasi di latar belakang semasa peranti tidak digunakan."</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>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <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_sim_communication" msgid="1180265879464893029">"komunikasi sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Membenarkan apl menghantar arahan kepada SIM. Ini amat berbahaya."</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>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"baca keadaan telefon yang tepat"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Membenarkan apl mengakses keadaan telefon yang tepat. Kebenaran ini membolehkan apl menentukan status panggilan sebenar, sama ada panggilan aktif atau di latar belakang, kegagalan panggilan, status sambungan data yang tepat dan kegagalan sambungan data."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"tukar penentukuran peranti input"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Membenarkan apl mengubah suai parameter penentukuran skrin sentuh. Ini 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Rumah"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Kerja"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Lain-lain"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Tiada aplikasi ditemui untuk melihat kenalan ini."</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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Berinteraksi dengan kemas kini dan sistem pemulihan"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Membenarkan aplikasi berinteraksi dengan sistem pemulihan dan kemas kini sistem."</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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"Tidak dapat melancarkan <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Sambung ke peranti"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Hantar skrin ke peranti"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Mencari peranti..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Tetapan"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Putuskan sambungan"</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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Menghantar skrin"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Menyambung ke <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Menghantar skrin"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Disambungkan ke <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Kod PUK mestilah 8 nombor."</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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Leret ke bawah untuk keluar dari skrin penuh"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Leret ke bawah dari atas untuk keluar dari skrin penuh."</string>
+    <string name="done_label" msgid="2093726099505892398">"Selesai"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Penggelangsar bulatan jam"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Penggelangsar bulatan minit"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pilih jam"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pilih minit"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grid hari bulanan"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Senarai tahun"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pilih bulan dan hari"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pilih tahun"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dipadamkan"</string>
 </resources>
diff --git a/core/res/res/values-ms/donottranslate-cldr.xml b/core/res/res/values-ms/donottranslate-cldr.xml
deleted file mode 100755
index 7da5a72..0000000
--- a/core/res/res/values-ms/donottranslate-cldr.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="numeric_date_template">"%s/%s/%s"</string>
-    <string name="month_day_year">%d %B %Y</string>
-    <string name="time_of_day">%-l:%M:%S %p</string>
-    <string name="date_and_time">%-l:%M:%S %p %d %b %Y</string>
-    <string name="date_time">%2$s %1$s</string>
-</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
deleted file mode 100644
index a9fe930..0000000
--- a/core/res/res/values-ms/strings.xml
+++ /dev/null
@@ -1,1587 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under 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="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_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>
-    <!-- no translation found for permlab_bindNfcService (2752731300419410724) -->
-    <skip />
-    <!-- no translation found for permdesc_bindNfcService (6120647629174066862) -->
-    <skip />
-    <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_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_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>
-    <!-- no translation found for permlab_captureAudioOutput (6857134498402346708) -->
-    <skip />
-    <!-- no translation found for permdesc_captureAudioOutput (6210597754212208853) -->
-    <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">"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>
-    <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="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="status_bar_device_locked" msgid="3092703448690669768">"Peranti dikunci."</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>
-    <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
-    <skip />
-    <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="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>
-</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 3be8817..c1cd604 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Skriv inn en PUK-kode på åtte tall eller mer."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-kortet ditt er PUK-låst. Skriv inn PUK-koden for å låse det opp."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Skriv inn PUK2 for å låse opp SIM-kortet."</string>
+    <string name="enablePin" msgid="209412020907207950">"Mislyktes – aktiver lås for SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Du har <xliff:g id="NUMBER">%d</xliff:g> forsøk igjen før SIM-kortet låses."</item>
+    <item quantity="other" msgid="7530597808358774740">"Du har <xliff:g id="NUMBER">%d</xliff:g> forsøk igjen før SIM-kortet låses."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Inngående nummervisning"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"avinstallere snarveier"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Lar appen fjerne snarveier på startsiden uten å involvere brukeren."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Lar appen se nummeret det ringes til under en utgående samtale, med mulighet for å omdirigere anropet til et annet nummer eller avbryte samtalen fullstendig."</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">"motta tekstmeldinger (MMS)"</string>
@@ -377,6 +382,8 @@
     <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">"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_bindRemoteDisplay" msgid="1782923938029941960">"binde til ekstern skjerm"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Lar innehaveren binde seg til det øverste grensesnittnivået for ekstern skjerm. Skal aldri være nødvendig for vanlige apper."</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">"kommunisere med enhetsadministrator"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"kjør appen når den ikke er i bruk"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Denne tillatelsen gjør at Android-systemet kan kjøre appen i bakgrunnen mens enheten ikke er i bruk."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Lar appen bruke grunnleggende SurfaceFlinger-funksjoner."</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_accessInputFlinger" msgid="5348635270689553857">"tilgang til InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Lar appen bruke grunnleggende InputFlinger-funksjoner."</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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Lar appen ta opp lyd med mikrofonen. Dette betyr at appen kan ta opp lyd når som helst uten at du har bedt om det."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"sim-kommunikasjon"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Lar appen sende kommandoer til SIM-kortet. Dette er veldig farlig."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ta bilder og videoer"</string>
     <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>
@@ -550,6 +563,8 @@
     <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">"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_readPrecisePhoneState" msgid="5476483020282007597">"lese nøyaktige telefontilstander"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Gir appen tilgang til nøyaktige telefontilstander. Denne tillatelsen gjør at appen kan fastslå den faktiske anropstatusen, om et anrop er aktivt eller i bakgrunnen, anropsfeil, nøyaktig status for datatilkobling og datatilkoblingsfeil."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"endre kalibreringen av inndataenheter"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lar appen endre kalibrasjonsparametrene for berøringsskjermen. Denne tillatelsen bør aldri 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Hjem"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbeid"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Annen"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Du har ingen apper som kan åpne denne kontakten."</string>
     <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>
@@ -865,7 +883,7 @@
     <string name="lockscreen_forgot_pattern_button_text" msgid="2626999449610695930">"Glemt mønsteret?"</string>
     <string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"Opplåsing av konto"</string>
     <string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"For mange forsøk på tegning av mønster"</string>
-    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Logg deg på med Google-kontoen din for å låse opp."</string>
+    <string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"Logg på med Google-kontoen din for å låse opp."</string>
     <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"Brukernavn (e-post)"</string>
     <string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"Passord"</string>
     <string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"Logg på"</string>
@@ -1182,7 +1200,7 @@
     <item quantity="other" msgid="7915895323644292768">"Åpne trådløsnett i nærheten"</item>
   </plurals>
     <string name="wifi_available_sign_in" msgid="4029489716605255386">"Pålogging til Wi-Fi-nettverk"</string>
-    <string name="network_available_sign_in" msgid="8495155593358054676">"Logg deg på nettverket"</string>
+    <string name="network_available_sign_in" msgid="8495155593358054676">"Logg på nettverket"</string>
     <!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
     <skip />
     <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan ikke koble til Wi-Fi"</string>
@@ -1218,7 +1236,7 @@
     <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Aldri tillat"</string>
     <string name="sim_removed_title" msgid="6227712319223226185">"SIM-kort er fjernet"</string>
     <string name="sim_removed_message" msgid="2333164559970958645">"Det mobile nettverket forblir utilgjengelig inntil du starter på nytt med et gyldig SIM-kort."</string>
-    <string name="sim_done_button" msgid="827949989369963775">"Fullført"</string>
+    <string name="sim_done_button" msgid="827949989369963775">"Ferdig"</string>
     <string name="sim_added_title" msgid="3719670512889674693">"SIM-kort er lagt til"</string>
     <string name="sim_added_message" msgid="6599945301141050216">"Start enheten på nytt for å få tilgang til det mobile nettverket."</string>
     <string name="sim_restart_button" msgid="4722407842815232347">"Start på nytt"</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Samhandling med oppdateringer og gjenopprettingssystem"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Tillater en app å samhandle med gjenopprettingsssystemet og systemoppdateringer."</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>
@@ -1414,18 +1434,10 @@
     <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">"Velg en app"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Kunne ikke starte <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Del med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Del med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Glidebryter. Trykk og hold inne."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Sveip for å låse opp."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Koble til hodetelefoner for å høre opplesing av bokstavene i passordet."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punktum."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Trådløs skjerm"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fullført"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Medieutgang"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Koble til enheten"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Cast skjermen til enheten"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Søker etter enheter …"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Innstillinger"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Koble fra"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Skanner ..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Kobler til ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Tilgjengelig"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Sender skjermen …"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Kobler til <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Sender skjermen …"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Koblet til <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Koble fra"</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>
@@ -1514,11 +1532,11 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK-koden skal være på åtte sifre."</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_instructions" msgid="1100551261265506448">"Logg 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Prøv på nytt senere"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Sveip ned fra toppen av skjermen for å gå ut av fullskjermvisningen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Ferdig"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Sirkulær glidebryter for timer"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Sirkulær glidebryter for minutter"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Angi timer"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Angi minutter"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Månedsrutenett med dager"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Årsliste"</string>
+    <string name="select_day" msgid="7774759604701773332">"Velg måneden og dagen"</string>
+    <string name="select_year" msgid="7952052866994196170">"Velg året"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> er valgt"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</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..8626897b
--- /dev/null
+++ b/core/res/res/values-ne-rNP/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">"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_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_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="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 30afea7..673df4e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Typ een PUK-code die 8 cijfers of langer is."</string>
     <string name="needPuk" msgid="919668385956251611">"Uw SIM-kaart is vergrendeld met de PUK-code. Typ de PUK-code om te ontgrendelen."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Voer de PUK2-code in om de SIM-kaart te ontgrendelen."</string>
+    <string name="enablePin" msgid="209412020907207950">"Mislukt. Schakel SIM/RUIM-vergrendeling in."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"U heeft nog <xliff:g id="NUMBER">%d</xliff:g> poging over voordat de simkaart wordt vergrendeld."</item>
+    <item quantity="other" msgid="7530597808358774740">"U heeft nog <xliff:g id="NUMBER">%d</xliff:g> pogingen over voordat de simkaart wordt vergrendeld."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Inkomende beller-id"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"snelkoppelingen verwijderen"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"De app toestaan snelkoppelingen van het startscherm te verwijderen zonder tussenkomst van de gebruiker."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"uitgaande oproepen doorschakelen"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Hiermee kan de app uitgaande oproepen verwerken en het nummer wijzigen dat wordt gebeld. De app kan uitgaande oproepen bijhouden, omleiden of blokkeren."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"De app toestaan het nummer te bekijken dat wordt gekozen voor een uitgaande oproep, met de mogelijkheid de oproep om te leiden naar een ander nummer of de oproep helemaal af te breken."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"tekstberichten (SMS) ontvangen"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Hiermee kan de app sms-berichten ontvangen en verwerken. Dit betekent dat de app berichten die naar uw apparaat zijn verzonden, kan bijhouden of verwijderen zonder deze aan u weer te geven."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"tekstberichten (MMS) ontvangen"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Staat de houder toe verbinding te maken met de hoofdinterface van een VPN-service. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"verbinden met een achtergrond"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Hiermee wordt de houder toegestaan zich te verbinden met de hoofdinterface van een achtergrond. Nooit vereist voor normale apps."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"verbinding maken met een extern display"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Hiermee wordt de houder toegestaan verbinding te maken met de hoofdinterface van een extern display. Nooit vereist voor normale apps."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"verbinden met een widgetservice"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"app uitvoeren tijdens inactiviteit"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Met dit recht kan het Android-systeem de app op de achtergrond uitvoeren terwijl het apparaat niet wordt gebruikt."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Hiermee kan de app SurfaceFlinger-functies op laag niveau gebruiken."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"framebuffer lezen"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Hiermee kan de app de inhoud van de framebuffer lezen."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"toegang krijgen tot InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Hiermee kan de app InputFlinger-functies op laag niveau gebruiken."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"wifi-displays configureren"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Hiermee kan de app audio opnemen met de microfoon. Met deze toestemming kan de app op elk moment audio opnemen, zonder om uw bevestiging te vragen."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"sim-communicatie"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Hiermee kan de app opdrachten verzenden naar de simkaart. Dit is erg gevaarlijk."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"foto\'s en video\'s maken"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Hiermee kan de app foto\'s en video\'s maken met de camera. Met deze toestemming kan de app de camera altijd gebruiken, zonder uw bevestiging."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"indicatielampje uitschakelen wanneer camera wordt gebruikt"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Hiermee kan de app de telefoonfuncties van het apparaat beheren. Een app met deze toestemming kan schakelen tussen netwerken, kan de radio van de telefoon in- en uitschakelen en dergelijke acties uitvoeren zonder dat u hiervan op de hoogte wordt gesteld."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefoonstatus en -identiteit lezen"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Hiermee kan de app toegang krijgen tot de telefoonfuncties van het apparaat, Met deze toestemming kan de app het telefoonnummer en de apparaat-ID\'s bepalen, of een oproep actief is, en het andere telefoonnummer waarmee wordt gebeld."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"exacte telefoonstatus lezen"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Toestaan dat de app toegang krijgt tot de exacte telefoonstatus. Hiermee kan de app bepalen wat de echte oproepstatus is, of een oproep actief is of zich op de achtergrond bevindt, of er mislukte oproepen zijn, wat de exacte status van de gegevensverbinding is en of er mislukte gegevensverbindingen zijn."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"voorkomen dat tablet overschakelt naar slaapmodus"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"kalibratie van invoerapparaat wijzigen"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Hiermee kan de app de kalibratieparameters van het aanraakscherm aanpassen. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Startpagina"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Werk"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Overig"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Er is geen app gevonden om dit contact te bekijken."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interactie met update- en herstelsysteem"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Hiermee kan een app interactie hebben met het herstelsysteem en systeemupdates."</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>
@@ -1414,18 +1434,10 @@
     <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">"Een app selecteren"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Kan <xliff:g id="APPLICATION_NAME">%s</xliff:g> niet starten"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delen met"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delen met <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Schuifgreep. Tikken en blijven aanraken."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Vegen om te ontgrendelen"</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Sluit een headset aan om wachtwoordtoetsen te laten voorlezen."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Stip."</string>
@@ -1482,9 +1494,13 @@
     <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Systeem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-audio"</string>
-    <string name="wireless_display_route_description" msgid="9070346425023979651">"Draadloze display"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gereed"</string>
+    <string name="wireless_display_route_description" msgid="9070346425023979651">"Draadloze weergave"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Media-uitvoer"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Verbinding maken met apparaat"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Scherm casten naar apparaat"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Zoeken naar apparaten…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Instellingen"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Verbinding verbreken"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Scannen..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Verbinden..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Beschikbaar"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Scherm sturen"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Verbinden met <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Scherm sturen"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Verbonden met <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Verbinding verbreken"</string>
     <string name="kg_emergency_call_label" msgid="684946192523830531">"Noodoproep"</string>
     <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Patroon vergeten"</string>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"De PUK-code is acht cijfers 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Probeer het later opnieuw"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Veeg omlaag vanaf de bovenkant om het volledige scherm te sluiten."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gereed"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Ronde schuifregelaar voor uren"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Ronde schuifregelaar voor minuten"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Uren selecteren"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Minuten selecteren"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Maandraster van dagen"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Jaarlijst"</string>
+    <string name="select_day" msgid="7774759604701773332">"Maand en dag selecteren"</string>
+    <string name="select_year" msgid="7952052866994196170">"Jaar selecteren"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> geselecteerd"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> verwijderd"</string>
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 0e1bee9..e9d701a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Wpisz kod PUK składający się z co najmniej 8 cyfr."</string>
     <string name="needPuk" msgid="919668385956251611">"Karta SIM jest zablokowana kodem PUK. Wprowadź kod PUK, aby odblokować kartę."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Wprowadź kod PUK2, aby odblokować kartę SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Nie udało się. Włącz blokadę karty SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Masz jeszcze <xliff:g id="NUMBER">%d</xliff:g> próbę, zanim karta SIM zostanie zablokowana."</item>
+    <item quantity="other" msgid="7530597808358774740">"Masz jeszcze <xliff:g id="NUMBER">%d</xliff:g> prób(y), zanim karta SIM zostanie zablokowana."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Nazwa rozmówcy przy połączeniach przychodzących"</string>
@@ -251,15 +256,15 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"odinstalowywanie skrótów"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Pozwala aplikacji usuwać skróty z ekranu głównego bez interwencji użytkownika."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"przekierowywanie połączeń wychodzących"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Pozwala aplikacji na przetwarzanie połączeń wychodzących i zmianę wybieranego numeru. Aplikacje z tym uprawnieniem mogą monitorować, przekierowywać lub blokować połączenia wychodzące."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Pozwala aplikacji na sprawdzenie numeru wybieranego w trakcie połączenia wychodzącego, a także umożliwia przerwanie połączenia lub przekierowanie go pod inny numer."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"odbieranie wiadomości tekstowych (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Pozwala aplikacji na odbieranie i przetwarzanie SMS-ów. To oznacza, że aplikacja będzie mogła bez Twojej wiedzy monitorować i usuwać wiadomości wysyłane do Twojego urządzenia."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"odbieranie wiadomości tekstowych (MMS)"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"Pozwala aplikacji na odbieranie i przetwarzanie MMS-ów. To oznacza, że aplikacja będzie mogła bez Twojej wiedzy monitorować i usuwać wiadomości wysyłane do Twojego urządzenia."</string>
     <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"odbiór emisji alarmowych"</string>
     <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Pozwala aplikacji na odbieranie i przetwarzanie komunikatów transmisji alarmowych. To pozwolenie jest dostępne tylko dla aplikacji systemowych."</string>
-    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"odczyt wiadomości z sieci komórkowej"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Zezwala aplikacji na odczyt wiadomości z sieci komórkowej odebranych na urządzeniu. Alerty sieci komórkowej są dostarczane w niektórych lokalizacjach w celu ostrzeżenia Cię o sytuacjach alarmowych. Złośliwe aplikacje mogą wpływać na wydajność lub zakłócać działanie urządzenia po odebraniu wiadomości alarmowej z sieci komórkowej."</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"odczyt komunikatów z sieci komórkowej"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Zezwala aplikacji na odczyt komunikatów z sieci komórkowej odebranych na urządzeniu. Komunikaty alarmowe z sieci komórkowej są dostarczane w niektórych lokalizacjach w celu ostrzeżenia Cię o sytuacjach zagrożenia. Złośliwe aplikacje mogą wpływać na wydajność lub zakłócać działanie urządzenia po odebraniu komunikatu alarmowego z sieci komórkowej."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"wysyłanie wiadomości SMS"</string>
     <string name="permdesc_sendSms" msgid="7094729298204937667">"Pozwala aplikacji na wysyłanie SMS-ów. Może to skutkować nieoczekiwanymi opłatami. Złośliwe aplikacje mogą generować koszty, wysyłając wiadomości bez Twojego potwierdzenia."</string>
     <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"wysyłanie zdarzeń odpowiedzi przez SMS"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Pozwala na tworzenie powiązania z interfejsem najwyższego poziomu usługi VPN. Nie powinno być nigdy potrzebne w przypadku zwykłych aplikacji."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"powiązanie z tapetą"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Pozwala na tworzenie powiązania z interfejsem najwyższego poziomu tapety. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"powiązanie z wyświetlaczem zdalnym"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Zezwala na tworzenie powiązania z interfejsem najwyższego poziomu wyświetlacza zdalnego. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"powiązanie z usługą widżetów"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"uruchom aplikację w czasie bezczynności"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To uprawnienie pozwala systemowi Android uruchomić aplikację w tle, gdy urządzenie nie jest używane."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Pozwala aplikacji na wykorzystanie funkcji niskiego poziomu usługi SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"czytanie bufora ramki"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Pozwala aplikacji na odczyt zawartości bufora ramki."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"dostęp do InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Zezwala aplikacji na wykorzystanie niskopoziomowych funkcji usługi InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurowanie wyświetlaczy Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Pozwala aplikacji na nagrywanie dźwięku przez mikrofon. Aplikacja z tym uprawnieniem może nagrywać dźwięk w dowolnym momencie bez Twojego potwierdzenia."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"komunikacja z kartą SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Pozwala aplikacji na wysyłanie poleceń do karty SIM. To bardzo niebezpieczne."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"wykonywanie zdjęć i filmów wideo"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Pozwala aplikacji na robienie zdjęć i nagrywanie filmów przy użyciu aparatu. Aplikacja z tym uprawnieniem może użyć aparatu w dowolnym momencie bez Twojego potwierdzenia."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"wyłącz wskaźnik LED transmisji, gdy aparat jest w użyciu"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Pozwala aplikacji na kontrolowanie funkcji telefonu w urządzeniu. Aplikacja z tymi uprawnieniami może zmieniać, włączać i wyłączać sieci bezprzewodowe itp. bez informowania użytkownika."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"odczytywanie stanu i informacji o telefonie"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Pozwala aplikacji na dostęp do funkcji telefonicznych urządzenia. Aplikacja z tym uprawnieniem może odczytać numer telefonu i identyfikator urządzenia, sprawdzić, czy połączenie jest aktywne, oraz poznać numer, z którym jest nawiązane połączenie."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"dokładne rozpoznawanie stanów telefonu"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Pozwala aplikacji dokładnie rozpoznawać stany telefonu. Aplikacja z tym uprawnieniem może określić rzeczywisty stan połączenia, ustalić, czy jest ono aktywne czy znajduje się w tle, odczytać informacje o nieudanych połączeniach, precyzyjnie określić stan połączenia transmisji danych oraz odczytać informacje o błędach transmisji danych."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zapobieganie przechodzeniu tabletu do trybu uśpienia"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"zmiana kalibracji urządzenia wejściwego"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Zezwala aplikacji na modyfikowanie parametrów kalibracji ekranu dotykowego. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Domowy"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Służbowy"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Inny"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Brak aplikacji do wyświetlenia tego kontaktu."</string>
     <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>
@@ -1204,7 +1222,7 @@
     <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"Na czas połączenia z <xliff:g id="DEVICE_NAME">%1$s</xliff:g> telefon zostanie tymczasowo odłączony od Wi-Fi"</string>
     <string name="select_character" msgid="3365550120617701745">"Wstaw znak"</string>
     <string name="sms_control_title" msgid="7296612781128917719">"Wysyłanie wiadomości SMS"</string>
-    <string name="sms_control_message" msgid="3867899169651496433">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wysyła wiele SMS-ów. Chcesz pozwolić tej aplikacji dalej wysyłać SMS-y?"</string>
+    <string name="sms_control_message" msgid="3867899169651496433">"Aplikacja &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wysyła wiele SMS-ów. Chcesz pozwolić tej aplikacji dalej wysyłać SMS-y?"</string>
     <string name="sms_control_yes" msgid="3663725993855816807">"Pozwól"</string>
     <string name="sms_control_no" msgid="625438561395534982">"Odmów"</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; chce wysłać wiadomość do &lt;b&gt;<xliff:g id="DEST_ADDRESS">%2$s</xliff:g>&lt;/b&gt;."</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interakcja z systemem odzyskiwania i aktualizacjami"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Zezwala aplikacji na interakcję z systemem odzyskiwania i aktualizacjami systemu."</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>
@@ -1349,9 +1369,9 @@
     <string name="next_button_label" msgid="1080555104677992408">"Dalej"</string>
     <string name="skip_button_label" msgid="1275362299471631819">"Pomiń"</string>
     <string name="throttle_warning_notification_title" msgid="4890894267454867276">"Wysoki poziom użycia danych"</string>
-    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Dotknij, aby uzyskać więcej informacji na temat używania danych komórkowych."</string>
+    <string name="throttle_warning_notification_message" msgid="3340822228599337743">"Dotknij, aby uzyskać więcej informacji na temat używania danych mobilnych."</string>
     <string name="throttled_notification_title" msgid="6269541897729781332">"Przekroczono limit danych"</string>
-    <string name="throttled_notification_message" msgid="5443457321354907181">"Dotknij, aby uzyskać więcej informacji na temat używania danych komórkowych."</string>
+    <string name="throttled_notification_message" msgid="5443457321354907181">"Dotknij, aby uzyskać więcej informacji na temat używania danych mobilnych."</string>
     <string name="no_matches" msgid="8129421908915840737">"Brak wyników"</string>
     <string name="find_on_page" msgid="1946799233822820384">"Znajdź na stronie"</string>
   <plurals name="matches_found">
@@ -1414,18 +1434,10 @@
     <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">"Wybierz aplikację"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nie udało się uruchomić aplikacji <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Udostępnij przez"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Udostępnij przez <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Uchwyt przesuwny. Dotknij i przytrzymaj."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Przesuń, aby odblokować."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Podłącz zestaw słuchawkowy, aby wysłuchać znaków hasła wypowiadanych na głos."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Kropka"</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Dźwięk Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Wyświetlacz bezprzewodowy"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotowe"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Wyjście multimediów"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Połącz z urządzeniem"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Prezentuj ekran na urządzeniu"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Szukam urządzeń…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Ustawienia"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Rozłącz"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Skanuję..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Łączę..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Dostępne"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Rozpoczynam prezentowanie ekranu"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Łączę z <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Trwa prezentowanie ekranu"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Połączono z <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Rozłącz"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK musi mieć 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Spróbuj ponownie później"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Przesuń z góry w dół, by zamknąć pełny ekran."</string>
+    <string name="done_label" msgid="2093726099505892398">"Gotowe"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kołowy suwak godzin"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kołowy suwak minut"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Wybierz godziny"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Wybierz minuty"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Siatka miesięczna z dniami"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista lat"</string>
+    <string name="select_day" msgid="7774759604701773332">"Wybierz miesiąc i dzień"</string>
+    <string name="select_year" msgid="7952052866994196170">"Wybierz rok"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Wybrałeś <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> usunięte"</string>
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index f3c4020..cf38b47 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Introduza um PUK que tenha 8 ou mais algarismos."</string>
     <string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado com PUK. Introduza o código PUK para desbloqueá-lo."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Introduza o PUK2 para desbloquear o cartão SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Ação sem êxito. Ative o bloqueio do SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Tem mais <xliff:g id="NUMBER">%d</xliff:g> tentativa antes de o cartão SIM ficar bloqueado."</item>
+    <item quantity="other" msgid="7530597808358774740">"Tem mais <xliff:g id="NUMBER">%d</xliff:g> tentativas antes de o cartão SIM ficar bloqueado."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID do Autor da Chamada"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstalar atalhos"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite que a aplicação remova atalhos do Ecrã principal sem a intervenção do utilizador."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecionar as chamadas efetuadas"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Permite que a aplicação processe chamadas efetuadas e mude o número a marcar. Esta autorização permite que a aplicação monitorize, redirecione ou impeça a realização de chamadas."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite que a aplicação veja o número que é marcado durante uma chamada efetuada, com a opção de redirecionar a chamada para um número diferente ou terminar a chamada."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"receber mensagens de texto (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que a aplicação receba e processe mensagens SMS. Isto significa que a aplicação poderá monitorizar ou eliminar mensagens enviadas para o seu dispositivo sem as apresentar."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"receber mensagens de texto (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permite que o titular se vincule à interface de nível superior de um serviço de VPN. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"vincular a uma imagem de fundo"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permite ao titular vincular-se à interface de nível superior de uma imagem de fundo. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"associar a um ecrã remoto"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite ao detentor associar a interface de nível superior a um ecrã remoto. Nunca deve ser necessário para aplicações normais."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"vincular a um serviço de widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"executar aplicação durante o tempo de inatividade"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Esta autorização permite ao sistema Android executar a aplicação em segundo plano enquanto o dispositivo não estiver a ser utilizado."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite à aplicação utilizar funcionalidades de SurfaceFlinger de nível inferior."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ler memória intermédia de fotogramas"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite à aplicação ler o conteúdo da memória intermédia de fotogramas."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"aceder a InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que a aplicação utilize funcionalidades de InputFlinger de nível inferior."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar visores Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Permite que a aplicação modifique definições de áudio globais, tais como o volume e qual o altifalante utilizado para a saída de som."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"gravar áudio"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permite que a aplicação grave áudio com o microfone. Esta autorização permite que a aplicação grave áudio em qualquer altura sem a confirmação do utilizador."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"comunicação com o SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite que a aplicação envie comandos para o SIM. Esta ação é muito perigosa."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"tirar fotografias e vídeos"</string>
     <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>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que a aplicação controle as funcionalidades de telefone do aparelho. Uma aplicação com esta permissão pode alternar entre redes, ligar/desligar o rádio do telefone e outras coisas semelhantes sem sequer o notificar."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ler o estado e a identidade do telemóvel"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que a aplicação aceda às funcionalidades de telefone do dispositivo. Esta autorização permite que a aplicação determine o número de telefone e IDs do dispositivo, se alguma chamada está ativa e qual o número remoto ligado por uma chamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ler os estados precisos do telemóvel"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que a aplicação aceda ao estados precisos do telemóvel. Esta autorização permite que a aplicação determine o estado real da chamada, se uma chamada está ativa ou em segundo plano, falhas em chamadas, o estado preciso da ligação de dados e falhas de ligação de dados."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir que o tablet entre em inactividade"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"alterar a calibragem de entrada do dispositivo"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite à aplicação modificar os parâmetros de calibragem do ecrã tátil. Esta funcionalidade nunca deverá ser necessária 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Casa"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Emprego"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Outro"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Não foram encontradas aplicações para visualizar este contacto."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interagir com o sistema de recuperação e de atualização"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permite que uma aplicação interaja com o sistema de recuperação e as atualizações do sistema."</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>
@@ -1414,18 +1434,10 @@
     <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">"Escolher uma aplicação"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Não foi possível iniciar <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Partilhar com:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Barra deslizante. Toque &amp; não solte."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Deslizar rapidamente para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Ligue os auscultadores com microfone integrado para ouvir as teclas da palavra-passe."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Visualização sem fios"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Saída de som multimédia"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Ligar ao dispositivo"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Transmitir ecrã para o dispositivo"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"A pesquisar dispositivos…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Definições"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Desligar"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"A procurar..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"A ligar..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponível"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"A transmitir o ecrã"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"A ligar a <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"A transmitir o ecrã"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Ligado a <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desligar"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"O código PUK deve ter 8 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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Tente novamente mais tarde"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Deslize rapidamente para baixo para sair do ecrã inteiro."</string>
+    <string name="done_label" msgid="2093726099505892398">"Concluído"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Controlo de deslize circular das horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Controlo de deslize circular dos minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selecionar horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selecionar minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grelha de dias do mês"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de anos"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selecionar mês e dia"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selecionar ano"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 15a6130..d048d51 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Digite um PUK com oito números ou mais."</string>
     <string name="needPuk" msgid="919668385956251611">"O seu cartão SIM está bloqueado por um PUK. Digite o código PUK para desbloqueá-lo."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Digite o PUK2 para desbloquear o cartão SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Falha. Ative o bloqueio do SIM/R-UIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Tentativas restantes: <xliff:g id="NUMBER">%d</xliff:g>. Caso o código correto não seja digitado, o SIM será bloqueado."</item>
+    <item quantity="other" msgid="7530597808358774740">"Tentativas restantes: <xliff:g id="NUMBER">%d</xliff:g>. Caso o código correto não seja digitado, o SIM será bloqueado."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID do chamador de entrada"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstalar atalhos"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite que o aplicativo remova atalhos da tela inicial sem a intervenção do usuário."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecionar as chamadas efetuadas"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Permite que o aplicativo processe as chamadas de saída e altere o número a ser discado. Esta permissão autoriza o aplicativo a monitorar, redirecionar ou evitar chamadas de saída."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite que o aplicativo veja o número discado ao realizar uma chamada, com a opção de redirecionar a chamada para outro número ou abortá-la."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"receber mensagens de texto (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que o aplicativo receba e processe mensagens SMS. Isso significa que o aplicativo pode monitorar ou excluir mensagens enviadas para o dispositivo sem mostrá-las para você."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"receber mensagens de texto (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permite que seu proprietário sujeite a interface de alto nível de um serviço de VPN. Nunca deve ser necessário para aplicativos normais."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"sujeitar-se a um plano de fundo"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permite que o proprietário utilize interface de nível superior de um plano de fundo. Nunca deve ser necessário para aplicativos normais."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"usar uma tela remota"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite que o proprietário use a interface de nível superior de uma tela remota. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"sujeitar-se a um serviço de widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"executar o aplicativo durante o tempo ocioso"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Permite que o sistema Android execute o aplicativo em segundo plano enquanto o dispositivo não está em uso."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite que o aplicativo use recursos com baixos níveis de SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"ler o buffer do frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite que o aplicativo leia o conteúdo do buffer de frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acessar InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite que o aplicativo use recursos com baixos níveis de InputFinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurar monitores Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permite que o aplicativo grave áudio com o microfone. Esta permissão autoriza o aplicativo a gravar áudio a qualquer momento, sem sua confirmação."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"comunicação com sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite que o aplicativo envie comandos ao SIM. Muito perigoso."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"tirar fotos e gravar vídeos"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Permite que o aplicativo tire fotos e filme vídeos com a câmera. Esta permissão autoriza o aplicativo a usar a câmera a qualquer momento sem sua confirmação."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"desativar a transmissão do LED indicador quando a câmera estiver em uso"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite que o aplicativo controle os recursos de telefone do dispositivo. Um aplicativo com essa permissão pode alternar entre redes, ligar e desligar o rádio do telefone e assim por diante, sem nunca notificá-lo."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"ler status e identidade do telefone"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite que o aplicativo acesse os recursos de telefonia do dispositivo. Esta permissão autoriza o aplicativo a determinar o número de telefone e IDs de dispositivo, quando uma chamada está ativa, e o número remoto conectado a uma chamada."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"ler estados precisos do telefone"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite que o aplicativo acesse estados precisos do telefone. Permite que o aplicativo determine o status real da chamada, se uma chamada está ativa em segundo plano, falhas em chamadas, o status preciso da conexão de dados e falhas na conexão de dados."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"impedir modo de inatividade do tablet"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"alterar calibragem do dispositivo de entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que o aplicativo modifique os parâmetros de calibragem da tela sensível ao toque. Não deve ser necessário para aplicativos normais."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Página inicial"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Comercial"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Outros"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nenhum aplicativo encontrado para visualizar este contato."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interagir com o sistema de atualizações e recuperação"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permite que um aplicativo interaja com o sistema de recuperação e as atualizações do sistema."</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>
@@ -1414,18 +1434,10 @@
     <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">"Selecione um aplicativo"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Não foi possível iniciar o <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Compartilhar com"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Compartilhar com <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Recurso deslizante. Toque e segure."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Deslize para desbloquear."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conecte um fone de ouvido para ouvir as teclas da senha."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Ponto final."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistema"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Display sem fio"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Saída de mídia"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Conectar ao dispositivo"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Transmitir tela para dispositivo"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Procurando dispositivos…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Configurações"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Desconectar"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Verificando..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Conectando..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponível"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Transmitindo a tela"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Conectando a <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Transmitindo a tela"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Conectado a <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Desconectar"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"O código PUK deve ter oito números."</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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Deslize para baixo para sair da tela inteira"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Deslize de cima para baixo para sair da tela inteira"</string>
+    <string name="done_label" msgid="2093726099505892398">"Concluído"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Controle deslizante circular das horas"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Controle deslizante circular dos minutos"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selecione as horas"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selecione os minutos"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grade mensal de dias"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista de anos"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selecione o mês e o dia"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selecione o ano"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selecionado"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string>
 </resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 9154621..8d007e4 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -57,6 +57,10 @@
     <skip />
     <string name="needPuk" msgid="919668385956251611">"Vossa carta SIM è bloccada cun in PUK. Endatai il PUK per debloccar ella."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Endatai il PUK2 per debloccar la carta SIM."</string>
+    <!-- no translation found for enablePin (209412020907207950) -->
+    <skip />
+    <!-- no translation found for pinpuk_attempts:one (6596245285809790142) -->
+    <!-- no translation found for pinpuk_attempts:other (7530597808358774740) -->
     <!-- no translation found for imei (2625429890869005782) -->
     <skip />
     <!-- no translation found for meid (4841221237681254195) -->
@@ -359,7 +363,7 @@
     <skip />
     <!-- no translation found for permlab_processOutgoingCalls (3906007831192990946) -->
     <skip />
-    <!-- no translation found for permdesc_processOutgoingCalls (5331318931937402040) -->
+    <!-- no translation found for permdesc_processOutgoingCalls (5156385005547315876) -->
     <skip />
     <!-- no translation found for permlab_receiveSms (8673471768947895082) -->
     <skip />
@@ -594,6 +598,10 @@
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"sa fixar vid in fund davos"</string>
     <!-- no translation found for permdesc_bindWallpaper (7108428692595491668) -->
     <skip />
+    <!-- no translation found for permlab_bindRemoteDisplay (1782923938029941960) -->
+    <skip />
+    <!-- no translation found for permdesc_bindRemoteDisplay (1261242718727295981) -->
+    <skip />
     <!-- no translation found for permlab_bindRemoteViews (5697987759897367099) -->
     <skip />
     <!-- no translation found for permdesc_bindRemoteViews (4717987810137692572) -->
@@ -670,6 +678,10 @@
     <skip />
     <!-- no translation found for permdesc_manageCaCertificates (4015644047196937014) -->
     <skip />
+    <!-- no translation found for permlab_bindIdleService (816311765497613780) -->
+    <skip />
+    <!-- no translation found for permdesc_bindIdleService (1767538493214100612) -->
+    <skip />
     <string name="permlab_diagnostic" msgid="8076743953908000342">"leger/scriver en resursas che appartegnan a diagnostics"</string>
     <!-- no translation found for permdesc_diagnostic (6608295692002452283) -->
     <skip />
@@ -783,6 +795,10 @@
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"leger il paraculp da frame"</string>
     <!-- no translation found for permdesc_readFrameBuffer (4937405521809454680) -->
     <skip />
+    <!-- no translation found for permlab_accessInputFlinger (5348635270689553857) -->
+    <skip />
+    <!-- no translation found for permdesc_accessInputFlinger (2104864941201226616) -->
+    <skip />
     <!-- no translation found for permlab_configureWifiDisplay (5595661694746742168) -->
     <skip />
     <!-- no translation found for permdesc_configureWifiDisplay (7916815158690218065) -->
@@ -817,6 +833,10 @@
     <string name="permlab_recordAudio" msgid="3876049771427466323">"registrar audio"</string>
     <!-- no translation found for permdesc_recordAudio (4906839301087980680) -->
     <skip />
+    <!-- no translation found for permlab_sim_communication (1180265879464893029) -->
+    <skip />
+    <!-- no translation found for permdesc_sim_communication (5725159654279639498) -->
+    <skip />
     <string name="permlab_camera" msgid="3616391919559751192">"fotografar e registrar videos"</string>
     <!-- no translation found for permdesc_camera (8497216524735535009) -->
     <skip />
@@ -915,6 +935,10 @@
     <skip />
     <!-- no translation found for permdesc_readPhoneState (1639212771826125528) -->
     <skip />
+    <!-- no translation found for permlab_readPrecisePhoneState (5476483020282007597) -->
+    <skip />
+    <!-- no translation found for permdesc_readPrecisePhoneState (6648009074263855418) -->
+    <skip />
     <!-- no translation found for permlab_wakeLock (1531731435011495015) -->
     <skip />
     <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"evitar ch\'il telefon midia en il modus stand-by"</string>
@@ -1146,6 +1170,10 @@
     <skip />
     <!-- no translation found for permdesc_accessNetworkConditions (6899102075825272211) -->
     <skip />
+    <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+    <skip />
+    <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+    <skip />
     <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
     <skip />
     <!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
@@ -1322,6 +1350,8 @@
     <skip />
     <!-- no translation found for sipAddressTypeOther (4408436162950119849) -->
     <skip />
+    <!-- no translation found for quick_contacts_not_available (746098007828579688) -->
+    <skip />
     <!-- no translation found for keyguard_password_enter_pin_code (3037685796058495017) -->
     <skip />
     <!-- no translation found for keyguard_password_enter_puk_code (4800725266925845333) -->
@@ -2082,6 +2112,10 @@
     <skip />
     <!-- no translation found for permdesc_control_keyguard (3043732290518629061) -->
     <skip />
+    <!-- no translation found for permlab_recovery (3157024487744125846) -->
+    <skip />
+    <!-- no translation found for permdesc_recovery (8511774533266359571) -->
+    <skip />
     <!-- no translation found for tutorial_double_tap_to_zoom_message_short (4070433208160063538) -->
     <skip />
     <!-- no translation found for gadget_host_error_inflating (4882004314906466162) -->
@@ -2267,30 +2301,14 @@
     <skip />
     <!-- no translation found for activitychooserview_choose_application (2125168057199941199) -->
     <skip />
+    <!-- no translation found for activitychooserview_choose_application_error (8624618365481126668) -->
+    <skip />
     <!-- no translation found for shareactionprovider_share_with (806688056141131819) -->
     <skip />
     <!-- no translation found for shareactionprovider_share_with_application (5627411384638389738) -->
     <skip />
     <!-- no translation found for content_description_sliding_handle (415975056159262248) -->
     <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 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_target_unlock_tablet (3833195335629795055) -->
     <skip />
     <!-- no translation found for keyboard_headset_required_to_hear_password (7011927352267668657) -->
@@ -2405,10 +2423,18 @@
     <skip />
     <!-- no translation found for wireless_display_route_description (9070346425023979651) -->
     <skip />
-    <!-- no translation found for media_route_chooser_grouping_done (7966438307723317169) -->
-    <skip />
     <!-- no translation found for media_route_button_content_description (5758553567065145276) -->
     <skip />
+    <!-- no translation found for media_route_chooser_title (1751618554539087622) -->
+    <skip />
+    <!-- no translation found for media_route_chooser_title_for_remote_display (3395541745872017583) -->
+    <skip />
+    <!-- no translation found for media_route_chooser_searching (4776236202610828706) -->
+    <skip />
+    <!-- no translation found for media_route_chooser_extended_settings (87015534236701604) -->
+    <skip />
+    <!-- no translation found for media_route_controller_disconnect (8966120286374158649) -->
+    <skip />
     <!-- no translation found for media_route_status_scanning (7279908761758293783) -->
     <skip />
     <!-- no translation found for media_route_status_connecting (6422571716007825440) -->
@@ -2429,9 +2455,13 @@
     <skip />
     <!-- no translation found for display_manager_overlay_display_secure_suffix (6022119702628572080) -->
     <skip />
-    <!-- no translation found for wifi_display_notification_title (2223050649240326557) -->
+    <!-- no translation found for wifi_display_notification_connecting_title (2838646471050359706) -->
     <skip />
-    <!-- no translation found for wifi_display_notification_message (4498802012464170685) -->
+    <!-- no translation found for wifi_display_notification_connecting_message (5837350993752841389) -->
+    <skip />
+    <!-- no translation found for wifi_display_notification_connected_title (8567308065912676285) -->
+    <skip />
+    <!-- no translation found for wifi_display_notification_connected_message (2587209325701109715) -->
     <skip />
     <!-- no translation found for wifi_display_notification_disconnect (6183754463561153372) -->
     <skip />
@@ -2467,7 +2497,7 @@
     <skip />
     <!-- no translation found for kg_invalid_sim_pin_hint (8795159358110620001) -->
     <skip />
-    <!-- no translation found for kg_invalid_sim_puk_hint (7553388325654369575) -->
+    <!-- no translation found for kg_invalid_sim_puk_hint (6025069204539532000) -->
     <skip />
     <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
     <skip />
@@ -2735,4 +2765,26 @@
     <!-- no translation found for immersive_mode_confirmation (7227416894979047467) -->
     <!-- no translation found for immersive_mode_confirmation (8554991488096662508) -->
     <skip />
+    <!-- no translation found for done_label (2093726099505892398) -->
+    <skip />
+    <!-- no translation found for hour_picker_description (6698199186859736512) -->
+    <skip />
+    <!-- no translation found for minute_picker_description (8606010966873791190) -->
+    <skip />
+    <!-- no translation found for select_hours (6043079511766008245) -->
+    <skip />
+    <!-- no translation found for select_minutes (3974345615920336087) -->
+    <skip />
+    <!-- no translation found for day_picker_description (8990847925961297968) -->
+    <skip />
+    <!-- no translation found for year_picker_description (5524331207436052403) -->
+    <skip />
+    <!-- no translation found for select_day (7774759604701773332) -->
+    <skip />
+    <!-- no translation found for select_year (7952052866994196170) -->
+    <skip />
+    <!-- no translation found for item_is_selected (949687401682476608) -->
+    <skip />
+    <!-- no translation found for deleted_key (7659477886625566590) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index dc5a211..dd9dd9e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Introduceţi un cod PUK care să aibă 8 cifre sau mai mult."</string>
     <string name="needPuk" msgid="919668385956251611">"Cardul SIM este blocat cu codul PUK. Introduceţi codul PUK pentru a-l debloca."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Introduceţi codul PUK2 pentru a debloca cardul SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Operațiunea nu a reușit. Activați blocarea cardului SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"V-a mai rămas <xliff:g id="NUMBER">%d</xliff:g> încercare până la blocarea cardului SIM."</item>
+    <item quantity="other" msgid="7530597808358774740">"V-au mai rămas <xliff:g id="NUMBER">%d</xliff:g> încercări până la blocarea cardului SIM."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID apelant de primire"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"dezinstalează comenzi rapide"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite aplicației să elimine comenzi rapide de pe ecranul de pornire, fără intervenția utilizatorului."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirecţionează apelurile efectuate"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Permite aplicaţiei să proceseze apelurile efectuate şi să schimbe numărul care trebuie format. Cu această permisiune aplicaţia poate monitoriza, redirecţiona sau împiedica apelurile efectuate."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite aplicației să vadă numărul format în timpul unui apel de ieșire, cu opțiunea de a redirecționa apelul către un alt număr sau de a întrerupe apelul."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"primeşte mesaje text (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite aplicaţiei să primească şi să proceseze mesaje SMS. Acest lucru înseamnă că aplicaţia ar putea monitoriza sau şterge mesajele trimise pe dispozitivul dvs. fără a vi le arăta."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"primeşte mesaje text (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unui serviciu VPN. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"conectare la o imagine de fundal"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Permite proprietarului să se conecteze la interfaţa de nivel superior a unei imagini de fundal. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"conectare la un ecran la distanță"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Permite proprietarului să se conecteze la interfața de nivel superior a unui ecran la distanță. Nu ar trebui să fie niciodată necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"conectare la un serviciu widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"rulează aplicația în timp ce dispozitivul este inactiv"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Cu această permisiune, sistemul Android poate rula aplicația în fundal în timp ce dispozitivul nu este utilizat."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Permite aplicaţiei să utilizeze funcţiile de nivel redus SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"citire zonă tampon de cadre"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Permite aplicaţiei să citească conţinutul zonei-tampon a cadrului."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"acces la InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Permite aplicației să utilizeze funcțiile de nivel redus InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"configurează afişaje Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Permite aplicaţiei să efectueze înregistrări audio cu ajutorul microfonului. Cu această permisiune aplicaţia efectuează oricând înregistrări audio fără confirmare."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"comunicare cu cardul SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Permite aplicației să trimită comenzi pe cardul SIM. Această permisiune este foarte periculoasă."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"realizarea de fotografii şi videoclipuri"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Permite aplicaţiei să realizeze fotografii şi videoclipuri cu camera foto. Cu această permisiune aplicaţia utilizează camera foto oricând şi fără confirmare."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"dezactivează ledul care indică când este utilizată camera foto"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Permite aplicaţiei să controleze funcţiile de telefon ale dispozitivului. O aplicaţie cu această permisiune poate să schimbe reţeaua, să închidă şi să deschidă radioul şi să efectueze alte acţiuni similare, fără să vă înştiinţeze."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"citeşte starea şi identitatea telefonului"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Permite aplicaţiei să acceseze funcţiile de telefon ale dispozitivului. Cu această permisiune aplicaţia stabileşte numărul de telefon şi ID-urile de dispozitiv, dacă un apel este activ, precum şi numărul de la distanţă conectat printr-un apel."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"accesați stările exacte ale telefonului"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Permite aplicației să acceseze stările exacte ale telefonului. Cu această permisiune, aplicația poate să determine starea reală a apelului, dacă apelul este activ sau în fundal, dacă apelul eșuează, starea exactă și întreruperile conexiunii de date."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"împiedicarea computerului tablet PC să intre în repaus"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"schimbați calibrarea dispozitivului de intrare"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite aplicației să modifice parametrii de calibrare a ecranului tactil. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Ecran pornire"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Serviciu"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Altul"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nu s-a găsit nicio aplicație pentru a afișa această persoană de contact."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interacțiune cu sistemul de recuperare și de actualizare"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Permite unei aplicații să interacționeze cu sistemul de recuperare și cu actualizările de sistem."</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>
@@ -1414,18 +1434,10 @@
     <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">"Alegeţi o aplicaţie"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Nu s-a putut lansa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Permiteţi accesul pentru"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Permiteţi accesul pentru <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Mâner glisant. Atingeţi şi ţineţi apăsat."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Glisaţi pentru a debloca."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Conectaţi un set căşti-microfon pentru a auzi tastele apăsate când introduceţi parola."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punct."</string>
@@ -1483,8 +1495,12 @@
     <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">"Ecran wireless"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Terminat"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Rezultate media"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Conectați-vă la dispozitiv"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Trimiteți ecranul pe dispozitiv"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Se caută dispozitive..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Setări"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Deconectați-vă"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Se scanează..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Se conectează..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Disponibilă"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Se trimite ecranul"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Se conectează la <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Se trimite ecranul"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Conectat la <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Deconectaţi-vă"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Codul PUK trebuie să conțină 8 numere."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Reîncercați mai târziu"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Glisați în jos pentru a ieși din ecran complet."</string>
+    <string name="done_label" msgid="2093726099505892398">"Terminat"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Selector circular pentru ore"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Selector circular pentru minute"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Selectați orele"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Selectați minutele"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Afișare pe luni"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Listă de ani"</string>
+    <string name="select_day" msgid="7774759604701773332">"Selectați luna și ziua"</string>
+    <string name="select_year" msgid="7952052866994196170">"Selectați anul"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> selectat"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> a fost șters"</string>
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5348084..f518a0c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Введите PUK-код из 8 или более цифр."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM-карта заблокирована с помощью кода PUK. Для разблокировки введите код PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Для разблокировки SIM-карты введите PUK2."</string>
+    <string name="enablePin" msgid="209412020907207950">"Произошла ошибка. Включите блокировку SIM-карты или карты R-UIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Осталось попыток: <xliff:g id="NUMBER">%d</xliff:g>. После этого SIM-карта будет заблокирована."</item>
+    <item quantity="other" msgid="7530597808358774740">"Осталось попыток: <xliff:g id="NUMBER">%d</xliff:g>. После этого SIM-карта будет заблокирована."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Идентификация вызывающего абонента"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"Удаление ярлыков"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Приложение сможет удалять ярлыки с главного экрана без вмешательства пользователя."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"Перенаправление исходящих вызовов"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Приложение сможет обрабатывать исходящие вызовы и изменять набираемые номера, а также отслеживать, перенаправлять или блокировать исходящие вызовы."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Приложение сможет видеть набранный номер во время исходящего вызова и при необходимости перенаправлять вызов или завершать его."</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>
@@ -274,9 +279,9 @@
     <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="permlab_interactAcrossUsers" msgid="7114255281944211682">"Взаимодействие с аккаунтами всех пользователей"</string>
     <string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Приложение сможет выполнять действия во всех аккаунтах на этом устройстве. При этом защита от вредоносных приложений может быть недостаточной."</string>
-    <string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"Полное взаимодействие со всеми аккаунтами"</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"Подключение к удаленному дисплею"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Приложение сможет подключаться к базовому интерфейсу удаленного дисплея. Это разрешение обычно используется только специальными приложениями."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"Подключение к службе виджетов"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Приложение сможет подключаться к базовому интерфейсу службы виджетов. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"Взаимодействие с администратором устройства"</string>
@@ -416,6 +423,8 @@
     <string name="permdesc_anyCodecForPlayback" msgid="8283912488433189010">"Приложение сможет использовать любой установленный дешифратор."</string>
     <string name="permlab_manageCaCertificates" msgid="1678391896786882014">"Управление учетными данными"</string>
     <string name="permdesc_manageCaCertificates" msgid="4015644047196937014">"Приложение сможет устанавливать сертификаты ЦС в качестве надежных учетных данных, а также удалять их."</string>
+    <string name="permlab_bindIdleService" msgid="816311765497613780">"выполнение приложения в спящем режиме"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Система Android сможет выполнять приложение в фоновом режиме, когда устройство не используется."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"Чтение/запись данных в системы диагностики"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Приложение сможет считывать и записывать данные системы диагностики (например, файлы в каталоге /dev). Это может повлиять на стабильность и безопасность системы. Это разрешение должно использоваться ТОЛЬКО производителем или оператором для диагностики аппаратного обеспечения."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"Включение/отключение компонентов приложения"</string>
@@ -477,6 +486,8 @@
     <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">"настраивать экраны, подключенные через Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Приложение сможет подключаться к экранам с помощью Wi-Fi и настраивать их."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Управление мониторами, подключенными через Wi-Fi"</string>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Приложение сможет изменять системные настройки звука, например уровень громкости и активный динамик."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"Запись аудио"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Приложение сможет записывать аудио с помощью микрофона в любое время без уведомления."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"Обращение к SIM-карте"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Приложение сможет отправлять команды SIM-карте (данное разрешение представляет большую угрозу)."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Фото- и видеосъемка"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Приложение сможет снимать фотографии и видеоролики с помощью камеры в любое время без вашего разрешения."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"Отключать светодиодный индикатор во время использования камеры"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Приложение сможет управлять на устройстве функциями телефона: переключать сети, включать и выключать приемопередатчик, а также выполнять другие подобные действия без уведомления."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"Получение данных о статусе телефона"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Приложение получит доступ к функциям телефона на устройстве. Кроме того, оно сможет определять номера телефонов и серийные номера моделей, состояние активности вызова, а также удаленные номера, с которыми установлено соединение."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Доступ к точным статусам телефона"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Приложение сможет определять точный статус вызовов (активный, в фоновом режиме или сбой), а также статус интернет-соединения (в том числе, если подключиться не удалось)."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Владелец сможет запускать приложение настроек, предоставленное оператором. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Использование данных о состоянии сети"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Приложение сможет использовать данные о состоянии сети. Это разрешение обычно используется только специальными приложениями."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"изменение параметров калибровки экрана"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Приложение сможет изменять параметры калибровки сенсорного экрана. Это разрешение обычно используется только специальными приложениями."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Домашний"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Рабочий"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Другой"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Не найдено приложение для просмотра контакта"</string>
     <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>
@@ -1102,8 +1120,8 @@
     <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="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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Взаимодействовать с системой восстановления и обновлениями"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Приложение сможет взаимодействовать с системой восстановления и обновлениями системы."</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>
@@ -1343,7 +1363,7 @@
     <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">"USB-модем/точка доступа Wi-Fi используется"</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Клавиша смены регистра"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Клавиша ввода"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Выберите приложение"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Не удалось запустить приложение \"<xliff:g id="APPLICATION_NAME">%s</xliff:g>\""</string>
     <string name="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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Подключение к устройству"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Подключение к удаленному дисплею"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Поиск устройств…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Настройки"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Отключить"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Сканирование..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Подключение..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Доступен"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Подключение к удаленному дисплею"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Подключение к <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Удаленный дисплей подключен"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Подключено к <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Чтобы вернуться в обычный режим, проведите пальцем вниз"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Чтобы вернуться в обычный режим, проведите пальцем вниз."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Выбор часов на циферблате"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Выбор минут на циферблате"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Выберите часы"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Выберите минуты"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Окно выбора даты"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Меню выбора года"</string>
+    <string name="select_day" msgid="7774759604701773332">"Выберите месяц и число"</string>
+    <string name="select_year" msgid="7952052866994196170">"Выберите год"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Выбран элемент <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Цифра <xliff:g id="KEY">%1$s</xliff:g> удалена"</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..0bbcd06
--- /dev/null
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -0,0 +1,1594 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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_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_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="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 cd865aa..4df9785 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -38,7 +38,7 @@
     <string name="mmiFdnError" msgid="5224398216385316471">"Operácia je obmedzená len na režim čísla pevného vytáčania."</string>
     <string name="serviceEnabled" msgid="8147278346414714315">"Služba bola povolená."</string>
     <string name="serviceEnabledFor" msgid="6856228140453471041">"Služba bola povolená pre:"</string>
-    <string name="serviceDisabled" msgid="1937553226592516411">"Služba bola zakázaná."</string>
+    <string name="serviceDisabled" msgid="1937553226592516411">"Služba bola vypnutá."</string>
     <string name="serviceRegistered" msgid="6275019082598102493">"Registrácia prebehla úspešne."</string>
     <string name="serviceErased" msgid="1288584695297200972">"Vymazanie prebehlo úspešne."</string>
     <string name="passwordIncorrect" msgid="7612208839450128715">"Nesprávne heslo."</string>
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Zadajte kód PUK, ktorý má 8 alebo viac čísel."</string>
     <string name="needPuk" msgid="919668385956251611">"Karta SIM je uzamknutá pomocou kódu PUK. Odomknite ju zadaním kódu PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ak chcete odblokovať kartu SIM, zadajte kód PUK2."</string>
+    <string name="enablePin" msgid="209412020907207950">"Neúspešné, povoľte uzamknutie SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Zostáva vám <xliff:g id="NUMBER">%d</xliff:g> pokus, než sa vaša karta SIM uzamkne."</item>
+    <item quantity="other" msgid="7530597808358774740">"Počet zostávajúcich pokusov pred uzamknutím karty SIM: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Prichádzajúca identifikácia volajúceho"</string>
@@ -185,7 +190,7 @@
     <string name="permgroupdesc_bluetoothNetwork" msgid="5625288577164282391">"Prístup k zariadeniam a sieťam prostredníctvom rozhrania Bluetooth."</string>
     <string name="permgrouplab_audioSettings" msgid="8329261670151871235">"Nastavenia zvuku"</string>
     <string name="permgroupdesc_audioSettings" msgid="2641515403347568130">"Zmena nastavení zvuku."</string>
-    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Má vplyv na batériu"</string>
+    <string name="permgrouplab_affectsBattery" msgid="6209246653424798033">"Vplyv na batériu"</string>
     <string name="permgroupdesc_affectsBattery" msgid="6441275320638916947">"Používanie funkcií, ktoré môžu rýchlo vyčerpať batériu."</string>
     <string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendár"</string>
     <string name="permgroupdesc_calendar" msgid="5777534316982184416">"Priamy prístup ku kalendáru a udalostiam."</string>
@@ -227,7 +232,7 @@
     <string name="permgroupdesc_developmentTools" msgid="7058828032358142018">"Funkcie len pre vývojárov aplikácií."</string>
     <string name="permgrouplab_display" msgid="4279909676036402636">"Používateľské rozhranie iných aplikácií"</string>
     <string name="permgroupdesc_display" msgid="6051002031933013714">"Vplyv na používateľské rozhranie ďalších aplikácií."</string>
-    <string name="permgrouplab_storage" msgid="1971118770546336966">"Ukladací priestor"</string>
+    <string name="permgrouplab_storage" msgid="1971118770546336966">"Úložisko"</string>
     <string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"Prístup do ukl. priestoru USB."</string>
     <string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"Prístup na kartu SD."</string>
     <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"Funkcie zjednodušenia ovládania"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"odinštalovať odkazy"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Povoľuje aplikácii odstrániť odkazy na ploche bez zásahu používateľa."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"presmerovať odchádzajúce hovory"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Umožňuje aplikácii spracovávať odchádzajúce hovory a meniť vytáčané číslo. Toto povolenie umožňuje aplikácii sledovať a presmerovať odchádzajúce hovory alebo im zabrániť."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Umožňuje aplikácii počas odchádzajúceho hovoru rozpoznať vytáčané číslo a poskytuje možnosť presmerovať daný hovor na odlišné číslo alebo ho úplne zrušiť."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"prijímať textové správy (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Umožňuje aplikácii prijímať a spracovávať správy SMS. Znamená to, že aplikácia môže sledovať správy odoslané na vaše zariadenie alebo ich odstrániť bez toho, aby sa vám zobrazili."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"prijímať textové správy (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania služby VPN. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"väzba na tapetu"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania tapety. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"viazať na vzdialený displej"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Umožňuje držiteľovi viazať sa na najvyššiu úroveň rozhrania vzdialeného displeja. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"viazať sa k službe miniaplikácie"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"spustiť aplikáciu počas nečinnosti"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Toto povolenie umožňuje systému Android spustiť aplikáciu na pozadí, keď sa zariadenie nepoužíva."</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>
@@ -470,13 +479,15 @@
     <string name="permlab_installLocationProvider" msgid="6578101199825193873">"Oprávnenie na inštaláciu poskytovateľa polohy"</string>
     <string name="permdesc_installLocationProvider" msgid="9066146120470591509">"Vytváranie simulovaných zdrojov polohy na testovanie alebo inštalácia nového poskytovateľa informácií o polohe. Aplikácii to umožní nahradiť polohu a stav, ktoré vracajú iné zdroje informácií o polohe, ako sú napríklad systém GPS alebo poskytovatelia informácií o polohe."</string>
     <string name="permlab_accessFineLocation" msgid="1191898061965273372">"presná poloha (pomocou GPS a siete)"</string>
-    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Umožňuje aplikácii získať vašu presnú polohu pomocou systému GPS (Global Positioning System) alebo zdrojov určenia polohy siete, napríklad mobilných veží a sietí Wi-Fi. Tieto služby využívajúce polohu musia byť na vašom zariadení zapnuté a dostupné, inak ich aplikácia nebude môcť využívať. Aplikácie môžu tieto služby využívať na určenie vašej polohy. Tieto služby môžu zvýšiť spotrebu batérie."</string>
+    <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"Umožňuje aplikácii získať vašu presnú polohu pomocou systému GPS (Global Positioning System) alebo zdrojov určenia polohy siete, napríklad mobilných veží a sietí Wi-Fi. Tieto služby určovania polohy musia byť na vašom zariadení zapnuté a dostupné, inak ich aplikácia nebude môcť využívať. Aplikácie môžu tieto služby využívať na určenie vašej polohy. Tieto služby môžu zvýšiť spotrebu batérie."</string>
     <string name="permlab_accessCoarseLocation" msgid="4887895362354239628">"približná poloha (pomocou siete)"</string>
-    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Umožňuje aplikácii získať vašu približnú polohu. Táto poloha je odvodená zo služieb využívajúcich polohu pomocou zdrojov určenia polohy siete, napríklad mobilných veží a sietí Wi-Fi. Tieto služby využívajúce polohu musia byť na vašom zariadení zapnuté a dostupné, inak ich aplikácia nebude môcť využívať. Aplikácie môžu tieto služby využívať na určenie vašej približnej polohy."</string>
+    <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"Umožňuje aplikácii získať vašu približnú polohu. Táto poloha je odvodená zo služieb určovania polohy pomocou zdrojov určenia polohy siete, napríklad mobilných veží a sietí Wi-Fi. Tieto služby určovania polohy musia byť na vašom zariadení zapnuté a dostupné, inak ich aplikácia nebude môcť využívať. Aplikácie môžu tieto služby využívať na určenie vašej približnej polohy."</string>
     <string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"prístup k službe SurfaceFlinger"</string>
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Umožňuje aplikácii používať funkcie nízkej úrovne aplikácie SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"čítanie vyrovnávacej pamäte snímok"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Umožňuje aplikácii čítať obsah vyrovnávacej pamäte snímok."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"prístup k aplikácii InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Umožňuje aplikácii používať funkcie nízkej úrovne aplikácie InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurovať displeje cez sieť Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Umožňuje aplikácii zaznamenávať zvuk pomocou mikrofónu. Toto povolenie umožňuje aplikácii zaznamenávať zvuk kedykoľvek bez vášho potvrdenia."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"komunikácia s kartou SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Umožňuje aplikácii odosielať príkazy na kartu SIM. Toto je veľmi nebezpečné povolenie."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"snímanie fotografií a natáčanie videí"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Umožňuje aplikácii fotografovať a nahrávať videá pomocou fotoaparátu. Toto povolenie umožňuje aplikácii používať fotoaparát kedykoľvek a bez vášho potvrdenia."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"Zakázať indikátor LED prenosu pri používaní fotoaparátu"</string>
@@ -515,14 +528,14 @@
     <string name="permdesc_mount_format_filesystems" msgid="8784268246779198627">"Umožňuje aplikácii formátovať vymeniteľný ukladací priestor."</string>
     <string name="permlab_asec_access" msgid="3411338632002193846">"získať informácie o internom ukladacom priestore"</string>
     <string name="permdesc_asec_access" msgid="3094563844593878548">"Umožňuje aplikácii získať informácie o internom ukladacom priestore."</string>
-    <string name="permlab_asec_create" msgid="6414757234789336327">"vytvoriť interný ukladací priestor"</string>
-    <string name="permdesc_asec_create" msgid="4558869273585856876">"Umožňuje aplikácii vytvoriť interný ukladací priestor."</string>
-    <string name="permlab_asec_destroy" msgid="526928328301618022">"zničiť interný ukladací priestor"</string>
-    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Umožňuje aplikácii zničiť interný ukladací priestor."</string>
-    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"pripojiť alebo odpojiť interný ukladací priestor"</string>
-    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Umožňuje aplikácii pripojiť alebo odpojiť interný ukladací priestor."</string>
-    <string name="permlab_asec_rename" msgid="7496633954080472417">"premenovať interný ukladací priestor"</string>
-    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Umožňuje aplikácii premenovať interný ukladací priestor."</string>
+    <string name="permlab_asec_create" msgid="6414757234789336327">"vytvoriť interné úložisko"</string>
+    <string name="permdesc_asec_create" msgid="4558869273585856876">"Umožňuje aplikácii vytvoriť interné úložisko."</string>
+    <string name="permlab_asec_destroy" msgid="526928328301618022">"zničiť interné úložisko"</string>
+    <string name="permdesc_asec_destroy" msgid="7218749286145526537">"Umožňuje aplikácii zničiť interné úložisko."</string>
+    <string name="permlab_asec_mount_unmount" msgid="8877998101944999386">"pripojiť alebo odpojiť interné úložisko"</string>
+    <string name="permdesc_asec_mount_unmount" msgid="3451360114902490929">"Umožňuje aplikácii pripojiť alebo odpojiť interné úložisko."</string>
+    <string name="permlab_asec_rename" msgid="7496633954080472417">"premenovať interné úložisko"</string>
+    <string name="permdesc_asec_rename" msgid="1794757588472127675">"Umožňuje aplikácii premenovať interné úložisko."</string>
     <string name="permlab_vibrate" msgid="7696427026057705834">"ovládať vibrovanie"</string>
     <string name="permdesc_vibrate" msgid="6284989245902300945">"Umožňuje aplikácii ovládať vibrácie."</string>
     <string name="permlab_flashlight" msgid="2155920810121984215">"ovládanie kontrolky"</string>
@@ -543,15 +556,17 @@
     <string name="permlab_locationUpdates" msgid="7785408253364335740">"ovládanie upozornení na aktualizáciu polohy"</string>
     <string name="permdesc_locationUpdates" msgid="1120741557891438876">"Umožňuje aplikácii povoliť alebo zakázať upozornenia s aktualizáciami polohy z rádia. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_checkinProperties" msgid="7855259461268734914">"prístup k vlastnostiam nahlásenia"</string>
-    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Umožňuje aplikácii čítať a zapisovať vlastnosti odovzdané službou nahlasovania. Bežné aplikácie toto nastavenie nepoužívajú."</string>
+    <string name="permdesc_checkinProperties" msgid="4024526968630194128">"Umožňuje aplikácii čítať a zapisovať vlastnosti nahrané službou nahlasovania. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_bindGadget" msgid="776905339015863471">"zvoliť miniaplikácie"</string>
     <string name="permdesc_bindGadget" msgid="8261326938599049290">"Umožňuje aplikácii povedať systému, ktoré aplikácie môžu používať určité miniaplikácie. Aplikácia s týmto povolením môže iným aplikáciám povoliť prístup k osobným údajom. Bežné aplikácie toto nastavenie nepoužívajú."</string>
     <string name="permlab_modifyPhoneState" msgid="8423923777659292228">"zmeny stavu telefónu"</string>
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Umožňuje aplikácii ovládať telefónne funkcie zariadenia. Aplikácia s týmto povolením môže prepínať siete alebo zapnúť a vypnúť rádio bez toho, aby vás na to upozornila."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"čítať stav a identitu telefónu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Umožňuje aplikácii pristupovať k telefónnym funkciám zariadenia. Aplikácia s týmto povolením môže určiť telefónne číslo a ID zariadenia, či práve prebieha hovor, a vzdialené číslo, s ktorým je prostredníctvom hovoru nadviazané spojenie."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"čítanie presných stavov telefónu"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Umožňuje aplikácii pristupovať k presným stavom telefónu. Toto povolenie umožňuje aplikácii zistiť skutočný stav hovoru, či je hovor aktívny alebo na pozadí, zlyhania hovorov, presný stav dátového pripojenia a zlyhania dátového pripojenia."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zabránenie prechodu tabletu do režimu spánku"</string>
-    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zabránenie prechodu telefónu do režimu spánku"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"deaktivácia 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>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"infračervený prenos"</string>
@@ -622,7 +637,7 @@
     <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Umožňuje aplikácii zobraziť informácie o konfigurácii Bluetooth na telefóne. Taktiež jej umožňuje nadväzovať a akceptovať spojenia so spárovanými zariadeniami."</string>
     <string name="permlab_nfc" msgid="4423351274757876953">"ovládať technológiu Near Field Communication"</string>
     <string name="permdesc_nfc" msgid="7120611819401789907">"Umožňuje aplikácii komunikovať so značkami, kartami a čítačkami s podporou technológie Near Field Communication (NFC)."</string>
-    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"zakázať uzamknutie obrazovky"</string>
+    <string name="permlab_disableKeyguard" msgid="3598496301486439258">"deaktivácia zámky obrazovky"</string>
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Umožňuje aplikácii zakázať uzamknutie klávesnice a akékoľvek súvisiace zabezpečenie heslom. Príkladom je zakázanie uzamknutia klávesnice pri prichádzajúcom telefonickom hovore a jeho opätovné povolenie po skončení hovoru."</string>
     <string name="permlab_readSyncSettings" msgid="6201810008230503052">"čítanie nastavení synchronizácie"</string>
     <string name="permdesc_readSyncSettings" msgid="2706745674569678644">"Umožňuje aplikácii čítať nastavenia synchronizácie v účte. Môže napríklad určiť, či je s účtom synchronizovaná aplikácia Ľudia."</string>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"zmeniť kalibráciu vstupného zariadenia"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Umožňuje aplikácii upraviť parametre kalibrácie dotykovej obrazovky. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Domov"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Práca"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Iné"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Nebola nájdená žiadna aplikácia, pomocou ktorej by bolo možné zobraziť tento kontakt."</string>
     <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>
@@ -1117,7 +1135,7 @@
     <string name="whichApplication" msgid="4533185947064773386">"Dokončiť akciu pomocou aplikácie"</string>
     <string name="whichHomeApplication" msgid="4616420172727326782">"Vyberte domovskú aplikáciu"</string>
     <string name="alwaysUse" msgid="4583018368000610438">"Použiť ako predvolené nastavenie pre túto akciu."</string>
-    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Vymazať predvolené nastavenia v sekcii Nastavenia systému &gt; Aplikácie &gt; Prevzaté položky."</string>
+    <string name="clearDefaultHintMsg" msgid="3252584689512077257">"Vymazať predvolené nastavenia v sekcii Nastavenia systému &gt; Aplikácie &gt; Stiahnuté položky."</string>
     <string name="chooseActivity" msgid="7486876147751803333">"Zvoľte akciu"</string>
     <string name="chooseUsbActivity" msgid="6894748416073583509">"Zvoľte aplikáciu pre zariadenie USB"</string>
     <string name="noApplications" msgid="2991814273936504689">"Túto akciu nemôžu vykonávať žiadne aplikácie."</string>
@@ -1138,7 +1156,7 @@
     <string name="launch_warning_original" msgid="188102023021668683">"Pôvodne bola spustená aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
     <string name="screen_compat_mode_scale" msgid="3202955667675944499">"Prispôsobiť veľkosť"</string>
     <string name="screen_compat_mode_show" msgid="4013878876486655892">"Vždy zobraziť"</string>
-    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Povoľte to znova v sekcii Nastavenia systému &gt; Aplikácie &gt; Prevzaté súbory."</string>
+    <string name="screen_compat_mode_hint" msgid="1064524084543304459">"Povoľte to znova v sekcii Nastavenia systému &gt; Aplikácie &gt; Stiahnuté súbory."</string>
     <string name="smv_application" msgid="3307209192155442829">"Aplikácia <xliff:g id="APPLICATION">%1$s</xliff:g> (proces <xliff:g id="PROCESS">%2$s</xliff:g>) porušila svoje vlastné vynútené pravidlá StrictMode."</string>
     <string name="smv_process" msgid="5120397012047462446">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> porušil svoje vlastné vynútené pravidlá StrictMode."</string>
     <string name="android_upgrading_title" msgid="1584192285441405746">"Prebieha inovácia systému Android..."</string>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interakcia so systémom aktualizácií a obnovenia"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Umožňuje aplikácii interakciu so systémom obnovenia a s aktualizáciami systému."</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>
@@ -1414,18 +1434,10 @@
     <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">"Zvoľte aplikáciu"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Aplikáciu <xliff:g id="APPLICATION_NAME">%s</xliff:g> nie je možné spustiť"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Zdieľať s"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Zdieľať s aplikáciou <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Posuvné tlačidlo. Dotknite sa a podržte."</string>
-    <string name="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="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_target_unlock_tablet" msgid="3833195335629795055">"Posunom odomknúť."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Ak si chcete vypočuť vyslovené klávesy hesla, pripojte náhlavnú súpravu."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Bodka."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Systém"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Bezdrôtový displej"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Pripojenie k zariadeniu"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Prenos obraz. do zariad."</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Prebieha vyhľadávanie zariadení…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Nastavenia"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Odpojiť"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Prebieha vyhľadávanie..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Prebieha pripájanie…"</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"K dispozícii"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Nahrávanie obrazovky na prehratie"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Prebieha pripájanie k obrazovke <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Nahrávanie obrazovky na prehratie"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Pripojené k obrazovke <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Odpojiť"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Kód PUK musí obsahovať 8 čí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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Režim celej obraz. ukončíte posunutím nadol"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Režim celej obrazovky ukončíte posunutím nadol."</string>
+    <string name="done_label" msgid="2093726099505892398">"Hotovo"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kruhový posúvač hodín"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kruhový posúvač minút"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Vyberte hodiny"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Vyberte minúty"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Tabuľka dní v mesiaci"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Zoznam rokov"</string>
+    <string name="select_day" msgid="7774759604701773332">"Vyberte mesiac a deň"</string>
+    <string name="select_year" msgid="7952052866994196170">"Vyberte rok"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Bola vybratá položka <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Číslo <xliff:g id="KEY">%1$s</xliff:g> bolo odstránené"</string>
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 43da811..cab43f2 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Vnesite 8- ali več mestni PUK."</string>
     <string name="needPuk" msgid="919668385956251611">"Kartica SIM je zaklenjena s kodo PUK. Če jo želite odkleniti, vnesite kodo PUK."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Če želite odstraniti blokiranje kartice SIM, vnesite PUK2."</string>
+    <string name="enablePin" msgid="209412020907207950">"Ni uspelo. Omogočite zaklepanje kartice SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Na voljo imate še <xliff:g id="NUMBER">%d</xliff:g> poskus. Potem se bo kartica SIM zaklenila."</item>
+    <item quantity="other" msgid="7530597808358774740">"Poskusite lahko še <xliff:g id="NUMBER">%d</xliff:g>-krat. Potem se bo kartica SIM zaklenila."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"ID dohodnega klicatelja"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"odstranjevanje bližnjic"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Aplikaciji omogoča odstranjevanje bližnjic z začetnega zaslona brez posredovanja uporabnika."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"preusmeritev odhodnih klicev"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Aplikaciji omogoča, da obdela odhodne klice in spreminja klicne številke. S tem lahko aplikacija nadzira, preusmerja ali preprečuje odhodne klice."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Aplikaciji dovoli ogled klicane številke pri odhodnem klicu in ji omogoča preusmeritev klica na drugo številko ali prekinitev klica."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"prejemanje sporočil (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Aplikaciji omogoča prejemanje in obdelavo SMS-ov. S tem lahko aplikacija nadzoruje ali izbriše sporočila, poslana v napravo, ne da bi vam jih pokazala."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"prejemanje sporočil (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Lastniku omogoča povezovanje z vmesnikom storitve navideznega zasebnega omrežja najvišje ravni. Ne uporabljajte za navadne programe."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"povezovanje z ozadjem"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Imetniku omogoča povezavo z vmesnikom ozadja najvišje ravni. Tega nikoli ni treba uporabiti za navadne programe."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"povezava z oddaljenim prikazom"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Imetniku omogoča povezovanje z vmesnikom oddaljenega prikaza najvišje ravni. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"poveži s storitvijo pripomočka"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"izvajanje aplikacije ob nedejavnosti"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"To dovoljenje sistemu Android omogoča, da izvaja aplikacijo v ozadju, ko naprava ni v uporabi."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Programu omogoča uporabo funkcij nizke ravni SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"branje grafičnega/slikovnega medpomnilnika"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Programu omogoča branje vsebine grafičnega/slikovnega medpomnilnika."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"dostop do funkcij InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Aplikaciji dovoljuje uporabo funkcij InputFlinger nizke ravni."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfiguriranje zaslonov Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Aplikaciji omogoča snemanje zvoka z mikrofonom. S tem dovoljenjem lahko aplikacija kadar koli snema zvok brez vaše potrditve."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"komuniciranje s kartico SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Aplikaciji dovoli pošiljanje ukazov kartici SIM. To je lahko zelo nevarno."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"fotografiranje in snemanje videoposnetkov"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Aplikaciji omogoča fotografiranje in snemanje videoposnetkov s kamero. S tem dovoljenjem lahko aplikacija kadar koli uporablja kamero brez vaše potrditve."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"onemogoči LED-indikator prenašanja, ko je fotoaparat v uporabi"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Programu omogoča nadziranje telefonskih funkcij naprave. Program lahko s tem dovoljenjem preklaplja omrežja, vklopi ali izklopi radio v telefonu, ne da bi vas obvestil."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"branje stanja in identitete telefona"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Aplikaciji omogoča dostop do funkcij telefona v napravi. S tem dovoljenjem lahko aplikacija določi telefonsko številko in ID-je naprave, določi lahko tudi, ali je klic aktiven, in oddaljeno številko, s katero je klic povezan."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"branje natančnih stanj telefona"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Aplikaciji dovoli dostop do natančnih stanj telefona. To dovoljenje aplikaciji omogoča ugotoviti pravo stanje klica; ali je klic aktiven ali v ozadju; neuspele klice; natančno stanje podatkovne povezave in neuspele podatkovne povezave."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"preprečitev prehoda tabličnega računalnika v stanje pripravljenosti"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"sprememba umerjanja vhodne naprave"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Aplikaciji dovoli spreminjanje parametrov za umerjanje zaslona na dotik. Tega ni treba nikoli uporabiti za navadne aplikacije."</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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Domov"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Služba"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Drugo"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Ni aplikacije za ogled tega stika."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Uporaba sistema za posodobitev in obnovitev"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Aplikaciji dovoli uporabo sistema za obnovitev in posodobitev sistema."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Tipka Shift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Tipka Enter"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Izberite program"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Aplikacije <xliff:g id="APPLICATION_NAME">%s</xliff:g> ni bilo mogoče zagnati"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Delite z"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Delite s programom <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Drsna ročica. Dotaknite se in pridržite."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Povlecite, če želite odkleniti."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Priključite slušalke, če želite slišati izgovorjene tipke gesla."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Pika."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Zvok prek Bluetootha"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Brezžični prikaz"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Končano"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Izhod predstavnosti"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Povezovanje z napravo"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Predvajanje zaslona v napravi"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Iskanje naprav …"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Nastavitve"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Prekinitev povezave"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Pregledovanje ..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Vzpostavljanje povezave ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Na voljo"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Predvajanje zaslona"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Povezovanje z zaslonom <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Predvajanje zaslona"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Vzpostavljena povezava z zaslonom <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Prekini povezavo"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Koda PUK mora biti 8-mestno število."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Poskusite znova pozneje"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Povlecite z vrha, da zaprete celozaslonski način."</string>
+    <string name="done_label" msgid="2093726099505892398">"Dokončano"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Okrogli drsnik za ure"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Okrogli drsnik za minute"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Izberite ure"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Izberite minute"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Mesečna mreža dni"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Seznam let"</string>
+    <string name="select_day" msgid="7774759604701773332">"Izberite mesec in dan"</string>
+    <string name="select_year" msgid="7952052866994196170">"Izberite leto"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Izbrano: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Številka <xliff:g id="KEY">%1$s</xliff:g> je izbrisana"</string>
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 14b22cc..7895ded 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Није успело. Омогућите закључавање SIM/RUIM картице."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Имате још <xliff:g id="NUMBER">%d</xliff:g> покушај пре него што се SIM картица закључа."</item>
+    <item quantity="other" msgid="7530597808358774740">"Имате још <xliff:g id="NUMBER">%d</xliff:g> покушаја пре него што се SIM картица закључа."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Долазни ИД позиваоца"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"деинсталирање пречица"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Омогућава апликацији да уклања пречице са почетног екрана без интервенције корисника."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"преусмеравање одлазних позива"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Дозвољава апликацији да обрађује одлазне позиве и промени број који се бира. Ова дозвола омогућава апликацији да надгледа, преусмерава или спречава одлазне позиве."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Дозвољава апликацији да види који број се бира при одлазном позиву уз опцију да преусмери позив на други број или га потпуно прекине."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"повезивање са удаљеним екраном"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Дозвољава власнику да се повеже са интерфејсом удаљеног екрана највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"обавезивање на услугу виџета"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дозвољава власнику да се обавеже на интерфејс услуге виџета највишег нивоа. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"интеракција са администратором уређаја"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"покреће апликације током неактивности"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ова дозвола омогућава систему Android да покреће апликације у позадини док се уређај не користи."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"читање ресурса у власништву дијагностике и уписивање података у њих"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозвољава апликацији да чита и уписује податке у било који ресурс у власништву групе за дијагностиковање, на пример, датотеке у директоријуму /dev. То може да угрози стабилност и безбедност система и треба да је користе САМО произвођач или оператер у сврхе дијагностиковањa хардвера."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"омогућавање или онемогућавање компоненти апликације"</string>
@@ -477,6 +486,8 @@
     <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">"конфигурисање Wi-Fi екрана"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозвољава апликацији да конфигурише Wi-Fi екране и повезује се са њима."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"контрола Wi-Fi екрана"</string>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Дозвољава апликацији да мења глобална аудио подешавања као што су јачина звука и избор звучника који се користи као излаз."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"снимање аудио записа"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Дозвољава апликацији да снима звук помоћу микрофона. Ова дозвола омогућава апликацији да снима звук у било ком тренутку без ваше потврде."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"Комуникација са SIM картицом"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Омогућава апликацији да шаље команде SIM картици. То је веома опасно."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"снимање фотографија и видео снимака"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Дозвољава апликацији да снима слике и видео снимке камером. Ова дозвола омогућава апликацији да у било ком тренутку користи камеру без ваше потврде."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"онемогући пренос LED осветљења индикатора док се камера користи"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Дозвољава апликацији да управља функцијама телефона на уређају. Апликација са овом дозволом може да прелази са једне мреже на другу и да без обавештења укључује и искључује радио телефона и сличне функције."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"читање статуса и идентитета телефона"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дозвољава апликацији да приступа функцијама телефона на уређају. Ова дозвола омогућава апликацији да утврди број телефона и ИД-ове уређаја, затим да ли је позив активан, као и број даљинског уређаја са којим је успостављен позив."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"читај прецизне статусе телефона"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Омогућава апликацији да приступа прецизним статусима телефона. Ова дозвола омогућава апликацији да утврди стварни статус позива, да ли је позив активан или у позадини, неуспеле позиве, прецизан статус везе за пренос података и неуспела успостављања везе за пренос података."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозвољава власнику да позива апликацију са конфигурацијом коју одређује оператер. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"праћење података о условима на мрежи"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозвољава апликацији да прати податке о условима на мрежи. Не би никада требало да буде потребно за нормалне апликације."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"промени калибрацију улазног уређаја"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Дозвољава апликацији да модификује параметре калибрације додирног екрана. Не би требало да буде потребно за нормалне апликације."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Почетна"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Посао"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Други"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Није пронађена ниједна апликација за приказ овог контакта."</string>
     <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>
@@ -1220,7 +1238,7 @@
     <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_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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Интеракција са системом за ажурирање и опоравак"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Дозвољава апликацији да ступа у интеракцију са системом за опоравак и ажурирањима система."</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"Није могуће покренути <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Дели са"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Дели са апликацијом <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Клизна ручица. Додирните и задржите."</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Повежите са уређајем"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Пребаците екран на уређај"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Тражење уређаја…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Подешавања"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Прекини везу"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Скенирање..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Повезивање..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Доступна"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Пребацивање екрана"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Повезивање са <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Пребацивање екрана"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Повезано је са <xliff:g id="NAME">%1$s</xliff:g>"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Покушајте поново касније"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Превуците прстом одозго надоле да бисте изашли из целог екрана."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Кружни клизач за сате"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Кружни клизач за минуте"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Изаберите сате"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Изаберите минуте"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Приказ дана у месецу у виду мреже"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Листа година"</string>
+    <string name="select_day" msgid="7774759604701773332">"Изаберите месец и дан"</string>
+    <string name="select_year" msgid="7952052866994196170">"Изаберите годину"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Изабрали сте <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Избрисали сте <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index aa20a64..c29f0a3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Ange en PUK-kod med minst 8 siffror."</string>
     <string name="needPuk" msgid="919668385956251611">"Ditt SIM-kort är PUK-låst. Ange PUK-koden om du vill låsa upp det."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Ange PUK2-koden för att häva spärren av SIM-kortet."</string>
+    <string name="enablePin" msgid="209412020907207950">"Försöket misslyckades. Aktivera SIM-/RUIM-lås."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Du har <xliff:g id="NUMBER">%d</xliff:g> försök kvar innan SIM-kortet låses."</item>
+    <item quantity="other" msgid="7530597808358774740">"Du har <xliff:g id="NUMBER">%d</xliff:g> försök kvar innan SIM-kortet låses."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI-kod"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Nummerpresentatör för inkommande samtal"</string>
@@ -152,7 +157,7 @@
     <string name="reboot_safemode_title" msgid="7054509914500140361">"Starta om i felsäkert läge"</string>
     <string name="reboot_safemode_confirm" msgid="55293944502784668">"Vill du starta om datorn i felsäkert läge? Då inaktiveras alla appar från tredje part som du har installerat. Apparna återställs när du startar om datorn igen."</string>
     <string name="recent_tasks_title" msgid="3691764623638127888">"Senaste"</string>
-    <string name="no_recent_tasks" msgid="8794906658732193473">"Inga nya appar."</string>
+    <string name="no_recent_tasks" msgid="8794906658732193473">"Inga aktiva appar."</string>
     <string name="global_actions" product="tablet" msgid="408477140088053665">"Alternativ för surfplattan"</string>
     <string name="global_actions" product="default" msgid="2406416831541615258">"Telefonalternativ"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"Skärmlås"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"avinstallera genvägar"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Tillåter att appen tar bort genvägar på startskärmen utan åtgärd från användaren."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"omdirigera utgående samtal"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Tillåter att appen hanterar utgående samtal och ändrar numret som ska ringas upp. Med den här behörigheten kan appen övervaka, omdirigera eller förhindra utgående samtal."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Tillåter att appen ser numret du slår under ett utgående samtal och har möjlighet att koppla samtalet till ett annat nummer eller avbryta samtalet helt."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"ta emot textmeddelanden (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Tillåter att appen tar emot och hanterar SMS. Detta innebär att appen kan övervaka eller ta bort meddelanden som skickats till enheten utan att visa dem för dig."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"ta emot textmeddelanden (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en VPN-tjänst. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"binda till en bakgrund"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Innehavaren kan binda till den översta nivåns gränssnitt för en bakgrund. Ska inte behövas för vanliga appar."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"bind till en fjärrskärm"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Innehavaren tillåts att binda till den översta nivåns gränssnitt för en fjärrskärm. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bind till en widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"kör appen när enheten är inaktiv"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Med den här behörigheten tillåts Android-systemet att köra appen i bakgrunden när enheten inte används."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Tillåter att appen använder lågnivåfunktioner i SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"läsa rambuffert"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Tillåter att appen läser innehållet i rambufferten."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"få tillgång till InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Tillåter att appen använder lågnivåfunktioner i InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"konfigurerar Wi-Fi-skärmar"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Tillåter att appen spelar in ljud med mikrofonen. Med den här behörigheten tillåts appen att spela in ljud när som helst utan ditt godkännande."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM-kommunikation"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Tillåter att appen skickar kommandon till SIM-kortet. Detta är mycket farligt."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ta bilder och spela in videoklipp"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Tillåter att appen tar bilder och spelar in videor med kameran. Med den här behörigheten tillåts appen att använda kameran när som helst utan ditt godkännande."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"inaktivera LED-sändningsindikator när kameran används"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Tillåter att appen styr enhetens telefonfunktioner. En app med den här behörigheten kan byta nätverk, aktivera/inaktivera mobilens radio och liknande utan att meddela dig."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"läsa telefonens status och identitet"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Tillåter att appen kommer åt enhetens telefonfunktioner. Med den här behörigheten tillåts appen att identifiera mobilens telefonnummer och enhets-ID, om ett samtal pågår och vilket nummer samtalet är kopplat till."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"läsa mobilens exakta status"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Tillåter att appen får tillgång till mobilens exakta status. Appen får behörighet att avgöra mobilens faktiska samtalsstatus, om samtalet är aktivt eller i bakgrunden, om samtal misslyckas, mobilens exakta dataanslutningsstatus och om dataanslutningar misslyckas."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"förhindra att surfplattan går in i viloläge"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"ändra kalibreringen för inmatningsenheten"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Tillåter att appen ändrar kalibreringsparametrarna för pekskärmen. Detta behövs aldrig för vanliga appar."</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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Hem"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Arbete"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Övrigt"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Ingen app för att visa den här kontakten hittades."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Interagera med uppdaterings- och återställningssystemet"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Tillåter att en app interagerar med systemuppdateringar och återställningssystemet."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Skift"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Retur"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Välj en app"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Det gick inte att starta <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Dela med"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dela med <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Skärmlåsfunktion. Tryck och dra."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Lås upp genom att dra."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Anslut mikrofonlurar om du vill att lösenordet ska läsas upp."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Punkt."</string>
@@ -1451,7 +1463,7 @@
     <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Gränsen för data via Wi-Fi har överskridits"</string>
     <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> över angiven gräns."</string>
     <string name="data_usage_restricted_title" msgid="5965157361036321914">"Bakgrundsdata är begränsade"</string>
-    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att radera begränsning"</string>
+    <string name="data_usage_restricted_body" msgid="6741521330997452990">"Tryck för att ta bort begränsning"</string>
     <string name="ssl_certificate" msgid="6510040486049237639">"Säkerhetscertifikat"</string>
     <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Certifikatet är giltigt."</string>
     <string name="issued_to" msgid="454239480274921032">"Utfärdad till:"</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ljud"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Trådlös skärm"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klar"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Medieuppspelning"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Anslut till enhet"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Överför skärmen till enheten"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Söker efter enheter ..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Inställningar"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Koppla från"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Skannar…"</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Ansluter ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Tillgängliga"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Överför skärmen"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Ansluter till <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Överför skärmen"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Ansluten till <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Koppla från"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK-koden ska vara å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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Försök igen senare"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Dra nedåt om du vill avbryta fullskärmsläget."</string>
+    <string name="done_label" msgid="2093726099505892398">"Klart"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Cirkelreglage för timmar"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Cirkelreglage för minuter"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Välj timmar"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Välj minuter"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Rutnät för månad"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Lista över år"</string>
+    <string name="select_day" msgid="7774759604701773332">"Välj månad och dag"</string>
+    <string name="select_year" msgid="7952052866994196170">"Välj år"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> har markerats"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> har tagits bort"</string>
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index b066758..3e11aa1 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Andika PUK ambayo ina urefu wa nambari 8 au zaidi."</string>
     <string name="needPuk" msgid="919668385956251611">"Kadi yako ya SIM imefungwa na PUK. Anika msimbo wa PUK ili kuifungua."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Chapisha PUK2 ili kufungua SIM kadi."</string>
+    <string name="enablePin" msgid="209412020907207950">"Imeshindwa, washa ufungaji wa SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Umesalia na majaribio <xliff:g id="NUMBER">%d</xliff:g> kabla ya SIM kufungwa."</item>
+    <item quantity="other" msgid="7530597808358774740">"Umesalia na majaribio <xliff:g id="NUMBER">%d</xliff:g> kabla ya SIM kufungwa."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Kitambulisho cha Mpigaji wa Simu Inayoingia"</string>
@@ -95,7 +100,7 @@
     <string name="roamingText4" msgid="8808456682550796530">"Nje ya Jengo"</string>
     <string name="roamingText5" msgid="7604063252850354350">"Urandaji - Mfumo unaopendelewa"</string>
     <string name="roamingText6" msgid="2059440825782871513">"Uzururaji - Mfumo Unaopatikana"</string>
-    <string name="roamingText7" msgid="7112078724097233605">"Uzururaji - Mwenza wa Ushirikiamo"</string>
+    <string name="roamingText7" msgid="7112078724097233605">"Roaming - Alliance Partner"</string>
     <string name="roamingText8" msgid="5989569778604089291">"Uzururaji - Mwenzi wa Thamani"</string>
     <string name="roamingText9" msgid="7969296811355152491">"Uzururaji - Utendajikazi Kamili wa Huduma"</string>
     <string name="roamingText10" msgid="3992906999815316417">"Uzururaji - Utendajikazi Nusi wa Huduma"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ondoa njia za mikato"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Huruhusu programu kuondoa njia za mkato za Skrini ya kwanza bila mtumiaji kuingilia."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"panga upya simu zinazotoka"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Inaruhusu programu kuchakata simu zinazotoka nje na kubadilisha nambari ya kupigwa. Idhini hii inaruhusu programu kuchunguza, kuelekeza upya, au kuzuia simu zinazotoka nje."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Huruhusu programu kuona nambari inayopigwa wakati simu inapigwa ikiwa na chaguo la kuelekeza simu kwenye nambari tofauti au kukata simu kabisa."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"pokea ujumbe wa maandishi wa SMS"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Hii inamaanisha programu hii inaweza kuchunguza na kufuta ujumbe uliotumwa katika kifaa chako bila ya kukuonyesha."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"pokea ujumbe wa maandishi wa MMS"</string>
@@ -343,9 +348,9 @@
     <string name="permlab_updateAppOpsStats" msgid="8829097373851521505">"rekebisha takwimu za oparesheni ya programu"</string>
     <string name="permdesc_updateAppOpsStats" msgid="50784596594403483">"Inaruhusu programu kurekebisha takwimu za matumizi ya programu zilizokusanywa. Si ya kutumiwa na programu za kawaida."</string>
     <string name="permlab_backup" msgid="470013022865453920">"Dhibiti kuhifadhi nakala na kurejesha kwa mfumo"</string>
-    <string name="permdesc_backup" msgid="6912230525140589891">"Inaruhusu programu kudhibiti utaratibu wa kucheleza na kurejesha wa mfumo. Si kwa matumizi na programu za kawaida."</string>
+    <string name="permdesc_backup" msgid="6912230525140589891">"Huruhusu programu kudhibiti utaratibu wa kuhifadhi nakala rudufu na kurejesha mfumo. Haifai kutumiwa na programu za kawaida."</string>
     <string name="permlab_confirm_full_backup" msgid="5557071325804469102">"thibitisha chelezo kamilifu au rejesha upya uendeshaji"</string>
-    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Inaruhusu programu kuzindua UI ya kuthibitisha chelezo kamili. Si ya kutumiwa na programu yoyote."</string>
+    <string name="permdesc_confirm_full_backup" msgid="1748762171637699562">"Huruhusu programu kuzindua kiolesura cha kuthibitisha kuhifadhiwa kwa nakala rudufu kamili. Haitumiwi na programu yoyote."</string>
     <string name="permlab_internalSystemWindow" msgid="2148563628140193231">"onyesha madirisha yasiyoidhinishwa"</string>
     <string name="permdesc_internalSystemWindow" msgid="7458387759461466397">"Huruhusu programu kuunda madirisha ambayo yananuiwa kutumiwa na kusano ya mtumiaji ya mfumo wa ndani. Sio ya matumizi na programu za kawaida."</string>
     <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"chora juu ya programu zingine"</string>
@@ -354,8 +359,8 @@
     <string name="permdesc_setAnimationScale" msgid="7690063428924343571">"Huruhusu programu kubadilisha kasi ya uhuishaji kijumla (uhuisho wa haraka zaidi au wa polepole zaidi) wakati wowote."</string>
     <string name="permlab_manageAppTokens" msgid="1286505717050121370">"Dhibiti shuhuda za programu"</string>
     <string name="permdesc_manageAppTokens" msgid="8043431713014395671">"Inaruhusu programu kuunda na kudhibiti shuhuda zake, kukwepa mipangilio yao ya kawaida. Haitahitajika kamwe na programu za kawaida."</string>
-    <string name="permlab_freezeScreen" msgid="4708181184441880175">"lemaza skrini"</string>
-    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Inaruhusu programu kulemaza kwa muda skrini kwa ajili ya mpito kamili wa skrinimaombi kwa muda kufungia screen kwa ajili ya mpito full-screen."</string>
+    <string name="permlab_freezeScreen" msgid="4708181184441880175">"fanya skrini isisonge"</string>
+    <string name="permdesc_freezeScreen" msgid="8558923789222670064">"Huruhusu programu kufanya skrini isisonge kwa muda ili kuruhusu kubadilisha hadi skrini nzima."</string>
     <string name="permlab_injectEvents" msgid="1378746584023586600">"bonyeza vitufe na vitufe vya kudhibiti"</string>
     <string name="permdesc_injectEvents" product="tablet" msgid="206352565599968632">"Huruhusu programu kuwasilisha matukio yake ya ingizo (mibonyezo ya vitufe, nk.) kwa programu zingine. programu hasidi zinaweza kutumia hii ili kutawala kompyuta kibao."</string>
     <string name="permdesc_injectEvents" product="default" msgid="653128057572326253">"Inaruhusu programu kuwasilisha matukio yake ya ingizo (mibonyezo ya kitufe, nk.)kwa programu zingine.Programu hasidi zinaweza kutumia hii kutawala simu."</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Inaruhusu kishikiliaji kushurutisha kusano ya kiwango cha juu cha huduma ya Vpn. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"funga kwa mandhari"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Inaruhusu kishikiliaji kushurutisha kwa kusano ya kiwango cha juu cha mandhari. Haipaswi kamwe kuhitajika kwa programu za kawaida."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"fungisha kwenye mwonekano wa mbali"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Huruhusu mtumiaji kujifungia kiolesura cha kiwango cha juu cha mwonekano wa mbali. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"funga kwenye huduma ya widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"endesha programu wakati kifaa hakifanyi kitu"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Ruhusa hii huwezesha mfumo wa Android kuendesha programu chini kwa chini wakati kifaa hakitumiki."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Inaruhusu programu kutumia vipengee vya kiwango cha chini vya SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"soma bafa ya fremu"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Inaruhusu programu kusoma maudhui ya fremu ya bafa."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"fikia InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Inaruhusu programu kutumia vipengele vya chini vya InputFlinger."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"sanidi maonyesho ya Wifi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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">"kurekodi sauti"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Inaruhusu programu kurekodi sauti kwa kinasa sauti. Idhini hii inaruhusu programu kurekodi sauti wakati wowote bila ya uthibitisho wako."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"mawasiliano ya sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Huruhusu programu kutuma amri kwa SIM. Hii ni hatari sana."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"Kupiga picha na kurekodi video"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Inaruhusu programu kupiga picha na video kwa kamera. Kibali hiki kinaruhusu programu kutumia kamera kwa wakati wowote bila uthibitisho wako."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"zima LED ya kisambaza kiashirio wakati kamera inatumika"</string>
@@ -550,8 +563,10 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Inaruhusu programu kudhibiti vipengee vya kifaa. Programu iliyo na ruhusa hii inaweza badilisha mtandao, kuzima na kuwasha redio ya simu bila hata kukujulisha."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"kusoma hali na kitambulisho cha simu"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Inaruhusu programu kufikia vipengele vya simu vya kifaa. Idhini hii inaruhusu programu kutambua nambari ya simu na kifaa, kama simu ni amilifu, na nambari ya mbali iliyounganishwa kwa simu."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"Soma hali sahihi ya simu"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Huruhusu programu kufikia hali sahihi ya simu. Ruhusa hii huwezesha programu kufahamu hali sahihi ya simu, iwapo simu inatumika au iko katika hali ya chini kwa chini, simu inaposhindikana, hali sahihi ya muunganisho wa data na muunganisho wa data unaposhindikana."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"zuia kompyuta ndogo dhidi ya kulala"</string>
-    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"zuia simu dhidi ya kulala"</string>
+    <string name="permlab_wakeLock" product="default" msgid="573480187941496130">"kuzuia simu isilale"</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>
     <string name="permlab_transmitIr" msgid="7545858504238530105">"sambaza infrared"</string>
@@ -674,28 +689,30 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"badilisha urekebishaji wa kifaa cha kuingiza data"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Huruhusu programu kubadilisha vigezo vya urekebishaji vya skrini ya kugusa. Havipaswi kuhitajika kamwe kwa programu za kawaida."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kudhibiti urefu na herufi zinazoruhusiwa katika manenosiri ya kufungua skrini."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Kuhesabu idadi ya mara ambazo skrini inajaribu kufunguliwa"</string>
     <string name="policydesc_watchLogin" product="tablet" msgid="3215729294215070072">"Fuatilia idadi ya manenosiri yasiyo sahihi yatakayoingizwa wakati wa kufungua skrini, na ufunge kompyuta kibao au ufute data yote iliyomo kama manenosiri mengi yenye makosa yataingizwa."</string>
     <string name="policydesc_watchLogin" product="default" msgid="5712323091846761073">"Fuatilia idadi ya manenosiri yasiyo sahihi yatakayoingizwa wakati wa kufungua skrini, na ufunge simu au ufute data yote iliyomo kama manenosiri mengi sana yasiyo sahihi yataingizwa."</string>
-    <string name="policylab_resetPassword" msgid="2620077191242688955">"Badilisha nenosiri la kufungua skrini"</string>
-    <string name="policydesc_resetPassword" msgid="605963962301904458">"Badilisha nenosiri la kufungua skrini."</string>
-    <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_resetPassword" msgid="2620077191242688955">"Kubadilisha nenosiri la kufungua skrini"</string>
+    <string name="policydesc_resetPassword" msgid="605963962301904458">"Kubadilisha nenosiri la kufungua skrini."</string>
+    <string name="policylab_forceLock" msgid="2274085384704248431">"Kufunga skrini"</string>
+    <string name="policydesc_forceLock" msgid="1141797588403827138">"Kudhibiti jinsi na wakati skrini inapofunga."</string>
     <string name="policylab_wipeData" msgid="3910545446758639713">"Kufuta data yote"</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">"Kufuta data ya simu bila ilani kwa kurejesha data ambayo kifaa kilitoka nayo kiwandani"</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>
-    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Dhibiti ni mara ngapi nenosiri la kufunga skrini linafaa libadilishwe."</string>
-    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Weka msimbo fiche wa hifadhi"</string>
-    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Inahitaji kwamba data ya programu iliyohifadhiwa iwe na msimbo fiche."</string>
-    <string name="policylab_disableCamera" msgid="6395301023152297826">"Zima kamera"</string>
-    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Zuia matumizi yote ya kamera za kifaa."</string>
-    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Lemaza vipengele kwenye kilinzi cha kitufe."</string>
-    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Inazuia matumizi ya baadhi ya vipengele kwenye kilinzi cha kitufe."</string>
+    <string name="policylab_setGlobalProxy" msgid="2784828293747791446">"Weka seva mbadala ya ulimwengu kote ya kifaa"</string>
+    <string name="policydesc_setGlobalProxy" msgid="6387497466660154931">"Weka seva mbadala ya ulimwengu kote ya kifaa itakayotumiwa wakati sera iwezeshwa. Msimamizi wa kwanza wa kifaa pekee ndiye anaweza kuweka seva mbadala ya ulimwengu inayofanya kazi."</string>
+    <string name="policylab_expirePassword" msgid="885279151847254056">"Kuweka kipindi cha kutumia nenosiri la kufunga skrini"</string>
+    <string name="policydesc_expirePassword" msgid="1729725226314691591">"Kudhibiti ni mara ngapi nenosiri la kufunga skrini linafaa libadilishwe."</string>
+    <string name="policylab_encryptedStorage" msgid="8901326199909132915">"Kuweka msimbo fiche wa hifadhi"</string>
+    <string name="policydesc_encryptedStorage" msgid="2637732115325316992">"Inahitaji kwamba data iliyohifadhiwa ya programu iwe na msimbo fiche."</string>
+    <string name="policylab_disableCamera" msgid="6395301023152297826">"Kuzima kamera"</string>
+    <string name="policydesc_disableCamera" msgid="2306349042834754597">"Kuzuia matumizi yote ya kamera za kifaa."</string>
+    <string name="policylab_disableKeyguardFeatures" msgid="266329104542638802">"Kuzima vipengele kwenye kilinda vitufe"</string>
+    <string name="policydesc_disableKeyguardFeatures" msgid="3467082272186534614">"Inazuia matumizi ya baadhi ya vipengele kwenye kilinda vitufe."</string>
   <string-array name="phoneTypes">
     <item msgid="8901098336658710359">"Nyumbani"</item>
     <item msgid="869923650527136615">"Simu ya mkononi"</item>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Nyumbani"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Kazi"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Nyinginezo"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Hakuna programu iliyopatikana ili kuona anwani hii."</string>
     <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>
@@ -831,7 +849,7 @@
     <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Jaribu tena"</string>
     <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Majaribio ya Juu ya Kufungua Uso yamezidishwa"</string>
     <string name="lockscreen_plugged_in" msgid="8057762828355572315">"Inachaji <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
-    <string name="lockscreen_charged" msgid="321635745684060624">"Imechajiwa"</string>
+    <string name="lockscreen_charged" msgid="321635745684060624">"Betri imejaa"</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">"Unganisha chaja yako"</string>
     <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Hakuna SIM kadi"</string>
@@ -879,8 +897,8 @@
     <string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Ruwaza imefutwa"</string>
     <string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Kiini kimeongezwa"</string>
     <string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Ruwaza imekamilika"</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_changed" msgid="5678624624681400191">"%1$s. Wijeti %2$d ya %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wijeti."</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>
@@ -889,7 +907,7 @@
     <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_start" msgid="8736853615588828197">"Upangaji upya wa wijeti 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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Ingiliana na sasisho na mfumo wa kurejesha"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Huruhusu programu kuingiliana na mfumo wa kurejesha na sasisho la mfumo."</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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"Songa"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Enter"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Chagua programu"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Haikuweza kuzindua <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Shiriki na"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Shiriki na <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Utambo unaosonga. Gusa &amp; shika"</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="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_target_unlock_tablet" msgid="3833195335629795055">"Pitisha ili kufungua."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Chomeka kifaa cha sauti ili kusikiliza vibonye vya nenosiri vikizungumzwa."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nukta."</string>
@@ -1483,8 +1495,12 @@
     <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">"Nimemaliza"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Towe la midia"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Unganisha kwenye kifaa"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Tuma skrini kwenye kifaa"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Inatafuta vifaa..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Mipangilio"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Ondoa"</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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Inatuma skrini"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Inaunganishwa na <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Inatuma skrini"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Imeungwanishwa na <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Tenganisha"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Msimbo wa PUK lazima uwe na tarakimu 8."</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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Telezesha kidole kwa kasi chini kuanzia juu ili uondoke kwenye skrini kamili"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Telezesha kidole kwa kasi chini kuanzia juu ili uondoke kwenye skrini zima."</string>
+    <string name="done_label" msgid="2093726099505892398">"Imekamilika"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Kitelezi cha mviringo wa saa"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Kitelezi cha mviringo wa dakika"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Chagua saa"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Chagua dakika"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Gridi ya mwezi ya siku"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Orodha ya miaka"</string>
+    <string name="select_day" msgid="7774759604701773332">"Chagua mwezi na siku"</string>
+    <string name="select_year" msgid="7952052866994196170">"Chagua mwaka"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> kimechaguliwa"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> kimefutwa"</string>
 </resources>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index d21f9b7..8f83ab2 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -22,6 +22,10 @@
     <dimen name="thumbnail_width">200dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
     <dimen name="thumbnail_height">177dp</dimen>
+    <!-- The width that is used when creating thumbnails of applications. -->
+    <dimen name="recents_thumbnail_width">512dp</dimen>
+    <!-- The height that is used when creating thumbnails of applications. -->
+    <dimen name="recents_thumbnail_height">512dp</dimen>
     <!-- The maximum number of action buttons that should be permitted within
          an action bar/action mode. This will be used to determine how many
          showAsAction="ifRoom" items can fit. "always" items can override this. -->
diff --git a/core/res/res/values-sw720dp/dimens.xml b/core/res/res/values-sw720dp/dimens.xml
index ccdb4be..040bb5b 100644
--- a/core/res/res/values-sw720dp/dimens.xml
+++ b/core/res/res/values-sw720dp/dimens.xml
@@ -38,6 +38,10 @@
     <dimen name="thumbnail_width">230dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
     <dimen name="thumbnail_height">135dp</dimen>
+    <!-- The width that is used when creating thumbnails of applications. -->
+    <dimen name="recents_thumbnail_width">512dp</dimen>
+    <!-- The height that is used when creating thumbnails of applications. -->
+    <dimen name="recents_thumbnail_height">512dp</dimen>
 
     <!-- Preference activity, vertical padding for the header list -->
     <dimen name="preference_screen_header_vertical_padding">32dp</dimen>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 58f5268..305036d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"พิมพ์รหัส PUK ซึ่งต้องเป็นตัวเลขอย่างน้อย 8 หลัก"</string>
     <string name="needPuk" msgid="919668385956251611">"ซิมการ์ดของคุณถูกล็อกด้วย PUK พิมพ์รหัส PUK เพื่อปลดล็อก"</string>
     <string name="needPuk2" msgid="4526033371987193070">"พิมพ์ PUK2 เพื่อยกเลิกการปิดกั้นซิมการ์ด"</string>
+    <string name="enablePin" msgid="209412020907207950">"ไม่สำเร็จ เปิดใช้การล็อกซิม/RUIM"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"คุณพยายามได้อีก <xliff:g id="NUMBER">%d</xliff:g> ครั้งก่อนที่ซิมจะถูกล็อก"</item>
+    <item quantity="other" msgid="7530597808358774740">"คุณพยายามได้อีก <xliff:g id="NUMBER">%d</xliff:g> ครั้งก่อนที่ซิมจะถูกล็อก"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"หมายเลขผู้โทรเข้า"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ถอนการติดตั้งทางลัด"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"อนุญาตให้แอปพลิเคชันลบทางลัดหน้าจอหลักโดยไม่ต้องให้ผู้ใช้จัดการ"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"จัดเส้นทางการโทรออกใหม่"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"อนุญาตให้แอปพลิเคชันประมวลผลการโทรออกและเปลี่ยนแปลงหมายเลขที่จะโทรไป การอนุญาตนี้จะทำให้แอปพลิเคชันสามารถตรวจสอบ เปลี่ยนเส้นทาง หรือกีดขวางไม่ให้โทรออกได้"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"อนุญาตให้แอปดูหมายเลขที่โทรในระหว่างการโทรออกโดยสามารถเลือกเปลี่ยนเส้นทางการโทรไปยังหมายเลขอื่นหรือยกเลิกการโทรไปเลยได้"</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"ผูกกับจอแสดงผลระยะไกล"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"อนุญาตให้ผู้ใช้ผูกกับอินเทอร์เฟซระดับสูงสุดของจอแสดงผลระยะไกล ซึ่งแอปพลิเคชันทั่วไปไม่จำเป็นต้องใช้"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"เชื่อมโยงกับบริการวิดเจ็ต"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"อนุญาตให้ผู้ใช้เชื่อมโยงกับส่วนติดต่อผู้ใช้ระดับสูงสุดของบริการวิดเจ็ต ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"ติดต่อกับผู้ดูแลอุปกรณ์"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"เรียกใช้แอปพลิเคชันในระหว่างที่ไม่ได้ใช้งาน"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"สิทธิ์นี้ช่วยให้ระบบแอนดรอยด์สามารถเรียกใช้แอปพลิเคชันในพื้นหลังขณะไม่ได้ใช้งานอุปกรณ์อยู่"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"อ่าน/เขียนไปยังรีซอร์สที่เป็นเจ้าของโดยกลุ่มวินิจฉัย"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"อนุญาตให้แอปพลิเคชันอ่านและเขียนไปยังทรัพยากรที่เป็นของกลุ่มวินิจฉัย เช่น ไฟล์ใน /dev การทำเช่นนี้อาจส่งผลต่อความเสถียรและความปลอดภัยของระบบ และควรใช้สำหรับการวินิจฉัยเกี่ยวกับฮาร์ดแวร์โดยเฉพาะที่ทำโดยผู้ผลิตหรือผู้ให้บริการเท่านั้น"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"เปิดหรือปิดใช้งานคอมโพเนนต์ของแอปพลิเคชัน"</string>
@@ -477,6 +486,8 @@
     <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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"อนุญาตให้แอปพลิเคชันปรับเปลี่ยนการตั้งค่าเสียงทั้งหมดได้ เช่น ระดับเสียงและลำโพงที่จะใช้งาน"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"บันทึกเสียง"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"อนุญาตให้แอปพลิเคชันบันทึกเสียงด้วยไมโครโฟน การอนุญาตนี้ทำให้แอปพลิเคชันสามารถบันทึกเสียงได้ทุกเมื่อโดยไม่ต้องรอการยืนยันจากคุณ"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"การสื่อสารกับ SIM"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"อนุญาตให้แอปส่งคำสั่งไปยัง SIM ซึ่งอันตรายมาก"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"ถ่ายภาพและวิดีโอ"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"อนุญาตให้แอปพลิเคชันถ่ายภาพและวิดีโอด้วยกล้องถ่ายรูปนี้ การอนุญาตนี้จะทำให้แอปพลิเคชันสามารถใช้กล้องถ่ายรูปได้ทุกเมื่อโดยไม่ต้องรอการยืนยันจากคุณ"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"ปิดไฟสัญญาณ LED เมื่อใช้งานกล้อง"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"อนุญาตให้แอปพลิชันควบคุมคุณลักษณะโทรศัพท์ของอุปกรณ์ แอปพลิเคชันที่ได้รับอนุญาตจะสามารถสลับเครือข่าย เปิดและปิดวิทยุในโทรศัพท์ และคุณลักษณะอื่นที่คล้ายกันนี้ได้โดยไม่ต้องแจ้งให้คุณทราบ"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"อ่านสถานะและข้อมูลระบุตัวตนของโทรศัพท์"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"อนุญาตให้แอปพลิเคชันเข้าถึงคุณลักษณะโทรศัพท์ของอุปกรณ์ การอนุญาตนี้ทำให้แอปพลิเคชันสามารถตรวจสอบหมายเลขโทรศัพท์และรหัสอุปกรณ์ ตรวจสอบว่ามีการโทรที่ทำงานอยู่หรือไม่ และตรวจสอบหมายเลขระยะไกลที่เชื่อมต่อด้วยการโทร"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"อ่านสถานะที่แม่นยำของโทรศัพท์"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"ช่วยให้แอปสามารถเข้าถึงสถานะที่แม่นยำของโทรศัพท์ สิทธิ์นี้ช่วยให้แอปสามารถทราบถึงสถานะการโทรที่แท้จริงว่ากำลังมีการโทรอยู่หรือการโทรในพื้นหลัง การโทรล้มเหลว สถานะการเชื่อมต่อข้อมูลที่แม่นยำและการเชื่อมต่อข้อมูลล้มเหลว"</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"อนุญาตให้ผู้ใช้สามารถเรียกใช้แอปการกำหนดค่าของผู้ให้บริการ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"อนุญาตให้แอปพลิเคชันฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย ไม่จำเป็นสำหรับแอปปกติ"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"เปลี่ยนการเทียบมาตรฐานอุปกรณ์อินพุต"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"อนุญาตให้แอปสามารถปรับพารามิเตอร์การเทียบมาตรฐานของหน้าจอสัมผัส ไม่ควรใช้สำหรับแอปทั่วไป"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"หน้าแรก"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"ที่ทำงาน"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"อื่นๆ"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"ไม่พบแอปพลิเคชันที่ใช้ดูที่อยู่ติดต่อนี้"</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"โต้ตอบกับการอัปเดตและระบบการกู้คืน"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"ช่วยให้แอปพลิเคชันสามารถโต้ตอบกับระบบการกู้คืนและการอัปเดตระบบ"</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>
@@ -1345,7 +1365,7 @@
     <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="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>
@@ -1414,18 +1434,10 @@
     <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="activitychooserview_choose_application_error" msgid="8624618365481126668">"ไม่สามารถเปิด <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"แบ่งปันกับ"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"แบ่งปันด้วย <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"ที่จับสำหรับเลื่อน แตะค้างไว้"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"เชื่อมต่อกับอุปกรณ์"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"ส่งหน้าจอไปยังอุปกรณ์"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"กำลังค้นหาอุปกรณ์…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"การตั้งค่า"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"ยกเลิกการเชื่อมต่อ"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"กำลังสแกน..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"กำลังเชื่อมต่อ..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"พร้อมใช้งาน"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"กำลังส่งหน้าจอ"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"กำลังเชื่อมต่อไปยัง <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"กำลังส่งหน้าจอ"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"เชื่อมต่อกับ <xliff:g id="NAME">%1$s</xliff:g> แล้ว"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"รหัส PUK ต้องเป็นตัวเลข 8 หลัก"</string>
     <string name="kg_invalid_puk" msgid="3638289409676051243">"ใส่รหัส PUK ที่ถูกต้องอีกครั้ง การพยายามซ้ำหลายครั้งจะทำให้ซิมการ์ดถูกปิดใช้งานอย่างถาวร"</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"รหัส PIN ไม่ตรง"</string>
     <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ลองหลายรูปแบบมากเกินไป"</string>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"กวาดนิ้วจากบนลงล่างเพื่อออกจากโหมดเต็มหน้าจอ"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"กวาดนิ้วบนลงล่างเพื่อออกจากโหมดเต็มหน้าจอ"</string>
+    <string name="done_label" msgid="2093726099505892398">"เสร็จสิ้น"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"ตัวเลื่อนหมุนระบุชั่วโมง"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"ตัวเลื่อนหมุนระบุนาที"</string>
+    <string name="select_hours" msgid="6043079511766008245">"เลือกชั่วโมง"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"เลือกนาที"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"ตารางเดือนของวัน"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"รายการปี"</string>
+    <string name="select_day" msgid="7774759604701773332">"เลือกเดือนและวัน"</string>
+    <string name="select_year" msgid="7952052866994196170">"เลือกปี"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"เลือก <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"ลบ <xliff:g id="KEY">%1$s</xliff:g> แล้ว"</string>
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index bc396ed..ec73999 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Mag-type ng PUK na may 8 numbero o mas mahaba."</string>
     <string name="needPuk" msgid="919668385956251611">"Na-PUK-lock ang iyong SIM card. I-type ang PUK code upang i-unlock ito."</string>
     <string name="needPuk2" msgid="4526033371987193070">"I-type ang PUK2 upang i-unblock ang SIM card."</string>
+    <string name="enablePin" msgid="209412020907207950">"Hindi matagumpay, i-enable ang SIM/RUIM Lock."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Mayroon kang <xliff:g id="NUMBER">%d</xliff:g> (na) natitirang pagsubok bago ma-lock ang SIM."</item>
+    <item quantity="other" msgid="7530597808358774740">"Mayroon kang <xliff:g id="NUMBER">%d</xliff:g> (na) natitirang pagsubok bago ma-lock ang SIM."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Papasok na Caller ID"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"i-uninstall ang mga shortcut"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Pinapayagan ang application na alisin ang mga shortcut ng Homescreen nang walang panghihimasok ng user."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"baguhin ang ruta ng mga papalabas na tawag"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Pinapayagan ang app na magproseso ng mga papalabas na tawag at baguhin ang numerong ida-dial. Pinapayagan ng pahintulot na ito ang app na sumubaybay, mag-redirect, o pumigil ng mga papalabas na tawag."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Pinapayagan ang app na makita ang numerong idina-dial sa isang papalabas na tawag na may opsyon na i-redirect ang tawag sa ibang numero o itigil ang tawag nang tuluyan."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"tumanggap ng mga text message (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Pinapayagan ang app na tumanggap at magproseso ng mga mensaheng SMS. Nangangahulugan ito na maaaring sumubaybay o magtanggal ang app ng mga mensaheng ipinapadala sa iyong device nang hindi ipinapakita ang mga ito sa iyo."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"tumanggap ng mga text message (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Pinapayagan ang may-hawak na sumailalim sa nangungunang interface ng serbisyo ng Vpn. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"sumailalim sa wallpaper"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Pinapayagan ang may-hawak na sumailalim sa nangungunang interface ng isang wallpaper. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"magpasaklaw sa isang remote na display"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Binibigyang-daan ang may-hawak na masaklaw ang pinakamataas na antas ng interface ng isang remote na display. Hindi dapat kailanman kailanganin ng normal na apps."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"itali sa serbisyo ng widget"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"paganahin ang application habang idle"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Nagbibigay-daan ang pahintulot na ito sa Android system na paganahin ang application sa background habang hindi ginagamit ang device."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Pinapayagan ang app na gamitin ang mababang antas na mga tampok ng SurfaceFlinger."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"basahin ang buffer ng frame"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Pinapayagan ang app na basahin ang nilalaman ng buffer ng frame."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"i-access ang InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Nagbibigay-daan sa app na gumamit ng mga tampok ng InputFlinger sa mababang antas."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"mag-configure ng mga Wifi display"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Pinapayagan ang app na mag-record ng audio gamit ang mikropono. Pinapayagan ng pahintulot na ito ang app na mag-record ng audio anumang oras nang wala ng iyong kumpirmasyon."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"pag-uusap sa sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Pinapahintulutang magpadala ang app ng mga command sa SIM. Napakapanganib nito."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"kumuha ng mga larawan at video"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Pinapayagan ang app na kumuha ng mga larawan at video gamit ang camera. Pinapayagan ng pahintulot na ito ang app na gamitin ang camera anumang oras nang wala ng iyong kumpirmasyon."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"i-disable ang LED na tagapagpahiwatig kapag ginagamit ang camera"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Pinapayagan ang app na kontrolin ang mga tampok ng telepono ng device. Maaaring lumipat ng mga network ang isang app na mayroong ganitong pahintulot, i-on o i-off ang radyo ng telepono at mga kaparehong bagay nang hindi ka nano-notify."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"basahin ang katayuan at pagkakakilanlan ng telepono"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Pinapayagan ang app na i-access ang mga tampok ng telepono ng device. Pinapayagan ng pahintulot na ito ang app na tukuyin ang numero ng telepono at  mga ID ng device, kung aktibo man ang isang tawag, at ang malayuang numerong ikinonekta ng isang tawag."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"basahin ang tiyak na katayuan ng telepono"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Binibigyang-daan ang app na ma-access ang tumpak na katayuan ng telepono. Nagbibigay-daan ang pahintulot na ito sa app na matukoy ang tunay na status ng tawag, kung aktibo ang isang tawag o nasa background, mga hindi natuloy na tawag, tumpak na status ng koneksyon sa data at hindi natuloy na pagkonekta sa data."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"pigilan ang tablet mula sa pag-sleep"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"baguhin ang pag-calibrate ng input device"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Pinapayagan ang app na baguhin ang mga parameter sa pag-calibrate ng touch screen. Hindi dapat kailanganin 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Home"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Trabaho"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Iba pa"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Walang nakitang application upang matingnan ang contact na ito."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Makipag-ugnay sa system ng pag-update at pagbawi"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Binibigyang-daan ang isang application na makipag-ugnay sa system ng pagbawi at mga pag-update ng system."</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>
@@ -1414,18 +1434,10 @@
     <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">"Pumili ng isang app"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Hindi mailunsad ang <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Ibahagi sa"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Ibahagi sa <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Hawakan sa pag-slide. Pindutin nang matagal."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Mag-swipe upang i-unlock."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Mag-plug in ng isang headset upang marinig ang mga password key na binabanggit."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dot."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio sa Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Wireless display"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tapos na"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Output ng media"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Kumonekta sa device"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"I-cast ang screen sa device"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Naghahanap ng mga device…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Mga Setting"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Idiskonekta"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Nagsa-scan..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Kumukonekta..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Available"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Kina-cast ang screen"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Kumokonekta sa <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Kina-cast ang screen"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Nakakonekta sa <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Alisin sa pagkakakonekta"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"8 numero dapat 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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Mag-swipe pababa upang lumabas sa full screen"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Mag-swipe pababa mula sa itaas upang lumabas sa full screen."</string>
+    <string name="done_label" msgid="2093726099505892398">"Tapos na"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Pabilog na slider ng mga oras"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Pabilog na slider ng mga minuto"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Pumili ng mga oras"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Pumili ng mga minuto"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Grid ng mga araw ayon sa buwan"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Listahan ng taon"</string>
+    <string name="select_day" msgid="7774759604701773332">"Pumili ng buwan at araw"</string>
+    <string name="select_year" msgid="7952052866994196170">"Pumili ng taon"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Napili ang <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Tinanggal ang <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 99a137b..902939e 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"8 veya daha uzun basamaklı bir PUK kodu yazın."</string>
     <string name="needPuk" msgid="919668385956251611">"SIM kartınızın PUK kilidi devrede. Kilidi açmak için PUK kodunu yazın."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Engellenen SIM kartı açmak için PUK2 kodunu yazın."</string>
+    <string name="enablePin" msgid="209412020907207950">"Başarısız. SIM/RUIM Kilidini etkinleştirin."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"SIM kilitlenmeden önce <xliff:g id="NUMBER">%d</xliff:g> deneme hakkınız kaldı."</item>
+    <item quantity="other" msgid="7530597808358774740">"SIM kilitlenmeden önce <xliff:g id="NUMBER">%d</xliff:g> deneme hakkınız kaldı."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Gelen Çağrı Kimliği"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"kısayolların yüklemesini kaldırma"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Uygulamaya, kullanıcının müdahalesi olmadan kısayolları Ana Ekrandan kaldırma izni verir."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"giden çağrıları yeniden yönlendir"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Uygulamaya, yapılan çağrıları işleme ve aranacak numarayı değiştirme izni verir. Bu izin, uygulamanın yapılan çağrıları izlemesine, yönlendirmesine ve önlemesine olanak sağlar."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Uygulamaya, giden bir çağrının numarası çevrilirken çağrıyı farklı bir numaraya yönlendirme ya da tamamen kapatma seçeneğiyle birlikte numarayı görme izni verir."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"kısa mesajları al (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Uygulamaya SMS mesajlarını alma ve işleme izni verir. Bu izin, uygulamanın cihazınıza gönderilen mesajları takip edip size göstermeden silebileceği anlamına gelir."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"kısa mesajları (MMS) al"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"Cihazın sahibine bir VPN hizmetinin en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"bir duvar kağıdına tabi kıl"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Cihazın sahibine, duvar kağıdının en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"uzak ekrana bağlan"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"İzin sahibine, bir uzak ekranın en üst düzey arayüzüne bağlanma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"bir widget hizmetine bağla"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"boşta kaldığında uygulamayı çalıştır"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Bu izin, cihaz kullanımda değilken Android sistemin uygulamayı arka planda çalıştırmasına olanak sağlar."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Uygulamaya, SurfaceFlinger\'a ait düşük düzey özellikleri kullanma izni verir."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"çerçeve arabelleğini oku"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Uygulamaya, çerçeve arabelleğinin içeriğini okuma izni verir."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger\'a eriş"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Uygulamaya, alt düzey InputFlinger özelliklerini kullanma izni verir."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Kablosuz ekranları yapılandır"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Uygulamaya mikrofonla ses kaydetme izni verir. Bu izin, uygulamanın istediği zaman onayınız olmadan ses kaydetmesine olanak sağlar."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"sim iletişimi"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Uygulamanın SIM karta komut göndermesine izin verir. Bu izin çok tehlikelidir."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"resim çekme ve görüntü kaydetme"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Uygulamaya kamerayla fotoğraf ve video çekme izni verir. Bu izin, uygulamanın sizin onayınız olmadan istediği zaman kamerayı kullanmasına olanak sağlar."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"Kamera kullanımda iken iletim göstergesi LED\'ini devre dışı bırak"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Uygulamaya, cihazın telefon özelliklerini kontrol etme izni verir. Bu izne sahip bir uygulama sizi hiç uyarmadan ağlar arasında geçiş, telefonun radyosunu açıp kapatma ve benzeri işlemler yapabilir."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"telefonun durumunu ve kimliğini okuma"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Uygulamaya cihazdaki telefon özelliklerine erişme izni verir. Bu izin, uygulamanın telefon numarasını ve cihaz kimliğini, etkin bir çağrı olup olmadığını ve çağrıda bağlanılan karşı tarafın numarasını öğrenmesine olanak sağlar."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"telefon durum bilgilerini hassas bir şekilde oku"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Uygulamanın, telefonun durum bilgilerine hassas bir şekilde erişmesine izin verir. Bu izin sayesinde uygulama, gerçek çağrı durumunu, çağrının aktif mi yoksa arka planda mı olduğunu, çağrının başarısız olup olmadığını, veri bağlantısı durumuyla ilgili hassas bilgileri ve veri bağlantısının başarısız olup olmadığını belirleyebilir."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"tabletin uykuya geçmesini önle"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"giriş cihazı kalibrasyonunu değiştir"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Uygulamaya, dokunmatik ekranın kalibrasyon parametrelerini değiştirme 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Ev"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"İş"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Diğer"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Bu kişiyi görüntüleyecek uygulama bulunamadı."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Güncelleme ve kurtarma sistemiyle etkileşim kur"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Bir uygulamaya, kurtarma sistemi ve sistem güncellemeriyle etkileşim kurma 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>
@@ -1414,18 +1434,10 @@
     <string name="keyboardview_keycode_shift" msgid="2270748814315147690">"ÜstKrkt"</string>
     <string name="keyboardview_keycode_enter" msgid="2985864015076059467">"Giriş"</string>
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Bir uygulama seçin"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> başlatılamadı"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Şununla paylaş:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"<xliff:g id="APPLICATION_NAME">%s</xliff:g> ile paylaş"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Kayan tutma yeri. Dokunun ve basılı tutun."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Kilidi açmak için kaydırın."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Şifre tuşlarının sesli okunmasını dinlemek için mikrofonlu kulaklık takın."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Nokta."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ses"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Kablosuz ekran"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tamamlandı"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Medya çıkışı"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Cihaza bağlanın"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Ekranı cihaza yayınlayın"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Cihaz aranıyor…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Ayarlar"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Bağlantıyı kes"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Taranıyor..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Bağlanılıyor..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Kullanılabilir"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Ekran yayınlanıyor"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"<xliff:g id="NAME">%1$s</xliff:g> bağlantısı yapılıyor"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Ekran yayınlanıyor"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"<xliff:g id="NAME">%1$s</xliff:g> bağlantısı yapıldı"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Bağlantıyı kes"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"PUK kodu 8 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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Tam ekrandan çıkmak için aşağıya hızlıca kaydırın"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Tam ekrandan çıkmak için yukarıdan aşağıya hızlıca kaydırın."</string>
+    <string name="done_label" msgid="2093726099505892398">"Bitti"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Saat kaydırma çemberi"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Dakika kaydırma çemberi"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Saati seçin"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Dakikayı seçin"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Ayın günleri tablosu"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Yıl listesi"</string>
+    <string name="select_day" msgid="7774759604701773332">"Ayı ve günü seçin"</string>
+    <string name="select_year" msgid="7952052866994196170">"Yılı seçin"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seçildi"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> silindi"</string>
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 61f45ec..fb96ca0 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"Помилка. Увімкніть блокування SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"У вас залишилась <xliff:g id="NUMBER">%d</xliff:g> спроба. Після цього SIM-карту буде заблоковано."</item>
+    <item quantity="other" msgid="7530597808358774740">"У вас залишилося стільки спроб: <xliff:g id="NUMBER">%d</xliff:g>. Після цього SIM-карту буде заблоковано."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Вхідн. ід. абонента"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"видаляти ярлики"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Дозволяє програмі самостійно вилучати ярлики з головного екрана."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"переадресовувати вихідні виклики"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Дозволяє програмі обробляти вихідні дзвінки та змінювати номер для виклику. Такий дозвіл дає програмі змогу відстежувати, переадресовувати чи блокувати вихідні дзвінки."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Дозволяє додатку читати номер вихідного дзвінка, переспрямовувати дзвінок на інший номер або переривати його."</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>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"прив’язуватися до віддаленого екрана"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня віддаленого екрана. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"прив\'язувати до служби віджетів"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"Дозволяє власникові прив’язуватися до інтерфейсу верхнього рівня служби віджетів. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"взаємодіяти з адмін. пристрою"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"запускати додаток, коли пристрій неактивний"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Маючи цей дозвіл, система Android може запускати додаток у фоновому режимі, коли пристрій не використовується."</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"чит./зап. на ресури., якими вол. діаг."</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"Дозволяє програмі читати та писати на будь-який ресурс, яким володіє діагностична група; наприклад, у файли в папці /dev. Це потенційно може вплинути на стабільність і безпеку системи. Потрібно використовувати ЛИШЕ для певної діагностики обладнання, яку виконує виробник чи оператор."</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"вмикати чи вимикати компоненти програми"</string>
@@ -477,6 +486,8 @@
     <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">"налаштувати екрани Wi-Fi"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Дозволяє програмі налаштовувати екрани Wi-Fi і під’єднуватися до них."</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"керувати екранами Wi-Fi"</string>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Дозволяє програмі змінювати загальні налаштування звуку, як-от гучність і динамік, який використовується для виводу сигналу."</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"запис-ти аудіо"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Дозволяє програмі записувати звук за допомогою мікрофона. Такий дозвіл дає програмі змогу будь-коли записувати звук без вашого підтвердження."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"комунікація із SIM-картою"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Дозволяє програмі надсилати команди на SIM-карту. Це дуже небезпечно."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"фотограф. та знімати відео"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Дозволяє програмі фотографувати та знімати відео за допомогою камери. Такий дозвіл дає програмі змогу будь-коли використовувати камеру без вашого підтвердження."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"вимикати світлодіодний індикатор передавання, коли використовується камера"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Дозволяє програмі контролювати телефонні функції пристрою. Програма з цим дозволом може переключати мережі, вмикати та вимикати радіо в телефоні тощо без вашого відома."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"читати статус та ідентифікаційну інформацію телефону"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Дозволяє програмі отримувати доступ до телефонних функцій пристрою. Такий дозвіл дає програмі змогу визначати номер телефону й ідентифікатори пристрою, активність виклику, а також віддалений номер, на який здійснюється виклик."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"читати точні статуси телефону"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Дозволяє додатку отримувати доступ до статусів телефону. Цей дозвіл дає додатку змогу визначати статус виклику (активний чи у фоновому режимі), помилки викликів, точний статус передавання даних і помилки передавання даних."</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозволяє власнику викликати надану оператором програму конфігурації. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"прослуховувати дані спостережень за станом мережі"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозволяє програмі прослуховувати дані спостережень за станом мережі. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"змінювати калібрування пристрою введення"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Програма може змінювати параметри калібрування сенсорного екрана. Ніколи не застосовується для звичайних програм."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Головна"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Робоча"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Інша"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Не знайдено програму для перегляду цього контакта."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Взаємодіяти з оновленнями системи та системою відновлення."</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Дозволяє додатку взаємодіяти із системою відновлення й оновленнями системи."</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"Не вдалося запустити програму <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Надіслати через"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Надіслати через <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Вказівник-повзунок. Торкніться й утримуйте."</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"Під’єднатися до пристрою"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Транслювати екран на пристрій"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Пошук пристроїв…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Налаштування"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Від’єднатися"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Сканування..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"З’єднання..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Доступно"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Транслювання екрана"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"<xliff:g id="NAME">%1$s</xliff:g> – під’єднання"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Транслювання екрана"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"<xliff:g id="NAME">%1$s</xliff:g> – під’єднано"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Спробуйте пізніше"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Проведіть пальцем зверху вниз, щоб вийти з повноекранного режиму."</string>
+    <string name="done_label" msgid="2093726099505892398">"Готово"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Вибір годин на циферблаті"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Вибір хвилин на циферблаті"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Виберіть години"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Виберіть хвилини"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Вікно вибору дати"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Меню вибору року"</string>
+    <string name="select_day" msgid="7774759604701773332">"Виберіть місяць і день"</string>
+    <string name="select_year" msgid="7952052866994196170">"Виберіть рік"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Вибрано: <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> видалено"</string>
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 82752b7..60b97c3 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Nhập PUK có từ 8 số trở lên."</string>
     <string name="needPuk" msgid="919668385956251611">"Thẻ SIM của bạn đã bị khóa PUK. Nhập mã PUK để mở khóa thẻ SIM đó."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Nhập mã PUK2 để bỏ chặn thẻ SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Không thành công, kích hoạt tính năng khóa SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Bạn còn <xliff:g id="NUMBER">%d</xliff:g> lần thử trước khi SIM bị khóa."</item>
+    <item quantity="other" msgid="7530597808358774740">"Bạn còn <xliff:g id="NUMBER">%d</xliff:g> lần thử trước khi SIM bị khóa."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"Số gọi đến"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"gỡ cài đặt lối tắt"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Cho phép ứng dụng xóa lối tắt trên Màn hình chính mà không cần sự can thiệp của người dùng."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"định tuyến lại cuộc gọi đi"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"Cho phép ứng dụng xử lý cuộc gọi đi và thay đổi số được gọi. Quyền này cho phép ứng dụng theo dõi, chuyển hướng hoặc chặn cuộc gọi đi."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Cho phép ứng dụng xem số được gọi trong một cuộc gọi đi với tùy chọn chuyển hướng cuộc gọi đến một số khác hoặc hủy cuộc gọi đó hoàn toàn."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"nhận tin nhắn văn bản (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Cho phép ứng dụng nhận và xử lý tin nhắn SMS. Điều này có nghĩa là ứng dụng có thể theo dõi hoặc xóa tin nhắn được gửi đến thiết bị của bạn mà không hiển thị chúng cho bạn."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"nhận tin nhắn văn bản (MMS)"</string>
@@ -377,6 +382,8 @@
     <string name="permdesc_bindVpnService" msgid="2067845564581693905">"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ụ Vpn. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindWallpaper" msgid="8716400279937856462">"liên kết với hình nền"</string>
     <string name="permdesc_bindWallpaper" msgid="7108428692595491668">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của hình nền. Không cần thiết cho các ứng dụng thông thường."</string>
+    <string name="permlab_bindRemoteDisplay" msgid="1782923938029941960">"liên kết với màn hình từ xa"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Cho phép chủ sở hữu liên kết với giao diện cấp cao nhất của màn hình từ xa. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"liên kết với dịch vụ tiện ích con"</string>
     <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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"chạy ứng dụng trong thời gian rảnh"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Quyền này cho phép hệ thống Android chạy ứng dụng trong nền khi thiết bị không được sử dụng."</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>
@@ -477,6 +486,8 @@
     <string name="permdesc_accessSurfaceFlinger" msgid="1041619516733293551">"Cho phép ứng dụng sử dụng các tính năng SurfaceFlinger cấp độ thấp."</string>
     <string name="permlab_readFrameBuffer" msgid="6690504248178498136">"đọc bộ đệm khung"</string>
     <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"Cho phép ứng dụng đọc nội dung của bộ đệm khung."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"truy cập InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Cho phép ứng dụng sử dụng các tính năng InputFlinger cấp độ thấp."</string>
     <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"định cấu hình màn hình Wi-Fi"</string>
     <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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Cho phép ứng dụng ghi âm bằng micrô. Quyền này cho phép ứng dụng ghi âm bất kỳ lúc nào mà không cần sự xác nhận của bạn."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"liên lạc qua sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Cho phép ứng dụng gửi lệnh đến SIM. Việc này rất nguy hiểm."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"chụp ảnh và quay video"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Cho phép ứng dụng chụp ảnh và quay video bằng máy ảnh. Quyền này cho phép ứng dụng sử dụng máy ảnh bất kỳ lúc nào mà không cần sự xác nhận của bạn."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"vô hiệu hóa tính năng phát đèn LED chỉ báo khi máy ảnh đang được sử dụng"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"Cho phép ứng dụng kiểm soát các tính năng điện thoại của thiết bị. Ứng dụng có quyền này có thể chuyển đổi mạng, bật và tắt radio điện thoại cũng như thực hiện các tác vụ tương tự mà không cần thông báo cho bạn."</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"đọc trạng thái và nhận dạng của điện thoại"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"Cho phép ứng dụng truy cập vào các tính năng điện thoại của thiết bị. Quyền này cho phép ứng dụng xác định số điện thoại và ID thiết bị, cho dù cuộc gọi có hiện hoạt hay không và số từ xa có được kết nối bằng một cuộc gọi hay không."</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"đọc trạng thái điện thoại chính xác"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Cho phép ứng dụng truy cập trạng thái điện thoại chính xác. Quyền này cho phép ứng dụng xác định trạng thái cuộc gọi thực, cuộc gọi đang hoạt động hay trong nền, cuộc gọi không thành công, trạng thái kết nối dữ liệu chính xác và kết nối dữ liệu không thành công."</string>
     <string name="permlab_wakeLock" product="tablet" msgid="1531731435011495015">"ngăn máy tính bảng chuyển sang chế độ ngủ"</string>
     <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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"thay đổi hiệu chỉnh thiết bị đầu vào"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Cho phép ứng dụng sửa đổi các thông số hiệu chỉnh của màn hình cảm ứng. Không 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Nhà riêng"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Cơ quan"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Khác"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Không tìm thấy ứng dụng nào để xem liên hệ này."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Tương tác với hệ thống khôi phục và bản cập nhật"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Cho phép ứng dụng tương tác với hệ thống khôi phục và bản cập nhật hệ thống."</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>
@@ -1414,18 +1434,10 @@
     <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">"Chọn một ứng dụng"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Không thể khởi chạy <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Chia sẻ với"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Chia sẻ với <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Tay trượt. Chạm &amp; giữ."</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="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_target_unlock_tablet" msgid="3833195335629795055">"Trượt để mở khóa."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Cắm tai nghe để nghe các khóa mật khẩu được đọc."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Dấu chấm."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Hệ thống"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Âm thanh Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Hiển thị không dây"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Xong"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Đầu ra phương tiện"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Kết nối với thiết bị"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Truyền màn hình tới thiết bị"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Đang tìm kiếm thiết bị…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Cài đặt"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Ngắt kết nối"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Đang quét..."</string>
     <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>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Truyền màn hình"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Đang kết nối với <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Truyền màn hình"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Đã kết nối với <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Ngắt kết nối"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Mã PUK phải có 8 số."</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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"Vuốt từ trên xuống để thoát toàn màn hình"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Vuốt từ trên xuống để thoát toàn màn hình."</string>
+    <string name="done_label" msgid="2093726099505892398">"Xong"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Thanh trượt giờ hình tròn"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Thanh trượt phút hình tròn"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Chọn giờ"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Chọn phút"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Lưới ngày theo tháng"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Danh sách năm"</string>
+    <string name="select_day" msgid="7774759604701773332">"Chọn tháng và ngày"</string>
+    <string name="select_year" msgid="7952052866994196170">"Chọn năm"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"Đã chọn <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"Đã xóa <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index dbfd039..1b775e8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"失败,请启用 SIM/RUIM 卡锁定设置。"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"您还有<xliff:g id="NUMBER">%d</xliff:g>次尝试机会。如果仍然失败,SIM 卡将被锁定。"</item>
+    <item quantity="other" msgid="7530597808358774740">"您还有<xliff:g id="NUMBER">%d</xliff:g>次尝试机会。如果仍然失败,SIM 卡将被锁定。"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"来电显示"</string>
@@ -71,7 +76,7 @@
     <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="RestrictedChangedTitle" msgid="5592189398956187498">"网络可用情况发生变化"</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"数据服务已禁用。"</string>
     <string name="RestrictedOnEmergency" msgid="6581163779072833665">"紧急服务已禁用。"</string>
     <string name="RestrictedOnNormal" msgid="4953867011389750673">"已禁用语音服务。"</string>
@@ -122,7 +127,7 @@
     <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="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>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"卸载快捷方式"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"允许应用自行删除主屏幕快捷方式。"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"重新设置外拨电话的路径"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"允许该应用处理外拨电话以及更改要拨打的号码。此权限可让该应用监视、重定向或阻止外拨电话。"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"允许应用在拨出电话时查看拨打的电话号码,并选择改为拨打其他号码或完全中止通话。"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"接收讯息(短信)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"允许该应用接收和处理短信。这就意味着,该应用可能会监视发送到您设备的短信,或删除发送到您设备的短信而不向您显示。"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"接收讯息(彩信)"</string>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"绑定至远程显示屏"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"允许应用绑定至远程显示屏的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"绑定到小部件服务"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允许应用绑定到小部件服务的顶级接口。普通应用绝不需要此权限。"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"与设备管理器交互"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"在设备处于闲置状态时运行应用"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"当设备处于闲置状态时,此权限允许Android系统在后台运行该应用。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"读取/写入诊断所拥有的资源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允许应用读取/写入诊断组拥有的所有资源(例如 /dev 中的文件)。这可能会影响系统的稳定性和安全性。此权限仅供制造商或运营商诊断硬件方面的问题时使用。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"启用或停用应用组件"</string>
@@ -477,14 +486,16 @@
     <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">"配置 WLAN 显示设备"</string>
     <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>
-    <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"检测关键词"</string>
-    <string name="permdesc_captureAudioHotword" msgid="9151807958153056810">"允许应用捕获音频以便检测语音指令的关键词。捕获操作会在后台进行,但不会妨碍其他音频捕获工具(例如摄像机)。"</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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"允许该应用修改全局音频设置,例如音量和用于输出的扬声器。"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"录音"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"允许该应用使用麦克风录制音频。此权限可让该应用不经您的确认即可随时录制音频。"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM卡通信"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"允许应用向SIM卡发送命令(此权限具有很高的危险性)。"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"拍摄照片和视频"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"允许该应用使用相机拍摄照片和视频。此权限可让该应用随时使用相机,而无需您的确认。"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"在相机使用过程中停用传输指示灯 LED"</string>
@@ -545,11 +558,13 @@
     <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="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_readPrecisePhoneState" msgid="5476483020282007597">"读取确切的手机状态"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允许应用获取确切的手机状态。此权限可让应用确定实际通话状态、通话是在界面上进行还是在后台进行、通话未接通情况、确切的数据网络连接状态,以及数据网络连接失败情况。"</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>
@@ -621,7 +636,7 @@
     <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="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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允许应用调用运营商提供的配置应用。普通应用绝不需要此权限。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"监听网络状况的观测信息"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允许应用监听网络状况的观测信息。普通应用绝不需要此权限。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"更改输入设备校准设置"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允许应用修改触摸屏的校准参数。普通应用绝不需要此权限。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"住宅"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"单位"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"找不到可用来查看此联系人的应用。"</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"与更新和恢复系统互动"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"允许应用与恢复系统和系统更新互动。"</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"无法启动“<xliff:g id="APPLICATION_NAME">%s</xliff:g>”"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享方式"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"使用<xliff:g id="APPLICATION_NAME">%s</xliff:g>分享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑动手柄。触摸并按住。"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"连接到设备"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"将屏幕投射到设备上"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"正在搜索设备…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"设置"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"断开连接"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"正在扫描..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"正在连接..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"可连接"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"正在投射屏幕"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"正在连接到“<xliff:g id="NAME">%1$s</xliff:g>”"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"正在投射屏幕"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"已连接到“<xliff:g id="NAME">%1$s</xliff:g>”"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"从顶部向下滑动即可退出全屏模式"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"从顶部向下滑动即可退出全屏模式。"</string>
+    <string name="done_label" msgid="2093726099505892398">"完成"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"小时转盘"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"分钟转盘"</string>
+    <string name="select_hours" msgid="6043079511766008245">"选择小时"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"选择分钟"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"按月份划分的日期网格"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年份列表"</string>
+    <string name="select_day" msgid="7774759604701773332">"选择月份和日期"</string>
+    <string name="select_year" msgid="7952052866994196170">"选择年份"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"已选择<xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"已删除<xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 2d2e77e..1273200 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"操作失敗,請啟用「SIM/RUIM 鎖定」。"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"您剩下 <xliff:g id="NUMBER">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,SIM 將會被鎖定。"</item>
+    <item quantity="other" msgid="7530597808358774740">"您剩下 <xliff:g id="NUMBER">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,SIM 將會被鎖定。"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"來電顯示"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"解除安裝捷徑"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"允許應用程式繞過用戶授權直接移除主畫面捷徑。"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"重新設定撥出電話的路徑"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"允許應用程式處理撥出電話及更改撥打的號碼。這項權限允許應用程式監控、轉接或阻止撥出的電話。"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"允許應用程式在撥出電話時查看所撥打的電話號碼,並選擇將電話重新導向至另一個號碼或完全中斷通話。"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"接收短訊 (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"允許應用程式接收和處理短訊。這表示應用程式可監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"接收短訊 (MMS)"</string>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"繫結至遠端螢幕"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"允許應用程式繫結至遠端屏螢的頂層介面 (不建議一般應用程式使用)。"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"繫結至小工具服務"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允許應用程式繫結至小工具服務的頂層介面 (不建議一般應用程式使用)。"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"當裝置閒置時執行應用程式"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"當您不使用裝置時,此權限允許 Android 系統在背景執行應用程式。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀取/寫入由診斷應用程式擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取及寫入診斷群組所擁有的任何資源 (例如:位於 /dev 中的檔案)。這可能會影響系統的穩定性及安全性,只應對製造商或網絡供應商所使用的硬件專用診斷程式開放這項權限。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
@@ -477,6 +486,8 @@
     <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 Display"</string>
     <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"允許應用程式設定及連接 WiFi Display。"</string>
     <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"控制 WiFi Display"</string>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"允許應用程式修改全域音頻設定,例如音量和用於輸出的喇叭。"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"錄製音效"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"允許應用程式使用麥克風錄音。這項權限允許應用程式隨時錄音,而不需經您確認。"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM 卡通訊"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"允許應用程式傳送指令到 SIM 卡。這項操作具有高危險性。"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"拍照和拍攝影片"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"允許應用程式使用相機拍照和錄影。這項權限允許應用程式隨時使用相機,而不需經您確認。"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"使用相機時停用傳輸指示燈"</string>
@@ -550,6 +563,8 @@
     <string name="permdesc_modifyPhoneState" msgid="1029877529007686732">"允許應用程式控制裝置上的電話功能。具備此權限的應用程式可在未通知您的情況下,進行切換網絡以及開關手機無線電之類的操作。"</string>
     <string name="permlab_readPhoneState" msgid="9178228524507610486">"讀取手機狀態和識別碼"</string>
     <string name="permdesc_readPhoneState" msgid="1639212771826125528">"允許應用程式使用裝置的電話功能。這項權限允許應用程式確定手機號碼和裝置編號、是否正在通話中,以及所撥打的對方號碼。"</string>
+    <string name="permlab_readPrecisePhoneState" msgid="5476483020282007597">"讀取精確的手機狀態"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取精確的手機狀態。此權限可讓應用程式判斷實際的通話狀態、是否正在通話或在背景中運作、無法通話次數、精確的數據連線狀態和數據連線失敗次數。"</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式調用流動網絡供應商提供的設定應用程式 (不建議一般應用程式使用)。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽對網絡狀況的觀察"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽對網絡狀況的觀察 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"變更輸入裝置校正設定"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允許應用程式修改觸控式螢幕的校正參數,而一般應用程式並不需要作出類似修改。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監控屏幕解鎖嘗試次數"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"家用"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"工作"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"找不到可以查看這位聯絡人的應用程式。"</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"與更新和復原系統互動"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"允許應用程式與復原系統和系統更新互動。"</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"無法啟動 <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享給"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"與「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」分享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑動控制。持續輕觸。"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"連接裝置"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"在裝置上放送螢幕"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"正在搜尋裝置…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"設定"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"停止連接"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"正在掃描…"</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"正在連線..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"可用"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"正在此放送螢幕"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"正在連線到「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"正在此放送螢幕"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"已連線到「<xliff:g id="NAME">%1$s</xliff:g>」"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"從頂端往下滑動即可結束全螢幕。"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"由頂端往下快速滑動即可離開全螢幕。"</string>
+    <string name="done_label" msgid="2093726099505892398">"完成"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"小時環形滑桿"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"分鐘環形滑桿"</string>
+    <string name="select_hours" msgid="6043079511766008245">"選取小時"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"選取分鐘"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"顯示每日的月曆方格"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年份清單"</string>
+    <string name="select_day" msgid="7774759604701773332">"選取月份和日期"</string>
+    <string name="select_year" msgid="7952052866994196170">"選取年份"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"已選取<xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 已刪除"</string>
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 3ec8d4c..f4b96d0 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -50,6 +50,11 @@
     <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="enablePin" msgid="209412020907207950">"操作失敗,請啟用 SIM/RUIM 鎖定。"</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"您還可以再試 <xliff:g id="NUMBER">%d</xliff:g> 次。如果仍然失敗,SIM 卡將被鎖住。"</item>
+    <item quantity="other" msgid="7530597808358774740">"您還可以再試 <xliff:g id="NUMBER">%d</xliff:g> 次。如果仍然失敗,SIM 卡將被鎖住。"</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"來電顯示"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"解除安裝捷徑"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"允許應用程式自動移除主螢幕捷徑。"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"重設撥號路徑"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5331318931937402040">"允許應用程式處理撥出電話及更改撥打的號碼。這項權限可讓應用程式監控、轉接或阻止撥出的電話。"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"允許應用程式在撥打電話期間查看撥出的電話號碼,並可選擇改撥其他號碼或中斷通話。"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"接收簡訊 (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"允許應用程式接收和處理簡訊。這項設定可讓應用程式監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"接收簡訊 (MMS)"</string>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"繫結至遠端螢幕"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"允許應用程式繫結至遠端螢幕的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindRemoteViews" msgid="5697987759897367099">"繫結至小工具服務"</string>
     <string name="permdesc_bindRemoteViews" msgid="4717987810137692572">"允許應用程式繫結至小工具服務的頂層介面 (一般應用程式不需使用)。"</string>
     <string name="permlab_bindDeviceAdmin" msgid="8704986163711455010">"與裝置管理員互動"</string>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"當裝置閒置時執行應用程式"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"當裝置處於未使用狀態時,此權限允許 Android 系統在背景執行應用程式。"</string>
     <string name="permlab_diagnostic" msgid="8076743953908000342">"讀寫 diag 擁有的資源"</string>
     <string name="permdesc_diagnostic" msgid="6608295692002452283">"允許應用程式讀取或寫入診斷群組擁有的任何資源,例如 /dev 底下的檔案。這可能會影響系統的穩定性和安全性,因此應由製造商或電信業者操作,且只用在特定硬體診斷。"</string>
     <string name="permlab_changeComponentState" msgid="6335576775711095931">"啟用或停用應用程式元件"</string>
@@ -477,14 +486,16 @@
     <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">"設定 Wi-Fi 顯示裝置"</string>
     <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_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>
@@ -495,6 +506,8 @@
     <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"允許應用程式修改全域音訊設定,例如音量和用來輸出的喇叭。"</string>
     <string name="permlab_recordAudio" msgid="3876049771427466323">"錄製音訊"</string>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"允許應用程式使用麥克風錄音。這項權限可讓應用程式隨時錄音,不需經過您的確認。"</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"SIM 卡通訊"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"允許應用程式傳送指令到 SIM 卡。這麼做非常危險。"</string>
     <string name="permlab_camera" msgid="3616391919559751192">"拍攝相片和影片"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"允許應用程式使用相機拍照和錄影。這項權限可讓應用程式隨時使用相機,而不需請求您進行確認。"</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"使用攝影機時停用傳輸指示器 LED"</string>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"讀取手機精確狀態"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"允許應用程式存取手機的精確狀態。這項權限可讓應用程式判別實際通話狀態,包括通話正在進行中或是在背景運作、通話失敗次數、精確數據連線狀態和數據連線失敗次數。"</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>
@@ -674,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式叫用行動通訊業者提供的設定應用程式 (一般應用程式並不需要)。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽網路狀況觀察資訊"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽網路狀況觀察資訊 (一般應用程式並不需要)。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"變更輸入裝置校正設定"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允許應用程式修改觸控螢幕的校正參數 (一般應用程式並不需要)。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"住家"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"公司"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"其他"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"找不到可用來查看這位聯絡人的應用程式。"</string>
     <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>
@@ -1122,7 +1140,7 @@
     <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_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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"與更新和還原系統互動"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"允許應用程式與還原系統及系統更新互動。"</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>
@@ -1414,18 +1434,10 @@
     <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_error" msgid="8624618365481126668">"無法啟動 <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"分享對象:"</string>
     <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"與「<xliff:g id="APPLICATION_NAME">%s</xliff:g>」分享"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"滑動控制。持續輕觸。"</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>
@@ -1483,8 +1495,12 @@
     <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_chooser_title" msgid="1751618554539087622">"連線至裝置"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"將螢幕投放到裝置上"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"正在搜尋裝置..."</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"設定"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"中斷連線"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"掃描中..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"連線中…"</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"可以使用"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"正在投放螢幕"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"正在連線至「<xliff:g id="NAME">%1$s</xliff:g>」"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"正在投放螢幕"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"已連線至「<xliff:g id="NAME">%1$s</xliff:g>」"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"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>
@@ -1649,5 +1667,16 @@
     <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="immersive_mode_confirmation" msgid="7227416894979047467">"從頂端往下滑動即可結束全螢幕。"</string>
+    <string name="immersive_mode_confirmation" msgid="7227416894979047467">"從頂端往下滑動即可退出全螢幕模式。"</string>
+    <string name="done_label" msgid="2093726099505892398">"完成"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"小時數環狀滑桿"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"分鐘數環狀滑桿"</string>
+    <string name="select_hours" msgid="6043079511766008245">"選取小時數"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"選取分鐘數"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"日期網格 (按月顯示)"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"年份清單"</string>
+    <string name="select_day" msgid="7774759604701773332">"選取月份和日期"</string>
+    <string name="select_year" msgid="7952052866994196170">"選取年份"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"已選取 <xliff:g id="ITEM">%1$s</xliff:g>"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"已刪除 <xliff:g id="KEY">%1$s</xliff:g>"</string>
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 57d59c3..c7faf48 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -50,6 +50,11 @@
     <string name="invalidPuk" msgid="8761456210898036513">"Thayipha i-PUK enezinombolo ezingu-8 noma ngaphezu."</string>
     <string name="needPuk" msgid="919668385956251611">"Ikhadi lakho le-SIM livalwe nge-PUK. Thayipha ikhodi ye-PUK ukulivula."</string>
     <string name="needPuk2" msgid="4526033371987193070">"Thayipha i-PUK2 ukuze uvule ikhadi le-SIM."</string>
+    <string name="enablePin" msgid="209412020907207950">"Akuphumelelanga, nika amandla ukhiye we-SIM/RUIM."</string>
+  <plurals name="pinpuk_attempts">
+    <item quantity="one" msgid="6596245285809790142">"Unemizamo engu-<xliff:g id="NUMBER">%d</xliff:g> ngaphambi kokuba i-SIM ikhiywe."</item>
+    <item quantity="other" msgid="7530597808358774740">"Unemizamo engu-<xliff:g id="NUMBER">%d</xliff:g> ngaphambi kokuba i-SIM ikhiywe."</item>
+  </plurals>
     <string name="imei" msgid="2625429890869005782">"IMEI"</string>
     <string name="meid" msgid="4841221237681254195">"MEID"</string>
     <string name="ClipMmi" msgid="6952821216480289285">"I-ID Yocingo Olungenayo"</string>
@@ -251,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"khipha izinqamuleli"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Ivumela uhlelo lokusebenza ukususa izinqamuleli zesikrini sasekhaya ngaphandle kokungenela komsebenzisi."</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="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Ivumela uhlelo lokusebenza ukubona inombolo eshayelwayo ngesikhathi sekholi ephumayo ngenketho yokuqondisa kabusha ikholi kwinombolo ehlukile noma ukuyekisa ikholi yonke."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"thola imiyalezo ebhaliwe (i-SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Ivumela uhlelo lokusebenza ukuthola nokucubungula imilayezo ye-SMS. Loku kuchaza ukuthi uhlelo lokusebenza lungangamela noma lesuse imilayezo ethunyelwe kudivayisi yakho ngaphandle kokukubonisa yona."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"thola imiyalezo ebhaliwe (i-MMS)"</string>
@@ -377,6 +382,8 @@
     <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_bindRemoteDisplay" msgid="1782923938029941960">"bophezela kusibonisi sesilawuli kude"</string>
+    <string name="permdesc_bindRemoteDisplay" msgid="1261242718727295981">"Ivumela umbambi ukuhlanganisa isixhumi esibonakalayo esisezingeni eliphezulu sesibonisi sesilawuli kude. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</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>
@@ -416,6 +423,8 @@
     <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_bindIdleService" msgid="816311765497613780">"qalisa uhlelo lokusebenza ngesikhathi sokungenzi lutho"</string>
+    <string name="permdesc_bindIdleService" msgid="1767538493214100612">"Le mvume ivumela isistimu ye-Android ukuthi iqalise uhlelo lokusebenza ngemuva ngenkathi idivayisi ingasebenzi."</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>
@@ -477,6 +486,8 @@
     <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 uhlelo lokusebenza ukuthi ifunde okuqukethwe ifreyimu yebhafa."</string>
+    <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"finyelela ku-InputFlinger"</string>
+    <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"Ivumela uhlelo lokusebenza ukuthi lusebenzise izici zezinga eliphansi ze-InputFlinger."</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>
@@ -495,6 +506,8 @@
     <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>
     <string name="permdesc_recordAudio" msgid="4906839301087980680">"Ivumela uhlelo lokusebenza ukurekhoda umsindo nge-microphone. Le mvume ivumela uhlelo lokusebenza ukuqopha umsindo noma kunini ngaphandle kokuqinisekisa kwakho."</string>
+    <string name="permlab_sim_communication" msgid="1180265879464893029">"uxhumano le-sim"</string>
+    <string name="permdesc_sim_communication" msgid="5725159654279639498">"Ivumela uhlelo lokusebenza ukuthumela imiyalo ku-SIM. Lokhu kuyingozi kakhulu."</string>
     <string name="permlab_camera" msgid="3616391919559751192">"thatha izithombe namavidiyo"</string>
     <string name="permdesc_camera" msgid="8497216524735535009">"Ivumela uhlelo lokusebenza ukuthatha izithombe namavidiyo ngekhamera. Le mvume ivumela uhlelo lokusebenza ukusebenzisa ikhamera nganoma isiphi isikhathi ngaphandle kwemvume yakho."</string>
     <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"khubaza i-LED yesikhombi sokudlulisa uma ikhamera isebenza"</string>
@@ -550,6 +563,8 @@
     <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_readPrecisePhoneState" msgid="5476483020282007597">"funda izimo zefoni ezinembile"</string>
+    <string name="permdesc_readPrecisePhoneState" msgid="6648009074263855418">"Ivumelanisa uhlelo lokusebenza ukuthi lufinyelele kuzimo ezinembile zefoni. Le mvume ivumela uhlelo lokusebenza ukuthi linqume isimo sekholi sangempela, noma ikholi isebenza noma ingemuva, ikholi ihluleka, isimo esinembile sokuxhumeka kwedatha nokuhluleka kokuxhumeka kwedatha."</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>
@@ -674,6 +689,8 @@
     <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="permlab_setInputCalibration" msgid="4902620118878467615">"guqula ukulinganisa kokufaka kwedivayisi"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ivumela uhlelo lokusebenza ukuthi lushintshe imingcele yokulinganisa yesikrini esithintwayo. 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>
@@ -809,6 +826,7 @@
     <string name="sipAddressTypeHome" msgid="6093598181069359295">"Ekhaya"</string>
     <string name="sipAddressTypeWork" msgid="6920725730797099047">"Umsebenzi"</string>
     <string name="sipAddressTypeOther" msgid="4408436162950119849">"Okunye"</string>
+    <string name="quick_contacts_not_available" msgid="746098007828579688">"Alukho uhlelo lokusebenza olutholakele lokubuka lona oxhumana naye."</string>
     <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>
@@ -1305,6 +1323,8 @@
     <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="permlab_recovery" msgid="3157024487744125846">"Ixhumana nesibuyekezo nesistimu yokutakula"</string>
+    <string name="permdesc_recovery" msgid="8511774533266359571">"Ivumela uhlelo lokusebenza ukuthi lixhumane nesistimu yokutakula nezibuyekezo zesistimu."</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>
@@ -1414,18 +1434,10 @@
     <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 uhlelo lokusebenza"</string>
+    <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Ayikwazanga ukuqalisa i-<xliff:g id="APPLICATION_NAME">%s</xliff:g>"</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>
-    <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="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_target_unlock_tablet" msgid="3833195335629795055">"Swayipha ukuze uvule."</string>
     <string name="keyboard_headset_required_to_hear_password" msgid="7011927352267668657">"Plaka ku-headset ukuze uzwe okhiye bephasiwedi ezindlebeni zakho bezwakala kakhulu."</string>
     <string name="keyboard_password_character_no_headset" msgid="2859873770886153678">"Icashazi."</string>
@@ -1483,8 +1495,12 @@
     <string name="default_audio_route_category_name" msgid="3722811174003886946">"Isistimu"</string>
     <string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Umsindo we-Bluetooth"</string>
     <string name="wireless_display_route_description" msgid="9070346425023979651">"Ukubonisa okungenazintambo"</string>
-    <string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Qedile"</string>
     <string name="media_route_button_content_description" msgid="5758553567065145276">"Okukhiphayo kwemidiya"</string>
+    <string name="media_route_chooser_title" msgid="1751618554539087622">"Xhuma kudivayisi"</string>
+    <string name="media_route_chooser_title_for_remote_display" msgid="3395541745872017583">"Lingisa isikrini kudivayisi"</string>
+    <string name="media_route_chooser_searching" msgid="4776236202610828706">"Isesha amadivayisi…"</string>
+    <string name="media_route_chooser_extended_settings" msgid="87015534236701604">"Izilungiselelo"</string>
+    <string name="media_route_controller_disconnect" msgid="8966120286374158649">"Nqamula"</string>
     <string name="media_route_status_scanning" msgid="7279908761758293783">"Iyaskena..."</string>
     <string name="media_route_status_connecting" msgid="6422571716007825440">"Iyaxhuma..."</string>
     <string name="media_route_status_available" msgid="6983258067194649391">"Kuyatholakala"</string>
@@ -1495,8 +1511,10 @@
     <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_connecting_title" msgid="2838646471050359706">"Isikrini sokulingisa"</string>
+    <string name="wifi_display_notification_connecting_message" msgid="5837350993752841389">"Ixhuma ku-<xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="wifi_display_notification_connected_title" msgid="8567308065912676285">"Isikrini sokulingisa"</string>
+    <string name="wifi_display_notification_connected_message" msgid="2587209325701109715">"Kuxhunywe ku-<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="wifi_display_notification_disconnect" msgid="6183754463561153372">"Nqamula"</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>
@@ -1514,7 +1532,7 @@
     <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_sim_puk_hint" msgid="6025069204539532000">"Ikhodi ye-PUK kumele ibe yizinombolo ezingu-8."</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>
@@ -1650,4 +1668,15 @@
   </plurals>
     <string name="restr_pin_try_later" msgid="973144472490532377">"Zama futhi emva kwesikhathi"</string>
     <string name="immersive_mode_confirmation" msgid="7227416894979047467">"Swayiphela phansi kusukela phezulu ukuze uphume kusikrini esigcwele."</string>
+    <string name="done_label" msgid="2093726099505892398">"Kwenziwe"</string>
+    <string name="hour_picker_description" msgid="6698199186859736512">"Amahora weslayidi esiyindingilizi"</string>
+    <string name="minute_picker_description" msgid="8606010966873791190">"Amaminithi weslayidi esiyindingilizi"</string>
+    <string name="select_hours" msgid="6043079511766008245">"Khetha amahora"</string>
+    <string name="select_minutes" msgid="3974345615920336087">"Khetha amaminithi"</string>
+    <string name="day_picker_description" msgid="8990847925961297968">"Igridi yenyanga yezinsuku"</string>
+    <string name="year_picker_description" msgid="5524331207436052403">"Uhlu lonyaka"</string>
+    <string name="select_day" msgid="7774759604701773332">"Khetha inyanga nosuku"</string>
+    <string name="select_year" msgid="7952052866994196170">"Khetha unyaka"</string>
+    <string name="item_is_selected" msgid="949687401682476608">"I-<xliff:g id="ITEM">%1$s</xliff:g> ekhethiwe"</string>
+    <string name="deleted_key" msgid="7659477886625566590">"I-<xliff:g id="KEY">%1$s</xliff:g> isusiwe"</string>
 </resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 91af50a..f01f10e 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -226,9 +226,11 @@
        <item>@drawable/ic_clear</item>
        <item>@drawable/ic_clear_disabled</item>
        <item>@drawable/ic_clear_normal</item>
-       <item>@drawable/ic_search</item>
+       <item>@drawable/ic_search_api_holo_dark</item>
+       <item>@drawable/ic_search_api_holo_light</item>
        <item>@drawable/ic_go</item>
-       <item>@drawable/ic_voice_search</item>
+       <item>@drawable/ic_voice_search_api_holo_dark</item>
+       <item>@drawable/ic_voice_search_api_holo_light</item>
        <item>@drawable/dialog_bottom_holo_dark</item>
        <item>@drawable/dialog_bottom_holo_light</item>
        <item>@drawable/dialog_full_holo_dark</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 1dda8bf..4d272ee 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -451,6 +451,15 @@
              Corresponds to {@link android.view.Window#FEATURE_SWIPE_TO_DISMISS} -->
         <attr name="windowSwipeToDismiss" format="boolean" />
 
+        <!-- Flag indicating whether this window requests that content changes be performed
+             as scene changes with transitions. Corresponds to
+             {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS}. -->
+        <attr name="windowContentTransitions" format="boolean" />
+
+        <!-- Reference to a TransitionManager XML resource defining the desired
+             transitions between different window content. -->
+        <attr name="windowContentTransitionManager" format="reference" />
+
         <!-- ============ -->
         <!-- Alert Dialog styles -->
         <!-- ============ -->
@@ -611,6 +620,8 @@
         <attr name="popupMenuStyle" format="reference" />
         <!-- Default StackView style. -->
         <attr name="stackViewStyle" format="reference" />
+        <!-- Default style for the FragmentBreadCrumbs widget. -->
+        <attr name="fragmentBreadCrumbsStyle" format="reference" />
 
         <!-- NumberPicker style. -->
         <attr name="numberPickerStyle" format="reference" />
@@ -621,6 +632,18 @@
         <!-- The TimePicker style. -->
         <attr name="timePickerStyle" format="reference" />
 
+        <!-- The TimePicker Header background color . -->
+        <attr name="timePickerHeaderBackgroundColor" format="reference" />
+
+        <!-- The TimePicker Header time label text appearance -->
+        <attr name="timePickerHeaderTimeLabelTextAppearance" format="reference" />
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <attr name="timePickerHeaderAmPmLabelTextAppearance" format="reference" />
+
+        <!-- The TimePicker dialog theme. -->
+        <attr name="timePickerDialogTheme" format="reference" />
+
         <!-- The DatePicker style. -->
         <attr name="datePickerStyle" format="reference" />
 
@@ -654,6 +677,8 @@
         <!-- Action bar styles   -->
         <!-- =================== -->
         <eat-comment />
+        <!-- Theme override for the Action Bar -->
+        <attr name="actionBarTheme" format="reference" />
         <!-- Default style for tabs within an action bar -->
         <attr name="actionBarTabStyle" format="reference" />
         <attr name="actionBarTabBarStyle" format="reference" />
@@ -1611,6 +1636,9 @@
         <attr name="windowTranslucentStatus" />
         <attr name="windowTranslucentNavigation" />
         <attr name="windowSwipeToDismiss" />
+        <attr name="windowContentTransitions" />
+        <attr name="windowContentTransitionManager" />
+
         <!-- The minimum width the window is allowed to be, along the major
              axis of the screen.  That is, when in landscape.  Can be either
              an absolute dimension or a fraction of the screen size in that
@@ -2074,10 +2102,13 @@
              property of the view, which is set by its layout. -->
         <attr name="translationX" format="dimension" />
 
-        <!-- translation in y of the view. This value is added post-layout to the left
+        <!-- translation in y of the view. This value is added post-layout to the top
              property of the view, which is set by its layout. -->
         <attr name="translationY" format="dimension" />
 
+        <!-- translation in z of the view. This value is added post-layout to its position. -->
+        <attr name="translationZ" format="dimension" />
+
         <!-- x location of the pivot point around which the view will rotate and scale.
              This xml attribute sets the pivotX property of the View. -->
         <attr name="transformPivotX" format="dimension" />
@@ -2222,6 +2253,25 @@
              Hence, the TextView is a label for the EditText. -->
         <attr name="labelFor" format="integer" />
 
+        <!-- Specifies a theme override for a view. When a theme override is set, the
+             view will be inflated using a {@link android.content.Context} themed with
+             the specified resource. During XML inflation, any child views under the
+             view with a theme override will inherit the themed context. -->
+        <attr name="theme" />
+
+        <!-- Specifies that the shared name of the View to be shared with another Activity.
+             When transitioning between Activities, the name links a UI element in the starting
+             Activity to UI element in the called Activity. Names should be unique in the
+             View hierarchy. -->
+        <attr name="sharedElementName" format="string" />
+    </declare-styleable>
+
+    <!-- Attributes that can be assigned to a tag for a particular View. -->
+    <declare-styleable name="ViewTag">
+        <!-- Specifies the key identifying a tag. This must be a resource reference. -->
+        <attr name="id" />
+        <!-- Specifies the value with which to tag the view. -->
+        <attr name="value" />
     </declare-styleable>
 
     <!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
@@ -2305,6 +2355,14 @@
             <!-- Use the children's optical bounds when laying out this container. -->
             <enum name="opticalBounds" value="1" />
         </attr>
+
+        <!-- Sets whether or not this ViewGroup should be treated as a single entity
+             when doing an Activity transition. Typically, the elements inside a
+             ViewGroup are each transitioned from the scene individually. The default
+             for a ViewGroup is false unless it has a background. See
+             {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.view.View, String)}
+             for more information. -->
+        <attr name="transitionGroup" format="boolean" />
     </declare-styleable>
 
     <!-- A {@link android.view.ViewStub} lets you lazily include other XML layouts
@@ -2413,7 +2471,7 @@
         <!-- 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()
+             the IME has to offer ways 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
@@ -2580,6 +2638,8 @@
             <flag name="flagReportViewIds" value="0x00000010" />
             <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_FILTER_KEY_EVENTS} -->
             <flag name="flagRequestFilterKeyEvents" value="0x00000020" />
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS} -->
+            <flag name="flagRetrieveInteractiveWindows" value="0x00000040" />
         </attr>
         <!-- Component name of an activity that allows the user to modify
              the settings for this service. This setting cannot be changed at runtime. -->
@@ -2732,6 +2792,8 @@
         <!-- Enables the fast scroll thumb that can be dragged to quickly scroll through
              the list. -->
         <attr name="fastScrollEnabled" format="boolean" />
+        <!-- Specifies the style of the fast scroll decorations. -->
+        <attr name="fastScrollStyle" format="reference" />
         <!-- When set to true, the list will use a more refined calculation
              method based on the pixels height of the items visible on screen. This
              property is set to true by default but should be set to false if your adapter
@@ -2800,6 +2862,36 @@
     </declare-styleable>
     <declare-styleable name="EditText">
     </declare-styleable>
+    <declare-styleable name="FastScroll">
+        <!-- Drawable used for the scroll bar thumb. -->
+        <attr name="thumbDrawable" format="reference" />
+        <!-- Minimum width of the thumb. -->
+        <attr name="thumbMinWidth" format="dimension" />
+        <!-- Minimum height of the thumb. -->
+        <attr name="thumbMinHeight" format="dimension" />
+        <!-- Drawable used for the scroll bar track. -->
+        <attr name="trackDrawable" format="reference" />
+        <!-- Drawable used for the section header preview when right-aligned. -->
+        <attr name="backgroundRight" format="reference" />
+        <!-- Drawable used for the section header preview when left-aligned. -->
+        <attr name="backgroundLeft" format="reference" />
+        <!-- Position of section header preview. -->
+        <attr name="position">
+            <!-- Floating at the top of the content. -->
+            <enum name="floating" value="0" />
+            <!-- Pinned alongside the thumb. -->
+            <enum name="atThumb" value="1" />
+        </attr>
+        <attr name="textAppearance" />
+        <attr name="textColor" />
+        <attr name="textSize" />
+        <!-- Minimum width of the section header preview. -->
+        <attr name="minWidth" />
+        <!-- Minimum height of the section header preview. -->
+        <attr name="minHeight" />
+        <!-- Padding for the section header preview. -->
+        <attr name="padding" />
+    </declare-styleable>
     <declare-styleable name="FrameLayout">
         <!-- Defines the drawable to draw over the content. This can be used as an overlay.
              The foreground drawable participates in the padding of the content if the gravity
@@ -3965,6 +4057,30 @@
     <declare-styleable name="TimePicker">
         <!-- @hide The layout of the time picker. -->
         <attr name="internalLayout" />
+        <!-- @hide The layout of the legacy time picker. -->
+        <attr name="legacyLayout" format="reference" />
+        <!-- @hide Enables or disable the use of the legacy layout for the TimePicker. -->
+        <attr name="legacyMode" format="boolean" />
+        <!-- @hide The color when the non legacy TimePicker is disabled. -->
+        <attr name="disabledColor" format="color|reference" />
+        <!-- @hide The color for selected text of the non legacy TimePicker. -->
+        <attr name="headerSelectedTextColor" format="color|reference" />
+        <!-- @hide The color for unselected text of the non legacy TimePicker. -->
+        <attr name="headerUnselectedTextColor" format="color|reference" />
+        <!-- @hide The background color for the header of the non legacy TimePicker. -->
+        <attr name="headerBackgroundColor" format="color|reference" />
+        <!-- @hide The color for the hours/minutes numbers of the non legacy TimePicker. -->
+        <attr name="numbersTextColor" format="color|reference" />
+        <!-- @hide The background color for the hours/minutes numbers of the non legacy TimePicker. -->
+        <attr name="numbersBackgroundColor" format="color|reference" />
+        <!-- @hide The color for the AM/PM selectors of the non legacy TimePicker. -->
+        <attr name="amPmTextColor" format="color|reference" />
+        <!-- @hide The background color for the AM/PM selectors of the non legacy TimePicker when unselected. -->
+        <attr name="amPmUnselectedBackgroundColor" format="color|reference" />
+        <!-- @hide The background color for the AM/PM selectors of the non legacy TimePicker when selected. -->
+        <attr name="amPmSelectedBackgroundColor" format="color|reference" />
+        <!-- @hide The color for the hours/minutes selector of the non legacy TimePicker. -->
+        <attr name="numbersSelectorColor" format="color|reference" />
     </declare-styleable>
 
     <!-- ========================= -->
@@ -4166,6 +4282,14 @@
         <!-- Indicates if the drawable needs to be mirrored when its layout direction is
              RTL (right-to-left). -->
         <attr name="autoMirrored" />
+        <!-- Indicates how layer padding should affect the bounds of subsequent layers.
+            The default value is nest. -->
+        <attr name="paddingMode">
+            <!-- Nest each layer inside the padding of the previous layer. -->
+            <enum name="nest" value="0" />
+            <!-- Stack each layer directly atop the previous layer. -->
+            <enum name="stack" value="1" />
+        </attr>
     </declare-styleable>
 
     <!-- Describes an item (or child) of a LayerDrawable. -->
@@ -4181,7 +4305,7 @@
         <!-- Drawable used to render the layer. -->
         <attr name="drawable" />
         <!-- Identifier of the layer. This can be used to retrieve the layer
-             from a drawbable container. -->
+             from a drawable container. -->
         <attr name="id" />
     </declare-styleable>
 
@@ -4258,6 +4382,21 @@
         <!-- Indicates if the drawable needs to be mirrored when its layout direction is
              RTL (right-to-left). -->
         <attr name="autoMirrored" />
+        <!-- If set, specifies the color to apply to the drawable as a tint. By default,
+             no tint is applied. May be a color state list. -->
+        <attr name="tint" />
+        <!-- When a tint color is set, specifies its Porter-Duff blending mode. The
+             default value is src_in, which treats the drawable as an alpha mask. -->
+        <attr name="tintMode">
+            <!-- [Sa * Da, Sc * Da] -->
+            <enum name="src_in" value="0" />
+            <!-- [Da, Sc * Da + (1 - Sa) * Dc] -->
+            <enum name="src_atop" value="1" />
+            <!-- [Sa * Da, Sc * Dc] -->
+            <enum name="multiply" value="2" />
+            <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+            <enum name="screen" value="3" />
+        </attr>
     </declare-styleable>
 
     <!-- Drawable used to draw 9-patches. -->
@@ -4271,6 +4410,12 @@
         <!-- Indicates if the drawable needs to be mirrored when its layout direction is
              RTL (right-to-left). -->
         <attr name="autoMirrored" />
+        <!-- If set, specifies the color to apply to the drawable as a tint. By default,
+             no tint is applied. May be a color state list. -->
+        <attr name="tint" />
+        <!-- When a tint color is set, specifies its Porter-Duff blending mode. The
+             default value is src_in, which treats the drawable as an alpha mask. -->
+        <attr name="tintMode" />
     </declare-styleable>
 
     <!-- Drawable used to draw a single color. -->
@@ -4279,6 +4424,20 @@
         <attr name="color" />
     </declare-styleable>
 
+    <!-- Drawable used to show animated touch feedback. -->
+    <declare-styleable name="TouchFeedbackDrawable">
+        <!-- The tint to use for feedback ripples. This attribute is mandatory. -->
+        <attr name="tint" />
+        <!-- Specifies the Porter-Duff blending mode used to apply the tint. The default vlaue is src_atop, which draws over the opaque parts of the drawable. -->
+        <attr name="tintMode" />
+        <!-- Whether to pin feedback ripples to the center of the drawable. Default value is false. -->
+        <attr name="pinned" format="boolean" />
+        <!-- Optional drawable used to mask ripple bounds before projection. -->
+        <attr name="mask" format="reference" />
+        <!-- Optional drawable onto which ripples are projected. -->
+        <attr name="drawable" />
+    </declare-styleable>
+
     <declare-styleable name="ScaleDrawable">
         <!-- Scale width, expressed as a percentage of the drawable's bound. The value's
              format is XX%. For instance: 100%, 12.5%, etc.-->
@@ -4545,6 +4704,13 @@
         <attr name="extraTension" format="float" />
     </declare-styleable>
 
+    <declare-styleable name="PathInterpolator">
+        <attr name="controlX1" format="float" />
+        <attr name="controlY1" format="float" />
+        <attr name="controlX2" format="float" />
+        <attr name="controlY2" format="float" />
+    </declare-styleable>
+
     <!-- ========================== -->
     <!-- Transition attributes -->
     <!-- ========================== -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 55392ef..0a27840 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -274,6 +274,17 @@
          applications can request this feature. Default value is false. -->
     <attr name="requiredForAllUsers" format="boolean" />
 
+    <!-- Flag to specifiy for which types of profile this application needs to be present.
+         Only pre-installed applications can request this feature. Default is none. -->
+    <attr name="requiredForProfile">
+        <!-- This application needs to be present for restricted profiles -->
+        <flag name="restricted" value="0x0001" />
+        <!-- This application needs to be present for managed profiles -->
+        <flag name="managed" value="0x0002" />
+        <!-- This application needs to be present for all types of profiles -->
+        <flag name="all" value="0xFFFF" />
+    </attr>
+
     <!-- Flag indicating whether the application can be debugged, even when
          running on a device that is running in user mode. -->
     <attr name="debuggable" format="boolean" />
@@ -917,6 +928,7 @@
         <attr name="hasCode" format="boolean" />
         <attr name="persistent" />
         <attr name="requiredForAllUsers" />
+        <attr name="requiredForProfile" />
         <!-- Specify whether the components in this application are enabled or not (that is, can be
              instantiated by the system).
              If "false", it overrides any component specific values (a value of "true" will not
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 28e7af7..1947c50 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -22,8 +22,6 @@
     <drawable name="screen_background_dark">#ff000000</drawable>
     <drawable name="status_bar_closed_default_background">#ff000000</drawable>
     <drawable name="status_bar_opened_default_background">#ff000000</drawable>
-    <drawable name="notification_item_background_color">#ff111111</drawable>
-    <drawable name="notification_item_background_color_pressed">#ff454545</drawable>
     <drawable name="search_bar_default_color">#ff000000</drawable>
     <drawable name="safe_mode_background">#60000000</drawable>
     <!-- Background drawable that can be used for a transparent activity to
@@ -125,8 +123,8 @@
     <color name="facelock_spotlight_mask">#CC000000</color>
 
     <!-- For holo theme -->
-      <drawable name="screen_background_holo_light">#fff3f3f3</drawable>
-      <drawable name="screen_background_holo_dark">#ff000000</drawable>
+    <drawable name="screen_background_holo_light">#fff3f3f3</drawable>
+    <drawable name="screen_background_holo_dark">#ff000000</drawable>
     <color name="background_holo_dark">#ff000000</color>
     <color name="background_holo_light">#fff3f3f3</color>
     <color name="bright_foreground_holo_dark">@android:color/background_holo_light</color>
@@ -202,5 +200,22 @@
     <color name="keyguard_avatar_frame_pressed_color">#ff35b5e5</color>
 
     <color name="accessibility_focus_highlight">#80ffff00</color>
+
+    <!-- New TimePicker colors -->
+    <color name="timepicker_default_background_holo_light">@android:color/white</color>
+    <color name="timepicker_default_background_holo_dark">#ff303030</color>
+
+    <color name="timepicker_default_text_color_holo_light">#8c8c8c</color>
+    <color name="timepicker_default_text_color_holo_dark">@android:color/white</color>
+
+    <color name="timepicker_default_disabled_color_holo_light">#7f000000</color>
+    <color name="timepicker_default_disabled_color_holo_dark">#7f08c8c8</color>
+
+    <color name="timepicker_default_ampm_selected_background_color_holo_light">@android:color/holo_blue_light</color>
+    <color name="timepicker_default_ampm_selected_background_color_holo_dark">@android:color/holo_blue_light</color>
+
+    <color name="timepicker_default_ampm_unselected_background_color_holo_light">@android:color/white</color>
+    <color name="timepicker_default_ampm_unselected_background_color_holo_dark">@android:color/transparent</color>
+
 </resources>
 
diff --git a/core/res/res/values/colors_quantum.xml b/core/res/res/values/colors_quantum.xml
new file mode 100644
index 0000000..c8083f4
--- /dev/null
+++ b/core/res/res/values/colors_quantum.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <color name="background_quantum_dark">@color/black</color>
+    <color name="background_quantum_light">@color/quantum_grey_50</color>
+    <color name="secondary_background_quantum_dark">@color/quantum_grey_700</color>
+    <color name="secondary_background_quantum_light">@color/quantum_grey_100</color>
+
+    <color name="bright_foreground_quantum_dark">@color/background_quantum_light</color>
+    <color name="bright_foreground_quantum_light">@color/background_quantum_dark</color>
+    <!-- TODO: This is 50% alpha black -->
+    <color name="bright_foreground_disabled_quantum_dark">#80000000</color>
+    <!-- TODO: This is 50% alpha grey_50 -->
+    <color name="bright_foreground_disabled_quantum_light">#80fafafa</color>
+    <color name="bright_foreground_inverse_quantum_dark">@color/bright_foreground_quantum_light</color>
+    <color name="bright_foreground_inverse_quantum_light">@color/bright_foreground_quantum_dark</color>
+
+    <color name="dim_foreground_quantum_dark">#ffbebebe</color>
+    <color name="dim_foreground_quantum_light">#ff323232</color>
+    <color name="dim_foreground_disabled_quantum_dark">#80bebebe</color>
+    <color name="dim_foreground_disabled_quantum_light">#80323232</color>
+
+    <!-- TODO: These should be theme attributes. -->
+    <color name="control_normal_foreground_quantum_light">@color/secondary_text_quantum_light</color>
+    <color name="control_activated_foreground_quantum_light">@color/quantum_teal_700</color>
+
+    <!-- TODO: These should be theme attributes. -->
+    <color name="control_normal_foreground_quantum_dark">@color/secondary_text_quantum_dark</color>
+    <color name="control_activated_foreground_quantum_dark">@color/quantum_lime_A200</color>
+
+    <!-- TODO: These should be theme attributes. -->
+    <color name="btn_default_normal_quantum_light">@color/quantum_grey_300</color>
+    <color name="btn_default_pressed_quantum_light">@color/quantum_grey_500</color>
+
+    <!-- TODO: These should be theme attributes. -->
+    <color name="btn_default_normal_quantum_dark">@color/quantum_grey_700</color>
+    <color name="btn_default_pressed_quantum_dark">@color/quantum_grey_500</color>
+
+    <color name="hint_foreground_quantum_dark">@color/bright_foreground_disabled_quantum_dark</color>
+    <color name="hint_foreground_quantum_light">@color/bright_foreground_disabled_quantum_light</color>
+    <!-- TODO: This is 40% alpha lime_A200 -->
+    <color name="highlighted_text_quantum_dark">#66eeff41</color>
+    <!-- TODO: This is 40% alpha teal_700 -->
+    <color name="highlighted_text_quantum_light">#660097a7</color>
+
+    <!-- TODO: These should all be pushed into a TimePicker widget style. -->
+    <color name="timepicker_default_background_quantum_dark">@color/background_quantum_dark</color>
+    <color name="timepicker_default_background_quantum_light">@color/background_quantum_light</color>
+    <color name="timepicker_default_text_color_quantum_dark">@color/bright_foreground_quantum_dark</color>
+    <color name="timepicker_default_text_color_quantum_light">@color/bright_foreground_quantum_light</color>
+    <color name="timepicker_default_disabled_color_quantum_dark">@color/bright_foreground_disabled_quantum_dark</color>
+    <color name="timepicker_default_disabled_color_quantum_light">@color/bright_foreground_disabled_quantum_light</color>
+    <color name="timepicker_default_ampm_selected_background_color_quantum_dark">@color/control_activated_foreground_quantum_dark</color>
+    <color name="timepicker_default_ampm_selected_background_color_quantum_light">@color/control_activated_foreground_quantum_light</color>
+    <color name="timepicker_default_ampm_unselected_background_color_quantum_dark">@color/transparent</color>
+    <color name="timepicker_default_ampm_unselected_background_color_quantum_light">@color/white</color>
+
+    <!-- Primary & accent colors -->
+
+    <color name="quantum_red_100">#fff4c7c3</color>
+    <color name="quantum_red_300">#ffe67c73</color>
+    <color name="quantum_red_500">#ffdb4437</color>
+    <color name="quantum_red_700">#ffc53929</color>
+    <color name="quantum_red_A200">#ffff5252</color>
+    <color name="quantum_red_A400">#ffff1744</color>
+
+    <color name="quantum_blue_100">#ffc6dafc</color>
+    <color name="quantum_blue_300">#ff7baaf7</color>
+    <color name="quantum_blue_500">#ff4285f4</color>
+    <color name="quantum_blue_700">#ff3367d6</color>
+    <color name="quantum_blue_A200">#ff448aff</color>
+    <color name="quantum_blue_A400">#ff2979ff</color>
+
+    <color name="quantum_teal_100">#ffb2ebf2</color>
+    <color name="quantum_teal_300">#ff4dd0e1</color>
+    <color name="quantum_teal_500">#ff00bcd4</color>
+    <color name="quantum_teal_700">#ff0097a7</color>
+    <color name="quantum_teal_A200">#ff18ffff</color>
+    <color name="quantum_teal_A400">#ff00e5ff</color>
+
+    <color name="quantum_green_100">#ffb7e1cd</color>
+    <color name="quantum_green_300">#ff57bb8a</color>
+    <color name="quantum_green_500">#ff0f9d58</color>
+    <color name="quantum_green_700">#ff0b8043</color>
+    <color name="quantum_green_A200">#ff69f0ae</color>
+    <color name="quantum_green_A400">#ff00e676</color>
+
+    <color name="quantum_lime_100">#fff0f4c3</color>
+    <color name="quantum_lime_300">#ffdce775</color>
+    <color name="quantum_lime_500">#ffcddc39</color>
+    <color name="quantum_lime_700">#ffafb42b</color>
+    <color name="quantum_lime_A200">#ffeeff41</color>
+    <color name="quantum_lime_A400">#ffc6ff00</color>
+
+    <color name="quantum_yellow_100">#fffce8b2</color>
+    <color name="quantum_yellow_300">#fff7cb4d</color>
+    <color name="quantum_yellow_500">#fff4b400</color>
+    <color name="quantum_yellow_700">#fff09300</color>
+    <color name="quantum_yellow_A200">#ffffcd40</color>
+    <color name="quantum_yellow_A400">#ffffbc00</color>
+
+    <color name="quantum_orange_100">#ffffe0b2</color>
+    <color name="quantum_orange_300">#ffffb74d</color>
+    <color name="quantum_orange_500">#ffff9800</color>
+    <color name="quantum_orange_700">#fff57c00</color>
+    <color name="quantum_orange_A200">#ffffab40</color>
+    <color name="quantum_orange_A400">#ffff9100</color>
+
+    <color name="quantum_deep_orange_100">#fff4c7c3</color>
+    <color name="quantum_deep_orange_300">#ffe67c73</color>
+    <color name="quantum_deep_orange_500">#ffff5722</color>
+    <color name="quantum_deep_orange_700">#ffc53929</color>
+    <color name="quantum_deep_orange_A200">#ffff5252</color>
+    <color name="quantum_deep_orange_A400">#ffff1744</color>
+
+    <!-- Neutral colors -->
+
+    <color name="quantum_grey_50">#fffafafa</color>
+    <color name="quantum_grey_100">#fff5f5f5</color>
+    <color name="quantum_grey_300">#ffeeeeee</color>
+    <color name="quantum_grey_500">#ffa3a3a3</color>
+    <color name="quantum_grey_700">#ff717171</color>
+
+    <color name="quantum_blue_grey_50">#ffeceff1</color>
+    <color name="quantum_blue_grey_100">#ffcfd8dc</color>
+    <color name="quantum_blue_grey_300">#ff90a4ae</color>
+    <color name="quantum_blue_grey_500">#ff607d8b</color>
+    <color name="quantum_blue_grey_700">#ff455a64</color>
+
+    <color name="quantum_brown_100">#ffd7ccc8</color>
+    <color name="quantum_brown_300">#ffa1887f</color>
+    <color name="quantum_brown_500">#ff795548</color>
+    <color name="quantum_brown_700">#ff5d4037</color>
+
+    <!-- Text & foreground colors -->
+
+    <color name="primary_text_quantum_light">#ff000000</color>
+    <color name="secondary_text_quantum_light">#de000000</color>
+    <color name="tertiary_text_quantum_light">#8a000000</color>
+
+    <color name="primary_text_quantum_dark">#ffffffff</color>
+    <color name="secondary_text_quantum_dark">#deffffff</color>
+    <color name="tertiary_text_quantum_dark">#8affffff</color>
+
+    <!-- "Theme" colors to be replaced by attrs when available -->
+    <color name="theme_color_100">@color/quantum_teal_100</color>
+    <color name="theme_color_300">@color/quantum_teal_300</color>
+    <color name="theme_color_500">@color/quantum_teal_500</color>
+    <color name="theme_color_700">@color/quantum_teal_700</color>
+</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 552b129..4656f32 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -352,10 +352,6 @@
     <!-- Wifi driver supports batched scan -->
     <bool translatable="false" name="config_wifi_batched_scan_supported">false</bool>
 
-    <!-- Wifi driver's fallback country code; WS is ISO-Alpha2 code for Samoa which
-         has restrictions on can be scanned; which may satisfy quite a few regulatory issues. -->
-    <string translatable="false" name="config_wifi_unknown_country_code">WS</string>
-
     <!-- 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>
@@ -532,6 +528,12 @@
         <item>40</item>
     </integer-array>
 
+    <!-- Vibrator pattern for feedback when selecting an hour/minute tick of a Clock -->
+    <integer-array name="config_clockTickVibePattern">
+        <item>125</item>
+        <item>5</item>
+    </integer-array>
+
     <!-- Vibrator pattern for feedback about booting with safe mode disabled -->
     <integer-array name="config_safeModeDisabledVibePattern">
         <item>0</item>
@@ -1207,6 +1209,12 @@
 
     <!--  Maximum number of supported users -->
     <integer name="config_multiuserMaximumUsers">1</integer>
+    <!-- Whether UI for multi user should be shown -->
+    <bool name="config_enableMultiUserUI">false</bool>
+
+    <!-- If true, then we do not ask user for permission for apps to connect to USB devices.
+         Do not set this to true for production devices. Doing so will cause you to fail CTS. -->
+    <bool name="config_disableUsbPermissionDialogs">false</bool>
 
     <!-- Minimum span needed to begin a touch scaling gesture.
          If the span is equal to or greater than this size, a scaling gesture
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f96195c..8ec2e6f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -22,6 +22,10 @@
     <dimen name="thumbnail_width">164dp</dimen>
     <!-- The height that is used when creating thumbnails of applications. -->
     <dimen name="thumbnail_height">145dp</dimen>
+    <!-- The width that is used when creating thumbnails of applications. -->
+    <dimen name="recents_thumbnail_width">256dp</dimen>
+    <!-- The height that is used when creating thumbnails of applications. -->
+    <dimen name="recents_thumbnail_height">256dp</dimen>
     <!-- The standard size (both width and height) of an application icon that
          will be displayed in the app launcher and elsewhere. -->
     <dimen name="app_icon_size">48dip</dimen>
@@ -50,16 +54,6 @@
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <dimen name="status_bar_edge_ignore">5dp</dimen>
 
-    <!-- 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">52sp</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 -->
-    <dimen name="fastscroll_thumb_height">52dp</dimen>
     <!-- Min width for a tablet device -->
     <dimen name="min_xlarge_screen_width">800dp</dimen>
 
@@ -77,18 +71,6 @@
     <!-- 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>
-
     <!-- Preference activity side margins -->
     <dimen name="preference_screen_side_margin">0dp</dimen>
     <!-- Preference activity side margins negative-->
@@ -356,6 +338,32 @@
     <!-- Outline width for video subtitles. -->
     <dimen name="subtitle_outline_width">2dp</dimen>
 
+    <!-- New TimePicker dimensions. -->
+    <item name="timepicker_circle_radius_multiplier" format="float" type="string">0.82</item>
+    <item name="timepicker_circle_radius_multiplier_24HourMode" format="float" type="string">0.85</item>
+    <item name="timepicker_selection_radius_multiplier" format="float" type="string">0.16</item>
+    <item name="timepicker_ampm_circle_radius_multiplier" format="float" type="string">0.19</item>
+    <item name="timepicker_numbers_radius_multiplier_normal" format="float" type="string">0.81</item>
+    <item name="timepicker_numbers_radius_multiplier_inner" format="float" type="string">0.60</item>
+    <item name="timepicker_numbers_radius_multiplier_outer" format="float" type="string">0.83</item>
+    <item name="timepicker_text_size_multiplier_normal" format="float" type="string">0.17</item>
+    <item name="timepicker_text_size_multiplier_inner" format="float" type="string">0.14</item>
+    <item name="timepicker_text_size_multiplier_outer" format="float" type="string">0.11</item>
+    <item name="timepicker_transition_mid_radius_multiplier" format="float" type="string">0.95</item>
+    <item name="timepicker_transition_end_radius_multiplier" format="float" type="string">1.3</item>
+
+    <dimen name="timepicker_time_label_size">60sp</dimen>
+    <dimen name="timepicker_extra_time_label_margin">-30dp</dimen>
+    <dimen name="timepicker_ampm_label_size">16sp</dimen>
+    <dimen name="timepicker_done_label_size">14sp</dimen>
+    <dimen name="timepicker_ampm_left_padding">6dip</dimen>
+    <dimen name="timepicker_separator_padding">4dip</dimen>
+    <dimen name="timepicker_header_height">96dip</dimen>
+    <dimen name="timepicker_minimum_margin_sides">48dip</dimen>
+    <dimen name="timepicker_minimum_margin_top_bottom">24dip</dimen>
+    <dimen name="timepicker_radial_picker_dimen">270dip</dimen>
+
     <!-- width of ImmersiveModeConfirmation (-1 for match_parent) -->
     <dimen name="immersive_mode_cling_width">-1px</dimen>
+
 </resources>
diff --git a/core/res/res/values/dimens_quantum.xml b/core/res/res/values/dimens_quantum.xml
new file mode 100644
index 0000000..3913752
--- /dev/null
+++ b/core/res/res/values/dimens_quantum.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+
+    <!-- Default height of an action bar. -->
+    <dimen name="action_bar_default_height_quantum">56dp</dimen>
+    <!-- Vertical padding around action bar icons. -->
+    <dimen name="action_bar_icon_vertical_padding_quantum">16dp</dimen>
+    <!-- Text size for action bar titles -->
+    <dimen name="action_bar_title_text_size_quantum">20sp</dimen>
+    <!-- Text size for action bar subtitles -->
+    <dimen name="action_bar_subtitle_text_size_quantum">16sp</dimen>
+    <!-- Top margin for action bar subtitles -->
+    <dimen name="action_bar_subtitle_top_margin_quantum">-3dp</dimen>
+    <!-- Bottom margin for action bar subtitles -->
+    <dimen name="action_bar_subtitle_bottom_margin_quantum">5dp</dimen>
+
+    <dimen name="text_size_display_4_quantum">112sp</dimen>
+    <dimen name="text_size_display_3_quantum">56sp</dimen>
+    <dimen name="text_size_display_2_quantum">45sp</dimen>
+    <dimen name="text_size_display_1_quantum">34sp</dimen>
+    <dimen name="text_size_headline_quantum">24sp</dimen>
+    <dimen name="text_size_title_quantum">20sp</dimen>
+    <dimen name="text_size_subhead_quantum">16sp</dimen>
+    <dimen name="text_size_body_2_quantum">14sp</dimen>
+    <dimen name="text_size_body_1_quantum">14sp</dimen>
+    <dimen name="text_size_caption_quantum">12sp</dimen>
+    <dimen name="text_size_menu_quantum">14sp</dimen>
+    <dimen name="text_size_button_quantum">14sp</dimen>
+
+</resources>
diff --git a/core/res/res/values/donottranslate_quantum.xml b/core/res/res/values/donottranslate_quantum.xml
new file mode 100644
index 0000000..83cc4e5
--- /dev/null
+++ b/core/res/res/values/donottranslate_quantum.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <string name="font_family_display_4_quantum">sans-serif-light</string>
+    <string name="font_family_display_3_quantum">sans-serif</string>
+    <string name="font_family_display_2_quantum">sans-serif</string>
+    <string name="font_family_display_1_quantum">sans-serif</string>
+    <string name="font_family_headline_quantum">sans-serif</string>
+    <string name="font_family_title_quantum">sans-serif-medium</string>
+    <string name="font_family_subhead_quantum">sans-serif</string>
+    <string name="font_family_body_2_quantum">sans-serif-medium</string>
+    <string name="font_family_body_1_quantum">sans-serif</string>
+    <string name="font_family_caption_quantum">sans-serif</string>
+    <string name="font_family_menu_quantum">sans-serif-medium</string>
+    <string name="font_family_button_quantum">sans-serif</string>
+
+</resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 5c0baaa..56bb15f 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -82,4 +82,5 @@
   <item type="id" name="action_bar_spinner" />
   <item type="id" name="current_scene" />
   <item type="id" name="scene_layoutid_cache" />
+  <item type="id" name="shared_element_name" />
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f6edf33..9493246 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2088,10 +2088,244 @@
   <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" id="0x010301e4" />
 
 <!-- ===============================================================
-    Resources added in version 20 of the platform
-    =============================================================== -->
+     Resources added in version 20 of the platform
+     =============================================================== -->
   <eat-comment />
 
   <public type="attr" name="banner" id="0x10103f2" />
   <public type="attr" name="windowSwipeToDismiss" id="0x10103f3" />
+
+<!-- ===============================================================
+     Resources added in version 21 of the platform
+     =============================================================== -->
+  <eat-comment />
+
+  <public type="attr" name="fragmentBreadCrumbsStyle" />
+  <public type="attr" name="fastScrollStyle" />
+  <public type="attr" name="windowContentTransitions" />
+  <public type="attr" name="windowContentTransitionManager" />
+  <public type="attr" name="translationZ" />
+  <public type="attr" name="tintMode" />
+  <public type="attr" name="controlX1" />
+  <public type="attr" name="controlY1" />
+  <public type="attr" name="controlX2" />
+  <public type="attr" name="controlY2" />
+  <public type="attr" name="sharedElementName" />
+  <public type="attr" name="transitionGroup" />
+  <public type="attr" name="requiredForProfile"/>
+  <public type="attr" name="pinned" />
+
+  <public type="dimen" name="recents_thumbnail_height" />
+  <public type="dimen" name="recents_thumbnail_width" />
+
+  <public type="id" name="shared_element_name" />
+
+  <public type="style" name="Widget.Holo.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.Holo.Light.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.DeviceDefault.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.DeviceDefault.Light.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.FastScroll" />
+  <public type="style" name="Widget.Holo.FastScroll" />
+  <public type="style" name="Widget.Holo.Light.FastScroll" />
+  <public type="style" name="Widget.DeviceDefault.FastScroll" />
+  <public type="style" name="Widget.DeviceDefault.Light.FastScroll" />
+
+  <public type="style" name="TextAppearance.Quantum" />
+  <public type="style" name="TextAppearance.Quantum.DialogWindowTitle" />
+  <public type="style" name="TextAppearance.Quantum.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.Large" />
+  <public type="style" name="TextAppearance.Quantum.Large.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.Medium" />
+  <public type="style" name="TextAppearance.Quantum.Medium.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.SearchResult.Subtitle" />
+  <public type="style" name="TextAppearance.Quantum.SearchResult.Title" />
+  <public type="style" name="TextAppearance.Quantum.Small" />
+  <public type="style" name="TextAppearance.Quantum.Small.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.WindowTitle" />
+
+  <public type="style" name="TextAppearance.Quantum.Widget" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Menu" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title" />
+  <public type="style" name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" />
+  <public type="style" name="TextAppearance.Quantum.Widget.Button" />
+  <public type="style" name="TextAppearance.Quantum.Widget.DropDownHint" />
+  <public type="style" name="TextAppearance.Quantum.Widget.DropDownItem" />
+  <public type="style" name="TextAppearance.Quantum.Widget.EditText" />
+  <public type="style" name="TextAppearance.Quantum.Widget.IconMenu.Item" />
+  <public type="style" name="TextAppearance.Quantum.Widget.PopupMenu" />
+  <public type="style" name="TextAppearance.Quantum.Widget.PopupMenu.Large" />
+  <public type="style" name="TextAppearance.Quantum.Widget.PopupMenu.Small" />
+  <public type="style" name="TextAppearance.Quantum.Widget.TabWidget" />
+  <public type="style" name="TextAppearance.Quantum.Widget.TextView" />
+  <public type="style" name="TextAppearance.Quantum.Widget.TextView.PopupMenu" />
+  <public type="style" name="TextAppearance.Quantum.Widget.TextView.SpinnerItem" />
+
+  <public type="style" name="Theme.Quantum" />
+  <public type="style" name="Theme.Quantum.Dialog" />
+  <public type="style" name="Theme.Quantum.Dialog.MinWidth" />
+  <public type="style" name="Theme.Quantum.Dialog.NoActionBar" />
+  <public type="style" name="Theme.Quantum.Dialog.NoActionBar.MinWidth" />
+  <public type="style" name="Theme.Quantum.DialogWhenLarge" />
+  <public type="style" name="Theme.Quantum.DialogWhenLarge.NoActionBar" />
+  <public type="style" name="Theme.Quantum.InputMethod" />
+  <public type="style" name="Theme.Quantum.NoActionBar" />
+  <public type="style" name="Theme.Quantum.NoActionBar.Fullscreen" />
+  <public type="style" name="Theme.Quantum.NoActionBar.Overscan" />
+  <public type="style" name="Theme.Quantum.NoActionBar.TranslucentDecor" />
+  <public type="style" name="Theme.Quantum.Panel" />
+  <public type="style" name="Theme.Quantum.Wallpaper" />
+  <public type="style" name="Theme.Quantum.Wallpaper.NoTitleBar" />
+
+  <public type="style" name="Theme.Quantum.Light" />
+  <public type="style" name="Theme.Quantum.Light.DarkActionBar" />
+  <public type="style" name="Theme.Quantum.Light.Dialog" />
+  <public type="style" name="Theme.Quantum.Light.Dialog.MinWidth" />
+  <public type="style" name="Theme.Quantum.Light.Dialog.NoActionBar" />
+  <public type="style" name="Theme.Quantum.Light.Dialog.NoActionBar.MinWidth" />
+  <public type="style" name="Theme.Quantum.Light.DialogWhenLarge" />
+  <public type="style" name="Theme.Quantum.Light.DialogWhenLarge.NoActionBar" />
+  <public type="style" name="Theme.Quantum.Light.NoActionBar" />
+  <public type="style" name="Theme.Quantum.Light.NoActionBar.Fullscreen" />
+  <public type="style" name="Theme.Quantum.Light.NoActionBar.Overscan" />
+  <public type="style" name="Theme.Quantum.Light.NoActionBar.TranslucentDecor" />
+  <public type="style" name="Theme.Quantum.Light.Panel" />
+
+  <public type="style" name="Widget.Quantum" />
+  <public type="style" name="Widget.Quantum.ActionBar" />
+  <public type="style" name="Widget.Quantum.ActionBar.Solid" />
+  <public type="style" name="Widget.Quantum.ActionBar.TabBar" />
+  <public type="style" name="Widget.Quantum.ActionBar.TabText" />
+  <public type="style" name="Widget.Quantum.ActionBar.TabView" />
+  <public type="style" name="Widget.Quantum.ActionButton" />
+  <public type="style" name="Widget.Quantum.ActionButton.CloseMode" />
+  <public type="style" name="Widget.Quantum.ActionButton.Overflow" />
+  <public type="style" name="Widget.Quantum.ActionButton.TextButton" />
+  <public type="style" name="Widget.Quantum.ActionMode" />
+  <public type="style" name="Widget.Quantum.AutoCompleteTextView" />
+  <public type="style" name="Widget.Quantum.Button" />
+  <public type="style" name="Widget.Quantum.Button.Borderless" />
+  <public type="style" name="Widget.Quantum.Button.Borderless.Small" />
+  <public type="style" name="Widget.Quantum.Button.Inset" />
+  <public type="style" name="Widget.Quantum.Button.Small" />
+  <public type="style" name="Widget.Quantum.Button.Toggle" />
+  <public type="style" name="Widget.Quantum.CalendarView" />
+  <public type="style" name="Widget.Quantum.CheckedTextView" />
+  <public type="style" name="Widget.Quantum.CompoundButton.CheckBox" />
+  <public type="style" name="Widget.Quantum.CompoundButton.RadioButton" />
+  <public type="style" name="Widget.Quantum.CompoundButton.Star" />
+  <public type="style" name="Widget.Quantum.DatePicker" />
+  <public type="style" name="Widget.Quantum.DropDownItem" />
+  <public type="style" name="Widget.Quantum.DropDownItem.Spinner" />
+  <public type="style" name="Widget.Quantum.EditText" />
+  <public type="style" name="Widget.Quantum.ExpandableListView" />
+  <public type="style" name="Widget.Quantum.FastScroll" />
+  <public type="style" name="Widget.Quantum.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.Quantum.GridView" />
+  <public type="style" name="Widget.Quantum.HorizontalScrollView" />
+  <public type="style" name="Widget.Quantum.ImageButton" />
+  <public type="style" name="Widget.Quantum.ListPopupWindow" />
+  <public type="style" name="Widget.Quantum.ListView" />
+  <public type="style" name="Widget.Quantum.ListView.DropDown" />
+  <public type="style" name="Widget.Quantum.MediaRouteButton" />
+  <public type="style" name="Widget.Quantum.PopupMenu" />
+  <public type="style" name="Widget.Quantum.PopupWindow" />
+  <public type="style" name="Widget.Quantum.ProgressBar" />
+  <public type="style" name="Widget.Quantum.ProgressBar.Horizontal" />
+  <public type="style" name="Widget.Quantum.ProgressBar.Large" />
+  <public type="style" name="Widget.Quantum.ProgressBar.Small" />
+  <public type="style" name="Widget.Quantum.ProgressBar.Small.Title" />
+  <public type="style" name="Widget.Quantum.RatingBar" />
+  <public type="style" name="Widget.Quantum.RatingBar.Indicator" />
+  <public type="style" name="Widget.Quantum.RatingBar.Small" />
+  <public type="style" name="Widget.Quantum.ScrollView" />
+  <public type="style" name="Widget.Quantum.SeekBar" />
+  <public type="style" name="Widget.Quantum.Spinner" />
+  <public type="style" name="Widget.Quantum.Tab" />
+  <public type="style" name="Widget.Quantum.TabWidget" />
+  <public type="style" name="Widget.Quantum.TextView" />
+  <public type="style" name="Widget.Quantum.TextView.SpinnerItem" />
+  <public type="style" name="Widget.Quantum.WebTextView" />
+  <public type="style" name="Widget.Quantum.WebView" />
+
+  <public type="style" name="Widget.Quantum.Light" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.Solid" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.Solid.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.TabBar" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.TabBar.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.TabText" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.TabText.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.TabView" />
+  <public type="style" name="Widget.Quantum.Light.ActionBar.TabView.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ActionButton" />
+  <public type="style" name="Widget.Quantum.Light.ActionButton.CloseMode" />
+  <public type="style" name="Widget.Quantum.Light.ActionButton.Overflow" />
+  <public type="style" name="Widget.Quantum.Light.ActionMode.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ActionMode" />
+  <public type="style" name="Widget.Quantum.Light.AutoCompleteTextView" />
+  <public type="style" name="Widget.Quantum.Light.Button" />
+  <public type="style" name="Widget.Quantum.Light.Button.Borderless.Small" />
+  <public type="style" name="Widget.Quantum.Light.Button.Inset" />
+  <public type="style" name="Widget.Quantum.Light.Button.Small" />
+  <public type="style" name="Widget.Quantum.Light.Button.Toggle" />
+  <public type="style" name="Widget.Quantum.Light.CalendarView" />
+  <public type="style" name="Widget.Quantum.Light.CheckedTextView" />
+  <public type="style" name="Widget.Quantum.Light.CompoundButton.CheckBox" />
+  <public type="style" name="Widget.Quantum.Light.CompoundButton.RadioButton" />
+  <public type="style" name="Widget.Quantum.Light.CompoundButton.Star" />
+  <public type="style" name="Widget.Quantum.Light.DropDownItem" />
+  <public type="style" name="Widget.Quantum.Light.DropDownItem.Spinner" />
+  <public type="style" name="Widget.Quantum.Light.EditText" />
+  <public type="style" name="Widget.Quantum.Light.ExpandableListView" />
+  <public type="style" name="Widget.Quantum.Light.FastScroll" />
+  <public type="style" name="Widget.Quantum.Light.FragmentBreadCrumbs" />
+  <public type="style" name="Widget.Quantum.Light.GridView" />
+  <public type="style" name="Widget.Quantum.Light.HorizontalScrollView" />
+  <public type="style" name="Widget.Quantum.Light.ImageButton" />
+  <public type="style" name="Widget.Quantum.Light.ListPopupWindow" />
+  <public type="style" name="Widget.Quantum.Light.ListView" />
+  <public type="style" name="Widget.Quantum.Light.ListView.DropDown" />
+  <public type="style" name="Widget.Quantum.Light.MediaRouteButton" />
+  <public type="style" name="Widget.Quantum.Light.PopupMenu" />
+  <public type="style" name="Widget.Quantum.Light.PopupWindow" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar.Horizontal" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar.Large" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar.Large.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar.Small" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar.Small.Inverse" />
+  <public type="style" name="Widget.Quantum.Light.ProgressBar.Small.Title" />
+  <public type="style" name="Widget.Quantum.Light.RatingBar" />
+  <public type="style" name="Widget.Quantum.Light.RatingBar.Indicator" />
+  <public type="style" name="Widget.Quantum.Light.RatingBar.Small" />
+  <public type="style" name="Widget.Quantum.Light.ScrollView" />
+  <public type="style" name="Widget.Quantum.Light.SeekBar" />
+  <public type="style" name="Widget.Quantum.Light.Spinner" />
+  <public type="style" name="Widget.Quantum.Light.Tab" />
+  <public type="style" name="Widget.Quantum.Light.TabWidget" />
+  <public type="style" name="Widget.Quantum.Light.TextView" />
+  <public type="style" name="Widget.Quantum.Light.TextView.SpinnerItem" />
+  <public type="style" name="Widget.Quantum.Light.WebTextView" />
+  <public type="style" name="Widget.Quantum.Light.WebView" />
+
+  <public type="style" name="Quantum.ButtonBar.AlertDialog" />
+  <public type="style" name="Quantum.ButtonBar" />
+  <public type="style" name="Quantum.SegmentedButton" />
+
+  <public type="style" name="Quantum.Light.ButtonBar.AlertDialog" />
+  <public type="style" name="Quantum.Light.ButtonBar" />
+  <public type="style" name="Quantum.Light.SegmentedButton" />
+
+  <public type="style" name="Widget.Quantum.Button.Paper" />
+  <public type="style" name="Widget.Quantum.Button.Paper.Color" />
+
+  <public type="style" name="Widget.Quantum.Light.Button.Paper" />
+  <public type="style" name="Widget.Quantum.Light.Button.Paper.Color" />
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 115bac0..0699e8b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -625,9 +625,9 @@
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_processOutgoingCalls">reroute outgoing calls</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_processOutgoingCalls">Allows the app to process
-      outgoing calls and change the number to be dialed. This permission allows
-      the app to monitor, redirect, or prevent outgoing calls.</string>
+    <string name="permdesc_processOutgoingCalls">Allows the app to see the
+        number being dialed during an outgoing call with the option to redirect
+        the call to a different number or abort the call altogether.</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_receiveSms">receive text messages (SMS)</string>
@@ -830,13 +830,6 @@
          user consent.</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_retrieve_window_info">retrieve window info</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_retrieve_window_info">Allows an application to retrieve
-         information about the the windows from the window manager. Malicious apps may
-         retrieve information that is intended for internal system usage.</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_filter_events">filter events</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_filter_events">Allows an application to register an input filter
@@ -844,13 +837,6 @@
             may control the system UI whtout user intervention.</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_magnify_display">magnify display</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_magnify_display">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>
-
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_shutdown">partial shutdown</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_shutdown">Puts the activity manager into a shutdown
@@ -1175,6 +1161,15 @@
     <!-- 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 a permission that is never presented to the user.  This is not a
+         permission that an application must be granted by the user.  Instead, it
+         is part of a mechanism that applications use to indicate to the system
+         that they want to do occasional work while the device is idle.  -->
+    <string name="permlab_bindIdleService">run application during idle time</string>
+    <!-- Description of an application permission, so that the user can understand
+         what is being done if they are curious. -->
+    <string name="permdesc_bindIdleService">This permission allows the Android system to run the application in the background while the device is not in use.</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. -->
@@ -1431,6 +1426,11 @@
     <string name="permdesc_readFrameBuffer">Allows the app to read the content of the frame buffer.</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_accessInputFlinger">access InputFlinger</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_accessInputFlinger">Allows the app to use InputFlinger low-level features.</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_configureWifiDisplay">configure Wifi displays</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_configureWifiDisplay">Allows the app to configure and connect to Wifi displays.</string>
@@ -1479,6 +1479,11 @@
       without your confirmation.</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_sim_communication">sim communication</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_sim_communication">Allows the app to send commands to the SIM. This is very dangerous.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_camera">take pictures and videos</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_camera">Allows the app to take pictures and videos
@@ -1993,6 +1998,10 @@
     <!-- 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>
 
+    <string name="permlab_setInputCalibration">change input device calibration</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_setInputCalibration">Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps.</string>
+
     <!-- Policy administration -->
 
     <!-- Title of policy access to limiting the user's password choices -->
@@ -3642,6 +3651,11 @@
     <!-- Description of an application permission that lets it control keyguard. -->
     <string name="permdesc_control_keyguard">Allows an application to control keguard.</string>
 
+    <!-- Title of an application permission that lets it interact with recovery. -->
+    <string name="permlab_recovery">Interact with update and recovery system</string>
+    <!-- Description of an application permission that lets it control keyguard. -->
+    <string name="permdesc_recovery">Allows an application to interact with the recovery system and system updates.</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>
 
@@ -3933,26 +3947,6 @@
     <!-- Description of the sliding handle in the Slide unlock screen. [CHAR LIMIT=NONE] -->
     <string name="content_description_sliding_handle">"Sliding handle. Touch &amp; hold."</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>
-
-    <!-- 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 unlock handle in the Slide unlock screen for tablets. [CHAR LIMIT=NONE] -->
     <string name="description_target_unlock_tablet">Swipe to unlock.</string>
 
@@ -4533,4 +4527,55 @@
     <!-- Cling help message when hiding the navigation bar entering immersive mode [CHAR LIMIT=none] -->
     <string name="immersive_mode_confirmation" msgid="8554991488096662508">Swipe down from the top to exit full screen.</string>
 
+    <!-- Label for button to confirm chosen date or time [CHAR LIMIT=30] -->
+    <string name="done_label">Done</string>
+    <!--
+         Content description for the hour selector in the time picker, which displays
+         selectable hours of the day along the inside edge of a circle, as in an analog clock.
+         [CHAR LIMIT=50]
+    -->
+    <string name="hour_picker_description">Hours circular slider</string>
+    <!--
+         Content description for the minute selector in the time picker, which displays
+         selectable five-minute intervals along the inside edge of a circle, as in an analog clock.
+         [CHAR LIMIT=50]
+    -->
+    <string name="minute_picker_description">Minutes circular slider</string>
+    <!-- Accessibility announcement for hour circular picker [CHAR LIMIT=NONE] -->
+    <string name="select_hours">Select hours</string>
+    <!-- Accessibility announcement for minute circular picker [CHAR LIMIT=NONE] -->
+    <string name="select_minutes">Select minutes</string>
+
+    <!--
+        Content description for the month and day selector in the date picker, which displays
+        a selectable grid of days laid out by month.
+        [CHAR LIMIT=50]
+     -->
+    <string name="day_picker_description">Month grid of days</string>
+    <!--
+        Content description for the year selector in the date picker, which displays
+        a scrolling, vertical list of years.
+        [CHAR LIMIT=50]
+     -->
+    <string name="year_picker_description">Year list</string>
+    <!-- Accessibility announcement for the day picker [CHAR LIMIT=NONE] -->
+    <string name="select_day">Select month and day</string>
+    <!-- Accessibility announcement for the year picker [CHAR LIMIT=NONE] -->
+    <string name="select_year">Select year</string>
+    <!-- Accessibility description for the item that is currently selected. -->
+    <string name="item_is_selected"><xliff:g id="item" example="2013">%1$s</xliff:g> selected</string>
+    <!-- Accessibility announcement when a number that had been typed in is deleted [CHAR_LIMIT=NONE] -->
+    <string name="deleted_key"><xliff:g id="key" example="4">%1$s</xliff:g> deleted</string>
+
+    <!-- DO NOT TRANSLATE -->
+    <string name="time_placeholder">--</string>
+
+    <!-- DO NOT TRANSLATE -->
+    <string name="radial_numbers_typeface">sans-serif</string>
+    <!-- DO NOT TRANSLATE -->
+    <string name="sans_serif">sans-serif</string>
+
+    <!-- DO NOT TRANSLATE -->
+    <string name="day_of_week_label_typeface">sans-serif</string>
+
 </resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 4d4feeee..be875ff 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -271,6 +271,33 @@
         <item name="android:textColor">#CCCCCC</item>
     </style>
 
+    <style name="TextAppearance.StatusBar.Quantum">
+    </style>
+    <style name="TextAppearance.StatusBar.Quantum.EventContent">
+        <item name="android:textColor">#888888</item>
+        <item name="android:textSize">@dimen/notification_text_size</item>
+    </style>
+    <style name="TextAppearance.StatusBar.Quantum.EventContent.Title">
+        <item name="android:textColor">#000000</item>
+        <item name="android:fontFamily">sans-serif-light</item>
+        <item name="android:textSize">@dimen/notification_title_text_size</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+    <style name="TextAppearance.StatusBar.Quantum.EventContent.Line2">
+        <item name="android:textSize">@dimen/notification_subtext_size</item>
+    </style>
+    <style name="TextAppearance.StatusBar.Quantum.EventContent.Info">
+        <item name="android:textSize">@dimen/notification_subtext_size</item>
+        <item name="android:textColor">#888888</item>
+    </style>
+    <style name="TextAppearance.StatusBar.Quantum.EventContent.Time">
+        <item name="android:textSize">@dimen/notification_subtext_size</item>
+        <item name="android:textColor">#888888</item>
+    </style>
+    <style name="TextAppearance.StatusBar.Quantum.EventContent.Emphasis">
+        <item name="android:textColor">#555555</item>
+    </style>
+
     <style name="TextAppearance.Small.CalendarViewWeekDayView">
         <item name="android:textStyle">bold</item>
     </style>
@@ -300,6 +327,7 @@
     <style name="Widget.AbsListView">
         <item name="android:scrollbars">vertical</item>
         <item name="android:fadingEdge">vertical</item>
+        <item name="android:fastScrollStyle">?android:attr/fastScrollStyle</item>
     </style>
 
     <style name="Widget.GestureOverlayView">
@@ -518,6 +546,11 @@
         <item name="android:childDivider">@android:drawable/divider_horizontal_bright_opaque</item>
     </style>
 
+    <style name="Widget.FragmentBreadCrumbs">
+        <item name="android:padding">4dp</item>
+        <item name="android:animateLayoutChanges">true</item>
+    </style>
+
     <style name="Widget.ImageWell">
         <item name="android:background">@android:drawable/panel_picture_frame_background</item>
     </style>
@@ -552,7 +585,7 @@
     </style>
 
     <style name="Widget.TimePicker">
-        <item name="android:internalLayout">@android:layout/time_picker</item>
+        <item name="android:legacyLayout">@android:layout/time_picker_legacy</item>
     </style>
 
     <style name="Widget.DatePicker">
@@ -689,12 +722,6 @@
         <item name="android:popupAnimationStyle">@android:style/Animation.PopupWindow</item>
     </style>
 
-    <!-- Default style for {@link android.app.FragmentBreadCrumbs} view. -->
-    <style name="Widget.FragmentBreadCrumbs">
-        <item name="android:padding">4dp</item>
-        <item name="android:animateLayoutChanges">true</item>
-    </style>
-
     <style name="Widget.KeyboardView" parent="android:Widget">
         <item name="android:background">@android:drawable/keyboard_background</item>
         <item name="android:keyBackground">@android:drawable/btn_keyboard_key</item>
@@ -1670,6 +1697,9 @@
     <style name="Widget.Holo.ExpandableListView.White">
     </style>
 
+    <style name="Widget.Holo.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs">
+    </style>
+
     <style name="Widget.Holo.Gallery" parent="Widget.Gallery">
     </style>
 
@@ -1706,7 +1736,18 @@
     </style>
 
     <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
+        <item name="android:legacyLayout">@android:layout/time_picker_legacy_holo</item>
         <item name="android:internalLayout">@android:layout/time_picker_holo</item>
+        <item name="android:disabledColor">@android:color/timepicker_default_disabled_color_holo_dark</item>
+        <item name="android:headerSelectedTextColor">@android:color/holo_blue_light</item>
+        <item name="android:headerUnselectedTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:headerBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+        <item name="android:numbersTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:numbersBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+        <item name="android:amPmTextColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:amPmUnselectedBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+        <item name="android:amPmSelectedBackgroundColor">@android:color/holo_blue_light</item>
+        <item name="android:numbersSelectorColor">@android:color/holo_blue_light</item>
     </style>
 
     <style name="Widget.Holo.DatePicker" parent="Widget.DatePicker">
@@ -2099,6 +2140,9 @@
     <style name="Widget.Holo.Light.ExpandableListView.White">
     </style>
 
+    <style name="Widget.Holo.Light.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs">
+    </style>
+
     <style name="Widget.Holo.Light.Gallery" parent="Widget.Gallery">
     </style>
 
@@ -2124,7 +2168,19 @@
     <style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker">
     </style>
 
-    <style name="Widget.Holo.Light.TimePicker" parent="Widget.Holo.TimePicker">
+    <style name="Widget.Holo.Light.TimePicker" parent="Widget.TimePicker">
+        <item name="android:legacyLayout">@android:layout/time_picker_legacy_holo</item>
+        <item name="android:internalLayout">@android:layout/time_picker_holo</item>
+        <item name="android:disabledColor">@android:color/timepicker_default_disabled_color_holo_light</item>
+        <item name="android:headerSelectedTextColor">@android:color/holo_blue_light</item>
+        <item name="android:headerUnselectedTextColor">@android:color/timepicker_default_text_color_holo_light</item>
+        <item name="android:headerBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+        <item name="android:numbersTextColor">@android:color/timepicker_default_text_color_holo_light</item>
+        <item name="android:numbersBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+        <item name="android:amPmTextColor">@android:color/timepicker_default_text_color_holo_light</item>
+        <item name="android:amPmUnselectedBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+        <item name="android:amPmSelectedBackgroundColor">@android:color/holo_blue_light</item>
+        <item name="android:numbersSelectorColor">@android:color/holo_blue_light</item>
     </style>
 
     <style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker">
@@ -2503,13 +2559,8 @@
         <item name="android:contentDescription">@android:string/media_route_button_content_description</item>
     </style>
 
-    <style name="Widget.Holo.Light.MediaRouteButton">
-        <item name="android:background">?android:attr/selectableItemBackground</item>
+    <style name="Widget.Holo.Light.MediaRouteButton" parent="Widget.Holo.MediaRouteButton">
         <item name="android:externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
-        <item name="android:minWidth">56dp</item>
-        <item name="android:minHeight">48dp</item>
-        <item name="android:focusable">true</item>
-        <item name="android:contentDescription">@android:string/media_route_button_content_description</item>
     </style>
 
     <!-- Keyguard PIN pad styles -->
@@ -2539,4 +2590,57 @@
         <item name="android:textColor">#80ffffff</item>
     </style>
 
+    <style name="TextAppearance.TimePicker.TimeLabel" parent="TextAppearance">
+    </style>
+
+    <style name="TextAppearance.TimePicker.AmPmLabel" parent="TextAppearance">
+    </style>
+
+    <style name="TextAppearance.Holo.TimePicker.TimeLabel" parent="TextAppearance.Holo">
+        <item name="android:textSize">@dimen/timepicker_time_label_size</item>
+        <item name="android:textColor">@android:color/timepicker_default_text_color_holo_dark</item>
+    </style>
+
+    <style name="TextAppearance.Holo.TimePicker.AmPmLabel" parent="TextAppearance.Holo">
+        <item name="android:textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:textColor">@android:color/timepicker_default_text_color_holo_dark</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="TextAppearance.Holo.Light.TimePicker.TimeLabel" parent="TextAppearance.Holo.Light">
+        <item name="android:textSize">@dimen/timepicker_time_label_size</item>
+        <item name="android:textColor">@color/timepicker_default_text_color_holo_light</item>
+    </style>
+
+    <style name="TextAppearance.Holo.Light.TimePicker.AmPmLabel" parent="TextAppearance.Holo.Light">
+        <item name="android:textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="android:textAllCaps">true</item>
+        <item name="android:textColor">@color/timepicker_default_text_color_holo_light</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="Widget.FastScroll">
+        <item name="android:thumbDrawable">?android:attr/fastScrollThumbDrawable</item>
+        <item name="android:trackDrawable">?android:attr/fastScrollTrackDrawable</item>
+        <item name="android:backgroundLeft">?android:attr/fastScrollPreviewBackgroundLeft</item>
+        <item name="android:backgroundRight">?android:attr/fastScrollPreviewBackgroundRight</item>
+        <item name="android:position">?android:attr/fastScrollOverlayPosition</item>
+        <item name="android:textColor">?android:attr/fastScrollTextColor</item>
+        <item name="android:thumbMinWidth">64dp</item>
+        <item name="android:thumbMinHeight">52dp</item>
+        <item name="android:textSize">52sp</item>
+        <item name="android:minWidth">72dp</item>
+        <item name="android:minHeight">72dp</item>
+        <item name="android:padding">16dp</item>
+    </style>
+
+    <style name="Widget.Holo.FastScroll" parent="Widget.FastScroll">
+        <item name="android:thumbMinWidth">0dp</item>
+        <item name="android:thumbMinHeight">0dp</item>
+    </style>
+
+    <style name="Widget.Holo.Light.FastScroll" parent="Widget.Holo.FastScroll">
+    </style>
+
 </resources>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index edeba02..512c9b8 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -206,6 +206,12 @@
     <style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Holo.ExpandableListView.White">
 
     </style>
+    <style name="Widget.DeviceDefault.FastScroll" parent="Widget.Holo.FastScroll">
+
+    </style>
+    <style name="Widget.DeviceDefault.FragmentBreadCrumbs" parent="Widget.Holo.FragmentBreadCrumbs">
+
+    </style>
     <style name="Widget.DeviceDefault.Gallery" parent="Widget.Holo.Gallery">
 
     </style>
@@ -309,6 +315,12 @@
     <style name="Widget.DeviceDefault.Light.ExpandableListView" parent="Widget.Holo.Light.ExpandableListView" >
 
     </style>
+    <style name="Widget.DeviceDefault.Light.FastScroll" parent="Widget.Holo.Light.FastScroll">
+
+    </style>
+    <style name="Widget.DeviceDefault.Light.FragmentBreadCrumbs" parent="Widget.Holo.Light.FragmentBreadCrumbs">
+
+    </style>
     <style name="Widget.DeviceDefault.Light.GridView" parent="Widget.Holo.Light.GridView" >
 
     </style>
@@ -729,4 +741,22 @@
     <style name="Widget.DeviceDefault.MediaRouteButton" parent="Widget.Holo.MediaRouteButton" />
     <style name="Widget.DeviceDefault.Light.MediaRouteButton" parent="Widget.Holo.Light.MediaRouteButton" />
 
+    <style name="TextAppearance.DeviceDefault.TimePicker.TimeLabel" parent="TextAppearance.Holo.TimePicker.TimeLabel">
+    </style>
+
+    <style name="TextAppearance.DeviceDefault.Light.TimePicker.TimeLabel" parent="TextAppearance.Holo.Light.TimePicker.TimeLabel">
+    </style>
+
+    <style name="TextAppearance.DeviceDefault.TimePicker.AmPmLabel" parent="TextAppearance.Holo.TimePicker.AmPmLabel">
+    </style>
+
+    <style name="TextAppearance.DeviceDefault.Light.TimePicker.AmPmLabel" parent="TextAppearance.Holo.Light.TimePicker.AmPmLabel">
+    </style>
+
+    <style name="Theme.DeviceDefault.Dialog.TimePicker" parent="Theme.Holo.Dialog.TimePicker">
+    </style>
+
+    <style name="Theme.DeviceDefault.Light.Dialog.TimePicker" parent="Theme.Holo.Light.Dialog.TimePicker">
+    </style>
+
 </resources>
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
new file mode 100644
index 0000000..44cdb5f
--- /dev/null
+++ b/core/res/res/values/styles_quantum.xml
@@ -0,0 +1,1211 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Quantum themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+ -->
+<resources>
+    <!-- Preference styles -->
+    <eat-comment />
+
+    <style name="Preference.Quantum">
+        <item name="layout">@layout/preference_holo</item>
+    </style>
+
+    <style name="PreferenceFragment.Quantum">
+        <item name="paddingStart">@dimen/preference_fragment_padding_side</item>
+        <item name="paddingEnd">@dimen/preference_fragment_padding_side</item>
+    </style>
+
+    <style name="Preference.Quantum.Information">
+        <item name="layout">@layout/preference_information_holo</item>
+        <item name="enabled">false</item>
+        <item name="shouldDisableView">false</item>
+    </style>
+
+    <style name="Preference.Quantum.Category">
+        <item name="layout">@layout/preference_category_holo</item>
+        <!-- The title should not dim if the category is disabled, instead only the preference children should dim. -->
+        <item name="shouldDisableView">false</item>
+        <item name="selectable">false</item>
+    </style>
+
+    <style name="Preference.Quantum.CheckBoxPreference">
+        <item name="widgetLayout">@layout/preference_widget_checkbox</item>
+    </style>
+
+    <style name="Preference.Quantum.SwitchPreference">
+        <item name="widgetLayout">@layout/preference_widget_switch</item>
+        <item name="switchTextOn">@string/capital_on</item>
+        <item name="switchTextOff">@string/capital_off</item>
+    </style>
+
+    <style name="Preference.Quantum.PreferenceScreen"/>
+
+    <style name="Preference.Quantum.DialogPreference">
+        <item name="positiveButtonText">@string/ok</item>
+        <item name="negativeButtonText">@string/cancel</item>
+    </style>
+
+    <style name="Preference.Quantum.DialogPreference.YesNoPreference">
+        <item name="positiveButtonText">@string/yes</item>
+        <item name="negativeButtonText">@string/no</item>
+    </style>
+
+    <style name="Preference.Quantum.DialogPreference.EditTextPreference">
+        <item name="dialogLayout">@layout/preference_dialog_edittext</item>
+    </style>
+
+    <style name="Preference.Quantum.RingtonePreference">
+        <item name="ringtoneType">ringtone</item>
+        <item name="showSilent">true</item>
+        <item name="showDefault">true</item>
+    </style>
+
+    <!-- Begin Quantum theme styles -->
+
+    <!-- Text styles -->
+
+    <style name="TextAppearance.Quantum" parent="TextAppearance"/>
+
+    <style name="TextAppearance.Quantum.Inverse" parent="TextAppearance.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Large" parent="TextAppearance.Large"/>
+
+    <style name="TextAppearance.Quantum.Large.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Medium" parent="TextAppearance.Medium"/>
+
+    <style name="TextAppearance.Quantum.Medium.Inverse">
+        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Small" parent="TextAppearance.Small"/>
+
+    <style name="TextAppearance.Quantum.Small.Inverse">
+        <item name="textColor">?attr/textColorSecondaryInverse</item>
+        <item name="textColorHint">?attr/textColorHintInverse</item>
+        <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+        <item name="textColorLink">?attr/textColorLinkInverse</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.SearchResult">
+        <item name="textStyle">normal</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textColorHint">?attr/textColorHint</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.SearchResult.Title">
+         <item name="textSize">18sp</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.SearchResult.Subtitle">
+        <item name="textSize">14sp</item>
+        <item name="textColor">?attr/textColorSecondary</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget" parent="TextAppearance.Widget"/>
+
+    <style name="TextAppearance.Quantum.Widget.Button">
+        <item name="fontFamily">@string/font_family_button_quantum</item>
+        <item name="textSize">@dimen/text_size_button_quantum</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textStyle">normal</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.EditText">
+        <item name="textColor">?textColorPrimaryInverse</item>
+        <item name="textColorHint">?textColorHintInverse</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.Switch" parent="TextAppearance.Quantum.Small">
+        <item name="textColor">@color/secondary_text_quantum_dark</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.PopupMenu" parent="TextAppearance.Widget.PopupMenu">
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.PopupMenu.Large">
+        <item name="textSize">18sp</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.PopupMenu.Small">
+        <item name="textSize">14sp</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.DropDownHint">
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textSize">14sp</item>
+    </style>
+    <style name="TextAppearance.Quantum.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Small">
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <!-- This style is for smaller screens; values-xlarge defines a version
+         for larger screens. -->
+    <style name="TextAppearance.Quantum.Widget.TabWidget">
+        <item name="textSize">14sp</item>
+        <item name="textStyle">normal</item>
+        <item name="textColor">@color/tab_indicator_text</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.TextView">
+        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
+        <item name="textColorHint">?attr/textColorHint</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.TextView.PopupMenu">
+        <item name="textSize">18sp</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem" />
+
+    <style name="TextAppearance.Quantum.Widget.DropDownItem">
+        <item name="textColor">?attr/textColorPrimaryDisableOnly</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode"/>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Title" parent="TextAppearance.Quantum.Medium">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" parent="TextAppearance.Quantum.Small">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
+    </style>
+
+    <!-- Text styles with no light versions -->
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Title" parent="TextAppearance.Quantum.Medium">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" parent="TextAppearance.Quantum.Small">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionBar.Menu" parent="TextAppearance.Quantum.Small">
+        <item name="textSize">12sp</item>
+        <item name="textStyle">bold</item>
+        <item name="textColor">?attr/actionMenuTextColor</item>
+        <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
+        <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
+        <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.WindowTitle">
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textSize">14sp</item>
+        <item name="textStyle">bold</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.DialogWindowTitle">
+        <item name="textSize">22sp</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView">
+        <item name="textColor">#505050</item>
+    </style>
+
+    <!-- Light text styles -->
+    <style name="TextAppearance.Quantum.Light" parent="TextAppearance.Quantum"/>
+
+    <style name="TextAppearance.Quantum.Light.Inverse" parent="TextAppearance.Quantum.Inverse" />
+
+    <style name="TextAppearance.Quantum.Light.Large" parent="TextAppearance.Quantum.Large"/>
+
+    <style name="TextAppearance.Quantum.Light.Medium" parent="TextAppearance.Quantum.Medium"/>
+
+    <style name="TextAppearance.Quantum.Light.Small" parent="TextAppearance.Quantum.Small"/>
+
+    <style name="TextAppearance.Quantum.Light.Large.Inverse" parent="TextAppearance.Quantum.Large.Inverse" />
+
+    <style name="TextAppearance.Quantum.Light.Medium.Inverse" parent="TextAppearance.Quantum.Medium.Inverse" />
+
+    <style name="TextAppearance.Quantum.Light.Small.Inverse" parent="TextAppearance.Quantum.Small.Inverse" />
+
+    <style name="TextAppearance.Quantum.Light.SearchResult" parent="TextAppearance.Quantum.SearchResult" />
+
+    <style name="TextAppearance.Quantum.Light.SearchResult.Title" parent="TextAppearance.Quantum.SearchResult.Title" />
+
+    <style name="TextAppearance.Quantum.Light.SearchResult.Subtitle" parent="TextAppearance.Quantum.SearchResult.Subtitle" />
+
+    <style name="TextAppearance.Quantum.Light.Widget" parent="TextAppearance.Widget"/>
+
+    <style name="TextAppearance.Quantum.Light.Widget.Button" parent="TextAppearance.Quantum.Widget.Button" />
+
+    <style name="TextAppearance.Quantum.Light.Widget.EditText" parent="TextAppearance.Quantum.Widget.EditText" />
+
+    <style name="TextAppearance.Quantum.Light.Widget.Switch" parent="TextAppearance.Quantum.Small">
+        <item name="textColor">@color/secondary_text_quantum_dark</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Light.Widget.PopupMenu" parent="TextAppearance.Quantum.Widget.PopupMenu"/>
+
+    <style name="TextAppearance.Quantum.Light.Widget.PopupMenu.Large" parent="TextAppearance.Quantum.Widget.PopupMenu.Large"/>
+
+    <style name="TextAppearance.Quantum.Light.Widget.PopupMenu.Small" parent="TextAppearance.Quantum.Widget.PopupMenu.Small"/>
+
+    <style name="TextAppearance.Quantum.Light.Widget.DropDownHint" parent="TextAppearance.Quantum.Widget.DropDownHint"/>
+
+    <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Title" parent="TextAppearance.Widget.ActionMode.Title"/>
+
+    <style name="TextAppearance.Quantum.Light.Widget.ActionMode.Subtitle" parent="TextAppearance.Widget.ActionMode.Subtitle"/>
+
+    <style name="TextAppearance.Quantum.Light.WindowTitle" parent="TextAppearance.Quantum.WindowTitle" />
+
+    <style name="TextAppearance.Quantum.Light.DialogWindowTitle" parent="TextAppearance.Quantum.DialogWindowTitle" />
+
+    <style name="TextAppearance.Quantum.Light.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView"/>
+
+    <!-- Widget Styles -->
+
+
+    <style name="Quantum" />
+    <style name="Quantum.Light" />
+
+    <style name="Widget.Quantum" parent="Widget" />
+
+    <!-- Bordered ink button -->
+    <style name="Widget.Quantum.Button" parent="Widget.Button">
+        <item name="background">@drawable/btn_default_quantum_dark</item>
+        <item name="textAppearance">?attr/textAppearanceButton</item>
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">96dip</item>
+    </style>
+
+    <!-- Small bordered ink button -->
+    <style name="Widget.Quantum.Button.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <!-- Bordered paper button -->
+    <style name="Widget.Quantum.Button.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
+
+    <!-- Bordered paper button with color -->
+    <style name="Widget.Quantum.Button.Paper.Color">
+        <item name="background">@drawable/btn_color_quantum_dark</item>
+    </style>
+
+    <!-- Borderless ink button -->
+    <style name="Widget.Quantum.Button.Borderless">
+        <item name="background">@drawable/btn_borderless_quantum_dark</item>
+    </style>
+
+    <!-- Small borderless ink button -->
+    <style name="Widget.Quantum.Button.Borderless.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <!-- Borderless paper button -->
+    <style name="Widget.Quantum.Button.Borderless.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
+    <style name="Widget.Quantum.Button.Inset">
+        <item name="background">@drawable/button_inset</item>
+    </style>
+
+    <style name="Widget.Quantum.Button.Toggle">
+        <item name="background">@drawable/btn_toggle_holo_dark</item>
+        <item name="textOn">@string/capital_on</item>
+        <item name="textOff">@string/capital_off</item>
+        <item name="textAppearance">?attr/textAppearanceSmall</item>
+        <item name="minHeight">48dip</item>
+    </style>
+
+    <style name="Quantum.ButtonBar" parent="ButtonBar">
+        <item name="paddingTop">0dip</item>
+        <item name="paddingStart">0dip</item>
+        <item name="paddingEnd">0dip</item>
+        <item name="paddingBottom">0dip</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="showDividers">middle</item>
+        <item name="dividerPadding">12dip</item>
+        <item name="background">@null</item>
+    </style>
+
+    <style name="Quantum.SegmentedButton" parent="SegmentedButton">
+        <item name="background">@drawable/btn_group_holo_dark</item>
+    </style>
+
+    <style name="Quantum.ButtonBar.AlertDialog">
+        <item name="background">@null</item>
+        <item name="dividerPadding">0dp</item>
+    </style>
+
+    <style name="Widget.Quantum.StackView">
+        <item name="resOutColor">@color/holo_blue_light</item>
+        <item name="clickColor">@color/holo_blue_light</item>
+    </style>
+
+    <style name="Widget.Quantum.TextView" parent="Widget.TextView"/>
+
+    <style name="Widget.Quantum.CheckedTextView" parent="Widget.CheckedTextView"/>
+
+    <style name="Widget.Quantum.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
+        <item name="background">@drawable/list_section_divider_quantum_dark</item>
+        <item name="textAllCaps">true</item>
+    </style>
+
+    <style name="Widget.Quantum.TextSelectHandle" parent="Widget.TextSelectHandle"/>
+
+    <style name="Widget.Quantum.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow"/>
+
+    <style name="Widget.Quantum.AbsListView" parent="Widget.AbsListView"/>
+
+    <style name="Widget.Quantum.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
+        <item name="dropDownSelector">@drawable/list_selector_holo_dark</item>
+        <item name="popupBackground">?attr/colorBackground</item>
+    </style>
+
+    <style name="Widget.Quantum.CompoundButton" parent="Widget.CompoundButton"/>
+
+    <style name="Widget.Quantum.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox"/>
+
+    <style name="Widget.Quantum.ListView.DropDown"/>
+
+    <style name="Widget.Quantum.EditText" parent="Widget.EditText"/>
+
+    <style name="Widget.Quantum.ExpandableListView" parent="Widget.Quantum.ListView">
+        <item name="groupIndicator">@drawable/expander_group_quantum_dark</item>
+        <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="childDivider">?attr/listDivider</item>
+    </style>
+
+    <style name="Widget.Quantum.ExpandableListView.White"/>
+
+    <style name="Widget.Quantum.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs"/>
+
+    <style name="Widget.Quantum.Gallery" parent="Widget.Gallery"/>
+
+    <style name="Widget.Quantum.GestureOverlayView" parent="Widget.GestureOverlayView"/>
+
+    <style name="Widget.Quantum.GridView" parent="Widget.GridView">
+        <item name="listSelector">?attr/selectableItemBackground</item>
+    </style>
+
+    <style name="Widget.Quantum.CalendarView" parent="Widget.CalendarView">
+        <item name="selectedWeekBackgroundColor">#330099FF</item>
+        <item name="focusedMonthDateColor">#FFFFFFFF</item>
+        <item name="unfocusedMonthDateColor">#66FFFFFF</item>
+        <item name="weekNumberColor">#33FFFFFF</item>
+        <item name="weekSeparatorLineColor">#19FFFFFF</item>
+        <item name="selectedDateVerticalBar">@drawable/day_picker_week_view_dayline_holo</item>
+        <item name="weekDayTextAppearance">@style/TextAppearance.Quantum.CalendarViewWeekDayView</item>
+    </style>
+
+    <style name="Widget.Quantum.ImageButton" parent="Widget.ImageButton">
+        <item name="background">@drawable/btn_default_quantum_dark</item>
+    </style>
+
+    <style name="Widget.Quantum.NumberPicker" parent="Widget.NumberPicker">
+        <item name="internalLayout">@layout/number_picker_with_selector_wheel</item>
+        <item name="solidColor">@color/transparent</item>
+        <item name="selectionDivider">@drawable/numberpicker_selection_divider</item>
+        <item name="selectionDividerHeight">2dip</item>
+        <item name="selectionDividersDistance">48dip</item>
+        <item name="internalMinWidth">64dip</item>
+        <item name="internalMaxHeight">180dip</item>
+        <item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item>
+    </style>
+
+    <style name="Widget.Quantum.TimePicker" parent="Widget.TimePicker">
+        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
+        <item name="internalLayout">@layout/time_picker_holo</item>
+        <item name="disabledColor">@color/timepicker_default_disabled_color_quantum_dark</item>
+        <item name="headerSelectedTextColor">@color/holo_blue_light</item>
+        <item name="headerUnselectedTextColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="headerBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+        <item name="numbersTextColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="numbersBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+        <item name="amPmTextColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="amPmUnselectedBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+        <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
+        <item name="numbersSelectorColor">@color/holo_blue_light</item>
+    </style>
+
+    <style name="Widget.Quantum.DatePicker" parent="Widget.DatePicker">
+        <item name="internalLayout">@layout/date_picker_holo</item>
+        <item name="calendarViewShown">true</item>
+    </style>
+
+    <style name="Widget.Quantum.ActivityChooserView" parent="Widget.ActivityChooserView"/>
+
+    <style name="Widget.Quantum.ImageWell" parent="Widget.ImageWell"/>
+
+    <style name="Widget.Quantum.ListView" parent="Widget.ListView">
+        <item name="divider">?attr/listDivider</item>
+        <item name="listSelector">?attr/listChoiceBackgroundIndicator</item>
+    </style>
+
+    <style name="Widget.Quantum.ListView.White"/>
+
+    <style name="Widget.Quantum.PopupWindow" parent="Widget.PopupWindow"/>
+
+    <style name="Widget.Quantum.PopupWindow.ActionMode">
+        <item name="popupBackground">@color/black</item>
+        <item name="popupAnimationStyle">@style/Animation.PopupWindow.ActionMode</item>
+    </style>
+
+    <style name="Widget.Quantum.ProgressBar" parent="Widget.ProgressBar">
+        <item name="indeterminateDrawable">@drawable/progress_medium_holo</item>
+    </style>
+
+    <style name="Widget.Quantum.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
+        <item name="progressDrawable">@drawable/progress_horizontal_quantum_dark</item>
+        <item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
+    </style>
+
+    <style name="Widget.Quantum.ProgressBar.Small" parent="Widget.ProgressBar.Small">
+        <item name="indeterminateDrawable">@drawable/progress_small_holo</item>
+    </style>
+
+    <style name="Widget.Quantum.ProgressBar.Small.Title"/>
+
+    <style name="Widget.Quantum.ProgressBar.Large" parent="Widget.ProgressBar.Large">
+        <item name="indeterminateDrawable">@drawable/progress_large_holo</item>
+    </style>
+
+    <style name="Widget.Quantum.ProgressBar.Inverse"/>
+
+    <style name="Widget.Quantum.ProgressBar.Small.Inverse"/>
+
+    <style name="Widget.Quantum.ProgressBar.Large.Inverse"/>
+
+    <style name="Widget.Quantum.SeekBar">
+        <item name="indeterminateOnly">false</item>
+        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum_dark</item>
+        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum_dark</item>
+        <item name="minHeight">13dip</item>
+        <item name="maxHeight">13dip</item>
+        <item name="thumb">@drawable/scrubber_control_selector_quantum_dark</item>
+        <item name="thumbOffset">16dip</item>
+        <item name="focusable">true</item>
+        <item name="paddingStart">16dip</item>
+        <item name="paddingEnd">16dip</item>
+        <item name="mirrorForRtl">true</item>
+    </style>
+
+    <style name="Widget.Quantum.RatingBar" parent="Widget.RatingBar">
+        <item name="progressDrawable">@drawable/ratingbar_full_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_full_holo_dark</item>
+    </style>
+
+    <style name="Widget.Quantum.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
+        <item name="progressDrawable">@drawable/ratingbar_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_holo_dark</item>
+        <item name="minHeight">35dip</item>
+        <item name="maxHeight">35dip</item>
+    </style>
+
+    <style name="Widget.Quantum.RatingBar.Small" parent="Widget.RatingBar.Small">
+        <item name="progressDrawable">@drawable/ratingbar_small_holo_dark</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_dark</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
+    </style>
+
+    <style name="Widget.Quantum.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton"/>
+
+    <style name="Widget.Quantum.ScrollView" parent="Widget.ScrollView"/>
+
+    <style name="Widget.Quantum.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
+
+    <style name="Widget.Quantum.Spinner" parent="Widget.Spinner.DropDown">
+        <item name="background">@drawable/spinner_background_quantum_dark</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_dark</item>
+        <item name="popupBackground">?attr/colorBackground</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+        <item name="popupPromptView">@layout/simple_dropdown_hint</item>
+        <item name="gravity">start|center_vertical</item>
+        <item name="disableChildrenWhenDisabled">true</item>
+    </style>
+
+    <style name="Widget.Quantum.Spinner.DropDown"/>
+
+    <style name="Widget.Quantum.Spinner.DropDown.ActionBar">
+        <item name="background">@drawable/spinner_background_quantum_dark</item>
+    </style>
+
+    <style name="Widget.Quantum.CompoundButton.Star" parent="Widget.CompoundButton.Star">
+        <item name="button">@drawable/btn_star_quantum_dark</item>
+    </style>
+
+    <style name="Widget.Quantum.TabWidget" parent="Widget.TabWidget">
+        <item name="tabStripLeft">@null</item>
+        <item name="tabStripRight">@null</item>
+        <item name="tabStripEnabled">false</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="showDividers">middle</item>
+        <item name="dividerPadding">8dip</item>
+        <item name="measureWithLargestChild">true</item>
+        <item name="tabLayout">@layout/tab_indicator_holo</item>
+    </style>
+
+    <style name="Widget.Quantum.Tab" parent="Widget.Quantum.ActionBar.TabView">
+        <item name="background">@drawable/tab_indicator_quantum_dark</item>
+        <item name="layout_width">0dip</item>
+        <item name="layout_weight">1</item>
+        <item name="minWidth">80dip</item>
+    </style>
+
+    <style name="Widget.Quantum.TabText" parent="Widget.Quantum.ActionBar.TabText">
+        <item name="maxWidth">180dip</item>
+    </style>
+
+    <style name="Widget.Quantum.WebTextView" parent="Widget.WebTextView"/>
+
+    <style name="Widget.Quantum.WebView" parent="Widget.WebView"/>
+
+    <style name="Widget.Quantum.DropDownItem" parent="Widget.DropDownItem">
+        <item name="textAppearance">@style/TextAppearance.Quantum.Widget.DropDownItem</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingEnd">8dp</item>
+    </style>
+
+    <style name="Widget.Quantum.DropDownItem.Spinner"/>
+
+    <style name="Widget.Quantum.TextView.SpinnerItem" parent="Widget.TextView.SpinnerItem">
+        <item name="textAppearance">@style/TextAppearance.Quantum.Widget.TextView.SpinnerItem</item>
+        <item name="paddingStart">8dp</item>
+        <item name="paddingEnd">8dp</item>
+    </style>
+
+    <style name="Widget.Quantum.KeyboardView" parent="Widget.KeyboardView"/>
+
+    <style name="Widget.Quantum.QuickContactBadge.WindowSmall" parent="Widget.QuickContactBadge.WindowSmall"/>
+
+    <style name="Widget.Quantum.QuickContactBadge.WindowMedium" parent="Widget.QuickContactBadge.WindowMedium"/>
+
+    <style name="Widget.Quantum.QuickContactBadge.WindowLarge" parent="Widget.QuickContactBadge.WindowLarge"/>
+
+    <style name="Widget.Quantum.QuickContactBadgeSmall.WindowSmall" parent="Widget.QuickContactBadgeSmall.WindowSmall"/>
+
+    <style name="Widget.Quantum.QuickContactBadgeSmall.WindowMedium" parent="Widget.QuickContactBadgeSmall.WindowMedium"/>
+
+    <style name="Widget.Quantum.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
+
+    <style name="Widget.Quantum.ListPopupWindow" parent="Widget.ListPopupWindow">
+        <item name="dropDownSelector">@drawable/list_selector_holo_dark</item>
+        <item name="popupBackground">?attr/colorBackground</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+    </style>
+
+    <style name="Widget.Quantum.PopupMenu" parent="Widget.Quantum.ListPopupWindow"/>
+
+    <style name="Widget.Quantum.ButtonBar">
+        <item name="divider">?attr/dividerVertical</item>
+    </style>
+
+    <style name="Widget.Quantum.ButtonBar.Button"/>
+
+    <style name="Widget.Quantum.ActionButton" parent="Widget.ActionButton">
+        <item name="minWidth">@dimen/action_button_min_width</item>
+        <item name="gravity">center</item>
+        <item name="paddingStart">12dip</item>
+        <item name="paddingEnd">12dip</item>
+        <item name="scaleType">center</item>
+        <item name="maxLines">2</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionButton.Overflow">
+        <item name="src">@drawable/ic_menu_moreoverflow_quantum_dark</item>
+        <item name="background">?attr/actionBarItemBackground</item>
+        <item name="contentDescription">@string/action_menu_overflow_description</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionButton.TextButton" parent="Widget.Quantum.ButtonBar.Button"/>
+
+    <style name="Widget.Quantum.ActionBar.TabView" parent="Widget.ActionBar.TabView">
+        <item name="background">@drawable/tab_indicator_quantum_dark</item>
+        <item name="paddingStart">16dip</item>
+        <item name="paddingEnd">16dip</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionBar.TabBar" parent="Widget.ActionBar.TabBar">
+        <item name="divider">?attr/actionBarDivider</item>
+        <item name="showDividers">middle</item>
+        <item name="dividerPadding">12dip</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionBar.TabText" parent="Widget.ActionBar.TabText">
+        <item name="textAppearance">@style/TextAppearance.Quantum.Medium</item>
+        <item name="textColor">?attr/textColorPrimary</item>
+        <item name="textSize">12sp</item>
+        <item name="textStyle">bold</item>
+        <item name="textAllCaps">true</item>
+        <item name="ellipsize">marquee</item>
+        <item name="maxLines">2</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionMode" parent="Widget.ActionMode">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionButton.CloseMode">
+        <item name="background">@drawable/btn_cab_done_holo_dark</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionBar" parent="Widget.ActionBar">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_transparent_quantum_dark</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_transparent_dark_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_transparent_dark_holo</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
+    </style>
+
+    <style name="Widget.Quantum.ActionBar.Solid">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_solid_dark_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_solid_dark_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_solid_dark_holo</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
+    </style>
+
+    <style name="Widget.Quantum.CompoundButton.Switch">
+        <item name="track">@drawable/switch_track_quantum_dark</item>
+        <item name="thumb">@drawable/switch_inner_quantum_dark</item>
+        <item name="switchTextAppearance">@style/TextAppearance.Quantum.Widget.Switch</item>
+        <item name="textOn"></item>
+        <item name="textOff"></item>
+        <item name="thumbTextPadding">12dip</item>
+        <item name="switchMinWidth">72dip</item>
+        <item name="switchPadding">16dip</item>
+    </style>
+
+    <!-- Light widget styles -->
+
+    <style name="Widget.Quantum.Light" parent="Widget" />
+
+    <!-- Bordered ink button -->
+    <style name="Widget.Quantum.Light.Button" parent="Widget.Quantum.Button">
+        <item name="background">@drawable/btn_default_quantum_light</item>
+        <item name="textAppearance">?attr/textAppearanceButton</item>
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">96dip</item>
+    </style>
+
+    <!-- Small bordered ink button -->
+    <style name="Widget.Quantum.Light.Button.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <!-- Bordered paper button -->
+    <style name="Widget.Quantum.Light.Button.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
+
+    <!-- Bordered paper button with color -->
+    <style name="Widget.Quantum.Light.Button.Paper.Color">
+        <item name="background">@drawable/btn_color_quantum_light</item>
+    </style>
+
+    <!-- Borderless ink button -->
+    <style name="Widget.Quantum.Light.Button.Borderless">
+        <item name="background">@drawable/btn_borderless_quantum_light</item>
+    </style>
+
+    <!-- Small borderless ink button -->
+    <style name="Widget.Quantum.Light.Button.Borderless.Small">
+        <item name="minHeight">48dip</item>
+        <item name="minWidth">48dip</item>
+    </style>
+
+    <!-- Borderless paper button -->
+    <style name="Widget.Quantum.Light.Button.Borderless.Paper">
+        <!-- TODO: Specify pressed state animation. -->
+    </style>
+    <style name="Widget.Quantum.Light.Button.Inset"/>
+
+    <style name="Widget.Quantum.Light.Button.Toggle">
+        <item name="background">@drawable/btn_toggle_holo_light</item>
+        <item name="textOn">@string/capital_on</item>
+        <item name="textOff">@string/capital_off</item>
+        <item name="textAppearance">?attr/textAppearanceSmall</item>
+        <item name="minHeight">48dip</item>
+    </style>
+
+    <style name="Quantum.Light.ButtonBar" parent="Quantum.ButtonBar"/>
+
+    <style name="Quantum.Light.ButtonBar.AlertDialog">
+        <item name="background">@null</item>
+        <item name="dividerPadding">0dp</item>
+    </style>
+
+    <style name="Quantum.Light.SegmentedButton" parent="SegmentedButton">
+        <item name="background">@drawable/btn_group_holo_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.TextView" parent="Widget.TextView"/>
+
+    <style name="Widget.Quantum.Light.CheckedTextView" parent="Widget.CheckedTextView"/>
+
+    <style name="Widget.Quantum.Light.TextView.ListSeparator" parent="Widget.TextView.ListSeparator">
+        <item name="background">@drawable/list_section_divider_quantum_light</item>
+        <item name="textAllCaps">true</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.TextSelectHandle" parent="Widget.TextSelectHandle"/>
+
+   <style name="Widget.Quantum.Light.TextSuggestionsPopupWindow" parent="Widget.TextSuggestionsPopupWindow"/>
+
+    <style name="Widget.Quantum.Light.AbsListView" parent="Widget.AbsListView"/>
+
+    <style name="Widget.Quantum.Light.AutoCompleteTextView" parent="Widget.AutoCompleteTextView">
+        <item name="dropDownSelector">@drawable/list_selector_holo_light</item>
+        <item name="popupBackground">?attr/colorBackground</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.CompoundButton.CheckBox" parent="Widget.CompoundButton.CheckBox"/>
+
+    <style name="Widget.Quantum.Light.ListView.DropDown"/>
+
+    <style name="Widget.Quantum.Light.EditText" parent="Widget.Quantum.EditText"/>
+
+    <style name="Widget.Quantum.Light.ExpandableListView" parent="Widget.Quantum.Light.ListView">
+        <item name="groupIndicator">@drawable/expander_group_quantum_light</item>
+        <item name="indicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="indicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="childDivider">?attr/listDivider</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ExpandableListView.White"/>
+
+    <style name="Widget.Quantum.Light.FragmentBreadCrumbs" parent="Widget.FragmentBreadCrumbs"/>
+
+    <style name="Widget.Quantum.Light.Gallery" parent="Widget.Gallery"/>
+
+    <style name="Widget.Quantum.Light.GestureOverlayView" parent="Widget.GestureOverlayView"/>
+
+    <style name="Widget.Quantum.Light.GridView" parent="Widget.Quantum.GridView"/>
+
+    <style name="Widget.Quantum.Light.ImageButton" parent="Widget.Quantum.ImageButton">
+        <item name="background">@drawable/btn_default_quantum_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.CalendarView" parent="Widget.CalendarView">
+        <item name="selectedWeekBackgroundColor">#330066ff</item>
+        <item name="focusedMonthDateColor">#FF000000</item>
+        <item name="unfocusedMonthDateColor">#7F08002B</item>
+        <item name="weekNumberColor">#7F080021</item>
+        <item name="weekSeparatorLineColor">#7F08002A</item>
+        <item name="weekDayTextAppearance">@style/TextAppearance.Quantum.Light.CalendarViewWeekDayView</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.NumberPicker" parent="Widget.Quantum.NumberPicker"/>
+
+    <style name="Widget.Quantum.Light.TimePicker" parent="Widget.TimePicker">
+        <item name="legacyLayout">@layout/time_picker_legacy_holo</item>
+        <item name="internalLayout">@layout/time_picker_holo</item>
+        <item name="disabledColor">@color/timepicker_default_disabled_color_quantum_light</item>
+        <item name="headerSelectedTextColor">@color/holo_blue_light</item>
+        <item name="headerUnselectedTextColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="headerBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+        <item name="numbersTextColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="numbersBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+        <item name="amPmTextColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="amPmUnselectedBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+        <item name="amPmSelectedBackgroundColor">@color/holo_blue_light</item>
+        <item name="numbersSelectorColor">@color/holo_blue_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.DatePicker" parent="Widget.Quantum.DatePicker"/>
+
+    <style name="Widget.Quantum.Light.ActivityChooserView" parent="Widget.Quantum.ActivityChooserView">
+        <item name="background">@drawable/ab_share_pack_holo_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ImageWell" parent="Widget.ImageWell"/>
+
+    <style name="Widget.Quantum.Light.ListView" parent="Widget.Quantum.ListView"/>
+
+    <style name="Widget.Quantum.Light.ListView.White"/>
+
+    <style name="Widget.Quantum.Light.PopupWindow" parent="Widget.PopupWindow"/>
+
+    <style name="Widget.Quantum.Light.PopupWindow.ActionMode">
+        <item name="popupBackground">@color/white</item>
+        <item name="popupAnimationStyle">@style/Animation.PopupWindow.ActionMode</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ProgressBar" parent="Widget.Quantum.ProgressBar"/>
+
+    <style name="Widget.Quantum.Light.ProgressBar.Horizontal" parent="Widget.Quantum.ProgressBar.Horizontal">
+        <item name="progressDrawable">@drawable/progress_horizontal_quantum_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ProgressBar.Small" parent="Widget.Quantum.ProgressBar.Small"/>
+
+    <style name="Widget.Quantum.Light.ProgressBar.Small.Title" parent="Widget.Quantum.ProgressBar.Small.Title"/>
+
+    <style name="Widget.Quantum.Light.ProgressBar.Large" parent="Widget.Quantum.ProgressBar.Large"/>
+
+    <style name="Widget.Quantum.Light.ProgressBar.Inverse" parent="Widget.Quantum.ProgressBar.Inverse"/>
+
+    <style name="Widget.Quantum.Light.ProgressBar.Small.Inverse" parent="Widget.Quantum.ProgressBar.Small.Inverse"/>
+
+    <style name="Widget.Quantum.Light.ProgressBar.Large.Inverse" parent="Widget.Quantum.ProgressBar.Large.Inverse"/>
+
+    <style name="Widget.Quantum.Light.SeekBar" parent="Widget.Quantum.SeekBar">
+        <item name="progressDrawable">@drawable/scrubber_progress_horizontal_quantum_light</item>
+        <item name="indeterminateDrawable">@drawable/scrubber_progress_horizontal_quantum_light</item>
+        <item name="thumb">@drawable/scrubber_control_selector_quantum_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.RatingBar" parent="Widget.RatingBar">
+        <item name="progressDrawable">@drawable/ratingbar_full_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_full_holo_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.RatingBar.Indicator" parent="Widget.RatingBar.Indicator">
+        <item name="progressDrawable">@drawable/ratingbar_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_holo_light</item>
+        <item name="minHeight">35dip</item>
+        <item name="maxHeight">35dip</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.RatingBar.Small" parent="Widget.RatingBar.Small">
+        <item name="progressDrawable">@drawable/ratingbar_small_holo_light</item>
+        <item name="indeterminateDrawable">@drawable/ratingbar_small_holo_light</item>
+        <item name="minHeight">16dip</item>
+        <item name="maxHeight">16dip</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.CompoundButton.RadioButton" parent="Widget.CompoundButton.RadioButton"/>
+
+    <style name="Widget.Quantum.Light.ScrollView" parent="Widget.ScrollView"/>
+
+    <style name="Widget.Quantum.Light.HorizontalScrollView" parent="Widget.HorizontalScrollView"/>
+
+    <style name="Widget.Quantum.Light.Spinner" parent="Widget.Quantum.Spinner">
+        <item name="background">@drawable/spinner_background_quantum_light</item>
+        <item name="dropDownSelector">@drawable/list_selector_holo_light</item>
+        <item name="popupBackground">?attr/colorBackground</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+        <item name="popupPromptView">@layout/simple_dropdown_hint</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.Spinner.DropDown"/>
+
+    <style name="Widget.Quantum.Light.Spinner.DropDown.ActionBar">
+        <item name="background">@drawable/spinner_background_quantum_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.CompoundButton.Star" parent="Widget.CompoundButton.Star">
+        <item name="button">@drawable/btn_star_quantum_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.TabWidget" parent="Widget.Quantum.TabWidget"/>
+
+    <style name="Widget.Quantum.Light.WebTextView" parent="Widget.WebTextView"/>
+
+    <style name="Widget.Quantum.Light.WebView" parent="Widget.WebView"/>
+
+    <style name="Widget.Quantum.Light.DropDownItem" parent="Widget.Quantum.DropDownItem"/>
+
+    <style name="Widget.Quantum.Light.DropDownItem.Spinner"/>
+
+    <style name="Widget.Quantum.Light.TextView.SpinnerItem" parent="Widget.Quantum.TextView.SpinnerItem"/>
+
+    <style name="Widget.Quantum.Light.KeyboardView" parent="Widget.KeyboardView"/>
+
+    <style name="Widget.Quantum.Light.QuickContactBadge.WindowSmall" parent="Widget.QuickContactBadge.WindowSmall"/>
+
+    <style name="Widget.Quantum.Light.QuickContactBadge.WindowMedium" parent="Widget.QuickContactBadge.WindowMedium"/>
+
+    <style name="Widget.Quantum.Light.QuickContactBadge.WindowLarge" parent="Widget.QuickContactBadge.WindowLarge"/>
+
+    <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowSmall" parent="Widget.QuickContactBadgeSmall.WindowSmall"/>
+
+    <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowMedium" parent="Widget.QuickContactBadgeSmall.WindowMedium"/>
+
+    <style name="Widget.Quantum.Light.QuickContactBadgeSmall.WindowLarge" parent="Widget.QuickContactBadgeSmall.WindowLarge"/>
+
+    <style name="Widget.Quantum.Light.ListPopupWindow" parent="Widget.ListPopupWindow">
+        <item name="dropDownSelector">@drawable/list_selector_holo_light</item>
+        <item name="popupBackground">?attr/colorBackground</item>
+        <item name="dropDownVerticalOffset">0dip</item>
+        <item name="dropDownHorizontalOffset">0dip</item>
+        <item name="dropDownWidth">wrap_content</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.PopupMenu" parent="Widget.Quantum.Light.ListPopupWindow"/>
+
+    <style name="Widget.Quantum.Light.ActionButton" parent="Widget.Quantum.ActionButton"/>
+
+    <style name="Widget.Quantum.Light.ActionButton.Overflow">
+        <item name="src">@drawable/ic_menu_moreoverflow_quantum_light</item>
+        <item name="contentDescription">@string/action_menu_overflow_description</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionBar.TabView" parent="Widget.Quantum.ActionBar.TabView">
+        <item name="background">@drawable/tab_indicator_quantum_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.Tab" parent="Widget.Quantum.Light.ActionBar.TabView">
+        <item name="layout_width">0dip</item>
+        <item name="layout_weight">1</item>
+        <item name="minWidth">80dip</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionBar.TabBar" parent="Widget.Quantum.ActionBar.TabBar"/>
+
+    <style name="Widget.Quantum.Light.ActionBar.TabText" parent="Widget.Quantum.ActionBar.TabText"/>
+
+    <style name="Widget.Quantum.Light.ActionBar.TabView.Inverse"/>
+
+    <style name="Widget.Quantum.Light.ActionBar.TabBar.Inverse"/>
+
+    <style name="Widget.Quantum.Light.ActionBar.TabText.Inverse">
+        <item name="textColor">?attr/textColorPrimaryInverse</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionMode" parent="Widget.Quantum.ActionMode">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionMode.Inverse" parent="Widget.ActionMode">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Title.Inverse</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionButton.CloseMode">
+        <item name="background">@drawable/btn_cab_done_holo_light</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionBar" parent="Widget.Quantum.ActionBar">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_transparent_quantum_light</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_transparent_light_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_transparent_light_holo</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_light</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionBar.Solid">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle</item>
+        <item name="background">@drawable/ab_solid_light_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_solid_light_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_solid_light_holo</item>
+        <item name="divider">?attr/dividerVertical</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.Light.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.ActionBar.Solid.Inverse">
+        <item name="titleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Title.Inverse</item>
+        <item name="subtitleTextStyle">@style/TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse</item>
+        <item name="background">@drawable/ab_solid_dark_holo</item>
+        <item name="backgroundStacked">@drawable/ab_stacked_solid_dark_holo</item>
+        <item name="backgroundSplit">@drawable/ab_bottom_solid_inverse_holo</item>
+        <item name="divider">@drawable/list_divider_quantum_dark</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="indeterminateProgressStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarPadding">32dip</item>
+        <item name="itemPadding">8dip</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.CompoundButton.Switch" parent="Widget.CompoundButton.Switch">
+        <item name="track">@drawable/switch_track_quantum_light</item>
+        <item name="thumb">@drawable/switch_inner_quantum_light</item>
+        <item name="switchTextAppearance">@style/TextAppearance.Quantum.Light.Widget.Switch</item>
+        <item name="textOn"></item>
+        <item name="textOff"></item>
+        <item name="thumbTextPadding">12dip</item>
+        <item name="switchMinWidth">96dip</item>
+        <item name="switchPadding">16dip</item>
+    </style>
+
+    <!-- Animation Styles -->
+
+    <style name="Animation.Quantum" parent="Animation"/>
+
+    <style name="Animation.Quantum.Activity" parent="Animation.Activity"/>
+
+    <style name="Animation.Quantum.Dialog" parent="Animation.Dialog"/>
+
+    <!-- Dialog styles -->
+
+    <style name="AlertDialog.Quantum" parent="AlertDialog">
+        <item name="fullDark">?attr/colorBackground</item>
+        <item name="topDark">?attr/colorBackground</item>
+        <item name="centerDark">?attr/colorBackground</item>
+        <item name="bottomDark">?attr/colorBackground</item>
+        <item name="fullBright">?attr/colorBackground</item>
+        <item name="topBright">?attr/colorBackground</item>
+        <item name="centerBright">?attr/colorBackground</item>
+        <item name="bottomBright">?attr/colorBackground</item>
+        <item name="bottomMedium">?attr/colorBackground</item>
+        <item name="centerMedium">?attr/colorBackground</item>
+        <item name="layout">@layout/alert_dialog_holo</item>
+        <item name="listLayout">@layout/select_dialog_holo</item>
+        <item name="progressLayout">@layout/progress_dialog_holo</item>
+        <item name="horizontalProgressLayout">@layout/alert_dialog_progress_holo</item>
+        <item name="listItemLayout">@layout/select_dialog_item_holo</item>
+        <item name="multiChoiceItemLayout">@layout/select_dialog_multichoice_holo</item>
+        <item name="singleChoiceItemLayout">@layout/select_dialog_singlechoice_holo</item>
+    </style>
+
+    <style name="AlertDialog.Quantum.Light" />
+
+    <!-- Window title -->
+    <style name="WindowTitleBackground.Quantum">
+        <item name="background">@null</item>
+    </style>
+
+    <style name="WindowTitle.Quantum">
+        <item name="singleLine">true</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.WindowTitle</item>
+        <item name="shadowColor">#BB000000</item>
+        <item name="shadowRadius">2.75</item>
+    </style>
+
+    <style name="DialogWindowTitle.Quantum">
+        <item name="maxLines">1</item>
+        <item name="scrollHorizontally">true</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.DialogWindowTitle</item>
+    </style>
+
+    <style name="DialogWindowTitle.Quantum.Light">
+        <item name="maxLines">1</item>
+        <item name="scrollHorizontally">true</item>
+        <item name="textAppearance">@style/TextAppearance.Quantum.Light.DialogWindowTitle</item>
+    </style>
+
+    <style name="Widget.Quantum.PreferenceFrameLayout">
+        <item name="borderTop">0dip</item>
+        <item name="borderBottom">@dimen/preference_fragment_padding_bottom</item>
+        <item name="borderLeft">?attr/preferenceFragmentPaddingSide</item>
+        <item name="borderRight">?attr/preferenceFragmentPaddingSide</item>
+    </style>
+
+    <style name="Widget.Quantum.MediaRouteButton">
+        <item name="background">?attr/selectableItemBackground</item>
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_dark</item>
+        <item name="minWidth">56dp</item>
+        <item name="minHeight">48dp</item>
+        <item name="focusable">true</item>
+        <item name="contentDescription">@string/media_route_button_content_description</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.MediaRouteButton" parent="Widget.Quantum.MediaRouteButton">
+        <item name="externalRouteEnabledDrawable">@drawable/ic_media_route_holo_light</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.TimePicker.TimeLabel" parent="TextAppearance.Quantum">
+        <item name="textSize">@dimen/timepicker_time_label_size</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.TimePicker.AmPmLabel" parent="TextAppearance.Quantum">
+        <item name="textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_dark</item>
+        <item name="textStyle">bold</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Light.TimePicker.TimeLabel" parent="TextAppearance.Quantum.Light">
+        <item name="textSize">@dimen/timepicker_time_label_size</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
+    </style>
+
+    <style name="TextAppearance.Quantum.Light.TimePicker.AmPmLabel" parent="TextAppearance.Quantum.Light">
+        <item name="textSize">@dimen/timepicker_ampm_label_size</item>
+        <item name="textAllCaps">true</item>
+        <item name="textColor">@color/timepicker_default_text_color_quantum_light</item>
+        <item name="textStyle">bold</item>
+    </style>
+
+    <style name="Widget.Quantum.FastScroll" parent="Widget.FastScroll">
+        <item name="thumbMinWidth">0dp</item>
+        <item name="thumbMinHeight">0dp</item>
+    </style>
+
+    <style name="Widget.Quantum.Light.FastScroll" parent="Widget.Quantum.FastScroll"/>
+
+</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 093eb3b..efa873d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -224,6 +224,7 @@
 
   <java-symbol type="attr" name="actionModeShareDrawable" />
   <java-symbol type="attr" name="alertDialogCenterButtons" />
+  <java-symbol type="attr" name="fragmentBreadCrumbsStyle" />
   <java-symbol type="attr" name="gestureOverlayViewStyle" />
   <java-symbol type="attr" name="keyboardViewStyle" />
   <java-symbol type="attr" name="numberPickerStyle" />
@@ -288,6 +289,8 @@
   <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="config_enableMultiUserUI"/>
+  <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
@@ -332,11 +335,6 @@
   <java-symbol type="dimen" name="default_gap" />
   <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="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,7 +476,6 @@
   <java-symbol type="string" name="config_ntpServer" />
   <java-symbol type="string" name="config_tether_apndata" />
   <java-symbol type="string" name="config_useragentprofile_url" />
-  <java-symbol type="string" name="config_wifi_unknown_country_code" />
   <java-symbol type="string" name="config_wifi_p2p_device_type" />
   <java-symbol type="string" name="contentServiceSync" />
   <java-symbol type="string" name="contentServiceSyncNotificationTitle" />
@@ -1093,7 +1090,6 @@
   <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_action_assist_generic" />
   <java-symbol type="drawable" name="notification_bg" />
   <java-symbol type="drawable" name="notification_bg_low" />
   <java-symbol type="drawable" name="notification_template_icon_bg" />
@@ -1181,7 +1177,7 @@
   <java-symbol type="layout" name="tab_content" />
   <java-symbol type="layout" name="tab_indicator_holo" />
   <java-symbol type="layout" name="textview_hint" />
-  <java-symbol type="layout" name="time_picker" />
+  <java-symbol type="layout" name="time_picker_legacy" />
   <java-symbol type="layout" name="time_picker_dialog" />
   <java-symbol type="layout" name="transient_notification" />
   <java-symbol type="layout" name="volume_adjust" />
@@ -1633,7 +1629,16 @@
   <java-symbol type="integer" name="config_maxResolverActivityColumns" />
   <java-symbol type="array" name="config_notificationScorers" />
 
-  <!-- From SystemUI -->
+  <java-symbol type="layout" name="notification_quantum_action" />
+  <java-symbol type="layout" name="notification_quantum_action_list" />
+  <java-symbol type="layout" name="notification_quantum_action_tombstone" />
+  <java-symbol type="layout" name="notification_template_quantum_base" />
+  <java-symbol type="layout" name="notification_template_quantum_big_base" />
+  <java-symbol type="layout" name="notification_template_quantum_big_picture" />
+  <java-symbol type="layout" name="notification_template_quantum_big_text" />
+  <java-symbol type="layout" name="notification_template_quantum_inbox" />
+
+    <!-- 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" />
@@ -1769,4 +1774,55 @@
   <java-symbol type="dimen" name="subtitle_shadow_radius" />
   <java-symbol type="dimen" name="subtitle_shadow_offset" />
   <java-symbol type="dimen" name="subtitle_outline_width" />
+
+  <!-- From the new TimePicker -->
+  <java-symbol type="attr" name="timePickerHeaderBackgroundColor" />
+  <java-symbol type="attr" name="timePickerDialogTheme" />
+  <java-symbol type="attr" name="headerSelectedTextColor" />
+  <java-symbol type="attr" name="headerUnselectedTextColor" />
+  <java-symbol type="attr" name="numbersTextColor" />
+  <java-symbol type="attr" name="numbersBackgroundColor" />
+  <java-symbol type="attr" name="amPmTextColor" />
+  <java-symbol type="attr" name="amPmUnselectedBackgroundColor" />
+  <java-symbol type="attr" name="amPmSelectedBackgroundColor" />
+  <java-symbol type="attr" name="numbersSelectorColor" />
+  <java-symbol type="attr" name="timePickerHeaderTimeLabelTextAppearance" />
+  <java-symbol type="style" name="TextAppearance.Holo.TimePicker.TimeLabel" />
+  <java-symbol type="layout" name="time_picker_holo" />
+  <java-symbol type="layout" name="time_header_label" />
+  <java-symbol type="id" name="time_header" />
+  <java-symbol type="id" name="hours" />
+  <java-symbol type="id" name="minutes" />
+  <java-symbol type="id" name="ampm_label" />
+  <java-symbol type="id" name="radial_picker" />
+  <java-symbol type="id" name="separator" />
+  <java-symbol type="id" name="layout_buttons" />
+  <java-symbol type="id" name="done_button" />
+  <java-symbol type="string" name="done_label" />
+  <java-symbol type="string" name="hour_picker_description" />
+  <java-symbol type="string" name="minute_picker_description" />
+  <java-symbol type="string" name="select_hours" />
+  <java-symbol type="string" name="select_minutes" />
+  <java-symbol type="string" name="time_placeholder" />
+  <java-symbol type="string" name="timepicker_circle_radius_multiplier" />
+  <java-symbol type="string" name="timepicker_circle_radius_multiplier_24HourMode" />
+  <java-symbol type="string" name="timepicker_ampm_circle_radius_multiplier" />
+  <java-symbol type="string" name="deleted_key" />
+  <java-symbol type="string" name="sans_serif" />
+  <java-symbol type="string" name="radial_numbers_typeface" />
+  <java-symbol type="string" name="timepicker_text_size_multiplier_inner" />
+  <java-symbol type="string" name="timepicker_text_size_multiplier_outer" />
+  <java-symbol type="string" name="timepicker_text_size_multiplier_normal" />
+  <java-symbol type="string" name="timepicker_numbers_radius_multiplier_outer" />
+  <java-symbol type="string" name="timepicker_selection_radius_multiplier" />
+  <java-symbol type="string" name="timepicker_numbers_radius_multiplier_inner" />
+  <java-symbol type="string" name="timepicker_numbers_radius_multiplier_normal" />
+  <java-symbol type="string" name="timepicker_transition_mid_radius_multiplier" />
+  <java-symbol type="string" name="timepicker_transition_end_radius_multiplier" />
+  <java-symbol type="color" name="timepicker_default_text_color_holo_light" />
+  <java-symbol type="color" name="timepicker_default_disabled_color_holo_light" />
+  <java-symbol type="color" name="timepicker_default_ampm_unselected_background_color_holo_light" />
+  <java-symbol type="color" name="timepicker_default_ampm_selected_background_color_holo_light" />
+  <java-symbol type="array" name="config_clockTickVibePattern" />
+
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index c8d9fc6..4a0158e 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -249,6 +249,7 @@
         <item name="editTextStyle">@android:style/Widget.EditText</item>
         <item name="expandableListViewStyle">@android:style/Widget.ExpandableListView</item>
         <item name="expandableListViewWhiteStyle">@android:style/Widget.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@android:style/Widget.FastScroll</item>
         <item name="galleryStyle">@android:style/Widget.Gallery</item>
         <item name="gestureOverlayViewStyle">@android:style/Widget.GestureOverlayView</item>
         <item name="gridViewStyle">@android:style/Widget.GridView</item>
@@ -296,8 +297,8 @@
         <item name="listPopupWindowStyle">@android:style/Widget.ListPopupWindow</item>
         <item name="popupMenuStyle">@android:style/Widget.PopupMenu</item>
         <item name="activityChooserViewStyle">@android:style/Widget.ActivityChooserView</item>
-
         <item name="mediaRouteButtonStyle">@android:style/Widget.DeviceDefault.MediaRouteButton</item>
+        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@android:style/Preference.PreferenceScreen</item>
@@ -362,9 +363,9 @@
         <item name="searchViewTextField">@drawable/textfield_searchview_holo_dark</item>
         <item name="searchViewTextFieldRight">@drawable/textfield_searchview_right_holo_dark</item>
         <item name="searchViewCloseIcon">@android:drawable/ic_clear</item>
-        <item name="searchViewSearchIcon">@android:drawable/ic_search</item>
+        <item name="searchViewSearchIcon">@android:drawable/ic_search_api_holo_dark</item>
         <item name="searchViewGoIcon">@android:drawable/ic_go</item>
-        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search</item>
+        <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search_api_holo_dark</item>
         <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_dark</item>
         <item name="searchViewEditQueryBackground">?attr/selectableItemBackground</item>
 
@@ -382,6 +383,18 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.TimePicker</item>
 
+        <!-- TimePicker background color -->
+        <item name="timePickerHeaderBackgroundColor">@android:color/darker_gray</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.DatePicker</item>
 
@@ -391,7 +404,6 @@
         <item name="fastScrollPreviewBackgroundLeft">@android:drawable/menu_submenu_background</item>
         <item name="fastScrollOverlayPosition">floating</item>
         <item name="fastScrollTextColor">@android:color/primary_text_dark</item>
-
         <!-- Pointer style -->
         <item name="pointerStyle">@android:style/Pointer</item>
 
@@ -688,7 +700,15 @@
         <item name="textAppearanceListItem">@android:style/TextAppearance.Large.Inverse</item>
         <item name="textAppearanceListItemSmall">@android:style/TextAppearance.Large.Inverse</item>
     </style>
-    
+
+    <!-- Default heme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Dialog.TimePicker">
+        <item name="windowBackground">@android:color/transparent</item>
+        <item name="windowTitleStyle">@android:style/DialogWindowTitle</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
     <!-- Default dark theme for panel windows (on API level 10 and lower).  This removes all
          extraneous window decorations, so you basically have an empty rectangle in which
          to place your content.  It makes the window floating, with a transparent
@@ -1088,6 +1108,7 @@
         <item name="editTextStyle">@android:style/Widget.Holo.EditText</item>
         <item name="expandableListViewStyle">@android:style/Widget.Holo.ExpandableListView</item>
         <item name="expandableListViewWhiteStyle">@android:style/Widget.Holo.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@android:style/Widget.Holo.FastScroll</item>
         <item name="galleryStyle">@android:style/Widget.Holo.Gallery</item>
         <item name="gestureOverlayViewStyle">@android:style/Widget.Holo.GestureOverlayView</item>
         <item name="gridViewStyle">@android:style/Widget.Holo.GridView</item>
@@ -1135,6 +1156,7 @@
         <item name="popupMenuStyle">@android:style/Widget.Holo.PopupMenu</item>
         <item name="stackViewStyle">@android:style/Widget.Holo.StackView</item>
         <item name="activityChooserViewStyle">@android:style/Widget.Holo.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.Holo.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@android:style/Preference.Holo.PreferenceScreen</item>
@@ -1202,6 +1224,18 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.Holo.TimePicker</item>
 
+        <!-- TimePicker background color -->
+        <item name="timePickerHeaderBackgroundColor">@android:color/timepicker_default_background_holo_dark</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Holo.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Holo.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.Holo.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Holo.DatePicker</item>
 
@@ -1403,6 +1437,7 @@
         <item name="editTextStyle">@android:style/Widget.Holo.Light.EditText</item>
         <item name="expandableListViewStyle">@android:style/Widget.Holo.Light.ExpandableListView</item>
         <item name="expandableListViewWhiteStyle">@android:style/Widget.Holo.Light.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@android:style/Widget.Holo.Light.FastScroll</item>
         <item name="galleryStyle">@android:style/Widget.Holo.Light.Gallery</item>
         <item name="gestureOverlayViewStyle">@android:style/Widget.Holo.Light.GestureOverlayView</item>
         <item name="gridViewStyle">@android:style/Widget.Holo.Light.GridView</item>
@@ -1450,6 +1485,7 @@
         <item name="popupMenuStyle">@android:style/Widget.Holo.Light.PopupMenu</item>
         <item name="stackViewStyle">@android:style/Widget.Holo.StackView</item>
         <item name="activityChooserViewStyle">@android:style/Widget.Holo.Light.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@android:style/Widget.Holo.Light.FragmentBreadCrumbs</item>
 
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@android:style/Preference.Holo.PreferenceScreen</item>
@@ -1517,6 +1553,18 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.Holo.Light.TimePicker</item>
 
+        <!-- TimePicker Header background color -->
+        <item name="timePickerHeaderBackgroundColor">@android:color/timepicker_default_background_holo_light</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Holo.Light.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Holo.Light.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.Holo.Light.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.Holo.Light.DatePicker</item>
 
@@ -1729,6 +1777,14 @@
         <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
+    <!-- Holo theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Holo.Dialog.TimePicker">
+        <item name="windowBackground">@android:color/transparent</item>
+        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
     <!-- Theme for a window that will be displayed either full-screen on
          smaller screens (small, normal) or as a dialog on larger screens
          (large, xlarge). -->
@@ -1844,6 +1900,14 @@
         <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
+    <!-- Holo Light theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Holo.Light.Dialog.TimePicker">
+        <item name="windowBackground">@android:color/transparent</item>
+        <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo.Light</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
     <!-- Theme for a presentation window on a secondary display. -->
     <style name="Theme.Holo.Light.Dialog.Presentation" parent="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen" >
     </style>
@@ -1861,4 +1925,5 @@
     <style name="Theme.Holo.Wallpaper.NoTitleBar">
         <item name="android:windowNoTitle">true</item>
     </style>
+
 </resources>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 721c6b0..19556a1 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -194,6 +194,15 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.DeviceDefault.TimePicker</item>
 
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.DeviceDefault.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.DeviceDefault.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.DeviceDefault.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.DeviceDefault.DatePicker</item>
 
@@ -363,6 +372,15 @@
         <!-- TimePicker style -->
         <item name="timePickerStyle">@style/Widget.DeviceDefault.Light.TimePicker</item>
 
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.DeviceDefault.Light.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog.TimePicker</item>
+
         <!-- DatePicker style -->
         <item name="datePickerStyle">@style/Widget.DeviceDefault.Light.DatePicker</item>
 
diff --git a/core/res/res/values/themes_quantum.xml b/core/res/res/values/themes_quantum.xml
new file mode 100644
index 0000000..d2eee28
--- /dev/null
+++ b/core/res/res/values/themes_quantum.xml
@@ -0,0 +1,1068 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!--
+===============================================================
+                        PLEASE READ
+===============================================================
+
+The Quantum themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+                        PLEASE READ
+===============================================================
+ -->
+<resources>
+
+    <!-- Quantum Paper theme (dark version).
+         <p>If you want to ensure that your
+         app consistently uses the Quantum theme at all times, you must explicitly declare it in your
+         manifest. For example, {@code &lt;application android:theme="@style/Theme.Quantum"&gt;}.
+
+         <p>Styles used by the Quantum theme are named using the convention Type.Quantum.Etc
+         (for example, {@code Widget.Quantum.Button} and {@code
+         TextAppearance.Quantum.Widget.PopupMenu.Large}).
+         Specific resources used by Quantum are named using the convention @type/foo_bar_baz_quantum
+         with trailing _dark or _light specifiers if they are not shared between both light and
+         dark versions of the theme. -->
+    <style name="Theme.Quantum">
+        <item name="colorForeground">@color/bright_foreground_quantum_dark</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_quantum_light</item>
+        <item name="colorBackground">@color/background_quantum_dark</item>
+        <item name="colorBackgroundCacheHint">@drawable/background_cache_hint_selector_quantum_dark</item>
+        <item name="disabledAlpha">0.5</item>
+        <item name="backgroundDimAmount">0.6</item>
+
+        <!-- Text styles -->
+        <item name="textAppearance">@style/TextAppearance.Quantum</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
+
+        <item name="textColorPrimary">@color/primary_text_quantum_dark</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_quantum_light</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_quantum_dark</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_light</item>
+        <item name="textColorTertiary">@color/tertiary_text_quantum_dark</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_light</item>
+        <item name="textColorHint">@color/hint_foreground_quantum_dark</item>
+        <item name="textColorHintInverse">@color/hint_foreground_quantum_light</item>
+        <item name="textColorHighlight">@color/highlighted_text_quantum_dark</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_light</item>
+        <item name="textColorLink">@color/quantum_teal_500</item>
+        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_quantum_dark</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_dark</item>
+
+        <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Large</item>
+        <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Large.Inverse</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Medium</item>
+        <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Medium.Inverse</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Small</item>
+        <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Small.Inverse</item>
+        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.SearchResult.Title</item>
+        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.SearchResult.Subtitle</item>
+
+        <item name="textAppearanceButton">@style/TextAppearance.Quantum.Widget.Button</item>
+
+        <item name="editTextColor">?attr/textColorPrimary</item>
+        <item name="editTextBackground">@drawable/edit_text_quantum_dark</item>
+
+        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
+
+        <item name="textCheckMark">@drawable/indicator_check_mark_dark</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_light</item>
+
+        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Large</item>
+        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Quantum.Widget.PopupMenu.Small</item>
+
+        <!-- Button styles -->
+        <item name="buttonStyle">@style/Widget.Quantum.Button</item>
+        <item name="buttonStyleSmall">@style/Widget.Quantum.Button.Small</item>
+        <item name="buttonStyleInset">@style/Widget.Quantum.Button.Inset</item>
+        <item name="buttonStyleToggle">@style/Widget.Quantum.Button.Toggle</item>
+
+        <item name="switchStyle">@style/Widget.Quantum.CompoundButton.Switch</item>
+        <item name="mediaRouteButtonStyle">@style/Widget.Quantum.MediaRouteButton</item>
+
+        <item name="selectableItemBackground">@drawable/item_background_quantum_dark</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_dark</item>
+
+        <!-- List attributes -->
+        <item name="listPreferredItemHeight">64dip</item>
+        <item name="listPreferredItemHeightSmall">48dip</item>
+        <item name="listPreferredItemHeightLarge">80dip</item>
+        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
+        <item name="textAppearanceListItemSmall">?attr/textAppearanceMedium</item>
+        <item name="listPreferredItemPaddingLeft">8dip</item>
+        <item name="listPreferredItemPaddingRight">8dip</item>
+        <item name="listPreferredItemPaddingStart">8dip</item>
+        <item name="listPreferredItemPaddingEnd">8dip</item>
+
+        <!-- @hide -->
+        <item name="searchResultListItemHeight">58dip</item>
+        <item name="listDivider">@drawable/list_divider_quantum_dark</item>
+        <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.TextView.ListSeparator</item>
+
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_dark</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_dark</item>
+
+        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_holo_dark</item>
+
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum_dark</item>
+
+        <item name="listDividerAlertDialog">@drawable/list_divider_quantum_dark</item>
+
+        <item name="expandableListPreferredItemPaddingLeft">40dip</item>
+        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
+
+        <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
+        <item name="expandableListPreferredItemIndicatorRight">0dip</item>
+        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum_dark</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum_dark</item>
+
+        <!-- Gallery attributes -->
+        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
+
+        <!-- Window attributes -->
+        <item name="windowBackground">@color/background_quantum_dark</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowNoTitle">false</item>
+        <item name="windowFullscreen">false</item>
+        <item name="windowOverscan">false</item>
+        <item name="windowIsFloating">false</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowShowWallpaper">false</item>
+        <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>
+        <item name="windowTitleSize">25dip</item>
+        <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Quantum</item>
+        <item name="windowContentTransitions">true</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Activity</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+        <item name="windowActionBar">true</item>
+        <item name="windowActionModeOverlay">false</item>
+
+        <!-- Dialog attributes -->
+        <item name="dialogTheme">@style/Theme.Quantum.Dialog</item>
+        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
+        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
+        <item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item>
+
+        <!-- AlertDialog attributes -->
+        <item name="alertDialogTheme">@style/Theme.Quantum.Dialog.Alert</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Quantum</item>
+        <item name="alertDialogCenterButtons">false</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum_dark</item>
+
+        <!-- Presentation attributes -->
+        <item name="presentationTheme">@style/Theme.Quantum.Dialog.Presentation</item>
+
+        <!-- Toast attributes -->
+        <item name="toastFrameBackground">@drawable/toast_frame</item>
+
+        <!-- Panel attributes -->
+        <item name="panelBackground">?attr/colorBackground</item>
+        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
+        <!-- These three attributes do not seems to be used by the framework. Declared public though -->
+        <item name="panelColorBackground">#000</item>
+        <item name="panelColorForeground">?attr/textColorPrimary</item>
+        <item name="panelTextAppearance">?attr/textAppearance</item>
+
+        <item name="panelMenuIsCompact">true</item>
+        <item name="panelMenuListWidth">250dip</item>
+        <item name="panelMenuListTheme">@style/Theme.Quantum.CompactMenu</item>
+
+        <!-- Scrollbar attributes -->
+        <item name="scrollbarFadeDuration">250</item>
+        <item name="scrollbarDefaultDelayBeforeFade">300</item>
+        <item name="scrollbarSize">10dip</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum_dark</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum_dark</item>
+        <item name="scrollbarTrackHorizontal">@null</item>
+        <item name="scrollbarTrackVertical">@null</item>
+
+        <!-- Text selection handle attributes -->
+        <item name="textSelectHandleLeft">@drawable/text_select_handle_left</item>
+        <item name="textSelectHandleRight">@drawable/text_select_handle_right</item>
+        <item name="textSelectHandle">@drawable/text_select_handle_middle</item>
+        <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
+        <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.TextSuggestionsPopupWindow</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_quantum_dark</item>
+
+        <!-- Widget styles -->
+        <item name="absListViewStyle">@style/Widget.Quantum.AbsListView</item>
+        <item name="autoCompleteTextViewStyle">@style/Widget.Quantum.AutoCompleteTextView</item>
+        <item name="checkboxStyle">@style/Widget.Quantum.CompoundButton.CheckBox</item>
+        <item name="checkedTextViewStyle">@style/Widget.Quantum.CheckedTextView</item>
+        <item name="dropDownListViewStyle">@style/Widget.Quantum.ListView.DropDown</item>
+        <item name="editTextStyle">@style/Widget.Quantum.EditText</item>
+        <item name="expandableListViewStyle">@style/Widget.Quantum.ExpandableListView</item>
+        <item name="expandableListViewWhiteStyle">@style/Widget.Quantum.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@style/Widget.Quantum.FastScroll</item>
+        <item name="galleryStyle">@style/Widget.Quantum.Gallery</item>
+        <item name="gestureOverlayViewStyle">@style/Widget.Quantum.GestureOverlayView</item>
+        <item name="gridViewStyle">@style/Widget.Quantum.GridView</item>
+        <item name="imageButtonStyle">@style/Widget.Quantum.ImageButton</item>
+        <item name="imageWellStyle">@style/Widget.Quantum.ImageWell</item>
+        <item name="listViewStyle">@style/Widget.Quantum.ListView</item>
+        <item name="listViewWhiteStyle">@style/Widget.Quantum.ListView.White</item>
+        <item name="popupWindowStyle">@style/Widget.Quantum.PopupWindow</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.ProgressBar</item>
+        <item name="progressBarStyleHorizontal">@style/Widget.Quantum.ProgressBar.Horizontal</item>
+        <item name="progressBarStyleSmall">@style/Widget.Quantum.ProgressBar.Small</item>
+        <item name="progressBarStyleSmallTitle">@style/Widget.Quantum.ProgressBar.Small.Title</item>
+        <item name="progressBarStyleLarge">@style/Widget.Quantum.ProgressBar.Large</item>
+        <item name="progressBarStyleInverse">@style/Widget.Quantum.ProgressBar.Inverse</item>
+        <item name="progressBarStyleSmallInverse">@style/Widget.Quantum.ProgressBar.Small.Inverse</item>
+        <item name="progressBarStyleLargeInverse">@style/Widget.Quantum.ProgressBar.Large.Inverse</item>
+        <item name="seekBarStyle">@style/Widget.Quantum.SeekBar</item>
+        <item name="ratingBarStyle">@style/Widget.Quantum.RatingBar</item>
+        <item name="ratingBarStyleIndicator">@style/Widget.Quantum.RatingBar.Indicator</item>
+        <item name="ratingBarStyleSmall">@style/Widget.Quantum.RatingBar.Small</item>
+        <item name="radioButtonStyle">@style/Widget.Quantum.CompoundButton.RadioButton</item>
+        <item name="scrollViewStyle">@style/Widget.Quantum.ScrollView</item>
+        <item name="horizontalScrollViewStyle">@style/Widget.Quantum.HorizontalScrollView</item>
+        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
+        <item name="dropDownSpinnerStyle">@style/Widget.Quantum.Spinner.DropDown</item>
+        <item name="starStyle">@style/Widget.Quantum.CompoundButton.Star</item>
+        <item name="tabWidgetStyle">@style/Widget.Quantum.TabWidget</item>
+        <item name="textViewStyle">@style/Widget.Quantum.TextView</item>
+        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_dark</item>
+        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_dark</item>
+        <item name="webTextViewStyle">@style/Widget.Quantum.WebTextView</item>
+        <item name="webViewStyle">@style/Widget.Quantum.WebView</item>
+        <item name="dropDownItemStyle">@style/Widget.Quantum.DropDownItem</item>
+        <item name="spinnerDropDownItemStyle">@style/Widget.Quantum.DropDownItem.Spinner</item>
+        <item name="spinnerItemStyle">@style/Widget.Quantum.TextView.SpinnerItem</item>
+        <item name="dropDownHintAppearance">@style/TextAppearance.Quantum.Widget.DropDownHint</item>
+        <item name="keyboardViewStyle">@style/Widget.Quantum.KeyboardView</item>
+        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
+        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
+        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
+        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
+        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
+        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
+        <item name="listPopupWindowStyle">@style/Widget.Quantum.ListPopupWindow</item>
+        <item name="popupMenuStyle">@style/Widget.Quantum.PopupMenu</item>
+        <item name="stackViewStyle">@style/Widget.Quantum.StackView</item>
+        <item name="activityChooserViewStyle">@style/Widget.Quantum.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@style/Widget.Quantum.FragmentBreadCrumbs</item>
+
+        <!-- Preference styles -->
+        <item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
+        <item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
+        <item name="preferenceStyle">@style/Preference.Quantum</item>
+        <item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
+        <item name="checkBoxPreferenceStyle">@style/Preference.Quantum.CheckBoxPreference</item>
+        <item name="switchPreferenceStyle">@style/Preference.Quantum.SwitchPreference</item>
+        <item name="yesNoPreferenceStyle">@style/Preference.Quantum.DialogPreference.YesNoPreference</item>
+        <item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
+        <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
+        <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
+        <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
+        <item name="detailsElementBackground">?attr/colorBackground</item>
+
+        <!-- Search widget styles -->
+        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
+
+        <!-- Action bar styles -->
+        <item name="actionDropDownStyle">@style/Widget.Quantum.Spinner.DropDown.ActionBar</item>
+        <item name="actionButtonStyle">@style/Widget.Quantum.ActionButton</item>
+        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.ActionButton.Overflow</item>
+        <item name="actionModeBackground">@color/theme_color_700</item>
+        <item name="actionModeSplitBackground">@color/theme_color_700</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum_dark</item>
+        <item name="actionBarTabStyle">@style/Widget.Quantum.ActionBar.TabView</item>
+        <item name="actionBarTabBarStyle">@style/Widget.Quantum.ActionBar.TabBar</item>
+        <item name="actionBarTabTextStyle">@style/Widget.Quantum.ActionBar.TabText</item>
+        <item name="actionModeStyle">@style/Widget.Quantum.ActionMode</item>
+        <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.ActionButton.CloseMode</item>
+        <item name="actionBarStyle">@style/Widget.Quantum.ActionBar</item>
+        <item name="actionBarSize">@dimen/action_bar_default_height</item>
+        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.PopupWindow.ActionMode</item>
+        <item name="actionBarWidgetTheme">@null</item>
+        <item name="actionBarItemBackground">@drawable/item_background_borderless_quantum_dark</item>
+
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum_dark</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum_dark</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum_dark</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum_dark</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum_dark</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum_dark</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum_dark</item>
+
+        <item name="dividerVertical">?attr/listDivider</item>
+        <item name="dividerHorizontal">?attr/listDivider</item>
+        <item name="buttonBarStyle">@style/Quantum.ButtonBar</item>
+        <item name="buttonBarButtonStyle">?attr/borderlessButtonStyle</item>
+        <item name="segmentedButtonStyle">@style/Quantum.SegmentedButton</item>
+
+        <!-- SearchView attributes -->
+        <item name="searchDropdownBackground">@drawable/search_dropdown_dark</item>
+
+        <item name="searchDialogTheme">@style/Theme.Quantum.SearchBar</item>
+
+        <!-- PreferenceFrameLayout attributes -->
+        <item name="preferenceFrameLayoutStyle">@style/Widget.Quantum.PreferenceFrameLayout</item>
+
+        <!-- NumberPicker style-->
+        <item name="numberPickerStyle">@style/Widget.Quantum.NumberPicker</item>
+
+        <!-- CalendarView style-->
+        <item name="calendarViewStyle">@style/Widget.Quantum.CalendarView</item>
+
+        <!-- TimePicker style -->
+        <item name="timePickerStyle">@style/Widget.Quantum.TimePicker</item>
+
+        <!-- TimePicker background color -->
+        <item name="timePickerHeaderBackgroundColor">@color/timepicker_default_background_quantum_dark</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Quantum.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@style/Theme.Quantum.Dialog.TimePicker</item>
+
+        <!-- DatePicker style -->
+        <item name="datePickerStyle">@style/Widget.Quantum.DatePicker</item>
+
+        <!-- TODO: This belongs in a FastScroll style -->
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum_light</item>
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_dark</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_dark</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum_dark</item>
+        <item name="fastScrollOverlayPosition">atThumb</item>
+    </style>
+
+    <!-- Quantum Paper theme (light version). -->
+    <style name="Theme.Quantum.Light" parent="Theme.Light">
+        <item name="colorForeground">@color/bright_foreground_quantum_light</item>
+        <item name="colorForegroundInverse">@color/bright_foreground_quantum_dark</item>
+        <item name="colorBackground">@color/background_quantum_light</item>
+        <item name="colorBackgroundCacheHint">@drawable/background_cache_hint_selector_quantum_light</item>
+        <item name="disabledAlpha">0.5</item>
+        <item name="backgroundDimAmount">0.6</item>
+
+        <!-- Text styles -->
+        <item name="textAppearance">@style/TextAppearance.Quantum.Light</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Light.Inverse</item>
+
+        <item name="textColorPrimary">@color/primary_text_quantum_light</item>
+        <item name="textColorPrimaryInverse">@color/primary_text_quantum_dark</item>
+        <item name="textColorSecondary">@color/secondary_text_quantum_light</item>
+        <item name="textColorSecondaryInverse">@color/secondary_text_quantum_dark</item>
+        <item name="textColorTertiary">@color/tertiary_text_quantum_light</item>
+        <item name="textColorTertiaryInverse">@color/tertiary_text_quantum_dark</item>
+        <item name="textColorPrimaryDisableOnly">@color/primary_text_disable_only_quantum_light</item>
+        <item name="textColorPrimaryInverseDisableOnly">@color/primary_text_disable_only_quantum_dark</item>
+        <item name="textColorHint">@color/hint_foreground_quantum_light</item>
+        <item name="textColorHintInverse">@color/hint_foreground_quantum_dark</item>
+        <item name="textColorHighlight">@color/highlighted_text_quantum_light</item>
+        <item name="textColorHighlightInverse">@color/highlighted_text_quantum_dark</item>
+        <item name="textColorLink">@color/quantum_teal_500</item>
+        <item name="textColorLinkInverse">@color/quantum_teal_500</item>
+        <item name="textColorSearchUrl">@color/search_url_text_quantum_light</item>
+        <item name="textColorAlertDialogListItem">@color/primary_text_quantum_light</item>
+
+        <item name="textAppearanceLarge">@style/TextAppearance.Quantum.Light.Large</item>
+        <item name="textAppearanceLargeInverse">@style/TextAppearance.Quantum.Light.Large.Inverse</item>
+        <item name="textAppearanceMedium">@style/TextAppearance.Quantum.Light.Medium</item>
+        <item name="textAppearanceMediumInverse">@style/TextAppearance.Quantum.Light.Medium.Inverse</item>
+        <item name="textAppearanceSmall">@style/TextAppearance.Quantum.Light.Small</item>
+        <item name="textAppearanceSmallInverse">@style/TextAppearance.Quantum.Light.Small.Inverse</item>
+        <item name="textAppearanceSearchResultTitle">@style/TextAppearance.Quantum.Light.SearchResult.Title</item>
+        <item name="textAppearanceSearchResultSubtitle">@style/TextAppearance.Quantum.Light.SearchResult.Subtitle</item>
+
+        <item name="textAppearanceButton">@style/TextAppearance.Quantum.Light.Widget.Button</item>
+
+        <item name="editTextColor">?attr/textColorPrimary</item>
+        <item name="editTextBackground">@drawable/edit_text_quantum_light</item>
+
+        <item name="candidatesTextStyleSpans">@string/candidates_style</item>
+
+        <item name="textCheckMark">@drawable/indicator_check_mark_light</item>
+        <item name="textCheckMarkInverse">@drawable/indicator_check_mark_dark</item>
+
+        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.Quantum.Light.Widget.PopupMenu.Large</item>
+        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.Quantum.Light.Widget.PopupMenu.Small</item>
+
+        <!-- Button styles -->
+        <item name="buttonStyle">@style/Widget.Quantum.Light.Button</item>
+
+        <item name="buttonStyleSmall">@style/Widget.Quantum.Light.Button.Small</item>
+        <item name="buttonStyleInset">@style/Widget.Quantum.Light.Button.Inset</item>
+
+        <item name="buttonStyleToggle">@style/Widget.Quantum.Light.Button.Toggle</item>
+        <item name="switchStyle">@style/Widget.Quantum.Light.CompoundButton.Switch</item>
+        <item name="mediaRouteButtonStyle">@style/Widget.Quantum.Light.MediaRouteButton</item>
+
+        <item name="selectableItemBackground">@drawable/item_background_quantum_light</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless</item>
+        <item name="homeAsUpIndicator">@drawable/ic_ab_back_quantum_light</item>
+
+        <!-- List attributes -->
+        <item name="listPreferredItemHeight">64dip</item>
+        <item name="listPreferredItemHeightSmall">48dip</item>
+        <item name="listPreferredItemHeightLarge">80dip</item>
+        <item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
+        <item name="textAppearanceListItemSmall">?attr/textAppearanceMedium</item>
+        <item name="listPreferredItemPaddingLeft">8dip</item>
+        <item name="listPreferredItemPaddingRight">8dip</item>
+        <item name="listPreferredItemPaddingStart">8dip</item>
+        <item name="listPreferredItemPaddingEnd">8dip</item>
+
+        <!-- @hide -->
+        <item name="searchResultListItemHeight">58dip</item>
+        <item name="listDivider">@drawable/list_divider_quantum_light</item>
+        <item name="listSeparatorTextViewStyle">@style/Widget.Quantum.Light.TextView.ListSeparator</item>
+
+        <item name="listChoiceIndicatorSingle">@drawable/btn_radio_quantum_light</item>
+        <item name="listChoiceIndicatorMultiple">@drawable/btn_check_quantum_light</item>
+
+        <item name="listChoiceBackgroundIndicator">@drawable/list_selector_holo_light</item>
+
+        <item name="activatedBackgroundIndicator">@drawable/activated_background_quantum_light</item>
+
+        <item name="expandableListPreferredItemPaddingLeft">40dip</item>
+        <item name="expandableListPreferredChildPaddingLeft">?attr/expandableListPreferredItemPaddingLeft</item>
+
+        <item name="expandableListPreferredItemIndicatorLeft">3dip</item>
+        <item name="expandableListPreferredItemIndicatorRight">0dip</item>
+        <item name="expandableListPreferredChildIndicatorLeft">?attr/expandableListPreferredItemIndicatorLeft</item>
+        <item name="expandableListPreferredChildIndicatorRight">?attr/expandableListPreferredItemIndicatorRight</item>
+
+        <item name="listDividerAlertDialog">@drawable/list_divider_quantum_light</item>
+        <item name="findOnPageNextDrawable">@drawable/ic_find_next_quantum_light</item>
+        <item name="findOnPagePreviousDrawable">@drawable/ic_find_previous_quantum_light</item>
+
+        <!-- Gallery attributes -->
+        <item name="galleryItemBackground">@drawable/gallery_item_background</item>
+
+        <!-- Window attributes -->
+        <item name="windowBackground">@color/background_quantum_light</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowNoTitle">false</item>
+        <item name="windowFullscreen">false</item>
+        <item name="windowOverscan">false</item>
+        <item name="windowIsFloating">false</item>
+        <item name="windowContentOverlay">@drawable/ab_solid_shadow_qntm</item>
+        <item name="windowShowWallpaper">false</item>
+        <item name="windowTitleStyle">@style/WindowTitle.Quantum</item>
+        <item name="windowTitleSize">25dip</item>
+        <item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Quantum</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Activity</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
+        <item name="windowActionBar">true</item>
+        <item name="windowActionModeOverlay">false</item>
+
+        <!-- Dialog attributes -->
+        <item name="dialogTheme">@style/Theme.Quantum.Light.Dialog</item>
+        <item name="dialogTitleIconsDecorLayout">@layout/dialog_title_icons_holo</item>
+        <item name="dialogCustomTitleDecorLayout">@layout/dialog_custom_title_holo</item>
+        <item name="dialogTitleDecorLayout">@layout/dialog_title_holo</item>
+
+        <!-- AlertDialog attributes -->
+        <item name="alertDialogTheme">@style/Theme.Quantum.Light.Dialog.Alert</item>
+        <item name="alertDialogStyle">@style/AlertDialog.Quantum.Light</item>
+        <item name="alertDialogCenterButtons">false</item>
+        <item name="alertDialogIcon">@drawable/ic_dialog_alert_quantum_light</item>
+
+        <!-- Presentation attributes -->
+        <item name="presentationTheme">@style/Theme.Quantum.Light.Dialog.Presentation</item>
+
+        <!-- Toast attributes -->
+        <item name="toastFrameBackground">@drawable/toast_frame</item>
+
+        <!-- Panel attributes -->
+        <item name="panelBackground">?attr/colorBackground</item>
+        <item name="panelFullBackground">@drawable/menu_background_fill_parent_width</item>
+        <!-- These three attributes do not seems to be used by the framework. Declared public though -->
+        <item name="panelColorBackground">#000</item>
+        <item name="panelColorForeground">?attr/textColorPrimary</item>
+        <item name="panelTextAppearance">?attr/textAppearance</item>
+
+        <item name="panelMenuIsCompact">true</item>
+        <item name="panelMenuListWidth">250dip</item>
+        <item name="panelMenuListTheme">@style/Theme.Quantum.Light.CompactMenu</item>
+
+        <!-- Scrollbar attributes -->
+        <item name="scrollbarFadeDuration">250</item>
+        <item name="scrollbarDefaultDelayBeforeFade">300</item>
+        <item name="scrollbarSize">10dip</item>
+        <item name="scrollbarThumbHorizontal">@drawable/scrollbar_handle_quantum_light</item>
+        <item name="scrollbarThumbVertical">@drawable/scrollbar_handle_quantum_light</item>
+        <item name="scrollbarTrackHorizontal">@null</item>
+        <item name="scrollbarTrackVertical">@null</item>
+
+        <!-- Text selection handle attributes -->
+        <item name="textSelectHandleLeft">@drawable/text_select_handle_left</item>
+        <item name="textSelectHandleRight">@drawable/text_select_handle_right</item>
+        <item name="textSelectHandle">@drawable/text_select_handle_middle</item>
+        <item name="textSelectHandleWindowStyle">@style/Widget.Quantum.TextSelectHandle</item>
+        <item name="textSuggestionsWindowStyle">@style/Widget.Quantum.Light.TextSuggestionsPopupWindow</item>
+        <item name="textCursorDrawable">@drawable/text_cursor_quantum_light</item>
+
+        <!-- Widget styles -->
+        <item name="absListViewStyle">@style/Widget.Quantum.Light.AbsListView</item>
+        <item name="autoCompleteTextViewStyle">@style/Widget.Quantum.Light.AutoCompleteTextView</item>
+        <item name="checkboxStyle">@style/Widget.Quantum.Light.CompoundButton.CheckBox</item>
+        <item name="checkedTextViewStyle">@style/Widget.Quantum.Light.CheckedTextView</item>
+        <item name="dropDownListViewStyle">@style/Widget.Quantum.ListView.DropDown</item>
+        <item name="editTextStyle">@style/Widget.Quantum.Light.EditText</item>
+        <item name="expandableListViewStyle">@style/Widget.Quantum.Light.ExpandableListView</item>
+        <item name="expandableListViewWhiteStyle">@style/Widget.Quantum.Light.ExpandableListView.White</item>
+        <item name="fastScrollStyle">@style/Widget.Quantum.Light.FastScroll</item>
+        <item name="galleryStyle">@style/Widget.Quantum.Light.Gallery</item>
+        <item name="gestureOverlayViewStyle">@style/Widget.Quantum.Light.GestureOverlayView</item>
+        <item name="gridViewStyle">@style/Widget.Quantum.Light.GridView</item>
+        <item name="imageButtonStyle">@style/Widget.Quantum.Light.ImageButton</item>
+        <item name="imageWellStyle">@style/Widget.Quantum.Light.ImageWell</item>
+        <item name="listViewStyle">@style/Widget.Quantum.Light.ListView</item>
+        <item name="listViewWhiteStyle">@style/Widget.Quantum.Light.ListView.White</item>
+        <item name="popupWindowStyle">@style/Widget.Quantum.Light.PopupWindow</item>
+        <item name="progressBarStyle">@style/Widget.Quantum.Light.ProgressBar</item>
+        <item name="progressBarStyleHorizontal">@style/Widget.Quantum.Light.ProgressBar.Horizontal</item>
+        <item name="progressBarStyleSmall">@style/Widget.Quantum.Light.ProgressBar.Small</item>
+        <item name="progressBarStyleSmallTitle">@style/Widget.Quantum.Light.ProgressBar.Small.Title</item>
+        <item name="progressBarStyleLarge">@style/Widget.Quantum.Light.ProgressBar.Large</item>
+        <item name="progressBarStyleInverse">@style/Widget.Quantum.Light.ProgressBar.Inverse</item>
+        <item name="progressBarStyleSmallInverse">@style/Widget.Quantum.Light.ProgressBar.Small.Inverse</item>
+        <item name="progressBarStyleLargeInverse">@style/Widget.Quantum.Light.ProgressBar.Large.Inverse</item>
+        <item name="seekBarStyle">@style/Widget.Quantum.Light.SeekBar</item>
+        <item name="ratingBarStyle">@style/Widget.Quantum.Light.RatingBar</item>
+        <item name="ratingBarStyleIndicator">@style/Widget.Quantum.Light.RatingBar.Indicator</item>
+        <item name="ratingBarStyleSmall">@style/Widget.Quantum.Light.RatingBar.Small</item>
+        <item name="radioButtonStyle">@style/Widget.Quantum.Light.CompoundButton.RadioButton</item>
+        <item name="scrollViewStyle">@style/Widget.Quantum.Light.ScrollView</item>
+        <item name="horizontalScrollViewStyle">@style/Widget.Quantum.Light.HorizontalScrollView</item>
+        <item name="spinnerStyle">?attr/dropDownSpinnerStyle</item>
+        <item name="dropDownSpinnerStyle">@style/Widget.Quantum.Light.Spinner.DropDown</item>
+        <item name="starStyle">@style/Widget.Quantum.Light.CompoundButton.Star</item>
+        <item name="tabWidgetStyle">@style/Widget.Quantum.Light.TabWidget</item>
+        <item name="textViewStyle">@style/Widget.Quantum.Light.TextView</item>
+        <item name="errorMessageBackground">@drawable/popup_inline_error_holo_light</item>
+        <item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_light</item>
+        <item name="webTextViewStyle">@style/Widget.Quantum.Light.WebTextView</item>
+        <item name="webViewStyle">@style/Widget.Quantum.Light.WebView</item>
+        <item name="dropDownItemStyle">@style/Widget.Quantum.Light.DropDownItem</item>
+        <item name="spinnerDropDownItemStyle">@style/Widget.Quantum.Light.DropDownItem.Spinner</item>
+        <item name="spinnerItemStyle">@style/Widget.Quantum.TextView.SpinnerItem</item>
+        <item name="dropDownHintAppearance">@style/TextAppearance.Quantum.Widget.DropDownHint</item>
+        <item name="keyboardViewStyle">@style/Widget.Quantum.KeyboardView</item>
+        <item name="quickContactBadgeStyleWindowSmall">@style/Widget.Quantum.QuickContactBadge.WindowSmall</item>
+        <item name="quickContactBadgeStyleWindowMedium">@style/Widget.Quantum.QuickContactBadge.WindowMedium</item>
+        <item name="quickContactBadgeStyleWindowLarge">@style/Widget.Quantum.QuickContactBadge.WindowLarge</item>
+        <item name="quickContactBadgeStyleSmallWindowSmall">@style/Widget.Quantum.QuickContactBadgeSmall.WindowSmall</item>
+        <item name="quickContactBadgeStyleSmallWindowMedium">@style/Widget.Quantum.QuickContactBadgeSmall.WindowMedium</item>
+        <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Quantum.QuickContactBadgeSmall.WindowLarge</item>
+        <item name="listPopupWindowStyle">@style/Widget.Quantum.Light.ListPopupWindow</item>
+        <item name="popupMenuStyle">@style/Widget.Quantum.Light.PopupMenu</item>
+        <item name="stackViewStyle">@style/Widget.Quantum.StackView</item>
+        <item name="activityChooserViewStyle">@style/Widget.Quantum.Light.ActivityChooserView</item>
+        <item name="fragmentBreadCrumbsStyle">@style/Widget.Quantum.Light.FragmentBreadCrumbs</item>
+
+        <!-- Preference styles -->
+        <item name="preferenceScreenStyle">@style/Preference.Quantum.PreferenceScreen</item>
+        <item name="preferenceFragmentStyle">@style/PreferenceFragment.Quantum</item>
+        <item name="preferenceCategoryStyle">@style/Preference.Quantum.Category</item>
+        <item name="preferenceStyle">@style/Preference.Quantum</item>
+        <item name="preferenceInformationStyle">@style/Preference.Quantum.Information</item>
+        <item name="checkBoxPreferenceStyle">@style/Preference.Quantum.CheckBoxPreference</item>
+        <item name="switchPreferenceStyle">@style/Preference.Quantum.SwitchPreference</item>
+        <item name="yesNoPreferenceStyle">@style/Preference.Quantum.DialogPreference.YesNoPreference</item>
+        <item name="dialogPreferenceStyle">@style/Preference.Quantum.DialogPreference</item>
+        <item name="editTextPreferenceStyle">@style/Preference.Quantum.DialogPreference.EditTextPreference</item>
+        <item name="ringtonePreferenceStyle">@style/Preference.Quantum.RingtonePreference</item>
+        <item name="preferenceLayoutChild">@layout/preference_child_holo</item>
+        <item name="detailsElementBackground">?attr/colorBackground</item>
+
+        <!-- PreferenceFrameLayout attributes -->
+        <item name="preferenceFrameLayoutStyle">@style/Widget.Quantum.PreferenceFrameLayout</item>
+
+        <!-- Search widget styles -->
+        <item name="searchWidgetCorpusItemBackground">@color/search_widget_corpus_item_background</item>
+
+        <!-- Action bar styles -->
+        <item name="actionDropDownStyle">@style/Widget.Quantum.Light.Spinner.DropDown.ActionBar</item>
+        <item name="actionButtonStyle">@style/Widget.Quantum.Light.ActionButton</item>
+        <item name="actionOverflowButtonStyle">@style/Widget.Quantum.Light.ActionButton.Overflow</item>
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
+        <item name="actionModeCloseDrawable">@drawable/ic_cab_done_quantum_light</item>
+        <item name="actionBarTabStyle">@style/Widget.Quantum.Light.ActionBar.TabView</item>
+        <item name="actionBarTabBarStyle">@style/Widget.Quantum.Light.ActionBar.TabBar</item>
+        <item name="actionBarTabTextStyle">@style/Widget.Quantum.Light.ActionBar.TabText</item>
+        <item name="actionModeStyle">@style/Widget.Quantum.Light.ActionMode</item>
+        <item name="actionModeCloseButtonStyle">@style/Widget.Quantum.Light.ActionButton.CloseMode</item>
+        <item name="actionBarStyle">@style/Widget.Quantum.Light.ActionBar.Solid</item>
+        <item name="actionBarSize">@dimen/action_bar_default_height</item>
+        <item name="actionModePopupWindowStyle">@style/Widget.Quantum.Light.PopupWindow.ActionMode</item>
+        <item name="actionBarWidgetTheme">@null</item>
+        <item name="actionBarItemBackground">@drawable/item_background_borderless_quantum_light</item>
+
+        <item name="actionModeCutDrawable">@drawable/ic_menu_cut_quantum_light</item>
+        <item name="actionModeCopyDrawable">@drawable/ic_menu_copy_quantum_light</item>
+        <item name="actionModePasteDrawable">@drawable/ic_menu_paste_quantum_light</item>
+        <item name="actionModeSelectAllDrawable">@drawable/ic_menu_selectall_quantum_light</item>
+        <item name="actionModeShareDrawable">@drawable/ic_menu_share_quantum_light</item>
+        <item name="actionModeFindDrawable">@drawable/ic_menu_find_quantum_light</item>
+        <item name="actionModeWebSearchDrawable">@drawable/ic_menu_search_quantum_light</item>
+
+        <item name="dividerVertical">?attr/listDivider</item>
+        <item name="dividerHorizontal">?attr/listDivider</item>
+        <item name="buttonBarStyle">@style/Quantum.Light.ButtonBar</item>
+        <item name="buttonBarButtonStyle">?attr/borderlessButtonStyle</item>
+        <item name="segmentedButtonStyle">@style/Quantum.Light.SegmentedButton</item>
+
+        <!-- SearchView attributes -->
+        <item name="searchDropdownBackground">@drawable/search_dropdown_light</item>
+
+        <item name="searchDialogTheme">@style/Theme.Quantum.Light.SearchBar</item>
+
+        <!-- NumberPicker style-->
+        <item name="numberPickerStyle">@style/Widget.Quantum.Light.NumberPicker</item>
+
+        <!-- CalendarView style-->
+        <item name="calendarViewStyle">@style/Widget.Quantum.Light.CalendarView</item>
+
+        <!-- TimePicker style -->
+        <item name="timePickerStyle">@style/Widget.Quantum.Light.TimePicker</item>
+
+        <!-- TimePicker Header background color -->
+        <item name="timePickerHeaderBackgroundColor">@color/timepicker_default_background_quantum_light</item>
+
+        <!-- TimePicker Header time label text appearance -->
+        <item name="timePickerHeaderTimeLabelTextAppearance">@style/TextAppearance.Quantum.Light.TimePicker.TimeLabel</item>
+
+        <!-- TimePicker Header am pm label text appearance -->
+        <item name="timePickerHeaderAmPmLabelTextAppearance">@style/TextAppearance.Quantum.Light.TimePicker.AmPmLabel</item>
+
+        <!-- TimePicker dialog theme -->
+        <item name="timePickerDialogTheme">@style/Theme.Quantum.Light.Dialog.TimePicker</item>
+
+        <!-- DatePicker style -->
+        <item name="datePickerStyle">@style/Widget.Quantum.Light.DatePicker</item>
+
+        <item name="fastScrollThumbDrawable">@drawable/fastscroll_thumb_quantum_light</item>
+        <item name="fastScrollPreviewBackgroundLeft">@drawable/fastscroll_label_left_holo_light</item>
+        <item name="fastScrollPreviewBackgroundRight">@drawable/fastscroll_label_right_holo_light</item>
+        <item name="fastScrollTrackDrawable">@drawable/fastscroll_track_quantum_light</item>
+        <item name="fastScrollOverlayPosition">atThumb</item>
+    </style>
+
+    <!-- Variant of the quantum (light) theme that has a solid (opaque) action bar
+         with an inverse color profile. The dark action bar sharply stands out against
+         the light content. -->
+    <style name="Theme.Quantum.Light.DarkActionBar">
+        <item name="actionBarTheme">@style/Theme.Quantum</item>
+    </style>
+
+    <!-- Variant of the quantum (dark) theme with no action bar. -->
+    <style name="Theme.Quantum.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of the quantum (dark) theme that has no title bar and fills
+         the entire screen.  This theme
+         sets {@link android.R.attr#windowFullscreen} to true.  -->
+    <style name="Theme.Quantum.NoActionBar.Fullscreen">
+        <item name="windowFullscreen">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the quantum (dark) theme that has no title bar and fills
+         the entire screen and extends into the display overscan region.  This theme
+         sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
+         to true. -->
+    <style name="Theme.Quantum.NoActionBar.Overscan">
+        <item name="windowFullscreen">true</item>
+        <item name="windowOverscan">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the quantum (dark) theme that has no title bar and translucent
+         system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
+         {@link android.R.attr#windowTranslucentNavigation} to true. -->
+    <style name="Theme.Quantum.NoActionBar.TranslucentDecor">
+        <item name="windowTranslucentStatus">true</item>
+        <item name="windowTranslucentNavigation">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the quantum (light) theme with no action bar. -->
+    <style name="Theme.Quantum.Light.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of the quantum (light) theme that has no title bar and fills
+         the entire screen.  This theme
+         sets {@link android.R.attr#windowFullscreen} to true.  -->
+    <style name="Theme.Quantum.Light.NoActionBar.Fullscreen">
+        <item name="windowFullscreen">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the quantum (light) theme that has no title bar and fills
+         the entire screen and extends into the display overscan region.  This theme
+         sets {@link android.R.attr#windowFullscreen} and {@link android.R.attr#windowOverscan}
+         to true. -->
+    <style name="Theme.Quantum.Light.NoActionBar.Overscan">
+        <item name="windowFullscreen">true</item>
+        <item name="windowOverscan">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Variant of the quantum (light) theme that has no title bar and translucent
+         system decor.  This theme sets {@link android.R.attr#windowTranslucentStatus} and
+         {@link android.R.attr#windowTranslucentNavigation} to true. -->
+    <style name="Theme.Quantum.Light.NoActionBar.TranslucentDecor">
+        <item name="windowTranslucentStatus">true</item>
+        <item name="windowTranslucentNavigation">true</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Default quantum dark theme for panel windows.  This removes all extraneous
+         window decorations, so you basically have an empty rectangle in which
+         to place your content.  It makes the window floating, with a transparent
+         background, and turns off dimming behind the window. -->
+    <style name="Theme.Quantum.Panel">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="windowIsFloating">true</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Default quantum light theme for panel windows.  This removes all extraneous
+         window decorations, so you basically have an empty rectangle in which
+         to place your content.  It makes the window floating, with a transparent
+         background, and turns off dimming behind the window. -->
+    <style name="Theme.Quantum.Light.Panel">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="windowIsFloating">true</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Default theme for quantum style input methods, which is used by the
+         {@link android.inputmethodservice.InputMethodService} class.
+         this inherits from Theme.Panel, but sets up IME appropriate animations
+         and a few custom attributes. -->
+    <style name="Theme.Quantum.InputMethod" parent="Theme.Quantum.Light.Panel">
+        <item name="windowAnimationStyle">@style/Animation.InputMethod</item>
+        <item name="imeFullscreenBackground">@drawable/screen_background_selector_light</item>
+        <item name="imeExtractEnterAnimation">@anim/input_method_extract_enter</item>
+        <item name="imeExtractExitAnimation">@anim/input_method_extract_exit</item>
+    </style>
+
+    <!-- Theme for the search input bar. -->
+
+    <style name="Theme.Quantum.SearchBar" parent="Theme.Quantum.Panel">
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_dark</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
+    </style>
+
+    <style name="Theme.Quantum.Light.SearchBar" parent="Theme.Quantum.Light.Panel">
+        <item name="actionModeBackground">@drawable/cab_background_top_holo_light</item>
+        <item name="actionModeSplitBackground">@drawable/cab_background_bottom_holo_light</item>
+    </style>
+
+    <!-- Menu Themes -->
+    <eat-comment />
+
+    <style name="Theme.Quantum.CompactMenu">
+        <!-- Menu/item attributes -->
+        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
+        <item name="listViewStyle">@style/Widget.Quantum.ListView</item>
+        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
+        <item name="background">@null</item>
+    </style>
+
+    <style name="Theme.Quantum.Light.CompactMenu">
+        <!-- Menu/item attributes -->
+        <item name="itemTextAppearance">?attr/textAppearanceMedium</item>
+        <item name="listViewStyle">@style/Widget.Quantum.Light.ListView</item>
+        <item name="windowAnimationStyle">@style/Animation.DropDownUp</item>
+        <item name="background">@null</item>
+    </style>
+
+    <!-- Dialog themes for Quantum -->
+    <eat-comment />
+
+    <!-- Quantum theme for dialog windows and activities, which is used by the
+         {@link android.app.Dialog} class.  This changes the window to be
+         floating (not fill the entire screen), and puts a frame around its
+         contents.  You can set this theme on an activity if you would like to
+         make an activity that looks like a Dialog. -->
+    <style name="Theme.Quantum.Dialog">
+        <item name="windowFrame">@null</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
+        <item name="windowBackground">?attr/colorBackground</item>
+        <item name="windowIsFloating">true</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowActionModeOverlay">true</item>
+        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
+
+        <item name="colorBackgroundCacheHint">@null</item>
+
+        <item name="buttonBarStyle">@style/Quantum.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Button.Borderless.Small</item>
+
+        <item name="textAppearance">@style/TextAppearance.Quantum</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Inverse</item>
+
+        <item name="listPreferredItemPaddingLeft">16dip</item>
+        <item name="listPreferredItemPaddingRight">16dip</item>
+        <item name="listPreferredItemPaddingStart">16dip</item>
+        <item name="listPreferredItemPaddingEnd">16dip</item>
+
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Dialog that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Quantum.Dialog.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Dialog that does not include a title bar. -->
+    <style name="Theme.Quantum.Dialog.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Dialog.NoActionBar that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Quantum.Dialog.NoActionBar.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Dialog that has a fixed size. -->
+    <style name="Theme.Quantum.Dialog.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Dialog.NoActionBar that has a fixed size. -->
+    <style name="Theme.Quantum.Dialog.NoActionBar.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Dialog that does not include a frame (or background).
+         The view hierarchy of the dialog is responsible for drawing all of
+         its pixels. -->
+    <style name="Theme.Quantum.Dialog.NoFrame">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowFrame">@null</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@null</item>
+        <item name="backgroundDimEnabled">false</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+        <item name="windowCloseOnTouchOutside">false</item>
+    </style>
+
+    <!-- Quantum theme for alert dialog windows, which is used by the
+         {@link android.app.AlertDialog} class.  This is basically a dialog
+         but sets the background to empty so it can do two-tone backgrounds.
+         For applications targeting Honeycomb or newer, this is the default
+         AlertDialog theme. -->
+    <style name="Theme.Quantum.Dialog.Alert">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Quantum theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Quantum.Dialog.TimePicker">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Theme for a window that will be displayed either full-screen on
+         smaller screens (small, normal) or as a dialog on larger screens
+         (large, xlarge). -->
+    <style name="Theme.Quantum.DialogWhenLarge" parent="@style/Theme.Quantum">
+    </style>
+
+    <!-- Theme for a window without a title bar that will be displayed either
+         full-screen on smaller screens (small, normal) or as a dialog on larger screens
+         (large, xlarge). -->
+    <style name="Theme.Quantum.DialogWhenLarge.NoActionBar" parent="@style/Theme.Quantum.NoActionBar">
+    </style>
+
+    <!-- Theme for a presentation window on a secondary display. -->
+    <style name="Theme.Quantum.Dialog.Presentation" parent="@style/Theme.Quantum.NoActionBar.Fullscreen">
+    </style>
+
+    <!-- Light quantum dialog themes -->
+
+    <!-- Quantum light theme for dialog windows and activities, which is used by the
+         {@link android.app.Dialog} class.  This changes the window to be
+         floating (not fill the entire screen), and puts a frame around its
+         contents.  You can set this theme on an activity if you would like to
+         make an activity that looks like a Dialog. -->
+    <style name="Theme.Quantum.Light.Dialog">
+        <item name="windowFrame">@null</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
+        <item name="windowBackground">?attr/colorBackground</item>
+        <item name="windowIsFloating">true</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowAnimationStyle">@style/Animation.Quantum.Dialog</item>
+        <item name="windowSoftInputMode">stateUnspecified|adjustPan</item>
+        <item name="windowActionBar">false</item>
+        <item name="windowActionModeOverlay">true</item>
+        <item name="windowCloseOnTouchOutside">@bool/config_closeDialogWhenTouchOutside</item>
+
+        <item name="colorBackgroundCacheHint">@null</item>
+
+        <item name="buttonBarStyle">@style/Quantum.Light.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@style/Widget.Quantum.Light.Button.Borderless.Small</item>
+
+        <item name="textAppearance">@style/TextAppearance.Quantum.Light</item>
+        <item name="textAppearanceInverse">@style/TextAppearance.Quantum.Light.Inverse</item>
+
+        <item name="listPreferredItemPaddingLeft">16dip</item>
+        <item name="listPreferredItemPaddingRight">16dip</item>
+        <item name="listPreferredItemPaddingStart">16dip</item>
+        <item name="listPreferredItemPaddingEnd">16dip</item>
+
+        <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Light.Dialog that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Quantum.Light.Dialog.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Light.Dialog that does not include a title bar. -->
+    <style name="Theme.Quantum.Light.Dialog.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Light.Dialog.NoActionBar that has a nice minimum width for
+         a regular dialog. -->
+    <style name="Theme.Quantum.Light.Dialog.NoActionBar.MinWidth">
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Light.Dialog that has a fixed size. -->
+    <style name="Theme.Quantum.Light.Dialog.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- Variant of Theme.Quantum.Light.Dialog.NoActionBar that has a fixed size. -->
+    <style name="Theme.Quantum.Light.Dialog.NoActionBar.FixedSize">
+        <item name="windowFixedWidthMajor">@dimen/dialog_fixed_width_major</item>
+        <item name="windowFixedWidthMinor">@dimen/dialog_fixed_width_minor</item>
+        <item name="windowFixedHeightMajor">@dimen/dialog_fixed_height_major</item>
+        <item name="windowFixedHeightMinor">@dimen/dialog_fixed_height_minor</item>
+    </style>
+
+    <!-- Theme for a window that will be displayed either full-screen on
+         smaller screens (small, normal) or as a dialog on larger screens
+         (large, xlarge). -->
+    <style name="Theme.Quantum.Light.DialogWhenLarge" parent="@style/Theme.Quantum.Light">
+    </style>
+
+    <!-- Theme for a window without an action bar that will be displayed either full-screen
+         on smaller screens (small, normal) or as a dialog on larger screens
+         (large, xlarge). -->
+    <style name="Theme.Quantum.Light.DialogWhenLarge.NoActionBar"
+            parent="@style/Theme.Quantum.Light.NoActionBar">
+    </style>
+
+    <!-- Quantum light theme for alert dialog windows, which is used by the
+         {@link android.app.AlertDialog} class.  This is basically a dialog
+         but sets the background to empty so it can do two-tone backgrounds.
+         For applications targeting Honeycomb or newer, this is the default
+         AlertDialog theme. -->
+    <style name="Theme.Quantum.Light.Dialog.Alert">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="windowMinWidthMajor">@dimen/dialog_min_width_major</item>
+        <item name="windowMinWidthMinor">@dimen/dialog_min_width_minor</item>
+    </style>
+
+    <!-- Quantum Light theme for the TimePicker dialog windows, which is used by the
+         {@link android.app.TimePickerDialog} class. -->
+    <style name="Theme.Quantum.Light.Dialog.TimePicker">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="windowTitleStyle">@style/DialogWindowTitle.Quantum.Light</item>
+        <item name="windowContentOverlay">@null</item>
+    </style>
+
+    <!-- Theme for a presentation window on a secondary display. -->
+    <style name="Theme.Quantum.Light.Dialog.Presentation" parent="@style/Theme.Quantum.Light.NoActionBar.Fullscreen" >
+    </style>
+
+    <!-- Default quantum (dark) for windows that want to have the user's selected
+         wallpaper appear behind them.  -->
+    <style name="Theme.Quantum.Wallpaper">
+        <item name="windowBackground">@color/transparent</item>
+        <item name="colorBackgroundCacheHint">@null</item>
+        <item name="windowShowWallpaper">true</item>
+    </style>
+
+    <!--Default quantum (dark) for windows that want to have the user's selected
+         wallpaper appear behind them and without an action bar. -->
+    <style name="Theme.Quantum.Wallpaper.NoTitleBar">
+        <item name="windowNoTitle">true</item>
+    </style>
+
+</resources>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index b942eb6..cad030a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -252,26 +252,26 @@
                 if (!validateEapValue(eapValue)) {
                     throw new SAXException();
                 }
-		if (eapValue.equals("TLS")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
-		} else if (eapValue.equals("TTLS")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
-		} else if (eapValue.equals("PEAP")) {
-		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
-		}
+                if (eapValue.equals("TLS")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+                } else if (eapValue.equals("TTLS")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
+                } else if (eapValue.equals("PEAP")) {
+                    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
+                }
                 eap = false;
             }
             if (phase2) {
                 String phase2Value = new String(ch, start, length);
-		if (phase2Value.equals("PAP")) {
+                if (phase2Value.equals("PAP")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
-		} else if (phase2Value.equals("MSCHAP")) {
+                } else if (phase2Value.equals("MSCHAP")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAP);
-		} else if (phase2Value.equals("MSCHAPV2")) {
+                } else if (phase2Value.equals("MSCHAPV2")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
-		} else if (phase2Value.equals("GTC")) {
+                } else if (phase2Value.equals("GTC")) {
                     config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
-		}
+                }
                 phase2 = false;
             }
             if (identity) {
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
index 04ce4b7..91c3093 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java
@@ -27,6 +27,7 @@
 import android.net.wifi.WifiManager;
 import android.os.Environment;
 import android.os.PowerManager;
+import android.os.SystemClock;
 import android.provider.Settings;
 import android.view.KeyEvent;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -52,6 +53,7 @@
         extends ConnectivityManagerTestBase {
     private final static String TAG = "WifiStressTest";
 
+    private final static long SCREEN_OFF_TIMER = 500; //500ms
     /**
      * Wi-Fi idle time for default sleep policy
      */
@@ -157,11 +159,11 @@
             writeOutput(String.format("average scanning time is %d", averageScanTime));
             writeOutput(String.format("ssid appear %d out of %d scan iterations",
                     ssidAppearInScanResultsCount, i));
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             scanResultAvailable = false;
             assertTrue("start scan failed", mWifiManager.startScan());
             while (true) {
-                if ((System.currentTimeMillis() - startTime) >
+                if ((SystemClock.uptimeMillis() - startTime) >
                 WIFI_SCAN_TIMEOUT) {
                     fail("Wifi scanning takes more than " + WIFI_SCAN_TIMEOUT + " ms");
                 }
@@ -172,7 +174,7 @@
                         e.printStackTrace();
                     }
                     if (scanResultAvailable) {
-                        long scanTime = (System.currentTimeMillis() - startTime);
+                        long scanTime = (SystemClock.uptimeMillis() - startTime);
                         scanTimeSum += scanTime;
                         break;
                     }
@@ -255,8 +257,13 @@
                     i, mReconnectIterations));
             log("iteration: " + i);
             turnScreenOff();
+            // Use clock time since boot for intervals.
+            long start = SystemClock.uptimeMillis();
             PowerManager pm =
                 (PowerManager)mRunner.getContext().getSystemService(Context.POWER_SERVICE);
+            while (pm.isScreenOn() && ((SystemClock.uptimeMillis() - start) < SCREEN_OFF_TIMER)) {
+                sleep(100, "wait for screen off");
+            }
             assertFalse(pm.isScreenOn());
             sleep(WIFI_IDLE_MS + WIFI_SHUTDOWN_DELAY, "Interruped while wait for wifi to be idle");
             assertTrue("Wait for Wi-Fi to idle timeout",
@@ -287,14 +294,14 @@
             mRunner.sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
 
             // Measure the time for Wi-Fi to get connected
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             assertTrue("Wait for Wi-Fi enable timeout after wake up",
                     waitForWifiState(WifiManager.WIFI_STATE_ENABLED,
                     SHORT_TIMEOUT));
             assertTrue("Wait for Wi-Fi connection timeout after wake up",
                     waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED,
                     WIFI_CONNECTION_TIMEOUT));
-            long connectionTime = System.currentTimeMillis() - startTime;
+            long connectionTime = SystemClock.uptimeMillis() - startTime;
             sum += connectionTime;
             log("average reconnection time is: " + sum/(i+1));
 
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index be55444..73a53cb 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -22,6 +22,7 @@
 	$(call all-java-files-under, EnabledTestApp/src)
 
 LOCAL_DX_FLAGS := --core-library
+LOCAL_AAPT_FLAGS = -0 dat -0 gld
 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/assets/backup_mock.dat b/core/tests/coretests/assets/backup_mock.dat
new file mode 100644
index 0000000..f70b573
--- /dev/null
+++ b/core/tests/coretests/assets/backup_mock.dat
Binary files differ
diff --git a/core/tests/coretests/assets/backup_mock.gld b/core/tests/coretests/assets/backup_mock.gld
new file mode 100644
index 0000000..5197c23
--- /dev/null
+++ b/core/tests/coretests/assets/backup_mock.gld
@@ -0,0 +1,4 @@
+key1:
+key2a:YWJjZGVmZw==
+key3bc:YWJjZGVmZ2g=
+key4dad:
diff --git a/core/tests/coretests/assets/backup_real.dat b/core/tests/coretests/assets/backup_real.dat
new file mode 100644
index 0000000..2262568
--- /dev/null
+++ b/core/tests/coretests/assets/backup_real.dat
Binary files differ
diff --git a/core/tests/coretests/assets/backup_real.gld b/core/tests/coretests/assets/backup_real.gld
new file mode 100644
index 0000000..ef28f9b
--- /dev/null
+++ b/core/tests/coretests/assets/backup_real.gld
@@ -0,0 +1,3 @@
+CAEYLw:CC8QABoIR0VMIFN0dWIgnP//////////ASgBMAJAAUgBapgBI0ludGVudDthY3Rpb249YW5kcm9pZC5pbnRlbnQuYWN0aW9uLk1BSU47Y2F0ZWdvcnk9YW5kcm9pZC5pbnRlbnQuY2F0ZWdvcnkuTEFVTkNIRVI7bGF1bmNoRmxhZ3M9MHgxMDIwMDAwMDtjb21wb25lbnQ9Y29tLmdvb2dsZS5hbmRyb2lkLmdlbC8uU3R1YkFwcDtlbmQ=
+CAEYLQ:
+CAEYLA:
diff --git a/core/tests/coretests/src/android/app/TranslucentFancyActivity.java b/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
index ec5ad7a..35abaaa 100644
--- a/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
+++ b/core/tests/coretests/src/android/app/TranslucentFancyActivity.java
@@ -53,7 +53,7 @@
      * describe what is to be displayed in the screen.
      */
     @Override
-	protected void onCreate(Bundle icicle)
+    protected void onCreate(Bundle icicle)
     {
         // Be sure to call the super class.
         super.onCreate(icicle);
diff --git a/core/tests/coretests/src/android/app/activity/AbortReceiver.java b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
index fef1775..8d5c022 100644
--- a/core/tests/coretests/src/android/app/activity/AbortReceiver.java
+++ b/core/tests/coretests/src/android/app/activity/AbortReceiver.java
@@ -32,7 +32,7 @@
 
     public void onReceive(Context context, Intent intent)
     {
-	//Log.i("AbortReceiver", "onReceiveIntent!");
+        //Log.i("AbortReceiver", "onReceiveIntent!");
         try {
             IBinder caller = intent.getIBinderExtra("caller");
             Parcel data = Parcel.obtain();
diff --git a/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
index e969d10..9f402a5 100644
--- a/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
+++ b/core/tests/coretests/src/android/app/activity/RemoteSubActivityScreen.java
@@ -24,19 +24,19 @@
 import android.util.Log;
 
 public class RemoteSubActivityScreen extends SubActivityScreen {
-	Handler mHandler = new Handler();
-	boolean mFirst = false;
+    Handler mHandler = new Handler();
+    boolean mFirst = false;
 
     public RemoteSubActivityScreen() {
     }
 
     @Override
     public void onCreate(Bundle icicle) {
-    	// We are running in a remote process, so want to have the sub-activity
-    	// sending the result back in the original process.
+        // We are running in a remote process, so want to have the sub-activity
+        // sending the result back in the original process.
         Intent intent = getIntent();
-    	intent.setClass(this, SubActivityScreen.class);
-    	
+        intent.setClass(this, SubActivityScreen.class);
+        
         super.onCreate(icicle);
         
         boolean kill = intent.getBooleanExtra("kill", false);
@@ -44,16 +44,16 @@
         //        + " kill=" + kill);
         
         if (kill) {
-	        // After finishing initialization, kill the process!  But only if
-	        // this is the first time...
-	        if (icicle == null) {
-		        mHandler.post(new Runnable() {
-		        	public void run() {
-		        		handleBeforeStopping();
-		        		Process.killProcess(Process.myPid());
-		        	}
-		        });
-	        }
+            // After finishing initialization, kill the process!  But only if
+            // this is the first time...
+            if (icicle == null) {
+                mHandler.post(new Runnable() {
+                    public void run() {
+                        handleBeforeStopping();
+                        Process.killProcess(Process.myPid());
+                    }
+                });
+            }
         }
     }
 }
diff --git a/core/tests/coretests/src/android/app/activity/SubActivityScreen.java b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
index 919c591..3caec7a 100644
--- a/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
+++ b/core/tests/coretests/src/android/app/activity/SubActivityScreen.java
@@ -44,24 +44,24 @@
         // Move on to the next thing that will generate a result...  but only
         // if we are being launched for the first time.
         if (icicle == null) {
-	        if (mMode == PENDING_RESULT_MODE) {
-	            PendingIntent apr = createPendingResult(1, null,
-	                    Intent.FILL_IN_ACTION);
-	            Intent res = new Intent();
+            if (mMode == PENDING_RESULT_MODE) {
+                PendingIntent apr = createPendingResult(1, null,
+                        Intent.FILL_IN_ACTION);
+                Intent res = new Intent();
                 res.putExtra("tkey", "tval");
                 res.setAction("test");
-	            try {
-    	            apr.send(this, RESULT_OK, res);
-	            } catch (PendingIntent.CanceledException e) {
-	            }
-	        } else if (mMode < CHILD_OFFSET) {
-	            Intent intent = new Intent();
-	        	intent.setClass(this, SubActivityScreen.class);
-	            intent.putExtra("mode", CHILD_OFFSET+mMode);
-	            //System.out.println("*** Starting from onStart: " + intent);
-	            startActivityForResult(intent, 1);
-	            return;
-	        }
+                try {
+                    apr.send(this, RESULT_OK, res);
+                } catch (PendingIntent.CanceledException e) {
+                }
+            } else if (mMode < CHILD_OFFSET) {
+                Intent intent = new Intent();
+                intent.setClass(this, SubActivityScreen.class);
+                intent.putExtra("mode", CHILD_OFFSET+mMode);
+                //System.out.println("*** Starting from onStart: " + intent);
+                startActivityForResult(intent, 1);
+                return;
+            }
         }
     }
 
@@ -77,15 +77,15 @@
         //Log.i("foo", "SubActivityScreen pid=" + Process.myPid() + " onResume");
         
         if (mMode >= CHILD_OFFSET) {
-        	// Wait a little bit, to give our parent time to kill itself
-        	// if that is something it is into.
-        	try {
-	        	Thread.sleep(500);
-        	} catch (InterruptedException e) {
-        		setResult(RESULT_CANCELED, (new Intent()).setAction("Interrupted!"));
-        		finish();
-        		return;
-        	}
+            // Wait a little bit, to give our parent time to kill itself
+            // if that is something it is into.
+            try {
+                Thread.sleep(500);
+            } catch (InterruptedException e) {
+                setResult(RESULT_CANCELED, (new Intent()).setAction("Interrupted!"));
+                finish();
+                return;
+            }
             //System.out.println("Resuming sub-activity: mode=" + mMode);
             switch (mMode-CHILD_OFFSET) {
             case NO_RESULT_MODE:
diff --git a/core/tests/coretests/src/android/app/backup/BackupDataTest.java b/core/tests/coretests/src/android/app/backup/BackupDataTest.java
new file mode 100644
index 0000000..0c204e0
--- /dev/null
+++ b/core/tests/coretests/src/android/app/backup/BackupDataTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.backup;
+
+import android.app.backup.BackupDataInput;
+import android.app.backup.BackupDataOutput;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
+import android.util.Base64;
+import android.util.Log;
+import org.json.JSONObject;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.Exception;
+import java.nio.ByteBuffer;
+
+public class BackupDataTest extends AndroidTestCase {
+    private static final String KEY1 = "key1";
+    private static final String KEY2 = "key2a";
+    private static final String KEY3 = "key3bc";
+    private static final String KEY4 = "key4dad";  // variable key lengths to test padding
+    private static final String[] KEYS = {KEY1, KEY2, KEY3, KEY4};
+
+    private static final String DATA1 = "abcdef";
+    private static final String DATA2 = "abcdefg";
+    private static final String DATA3 = "abcdefgh";
+    private static final String DATA4 = "abcdeffhi"; //variable data lengths to test padding
+    private static final String[] DATA = {DATA1, DATA2, DATA3, DATA4};
+    private static final String TAG = "BackupDataTest";
+
+    private File mFile;
+    private ParcelFileDescriptor mDataFile;
+    private File mDirectory;
+    private Bundle mStatusBundle;
+    private AssetManager mAssets;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDirectory = new File(Environment.getExternalStorageDirectory(), "test_data");
+        mDirectory.mkdirs();
+        mAssets = mContext.getAssets();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (mDataFile != null) {
+            mDataFile.close();
+        }
+    }
+
+    public void testSingle() throws IOException {
+        mFile = new File(mDirectory, "backup_mixed_sinlge.dat");
+        openForWriting();
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        writeEntity(bdo, KEY1, DATA1.getBytes());
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int count = 0;
+        while (bdi.readNextHeader()) {
+            readAndVerifyEntity(bdi, KEY1, DATA1.getBytes());
+            count++;
+        }
+        assertEquals("only one entity in this stream", 1, count);
+    }
+
+    public void testMultiple() throws IOException {
+        mFile = new File(mDirectory, "backup_multiple_test.dat");
+        openForWriting();
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        for(int i = 0; i < KEYS.length; i++) {
+            writeEntity(bdo, KEYS[i], DATA[i].getBytes());
+        }
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int count = 0;
+        while (bdi.readNextHeader()) {
+            readAndVerifyEntity(bdi, KEYS[count], DATA[count].getBytes());
+            count++;
+        }
+        assertEquals("four entities in this stream", KEYS.length, count);
+    }
+
+    public void testDelete() throws IOException {
+        mFile = new File(mDirectory, "backup_delete_test.dat");
+        openForWriting();
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        for(int i = 0; i < KEYS.length; i++) {
+            deleteEntity(bdo, KEYS[i]);
+        }
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int count = 0;
+        while (bdi.readNextHeader()) {
+            readAndVerifyDeletedEntity(bdi, KEYS[count]);
+            count++;
+        }
+        assertEquals("four deletes in this stream", KEYS.length, count);
+    }
+
+    public void testMixed() throws IOException {
+        mFile = new File(mDirectory, "backup_mixed_test.dat");
+        openForWriting();
+
+        BackupDataOutput bdo = new BackupDataOutput(mDataFile.getFileDescriptor());
+
+        int i = 0;
+        deleteEntity(bdo, KEYS[i]); i++;
+        writeEntity(bdo, KEYS[i], DATA[i].getBytes()); i++;
+        writeEntity(bdo, KEYS[i], DATA[i].getBytes()); i++;
+        deleteEntity(bdo, KEYS[i]); i++;
+
+        mDataFile.close();
+        openForReading();
+
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        int out = 0;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyDeletedEntity(bdi, KEYS[out]); out++;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyEntity(bdi, KEYS[out], DATA[out].getBytes()); out++;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyEntity(bdi, KEYS[out], DATA[out].getBytes()); out++;
+        assertTrue(bdi.readNextHeader());
+        readAndVerifyDeletedEntity(bdi, KEYS[out]); out++;
+        assertFalse("four items in this stream",
+                bdi.readNextHeader());
+    }
+
+    public void testReadMockData() throws IOException {
+        copyAssetToFile("backup_mock.dat", "backup_read_mock_test.dat");
+
+        openForReading();
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        BufferedReader truth = new BufferedReader(new InputStreamReader(
+                mAssets.openFd("backup_mock.gld").createInputStream()));
+        while( bdi.readNextHeader()) {
+            String[] expected = truth.readLine().split(":");
+            byte[] expectedBytes = null;
+            if (expected.length > 1) {
+                expectedBytes = Base64.decode(expected[1], Base64.DEFAULT);
+            }
+            String key = bdi.getKey();
+            int dataSize = bdi.getDataSize();
+
+            assertEquals("wrong key", expected[0], key);
+            assertEquals("wrong length for key " + key,
+                    (expectedBytes == null ? -1: expectedBytes.length), dataSize);
+            if (dataSize != -1) {
+                byte[] buffer = new byte[dataSize];
+                bdi.readEntityData(buffer, 0, dataSize);
+                assertEquals("wrong data for key " + key, expected[1],
+                        Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
+            }
+        }
+        assertNull("there are unused entries in the golden file", truth.readLine());
+    }
+
+    public void testReadRealData() throws IOException {
+        copyAssetToFile("backup_real.dat", "backup_read_real_test.dat");
+
+        openForReading();
+        BackupDataInput bdi = new BackupDataInput(mDataFile.getFileDescriptor());
+        BufferedReader truth = new BufferedReader(new InputStreamReader(
+                mAssets.openFd("backup_real.gld").createInputStream()));
+
+        while(bdi.readNextHeader()) {
+            String[] expected = truth.readLine().split(":");
+            byte[] expectedBytes = null;
+            if (expected.length > 1) {
+                expectedBytes = Base64.decode(expected[1], Base64.DEFAULT);
+            }
+            String key = bdi.getKey();
+            int dataSize = bdi.getDataSize();
+
+            assertEquals("wrong key", expected[0], key);
+            assertEquals("wrong length for key " + key,
+                    (expectedBytes == null ? -1: expectedBytes.length), dataSize);
+            if (dataSize != -1) {
+                byte[] buffer = new byte[dataSize];
+                bdi.readEntityData(buffer, 0, dataSize);
+                assertEquals("wrong data for key " + key, expected[1],
+                        Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
+            }
+        }
+        assertNull("there are unused entries in the golden file", truth.readLine());
+    }
+
+    private void copyAssetToFile(String source, String destination) throws IOException {
+        mFile = new File(mDirectory, destination);
+        openForWriting();
+        FileInputStream fileInputStream = mAssets.openFd(source).createInputStream();
+        FileOutputStream fileOutputStream = new FileOutputStream(mDataFile.getFileDescriptor());
+        byte[] copybuffer = new byte[1024];
+        int numBytes = fileInputStream.read(copybuffer);
+        fileOutputStream.write(copybuffer, 0, numBytes);
+        fileOutputStream.close();
+    }
+
+    private void openForWriting() throws FileNotFoundException {
+        mDataFile = ParcelFileDescriptor.open(mFile,
+                ParcelFileDescriptor.MODE_WRITE_ONLY |
+                        ParcelFileDescriptor.MODE_CREATE |
+                        ParcelFileDescriptor.MODE_TRUNCATE);  // Make an empty file if necessary
+    }
+
+    private void openForReading() throws FileNotFoundException {
+        mDataFile = ParcelFileDescriptor.open(mFile,
+                ParcelFileDescriptor.MODE_READ_ONLY |
+                        ParcelFileDescriptor.MODE_CREATE);  // Make an empty file if necessary
+    }
+
+    private void writeEntity(BackupDataOutput bdo, String key, byte[] data) throws IOException {
+        int status = bdo.writeEntityHeader(key, data.length);
+        // documentation says "number of bytes written" but that's not what we get:
+        assertEquals(0, status);
+
+        status = bdo.writeEntityData(data, data.length);
+        // documentation says "number of bytes written" but that's not what we get:
+        assertEquals(0, status);
+    }
+
+    private void deleteEntity(BackupDataOutput bdo, String key) throws IOException {
+        int status = bdo.writeEntityHeader(key, -1);
+        // documentation says "number of bytes written" but that's not what we get:
+        assertEquals(0, status);
+    }
+
+    private void readAndVerifyEntity(BackupDataInput bdi, String expectedKey, byte[] expectedData)
+            throws IOException {
+        assertEquals("Key mismatch",
+                expectedKey, bdi.getKey());
+        assertEquals("data size mismatch",
+                expectedData.length, bdi.getDataSize());
+        byte[] data = new byte[bdi.getDataSize()];
+        bdi.readEntityData(data, 0, bdi.getDataSize());
+        assertEquals("payload size is wrong",
+                expectedData.length, data.length);
+        for (int i = 0; i < data.length; i++) {
+            assertEquals("payload mismatch",
+                    expectedData[i], data[i]);
+        }
+    }
+    private void readAndVerifyDeletedEntity(BackupDataInput bdi, String expectedKey)
+            throws IOException {
+        assertEquals("Key mismatch",
+                expectedKey, bdi.getKey());
+        assertEquals("deletion mis-reported",
+                -1, bdi.getDataSize());
+    }
+}
diff --git a/core/tests/coretests/src/android/database/DatabaseCursorTest.java b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
index 36f0f4b..08cd027 100644
--- a/core/tests/coretests/src/android/database/DatabaseCursorTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
@@ -51,8 +51,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-	File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
-	mDatabaseFile = new File(dbDir, "database_test.db");
+        File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, "database_test.db");
 
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/core/tests/coretests/src/android/database/DatabaseStatementTest.java b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
index 512d5cd..895d715 100644
--- a/core/tests/coretests/src/android/database/DatabaseStatementTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
@@ -41,8 +41,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-	File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
-	mDatabaseFile = new File(dbDir, "database_test.db");
+        File dbDir = getContext().getDir("tests", Context.MODE_PRIVATE);
+        mDatabaseFile = new File(dbDir, "database_test.db");
 
         if (mDatabaseFile.exists()) {
             mDatabaseFile.delete();
diff --git a/core/tests/coretests/src/android/net/SSLSessionCacheTest.java b/core/tests/coretests/src/android/net/SSLSessionCacheTest.java
new file mode 100644
index 0000000..be19303
--- /dev/null
+++ b/core/tests/coretests/src/android/net/SSLSessionCacheTest.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 android.net;
+
+import com.android.org.conscrypt.ClientSessionContext;
+import com.android.org.conscrypt.SSLClientSessionCache;
+
+import com.google.testing.littlemock.LittleMock;
+
+import junit.framework.TestCase;
+
+import java.security.KeyManagementException;
+import java.security.SecureRandom;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLContextSpi;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSessionContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+public class SSLSessionCacheTest extends TestCase {
+
+    public void testInstall_compatibleContext() throws Exception {
+        final SSLContext ctx = SSLContext.getDefault();
+        final SSLClientSessionCache mock = LittleMock.mock(SSLClientSessionCache.class);
+        final ClientSessionContext clientCtx = (ClientSessionContext) ctx.getClientSessionContext();
+
+        try {
+            SSLSessionCache.install(new SSLSessionCache(mock), ctx);
+            clientCtx.getSession("www.foogle.com", 443);
+            LittleMock.verify(mock).getSessionData(LittleMock.anyString(), LittleMock.anyInt());
+        } finally {
+            // Restore cacheless behaviour.
+            SSLSessionCache.install(null, ctx);
+            clientCtx.getSession("www.foogle.com", 443);
+            LittleMock.verifyNoMoreInteractions(mock);
+        }
+    }
+
+    public void testInstall_incompatibleContext() {
+        try {
+            SSLSessionCache.install(
+                    new SSLSessionCache(LittleMock.mock(SSLClientSessionCache.class)),
+                    new FakeSSLContext());
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    static final class FakeSSLContext extends SSLContext {
+        protected FakeSSLContext() {
+            super(new FakeSSLContextSpi(), null, "test");
+        }
+    }
+
+    static final class FakeSSLContextSpi extends SSLContextSpi {
+        @Override
+        protected void engineInit(KeyManager[] keyManagers, TrustManager[] trustManagers,
+                SecureRandom secureRandom) throws KeyManagementException {
+        }
+
+        @Override
+        protected SSLSocketFactory engineGetSocketFactory() {
+            return null;
+        }
+
+        @Override
+        protected SSLServerSocketFactory engineGetServerSocketFactory() {
+            return null;
+        }
+
+        @Override
+        protected SSLEngine engineCreateSSLEngine(String s, int i) {
+            return null;
+        }
+
+        @Override
+        protected SSLEngine engineCreateSSLEngine() {
+            return null;
+        }
+
+        @Override
+        protected SSLSessionContext engineGetServerSessionContext() {
+            return null;
+        }
+
+        @Override
+        protected SSLSessionContext engineGetClientSessionContext() {
+            return LittleMock.mock(SSLSessionContext.class);
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 0f2b803..93e68eb 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -26,6 +26,8 @@
 
 import com.google.android.collect.Sets;
 
+import libcore.io.IoUtils;
+
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -33,8 +35,6 @@
 import java.util.Arrays;
 import java.util.HashSet;
 
-import libcore.io.IoUtils;
-
 @MediumTest
 public class FileUtilsTest extends AndroidTestCase {
     private static final String TEST_DATA =
@@ -112,6 +112,23 @@
         assertEquals("", FileUtils.readTextFile(mTestFile, -10, "<>"));
     }
 
+    public void testContains() throws Exception {
+        assertTrue(FileUtils.contains(new File("/"), new File("/moo.txt")));
+        assertTrue(FileUtils.contains(new File("/"), new File("/")));
+
+        assertTrue(FileUtils.contains(new File("/sdcard"), new File("/sdcard")));
+        assertTrue(FileUtils.contains(new File("/sdcard/"), new File("/sdcard/")));
+
+        assertTrue(FileUtils.contains(new File("/sdcard"), new File("/sdcard/moo.txt")));
+        assertTrue(FileUtils.contains(new File("/sdcard/"), new File("/sdcard/moo.txt")));
+
+        assertFalse(FileUtils.contains(new File("/sdcard"), new File("/moo.txt")));
+        assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/moo.txt")));
+
+        assertFalse(FileUtils.contains(new File("/sdcard"), new File("/sdcard.txt")));
+        assertFalse(FileUtils.contains(new File("/sdcard/"), new File("/sdcard.txt")));
+    }
+
     public void testDeleteOlderEmptyDir() throws Exception {
         FileUtils.deleteOlderFiles(mDir, 10, WEEK_IN_MILLIS);
         assertDirContents();
@@ -123,7 +140,7 @@
         touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
         touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
         touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
-        FileUtils.deleteOlderFiles(mDir, 3, DAY_IN_MILLIS);
+        assertTrue(FileUtils.deleteOlderFiles(mDir, 3, DAY_IN_MILLIS));
         assertDirContents("file1", "file2", "file3");
     }
 
@@ -131,13 +148,13 @@
         touch("file1", -HOUR_IN_MILLIS);
         touch("file2", HOUR_IN_MILLIS);
         touch("file3", WEEK_IN_MILLIS);
-        FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS);
+        assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
         assertDirContents("file1", "file2");
 
         touch("file1", -HOUR_IN_MILLIS);
         touch("file2", HOUR_IN_MILLIS);
         touch("file3", WEEK_IN_MILLIS);
-        FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS);
+        assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
         assertDirContents("file1", "file2");
     }
 
@@ -147,7 +164,8 @@
         touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
         touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
         touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
-        FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS);
+        assertTrue(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
+        assertFalse(FileUtils.deleteOlderFiles(mDir, 0, DAY_IN_MILLIS));
         assertDirContents("file1");
     }
 
@@ -157,7 +175,8 @@
         touch("file3", 2 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
         touch("file4", 3 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
         touch("file5", 4 * DAY_IN_MILLIS + HOUR_IN_MILLIS);
-        FileUtils.deleteOlderFiles(mDir, 2, 0);
+        assertTrue(FileUtils.deleteOlderFiles(mDir, 2, 0));
+        assertFalse(FileUtils.deleteOlderFiles(mDir, 2, 0));
         assertDirContents("file1", "file2");
     }
 
diff --git a/core/tests/coretests/src/android/text/HtmlTest.java b/core/tests/coretests/src/android/text/HtmlTest.java
deleted file mode 100644
index b2298f7..0000000
--- a/core/tests/coretests/src/android/text/HtmlTest.java
+++ /dev/null
@@ -1,247 +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.text;
-
-import android.content.res.ColorStateList;
-import android.content.res.Resources;
-import android.graphics.Typeface;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.QuoteSpan;
-import android.text.style.StrikethroughSpan;
-import android.text.style.StyleSpan;
-import android.text.style.SubscriptSpan;
-import android.text.style.SuperscriptSpan;
-import android.text.style.TextAppearanceSpan;
-import android.text.style.TypefaceSpan;
-import android.text.style.URLSpan;
-import android.text.style.UnderlineSpan;
-
-import junit.framework.TestCase;
-
-public class HtmlTest extends TestCase {
-
-    @SmallTest
-    public void testSingleTagOnWhileString() {
-        Spanned spanned = Html.fromHtml("<b>hello</b>");
-        Object[] spans = spanned.getSpans(-1, 100, Object.class);
-        assertEquals(1, spans.length);
-        Object span = spans[0];
-        assertEquals(0, spanned.getSpanStart(span));
-        assertEquals(5, spanned.getSpanEnd(span));
-    }
-
-    @SmallTest
-    public void testEmptyFontTag() {
-        Spanned spanned = Html.fromHtml("Hello <font color=\"#ff00ff00\"></font>");
-        Object[] spans = spanned.getSpans(0, 100, Object.class);
-        // TODO: figure out what the spans should be after the crashes are fixed and assert them.
-    }
-
-    /** Tests that the parser can handle mal-formed HTML. */
-    @SmallTest
-    public void testBadHtml() {
-        Spanned spanned = Html.fromHtml("Hello <b>b<i>bi</b>i</i>");
-        Object[] spans = spanned.getSpans(0, 100, Object.class);
-        assertEquals(Typeface.ITALIC, ((StyleSpan) spans[0]).getStyle());
-        assertEquals(7, spanned.getSpanStart(spans[0]));
-        assertEquals(9, spanned.getSpanEnd(spans[0]));
-        assertEquals(Typeface.BOLD, ((StyleSpan) spans[1]).getStyle());
-        assertEquals(6, spanned.getSpanStart(spans[1]));
-        assertEquals(9, spanned.getSpanEnd(spans[1]));
-        assertEquals(Typeface.ITALIC, ((StyleSpan) spans[2]).getStyle());
-        assertEquals(9, spanned.getSpanStart(spans[2]));
-        assertEquals(10, spanned.getSpanEnd(spans[2]));
-    }
-
-    @SmallTest
-    public void testSymbols() {
-        String spanned = Html.fromHtml("&copy; &gt; &lt").toString();
-        assertEquals("\u00a9 > <", spanned);
-    }
-    
-    @SmallTest
-    public void testColor() throws Exception {
-        Spanned s;
-        ForegroundColorSpan[] colors;
-
-        s = Html.fromHtml("<font color=\"#00FF00\">something</font>");
-        colors = s.getSpans(0, s.length(), ForegroundColorSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(0xFF00FF00, colors[0].getForegroundColor());
-
-        s = Html.fromHtml("<font color=\"navy\">something</font>");
-        colors = s.getSpans(0, s.length(), ForegroundColorSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(0xFF000080, colors[0].getForegroundColor());
-
-        s = Html.fromHtml("<font color=\"gibberish\">something</font>");
-        colors = s.getSpans(0, s.length(), ForegroundColorSpan.class);
-        assertEquals(0, colors.length);
-    }
-
-    @SmallTest
-    public void testResourceColor() throws Exception {
-        ColorStateList c =
-                Resources.getSystem().getColorStateList(android.R.color.primary_text_dark);
-        Spanned s;
-        TextAppearanceSpan[] colors;
-
-        s = Html.fromHtml("<font color=\"@android:color/primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@android:primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@color/primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@primary_text_dark\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"@" + android.R.color.primary_text_dark
-                + "\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(1, colors.length);
-        assertEquals(c.toString(), colors[0].getTextColor().toString());
-
-        s = Html.fromHtml("<font color=\"gibberish\">something</font>");
-        colors = s.getSpans(0, s.length(), TextAppearanceSpan.class);
-        assertEquals(colors.length, 0);
-    }
-
-    @SmallTest
-    public void testParagraphs() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello world");
-        assertEquals(Html.toHtml(s), "<p>Hello world</p>\n");
-
-        s = new SpannableString("Hello world\nor something");
-        assertEquals(Html.toHtml(s), "<p>Hello world<br>\nor something</p>\n");
-
-        s = new SpannableString("Hello world\n\nor something");
-        assertEquals(Html.toHtml(s), "<p>Hello world</p>\n<p>or something</p>\n");
-
-        s = new SpannableString("Hello world\n\n\nor something");
-        assertEquals(Html.toHtml(s), "<p>Hello world<br></p>\n<p>or something</p>\n");
-
-        assertEquals("foo\nbar", Html.fromHtml("foo<br>bar").toString());
-        assertEquals("foo\nbar", Html.fromHtml("foo<br>\nbar").toString());
-        assertEquals("foo\nbar", Html.fromHtml("foo<br>\n \nbar").toString());
-    }
-
-    @SmallTest
-    public void testBlockquote() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello world");
-        s.setSpan(new QuoteSpan(), 0, s.length(), Spannable.SPAN_PARAGRAPH);
-        assertEquals(Html.toHtml(s), "<blockquote><p>Hello world</p>\n</blockquote>\n");
-
-        s = new SpannableString("Hello\n\nworld");
-        s.setSpan(new QuoteSpan(), 0, 7, Spannable.SPAN_PARAGRAPH);
-        assertEquals(Html.toHtml(s), "<blockquote><p>Hello</p>\n</blockquote>\n<p>world</p>\n");
-    }
-
-    @SmallTest
-    public void testEntities() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello <&> world");
-        assertEquals(Html.toHtml(s), "<p>Hello &lt;&amp;&gt; world</p>\n");
-
-        s = new SpannableString("Hello \u03D5 world");
-        assertEquals(Html.toHtml(s), "<p>Hello &#981; world</p>\n");
-
-        s = new SpannableString("Hello  world");
-        assertEquals(Html.toHtml(s), "<p>Hello&nbsp; world</p>\n");
-    }
-
-    @SmallTest
-    public void testMarkup() throws Exception {
-        SpannableString s;
-
-        s = new SpannableString("Hello bold world");
-        s.setSpan(new StyleSpan(Typeface.BOLD), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <b>bold</b> world</p>\n");
-
-        s = new SpannableString("Hello italic world");
-        s.setSpan(new StyleSpan(Typeface.ITALIC), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <i>italic</i> world</p>\n");
-
-        s = new SpannableString("Hello monospace world");
-        s.setSpan(new TypefaceSpan("monospace"), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <tt>monospace</tt> world</p>\n");
-
-        s = new SpannableString("Hello superscript world");
-        s.setSpan(new SuperscriptSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <sup>superscript</sup> world</p>\n");
-
-        s = new SpannableString("Hello subscript world");
-        s.setSpan(new SubscriptSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <sub>subscript</sub> world</p>\n");
-
-        s = new SpannableString("Hello underline world");
-        s.setSpan(new UnderlineSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <u>underline</u> world</p>\n");
-
-        s = new SpannableString("Hello struck world");
-        s.setSpan(new StrikethroughSpan(), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s), "<p>Hello <strike>struck</strike> world</p>\n");
-
-        s = new SpannableString("Hello linky world");
-        s.setSpan(new URLSpan("http://www.google.com"), 6, s.length() - 6,
-                  Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        assertEquals(Html.toHtml(s),
-                     "<p>Hello <a href=\"http://www.google.com\">linky</a> world</p>\n");
-    }
-
-    @SmallTest
-    public void testImg() throws Exception {
-        Spanned s;
-
-        s = Html.fromHtml("yes<img src=\"http://example.com/foo.gif\">no");
-
-        assertEquals("<p>yes<img src=\"http://example.com/foo.gif\">no</p>\n",
-                     Html.toHtml(s));
-    }
-
-    @SmallTest
-    public void testUtf8() throws Exception {
-        Spanned s;
-
-        s = Html.fromHtml("<p>\u0124\u00eb\u0142\u0142o, world!</p>");
-        assertEquals("<p>&#292;&#235;&#322;&#322;o, world!</p>\n", Html.toHtml(s));
-    }
-
-}
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
index f493e9a..fc2897f 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
@@ -27,14 +27,14 @@
 import android.net.NetworkInfo;
 import android.net.wifi.WifiManager;
 import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
-import java.io.File;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.TimeoutException;
@@ -47,7 +47,6 @@
     protected DownloadManager mDownloadManager = null;
     protected String mFileType = "text/plain";
     protected Context mContext = null;
-    protected MultipleDownloadsCompletedReceiver mReceiver = null;
     protected static final int DEFAULT_FILE_SIZE = 10 * 1024;  // 10kb
     protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024;
 
@@ -65,70 +64,9 @@
     protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
     protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes
 
-    public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
-        private volatile int mNumDownloadsCompleted = 0;
-        private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());
+    private DownloadFinishedListener mListener;
+    private Thread mListenerThread;
 
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equalsIgnoreCase(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
-                synchronized(this) {
-                    long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
-                    Log.i(LOG_TAG, "Received Notification for download: " + id);
-                    if (!downloadIds.contains(id)) {
-                        ++mNumDownloadsCompleted;
-                        Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
-                                intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
-                        downloadIds.add(id);
-
-                        DownloadManager dm = (DownloadManager)context.getSystemService(
-                                Context.DOWNLOAD_SERVICE);
-
-                        Cursor cursor = dm.query(new Query().setFilterById(id));
-                        try {
-                            if (cursor.moveToFirst()) {
-                                int status = cursor.getInt(cursor.getColumnIndex(
-                                        DownloadManager.COLUMN_STATUS));
-                                Log.i(LOG_TAG, "Download status is: " + status);
-                            } else {
-                                fail("No status found for completed download!");
-                            }
-                        } finally {
-                            cursor.close();
-                        }
-                    } else {
-                        Log.i(LOG_TAG, "Notification for id: " + id + " has already been made.");
-                    }
-                }
-            }
-        }
-
-        /**
-         * Gets the number of times the {@link #onReceive} callback has been called for the
-         * {@link DownloadManager#ACTION_DOWNLOAD_COMPLETE} action, indicating the number of
-         * downloads completed thus far.
-         *
-         * @return the number of downloads completed so far.
-         */
-        public int numDownloadsCompleted() {
-            return mNumDownloadsCompleted;
-        }
-
-        /**
-         * Gets the list of download IDs.
-         * @return A Set<Long> with the ids of the completed downloads.
-         */
-        public Set<Long> getDownloadIds() {
-            synchronized(this) {
-                Set<Long> returnIds = new HashSet<Long>(downloadIds);
-                return returnIds;
-            }
-        }
-
-    }
 
     public static class WiFiChangedReceiver extends BroadcastReceiver {
         private Context mContext = null;
@@ -172,13 +110,138 @@
     }
 
     /**
+     * Broadcast receiver to listen for broadcast from DownloadManager indicating that downloads
+     * are finished.
+     */
+    private class DownloadFinishedListener extends BroadcastReceiver implements Runnable {
+        private Handler mHandler = null;
+        private Looper mLooper;
+        private Set<Long> mFinishedDownloads = new HashSet<Long>();
+
+        /**
+         * Event loop for the thread that listens to broadcasts.
+         */
+        @Override
+        public void run() {
+            Looper.prepare();
+            synchronized (this) {
+                mLooper = Looper.myLooper();
+                mHandler = new Handler();
+                notifyAll();
+            }
+            Looper.loop();
+        }
+
+        /**
+         * Handles the incoming notifications from DownloadManager.
+         */
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
+                long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
+                Log.i(LOG_TAG, "Received Notification for download: " + id);
+                synchronized (this) {
+                    if(!mFinishedDownloads.contains(id)) {
+                        mFinishedDownloads.add(id);
+                        notifyAll();
+                    } else {
+                        Log.i(LOG_TAG,
+                              String.format("Notification for %d was already received", id));
+                    }
+                }
+            }
+        }
+
+        /**
+         * Returns the handler for this thread. Need this to make sure that the events are handled
+         * in it is own thread and don't interfere with the instrumentation thread.
+         * @return Handler for the receiver thread.
+         * @throws InterruptedException
+         */
+        private Handler getHandler() throws InterruptedException {
+            synchronized (this) {
+                if (mHandler != null) return mHandler;
+                while (mHandler == null) {
+                    wait();
+                }
+                return mHandler;
+            }
+        }
+
+        /**
+         * Stops the thread that receives notification from DownloadManager.
+         */
+        public void cancel() {
+            synchronized(this) {
+                if (mLooper != null) {
+                    mLooper.quit();
+                }
+            }
+        }
+
+        /**
+         * Waits for a given download to finish, or until the timeout expires.
+         * @param id id of the download to wait for.
+         * @param timeout maximum time to wait, in milliseconds
+         * @return true if the download finished, false otherwise.
+         * @throws InterruptedException
+         */
+        public boolean waitForDownloadToFinish(long id, long timeout) throws InterruptedException {
+            long startTime = SystemClock.uptimeMillis();
+            synchronized (this) {
+                while (!mFinishedDownloads.contains(id)) {
+                    if (SystemClock.uptimeMillis() - startTime > timeout) {
+                        Log.i(LOG_TAG, String.format("Timeout while waiting for %d to finish", id));
+                        return false;
+                    } else {
+                        wait(timeout);
+                    }
+                }
+                return true;
+            }
+        }
+
+        /**
+         * Waits for multiple downloads to finish, or until timeout expires.
+         * @param ids ids of the downloads to wait for.
+         * @param timeout maximum time to wait, in milliseconds
+         * @return true of all the downloads finished, false otherwise.
+         * @throws InterruptedException
+         */
+        public boolean waitForMultipleDownloadsToFinish(Set<Long> ids, long timeout)
+                throws InterruptedException {
+            long startTime = SystemClock.uptimeMillis();
+            synchronized (this) {
+                while (!mFinishedDownloads.containsAll(ids)) {
+                    if (SystemClock.uptimeMillis() - startTime > timeout) {
+                        Log.i(LOG_TAG, "Timeout waiting for multiple downloads to finish");
+                        return false;
+                    } else {
+                        wait(timeout);
+                    }
+                }
+                return true;
+            }
+        }
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
     public void setUp() throws Exception {
+        super.setUp();
         mContext = getInstrumentation().getContext();
         mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
-        mReceiver = registerNewMultipleDownloadsReceiver();
+        mListener = registerDownloadsListener();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mContext.unregisterReceiver(mListener);
+        mListener.cancel();
+        mListenerThread.join();
+        super.tearDown();
     }
 
     /**
@@ -198,12 +261,15 @@
      * that have completed.
      *
      * @return A new receiver that records and can be queried on how many downloads have completed.
+     * @throws InterruptedException
      */
-    protected MultipleDownloadsCompletedReceiver registerNewMultipleDownloadsReceiver() {
-        MultipleDownloadsCompletedReceiver receiver = new MultipleDownloadsCompletedReceiver();
-        mContext.registerReceiver(receiver, new IntentFilter(
-                DownloadManager.ACTION_DOWNLOAD_COMPLETE));
-        return receiver;
+    protected DownloadFinishedListener registerDownloadsListener() throws InterruptedException {
+        DownloadFinishedListener listener = new DownloadFinishedListener();
+        mListenerThread = new Thread(listener);
+        mListenerThread.start();
+        mContext.registerReceiver(listener, new IntentFilter(
+                DownloadManager.ACTION_DOWNLOAD_COMPLETE), null, listener.getHandler());
+        return listener;
     }
 
     /**
@@ -283,76 +349,35 @@
     }
 
     /**
-     * Helper to wait for a particular download to finish, or else a timeout to occur
-     *
-     * Does not wait for a receiver notification of the download.
-     *
-     * @param id The download id to query on (wait for)
-     */
-    protected void waitForDownloadOrTimeout_skipNotification(long id) throws TimeoutException,
-            InterruptedException {
-        doWaitForDownloadsOrTimeout(new Query().setFilterById(id),
-                WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
-    }
-
-    /**
-     * Helper to wait for a particular download to finish, or else a timeout to occur
-     *
-     * Also guarantees a notification has been posted for the download.
-     *
-     * @param id The download id to query on (wait for)
-     */
-    protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
-            InterruptedException {
-        waitForDownloadOrTimeout(id, WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
-    }
-
-    /**
-     * Helper to wait for a particular download to finish, or else a timeout to occur
-     *
-     * Also guarantees a notification has been posted for the download.
+     * Helper to wait for a particular download to finish, or else a timeout to occur.
      *
      * @param id The download id to query on (wait for)
      * @param poll The amount of time to wait
      * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
      */
-    protected void waitForDownloadOrTimeout(long id, long poll, long timeoutMillis)
-            throws TimeoutException, InterruptedException {
-        doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
-        waitForReceiverNotifications(1);
+    protected boolean waitForDownload(long id, long timeoutMillis)
+            throws InterruptedException {
+        return mListener.waitForDownloadToFinish(id, timeoutMillis);
+    }
+
+    protected boolean waitForMultipleDownloads(Set<Long> ids, long timeout)
+            throws InterruptedException {
+        return mListener.waitForMultipleDownloadsToFinish(ids, timeout);
     }
 
     /**
-     * Helper to wait for all downloads to finish, or else a specified timeout to occur
-     *
-     * Makes no guaranee that notifications have been posted for all downloads.
-     *
-     * @param poll The amount of time to wait
-     * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
+     * Checks with the download manager if the give download is finished.
+     * @param id id of the download to check
+     * @return true if download is finished, false otherwise.
      */
-    protected void waitForDownloadsOrTimeout(long poll, long timeoutMillis) throws TimeoutException,
-            InterruptedException {
-        doWaitForDownloadsOrTimeout(new Query(), poll, timeoutMillis);
-    }
-
-    /**
-     * Helper to wait for all downloads to finish, or else a timeout to occur, but does not throw
-     *
-     * Also guarantees a notification has been posted for the download.
-     *
-     * @param id The id of the download to query against
-     * @param poll The amount of time to wait
-     * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
-     * @return true if download completed successfully (didn't timeout), false otherwise
-     */
-    private boolean waitForDownloadOrTimeoutNoThrow(long id, long poll, long timeoutMillis) {
-        try {
-            doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
-            waitForReceiverNotifications(1);
-        } catch (TimeoutException e) {
-            return false;
-        }
-        return true;
+    private boolean hasDownloadFinished(long id) {
+        Query q = new Query();
+        q.setFilterById(id);
+        q.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL);
+        Cursor cursor = mDownloadManager.query(q);
+        boolean finished = cursor.getCount() == 1;
+        cursor.close();
+        return finished;
     }
 
     /**
@@ -389,34 +414,6 @@
     }
 
     /**
-     * Helper to wait for all downloads to finish, or else a timeout to occur
-     *
-     * @param query The query to pass to the download manager
-     * @param poll The poll time to wait between checks
-     * @param timeoutMillis The max amount of time (in ms) to wait for the download(s) to complete
-     */
-    private void doWaitForDownloadsOrTimeout(Query query, long poll, long timeoutMillis)
-            throws TimeoutException {
-        int currentWaitTime = 0;
-        while (true) {
-            query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_PAUSED
-                    | DownloadManager.STATUS_RUNNING);
-            Cursor cursor = mDownloadManager.query(query);
-
-            try {
-                if (cursor.getCount() == 0) {
-                    Log.i(LOG_TAG, "All downloads should be done...");
-                    break;
-                }
-                currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
-                        "Timed out waiting for all downloads to finish");
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-
-    /**
      * Synchronously waits for external store to be mounted (eg: SD Card).
      *
      * @throws InterruptedException if interrupted
@@ -465,53 +462,50 @@
     }
 
     /**
-     * Synchronously waits for our receiver to receive notification for a given number of
-     * downloads.
+     * Synchronously waits for the download manager to start incrementing the number of
+     * bytes downloaded so far.
      *
-     * @param targetNumber The number of notifications for unique downloads to wait for; pass in
-     *         -1 to not wait for notification.
-     * @throws Exception if timed out while waiting
-     */
-    private void waitForReceiverNotifications(int targetNumber) throws TimeoutException {
-        int count = mReceiver.numDownloadsCompleted();
-        int currentWaitTime = 0;
-
-        while (count < targetNumber) {
-            Log.i(LOG_TAG, "Waiting for notification of downloads...");
-            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
-                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download notifications!"
-                    + " Received " + count + "notifications.");
-            count = mReceiver.numDownloadsCompleted();
-        }
-    }
-
-    /**
-     * Synchronously waits for a file to increase in size (such as to monitor that a download is
-     * progressing).
-     *
-     * @param file The file whose size to track.
+     * @param id DownloadManager download id that needs to be checked.
      * @throws Exception if timed out while waiting for the file to grow in size.
      */
-    protected void waitForFileToGrow(File file) throws Exception {
+    protected void waitToReceiveData(long id) throws Exception {
         int currentWaitTime = 0;
-
-        // File may not even exist yet, so wait until it does (or we timeout)
-        while (!file.exists()) {
-            Log.i(LOG_TAG, "Waiting for file to exist...");
-            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
-                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be created.");
-        }
-
-        // Get original file size...
-        long originalSize = file.length();
-
-        while (file.length() <= originalSize) {
-            Log.i(LOG_TAG, "Waiting for file to be written to...");
+        long originalSize = getBytesDownloaded(id);
+        long currentSize = 0;
+        while ((currentSize = getBytesDownloaded(id)) <= originalSize) {
+            Log.i(LOG_TAG, String.format("orig: %d, cur: %d. Waiting for file to be written to...",
+                    originalSize, currentSize));
             currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
                     MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be written to.");
         }
     }
 
+    private long getBytesDownloaded(long id) {
+        DownloadManager.Query q = new DownloadManager.Query();
+        q.setFilterById(id);
+        Cursor response = mDownloadManager.query(q);
+        if (response.getCount() < 1) {
+            Log.i(LOG_TAG, String.format("Query to download manager returned nothing for id %d",id));
+            response.close();
+            return -1;
+        }
+        while(response.moveToNext()) {
+            int index = response.getColumnIndex(DownloadManager.COLUMN_ID);
+            if (id == response.getLong(index)) {
+                break;
+            }
+        }
+        int index = response.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
+        if (index < 0) {
+            Log.i(LOG_TAG, String.format("No downloaded bytes for id %d", id));
+            response.close();
+            return -1;
+        }
+        long size = response.getLong(index);
+        response.close();
+        return size;
+    }
+
     /**
      * Helper to remove all downloads that are registered with the DL Manager.
      *
@@ -536,19 +530,6 @@
     }
 
     /**
-     * Helper to verify an int value in a Cursor
-     *
-     * @param cursor The cursor containing the query results
-     * @param columnName The name of the column to query
-     * @param expected The expected int value
-     */
-    private void verifyInt(Cursor cursor, String columnName, int expected) {
-        int index = cursor.getColumnIndex(columnName);
-        int actual = cursor.getInt(index);
-        assertEquals(expected, actual);
-    }
-
-    /**
      * Performs a query based on ID and returns a Cursor for the query.
      *
      * @param id The id of the download in DL Manager; pass -1 to query all downloads
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
index 0518e64..ef48a18 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
@@ -38,14 +38,8 @@
     protected static String LOG_TAG =
             "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
 
-    protected static String DOWNLOAD_500K_FILENAME = "External541kb.apk";
-    protected static long DOWNLOAD_500K_FILESIZE = 570927;
-    protected static String DOWNLOAD_1MB_FILENAME = "External1mb.apk";
-    protected static long DOWNLOAD_1MB_FILESIZE = 1041262;
-    protected static String DOWNLOAD_5MB_FILENAME = "External5mb.apk";
-    protected static long DOWNLOAD_5MB_FILESIZE = 5138700;
-    protected static String DOWNLOAD_10MB_FILENAME = "External10mb.apk";
-    protected static long DOWNLOAD_10MB_FILESIZE = 10258741;
+    protected static final String DOWNLOAD_FILENAME = "External93mb.apk";
+    protected static final long DOWNLOAD_FILESIZE = 95251708;
 
     private static final String FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX = "file";
     private static final String FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION = ".bin";
@@ -126,7 +120,7 @@
      * @throws Exception if unsuccessful
      */
     public void initiateDownload() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
+        String filename = DOWNLOAD_FILENAME;
         mContext.deleteFile(DOWNLOAD_STARTED_FLAG);
         FileOutputStream fileOutput = mContext.openFileOutput(DOWNLOAD_STARTED_FLAG, 0);
         DataOutputStream outputFile = null;
@@ -162,8 +156,8 @@
      * @throws Exception if unsuccessful
      */
     public void verifyFileDownloadSucceeded() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         long dlRequest = -1;
         boolean rebootMarkerValid = false;
         DataInputStream dataInputFile = null;
@@ -196,9 +190,7 @@
             int status = cursor.getInt(columnIndex);
             int currentWaitTime = 0;
 
-            // Wait until the download finishes; don't wait for a notification b/c
-            // the download may well have been completed before the last reboot.
-            waitForDownloadOrTimeout_skipNotification(dlRequest);
+            assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
 
             Log.i(LOG_TAG, "Verifying download information...");
             // Verify specific info about the file (size, name, etc)...
@@ -223,8 +215,8 @@
      * @throws Exception if unsuccessful
      */
     public void runLargeDownloadOverWiFi() throws Exception {
-        String filename = DOWNLOAD_10MB_FILENAME;
-        long filesize = DOWNLOAD_10MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         long dlRequest = -1;
         doCommonDownloadSetup();
 
@@ -238,7 +230,7 @@
         dlRequest = mDownloadManager.enqueue(request);
 
         // Rather large file, so wait up to 15 mins...
-        waitForDownloadOrTimeout(dlRequest, WAIT_FOR_DOWNLOAD_POLL_TIME, 15 * 60 * 1000);
+        assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
 
         Cursor cursor = getCursor(dlRequest);
         ParcelFileDescriptor pfd = null;
@@ -265,8 +257,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleSwitching() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         doCommonDownloadSetup();
 
         String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
@@ -292,7 +284,7 @@
             dlRequest = mDownloadManager.enqueue(request);
             waitForDownloadToStart(dlRequest);
             // make sure we're starting to download some data...
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             setWiFiStateOn(false);
@@ -320,7 +312,7 @@
             Log.i(LOG_TAG, "Turning on WiFi...");
             setWiFiStateOn(true);
             Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
-            waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+            assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000));
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -340,8 +332,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleWiFiEnableDisable() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         doCommonDownloadSetup();
 
         String localDownloadDirectory = Environment.getExternalStorageDirectory().getPath();
@@ -366,7 +358,7 @@
             dlRequest = mDownloadManager.enqueue(request);
             waitForDownloadToStart(dlRequest);
             // are we making any progress?
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             Log.i(LOG_TAG, "Turning off WiFi...");
@@ -376,7 +368,7 @@
             // enable download...
             Log.i(LOG_TAG, "Turning on WiFi again...");
             setWiFiStateOn(true);
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             Log.i(LOG_TAG, "Turning off WiFi...");
@@ -388,7 +380,7 @@
             setWiFiStateOn(true);
 
             Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
-            waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+            assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000));
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -409,8 +401,8 @@
      * @throws Exception if unsuccessful
      */
     public void runDownloadMultipleAirplaneModeEnableDisable() throws Exception {
-        String filename = DOWNLOAD_5MB_FILENAME;
-        long filesize = DOWNLOAD_5MB_FILESIZE;
+        String filename = DOWNLOAD_FILENAME;
+        long filesize = DOWNLOAD_FILESIZE;
         // make sure WiFi is enabled, and airplane mode is not on
         doCommonDownloadSetup();
 
@@ -436,7 +428,7 @@
             dlRequest = mDownloadManager.enqueue(request);
             waitForDownloadToStart(dlRequest);
             // are we making any progress?
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             Log.i(LOG_TAG, "Turning on Airplane mode...");
@@ -447,7 +439,7 @@
             Log.i(LOG_TAG, "Turning off Airplane mode...");
             setAirplaneModeOn(false);
             // make sure we're starting to download some data...
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // reenable the connection to start up the download again
             Log.i(LOG_TAG, "Turning on Airplane mode again...");
@@ -459,7 +451,7 @@
             setAirplaneModeOn(false);
 
             Log.i(LOG_TAG, "Waiting up to 3 minutes for donwload to complete...");
-            waitForDownloadsOrTimeout(dlRequest, 180 * 1000);  // wait up to 3 mins before timeout
+            assertTrue(waitForDownload(dlRequest, 180 * 1000));  // wait up to 3 mins before timeout
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -479,7 +471,6 @@
     public void runDownloadMultipleSimultaneously() throws Exception {
         final int TOTAL_DOWNLOADS = 15;
         HashSet<Long> downloadIds = new HashSet<Long>(TOTAL_DOWNLOADS);
-        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
 
         // Make sure there are no pending downloads currently going on
         removeAllCurrentDownloads();
@@ -497,8 +488,7 @@
                 downloadIds.add(dlRequest);
             }
 
-            waitForDownloadsOrTimeout(DEFAULT_WAIT_POLL_TIME, 15 * 60 * 2000);  // wait 15 mins max
-            assertEquals(TOTAL_DOWNLOADS, receiver.numDownloadsCompleted());
+            assertTrue(waitForMultipleDownloads(downloadIds, 15 * 60 * 2000));  // wait 15 mins max
         } finally {
             removeAllCurrentDownloads();
         }
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
new file mode 100644
index 0000000..9f04228
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v1
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
new file mode 100644
index 0000000..c7b066d
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.framework.multidexlegacyversionedtestapp"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="9"
+        android:targetSdkVersion="18" />
+
+    <application
+        android:name="android.support.multidex.MultiDexApplication"
+        android:allowBackup="true"
+        android:label="MultiDexLegacyVersionedTestApp_v1">
+        <activity
+            android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+            android:label="MultiDexLegacyVersionedTestApp_v1" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+                     android:label="Test for MultiDexLegacyVersionedTestApp_v1" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+    public static int getVersion() {
+        return Version.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+
+    public int getVersion() {
+        return ClassForMainDex.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..24b4d69
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+    public MultiDexUpdateTest() {
+        super(MainActivity.class);
+    }
+
+    /**
+     * Tests that all classes of the application can be loaded. Verifies also that we load the
+     * correct version of {@link Version} ie the class is the secondary dex file.
+     */
+    public void testAllClassAvailable()
+    {
+        assertEquals(1, getActivity().getVersion());
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
new file mode 100644
index 0000000..eb9827a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v1/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/* can go in secondary dex */
+public class Version {
+
+    public static int getVersion() {
+        return 1;
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
new file mode 100644
index 0000000..1b8da41
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v2
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
new file mode 100644
index 0000000..4d24793
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.framework.multidexlegacyversionedtestapp"
+    android:versionCode="2"
+    android:versionName="2.0" >
+
+    <uses-sdk
+        android:minSdkVersion="9"
+        android:targetSdkVersion="18" />
+
+    <application
+        android:name="android.support.multidex.MultiDexApplication"
+        android:allowBackup="true"
+        android:label="MultiDexLegacyVersionedTestApp_v2">
+        <activity
+            android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+            android:label="MultiDexLegacyVersionedTestApp_v2" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+                     android:label="Test for MultiDexLegacyVersionedTestApp_v2" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+    public static int getVersion() {
+        return Version.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+
+    public int getVersion() {
+        return ClassForMainDex.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..f130cb2
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+    public MultiDexUpdateTest() {
+        super(MainActivity.class);
+    }
+
+    /**
+     * Tests that all classes of the application can be loaded. Verifies also that we load the
+     * correct version of {@link Version} ie the class is the secondary dex file.
+     */
+    public void testAllClassAvailable()
+    {
+        assertEquals(2, getActivity().getVersion());
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
new file mode 100644
index 0000000..1f2305f
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v2/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/* can go in secondary dex */
+public class Version {
+
+    public static int getVersion() {
+        return 2;
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
new file mode 100644
index 0000000..945bfcca
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2014 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := 9
+
+LOCAL_PACKAGE_NAME := MultiDexLegacyVersionedTestApp_v3
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-multidex
+
+mainDexList:= \
+	$(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME),$(LOCAL_IS_HOST_MODULE),common)/maindex.list
+
+LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(mainDexList) --minimal-main-dex
+
+include $(BUILD_PACKAGE)
+
+$(mainDexList): $(full_classes_proguard_jar) | $(HOST_OUT_EXECUTABLES)/mainDexClasses
+	$(HOST_OUT_EXECUTABLES)/mainDexClasses $< 1>$@
+	echo "com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.class" >> $@
+
+$(built_dex_intermediate): $(mainDexList)
+
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
new file mode 100644
index 0000000..76c92dd
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.framework.multidexlegacyversionedtestapp"
+    android:versionCode="3"
+    android:versionName="3.0" >
+
+    <uses-sdk
+        android:minSdkVersion="9"
+        android:targetSdkVersion="18" />
+
+    <application
+        android:name="android.support.multidex.MultiDexApplication"
+        android:allowBackup="true"
+        android:label="MultiDexLegacyVersionedTestApp_v3">
+        <activity
+            android:name="com.android.framework.multidexlegacyversionedtestapp.MainActivity"
+            android:label="MultiDexLegacyVersionedTestApp_v3" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.test.InstrumentationTestRunner"
+                     android:targetPackage="com.android.framework.multidexlegacyversionedtestapp"
+                     android:label="Test for MultiDexLegacyVersionedTestApp_v3" />
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml
new file mode 100644
index 0000000..58ae67a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/res/layout/activity_main.xml
@@ -0,0 +1,7 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+</RelativeLayout>
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
new file mode 100644
index 0000000..8662562
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/ClassForMainDex.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/**
+ * Class directly referenced from Activity, will be kept in main dex. The class is not referenced
+ * by <clinit> or <init>, its direct references are not kept in main dex.
+ */
+public class ClassForMainDex {
+
+    public static int getVersion() {
+        return Version.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
new file mode 100644
index 0000000..351d860
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MainActivity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+    }
+
+    public int getVersion() {
+        return ClassForMainDex.getVersion();
+    }
+
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
new file mode 100644
index 0000000..67aa478
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/MultiDexUpdateTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.framework.multidexlegacyversionedtestapp;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+/**
+ * Run the tests with: <code>adb shell am instrument -w
+ com.android.framework.multidexlegacyversionedtestapp/android.test.InstrumentationTestRunner
+</code>
+ */
+public class MultiDexUpdateTest extends ActivityInstrumentationTestCase2<MainActivity>
+{
+    public MultiDexUpdateTest() {
+        super(MainActivity.class);
+    }
+
+    /**
+     * Tests that all classes of the application can be loaded. Verifies also that we load the
+     * correct version of {@link Version} ie the class is the secondary dex file.
+     */
+    public void testAllClassAvailable()
+    {
+        assertEquals(3, getActivity().getVersion());
+    }
+}
diff --git a/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
new file mode 100644
index 0000000..1c8ef3b
--- /dev/null
+++ b/core/tests/hosttests/test-apps/MultiDexLegacyVersionedTestApp_v3/src/com/android/framework/multidexlegacyversionedtestapp/Version.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.framework.multidexlegacyversionedtestapp;
+
+/* can go in secondary dex */
+public class Version {
+
+    public static int getVersion() {
+        return 3;
+    }
+}
diff --git a/core/tests/inputmethodtests/run_core_inputmethod_test.sh b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
index 5e123ec..b0b119b 100755
--- a/core/tests/inputmethodtests/run_core_inputmethod_test.sh
+++ b/core/tests/inputmethodtests/run_core_inputmethod_test.sh
@@ -21,4 +21,4 @@
   $COMMAND
 fi
 
-adb shell am instrument -w -e class android.os.InputMethodTest com.android.frameworks.coretests.inputmethod/android.test.InstrumentationTestRunner
+adb shell am instrument -w -e class android.os.InputMethodTest,android.os.InputMethodSubtypeArrayTest com.android.frameworks.coretests.inputmethod/android.test.InstrumentationTestRunner
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java
new file mode 100644
index 0000000..1e0a919
--- /dev/null
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeArrayTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.inputmethod.InputMethodSubtype;
+import android.view.inputmethod.InputMethodSubtypeArray;
+import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+
+import java.util.ArrayList;
+
+public class InputMethodSubtypeArrayTest extends InstrumentationTestCase {
+    @SmallTest
+    public void testInstanciate() throws Exception {
+        final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+        subtypes.add(createDummySubtype(0, "en_US"));
+        subtypes.add(createDummySubtype(1, "en_US"));
+        subtypes.add(createDummySubtype(2, "ja_JP"));
+
+        final InputMethodSubtypeArray array = new InputMethodSubtypeArray(subtypes);
+        assertEquals(subtypes.size(), array.getCount());
+        assertEquals(subtypes.get(0), array.get(0));
+        assertEquals(subtypes.get(1), array.get(1));
+        assertEquals(subtypes.get(2), array.get(2));
+
+        final InputMethodSubtypeArray clonedArray = cloneViaParcel(array);
+        assertEquals(subtypes.size(), clonedArray.getCount());
+        assertEquals(subtypes.get(0), clonedArray.get(0));
+        assertEquals(subtypes.get(1), clonedArray.get(1));
+        assertEquals(subtypes.get(2), clonedArray.get(2));
+
+        final InputMethodSubtypeArray clonedClonedArray = cloneViaParcel(clonedArray);
+        assertEquals(clonedArray.getCount(), clonedClonedArray.getCount());
+        assertEquals(clonedArray.get(0), clonedClonedArray.get(0));
+        assertEquals(clonedArray.get(1), clonedClonedArray.get(1));
+        assertEquals(clonedArray.get(2), clonedClonedArray.get(2));
+    }
+
+    InputMethodSubtypeArray cloneViaParcel(final InputMethodSubtypeArray original) {
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            original.writeToParcel(parcel);
+            parcel.setDataPosition(0);
+            return new InputMethodSubtypeArray(parcel);
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+    }
+
+    private static InputMethodSubtype createDummySubtype(final int id, final String locale) {
+        final InputMethodSubtypeBuilder builder = new InputMethodSubtypeBuilder();
+        return builder.setSubtypeNameResId(0)
+                .setSubtypeIconResId(0)
+                .setSubtypeId(id)
+                .setSubtypeLocale(locale)
+                .setIsAsciiCapable(true)
+                .build();
+    }
+}
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
index 0a2b50c..fa1bd8f 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
@@ -34,6 +34,7 @@
     private static final boolean IS_AUX = true;
     private static final boolean IS_DEFAULT = true;
     private static final boolean IS_AUTO = true;
+    private static final ArrayList<InputMethodSubtype> NO_SUBTYPE = null;
 
     @SmallTest
     public void testDefaultEnabledImesWithDefaultVoiceIme() throws Exception {
@@ -45,6 +46,7 @@
         imis.add(createNonDefaultDummyVoiceIme2());
         imis.add(createDefaultDummyEnUSKeyboardIme());
         imis.add(createNonDefaultDummyJaJPKeyboardIme());
+        imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
         final ArrayList<InputMethodInfo> enabledImis = InputMethodUtils.getDefaultEnabledImes(
                 context, true, imis);
         assertEquals(2, enabledImis.size());
@@ -69,6 +71,7 @@
         imis.add(createNonDefaultDummyVoiceIme2());
         imis.add(createDefaultDummyEnUSKeyboardIme());
         imis.add(createNonDefaultDummyJaJPKeyboardIme());
+        imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
         final ArrayList<InputMethodInfo> enabledImis = InputMethodUtils.getDefaultEnabledImes(
                 context, true, imis);
         assertEquals(3, enabledImis.size());
@@ -86,6 +89,55 @@
         }
     }
 
+    @SmallTest
+    public void testParcelable() throws Exception {
+        final ArrayList<InputMethodInfo> originalList = new ArrayList<InputMethodInfo>();
+        originalList.add(createNonDefaultAutoDummyVoiceIme0());
+        originalList.add(createNonDefaultAutoDummyVoiceIme1());
+        originalList.add(createNonDefaultDummyVoiceIme2());
+        originalList.add(createDefaultDummyEnUSKeyboardIme());
+        originalList.add(createNonDefaultDummyJaJPKeyboardIme());
+        originalList.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
+
+        final List<InputMethodInfo> clonedList = cloneViaParcel(originalList);
+        assertNotNull(clonedList);
+        final List<InputMethodInfo> clonedClonedList = cloneViaParcel(clonedList);
+        assertNotNull(clonedClonedList);
+        assertEquals(originalList, clonedList);
+        assertEquals(clonedList, clonedClonedList);
+        assertEquals(originalList.size(), clonedList.size());
+        assertEquals(clonedList.size(), clonedClonedList.size());
+        for (int imeIndex = 0; imeIndex < originalList.size(); ++imeIndex) {
+            verifyEquality(originalList.get(imeIndex), clonedList.get(imeIndex));
+            verifyEquality(clonedList.get(imeIndex), clonedClonedList.get(imeIndex));
+        }
+    }
+
+    private static List<InputMethodInfo> cloneViaParcel(final List<InputMethodInfo> list) {
+        Parcel p = null;
+        try {
+            p = Parcel.obtain();
+            p.writeTypedList(list);
+            p.setDataPosition(0);
+            return p.createTypedArrayList(InputMethodInfo.CREATOR);
+        } finally {
+            if (p != null) {
+                p.recycle();
+            }
+        }
+    }
+
+    private static void verifyEquality(InputMethodInfo expected, InputMethodInfo actual) {
+        assertEquals(expected, actual);
+        assertEquals(expected.getSubtypeCount(), actual.getSubtypeCount());
+        for (int subtypeIndex = 0; subtypeIndex < expected.getSubtypeCount(); ++subtypeIndex) {
+            final InputMethodSubtype expectedSubtype = expected.getSubtypeAt(subtypeIndex);
+            final InputMethodSubtype actualSubtype = actual.getSubtypeAt(subtypeIndex);
+            assertEquals(expectedSubtype, actualSubtype);
+            assertEquals(expectedSubtype.hashCode(), actualSubtype.hashCode());
+        }
+    }
+
     private static InputMethodInfo createDummyInputMethodInfo(String packageName, String name,
             CharSequence label, boolean isAuxIme, boolean isDefault,
             List<InputMethodSubtype> subtypes) {
@@ -155,4 +207,12 @@
         return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardIme", "dummy.keyboard1",
                 "DummyKeyboard1", !IS_AUX, !IS_DEFAULT, subtypes);
     }
+
+    // Although IMEs that have no subtype are considered to be deprecated, the Android framework
+    // must still be able to handle such IMEs as well as IMEs that have at least one subtype.
+    private static InputMethodInfo createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes() {
+        final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+        return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardImeWithoutSubtypes",
+                "dummy.keyboard2", "DummyKeyboard2", !IS_AUX, !IS_DEFAULT, NO_SUBTYPE);
+    }
 }
diff --git a/data/keyboards/Vendor_0a5c_Product_8502.kl b/data/keyboards/Vendor_0a5c_Product_8502.kl
new file mode 100644
index 0000000..f6dbfd4
--- /dev/null
+++ b/data/keyboards/Vendor_0a5c_Product_8502.kl
@@ -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.
+
+# Rhodi
+
+key 304 BUTTON_A
+key 305 BUTTON_B
+key 307 BUTTON_X
+key 308 BUTTON_Y
+key 310 BUTTON_L1
+key 311 BUTTON_R1
+key 316 BUTTON_MODE
+key 317 BUTTON_THUMBL
+key 318 BUTTON_THUMBR
+
+key 158 BACK            WAKE_DROPPED
+key 172 HOME
+
+axis 0x00 X
+axis 0x01 Y
+axis 0x02 Z
+axis 0x05 RZ
+axis 0x09 RTRIGGER
+axis 0x0a LTRIGGER
+axis 0x10 HAT_X
+axis 0x11 HAT_Y
+
+led 0x00 CONTROLLER_1
+led 0x01 CONTROLLER_2
+led 0x02 CONTROLLER_3
+led 0x03 CONTROLLER_4
diff --git a/data/sounds/effects/ogg/KeypressInvalid_48k.ogg b/data/sounds/effects/ogg/KeypressInvalid_48k.ogg
index 24935ad..d1843a7 100644
--- a/data/sounds/effects/ogg/KeypressInvalid_48k.ogg
+++ b/data/sounds/effects/ogg/KeypressInvalid_48k.ogg
Binary files differ
diff --git a/docs/html/design/building-blocks/buttons.jd b/docs/html/design/building-blocks/buttons.jd
index 8a65b82..3a34601 100644
--- a/docs/html/design/building-blocks/buttons.jd
+++ b/docs/html/design/building-blocks/buttons.jd
@@ -1,5 +1,5 @@
 page.title=Buttons
-page.tags="button","input"
+page.tags=button,input
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/button.html">
diff --git a/docs/html/design/building-blocks/dialogs.jd b/docs/html/design/building-blocks/dialogs.jd
index 7cd032c..53d99b8 100644
--- a/docs/html/design/building-blocks/dialogs.jd
+++ b/docs/html/design/building-blocks/dialogs.jd
@@ -1,5 +1,5 @@
 page.title=Dialogs
-page.tags="dialog","alert","popup","toast"
+page.tags=dialog,alert,popup,toast
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/dialogs.html">
diff --git a/docs/html/design/building-blocks/grid-lists.jd b/docs/html/design/building-blocks/grid-lists.jd
index 6c9d227..d98637cc 100644
--- a/docs/html/design/building-blocks/grid-lists.jd
+++ b/docs/html/design/building-blocks/grid-lists.jd
@@ -1,5 +1,5 @@
 page.title=Grid Lists
-page.tags="gridview","layout","listview"
+page.tags=gridview,layout,listview
 @jd:body
 
 <img src="{@docRoot}design/media/gridview_overview.png">
diff --git a/docs/html/design/building-blocks/lists.jd b/docs/html/design/building-blocks/lists.jd
index 0bbd08b..4949d00 100644
--- a/docs/html/design/building-blocks/lists.jd
+++ b/docs/html/design/building-blocks/lists.jd
@@ -1,5 +1,5 @@
 page.title=Lists
-page.tags="listview","layout"
+page.tags=listview,layout
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/layout/listview.html">
diff --git a/docs/html/design/building-blocks/pickers.jd b/docs/html/design/building-blocks/pickers.jd
index 9473d11..fb5e287 100644
--- a/docs/html/design/building-blocks/pickers.jd
+++ b/docs/html/design/building-blocks/pickers.jd
@@ -1,5 +1,5 @@
 page.title=Pickers
-page.tags="datepicker","timepicker"
+page.tags=datepicker,timepicker
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/pickers.html">
diff --git a/docs/html/design/building-blocks/progress.jd b/docs/html/design/building-blocks/progress.jd
index 90732f4..6946a75 100644
--- a/docs/html/design/building-blocks/progress.jd
+++ b/docs/html/design/building-blocks/progress.jd
@@ -1,5 +1,5 @@
 page.title=Progress &amp; Activity
-page.tags="progressbar","download","network"
+page.tags=progressbar,download,network
 @jd:body
 
 <p>Progress bars and activity indicators signal to users that something is happening that will take a moment.</p>
diff --git a/docs/html/design/building-blocks/scrolling.jd b/docs/html/design/building-blocks/scrolling.jd
index 13b3b09..41e7cec 100644
--- a/docs/html/design/building-blocks/scrolling.jd
+++ b/docs/html/design/building-blocks/scrolling.jd
@@ -1,5 +1,5 @@
 page.title=Scrolling
-page.tags="scrollview","listview"
+page.tags=scrollview,listview
 @jd:body
 
 <p>Scrolling allows the user to navigate to content in the overflow using a swipe gesture. The
diff --git a/docs/html/design/building-blocks/seek-bars.jd b/docs/html/design/building-blocks/seek-bars.jd
index 9d38e36..1465688 100644
--- a/docs/html/design/building-blocks/seek-bars.jd
+++ b/docs/html/design/building-blocks/seek-bars.jd
@@ -1,5 +1,5 @@
 page.title=Seek Bars and Sliders
-page.tags="seekbar","progressbar"
+page.tags=seekbar,progressbar
 @jd:body
 
 <p>Interactive sliders make it possible to select a value from a continuous or discrete range of values
diff --git a/docs/html/design/building-blocks/spinners.jd b/docs/html/design/building-blocks/spinners.jd
index cdc933b..f7d80e7 100644
--- a/docs/html/design/building-blocks/spinners.jd
+++ b/docs/html/design/building-blocks/spinners.jd
@@ -1,5 +1,5 @@
 page.title=Spinners
-page.tags="spinner","dropdown"
+page.tags=spinner,dropdown
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/spinner.html">
diff --git a/docs/html/design/building-blocks/switches.jd b/docs/html/design/building-blocks/switches.jd
index dff6c73..d435657 100644
--- a/docs/html/design/building-blocks/switches.jd
+++ b/docs/html/design/building-blocks/switches.jd
@@ -1,5 +1,5 @@
 page.title=Switches
-page.tags="switch","checkbox","radiobutton","button"
+page.tags=switch,checkbox,radiobutton,button
 @jd:body
 
 <p>Switches allow the user to select options. There are three kinds of switches: checkboxes, radio
diff --git a/docs/html/design/building-blocks/tabs.jd b/docs/html/design/building-blocks/tabs.jd
index 2186b18..93818c3 100644
--- a/docs/html/design/building-blocks/tabs.jd
+++ b/docs/html/design/building-blocks/tabs.jd
@@ -1,5 +1,5 @@
 page.title=Tabs
-page.tags="tabs","actionbar","navigation","viewpager"
+page.tags=tabs,actionbar,navigation,viewpager
 @jd:body
 
 <img src="{@docRoot}design/media/tabs_overview.png">
diff --git a/docs/html/design/building-blocks/text-fields.jd b/docs/html/design/building-blocks/text-fields.jd
index 3840ca2..e109d5f 100644
--- a/docs/html/design/building-blocks/text-fields.jd
+++ b/docs/html/design/building-blocks/text-fields.jd
@@ -1,5 +1,5 @@
 page.title=Text Fields
-page.tags="text","edittext","input"
+page.tags=text,edittext,input
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/controls/text.html">
diff --git a/docs/html/design/downloads/index.jd b/docs/html/design/downloads/index.jd
index 16f5509..ddeda5c 100644
--- a/docs/html/design/downloads/index.jd
+++ b/docs/html/design/downloads/index.jd
@@ -1,5 +1,5 @@
 page.title=Downloads
-page tags="Icons", "stencils", "color swatches"
+page.tags=Icons,stencils,color swatches
 @jd:body
 
 <div class="layout-content-row">
diff --git a/docs/html/design/patterns/app-structure.jd b/docs/html/design/patterns/app-structure.jd
index 1447d4e..e0a11ed 100644
--- a/docs/html/design/patterns/app-structure.jd
+++ b/docs/html/design/patterns/app-structure.jd
@@ -1,5 +1,5 @@
 page.title=App Structure
-page.tags="navigation","layout","tablet"
+page.tags=navigation,layout,tablet
 @jd:body
 
     <p>Apps come in many varieties that address very different needs. For example:</p>
@@ -307,4 +307,4 @@
 <li>
 <p>Allow for quick navigation between detail items with swipe views.</p>
 </li>
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/design/patterns/buttons.jd b/docs/html/design/patterns/buttons.jd
index 46e41c8..2d65b2d 100644
--- a/docs/html/design/patterns/buttons.jd
+++ b/docs/html/design/patterns/buttons.jd
@@ -1,5 +1,5 @@
 page.title=Buttons
-page.tags="buttons"
+page.tags=buttons
 @jd:body
 
 <p>
@@ -148,4 +148,4 @@
   Replace previous implementations of Lights Out mode with the Lean Back or
   Immersive approaches. Continue to use Lights Out mode for implementations of
   your app targeted for earlier releases.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/design/patterns/confirming-acknowledging.jd b/docs/html/design/patterns/confirming-acknowledging.jd
index e347231..d39d32d 100644
--- a/docs/html/design/patterns/confirming-acknowledging.jd
+++ b/docs/html/design/patterns/confirming-acknowledging.jd
@@ -1,5 +1,5 @@
 page.title=Confirming &amp; Acknowledging
-page.tags="dialog","toast","notification"
+page.tags=dialog,toast,notification
 @jd:body
 
 <p>In some situations, when a user invokes an action in your app, it's a good idea to <em>confirm</em> or <em>acknowledge</em> that action through text.</p>
@@ -67,4 +67,4 @@
     <p><strong>Acknowledgment is unnecessary</strong>. The user will know the app is gone from the Home Screen because they made it disappear by dragging it away.</p>
 
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/design/patterns/fullscreen.jd b/docs/html/design/patterns/fullscreen.jd
index de016fe..624d44c 100644
--- a/docs/html/design/patterns/fullscreen.jd
+++ b/docs/html/design/patterns/fullscreen.jd
@@ -1,5 +1,5 @@
 page.title=Full Screen
-page.tags="full screen","immersive", "leanback"
+page.tags=full screen,immersive,leanback
 @jd:body
 
 <p>
@@ -148,4 +148,4 @@
   Replace previous implementations of Lights Out mode with the Lean Back or
   Immersive approaches. Continue to use Lights Out mode for implementations of
   your app targeted for earlier releases.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/design/patterns/gestures.jd b/docs/html/design/patterns/gestures.jd
index 213902f..1ec7094 100644
--- a/docs/html/design/patterns/gestures.jd
+++ b/docs/html/design/patterns/gestures.jd
@@ -1,5 +1,5 @@
 page.title=Gestures
-page.tags="gesture","input","touch"
+page.tags=gesture,input,touch
 @jd:body
 
 <p>Gestures allow users to interact with your app by manipulating the screen objects you provide. The
diff --git a/docs/html/design/patterns/help.jd b/docs/html/design/patterns/help.jd
index e47bc5a..97949e2 100644
--- a/docs/html/design/patterns/help.jd
+++ b/docs/html/design/patterns/help.jd
@@ -1,5 +1,5 @@
 page.title=Help
-page.tags="settings","preferences"
+page.tags=settings,preferences
 @jd:body
 
 <p>We wish we could guarantee that if you follow every piece of advice on this website, everyone will be able to learn and use your app without a hitch. Sadly, that's not the case.</p>
@@ -110,4 +110,4 @@
 <p>People don't read help from start to finish. They scan around, looking for a piece of information containing the answer they need. Make it less burdensome with friendly formatting and layout choices like bold headings, bulleted and numbered lists, tables, and white space between paragraphs. And if you have a large amount of content, divide it into multiple screens to cut down on scrolling.</p>
 
 <h4>Take me straight to the answer</h4>
-<p>What's better than a screen that's easy to scan? A screen that requires no scanning at all because the answer's right there. Consider having each screen in your app navigate to help that's relevant just to that screen. We call this <em>contextual help</em>, and it's the holy grail of user assistance. If you take this approach, be sure to also provide a way to get to the rest of the help content.</p>
\ No newline at end of file
+<p>What's better than a screen that's easy to scan? A screen that requires no scanning at all because the answer's right there. Consider having each screen in your app navigate to help that's relevant just to that screen. We call this <em>contextual help</em>, and it's the holy grail of user assistance. If you take this approach, be sure to also provide a way to get to the rest of the help content.</p>
diff --git a/docs/html/design/patterns/multi-pane-layouts.jd b/docs/html/design/patterns/multi-pane-layouts.jd
index 6071ef3..c207006 100644
--- a/docs/html/design/patterns/multi-pane-layouts.jd
+++ b/docs/html/design/patterns/multi-pane-layouts.jd
@@ -3,6 +3,7 @@
 page.metaDescription=Android devices come in many different screen sizes and types. Multi-pane layouts help you provide a balanced and aesthetically pleasing layout across the range of Android devices.
 @jd:body
 
+
 <a class="notice-developers" href="{@docRoot}training/basics/fragments/index.html">
   <div>
     <h3>Developer Docs</h3>
diff --git a/docs/html/design/patterns/navigation-drawer.jd b/docs/html/design/patterns/navigation-drawer.jd
index bf6609e..7e63ba6c 100644
--- a/docs/html/design/patterns/navigation-drawer.jd
+++ b/docs/html/design/patterns/navigation-drawer.jd
@@ -1,5 +1,5 @@
 page.title=Navigation Drawer
-page.tags="DrawerLayout","SlidingPaneLayout"
+page.tags=DrawerLayout,SlidingPaneLayout
 @jd:body
 
 
diff --git a/docs/html/design/patterns/navigation.jd b/docs/html/design/patterns/navigation.jd
index 3e60f66..3edf6ba 100644
--- a/docs/html/design/patterns/navigation.jd
+++ b/docs/html/design/patterns/navigation.jd
@@ -1,5 +1,5 @@
 page.title=Navigation with Back and Up
-page.tags="navigation","activity","task","up navigation","back navigation"
+page.tags=navigation,activity,task,up navigation,back navigation
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/implementing-navigation/index.html">
diff --git a/docs/html/design/patterns/new.jd b/docs/html/design/patterns/new.jd
index 50cb950..d672e46 100644
--- a/docs/html/design/patterns/new.jd
+++ b/docs/html/design/patterns/new.jd
@@ -1,5 +1,5 @@
 page.title=New in Android
-page.tags="KitKat", "Android 4.4"
+page.tags=KitKat,Android 4.4
 @jd:body
 
 
diff --git a/docs/html/design/patterns/selection.jd b/docs/html/design/patterns/selection.jd
index d0ad837..be31677 100644
--- a/docs/html/design/patterns/selection.jd
+++ b/docs/html/design/patterns/selection.jd
@@ -1,5 +1,5 @@
 page.title=Selection
-page.tags="actionmode","navigation","contextual"
+page.tags=actionmode,navigation,contextual
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/menus.html#context-menu">
diff --git a/docs/html/design/patterns/settings.jd b/docs/html/design/patterns/settings.jd
index 7e0485f..e3a3f05 100644
--- a/docs/html/design/patterns/settings.jd
+++ b/docs/html/design/patterns/settings.jd
@@ -1,5 +1,5 @@
 page.title=Settings
-page.tags="preferences","sharedpreferences"
+page.tags=preferences,sharedpreferences
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/ui/settings.html">
@@ -696,4 +696,4 @@
 <li><p>Use design patterns wherever applicable so users don't face a learning curve.</p></li>
 <li><p>Choose defaults that are safe, neutral, and fit the majority of users.</p></li>
 <li><p>Give each setting a clear, concise label and use secondary text appropriately.</p></li>
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/design/patterns/swipe-views.jd b/docs/html/design/patterns/swipe-views.jd
index 46d6ffb8..af5c9dc 100644
--- a/docs/html/design/patterns/swipe-views.jd
+++ b/docs/html/design/patterns/swipe-views.jd
@@ -1,5 +1,5 @@
 page.title=Swipe Views
-page.tags="viewpager","navigation","tabs"
+page.tags=viewpager,navigation,tabs
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}training/implementing-navigation/lateral.html">
diff --git a/docs/html/design/patterns/widgets.jd b/docs/html/design/patterns/widgets.jd
index d08f178..654cf37 100644
--- a/docs/html/design/patterns/widgets.jd
+++ b/docs/html/design/patterns/widgets.jd
@@ -1,5 +1,5 @@
 page.title=Widgets
-page.tags="appwidget","home"
+page.tags=appwidget,home
 @jd:body
 
 <a class="notice-developers" href="{@docRoot}guide/topics/appwidgets/index.html">
diff --git a/docs/html/design/style/branding.jd b/docs/html/design/style/branding.jd
index 2ea4d47..2353a93 100644
--- a/docs/html/design/style/branding.jd
+++ b/docs/html/design/style/branding.jd
@@ -1,5 +1,5 @@
 page.title=Your Branding
-page.tags="branding","logo"
+page.tags=branding,logo
 @jd:body
 
 <p>Following Android design patterns doesn't mean that your app has to look the same as
diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd
index 4559f00..d8d8c76 100644
--- a/docs/html/design/style/iconography.jd
+++ b/docs/html/design/style/iconography.jd
@@ -10,7 +10,7 @@
 <p>An icon is a graphic that takes up a small portion of screen real estate and provides a quick,
 intuitive representation of an action, a status, or an app.</p>
 
-<p >When you design icons for your app, it's important to keep in mind that your
+<p>When you design icons for your app, it's important to keep in mind that your
 app may be installed on a variety of devices that offer a range of
 pixel densities, as mentioned in
 <a href="{@docRoot}design/style/devices-displays.html">Devices
diff --git a/docs/html/design/style/metrics-grids.jd b/docs/html/design/style/metrics-grids.jd
index c375631..a553475 100644
--- a/docs/html/design/style/metrics-grids.jd
+++ b/docs/html/design/style/metrics-grids.jd
@@ -1,5 +1,5 @@
 page.title=Metrics and Grids
-page.tags="layout","screens"
+page.tags=layout,screens
 @jd:body
 
 <p>Devices vary not only in physical size, but also in screen density (<acronym title="Dots per
diff --git a/docs/html/design/style/touch-feedback.jd b/docs/html/design/style/touch-feedback.jd
index 2017d8e..9f36fed 100644
--- a/docs/html/design/style/touch-feedback.jd
+++ b/docs/html/design/style/touch-feedback.jd
@@ -1,5 +1,5 @@
 page.title=Touch Feedback
-page.tags="input","button"
+page.tags=input,button
 @jd:body
 
     <div class="layout-content-row" style="margin-bottom: -100px">
@@ -83,4 +83,4 @@
   widgets, like lists and grid lists, have support for boundary feedback built
   in. If you’re building custom widgets, keep boundary feedback in mind and
   provide it from within your app.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/design/style/typography.jd b/docs/html/design/style/typography.jd
index 3c201f7..ec6fba2 100644
--- a/docs/html/design/style/typography.jd
+++ b/docs/html/design/style/typography.jd
@@ -1,5 +1,5 @@
 page.title=Typography
-page.tags="textview","font"
+page.tags=textview,font
 @jd:body
 
 <div class="layout-content-row">
diff --git a/docs/html/design/style/writing.jd b/docs/html/design/style/writing.jd
index cda17eb..4f62253 100644
--- a/docs/html/design/style/writing.jd
+++ b/docs/html/design/style/writing.jd
@@ -1,5 +1,5 @@
 page.title=Writing Style
-page.tags="dialog","toast","notification"
+page.tags=dialog,toast,notification
 @jd:body
 
 <h2 id="voa">Android's Voice</h2>
@@ -319,4 +319,4 @@
         ellipsis. </li>
     </ul>
   </li>
-</ul>
\ No newline at end of file
+</ul>
diff --git a/docs/html/distribute/googleplay/edu/index.jd b/docs/html/distribute/googleplay/edu/index.jd
index 487028f..a27f82f 100644
--- a/docs/html/distribute/googleplay/edu/index.jd
+++ b/docs/html/distribute/googleplay/edu/index.jd
@@ -1,5 +1,5 @@
 page.title=Google Play for Education
-page.tags="Google Play","education","schools", "distribution"
+page.tags=Google Play,education,schools,distribution
 header.hide=1
 
 @jd:body
diff --git a/docs/html/distribute/googleplay/publish/localizing.jd b/docs/html/distribute/googleplay/publish/localizing.jd
index 1a5f3c1..30f10b7 100644
--- a/docs/html/distribute/googleplay/publish/localizing.jd
+++ b/docs/html/distribute/googleplay/publish/localizing.jd
@@ -1,5 +1,5 @@
 page.title=Localization Checklist
-page.tags="localize","localization","resources", "formats", "l10n"
+page.tags=localize,localization,resources,formats,l10n
 @jd:body
 
 <div id="qv-wrapper"><div id="qv">
diff --git a/docs/html/distribute/googleplay/publish/preparing.jd b/docs/html/distribute/googleplay/publish/preparing.jd
index b9dd0e0..6af3eea 100644
--- a/docs/html/distribute/googleplay/publish/preparing.jd
+++ b/docs/html/distribute/googleplay/publish/preparing.jd
@@ -1,5 +1,5 @@
 page.title=Launch Checklist
-page.tags="publishing","launch","Google Play", "Developer Console"
+page.tags=publishing,launch,Google Play,Developer Console
 @jd:body
 
 <div id="qv-wrapper"><div id="qv">
diff --git a/docs/html/google/gcm/client.jd b/docs/html/google/gcm/client.jd
index 42cebfc..ac446dc 100644
--- a/docs/html/google/gcm/client.jd
+++ b/docs/html/google/gcm/client.jd
@@ -1,5 +1,5 @@
 page.title=Implementing GCM Client
-page.tags="cloud","push","messaging"
+page.tags=cloud,push,messaging
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/google/gcm/gs.jd b/docs/html/google/gcm/gs.jd
index d937955..4cfe1bc 100644
--- a/docs/html/google/gcm/gs.jd
+++ b/docs/html/google/gcm/gs.jd
@@ -1,5 +1,5 @@
 page.title=Getting Started
-page.tags="cloud","push","messaging"
+page.tags=cloud,push,messaging
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/google/gcm/helper.jd b/docs/html/google/gcm/helper.jd
index e7f2f73..19dcdc5 100644
--- a/docs/html/google/gcm/helper.jd
+++ b/docs/html/google/gcm/helper.jd
@@ -1,5 +1,5 @@
 page.title=Using the GCM Helper Libraries
-page.tags="cloud","push","messaging"
+page.tags=cloud,push,messaging
 @jd:body
 
 <div id="deprecatedSticker">
diff --git a/docs/html/google/gcm/index.jd b/docs/html/google/gcm/index.jd
index 8f325b8..70f7a9c 100644
--- a/docs/html/google/gcm/index.jd
+++ b/docs/html/google/gcm/index.jd
@@ -1,5 +1,5 @@
 page.title=Google Cloud Messaging for Android
-page.tags="gcm"
+page.tags=gcm
 header.hide=1
 @jd:body
 
diff --git a/docs/html/google/play-services/ads.jd b/docs/html/google/play-services/ads.jd
index 18579c7..ed346c6 100644
--- a/docs/html/google/play-services/ads.jd
+++ b/docs/html/google/play-services/ads.jd
@@ -1,5 +1,5 @@
 page.title=Google Mobile Ads
-page.tags="Ads","monetization", "AdMob", "Google Play services"
+page.tags=Ads,monetization,AdMob,Google Play services
 header.hide=1
 
 @jd:body
diff --git a/docs/html/google/play-services/auth.jd b/docs/html/google/play-services/auth.jd
index 7acaf1c..dded599 100644
--- a/docs/html/google/play-services/auth.jd
+++ b/docs/html/google/play-services/auth.jd
@@ -1,5 +1,5 @@
 page.title=Authorization
-page.tags="AccountManager","oauth2"
+page.tags=AccountManager,oauth2
 @jd:body
 
 <div id="qv-wrapper">
@@ -236,4 +236,4 @@
     case, obtain a new token using <a
 href="{@docRoot}reference/com/google/android/gms/auth/GoogleAuthUtil.html#getToken(android.content.Context, java.lang.String, java.lang.String)"
 >{@code GoogleAuthUtil.getToken()}</a>.
-</p>
\ No newline at end of file
+</p>
diff --git a/docs/html/google/play-services/id.jd b/docs/html/google/play-services/id.jd
index 466dfef..db50c7f 100644
--- a/docs/html/google/play-services/id.jd
+++ b/docs/html/google/play-services/id.jd
@@ -1,5 +1,5 @@
 page.title=Advertising ID
-page.tags="Ads","Advertising ID", "ID"
+page.tags=Ads,Advertising ID,ID
 header.hide=1
 
 @jd:body
@@ -195,4 +195,4 @@
   }
   final String id = adInfo.getId();
   final boolean isLAT = adInfo.isLimitAdTrackingEnabled();
-}</pre>
\ No newline at end of file
+}</pre>
diff --git a/docs/html/google/play-services/location.jd b/docs/html/google/play-services/location.jd
index 1cdd247..3fbf00e 100644
--- a/docs/html/google/play-services/location.jd
+++ b/docs/html/google/play-services/location.jd
@@ -1,5 +1,5 @@
 page.title=Location APIs
-page.tags="location","geofence", "geofencing", "gps"
+page.tags=location,geofence,geofencing,gps
 header.hide=1
 @jd:body
 
diff --git a/docs/html/google/play-services/maps.jd b/docs/html/google/play-services/maps.jd
index 68a84614..c24cc74 100644
--- a/docs/html/google/play-services/maps.jd
+++ b/docs/html/google/play-services/maps.jd
@@ -1,5 +1,5 @@
 page.title=Google Maps Android API
-page.tags="mapview","location"
+page.tags=mapview,location
 header.hide=1
 
 @jd:body
@@ -87,4 +87,4 @@
     </p>
   </div>
 
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/google/play-services/plus.jd b/docs/html/google/play-services/plus.jd
index 95c9e0e..84224e7 100644
--- a/docs/html/google/play-services/plus.jd
+++ b/docs/html/google/play-services/plus.jd
@@ -1,5 +1,5 @@
 page.title=Google+ Platform for Android
-page.tags="authentication","signin","social"
+page.tags=authentication,signin,social
 header.hide=1
 
 @jd:body
@@ -87,4 +87,4 @@
     Google+ developer documents at <a class="external-link"
     href="https://developers.google.com/+/mobile/android/">developers.google.com/+</a>.</p>
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/google/play-services/wallet.jd b/docs/html/google/play-services/wallet.jd
index 6c0dd4c..9f2b4dd 100644
--- a/docs/html/google/play-services/wallet.jd
+++ b/docs/html/google/play-services/wallet.jd
@@ -1,5 +1,5 @@
 page.title=Google Wallet Instant Buy for Android
-page.tags="Wallet","payments","Instant Buy"
+page.tags=Wallet,payments,Instant Buy
 header.hide=1
 
 @jd:body
@@ -83,4 +83,4 @@
 
 
   </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/google/play/billing/gp-purchase-status-api.jd b/docs/html/google/play/billing/gp-purchase-status-api.jd
index 4cfacee..d272301 100644
--- a/docs/html/google/play/billing/gp-purchase-status-api.jd
+++ b/docs/html/google/play/billing/gp-purchase-status-api.jd
@@ -1,5 +1,5 @@
 page.title=Purchase Status API
-page.tags="In-app Billing", "Google Play", "inapp billing", "in app billing", "iab", "billing"
+page.tags=In-app Billing,Google Play,inapp billing,in app billing,iab,billing
 
 @jd:body
 
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index 7c6c145..19f510a 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -1,5 +1,5 @@
 page.title=Supported Media Formats
-page.tags="video","audio","mpeg","mp4","m4a","mp3","3gp","3gpp","flac","wave","wav"
+page.tags=video,audio,mpeg,mp4,m4a,mp3,3gp,3gpp,flac,wave,wav
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/components/activities.jd b/docs/html/guide/components/activities.jd
index 1cbaa79..b4617fb 100644
--- a/docs/html/guide/components/activities.jd
+++ b/docs/html/guide/components/activities.jd
@@ -1,5 +1,5 @@
 page.title=Activities
-page.tags="activity","intent"
+page.tags=activity,intent
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/components/processes-and-threads.jd b/docs/html/guide/components/processes-and-threads.jd
index 1fed712..c8c3764 100644
--- a/docs/html/guide/components/processes-and-threads.jd
+++ b/docs/html/guide/components/processes-and-threads.jd
@@ -1,5 +1,5 @@
 page.title=Processes and Threads
-page.tags="lifecycle","background"
+page.tags=lifecycle,background
 
 @jd:body
 
diff --git a/docs/html/guide/faq/security.jd b/docs/html/guide/faq/security.jd
index 96fc7f5..8ccf21f 100644
--- a/docs/html/guide/faq/security.jd
+++ b/docs/html/guide/faq/security.jd
@@ -47,8 +47,7 @@
 <a name="issue" id="issue"></a><h2>I think I found a security flaw. How do I
 report it?</h2>
 
-<p>You can reach the Android security team at <a
-href="mailto:security@android.com">security@android.com</a>. If you like, you
+<p>You can reach the Android security team at security@android.com. If you like, you
 can protect your message using our <a
 href="http://code.google.com/android/security_at_android_dot_com.txt">PGP
 key</a>.</p>
@@ -58,6 +57,15 @@
 users are at risk. In return, we will make sure to keep the researcher informed
 of our progress in issuing a fix. </p>
 
+<p>Vulnerabilities specific to Android OEMs should be reported to the relevant
+vendor. An incomplete list of Android vendor security contacts can be found below.
+To be added to this list, please contact security@android.com.</p>
+
+<ul>
+  <li><a href="http://www.htc.com/www/terms/product-security/">HTC</a></li>
+  <li><a href="http://www.motorolasolutions.com/US-EN/About/Security%20Vulnerability">Motorola</a></li>
+  <li><a href="http://developer.samsung.com/notice/How-to-Use-the-Forum">Samsung</a> - m.security@samsung.com</li>
+</ul>
 
 <a name="informed" id="informed"></a><h2>How can I stay informed about Android security?</h2>
 
@@ -91,8 +99,8 @@
 <p>Like any other platform, it will be possible for unethical developers
 to create malicious software, known as <a
 href="http://en.wikipedia.org/wiki/Malware">malware</a>, for Android. If you
-think somebody is trying to spread malware, please let us know at <a
-href="mailto:security@android.com">security@android.com</a>. Please include as
+think somebody is trying to spread malware, please let us know at
+security@android.com. Please include as
 much detail about the application as possible, with the location it is
 being distributed from and why you suspect it of being malicious software.</p>
 
diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd
index a474498..ee6b814 100644
--- a/docs/html/guide/topics/admin/device-admin.jd
+++ b/docs/html/guide/topics/admin/device-admin.jd
@@ -1,5 +1,5 @@
 page.title=Device Administration
-page.tags="devicepolicymanager","policy","security"
+page.tags=devicepolicymanager,policy,security
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/appwidgets/host.jd b/docs/html/guide/topics/appwidgets/host.jd
index da7408f..169e388 100644
--- a/docs/html/guide/topics/appwidgets/host.jd
+++ b/docs/html/guide/topics/appwidgets/host.jd
@@ -1,5 +1,5 @@
 page.title=App Widget Host
-page.tags="AppWidgetHost","home screen","launcher"
+page.tags=AppWidgetHost,home screen,launcher
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index d8ad844..a783ad1 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -1,5 +1,5 @@
 page.title=App Widgets
-page.tags="home","AppWidgetProvider"
+page.tags=home,AppWidgetProvider
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/connectivity/bluetooth-le.jd b/docs/html/guide/topics/connectivity/bluetooth-le.jd
index 449c892..5c32e56 100644
--- a/docs/html/guide/topics/connectivity/bluetooth-le.jd
+++ b/docs/html/guide/topics/connectivity/bluetooth-le.jd
@@ -1,5 +1,5 @@
 page.title=Bluetooth Low Energy
-page.tags="wireless","bluetoothadapter","bluetoothdevice","BLE","BTLE"
+page.tags=wireless,bluetoothadapter,bluetoothdevice,BLE,BTLE
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/connectivity/bluetooth.jd b/docs/html/guide/topics/connectivity/bluetooth.jd
index b57f3e2..96008c5 100644
--- a/docs/html/guide/topics/connectivity/bluetooth.jd
+++ b/docs/html/guide/topics/connectivity/bluetooth.jd
@@ -1,5 +1,5 @@
 page.title=Bluetooth
-page.tags="wireless","bluetoothadapter","bluetoothdevice"
+page.tags=wireless,bluetoothadapter,bluetoothdevice
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/connectivity/nfc/hce.jd b/docs/html/guide/topics/connectivity/nfc/hce.jd
index d6efaa7..9ec1a8d 100644
--- a/docs/html/guide/topics/connectivity/nfc/hce.jd
+++ b/docs/html/guide/topics/connectivity/nfc/hce.jd
@@ -1,5 +1,5 @@
 page.title=Host-based Card Emulation
-page.tags="host card emulation", "hce","HostApduService","OffHostApduService","tap and pay"
+page.tags=host card emulation,hce,HostApduService,OffHostApduService,tap and pay
 
 @jd:body
 
diff --git a/docs/html/guide/topics/connectivity/sip.jd b/docs/html/guide/topics/connectivity/sip.jd
index 526eb83..5154767 100644
--- a/docs/html/guide/topics/connectivity/sip.jd
+++ b/docs/html/guide/topics/connectivity/sip.jd
@@ -1,5 +1,5 @@
 page.title=Session Initiation Protocol
-page.tags="sipmanager","sipprofile","sipaudiocall","telephony"
+page.tags=sipmanager,sipprofile,sipaudiocall,telephony
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/connectivity/wifip2p.jd b/docs/html/guide/topics/connectivity/wifip2p.jd
index 7cadde1..d7e1269 100644
--- a/docs/html/guide/topics/connectivity/wifip2p.jd
+++ b/docs/html/guide/topics/connectivity/wifip2p.jd
@@ -1,5 +1,5 @@
 page.title=Wi-Fi Peer-to-Peer
-page.tags="wireless","WifiP2pManager","Wi-Fi Direct","WiFi Direct","P2P","Wi-Fi P2P","WiFi P2P"
+page.tags=wireless,WifiP2pManager,Wi-Fi Direct,WiFi Direct,P2P,Wi-Fi P2P,WiFi P2P
 
 @jd:body
 
diff --git a/docs/html/guide/topics/data/data-storage.jd b/docs/html/guide/topics/data/data-storage.jd
index 4b8a647..24e7f54 100644
--- a/docs/html/guide/topics/data/data-storage.jd
+++ b/docs/html/guide/topics/data/data-storage.jd
@@ -1,5 +1,5 @@
 page.title=Storage Options
-page.tags="database","sharedpreferences","sdcard"
+page.tags=database,sharedpreferences,sdcard
 @jd:body
 
 
diff --git a/docs/html/guide/topics/data/install-location.jd b/docs/html/guide/topics/data/install-location.jd
index 2ec0d5a..cc58b46 100644
--- a/docs/html/guide/topics/data/install-location.jd
+++ b/docs/html/guide/topics/data/install-location.jd
@@ -1,5 +1,5 @@
 page.title=App Install Location
-page.tags="sdcard","external"
+page.tags=sdcard,external
 @jd:body
 
 
diff --git a/docs/html/guide/topics/graphics/hardware-accel.jd b/docs/html/guide/topics/graphics/hardware-accel.jd
index 54ef20c..7c957b8 100644
--- a/docs/html/guide/topics/graphics/hardware-accel.jd
+++ b/docs/html/guide/topics/graphics/hardware-accel.jd
@@ -263,256 +263,153 @@
   <p>The following table describes the support level of various operations across API levels:</p>
 
   <style type="text/css">
-    .tblGenFixed, .tblGeneric{font-size:15px}.tblGenFixed td {padding:0 3px;letter-spacing:0;word-spacing:0;background-color:#fff;z-index:1;border-top:0px none;border-left:0px none;border-bottom:1px solid #CCC;border-right:1px solid #CCC;} .dn {display:none} .tblGenFixed td.s0 {background-color:white;border-top:1px solid #CCC;border-left:1px solid #CCC;} .tblGenFixed td.s1 {background-color:#434343;color:#ffffff;text-align:center;border-top:1px solid #CCC;} .tblGenFixed td.s2 {background-color:#d9d9d9;color:#000000;text-align:center;} .tblGenFixed td.s3 {background-color:white;color:#000000;text-align:center;} .tblGenFixed td.s5 {background-color:#434343;color:#ffffff;text-align:left;border-left:1px solid #CCC;} .tblGenFixed td.s10 {background-color:white;font-family:courier new,monospace;color:#000000;text-align:right;border-left:1px solid #CCC;} .tblGenFixed td.g_pos {background-color:#d9d9d9;color:#6aa84f;text-align:center;} .tblGenFixed td.g_neg {background-color:#d9d9d9;color:#980000;text-align:center;} .tblGenFixed td.w_pos {background-color:white;color:#6aa84f;text-align:center;} .tblGenFixed td.w_neg {background-color:white;color:#980000;text-align:center;}
+    .tblGenFixed, .tblGeneric{font-size:15px}.tblGenFixed td {padding:0 3px;letter-spacing:0;word-spacing:0;background-color:#fff;z-index:1;border-top:0px none;border-left:0px none;border-bottom:1px solid #CCC;border-right:1px solid #CCC;} .dn {display:none} .tblGenFixed td.s0 {background-color:white;border-top:1px solid #CCC;border-left:1px solid #CCC;} .tblGenFixed td.s1 {background-color:#434343;color:#ffffff;text-align:center;border-top:1px solid #CCC;} .tblGenFixed td.s3 {background-color:white;color:#000000;text-align:center;} .tblGenFixed td.s5 {background-color:#434343;color:#ffffff;text-align:left;border-left:1px solid #CCC;} .tblGenFixed td.label_pos {background-color:white;font-family:courier new,monospace;color:#000000;text-align:right;border-left:1px solid #CCC;} .tblGenFixed td.label_neg {background-color:#ececec;font-family:courier new,monospace;color:#000000;text-align:right;border-left:1px solid #CCC;} .tblGenFixed td.value_pos {background-color:white;color:#000000;text-align:center;} .tblGenFixed td.value_neg {background-color:#ececec;color:#980000;text-align:center;}
   </style>
   <table border="0" cellpadding="0" cellspacing="0" class="tblGenFixed" id="tblMain">
     <tbody>
     <tr class="rShim">
         <td class="rShim" style="width:380px;"></td>
-        <td class="rShim" style="width:120px;"></td>
-        <td class="rShim" style="width:120px;"></td>
-        <td class="rShim" style="width:120px;"></td>
-        <td class="rShim" style="width:120px;"></td>
+        <td class="rShim" style="width:240px;"></td>
     </tr>
     <tr>
-        <td rowspan="2" class="s0"></td>
-        <td colspan="4" class="s1">API level</td>
-    </tr>
-    <tr>
-        <td style="display:none;"></td>
-        <td class="s2">&lt; 16</td>
-        <td class="s3">16</td>
-        <td class="s2">17</td>
-        <td class="s3">18</td>
+        <td class="s0"></td>
+        <td class="s1">First supported API level</td>
     </tr>
     <tr>
         <td colspan="5" class="s5">Canvas</td>
     </tr>
     <tr>
-        <td class="s10">drawBitmapMesh() (colors array)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">drawBitmapMesh() (colors array)</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">drawPicture()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">drawPicture()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">drawPosText()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
-        <td class="g_pos">&#10003;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">drawPosText()</td>
+        <td class="value_pos">16</td>
     </tr>
     <tr>
-        <td class="s10">drawTextOnPath()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
-        <td class="g_pos">&#10003;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">drawTextOnPath()</td>
+        <td class="value_pos">16</td>
     </tr>
     <tr>
-        <td class="s10">drawVertices()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">drawVertices()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">setDrawFilter()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
-        <td class="g_pos">&#10003;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">setDrawFilter()</td>
+        <td class="value_pos">16</td>
     </tr>
     <tr>
-        <td class="s10">clipPath()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">clipPath()</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">clipRegion()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">clipRegion()</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">clipRect(Region.Op.XOR)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">clipRect(Region.Op.XOR)</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">clipRect(Region.Op.Difference)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">clipRect(Region.Op.Difference)</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">clipRect(Region.Op.ReverseDifference)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">clipRect(Region.Op.ReverseDifference)</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">clipRect() with rotation/perspective</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">clipRect() with rotation/perspective</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
         <td colspan="5" class="s5">Paint</td>
     </tr>
     <tr>
-        <td class="s10">setAntiAlias() (for text)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">setAntiAlias() (for text)</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">setAntiAlias() (for lines)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
-        <td class="g_pos">&#10003;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">setAntiAlias() (for lines)</td>
+        <td class="value_pos">16</td>
     </tr>
     <tr>
-        <td class="s10">setFilterBitmap()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_pos">&#10003;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">setFilterBitmap()</td>
+        <td class="value_pos">17</td>
     </tr>
     <tr>
-        <td class="s10">setLinearText()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">setLinearText()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">setMaskFilter()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">setMaskFilter()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">setPathEffect() (for lines)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">setPathEffect() (for lines)</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">setRasterizer()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">setRasterizer()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">setShadowLayer() (other than text)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">setShadowLayer() (other than text)</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">setStrokeCap() (for lines)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">setStrokeCap() (for lines)</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td class="s10">setStrokeCap() (for points)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_pos">setStrokeCap() (for points)</td>
+        <td class="value_pos">19</td>
     </tr>
     <tr>
-        <td class="s10">setSubpixelText()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">setSubpixelText()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
         <td colspan="5" class="s5">Xfermode</td>
     </tr>
     <tr>
-        <td class="s10">AvoidXfermode</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">AvoidXfermode</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">PixelXorXfermode</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">PixelXorXfermode</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">PorterDuff.Mode.DARKEN (framebuffer)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">PorterDuff.Mode.DARKEN (framebuffer)</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">PorterDuff.Mode.LIGHTEN (framebuffer)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">PorterDuff.Mode.LIGHTEN (framebuffer)</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">PorterDuff.Mode.OVERLAY (framebuffer)</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">PorterDuff.Mode.OVERLAY (framebuffer)</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
         <td colspan="5" class="s5">Shader</td>
     </tr>
     <tr>
-        <td class="s10">ComposeShader inside ComposeShader</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">ComposeShader inside ComposeShader</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">Same type shaders inside ComposeShader</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
+        <td class="label_neg">Same type shaders inside ComposeShader</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">Local matrix on ComposeShader</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
+        <td class="label_pos">Local matrix on ComposeShader</td>
+        <td class="value_pos">18</td>
     </tr>
     </tbody>
   </table>
@@ -530,64 +427,39 @@
     <tbody>
     <tr class="rShim">
         <td class="rShim" style="width:380px;"></td>
-        <td class="rShim" style="width:120px;"></td>
-        <td class="rShim" style="width:120px;"></td>
-        <td class="rShim" style="width:120px;"></td>
+        <td class="rShim" style="width:240px;"></td>
     </tr>
     <tr>
-        <td rowspan="2" class="s0"></td>
-        <td colspan="4" class="s1">API level</td>
+        <td class="s5">Drawing operation to be scaled</td>
+        <td class="s1">First supported API level</td>
     </tr>
     <tr>
-        <td style="display:none;"></td>
-        <td class="s2">&lt; 17</td>
-        <td class="s3">17</td>
-        <td class="s2">18</td>
+        <td class="label_pos">drawText()</td>
+        <td class="value_pos">18</td>
     </tr>
     <tr>
-        <td colspan="5" class="s5">Support for large scale factors</td>
+        <td class="label_neg">drawPosText()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">drawText()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_pos">&#10003;</td>
+        <td class="label_neg">drawTextOnPath()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">drawPosText()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
+        <td class="label_pos">Simple Shapes*</td>
+        <td class="value_pos">17</td>
     </tr>
     <tr>
-        <td class="s10">drawTextOnPath()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
+        <td class="label_neg">Complex Shapes*</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">Simple Shapes*</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_pos">&#10003;</td>
-        <td class="g_pos">&#10003;</td>
+        <td class="label_neg">drawPath()</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     <tr>
-        <td class="s10">Complex Shapes*</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-    </tr>
-    <tr>
-        <td class="s10">drawPath()</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
-    </tr>
-    <tr>
-        <td class="s10">Shadow layer</td>
-        <td class="g_neg">&#10007;</td>
-        <td class="w_neg">&#10007;</td>
-        <td class="g_neg">&#10007;</td>
+        <td class="label_neg">Shadow layer</td>
+        <td class="value_neg">&#10007;</td>
     </tr>
     </tbody>
   </table>
diff --git a/docs/html/guide/topics/graphics/opengl.jd b/docs/html/guide/topics/graphics/opengl.jd
index f46113d..d194082 100644
--- a/docs/html/guide/topics/graphics/opengl.jd
+++ b/docs/html/guide/topics/graphics/opengl.jd
@@ -1,5 +1,5 @@
 page.title=OpenGL ES
-page.tags="games"
+page.tags=games
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/graphics/prop-animation.jd b/docs/html/guide/topics/graphics/prop-animation.jd
index 22bf7696..e455496 100644
--- a/docs/html/guide/topics/graphics/prop-animation.jd
+++ b/docs/html/guide/topics/graphics/prop-animation.jd
@@ -1,5 +1,5 @@
 page.title=Property Animation
-page.tags="valueanimator","objectanimator","layouttransition","ViewPropertyAnimator"
+page.tags=valueanimator,objectanimator,layouttransition,ViewPropertyAnimator
 @jd:body
 
   <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index d421591..4057736 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -1,5 +1,5 @@
 page.title=&lt;uses-feature&gt;
-page.tags="filtering","features","google play filters","permissions"
+page.tags=filtering,features,google play filters,permissions
 @jd:body
 
 <div id="qv-wrapper">
@@ -1099,4 +1099,4 @@
   <td><code>android.hardware.wifi</code></td>
 <!--  <td></td> -->
 </tr>
-</table>
\ No newline at end of file
+</table>
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index b372592..79a37f0 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -1,5 +1,5 @@
 page.title=&lt;uses-sdk&gt;
-page.tags="api levels","sdk version","minsdkversion","targetsdkversion","maxsdkversion"
+page.tags=api levels,sdk version,minsdkversion,targetsdkversion,maxsdkversion
 @jd:body
 
 
diff --git a/docs/html/guide/topics/media/audio-capture.jd b/docs/html/guide/topics/media/audio-capture.jd
index 44c618f..8e60c8f 100644
--- a/docs/html/guide/topics/media/audio-capture.jd
+++ b/docs/html/guide/topics/media/audio-capture.jd
@@ -1,5 +1,5 @@
 page.title=Audio Capture
-page.tags="mediarecorder"
+page.tags=mediarecorder
 @jd:body
 
     <div id="qv-wrapper">
@@ -249,4 +249,4 @@
         }
     }
 }
-</pre>
\ No newline at end of file
+</pre>
diff --git a/docs/html/guide/topics/media/camera.jd b/docs/html/guide/topics/media/camera.jd
index e48109a..56ef624 100644
--- a/docs/html/guide/topics/media/camera.jd
+++ b/docs/html/guide/topics/media/camera.jd
@@ -1,5 +1,5 @@
 page.title=Camera
-page.tags="photo","video","picture","mediarecorder"
+page.tags=photo,video,picture,mediarecorder
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/media/mediaplayer.jd b/docs/html/guide/topics/media/mediaplayer.jd
index dc789d2..6d03af6 100644
--- a/docs/html/guide/topics/media/mediaplayer.jd
+++ b/docs/html/guide/topics/media/mediaplayer.jd
@@ -1,5 +1,5 @@
 page.title=Media Playback
-page.tags="mediaplayer","soundpool","audiomanager"
+page.tags=mediaplayer,soundpool,audiomanager
 @jd:body
 
     <div id="qv-wrapper">
@@ -743,4 +743,4 @@
 mMediaPlayer.setDataSource(getApplicationContext(), contentUri);
 
 // ...prepare and start...
-</pre>
\ No newline at end of file
+</pre>
diff --git a/docs/html/guide/topics/resources/localization.jd b/docs/html/guide/topics/resources/localization.jd
index 7288aeb..3bb9ab5 100644
--- a/docs/html/guide/topics/resources/localization.jd
+++ b/docs/html/guide/topics/resources/localization.jd
@@ -1,487 +1,485 @@
-page.title=Localizing with Resources

-parent.title=Application Resources

-page.tags="localizing","localization","resources", "formats", "l10n"

-parent.link=index.html

-@jd:body

-

-<div id="qv-wrapper">

-    <div id="qv">

-

-<h2>Quickview</h2>

-

-<ul>

-  <li>Use resource sets to create a localized app.</li>

-  <li>Android loads the correct resource set for the user's language and locale.</li>

-  <li>If localized resources are not available, Android loads your default resources.</li>

-</ul>

-

-<h2>In this document</h2>

-<ol>

-  <li><a href="#resource-switching">Overview: Resource-Switching in Android</a></li>

-<li><a href="#using-framework">Using Resources for Localization</a></li>

-<li><a href="#strategies">Localization Tips</a></li>

-<li><a href="#testing">Testing Localized Applications</a></li>

-</ol>

-

-<h2>See also</h2>

-  <ol>

-    <li><a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization Checklist</a></li>

-    <li><a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a></li>

-    <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Layouts</a></li>

-    <li><a href="{@docRoot}reference/android/app/Activity.html#ActivityLifecycle">Activity Lifecycle</a></li>

-</ol>

-</div>

-</div>

-

-<p>Android will run on many  devices in many  regions. To reach the most users,

-your application should handle text, audio files, numbers, currency, and

-graphics in ways appropriate to the locales where your application will be used.

-</p>

-

-<p>This document describes best practices for localizing Android

-applications. The principles apply whether you are developing your application  

-using ADT with Eclipse, Ant-based tools, or any other IDE. </p>

-

-<p>You should already have a working knowledge of Java and be  familiar with

-Android resource loading, the declaration of user interface elements in XML,

-development considerations such as Activity lifecycle, and general principles of

-internationalization and localization. </p>

-

-<p>It is good practice to use the Android resource framework to separate the

-localized aspects of your application as much as possible from the core Java

-functionality:</p>

-

-<ul>

-  <li>You can put most or all of the <em>contents</em> of your application's

-user interface into resource files, as described in this document and in <a

-href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.</li>

-  <li>The <em>behavior</em> of the user interface, on the other hand, is driven

-by your Java code. 

-    For example, if users input data that needs to be formatted or sorted

-differently depending on locale, then you would use Java to handle the data

-programmatically. This document does not cover how to  localize your Java code.

-</li>

-</ul>

-

-<p>For a short guide to localizing strings in your app, see the training lesson, <a

-href="{@docRoot}training/basics/supporting-devices/languages.html">Supporting Different Languages</a>. </p>

-

-

-<h2 id="resource-switching">Overview: Resource-Switching in Android</h2>

-

-<p>Resources are text strings, layouts, sounds, graphics, and any other static

-data that your  Android application  needs. An application can include multiple

-sets of resources, each customized for a different device configuration. When a

-user runs the application,  Android    automatically selects and loads the 

-resources that best match the device.</p>

-

-<p>(This document focuses on localization and locale. For a complete description

-of resource-switching and all the types of configurations that you can

-specify &#8212; screen orientation, touchscreen type, and so on &#8212; see <a

-href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing

-Alternative Resources</a>.)</p>

-

-<table border="0" cellspacing="0" cellpadding="0">

-  <tr border="0">

-    <td width="180" style="border: 0pt none ;"><p class="special-note">

-    <strong>When you write your application:</strong>

-    <br><br>

-    You create a set of default resources, plus alternatives to be used in

-    different locales.</p></td>

-    <td style="border: 0pt none; padding:0">

-    <p style="border:0; padding:0"><img src="../../../images/resources/right-arrow.png" alt="right-arrow" 

-    width="51" height="17"></p></td>

-    <td width="180" style="border: 0pt none ;"><p class="special-note">

-    <strong>When a user runs your application:</strong>

-    <br><br>The Android system selects which resources to load, based on the

-    device's locale.</p></td>

-  </tr>

-</table>

-

-<p>When you write your application, you create default and alternative resources

-for your application to use. To create  resources, you place files within

-specially named subdirectories of the project's <code>res/</code> directory.

-</p>

-

-

-

-<h3 id="defaults-r-important">Why Default Resources Are Important</h3>

-

-<p>Whenever the application runs in a locale for which you have not provided

-locale-specific text,  Android will load the default strings from

-<code>res/values/strings.xml</code>. If this default  file is absent, or if it 

-is missing a string that your application needs, then your application will not run 

-and will show an error. 

-The example below illustrates what can happen when the default text file is incomplete. </p>

-

-<p><em>Example:</em>

-<p>An application's Java code refers to just two strings, <code>text_a</code> and 

-	<code>text_b</code>. This application includes a localized resource file 

-	(<code>res/values-en/strings.xml</code>) that defines <code>text_a</code> and 

-	<code>text_b</code> in English. This application also includes a default 

-	resource file (<code>res/values/strings.xml</code>) that includes a

-definition for <code>text_a</code>, but not for <code>text_b</code>:

-<ul>

-  <li>This application might compile without a problem. An IDE such as Eclipse 

-  	will not highlight any errors if a resource is missing.</li>

-  <li>When this application is launched on a device with locale set to English, 

-  	the application  might run without a problem, because 

-  	<code>res/values-en/strings.xml</code> contains both of the needed text 

-  	strings.</li>

-  <li>However, <strong>the user  will see an error message and a Force Close 

-  	button</strong> when this application is launched on a device set to a 

-  	language other than English. The application will not load.</li>

-</ul>

-

-

-<p>To prevent this situation, make sure that a <code>res/values/strings.xml</code> 

-	file exists and that it defines every needed string. The situation applies to 

-	all types of resources, not just strings: You 

-	need to create a  set of default resource files containing all 

-	the resources that your application calls upon &#8212; layouts, drawables, 

-	animations, etc. For information about testing, see <a href="#test-for-default">

-	Testing for Default Resources</a>.</p>

-

-<h2 id="using-framework">Using Resources for Localization</h2>

-

-<h3 id="creating-defaults">How to Create Default Resources</h3>

-

-<p>Put the application's default text in

-a file with the following location and name:</p>

-<p><code>&nbsp;&nbsp;&nbsp;&nbsp;res/values/strings.xml</code> (required directory)</p>

-

-<p>The text strings in <code>res/values/strings.xml</code> should  use the

-default language, which is the language that you expect most of your application's users to

-speak.  </p>

-

-<p>The default resource set must also include any default drawables and layouts, 

-	and can include other types of resources such as animations. 

-<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/drawable/</code>(required directory holding at least

-  one graphic file, for the application's icon on Google Play)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/layout/</code> (required directory holding an XML

-  file that defines the default layout)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/anim/</code> (required if you have any 

-  <code>res/anim-<em>&lt;qualifiers&gt;</em></code> folders)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/xml/</code> (required if you have any 

-  <code>res/xml-<em>&lt;qualifiers&gt;</em></code> folders)<br>

-  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/raw/</code> (required if you have any 

-  <code>res/raw-<em>&lt;qualifiers&gt;</em></code> folders)

-</p>

-

-<p class="note"><strong>Tip:</strong> In your code, examine each reference to 

-	an Android resource. Make sure that a default resource is defined for each

-	one. Also make sure that the default string file is complete: A <em>

-	localized</em> string file can contain a subset of the strings, but the 

-	<em>default</em> string file must contain them all. 

-</p>

-

-<h3 id="creating-alternatives">How to Create Alternative Resources</h3>

-

-<p>A large part of localizing an application is providing alternative text for

-different languages. In some cases you will also provide alternative graphics,

-sounds, layouts, and other locale-specific resources. </p>

-

-<p>An application can specify many <code>res/<em>&lt;qualifiers&gt;</em>/</code>

-directories, each with different qualifiers. To create an alternative resource for

-a different locale, you use a qualifier that specifies a language or a 

-language-region combination. (The name of a resource directory must conform 

-to the naming scheme described in 

-<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing

-Alternative Resources</a>,

-or else it will not compile.)</p>

-

-<p><em>Example:</em></p>

-

-<p>Suppose that your application's default language is English. Suppose also

-that you want to localize all the text in your application to French, and most

-of the text in your application (everything except the application's title) to

-Japanese. In this case, you could create three alternative <code>strings.xml</code>

-files, each stored in a locale-specific resource directory:</p>

-

-<ol>

-  <li><code>res/values/strings.xml</code><br>

-    Contains  English text for all  the strings that the application uses,

-including text for a string named <code>title</code>.</li>

-  <li><code>res/values-fr/strings.xml</code><br>

-    Contain French text for all  the strings, including <code>title</code>.</li>

-  <li><code>res/values-ja/strings.xml</code><br>

-    Contain Japanese text for all  the strings <em>except</em>

-<code>title</code>.<br>

-  <code></code></li>

-</ol>

-

-<p>If your Java code refers to <code>R.string.title</code>,  here is what will

-happen at runtime:</p>

-

-<ul>

-  <li>If the device is set to any language other than French, Android will load

-<code>title</code> from the <code>res/values/strings.xml</code> file.</li>

-  <li>If the device is set to French, Android will load <code>title</code> from

-the <code>res/values-fr/strings.xml</code> file.</li>

-</ul>

-

-<p>Notice that if the device is set to Japanese, Android will look for

-<code>title</code> in the <code>res/values-ja/strings.xml</code> file. But

-because no such string is included in that file, Android will fall back to the

-default, and will load  <code>title</code> in English from the

-<code>res/values/strings.xml</code> file.  </p>

-

-<h3 id="resource-precedence">Which Resources Take Precedence?</h3>

-

-<p> If multiple resource files match a device's configuration, Android follows a

-set of rules in deciding which file to use. Among the qualifiers that can be

-specified in a resource directory name, <strong>locale almost always takes

-precedence</strong>. </p>

-<p><em>Example:</em></p>

-

-<p>Assume that an application  includes a default set of graphics and two other

-sets of graphics, each optimized for a different device setup:</p>

-

-<ul>

-  <li><code>res/drawable/</code><br>

-    Contains

-  default graphics.</li>

-  <li><code>res/drawable-small-land-stylus/</code><br>

-  Contains  graphics optimized for use with a device that expects input from a 

-  stylus and has a QVGA low-density screen in landscape orientation.</li>

-  <li><code>res/drawable-ja/</code> <br>

-  Contains  graphics optimized for use with Japanese.</li>

-</ul>

-

-<p>If the application runs on a device that is configured to use Japanese,

-Android will load graphics from  <code>res/drawable-ja/</code>, even if the

-device happens to be one that expects input from a stylus and has a QVGA 

-low-density screen in landscape orientation.</p>

-

-<p class="note"><strong>Exception:</strong> The only qualifiers that take

-precedence over locale in the selection process are MCC and MNC (mobile country

-code and mobile network code). </p>

-

-<p><em>Example:</em></p>

-

-<p>Assume that you have the following situation:</p>

-

-<ul>

-  <li>The application code calls for <code>R.string.text_a</code></li>

-  <li>Two relevant resource files are available:

-    <ul>

-      <li><code>res/values-mcc404/strings.xml</code>, which includes

-<code>text_a</code> in the application's default language, in this case

-English.</li>

-      <li><code>res/values-hi/strings.xml</code>, which includes

-<code>text_a</code> in Hindi.</li>

-    </ul>

-  </li>

-  <li>The application is running on a device that has the following

-configuration:

-    <ul>

-      <li>The SIM card is connected to a mobile network in India (MCC 404).</li>

-      <li>The language is set to Hindi (<code>hi</code>).</li>

-    </ul>

-  </li>

-</ul>

-

-<p>Android will load <code>text_a</code> from

-<code>res/values-mcc404/strings.xml</code> (in English), even if the device is

-configured for Hindi. That is because in the resource-selection process, Android

-will prefer an MCC match over a language match. </p>

-

-<p>The selection process is not always as straightforward as these examples

-suggest. Please read  <a

-href="{@docRoot}guide/topics/resources/providing-resources.html#BestMatch">How Android Finds

-the Best-matching Resource</a> for a more nuanced description of the

-process. All the qualifiers are described and listed in order of

-precedence in <a

-href="{@docRoot}guide/topics/resources/providing-resources.html#table2">Table 2 of Providing

-Alternative Resources</a>.</p>

-

-<h3 id="referring-to-resources">Referring to Resources in Java</h3>

-

-<p>In your application's Java code, you refer to  resources using the syntax

-<code>R.<em>resource_type</em>.<em>resource_name</em></code> or

-<code>android.R.<em>resource_type</em>.<em>resource_name</em></code><em>.</em>

-For more about this, see <a

-href="{@docRoot}guide/topics/resources/accessing-resources.html">Accessing Resources</a>.</p>

-

-<h2 id="checklist">Localization Checklist</h2>

-

-<p>For a complete overview of the process of localizing and distributing an Android application,

-see the <a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization

-Checklist</a> document.</p>

-

-<h2 id="strategies">Localization Tips</h2>

-

-<h4 id="failing2">Design your application  to work in any locale</h4>

-

-<p>You cannot assume anything about the device on which a user will

-run your application. The device might have hardware that you were not

-anticipating, or it might be set to a locale that you did not plan for or that 

-you cannot test. Design your application so that it will function normally or fail gracefully no 

-matter what device it runs on.</p>

-

-<p class="note"><strong>Important:</strong> Make sure that your application

-includes a full set of default resources.</p> <p>Make sure to include

-<code>res/drawable/</code> and a <code>res/values/</code> folders (without any

-additional modifiers in the folder names) that contain all the images and text

-that your application will need. </p>

-

-<p>If an application is missing even one default resource, it will not run on a 

-	device that is set to an unsupported locale. For example, the 

-	<code>res/values/strings.xml</code> default file might lack one string that 

-	the application needs: When the application runs in an unsupported locale and 

-	attempts to load <code>res/values/strings.xml</code>, the user will see an 

-	error message and a Force Close button. An IDE such as Eclipse will not 

-	highlight this kind of error, and you will not see the problem when you 

-	test the application on a device or emulator that is set to a supported locale.</p>

-

-<p>For more information, see <a href="#test-for-default">Testing for Default Resources</a>.</p>

-

-<h4>Design a flexible layout</h4>

-

-<p> If you need to rearrange your layout to fit a certain language (for example

-German with its long words), you can create an alternative layout for that

-language (for example <code>res/layout-de/main.xml</code>). However, doing this

-can make your application harder to maintain.  It is better to create a single

-layout that is more flexible.</p>

-

-<p>Another typical situation is a language that requires something different in

-its layout. For example, you might have a contact form that should include  two

-name fields when the application runs in Japanese, but three name fields when

-the application  runs in some other language. You could handle this in either of

-two ways:</p>

-

-<ul>

-  <li>Create  one  layout with a field that you can programmatically enable or

-disable, based on the language, or</li>

-  <li>Have the main layout include another layout that  includes the changeable

-field. The second layout can have different configurations for different

-languages.</li>

-</ul>

-

-<h4>Avoid creating more resource files and text strings than you need</h4>

-

-<p>You probably do not need to create a locale-specific

-alternative for every resource in your application. For example, the layout

-defined in the <code>res/layout/main.xml</code> file might work in any locale,

-in which case there would be no need to create any alternative layout files.

-</p>

-

-<p>Also, you might not need to create alternative text for every

-string. For example, assume the following:</p>

-

-<ul>

-  <li>Your application's default language is American

-English. Every string that the application uses is defined, using American

-English spellings, in <code>res/values/strings.xml</code>. </li>

-

-  <li>For  a few important phrases, you want to provide

-British English spelling. You want these alternative strings to be used when your

-application runs on a device in the United Kingdom. </li>

-</ul>

-

-<p>To do this, you could create a small file called

-<code>res/values-en-rGB/strings.xml</code> that includes only the strings that

-should be different when the application  runs in the U.K. For all the rest of

-the strings, the application will fall back to the defaults and use what is

-defined in <code>res/values/strings.xml</code>.</p>

-

-<h4>Use the Android Context object for manual locale lookup</h4>

-

-<p>You can look up the locale using the {@link android.content.Context} object

-that Android makes available:</p>

-

-<pre>String locale = context.getResources().getConfiguration().locale.getDisplayName();</pre>

-

-<h2 id="testing">Testing Localized Applications</h2>

-

-<h3 id="device">Testing on a Device</h3>

-<p>Keep in mind that the device you are testing may be significantly different from 

-	the devices available to consumers in other geographies. The locales available 

-	on your device may differ from those available on other devices. Also, the 

-	resolution and density of the device screen may differ, which could affect 

-	the display of strings and drawables in your UI.</p>

-

-<p>To change the locale on a device, use  the Settings application  (Home &gt;

-Menu &gt; Settings &gt; Locale &amp; text &gt; Select locale). </p>

-

-<h3 id="emulator">Testing on an Emulator</h3>

-

-<p>For details about using the emulator, see See <a

-href="{@docRoot}tools/help/emulator.html">Android Emulator</a>.</p>

-<h4>Creating and using a custom locale</h4>

-

-<p>A &quot;custom&quot; locale is a language/region combination that the Android

-system image does not explicitly support. (For a list of supported locales in

-Android platforms see the Version Notes in the <a

-href="{@docRoot}sdk/index.html">SDK</a> tab). You can test

-how your application will run in a custom locale by creating a custom locale in

-the emulator. There are two ways to do this:</p>

-

-<ul>

-  <li>Use the Custom Locale application, which is accessible from the

-Application tab. (After you create a custom locale, switch to it by 

-pressing and holding the locale name.)</li>

-  <li>Change to a custom locale from the adb shell, as described below.</li>

-</ul>

-

-<p>When you set the emulator to a locale that is not available in the Android

-system image, the system itself will display in its default language. Your

-application, however, should localize properly.</p>

-

-<h4>Changing the emulator locale from the adb shell</h4>

-

-<p>To change the locale in the emulator by using the adb shell. </p>

-

-<ol>

-  <li>Pick the locale you want to test and determine its language and region codes, for

-example <code>fr</code> for French and <code>CA</code> for Canada.<br>

-  </li>

-  <li>Launch an emulator.</li>

-  <li>From a command-line shell on the host computer, run the following

-command:<br>

-    <code>adb shell</code><br>

-  or if you have a device attached, specify that you want the emulator by adding

-the <code>-e</code> option:<br>

-  <code>adb -e shell</code></li>

-  <li>At  the  adb shell prompt (<code>#</code>), run this command: <br>

-    <code>setprop persist.sys.language  [<em>language code</em>];setprop

-persist.sys.country [<em>country  code</em>];stop;sleep 5;start <br>

-    </code>Replace bracketed sections with the  appropriate codes from Step

-1.</li>

-</ol>

-

-<p>For instance, to test in Canadian French:</p>

-

-<p><code>setprop persist.sys.language  fr;setprop persist.sys.country

-CA;stop;sleep 5;start </code></p>

-

-<p>This will cause the emulator  to restart. (It will look like a full reboot,

-but it is not.) Once the Home screen appears again, re-launch your application (for

-example, click the Run icon in Eclipse), and the application will launch with

-the new locale. </p>

-

-<h3 id="test-for-default">Testing for Default Resources</h3>

-<p>Here's how to test whether an application includes every string resource that it needs:  </p>

-<ol><li>Set the emulator or device to a language that your application does not 

-	support. For example, if the application has French strings in 

-	<code>res/values-fr/</code> but does not have any Spanish strings in 

-	<code>res/values-es/</code>, then set the emulator's locale to Spanish. 

-	(You can use the Custom Locale application to set the emulator to an 

-	unsupported locale.)</li>

-	<li>Run the application.</li>  

-<li>If the application shows an error message and a Force Close button, it might 

-	be looking for a string that is not available. Make sure that your 

-	<code>res/values/strings.xml</code> file includes a definition for 

-	every string that the application uses.</li>

-</ol> 

-</p> 

-

-<p>If the test is successful, repeat it for other types of 

-	configurations. For example, if the application has a layout file called 

-	<code>res/layout-land/main.xml</code> but does not contain a file called 

-	<code>res/layout-port/main.xml</code>, then set the emulator or device to 

-	portrait orientation and see if the application will run. 

-

-

-

+page.title=Localizing with Resources
+parent.title=Application Resources
+page.tags=localizing,localization,resources,formats,l10n
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+    <div id="qv">
+
+<h2>Quickview</h2>
+
+<ul>
+  <li>Use resource sets to create a localized app.</li>
+  <li>Android loads the correct resource set for the user's language and locale.</li>
+  <li>If localized resources are not available, Android loads your default resources.</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#resource-switching">Overview: Resource-Switching in Android</a></li>
+<li><a href="#using-framework">Using Resources for Localization</a></li>
+<li><a href="#strategies">Localization Tips</a></li>
+<li><a href="#testing">Testing Localized Applications</a></li>
+</ol>
+
+<h2>See also</h2>
+  <ol>
+    <li><a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization Checklist</a></li>
+    <li><a href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a></li>
+    <li><a href="{@docRoot}guide/topics/ui/declaring-layout.html">Layouts</a></li>
+    <li><a href="{@docRoot}reference/android/app/Activity.html#ActivityLifecycle">Activity Lifecycle</a></li>
+</ol>
+</div>
+</div>
+
+<p>Android will run on many  devices in many  regions. To reach the most users,
+your application should handle text, audio files, numbers, currency, and
+graphics in ways appropriate to the locales where your application will be used.
+</p>
+
+<p>This document describes best practices for localizing Android
+applications. The principles apply whether you are developing your application
+using ADT with Eclipse, Ant-based tools, or any other IDE. </p>
+
+<p>You should already have a working knowledge of Java and be  familiar with
+Android resource loading, the declaration of user interface elements in XML,
+development considerations such as Activity lifecycle, and general principles of
+internationalization and localization. </p>
+
+<p>It is good practice to use the Android resource framework to separate the
+localized aspects of your application as much as possible from the core Java
+functionality:</p>
+
+<ul>
+  <li>You can put most or all of the <em>contents</em> of your application's
+user interface into resource files, as described in this document and in <a
+href="{@docRoot}guide/topics/resources/providing-resources.html">Providing Resources</a>.</li>
+  <li>The <em>behavior</em> of the user interface, on the other hand, is driven
+by your Java code.
+    For example, if users input data that needs to be formatted or sorted
+differently depending on locale, then you would use Java to handle the data
+programmatically. This document does not cover how to  localize your Java code.
+</li>
+</ul>
+
+<p>For a short guide to localizing strings in your app, see the training lesson, <a
+href="{@docRoot}training/basics/supporting-devices/languages.html">Supporting Different Languages</a>. </p>
+
+
+<h2 id="resource-switching">Overview: Resource-Switching in Android</h2>
+
+<p>Resources are text strings, layouts, sounds, graphics, and any other static
+data that your  Android application  needs. An application can include multiple
+sets of resources, each customized for a different device configuration. When a
+user runs the application,  Android    automatically selects and loads the
+resources that best match the device.</p>
+
+<p>(This document focuses on localization and locale. For a complete description
+of resource-switching and all the types of configurations that you can
+specify &#8212; screen orientation, touchscreen type, and so on &#8212; see <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing
+Alternative Resources</a>.)</p>
+
+<table border="0" cellspacing="0" cellpadding="0">
+  <tr border="0">
+    <td width="180" style="border: 0pt none ;"><p class="special-note">
+    <strong>When you write your application:</strong>
+    <br><br>
+    You create a set of default resources, plus alternatives to be used in
+    different locales.</p></td>
+    <td style="border: 0pt none; padding:0">
+    <p style="border:0; padding:0"><img src="../../../images/resources/right-arrow.png" alt="right-arrow"
+    width="51" height="17"></p></td>
+    <td width="180" style="border: 0pt none ;"><p class="special-note">
+    <strong>When a user runs your application:</strong>
+    <br><br>The Android system selects which resources to load, based on the
+    device's locale.</p></td>
+  </tr>
+</table>
+
+<p>When you write your application, you create default and alternative resources
+for your application to use. To create  resources, you place files within
+specially named subdirectories of the project's <code>res/</code> directory.
+</p>
+
+
+
+<h3 id="defaults-r-important">Why Default Resources Are Important</h3>
+
+<p>Whenever the application runs in a locale for which you have not provided
+locale-specific text,  Android will load the default strings from
+<code>res/values/strings.xml</code>. If this default  file is absent, or if it
+is missing a string that your application needs, then your application will not run
+and will show an error.
+The example below illustrates what can happen when the default text file is incomplete. </p>
+
+<p><em>Example:</em>
+<p>An application's Java code refers to just two strings, <code>text_a</code> and
+  <code>text_b</code>. This application includes a localized resource file
+  (<code>res/values-en/strings.xml</code>) that defines <code>text_a</code> and
+  <code>text_b</code> in English. This application also includes a default
+  resource file (<code>res/values/strings.xml</code>) that includes a
+definition for <code>text_a</code>, but not for <code>text_b</code>:
+<ul>
+  <li>This application might compile without a problem. An IDE such as Eclipse
+    will not highlight any errors if a resource is missing.</li>
+  <li>When this application is launched on a device with locale set to English,
+    the application  might run without a problem, because
+    <code>res/values-en/strings.xml</code> contains both of the needed text
+    strings.</li>
+  <li>However, <strong>the user  will see an error message and a Force Close
+    button</strong> when this application is launched on a device set to a
+    language other than English. The application will not load.</li>
+</ul>
+
+
+<p>To prevent this situation, make sure that a <code>res/values/strings.xml</code>
+  file exists and that it defines every needed string. The situation applies to
+  all types of resources, not just strings: You
+  need to create a  set of default resource files containing all
+  the resources that your application calls upon &#8212; layouts, drawables,
+  animations, etc. For information about testing, see <a href="#test-for-default">
+  Testing for Default Resources</a>.</p>
+
+<h2 id="using-framework">Using Resources for Localization</h2>
+
+<h3 id="creating-defaults">How to Create Default Resources</h3>
+
+<p>Put the application's default text in
+a file with the following location and name:</p>
+<p><code>&nbsp;&nbsp;&nbsp;&nbsp;res/values/strings.xml</code> (required directory)</p>
+
+<p>The text strings in <code>res/values/strings.xml</code> should  use the
+default language, which is the language that you expect most of your application's users to
+speak.  </p>
+
+<p>The default resource set must also include any default drawables and layouts,
+  and can include other types of resources such as animations.
+<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/drawable/</code>(required directory holding at least
+  one graphic file, for the application's icon on Google Play)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/layout/</code> (required directory holding an XML
+  file that defines the default layout)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/anim/</code> (required if you have any
+  <code>res/anim-<em>&lt;qualifiers&gt;</em></code> folders)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/xml/</code> (required if you have any
+  <code>res/xml-<em>&lt;qualifiers&gt;</em></code> folders)<br>
+  <code>&nbsp;&nbsp;&nbsp;&nbsp;res/raw/</code> (required if you have any
+  <code>res/raw-<em>&lt;qualifiers&gt;</em></code> folders)
+</p>
+
+<p class="note"><strong>Tip:</strong> In your code, examine each reference to
+  an Android resource. Make sure that a default resource is defined for each
+  one. Also make sure that the default string file is complete: A <em>
+  localized</em> string file can contain a subset of the strings, but the
+  <em>default</em> string file must contain them all.
+</p>
+
+<h3 id="creating-alternatives">How to Create Alternative Resources</h3>
+
+<p>A large part of localizing an application is providing alternative text for
+different languages. In some cases you will also provide alternative graphics,
+sounds, layouts, and other locale-specific resources. </p>
+
+<p>An application can specify many <code>res/<em>&lt;qualifiers&gt;</em>/</code>
+directories, each with different qualifiers. To create an alternative resource for
+a different locale, you use a qualifier that specifies a language or a
+language-region combination. (The name of a resource directory must conform
+to the naming scheme described in
+<a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">Providing
+Alternative Resources</a>,
+or else it will not compile.)</p>
+
+<p><em>Example:</em></p>
+
+<p>Suppose that your application's default language is English. Suppose also
+that you want to localize all the text in your application to French, and most
+of the text in your application (everything except the application's title) to
+Japanese. In this case, you could create three alternative <code>strings.xml</code>
+files, each stored in a locale-specific resource directory:</p>
+
+<ol>
+  <li><code>res/values/strings.xml</code><br>
+    Contains  English text for all  the strings that the application uses,
+including text for a string named <code>title</code>.</li>
+  <li><code>res/values-fr/strings.xml</code><br>
+    Contain French text for all  the strings, including <code>title</code>.</li>
+  <li><code>res/values-ja/strings.xml</code><br>
+    Contain Japanese text for all  the strings <em>except</em>
+<code>title</code>.<br>
+  <code></code></li>
+</ol>
+
+<p>If your Java code refers to <code>R.string.title</code>,  here is what will
+happen at runtime:</p>
+
+<ul>
+  <li>If the device is set to any language other than French, Android will load
+<code>title</code> from the <code>res/values/strings.xml</code> file.</li>
+  <li>If the device is set to French, Android will load <code>title</code> from
+the <code>res/values-fr/strings.xml</code> file.</li>
+</ul>
+
+<p>Notice that if the device is set to Japanese, Android will look for
+<code>title</code> in the <code>res/values-ja/strings.xml</code> file. But
+because no such string is included in that file, Android will fall back to the
+default, and will load  <code>title</code> in English from the
+<code>res/values/strings.xml</code> file.  </p>
+
+<h3 id="resource-precedence">Which Resources Take Precedence?</h3>
+
+<p> If multiple resource files match a device's configuration, Android follows a
+set of rules in deciding which file to use. Among the qualifiers that can be
+specified in a resource directory name, <strong>locale almost always takes
+precedence</strong>. </p>
+<p><em>Example:</em></p>
+
+<p>Assume that an application  includes a default set of graphics and two other
+sets of graphics, each optimized for a different device setup:</p>
+
+<ul>
+  <li><code>res/drawable/</code><br>
+    Contains
+  default graphics.</li>
+  <li><code>res/drawable-small-land-stylus/</code><br>
+  Contains  graphics optimized for use with a device that expects input from a
+  stylus and has a QVGA low-density screen in landscape orientation.</li>
+  <li><code>res/drawable-ja/</code> <br>
+  Contains  graphics optimized for use with Japanese.</li>
+</ul>
+
+<p>If the application runs on a device that is configured to use Japanese,
+Android will load graphics from  <code>res/drawable-ja/</code>, even if the
+device happens to be one that expects input from a stylus and has a QVGA
+low-density screen in landscape orientation.</p>
+
+<p class="note"><strong>Exception:</strong> The only qualifiers that take
+precedence over locale in the selection process are MCC and MNC (mobile country
+code and mobile network code). </p>
+
+<p><em>Example:</em></p>
+
+<p>Assume that you have the following situation:</p>
+
+<ul>
+  <li>The application code calls for <code>R.string.text_a</code></li>
+  <li>Two relevant resource files are available:
+    <ul>
+      <li><code>res/values-mcc404/strings.xml</code>, which includes
+<code>text_a</code> in the application's default language, in this case
+English.</li>
+      <li><code>res/values-hi/strings.xml</code>, which includes
+<code>text_a</code> in Hindi.</li>
+    </ul>
+  </li>
+  <li>The application is running on a device that has the following
+configuration:
+    <ul>
+      <li>The SIM card is connected to a mobile network in India (MCC 404).</li>
+      <li>The language is set to Hindi (<code>hi</code>).</li>
+    </ul>
+  </li>
+</ul>
+
+<p>Android will load <code>text_a</code> from
+<code>res/values-mcc404/strings.xml</code> (in English), even if the device is
+configured for Hindi. That is because in the resource-selection process, Android
+will prefer an MCC match over a language match. </p>
+
+<p>The selection process is not always as straightforward as these examples
+suggest. Please read  <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#BestMatch">How Android Finds
+the Best-matching Resource</a> for a more nuanced description of the
+process. All the qualifiers are described and listed in order of
+precedence in <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#table2">Table 2 of Providing
+Alternative Resources</a>.</p>
+
+<h3 id="referring-to-resources">Referring to Resources in Java</h3>
+
+<p>In your application's Java code, you refer to  resources using the syntax
+<code>R.<em>resource_type</em>.<em>resource_name</em></code> or
+<code>android.R.<em>resource_type</em>.<em>resource_name</em></code><em>.</em>
+For more about this, see <a
+href="{@docRoot}guide/topics/resources/accessing-resources.html">Accessing Resources</a>.</p>
+
+<h2 id="checklist">Localization Checklist</h2>
+
+<p>For a complete overview of the process of localizing and distributing an Android application,
+see the <a href="{@docRoot}distribute/googleplay/publish/localizing.html">Localization
+Checklist</a> document.</p>
+
+<h2 id="strategies">Localization Tips</h2>
+
+<h4 id="failing2">Design your application  to work in any locale</h4>
+
+<p>You cannot assume anything about the device on which a user will
+run your application. The device might have hardware that you were not
+anticipating, or it might be set to a locale that you did not plan for or that
+you cannot test. Design your application so that it will function normally or fail gracefully no
+matter what device it runs on.</p>
+
+<p class="note"><strong>Important:</strong> Make sure that your application
+includes a full set of default resources.</p> <p>Make sure to include
+<code>res/drawable/</code> and a <code>res/values/</code> folders (without any
+additional modifiers in the folder names) that contain all the images and text
+that your application will need. </p>
+
+<p>If an application is missing even one default resource, it will not run on a
+  device that is set to an unsupported locale. For example, the
+  <code>res/values/strings.xml</code> default file might lack one string that
+  the application needs: When the application runs in an unsupported locale and
+  attempts to load <code>res/values/strings.xml</code>, the user will see an
+  error message and a Force Close button. An IDE such as Eclipse will not
+  highlight this kind of error, and you will not see the problem when you
+  test the application on a device or emulator that is set to a supported locale.</p>
+
+<p>For more information, see <a href="#test-for-default">Testing for Default Resources</a>.</p>
+
+<h4>Design a flexible layout</h4>
+
+<p> If you need to rearrange your layout to fit a certain language (for example
+German with its long words), you can create an alternative layout for that
+language (for example <code>res/layout-de/main.xml</code>). However, doing this
+can make your application harder to maintain.  It is better to create a single
+layout that is more flexible.</p>
+
+<p>Another typical situation is a language that requires something different in
+its layout. For example, you might have a contact form that should include  two
+name fields when the application runs in Japanese, but three name fields when
+the application  runs in some other language. You could handle this in either of
+two ways:</p>
+
+<ul>
+  <li>Create  one  layout with a field that you can programmatically enable or
+disable, based on the language, or</li>
+  <li>Have the main layout include another layout that  includes the changeable
+field. The second layout can have different configurations for different
+languages.</li>
+</ul>
+
+<h4>Avoid creating more resource files and text strings than you need</h4>
+
+<p>You probably do not need to create a locale-specific
+alternative for every resource in your application. For example, the layout
+defined in the <code>res/layout/main.xml</code> file might work in any locale,
+in which case there would be no need to create any alternative layout files.
+</p>
+
+<p>Also, you might not need to create alternative text for every
+string. For example, assume the following:</p>
+
+<ul>
+  <li>Your application's default language is American
+English. Every string that the application uses is defined, using American
+English spellings, in <code>res/values/strings.xml</code>. </li>
+
+  <li>For  a few important phrases, you want to provide
+British English spelling. You want these alternative strings to be used when your
+application runs on a device in the United Kingdom. </li>
+</ul>
+
+<p>To do this, you could create a small file called
+<code>res/values-en-rGB/strings.xml</code> that includes only the strings that
+should be different when the application  runs in the U.K. For all the rest of
+the strings, the application will fall back to the defaults and use what is
+defined in <code>res/values/strings.xml</code>.</p>
+
+<h4>Use the Android Context object for manual locale lookup</h4>
+
+<p>You can look up the locale using the {@link android.content.Context} object
+that Android makes available:</p>
+
+<pre>String locale = context.getResources().getConfiguration().locale.getDisplayName();</pre>
+
+<h2 id="testing">Testing Localized Applications</h2>
+
+<h3 id="device">Testing on a Device</h3>
+<p>Keep in mind that the device you are testing may be significantly different from
+  the devices available to consumers in other geographies. The locales available
+  on your device may differ from those available on other devices. Also, the
+  resolution and density of the device screen may differ, which could affect
+  the display of strings and drawables in your UI.</p>
+
+<p>To change the locale on a device, use  the Settings application  (Home &gt;
+Menu &gt; Settings &gt; Locale &amp; text &gt; Select locale). </p>
+
+<h3 id="emulator">Testing on an Emulator</h3>
+
+<p>For details about using the emulator, see See <a
+href="{@docRoot}tools/help/emulator.html">Android Emulator</a>.</p>
+<h4>Creating and using a custom locale</h4>
+
+<p>A &quot;custom&quot; locale is a language/region combination that the Android
+system image does not explicitly support. (For a list of supported locales in
+Android platforms see the Version Notes in the <a
+href="{@docRoot}sdk/index.html">SDK</a> tab). You can test
+how your application will run in a custom locale by creating a custom locale in
+the emulator. There are two ways to do this:</p>
+
+<ul>
+  <li>Use the Custom Locale application, which is accessible from the
+Application tab. (After you create a custom locale, switch to it by
+pressing and holding the locale name.)</li>
+  <li>Change to a custom locale from the adb shell, as described below.</li>
+</ul>
+
+<p>When you set the emulator to a locale that is not available in the Android
+system image, the system itself will display in its default language. Your
+application, however, should localize properly.</p>
+
+<h4>Changing the emulator locale from the adb shell</h4>
+
+<p>To change the locale in the emulator by using the adb shell. </p>
+
+<ol>
+  <li>Pick the locale you want to test and determine its language and region codes, for
+example <code>fr</code> for French and <code>CA</code> for Canada.<br>
+  </li>
+  <li>Launch an emulator.</li>
+  <li>From a command-line shell on the host computer, run the following
+command:<br>
+    <code>adb shell</code><br>
+  or if you have a device attached, specify that you want the emulator by adding
+the <code>-e</code> option:<br>
+  <code>adb -e shell</code></li>
+  <li>At  the  adb shell prompt (<code>#</code>), run this command: <br>
+    <code>setprop persist.sys.language  [<em>language code</em>];setprop
+persist.sys.country [<em>country  code</em>];stop;sleep 5;start <br>
+    </code>Replace bracketed sections with the  appropriate codes from Step
+1.</li>
+</ol>
+
+<p>For instance, to test in Canadian French:</p>
+
+<p><code>setprop persist.sys.language  fr;setprop persist.sys.country
+CA;stop;sleep 5;start </code></p>
+
+<p>This will cause the emulator  to restart. (It will look like a full reboot,
+but it is not.) Once the Home screen appears again, re-launch your application (for
+example, click the Run icon in Eclipse), and the application will launch with
+the new locale. </p>
+
+<h3 id="test-for-default">Testing for Default Resources</h3>
+<p>Here's how to test whether an application includes every string resource that it needs:  </p>
+<ol><li>Set the emulator or device to a language that your application does not
+  support. For example, if the application has French strings in
+  <code>res/values-fr/</code> but does not have any Spanish strings in
+  <code>res/values-es/</code>, then set the emulator's locale to Spanish.
+  (You can use the Custom Locale application to set the emulator to an
+  unsupported locale.)</li>
+  <li>Run the application.</li>
+<li>If the application shows an error message and a Force Close button, it might
+  be looking for a string that is not available. Make sure that your
+  <code>res/values/strings.xml</code> file includes a definition for
+  every string that the application uses.</li>
+</ol>
+</p>
+
+<p>If the test is successful, repeat it for other types of
+  configurations. For example, if the application has a layout file called
+  <code>res/layout-land/main.xml</code> but does not contain a file called
+  <code>res/layout-port/main.xml</code>, then set the emulator or device to
+  portrait orientation and see if the application will run.
+
diff --git a/docs/html/guide/topics/resources/runtime-changes.jd b/docs/html/guide/topics/resources/runtime-changes.jd
index d074873..0e03fe0 100644
--- a/docs/html/guide/topics/resources/runtime-changes.jd
+++ b/docs/html/guide/topics/resources/runtime-changes.jd
@@ -1,5 +1,5 @@
 page.title=Handling Runtime Changes
-page.tags="activity","lifecycle"
+page.tags=activity,lifecycle
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/search/adding-custom-suggestions.jd b/docs/html/guide/topics/search/adding-custom-suggestions.jd
index 47ad2fe..6ebef08 100644
--- a/docs/html/guide/topics/search/adding-custom-suggestions.jd
+++ b/docs/html/guide/topics/search/adding-custom-suggestions.jd
@@ -1,5 +1,5 @@
 page.title=Adding Custom Suggestions
-page.tags="SearchRecentSuggestionsProvider",
+page.tags=SearchRecentSuggestionsProvider,
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
index c1d59d4..e1020dd 100644
--- a/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
+++ b/docs/html/guide/topics/search/adding-recent-query-suggestions.jd
@@ -1,5 +1,5 @@
 page.title=Adding Recent Query Suggestions
-page.tags="SearchRecentSuggestions","SearchRecentSuggestionsProvider"
+page.tags=SearchRecentSuggestions,SearchRecentSuggestionsProvider
 
 @jd:body
 
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index fc722b2..fcaaed36 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -1,5 +1,5 @@
 page.title=Creating a Search Interface
-page.tags="searchview"
+page.tags=searchview
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/sensors/index.jd b/docs/html/guide/topics/sensors/index.jd
index 65560e6..09d27e7 100644
--- a/docs/html/guide/topics/sensors/index.jd
+++ b/docs/html/guide/topics/sensors/index.jd
@@ -1,6 +1,6 @@
 page.title=Location and Sensors APIs
 page.landing=true
-page.tags="location","sensors"
+page.tags=location,sensors
 page.landing.intro=Use sensors on the device to add rich location and motion capabilities to your app, from GPS or network location to accelerometer, gyroscope, temperature, barometer, and more. 
 page.landing.image=
 
@@ -38,4 +38,4 @@
     </a>
   </div>
 
-</div>
\ No newline at end of file
+</div>
diff --git a/docs/html/guide/topics/sensors/sensors_motion.jd b/docs/html/guide/topics/sensors/sensors_motion.jd
index 945f8a6..99b689f 100644
--- a/docs/html/guide/topics/sensors/sensors_motion.jd
+++ b/docs/html/guide/topics/sensors/sensors_motion.jd
@@ -1,5 +1,5 @@
 page.title=Motion Sensors
-page.tags="sensorevent","accelerometer","gyroscope","gravity","rotation","stepcounter"
+page.tags=sensorevent,accelerometer,gyroscope,gravity,rotation
 @jd:body
 
 <div id="qv-wrapper">
@@ -11,9 +11,6 @@
       <li><a href="#sensors-motion-gyro">Using the Gyroscope</a></li>
       <li><a href="#sensors-motion-linear">Using the Linear Accelerometer</a></li>
       <li><a href="#sensors-motion-rotate">Using the Rotation Vector Sensor</a></li>
-      <li><a href="#sensors-motion-significant">Using the Significant Motion Sensor</a></li>
-      <li><a href="#sensors-motion-stepcounter">Using the Step Counter Sensor</a></li>
-      <li><a href="#sensors-motion-stepdetector">Using the Step Detector Sensor</a></li>
     </ol>
     <h2>Key classes and interfaces</h2>
     <ol>
@@ -50,7 +47,7 @@
 rotation vector sensors). For example, on some devices the software-based sensors derive their data
 from the accelerometer and magnetometer, but on other devices they may also use the gyroscope to
 derive their data. Most Android-powered devices have an accelerometer, and many now
-include a gyroscope. The availability of the software-based sensors is more variable because they
+include a gyroscope. The availability of the softare-based sensors is more variable because they
 often rely on one or more hardware sensors to derive their data.</p>
 
 <p>Motion sensors are useful for monitoring device movement, such as tilt, shake, rotation, or
@@ -124,32 +121,6 @@
     <td>Rate of rotation around the z axis.</td>
   </tr>
   <tr>
-    <td rowspan="6">{@link android.hardware.Sensor#TYPE_GYROSCOPE_UNCALIBRATED}</td>
-    <td><code>SensorEvent.values[0]</code></td>
-    <td>Rate of rotation (without drift compensation) around the x axis.</td>
-    <td rowspan="6">rad/s</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[1]</code></td>
-    <td>Rate of rotation (without drift compensation) around the y axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[2]</code></td>
-    <td>Rate of rotation (without drift compensation) around the z axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[3]</code></td>
-    <td>Estimated drift around the x axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[4]</code></td>
-    <td>Estimated drift around the y axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[5]</code></td>
-    <td>Estimated drift around the z axis.</td>
-  </tr>
-  <tr>
     <td rowspan="3">{@link android.hardware.Sensor#TYPE_LINEAR_ACCELERATION}</td>
     <td><code>SensorEvent.values[0]</code></td>
     <td>Acceleration force along the x axis (excluding gravity).</td>
@@ -181,25 +152,6 @@
     <td><code>SensorEvent.values[3]</code></td>
     <td>Scalar component of the rotation vector ((cos(θ/2)).<sup>1</sup></td>
   </tr>
-  <tr>
-    <td>{@link android.hardware.Sensor#TYPE_SIGNIFICANT_MOTION}</td>
-    <td>N/A</td>
-    <td>N/A</td>
-    <td>N/A</td>
-  </tr>
-  <tr>
-    <td>{@link android.hardware.Sensor#TYPE_STEP_COUNTER}</td>
-    <td><code>SensorEvent.values[0]</code></td>
-    <td>Number of steps taken by the user since the last reboot while the sensor
-        was activated.</td>
-    <td>Steps</td>
-  </tr>
-  <tr>
-    <td>{@link android.hardware.Sensor#TYPE_STEP_DETECTOR}</td>
-    <td>N/A</td>
-    <td>N/A</td>
-    <td>N/A</td>
-  </tr>
 </table>
 
 <p class="note"><strong><sup>1</sup></strong> The scalar component is an optional value.</p>
@@ -414,36 +366,6 @@
 compensated for. You usually determine the drift (bias) and noise by monitoring other sensors, such
 as the gravity sensor or accelerometer.</p>
 
-<h2 id="sensors-motion-gyrounc">Using the Uncalibrated Gyroscope</h2>
-
-<p>The uncalibrated gyroscope is similar to the <a href="#sensors-motion-gyro">gyroscope</a>,
-except that no gyro-drift compensation is applied to the rate of rotation. Factory calibration
-and temperature compensation are still applied to the rate of rotation. The uncalibrated
-gyroscope is useful for post-processing and melding orientation data. In general,
-<code>gyroscope_event.values[0]</code> will be close to
-<code>uncalibrated_gyroscope_event.values[0] - uncalibrated_gyroscope_event.values[3]</code>.
-That is,</p>
-
-<p><code>calibrated_x ~= uncalibrated_x - bias_estimate_x</code></p>
-
-<p class="note"><strong>Note:</strong> Uncalibrated sensors provide more raw results and may
-include some bias, but their measurements contain fewer jumps from corrections applied through
-calibration. Some applications may prefer these uncalibrated results as smoother and more
-reliable. For instance, if an application is attempting to conduct its own sensor fusion,
-introducing calibrations can actually distort results.</p>
-
-<p>In addition to the rates of rotation, the uncalibrated gyroscope also provides the estimated
-drift around each axis. The following code shows you how to get an instance of the default
-uncalibrated gyroscope:</p>
-
-<pre>
-private SensorManager mSensorManager;
-private Sensor mSensor;
-...
-mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);
-</pre>
-
 <h2 id="sensors-motion-linear">Using the Linear Accelerometer</h2>
 
 <p>The linear acceleration sensor provides you with a three-dimensional vector representing
@@ -529,63 +451,3 @@
 The sample application is located in the API Demos code (<a
 href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/os/RotationVectorDemo.html">
 OS - RotationVectorDemo</a>).</p>
-
-
-<h2 id="sensors-motion-significant">Using the Significant Motion Sensor</h2>
-
-<p>The significant motion sensor triggers an event each time significant motion is detected and
-then it disables itself. A significant motion is a motion that might lead to a change in the
-user's location; for example walking, biking, or sitting in a moving car. The following code shows you
-how to get an instance of the default significant motion sensor and how to register an event
-listener:</p>
-
-<pre>
-private SensorManager mSensorManager;
-private Sensor mSensor;
-private TriggerEventListener mTriggerEventListener;
-...
-mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
-
-mTriggerEventListener = new TriggerEventListener() {
-    &#64;Override
-    public void onTrigger(TriggerEvent event) {
-        // Do work
-    }
-};
-
-mSensorManager.requestTriggerSensor(mTriggerEventListener, mSensor);
-</pre>
-
-<p>For more information, see {@link android.hardware.TriggerEventListener}.</p>
-
-
-<h2 id="sensors-motion-stepcounter">Using the Step Counter Sensor</h2>
-
-<p>The step counter sensor provides the number of steps taken by the user since the last reboot
-while the sensor was activated. The step counter has more latency (up to 10 seconds) but more
-accuracy than the step detector sensor. The following code shows you how to get an instance of
-the default step counter sensor:</p>
-
-<pre>
-private SensorManager mSensorManager;
-private Sensor mSensor;
-...
-mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
-</pre>
-
-
-<h2 id="sensors-motion-stepdetector">Using the Step Detector Sensor</h2>
-
-<p>The step detector sensor triggers an event each time the user takes a step. The latency is
-expected to be below 2 seconds. The following code shows you how to get an instance of the
-default step detector sensor:</p>
-
-<pre>
-private SensorManager mSensorManager;
-private Sensor mSensor;
-...
-mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
-</pre>
diff --git a/docs/html/guide/topics/sensors/sensors_overview.jd b/docs/html/guide/topics/sensors/sensors_overview.jd
index 0b3cb2b..a162ccf 100644
--- a/docs/html/guide/topics/sensors/sensors_overview.jd
+++ b/docs/html/guide/topics/sensors/sensors_overview.jd
@@ -710,7 +710,7 @@
 href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-accel">Acceleration
 sensor</a></li>
 <li><a
-href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-grav">Gravity
+href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-gravity">Gravity
 sensor</a></li>
 <li><a
 href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-gyro">Gyroscope</a></li>
diff --git a/docs/html/guide/topics/sensors/sensors_position.jd b/docs/html/guide/topics/sensors/sensors_position.jd
index f021afe..65b9350 100644
--- a/docs/html/guide/topics/sensors/sensors_position.jd
+++ b/docs/html/guide/topics/sensors/sensors_position.jd
@@ -1,14 +1,12 @@
 page.title=Position Sensors
-page.tags="sensorevent","orientation","proximity"
+page.tags=sensorevent,orientation,proximity
 @jd:body
 
 <div id="qv-wrapper">
   <div id="qv">
   <h2>In this document</h2>
   <ol>
-    <li><a href="#sensors-pos-gamerot">Using the Game Rotation Vector Sensor</a></li>
-    <li><a href="#sensors-pos-geomrot">Using the Geomagnetic Rotation Vector Sensor</a></li>
-    <li><a href="#sensors-pos-orient">Using the Orientation Sensor</a></li>
+     <li><a href="#sensors-pos-orient">Using the Orientation Sensor</a></li>
     <li><a href="#sensors-pos-mag">Using the Geomagnetic Field Sensor</a></li>
     <li><a href="#sensors-pos-prox">Using the Proximity Sensor</a></li>
   </ol>
@@ -85,34 +83,6 @@
     <th scope="col" style="white-space:nowrap">Units of measure</th>
   </tr>
   <tr>
-    <td rowspan="3">{@link android.hardware.Sensor#TYPE_GAME_ROTATION_VECTOR}</td>
-    <td><code>SensorEvent.values[0]</code></td>
-    <td>Rotation vector component along the x axis (x * sin(θ/2)).</td>
-    <td rowspan="3">Unitless</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[1]</code></td>
-    <td>Rotation vector component along the y axis (y * sin(θ/2)).</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[2]</code></td>
-    <td>Rotation vector component along the z axis (z * sin(θ/2)).</td>
-  </tr>
-  <tr>
-    <td rowspan="3">{@link android.hardware.Sensor#TYPE_GEOMAGNETIC_ROTATION_VECTOR}</td>
-    <td><code>SensorEvent.values[0]</code></td>
-    <td>Rotation vector component along the x axis (x * sin(θ/2)).</td>
-    <td rowspan="3">Unitless</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[1]</code></td>
-    <td>Rotation vector component along the y axis (y * sin(θ/2)).</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[2]</code></td>
-    <td>Rotation vector component along the z axis (z * sin(θ/2)).</td>
-  </tr>
-  <tr>
     <td rowspan="3">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD}</td>
     <td><code>SensorEvent.values[0]</code></td>
     <td>Geomagnetic field strength along the x axis.</td>
@@ -127,32 +97,6 @@
     <td>Geomagnetic field strength along the z axis.</td>
   </tr>
   <tr>
-    <td rowspan="6">{@link android.hardware.Sensor#TYPE_MAGNETIC_FIELD_UNCALIBRATED}</td>
-    <td><code>SensorEvent.values[0]</code></td>
-    <td>Geomagnetic field strength (without hard iron calibration) along the x axis.</td>
-    <td rowspan="6">&mu;T</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[1]</code></td>
-    <td>Geomagnetic field strength (without hard iron calibration) along the y axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[2]</code></td>
-    <td>Geomagnetic field strength (without hard iron calibration) along the z axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[3]</code></td>
-    <td>Iron bias estimation along the x axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[4]</code></td>
-    <td>Iron bias estimation along the y axis.</td>
-  </tr>
-  <tr>
-    <td><code>SensorEvent.values[5]</code></td>
-    <td>Iron bias estimation along the z axis.</td>
-  </tr>
-  <tr>
     <td rowspan="3">{@link android.hardware.Sensor#TYPE_ORIENTATION}<sup>1</sup></td>
     <td><code>SensorEvent.values[0]</code></td>
     <td>Azimuth (angle around the z-axis).</td>
@@ -181,58 +125,11 @@
 <p class="note"><sup><strong>2</strong></sup> Some proximity sensors provide only binary values
 representing near and far.</p>
 
-
-<h2 id="sensors-pos-gamerot">Using the Game Rotation Vector Sensor</h2>
-
-<p>The game rotation vector sensor is identical to the
-<a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation
-Vector Sensor</a>, except it does not use the geomagnetic field. Therefore the Y axis does not
-point north but instead to some other reference. That reference is allowed to drift by the
-same order of magnitude as the gyroscope drifts around the Z axis.</p>
-
-<p>Because the game rotation vector sensor does not use the magnetic field, relative rotations
-are more accurate, and not impacted by magnetic field changes. Use this sensor in a game if
-you do not care about where north is, and the normal rotation vector does not fit your needs
-because of its reliance on the magnetic field.</p>
-
-<p>The following code shows you how to get an instance of the default game rotation vector
-sensor:</p>
-
-<pre>
-private SensorManager mSensorManager;
-private Sensor mSensor;
-...
-mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
-</pre>
-
-
-<h2 id="sensors-pos-geomrot">Using the Geomagnetic Rotation Vector Sensor</h2>
-
-<p>The geomagnetic rotation vector sensor is similar to the
-<a href="{@docRoot}guide/topics/sensors/sensors_motion.html#sensors-motion-rotate">Rotation
-Vector Sensor</a>, but it uses a magnetometer instead of a gyroscope. The accuracy of this
-sensor is lower than the normal rotation vector sensor, but the power consumption is reduced.
-Only use this sensor if you want to collect some rotation information in the background without
-draining too much battery. This sensor is most useful when used in conjunction with batching.</p>
-
-<p>The following code shows you how to get an instance of the default geomagnetic rotation
-vector sensor:</p>
-
-<pre>
-private SensorManager mSensorManager;
-private Sensor mSensor;
-...
-mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);
-</pre>
-
-
 <h2 id="sensors-pos-orient">Using the Orientation Sensor</h2>
 
 <p>The orientation sensor lets you monitor the position of a device relative to the earth's frame of
 reference (specifically, magnetic north). The following code shows you how to get an instance of the
-default orientation sensor:</p>
+default orientation sensor :</p>
 
 <pre>
 private SensorManager mSensorManager;
@@ -352,35 +249,6 @@
 and {@link android.hardware.SensorManager#getInclination getInclination()} methods to obtain azimuth
 and geomagnetic inclination data.</p>
 
-<h2 id="sensors-pos-magunc">Using the Uncalibrated Magnetometer</h2>
-
-<p>The uncalibrated magnetometer is similar to the <a href="#sensors-pos-mag">geomagnetic field
-sensor</a>, except that no hard iron calibration is applied to the magnetic field. Factory calibration
-and temperature compensation are still applied to the magnetic field. The uncalibrated magnetometer
-is useful to handle bad hard iron estimations. In general, <code>geomagneticsensor_event.values[0]</code>
-will be close to <code>uncalibrated_magnetometer_event.values[0] -
-uncalibrated_magnetometer_event.values[3]</code>. That is,</p>
-
-<p><code>calibrated_x ~= uncalibrated_x - bias_estimate_x</code></p></p>
-
-<p class="note"><strong>Note:</strong> Uncalibrated sensors provide more raw results and may
-include some bias, but their measurements contain fewer jumps from corrections applied through
-calibration. Some applications may prefer these uncalibrated results as smoother and more
-reliable. For instance, if an application is attempting to conduct its own sensor fusion,
-introducing calibrations can actually distort results.</p>
-
-<p>In addition to the magnetic field, the uncalibrated magnetometer also provides the
-estimated hard iron bias in each axis. The following code shows you how to get an instance of the
-default uncalibrated magnetometer:</p>
-
-<pre>
-private SensorManager mSensorManager;
-private Sensor mSensor;
-...
-mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
-mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED);
-</pre>
-
 <h2 id="sensors-pos-prox">Using the Proximity Sensor</h2>
 <p>The proximity sensor lets you determine how far away an object is from a device. The following
 code shows you how to get an instance of the default proximity sensor:</p>
diff --git a/docs/html/guide/topics/text/copy-paste.jd b/docs/html/guide/topics/text/copy-paste.jd
index b34f0fa..8f898e4 100644
--- a/docs/html/guide/topics/text/copy-paste.jd
+++ b/docs/html/guide/topics/text/copy-paste.jd
@@ -1,5 +1,5 @@
 page.title=Copy and Paste
-page.tags="clipboardmanager","clipdata","input"
+page.tags=clipboardmanager,clipdata,input
 @jd:body
 <div id="qv-wrapper">
     <div id="qv">
diff --git a/docs/html/guide/topics/text/creating-input-method.jd b/docs/html/guide/topics/text/creating-input-method.jd
index 7254594..205fd96 100644
--- a/docs/html/guide/topics/text/creating-input-method.jd
+++ b/docs/html/guide/topics/text/creating-input-method.jd
@@ -1,5 +1,5 @@
 page.title=Creating an Input Method
-page.tags="ime","keyboard","inputmethodservice"
+page.tags=ime,keyboard,inputmethodservice
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/text/spell-checker-framework.jd b/docs/html/guide/topics/text/spell-checker-framework.jd
index 366f9cc..a5d9932 100644
--- a/docs/html/guide/topics/text/spell-checker-framework.jd
+++ b/docs/html/guide/topics/text/spell-checker-framework.jd
@@ -1,5 +1,5 @@
 page.title=Spelling Checker Framework
-page.tags="input","spellcheckerservice"
+page.tags=input,spellcheckerservice
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index 3173ff1..a122443 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -1,5 +1,5 @@
 page.title=Action Bar
-page.tags="actionbar","menu","tabs"
+page.tags=actionbar,menu,tabs
 
 @jd:body
 
diff --git a/docs/html/guide/topics/ui/controls/button.jd b/docs/html/guide/topics/ui/controls/button.jd
index cb274ae..b52c3e9 100644
--- a/docs/html/guide/topics/ui/controls/button.jd
+++ b/docs/html/guide/topics/ui/controls/button.jd
@@ -1,5 +1,5 @@
 page.title=Buttons
-page.tags="button","imagebutton"
+page.tags=button,imagebutton
 @jd:body
 
 <div id="qv-wrapper">
@@ -241,4 +241,4 @@
   <p>For more information about this XML syntax, including how to define a disabled, hovered, or
 other button states, read about <a
 href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">State List
-Drawable</a>.</p>
\ No newline at end of file
+Drawable</a>.</p>
diff --git a/docs/html/guide/topics/ui/controls/pickers.jd b/docs/html/guide/topics/ui/controls/pickers.jd
index 4c55840..31e4d3f5 100644
--- a/docs/html/guide/topics/ui/controls/pickers.jd
+++ b/docs/html/guide/topics/ui/controls/pickers.jd
@@ -1,5 +1,5 @@
 page.title=Pickers
-page.tags="datepicker","timepicker"
+page.tags=datepicker,timepicker
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/controls/radiobutton.jd b/docs/html/guide/topics/ui/controls/radiobutton.jd
index d0c48ed..b2556e19 100644
--- a/docs/html/guide/topics/ui/controls/radiobutton.jd
+++ b/docs/html/guide/topics/ui/controls/radiobutton.jd
@@ -1,5 +1,5 @@
 page.title=Radio Buttons
-page.tags="radiobutton","radiogroup"
+page.tags=radiobutton,radiogroup
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/controls/spinner.jd b/docs/html/guide/topics/ui/controls/spinner.jd
index 85714b6..d2db7a4 100644
--- a/docs/html/guide/topics/ui/controls/spinner.jd
+++ b/docs/html/guide/topics/ui/controls/spinner.jd
@@ -1,5 +1,5 @@
 page.title=Spinners
-page.tags="adapterview","spinneradapter"
+page.tags=adapterview,spinneradapter
 @jd:body
 
 <div id="qv-wrapper">
@@ -143,4 +143,4 @@
 <p>If you implement the {@link
 android.widget.AdapterView.OnItemSelectedListener} interface with your {@link
 android.app.Activity} or {@link android.app.Fragment} (such as in the example above), you can pass
-<code>this</code> as the interface instance.</p>
\ No newline at end of file
+<code>this</code> as the interface instance.</p>
diff --git a/docs/html/guide/topics/ui/controls/text.jd b/docs/html/guide/topics/ui/controls/text.jd
index c0b9873..9474dee 100644
--- a/docs/html/guide/topics/ui/controls/text.jd
+++ b/docs/html/guide/topics/ui/controls/text.jd
@@ -1,5 +1,5 @@
 page.title=Text Fields
-page.tags="edittext","autocompletetextview"
+page.tags=edittext,autocompletetextview
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/controls/togglebutton.jd b/docs/html/guide/topics/ui/controls/togglebutton.jd
index 5e2a551..09af516 100644
--- a/docs/html/guide/topics/ui/controls/togglebutton.jd
+++ b/docs/html/guide/topics/ui/controls/togglebutton.jd
@@ -1,5 +1,5 @@
 page.title=Toggle Buttons
-page.tags="switch","togglebutton"
+page.tags=switch,togglebutton
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/custom-components.jd b/docs/html/guide/topics/ui/custom-components.jd
index 703a5ce..b146098 100644
--- a/docs/html/guide/topics/ui/custom-components.jd
+++ b/docs/html/guide/topics/ui/custom-components.jd
@@ -1,5 +1,5 @@
 page.title=Custom Components
-page.tags="view","widget"
+page.tags=view,widget
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index 6586c2f..616949b 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -1,5 +1,5 @@
 page.title=Layouts
-page.tags="view","viewgroup"
+page.tags=view,viewgroup
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd
index 043879c..0c6ec84 100644
--- a/docs/html/guide/topics/ui/dialogs.jd
+++ b/docs/html/guide/topics/ui/dialogs.jd
@@ -1,5 +1,5 @@
 page.title=Dialogs
-page.tags="alertdialog","dialogfragment"
+page.tags=alertdialog,dialogfragment
 
 @jd:body
 
diff --git a/docs/html/guide/topics/ui/drag-drop.jd b/docs/html/guide/topics/ui/drag-drop.jd
index 9a6b0e9..9d8aa9b 100644
--- a/docs/html/guide/topics/ui/drag-drop.jd
+++ b/docs/html/guide/topics/ui/drag-drop.jd
@@ -1,5 +1,5 @@
 page.title=Drag and Drop
-page.tags="clipdata","dragevent","onlongclicklistener"
+page.tags=clipdata,dragevent,onlongclicklistener
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/layout/gridview.jd b/docs/html/guide/topics/ui/layout/gridview.jd
index bc189c4..b8d24b60 100644
--- a/docs/html/guide/topics/ui/layout/gridview.jd
+++ b/docs/html/guide/topics/ui/layout/gridview.jd
@@ -1,5 +1,5 @@
 page.title=Grid View
-page.tags="gridview"
+page.tags=gridview
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/ui/layout/linear.jd b/docs/html/guide/topics/ui/layout/linear.jd
index 444dc71..902f22f 100644
--- a/docs/html/guide/topics/ui/layout/linear.jd
+++ b/docs/html/guide/topics/ui/layout/linear.jd
@@ -1,5 +1,5 @@
 page.title=Linear Layout
-page.tags="linearlayout"
+page.tags=linearlayout
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/guide/topics/ui/layout/listview.jd b/docs/html/guide/topics/ui/layout/listview.jd
index f8315c5..3c6e32c 100644
--- a/docs/html/guide/topics/ui/layout/listview.jd
+++ b/docs/html/guide/topics/ui/layout/listview.jd
@@ -1,5 +1,5 @@
 page.title=List View
-page.tags="listview"
+page.tags=listview
 @jd:body
 <div id="qv-wrapper">
 <div id="qv">
diff --git a/docs/html/guide/topics/ui/layout/relative.jd b/docs/html/guide/topics/ui/layout/relative.jd
index 65c5617..69f5c0a 100644
--- a/docs/html/guide/topics/ui/layout/relative.jd
+++ b/docs/html/guide/topics/ui/layout/relative.jd
@@ -1,5 +1,5 @@
 page.title=Relative Layout
-page.tags="relativelayout"
+page.tags=relativelayout
 @jd:body
 
 <div id="qv-wrapper">
@@ -114,4 +114,4 @@
 </pre>
 
 <p>For details about all the layout attributes available to each child view of a {@link
-android.widget.RelativeLayout}, see {@link android.widget.RelativeLayout.LayoutParams}.</p>
\ No newline at end of file
+android.widget.RelativeLayout}, see {@link android.widget.RelativeLayout.LayoutParams}.</p>
diff --git a/docs/html/guide/topics/ui/settings.jd b/docs/html/guide/topics/ui/settings.jd
index d96447d..1d36430 100644
--- a/docs/html/guide/topics/ui/settings.jd
+++ b/docs/html/guide/topics/ui/settings.jd
@@ -1,5 +1,5 @@
 page.title=Settings
-page.tags="preference","preferenceactivity","preferencefragment"
+page.tags=preference,preferenceactivity,preferencefragment
 
 @jd:body
 
diff --git a/docs/html/images/camera2/metadata/android.colorCorrection.mode/processing_pipeline.png b/docs/html/images/camera2/metadata/android.colorCorrection.mode/processing_pipeline.png
new file mode 100644
index 0000000..7578b48
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.colorCorrection.mode/processing_pipeline.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/blue_shading.png b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/blue_shading.png
new file mode 100644
index 0000000..7b10f6b
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/blue_shading.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/green_e_shading.png b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/green_e_shading.png
new file mode 100644
index 0000000..41972cf
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/green_e_shading.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/green_o_shading.png b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/green_o_shading.png
new file mode 100644
index 0000000..d26600b
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/green_o_shading.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png
new file mode 100644
index 0000000..1e7208e
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/inv_shading.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/red_shading.png b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/red_shading.png
new file mode 100644
index 0000000..ecef3ae
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.statistics.lensShadingMap/red_shading.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png b/docs/html/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
new file mode 100644
index 0000000..ec89e37
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.tonemap.curveRed/gamma_tonemap.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png b/docs/html/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
new file mode 100644
index 0000000..cf0c63d
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.tonemap.curveRed/inverse_tonemap.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png b/docs/html/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
new file mode 100644
index 0000000..f226a54
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.tonemap.curveRed/linear_tonemap.png
Binary files differ
diff --git a/docs/html/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png b/docs/html/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
new file mode 100644
index 0000000..ded0645
--- /dev/null
+++ b/docs/html/images/camera2/metadata/android.tonemap.curveRed/srgb_tonemap.png
Binary files differ
diff --git a/docs/html/samples/index.jd b/docs/html/samples/index.jd
index c1213b6..ab15e32 100644
--- a/docs/html/samples/index.jd
+++ b/docs/html/samples/index.jd
@@ -1,5 +1,5 @@
 page.title=Samples
-page.tags="samples","examples","code"
+page.tags=samples,examples,code
 
 @jd:body
 
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 87a1bb3..8bb75df 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -1,5 +1,5 @@
 page.title=Android SDK
-page.tags="download"
+page.tags=download
 page.template=sdk
 header.hide=1
 page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index 1850b44..feb7a6e 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -1,5 +1,5 @@
 page.title=Getting Started with Android Studio
-page.tags="studio"
+page.tags=studio
 @jd:body
 
 
diff --git a/docs/html/tools/adk/adk.jd b/docs/html/tools/adk/adk.jd
index 1651747..7e75c11 100644
--- a/docs/html/tools/adk/adk.jd
+++ b/docs/html/tools/adk/adk.jd
@@ -1,5 +1,5 @@
 page.title=Accessory Development Kit 2011 Guide
-page.tags="adk"
+page.tags=adk
 @jd:body
 
   <div id="qv-wrapper">
diff --git a/docs/html/tools/adk/adk2.jd b/docs/html/tools/adk/adk2.jd
index c60e920..d69125a 100644
--- a/docs/html/tools/adk/adk2.jd
+++ b/docs/html/tools/adk/adk2.jd
@@ -1,5 +1,5 @@
 page.title=Accessory Development Kit 2012 Guide
-page.tags="adk"
+page.tags=adk
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/tools/adk/index.jd b/docs/html/tools/adk/index.jd
index e035115..e08748fc 100644
--- a/docs/html/tools/adk/index.jd
+++ b/docs/html/tools/adk/index.jd
@@ -1,5 +1,5 @@
 page.title=Accessory Development Kit
-page.tags="adk"
+page.tags=adk
 @jd:body
 
 <p>The Accessory Development Kit (ADK) is a reference implementation for hardware manufacturers and
diff --git a/docs/html/tools/debugging/debugging-memory.jd b/docs/html/tools/debugging/debugging-memory.jd
index a7f443c..fccb67e 100644
--- a/docs/html/tools/debugging/debugging-memory.jd
+++ b/docs/html/tools/debugging/debugging-memory.jd
@@ -1,5 +1,5 @@
 page.title=Investigating Your RAM Usage
-page.tags="memory","OutOfMemoryError"
+page.tags=memory,OutOfMemoryError
 @jd:body
 
  <div id="qv-wrapper">
@@ -492,4 +492,4 @@
 <p class="note"><strong>Tip:</strong> You can also perform the above steps by using the "monkey"
 test framework. For more information on running the monkey test framework, read the <a href=
 "{@docRoot}tools/help/monkeyrunner_concepts.html">monkeyrunner</a>
-documentation.</p>
\ No newline at end of file
+documentation.</p>
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index c339943..f980042 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -1,7 +1,7 @@
 page.title=Android Debug Bridge
 parent.title=Tools
 parent.link=index.html
-page.tags="adb"
+page.tags=adb
 @jd:body
 
 <div id="qv-wrapper">
diff --git a/docs/html/tools/help/adt.jd b/docs/html/tools/help/adt.jd
index 4dac574..1bb3015 100644
--- a/docs/html/tools/help/adt.jd
+++ b/docs/html/tools/help/adt.jd
@@ -1,5 +1,5 @@
 page.title=Android Developer Tools
-page.tags="adt"
+page.tags=adt
 @jd:body
 
   <div id="qv-wrapper">
diff --git a/docs/html/tools/help/draw9patch.jd b/docs/html/tools/help/draw9patch.jd
index ebf2c6c..859b1cf 100644
--- a/docs/html/tools/help/draw9patch.jd
+++ b/docs/html/tools/help/draw9patch.jd
@@ -1,5 +1,5 @@
 page.title=Draw 9-patch
-page.tags="NinePatch"
+page.tags=NinePatch
 @jd:body
 
 <p>The Draw 9-patch tool allows you to easily create a 
diff --git a/docs/html/training/accessibility/index.jd b/docs/html/training/accessibility/index.jd
index 0af1d87..ea54dc4 100644
--- a/docs/html/training/accessibility/index.jd
+++ b/docs/html/training/accessibility/index.jd
@@ -1,5 +1,5 @@
 page.title=Implementing Accessibility
-page.tags="navigation","input"
+page.tags=navigation,input
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/activity-testing/index.jd b/docs/html/training/activity-testing/index.jd
index ddede71..b9542b6 100644
--- a/docs/html/training/activity-testing/index.jd
+++ b/docs/html/training/activity-testing/index.jd
@@ -1,5 +1,5 @@
 page.title=Testing Your Android Activity
-page.tags="testing"
+page.tags=testing
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/animation/index.jd b/docs/html/training/animation/index.jd
index b6940f8..4f37788 100644
--- a/docs/html/training/animation/index.jd
+++ b/docs/html/training/animation/index.jd
@@ -1,5 +1,5 @@
 page.title=Adding Animations
-page.tags="Animator","views","layout","user interface"
+page.tags=Animator,views,layout,user interface
 trainingnavtop=true
 startpage=true
 
@@ -84,4 +84,4 @@
       <dd>
         Learn how to enable built-in animations when adding, removing, or updating child views in a layout.
       </dd>
-    </dl>
\ No newline at end of file
+    </dl>
diff --git a/docs/html/training/articles/memory.jd b/docs/html/training/articles/memory.jd
index cdc0cd4..f15af68 100644
--- a/docs/html/training/articles/memory.jd
+++ b/docs/html/training/articles/memory.jd
@@ -1,5 +1,5 @@
 page.title=Managing Your App's Memory
-page.tags="ram","low memory","OutOfMemoryError","onTrimMemory"
+page.tags=ram,low memory,OutOfMemoryError,onTrimMemory
 page.article=true
 @jd:body
 
diff --git a/docs/html/training/articles/perf-anr.jd b/docs/html/training/articles/perf-anr.jd
index 87cfc1c..b32cc4f 100644
--- a/docs/html/training/articles/perf-anr.jd
+++ b/docs/html/training/articles/perf-anr.jd
@@ -1,5 +1,5 @@
 page.title=Keeping Your App Responsive
-page.tags="threads","asynctask"
+page.tags=threads,asynctask
 
 page.article=true
 @jd:body
diff --git a/docs/html/training/articles/perf-jni.jd b/docs/html/training/articles/perf-jni.jd
index 9f880ec..1a40f62 100644
--- a/docs/html/training/articles/perf-jni.jd
+++ b/docs/html/training/articles/perf-jni.jd
@@ -1,5 +1,5 @@
 page.title=JNI Tips
-page.tags="ndk","native"
+page.tags=ndk,native
 
 page.article=true
 @jd:body
@@ -444,7 +444,9 @@
 
 <pre>D Late-enabling CheckJNI</pre>
 
-
+<p>You can also set the <code>android:debuggable</code> attribute in your application's manifest to
+turn on CheckJNI just for your app. Note that the Android build tools will do this automatically for
+certain build types.
 
 
 <a name="native_libraries" id="native_libraries"></a>
diff --git a/docs/html/training/articles/security-ssl.jd b/docs/html/training/articles/security-ssl.jd
index f52865a..0639fb0 100644
--- a/docs/html/training/articles/security-ssl.jd
+++ b/docs/html/training/articles/security-ssl.jd
@@ -1,5 +1,5 @@
 page.title=Security with HTTPS and SSL
-page.tags="network","certificates"
+page.tags=network,certificates
 
 page.article=true
 @jd:body
diff --git a/docs/html/training/articles/smp.jd b/docs/html/training/articles/smp.jd
index 7240eec..0b45987 100644
--- a/docs/html/training/articles/smp.jd
+++ b/docs/html/training/articles/smp.jd
@@ -1,5 +1,5 @@
 page.title=SMP Primer for Android
-page.tags="ndk","native"
+page.tags=ndk,native
 
 page.article=true
 @jd:body
diff --git a/docs/html/training/backward-compatible-ui/index.jd b/docs/html/training/backward-compatible-ui/index.jd
index 4baa55c..c8b6ecc 100644
--- a/docs/html/training/backward-compatible-ui/index.jd
+++ b/docs/html/training/backward-compatible-ui/index.jd
@@ -1,5 +1,5 @@
 page.title=Creating Backward-Compatible UIs
-page.tags="widgets","support"
+page.tags=widgets,support
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/actionbar/index.jd b/docs/html/training/basics/actionbar/index.jd
index f0de758..0303043 100644
--- a/docs/html/training/basics/actionbar/index.jd
+++ b/docs/html/training/basics/actionbar/index.jd
@@ -1,5 +1,5 @@
 page.title=Adding the Action Bar
-page.tags="actionbar"
+page.tags=actionbar
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/data-storage/index.jd b/docs/html/training/basics/data-storage/index.jd
index 4ccad75..fc0c8b5 100644
--- a/docs/html/training/basics/data-storage/index.jd
+++ b/docs/html/training/basics/data-storage/index.jd
@@ -1,5 +1,5 @@
 page.title=Saving Data
-page.tags="data storage","files","sql","database","preferences"
+page.tags=data storage,files,sql,database,preferences
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/fragments/index.jd b/docs/html/training/basics/fragments/index.jd
index 987decf..e78b694 100644
--- a/docs/html/training/basics/fragments/index.jd
+++ b/docs/html/training/basics/fragments/index.jd
@@ -1,5 +1,5 @@
 page.title=Building a Dynamic UI with Fragments
-page.tags="fragments", "user interface", "support library"
+page.tags=fragments,user interface,support library
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/fragments/support-lib.jd b/docs/html/training/basics/fragments/support-lib.jd
index d949267..1d538af 100644
--- a/docs/html/training/basics/fragments/support-lib.jd
+++ b/docs/html/training/basics/fragments/support-lib.jd
@@ -1,5 +1,5 @@
 page.title=Using the Support Library
-page.tags="support library"
+page.tags=support library
 
 trainingnavtop=true
 
diff --git a/docs/html/training/basics/intents/index.jd b/docs/html/training/basics/intents/index.jd
index 59ba11f..aa0232a 100644
--- a/docs/html/training/basics/intents/index.jd
+++ b/docs/html/training/basics/intents/index.jd
@@ -1,5 +1,5 @@
 page.title=Interacting with Other Apps
-page.tags="intents","activity"
+page.tags=intents,activity
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/network-ops/index.jd b/docs/html/training/basics/network-ops/index.jd
index cb3a390..89ab539 100644
--- a/docs/html/training/basics/network-ops/index.jd
+++ b/docs/html/training/basics/network-ops/index.jd
@@ -1,5 +1,5 @@
 page.title=Performing Network Operations
-page.tags="network","wireless"
+page.tags=network,wireless
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/supporting-devices/index.jd b/docs/html/training/basics/supporting-devices/index.jd
index 1e3eb42..6f339f4 100644
--- a/docs/html/training/basics/supporting-devices/index.jd
+++ b/docs/html/training/basics/supporting-devices/index.jd
@@ -1,5 +1,5 @@
 page.title=Supporting Different Devices
-page.tags="resources","screens","versions","localization"
+page.tags=resources,screens,versions,localization
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/basics/supporting-devices/languages.jd b/docs/html/training/basics/supporting-devices/languages.jd
index 130848e..5a1507c 100644
--- a/docs/html/training/basics/supporting-devices/languages.jd
+++ b/docs/html/training/basics/supporting-devices/languages.jd
@@ -1,6 +1,6 @@
 page.title=Supporting Different Languages
 parent.title=Supporting Different Devices
-page.tags="localizing","localization","resources", "formats", "l10n"
+page.tags=localizing,localization,resources,formats,l10n
 parent.link=index.html
 
 trainingnavtop=true
diff --git a/docs/html/training/beam-files/index.jd b/docs/html/training/beam-files/index.jd
index e4bac2e..910fa38 100644
--- a/docs/html/training/beam-files/index.jd
+++ b/docs/html/training/beam-files/index.jd
@@ -1,5 +1,5 @@
 page.title=Sharing Files with NFC
-page.tags="NfcAdapter","Android Beam","share","file transfer"
+page.tags=NfcAdapter,Android Beam,share,file transfer
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/camera/index.jd b/docs/html/training/camera/index.jd
index c6b49cf..5501ab0 100644
--- a/docs/html/training/camera/index.jd
+++ b/docs/html/training/camera/index.jd
@@ -1,5 +1,5 @@
 page.title=Capturing Photos
-page.tags="camera","video","picture"
+page.tags=camera,video,picture
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/cloudsave/conflict-res.jd b/docs/html/training/cloudsave/conflict-res.jd
index 0ff50e2..73e75db 100644
--- a/docs/html/training/cloudsave/conflict-res.jd
+++ b/docs/html/training/cloudsave/conflict-res.jd
@@ -1,5 +1,5 @@
 page.title=Resolving Cloud Save Conflicts
-page.tags="cloud"
+page.tags=cloud
 
 page.article=true
 @jd:body
@@ -594,4 +594,4 @@
 limited. Depending on your implementation, it might make sense to store the
 timestamp for when each entry in the dictionary was modified. When you detect that a
 given entry has not been modified in the last several weeks or months, it is
-probably safe to transfer the coins into another entry and delete the old entry.</p>
\ No newline at end of file
+probably safe to transfer the coins into another entry and delete the old entry.</p>
diff --git a/docs/html/training/cloudsync/index.jd b/docs/html/training/cloudsync/index.jd
index 55b275b..eb7df3d 100644
--- a/docs/html/training/cloudsync/index.jd
+++ b/docs/html/training/cloudsync/index.jd
@@ -1,5 +1,5 @@
 page.title=Syncing to the Cloud
-page.tags="cloud","sync","backup"
+page.tags=cloud,sync,backup
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/connect-devices-wirelessly/index.jd b/docs/html/training/connect-devices-wirelessly/index.jd
index aada1fd..3206d7f 100644
--- a/docs/html/training/connect-devices-wirelessly/index.jd
+++ b/docs/html/training/connect-devices-wirelessly/index.jd
@@ -1,5 +1,5 @@
 page.title=Connecting Devices Wirelessly
-page.tags="wifi","network","wireless"
+page.tags=wifi,network,wireless
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/custom-views/index.jd b/docs/html/training/custom-views/index.jd
index 1c09e66..87cd0b0 100644
--- a/docs/html/training/custom-views/index.jd
+++ b/docs/html/training/custom-views/index.jd
@@ -1,5 +1,5 @@
 page.title=Creating Custom Views
-page.tags="widgets","ui","layout"
+page.tags=widgets,ui,layout
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/displaying-bitmaps/index.jd b/docs/html/training/displaying-bitmaps/index.jd
index 8c11e52..831c64d 100644
--- a/docs/html/training/displaying-bitmaps/index.jd
+++ b/docs/html/training/displaying-bitmaps/index.jd
@@ -1,5 +1,5 @@
 page.title=Displaying Bitmaps Efficiently
-page.tags="bitmaps","images","graphics"
+page.tags=bitmaps,images,graphics
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/efficient-downloads/index.jd b/docs/html/training/efficient-downloads/index.jd
index 2ab93ae..d9d7ef0 100644
--- a/docs/html/training/efficient-downloads/index.jd
+++ b/docs/html/training/efficient-downloads/index.jd
@@ -1,5 +1,5 @@
 page.title=Transferring Data Without Draining the Battery
-page.tags="battery","network","wireless"
+page.tags=battery,network,wireless
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/enterprise/index.jd b/docs/html/training/enterprise/index.jd
index ac1b565..2926f71 100644
--- a/docs/html/training/enterprise/index.jd
+++ b/docs/html/training/enterprise/index.jd
@@ -1,5 +1,5 @@
 page.title=Developing for Enterprise
-page.tags="policy","privacy"
+page.tags=policy,privacy
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/gestures/index.jd b/docs/html/training/gestures/index.jd
index 9d21b08..260cfff 100644
--- a/docs/html/training/gestures/index.jd
+++ b/docs/html/training/gestures/index.jd
@@ -1,5 +1,5 @@
 page.title=Using Touch Gestures
-page.tags="input","navigation","gesturedetector","scroller"
+page.tags=input,navigation,gesturedetector,scroller
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/graphics/opengl/index.jd b/docs/html/training/graphics/opengl/index.jd
index cf33d80..3549f95 100644
--- a/docs/html/training/graphics/opengl/index.jd
+++ b/docs/html/training/graphics/opengl/index.jd
@@ -1,5 +1,5 @@
 page.title=Displaying Graphics with OpenGL ES
-page=tags="open gl","graphics"
+page.tags=open gl,graphics
 trainingnavtop=true
 
 @jd:body
diff --git a/docs/html/training/id-auth/index.jd b/docs/html/training/id-auth/index.jd
index 2bae9c4..f15ee29 100644
--- a/docs/html/training/id-auth/index.jd
+++ b/docs/html/training/id-auth/index.jd
@@ -1,5 +1,5 @@
 page.title=Remembering Users
-page.tags="privacy","oauth","accounts"
+page.tags=privacy,oauth,accounts
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/implementing-navigation/ancestral.jd b/docs/html/training/implementing-navigation/ancestral.jd
index 12d5005..57251c1 100644
--- a/docs/html/training/implementing-navigation/ancestral.jd
+++ b/docs/html/training/implementing-navigation/ancestral.jd
@@ -1,5 +1,5 @@
 page.title=Providing Up Navigation
-page.tags="up navigation","NavUtils","TaskStackBuilder"
+page.tags=up navigation,NavUtils,TaskStackBuilder
 
 trainingnavtop=true
 
diff --git a/docs/html/training/implementing-navigation/lateral.jd b/docs/html/training/implementing-navigation/lateral.jd
index bb9d78c..9c83479 100644
--- a/docs/html/training/implementing-navigation/lateral.jd
+++ b/docs/html/training/implementing-navigation/lateral.jd
@@ -1,5 +1,5 @@
 page.title=Creating Swipe Views with Tabs
-page.tags="viewpager","horizontal","paging","swipe view","tabs"
+page.tags=viewpager,horizontal,paging,swipe view,tabs
 
 trainingnavtop=true
 
diff --git a/docs/html/training/implementing-navigation/nav-drawer.jd b/docs/html/training/implementing-navigation/nav-drawer.jd
index f7f79166..679c240 100644
--- a/docs/html/training/implementing-navigation/nav-drawer.jd
+++ b/docs/html/training/implementing-navigation/nav-drawer.jd
@@ -1,5 +1,5 @@
 page.title=Creating a Navigation Drawer
-page.tags="DrawerLayout", "navigation"
+page.tags=DrawerLayout,navigation
 
 trainingnavtop=true
 
diff --git a/docs/html/training/implementing-navigation/temporal.jd b/docs/html/training/implementing-navigation/temporal.jd
index 3abab53..e736648 100644
--- a/docs/html/training/implementing-navigation/temporal.jd
+++ b/docs/html/training/implementing-navigation/temporal.jd
@@ -1,5 +1,5 @@
 page.title=Providing Proper Back Navigation
-page.tags="back navigation","NavUtils","TaskStackBuilder"
+page.tags=back navigation,NavUtils,TaskStackBuilder
 
 trainingnavtop=true
 
diff --git a/docs/html/training/improving-layouts/index.jd b/docs/html/training/improving-layouts/index.jd
index 8cb2258..a2ab7a1 100644
--- a/docs/html/training/improving-layouts/index.jd
+++ b/docs/html/training/improving-layouts/index.jd
@@ -1,5 +1,5 @@
 page.title=Improving Layout Performance
-page.tags="include","merge","viewstub","listview"
+page.tags=include,merge,viewstub,listview
 
 trainingnavtop=true
 startpage=true
@@ -63,4 +63,4 @@
     <dd>If you've built an instance of {@link android.widget.ListView} that contains complex or
 data-heavy content in each list item, the scroll performance of the list might suffer. This
 lesson provides some tips about how you can make your scrolling performance more smooth.</dd>
-</dl>
\ No newline at end of file
+</dl>
diff --git a/docs/html/training/in-app-billing/index.jd b/docs/html/training/in-app-billing/index.jd
index 94708b8..4a446f3 100644
--- a/docs/html/training/in-app-billing/index.jd
+++ b/docs/html/training/in-app-billing/index.jd
@@ -1,5 +1,5 @@
 page.title=Selling In-app Products
-page.tags="billing"
+page.tags=billing
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/keyboard-input/index.jd b/docs/html/training/keyboard-input/index.jd
index 7ac79e6..46795c4 100644
--- a/docs/html/training/keyboard-input/index.jd
+++ b/docs/html/training/keyboard-input/index.jd
@@ -1,5 +1,5 @@
 page.title=Handling Keyboard Input
-page.tags="edittext","accessibility"
+page.tags=edittext,accessibility
 
 trainingnavtop=true
 startpage=true
@@ -52,4 +52,4 @@
     <dd>Learn how to respond directly to keyboard input for user actions.
     </dd>
  
-</dl> 
\ No newline at end of file
+</dl> 
diff --git a/docs/html/training/load-data-background/index.jd b/docs/html/training/load-data-background/index.jd
index 29108e8..e991003 100644
--- a/docs/html/training/load-data-background/index.jd
+++ b/docs/html/training/load-data-background/index.jd
@@ -1,5 +1,5 @@
 page.title=Loading Data in the Background
-page.tags="cursorloader"
+page.tags=cursorloader
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/location/index.jd b/docs/html/training/location/index.jd
index e03eac6..249c42d 100644
--- a/docs/html/training/location/index.jd
+++ b/docs/html/training/location/index.jd
@@ -1,5 +1,5 @@
 page.title=Making Your App Location-Aware
-page.tags="location","geofence", "geofencing", "activity recognition", "activity detection", "gps"
+page.tags=location,geofence,geofencing,activity recognition,activity detection,gps
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/managing-audio/index.jd b/docs/html/training/managing-audio/index.jd
index 3e3bcf0..9391449 100644
--- a/docs/html/training/managing-audio/index.jd
+++ b/docs/html/training/managing-audio/index.jd
@@ -1,5 +1,5 @@
 page.title=Managing Audio Playback
-page.tags="audio","media"
+page.tags=audio,media
 
 trainingnavtop=true
 startpage=true
@@ -58,4 +58,4 @@
   <dt><b><a href="audio-output.html">Dealing with Audio Output Hardware</a></b></dt>
   <dd>Audio can be played from a number of sources. Learn how to find out where the audio is being
 played and how to handle a headset being disconnected during playback.</dd> 
- </dl> 
\ No newline at end of file
+ </dl> 
diff --git a/docs/html/training/monitoring-device-state/index.jd b/docs/html/training/monitoring-device-state/index.jd
index c3d700a..949c1da 100644
--- a/docs/html/training/monitoring-device-state/index.jd
+++ b/docs/html/training/monitoring-device-state/index.jd
@@ -1,5 +1,5 @@
 page.title=Optimizing Battery Life
-page.tags="network","internet"
+page.tags=network,internet
 
 trainingnavtop=true
 startpage=true
@@ -59,4 +59,4 @@
 those that aren't necessary due to the current device state. Learn to improve
 efficiency by toggling and cascading state change receivers and delay actions until the device is in
 a specific state.</dd>
-</dl> 
\ No newline at end of file
+</dl> 
diff --git a/docs/html/training/multiple-apks/index.jd b/docs/html/training/multiple-apks/index.jd
index 5754da9..40a26b9 100644
--- a/docs/html/training/multiple-apks/index.jd
+++ b/docs/html/training/multiple-apks/index.jd
@@ -1,5 +1,5 @@
 page.title=Maintaining Multiple APKs
-page.tags="support"
+page.tags=support
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/multiple-threads/index.jd b/docs/html/training/multiple-threads/index.jd
index cbd42b4..136f0af 100644
--- a/docs/html/training/multiple-threads/index.jd
+++ b/docs/html/training/multiple-threads/index.jd
@@ -1,5 +1,5 @@
 page.title=Sending Operations to Multiple Threads
-page.tags="threadpool","runnable"
+page.tags=threadpool,runnable
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/multiscreen/index.jd b/docs/html/training/multiscreen/index.jd
index 2d34b28..45b6161 100644
--- a/docs/html/training/multiscreen/index.jd
+++ b/docs/html/training/multiscreen/index.jd
@@ -1,5 +1,5 @@
 page.title=Designing for Multiple Screens
-page.tags="tablet","tv","fragments","support"
+page.tags=tablet,tv,fragments,support
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/notify-user/index.jd b/docs/html/training/notify-user/index.jd
index 51f058f..f7d0f87 100644
--- a/docs/html/training/notify-user/index.jd
+++ b/docs/html/training/notify-user/index.jd
@@ -1,5 +1,5 @@
 page.title=Notifying the User
-page.tags="notifications"
+page.tags=notifications
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/printing/index.jd b/docs/html/training/printing/index.jd
index 8161b6b..e33e5e8 100644
--- a/docs/html/training/printing/index.jd
+++ b/docs/html/training/printing/index.jd
@@ -1,5 +1,5 @@
 page.title=Printing Content
-page.tags="print","navigation","gesturedetector","scroller"
+page.tags=print,navigation,gesturedetector,scroller
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/run-background-service/index.jd b/docs/html/training/run-background-service/index.jd
index 3360df5..22f3fc8 100644
--- a/docs/html/training/run-background-service/index.jd
+++ b/docs/html/training/run-background-service/index.jd
@@ -1,5 +1,5 @@
 page.title=Running in a Background Service
-page.tags="intentservice"
+page.tags=intentservice
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/scheduling/index.jd b/docs/html/training/scheduling/index.jd
index 9ffbc16..4d2db60 100644
--- a/docs/html/training/scheduling/index.jd
+++ b/docs/html/training/scheduling/index.jd
@@ -1,5 +1,5 @@
 page.title=Managing Device Awake State
-page.tags=""
+page.tags=
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/search/index.jd b/docs/html/training/search/index.jd
index 4070372..612e8e8 100644
--- a/docs/html/training/search/index.jd
+++ b/docs/html/training/search/index.jd
@@ -1,5 +1,5 @@
 page.title=Adding Search Functionality
-page.tags="searchview","database"
+page.tags=searchview,database
 
 trainingnavtop=true
 startpage=true
@@ -50,4 +50,4 @@
     <dt><b><a href="backward-compat.html">Remaining Backward Compatible</a></b></dt>
 
     <dd>Learn how to keep search features backward compatible with older devices by using.</dd>
-  </dl>
\ No newline at end of file
+  </dl>
diff --git a/docs/html/training/secure-file-sharing/index.jd b/docs/html/training/secure-file-sharing/index.jd
index aa009fc..4adc1c0 100644
--- a/docs/html/training/secure-file-sharing/index.jd
+++ b/docs/html/training/secure-file-sharing/index.jd
@@ -1,5 +1,5 @@
 page.title=Sharing Files
-page.tags="FileProvider","share","ContentProvider"
+page.tags=FileProvider,share,ContentProvider
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/sharing/index.jd b/docs/html/training/sharing/index.jd
index 06d42fc..58a69fc 100644
--- a/docs/html/training/sharing/index.jd
+++ b/docs/html/training/sharing/index.jd
@@ -1,5 +1,5 @@
 page.title=Sharing Simple Data
-page.tags="intents","share"
+page.tags=intents,share
 
 trainingnavtop=true
 startpage=true
diff --git a/docs/html/training/system-ui/index.jd b/docs/html/training/system-ui/index.jd
index c45327f..56fa54b 100644
--- a/docs/html/training/system-ui/index.jd
+++ b/docs/html/training/system-ui/index.jd
@@ -1,5 +1,5 @@
 page.title=Managing the System UI
-page.tags=""
+page.tags=
 
 trainingnavtop=true
 startpage=true
@@ -120,4 +120,4 @@
         so that you can adjust your app's UI accordingly.
     </dd>
 
-</dl>
\ No newline at end of file
+</dl>
diff --git a/docs/html/training/tv/index.jd b/docs/html/training/tv/index.jd
index 54f7016..a99e378 100644
--- a/docs/html/training/tv/index.jd
+++ b/docs/html/training/tv/index.jd
@@ -1,5 +1,5 @@
 page.title=Designing for TV
-page.tags="input","screens"
+page.tags=input,screens
 
 trainingnavtop=true
 startpage=true
diff --git a/drm/java/android/drm/DrmOutputStream.java b/drm/java/android/drm/DrmOutputStream.java
index 87677b8..22e7ac2 100644
--- a/drm/java/android/drm/DrmOutputStream.java
+++ b/drm/java/android/drm/DrmOutputStream.java
@@ -18,18 +18,23 @@
 
 import static android.drm.DrmConvertedStatus.STATUS_OK;
 import static android.drm.DrmManagerClient.INVALID_SESSION;
+import static libcore.io.OsConstants.SEEK_SET;
 
+import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
+import libcore.io.ErrnoException;
+import libcore.io.IoBridge;
+import libcore.io.Libcore;
+import libcore.io.Streams;
+
+import java.io.FileDescriptor;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.io.RandomAccessFile;
 import java.net.UnknownServiceException;
 import java.util.Arrays;
 
-import libcore.io.Streams;
-
 /**
  * Stream that applies a {@link DrmManagerClient} transformation to data before
  * writing to disk, similar to a {@link FilterOutputStream}.
@@ -40,17 +45,19 @@
     private static final String TAG = "DrmOutputStream";
 
     private final DrmManagerClient mClient;
-    private final RandomAccessFile mFile;
+    private final ParcelFileDescriptor mPfd;
+    private final FileDescriptor mFd;
 
     private int mSessionId = INVALID_SESSION;
 
     /**
-     * @param file Opened with "rw" mode.
+     * @param pfd Opened with "rw" mode.
      */
-    public DrmOutputStream(DrmManagerClient client, RandomAccessFile file, String mimeType)
+    public DrmOutputStream(DrmManagerClient client, ParcelFileDescriptor pfd, String mimeType)
             throws IOException {
         mClient = client;
-        mFile = file;
+        mPfd = pfd;
+        mFd = pfd.getFileDescriptor();
 
         mSessionId = mClient.openConvertSession(mimeType);
         if (mSessionId == INVALID_SESSION) {
@@ -61,8 +68,12 @@
     public void finish() throws IOException {
         final DrmConvertedStatus status = mClient.closeConvertSession(mSessionId);
         if (status.statusCode == STATUS_OK) {
-            mFile.seek(status.offset);
-            mFile.write(status.convertedData);
+            try {
+                Libcore.os.lseek(mFd, status.offset, SEEK_SET);
+            } catch (ErrnoException e) {
+                e.rethrowAsIOException();
+            }
+            IoBridge.write(mFd, status.convertedData, 0, status.convertedData.length);
             mSessionId = INVALID_SESSION;
         } else {
             throw new IOException("Unexpected DRM status: " + status.statusCode);
@@ -75,7 +86,7 @@
             Log.w(TAG, "Closing stream without finishing");
         }
 
-        mFile.close();
+        mPfd.close();
     }
 
     @Override
@@ -92,7 +103,7 @@
 
         final DrmConvertedStatus status = mClient.convertData(mSessionId, exactBuffer);
         if (status.statusCode == STATUS_OK) {
-            mFile.write(status.convertedData);
+            IoBridge.write(mFd, status.convertedData, 0, status.convertedData.length);
         } else {
             throw new IOException("Unexpected DRM status: " + status.statusCode);
         }
diff --git a/drm/java/android/drm/DrmUtils.java b/drm/java/android/drm/DrmUtils.java
index 4f7cb22..2a86996 100644
--- a/drm/java/android/drm/DrmUtils.java
+++ b/drm/java/android/drm/DrmUtils.java
@@ -19,7 +19,6 @@
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 9b71d64..06cf253 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1624,7 +1624,8 @@
 
     private static native void nativePrepareToDraw(long nativeBitmap);
     private static native boolean nativeHasAlpha(long nativeBitmap);
-    private static native void nativeSetAlphaAndPremultiplied(long nBitmap, boolean hasAlpha,
+    private static native void nativeSetAlphaAndPremultiplied(long nativeBitmap,
+                                                              boolean hasAlpha,
                                                               boolean isPremul);
     private static native boolean nativeHasMipMap(long nativeBitmap);
     private static native void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap);
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 67e8f23..c20502f 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -307,17 +307,22 @@
         public boolean inPreferQualityOverSpeed;
 
         /**
-         * The resulting width of the bitmap, set independent of the state of
-         * inJustDecodeBounds. However, if there is an error trying to decode,
-         * outWidth will be set to -1.
+         * The resulting width of the bitmap. If {@link #inJustDecodeBounds} is
+         * set to false, this will be width of the output bitmap after any
+         * scaling is applied. If true, it will be the width of the input image
+         * without any accounting for scaling.
+         *
+         * <p>outWidth will be set to -1 if there is an error trying to decode.</p>
          */
-
         public int outWidth;
 
         /**
-         * The resulting height of the bitmap, set independent of the state of
-         * inJustDecodeBounds. However, if there is an error trying to decode,
-         * outHeight will be set to -1. 
+         * The resulting height of the bitmap. If {@link #inJustDecodeBounds} is
+         * set to false, this will be height of the output bitmap after any
+         * scaling is applied. If true, it will be the height of the input image
+         * without any accounting for scaling.
+         *
+         * <p>outHeight will be set to -1 if there is an error trying to decode.</p>
          */
         public int outHeight;
 
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index f86840e..2b72b93 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1403,7 +1403,7 @@
             throw new IndexOutOfBoundsException();
         }
         native_drawText(mNativeCanvas, text, index, count, x, y, paint.mBidiFlags,
-                paint.mNativePaint);
+                paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1417,7 +1417,7 @@
      */
     public void drawText(String text, float x, float y, Paint paint) {
         native_drawText(mNativeCanvas, text, 0, text.length(), x, y, paint.mBidiFlags,
-                paint.mNativePaint);
+                paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1436,7 +1436,7 @@
             throw new IndexOutOfBoundsException();
         }
         native_drawText(mNativeCanvas, text, start, end, x, y, paint.mBidiFlags,
-                paint.mNativePaint);
+                paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1456,7 +1456,7 @@
         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, paint.mNativeTypeface);
         } else if (text instanceof GraphicsOperations) {
             ((GraphicsOperations) text).drawText(this, start, end, x, y,
                     paint);
@@ -1464,7 +1464,7 @@
             char[] buf = TemporaryBuffer.obtain(end - start);
             TextUtils.getChars(text, start, end, buf, 0);
             native_drawText(mNativeCanvas, buf, 0, end - start, x, y,
-                    paint.mBidiFlags, paint.mNativePaint);
+                    paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
             TemporaryBuffer.recycle(buf);
         }
     }
@@ -1507,7 +1507,7 @@
         }
 
         native_drawTextRun(mNativeCanvas, text, index, count,
-                contextIndex, contextCount, x, y, dir, paint.mNativePaint);
+                contextIndex, contextCount, x, y, dir, paint.mNativePaint, paint.mNativeTypeface);
     }
 
     /**
@@ -1545,7 +1545,7 @@
         if (text instanceof String || text instanceof SpannedString ||
                 text instanceof SpannableString) {
             native_drawTextRun(mNativeCanvas, text.toString(), start, end,
-                    contextStart, contextEnd, x, y, flags, paint.mNativePaint);
+                    contextStart, contextEnd, x, y, flags, paint.mNativePaint, paint.mNativeTypeface);
         } else if (text instanceof GraphicsOperations) {
             ((GraphicsOperations) text).drawTextRun(this, start, end,
                     contextStart, contextEnd, x, y, flags, paint);
@@ -1555,7 +1555,7 @@
             char[] buf = TemporaryBuffer.obtain(contextLen);
             TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
             native_drawTextRun(mNativeCanvas, buf, start - contextStart, len,
-                    0, contextLen, x, y, flags, paint.mNativePaint);
+                    0, contextLen, x, y, flags, paint.mNativePaint, paint.mNativeTypeface);
             TemporaryBuffer.recycle(buf);
         }
     }
@@ -1830,20 +1830,20 @@
 
     private static native void native_drawText(long nativeCanvas, char[] text,
                                                int index, int count, float x,
-                                               float y, int flags,
-                                               long nativePaint);
+                                               float y, int flags, long nativePaint,
+                                               long nativeTypeface);
     private static native void native_drawText(long nativeCanvas, String text,
                                                int start, int end, float x,
-                                               float y, int flags,
-                                               long nativePaint);
+                                               float y, int flags, long nativePaint,
+                                               long nativeTypeface);
 
     private static native void native_drawTextRun(long nativeCanvas, String text,
             int start, int end, int contextStart, int contextEnd,
-            float x, float y, int flags, long nativePaint);
+            float x, float y, int flags, long nativePaint, long nativeTypeface);
 
     private static native void native_drawTextRun(long nativeCanvas, char[] text,
             int start, int count, int contextStart, int contextCount,
-            float x, float y, int flags, long nativePaint);
+            float x, float y, int flags, long nativePaint, long nativeTypeface);
 
     private static native void native_drawPosText(long nativeCanvas,
                                                   char[] text, int index,
diff --git a/graphics/java/android/graphics/ColorFilter.java b/graphics/java/android/graphics/ColorFilter.java
index 8e432da..4838aa0 100644
--- a/graphics/java/android/graphics/ColorFilter.java
+++ b/graphics/java/android/graphics/ColorFilter.java
@@ -21,22 +21,27 @@
 
 package android.graphics;
 
-
+/**
+ * A color filter can be used with a {@link Paint} to modify the color of
+ * each pixel drawn with that paint. This is an abstract class that should
+ * never be used directly.
+ */
 public class ColorFilter {
-    long native_instance;
-
     /**
+     * Holds the pointer to the native SkColorFilter instance.
+     *
      * @hide
      */
-    public long nativeColorFilter;
+    public long native_instance;
 
+    @Override
     protected void finalize() throws Throwable {
         try {
             super.finalize();
         } finally {
-            finalizer(native_instance, nativeColorFilter);
+            destroyFilter(native_instance);
         }
     }
 
-    private static native void finalizer(long native_instance, long nativeColorFilter);
+    static native void destroyFilter(long native_instance);
 }
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
index e3596c8..1242eb5 100644
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ b/graphics/java/android/graphics/ColorMatrix.java
@@ -18,23 +18,29 @@
 
 import android.util.FloatMath;
 
+import java.util.Arrays;
+
 /**
  *  4x5 matrix for transforming the color+alpha components of a Bitmap.
  *  The matrix is stored in a single array, and its treated as follows:
+ * <pre>
  *  [ a, b, c, d, e,
  *    f, g, h, i, j,
  *    k, l, m, n, o,
  *    p, q, r, s, t ]
+ * </pre>
  *
- * When applied to a color [r, g, b, a], the resulting color is computed as
- * (after clamping)
+ * When applied to a color <code>[r, g, b, a]</code>, the resulting color
+ * is computed as (after clamping):
+ * <pre>
  *   R' = a*R + b*G + c*B + d*A + e;
  *   G' = f*R + g*G + h*B + i*A + j;
  *   B' = k*R + l*G + m*B + n*A + o;
  *   A' = p*R + q*G + r*B + s*A + t;
+ * </pre>
  */
+@SuppressWarnings({ "MismatchedReadAndWriteOfArray", "PointlessArithmeticExpression" })
 public class ColorMatrix {
-
     private final float[] mArray = new float[20];
 
     /**
@@ -66,17 +72,16 @@
     
     /**
      * Set this colormatrix to identity:
+     * <pre>
      * [ 1 0 0 0 0   - red vector
      *   0 1 0 0 0   - green vector
      *   0 0 1 0 0   - blue vector
      *   0 0 0 1 0 ] - alpha vector
+     * </pre>
      */
     public void reset() {
         final float[] a = mArray;
-        
-        for (int i = 19; i > 0; --i) {
-            a[i] = 0;
-        }
+        Arrays.fill(a, 0);
         a[0] = a[6] = a[12] = a[18] = 1;
     }
     
@@ -112,9 +117,9 @@
     
     /**
      * Set the rotation on a color axis by the specified values.
-     * axis=0 correspond to a rotation around the RED color
-     * axis=1 correspond to a rotation around the GREEN color
-     * axis=2 correspond to a rotation around the BLUE color
+     * <code>axis=0</code> correspond to a rotation around the RED color
+     * <code>axis=1</code> correspond to a rotation around the GREEN color
+     * <code>axis=2</code> correspond to a rotation around the BLUE color
      */
     public void setRotate(int axis, float degrees) {
         reset();
@@ -144,7 +149,7 @@
             throw new RuntimeException();
         }
     }
-    
+
     /**
      * Set this colormatrix to the concatenation of the two specified
      * colormatrices, such that the resulting colormatrix has the same effect
@@ -152,12 +157,10 @@
      * matB to be the same colormatrix as this.
      */
     public void setConcat(ColorMatrix matA, ColorMatrix matB) {
-        float[] tmp = null;
-        
+        float[] tmp;
         if (matA == this || matB == this) {
             tmp = new float[20];
-        }
-        else {
+        } else {
             tmp = mArray;
         }
         
@@ -178,7 +181,7 @@
             System.arraycopy(tmp, 0, mArray, 0, 20);
         }
     }
-    
+
     /**
      * Concat this colormatrix with the specified prematrix. This is logically
      * the same as calling setConcat(this, prematrix);
@@ -186,7 +189,7 @@
     public void preConcat(ColorMatrix prematrix) {
         setConcat(this, prematrix);
     }
-    
+
     /**
      * Concat this colormatrix with the specified postmatrix. This is logically
      * the same as calling setConcat(postmatrix, this);
@@ -194,7 +197,7 @@
     public void postConcat(ColorMatrix postmatrix) {
         setConcat(postmatrix, this);
     }
-    
+
     ///////////////////////////////////////////////////////////////////////////
     
     /**
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 21b7721..7822c41 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -16,24 +16,31 @@
 
 package android.graphics;
 
+/**
+ * A color filter that transforms colors through a 4x5 color matrix. This filter
+ * can be used to change the saturation of pixels, convert from YUV to RGB, etc.
+ *
+ * @see ColorMatrix
+ */
 public class ColorMatrixColorFilter extends ColorFilter {
+    private final ColorMatrix mMatrix = new ColorMatrix();
+
     /**
-     * Create a colorfilter that transforms colors through a 4x5 color matrix.
+     * Create a color filter that transforms colors through a 4x5 color matrix.
      *
      * @param matrix 4x5 matrix used to transform colors. It is copied into
      *               the filter, so changes made to the matrix after the filter
      *               is constructed will not be reflected in the filter.
      */
     public ColorMatrixColorFilter(ColorMatrix matrix) {
-        final float[] colorMatrix = matrix.getArray();
-        native_instance = nativeColorMatrixFilter(colorMatrix);
-        nativeColorFilter = nColorMatrixFilter(native_instance, colorMatrix);
+        mMatrix.set(matrix);
+        update();
     }
 
     /**
-    * Create a colorfilter that transforms colors through a 4x5 color matrix.
+     * Create a color filter that transforms colors through a 4x5 color matrix.
      *
-     * @param array array of floats used to transform colors, treated as a 4x5
+     * @param array Array of floats used to transform colors, treated as a 4x5
      *              matrix. The first 20 entries of the array are copied into
      *              the filter. See ColorMatrix.
      */
@@ -41,10 +48,75 @@
         if (array.length < 20) {
             throw new ArrayIndexOutOfBoundsException();
         }
-        native_instance = nativeColorMatrixFilter(array);
-        nativeColorFilter = nColorMatrixFilter(native_instance, array);
+        mMatrix.set(array);
+        update();
+    }
+
+    /**
+     * Returns the {@link ColorMatrix} used by this filter. The returned
+     * value is never null. Modifying the returned matrix does not have
+     * any effect until you call {@link #setColorMatrix(ColorMatrix)}.
+     *
+     * @see #setColorMatrix(ColorMatrix)
+     */
+    public ColorMatrix getColorMatrix() {
+        return mMatrix;
+    }
+
+    /**
+     * Specifies the color matrix used by this filter. If the specified
+     * color matrix is null, this filter's color matrix will be reset to
+     * the identity matrix.
+     *
+     * @param matrix A {@link ColorMatrix} or null
+     *
+     * @see #getColorMatrix()
+     * @see android.graphics.ColorMatrix#reset()
+     * @see #setColorMatrix(float[])
+     */
+    public void setColorMatrix(ColorMatrix matrix) {
+        if (matrix == null) {
+            mMatrix.reset();
+        } else if (matrix != mMatrix) {
+            mMatrix.set(matrix);
+        }
+        update();
+    }
+
+    /**
+     * Specifies the color matrix used by this filter. If the specified
+     * color matrix is null, this filter's color matrix will be reset to
+     * the identity matrix.
+     *
+     * @param array Array of floats used to transform colors, treated as a 4x5
+     *              matrix. The first 20 entries of the array are copied into
+     *              the filter. See {@link ColorMatrix}.
+     *
+     * @see #getColorMatrix()
+     * @see android.graphics.ColorMatrix#reset()
+     * @see #setColorMatrix(ColorMatrix)
+     *
+     * @throws ArrayIndexOutOfBoundsException if the specified array's
+     *         length is < 20
+     */
+    public void setColorMatrix(float[] array) {
+        if (array == null) {
+            mMatrix.reset();
+        } else {
+            if (array.length < 20) {
+                throw new ArrayIndexOutOfBoundsException();
+            }
+
+            mMatrix.set(array);
+        }
+        update();
+    }
+
+    private void update() {
+        final float[] colorMatrix = mMatrix.getArray();
+        destroyFilter(native_instance);
+        native_instance = nativeColorMatrixFilter(colorMatrix);
     }
 
     private static native long nativeColorMatrixFilter(float[] array);
-    private static native long nColorMatrixFilter(long nativeFilter, float[] array);
 }
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 1bcfc18..e08ed50 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -187,6 +187,10 @@
      * == {@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
@@ -203,8 +207,6 @@
      * needed information to interpret a raw sensor image must be queried from
      * the {@link android.hardware.camera2.CameraDevice} which produced the
      * image.</p>
-     *
-     * @hide
      */
     public static final int RAW_SENSOR = 0x20;
 
diff --git a/graphics/java/android/graphics/LargeBitmap.java b/graphics/java/android/graphics/LargeBitmap.java
index 238b32a..936c338 100644
--- a/graphics/java/android/graphics/LargeBitmap.java
+++ b/graphics/java/android/graphics/LargeBitmap.java
@@ -16,16 +16,6 @@
 
 package android.graphics;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.DisplayMetrics;
-
-import java.io.OutputStream;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
-
 /**
  * LargeBitmap can be used to decode a rectangle region from an image.
  * LargeBimap is particularly useful when an original image is large and
diff --git a/graphics/java/android/graphics/LayerRasterizer.java b/graphics/java/android/graphics/LayerRasterizer.java
index dc307c6..5b356089 100644
--- a/graphics/java/android/graphics/LayerRasterizer.java
+++ b/graphics/java/android/graphics/LayerRasterizer.java
@@ -21,11 +21,11 @@
         native_instance = nativeConstructor();
     }
     
-	/**	Add a new layer (above any previous layers) to the rasterizer.
-		The layer will extract those fields that affect the mask from
-		the specified paint, but will not retain a reference to the paint
-		object itself, so it may be reused without danger of side-effects.
-	*/
+    /** Add a new layer (above any previous layers) to the rasterizer.
+        The layer will extract those fields that affect the mask from
+        the specified paint, but will not retain a reference to the paint
+        object itself, so it may be reused without danger of side-effects.
+    */
     public void addLayer(Paint paint, float dx, float dy) {
         nativeAddLayer(native_instance, paint.mNativePaint, dx, dy);
     }
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index fbd2694..70a3fe8 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -21,18 +21,87 @@
 
 package android.graphics;
 
+/**
+ * A color filter that can be used to simulate simple lighting effects.
+ * A <code>LightingColorFilter</code> is defined by two parameters, one
+ * used to multiply the source color (called <code>colorMultiply</code>)
+ * and one used to add to the source color (called <code>colorAdd</code>).
+ * The alpha channel is left untouched by this color filter.
+ *
+ * Given a source color RGB, the resulting R'G'B' color is computed thusly:
+ * <pre>
+ * R' = R * colorMultiply.R + colorAdd.R
+ * G' = G * colorMultiply.G + colorAdd.G
+ * B' = B * colorMultiply.B + colorAdd.B
+ * </pre>
+ * The result is pinned to the <code>[0..255]</code> range for each channel.
+ */
 public class LightingColorFilter extends ColorFilter {
+    private int mMul;
+    private int mAdd;
 
     /**
-     * Create a colorfilter that multiplies the RGB channels by one color, and then adds a second color,
-     * pinning the result for each component to [0..255]. The alpha components of the mul and add arguments
-     * are ignored.
+     * Create a colorfilter that multiplies the RGB channels by one color,
+     * and then adds a second color. The alpha components of the mul and add
+     * arguments are ignored.
+     *
+     * @see #setColorMultiply(int)
+     * @see #setColorAdd(int)
      */
     public LightingColorFilter(int mul, int add) {
-        native_instance = native_CreateLightingFilter(mul, add);
-        nativeColorFilter = nCreateLightingFilter(native_instance, mul, add);
+        mMul = mul;
+        mAdd = add;
+        update();
+    }
+
+    /**
+     * Returns the RGB color used to multiply the source color when the
+     * color filter is applied.
+     *
+     * @see #setColorMultiply(int)
+     */
+    public int getColorMultiply() {
+        return mMul;
+    }
+
+    /**
+     * Specifies the RGB color used to multiply the source color when the
+     * color filter is applied.
+     * The alpha channel of this color is ignored.
+     *
+     * @see #getColorMultiply()
+     */
+    public void setColorMultiply(int mul) {
+        mMul = mul;
+        update();
+    }
+
+    /**
+     * Returns the RGB color that will be added to the source color
+     * when the color filter is applied.
+     *
+     * @see #setColorAdd(int)
+     */
+    public int getColorAdd() {
+        return mAdd;
+    }
+
+    /**
+     * Specifies the RGB that will be added to the source color when
+     * the color filter is applied.
+     * The alpha channel of this color is ignored.
+     *
+     * @see #getColorAdd()
+     */
+    public void setColorAdd(int add) {
+        mAdd = add;
+        update();
+    }
+
+    private void update() {
+        destroyFilter(native_instance);
+        native_instance = native_CreateLightingFilter(mMul, mAdd);
     }
 
     private static native long native_CreateLightingFilter(int mul, int add);
-    private static native long nCreateLightingFilter(long nativeFilter, int mul, int add);
 }
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 9ad3e49..0eae67c 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -38,7 +38,7 @@
 
     private TileMode mTileMode;
 
-	/**	Create a shader that draws a linear gradient along a line.
+    /** 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
         @param x1           The x-coordinate for the end of the gradient line
@@ -48,8 +48,8 @@
                             each corresponding color in the colors array. If this is null,
                             the the colors are distributed evenly along the gradient line.
         @param  tile        The Shader tiling mode
-	*/
-	public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
+    */
+    public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
             TileMode tile) {
         if (colors.length < 2) {
             throw new IllegalArgumentException("needs >= 2 number of colors");
@@ -70,7 +70,7 @@
                 tile.nativeInt);
     }
 
-	/**	Create a shader that draws a linear gradient along a line.
+    /** 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
         @param x1       The x-coordinate for the end of the gradient line
@@ -78,8 +78,8 @@
         @param  color0  The color at the start of the gradient line.
         @param  color1  The color at the end of the gradient line.
         @param  tile    The Shader tiling mode
-	*/
-	public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1,
+    */
+    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;
@@ -118,7 +118,7 @@
 
     private native long nativeCreate1(float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
-	private native long nativeCreate2(float x0, float y0, float x1, float y1,
+    private native long nativeCreate2(float x0, float y0, float x1, float y1,
             int color0, int color1, int tileMode);
     private native long nativePostCreate1(long native_shader, float x0, float y0, float x1, float y1,
             int colors[], float positions[], int tileMode);
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
new file mode 100644
index 0000000..a65ac87
--- /dev/null
+++ b/graphics/java/android/graphics/Outline.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics;
+
+/**
+ * Defines an area of content.
+ *
+ * Can be used with a View or Drawable to drive the shape of shadows cast by a
+ * View, and allowing Views to clip inner content.
+ *
+ * @see View#setOutline(Outline)
+ * @see View#setClipToOutline(boolean)
+ */
+public class Outline {
+    /** @hide */
+    public Rect mRect;
+
+    /** @hide */
+    public float mRadius;
+
+    /** @hide */
+    public Path mPath;
+
+    /**
+     * Constructs an invalid Outline. Call one of the setter methods to make
+     * the outline valid for use with a View.
+     */
+    public Outline() {}
+
+    /**
+     * Returns whether the Outline is valid for use with a View.
+     * <p>
+     * Outlines are invalid when constructed until a setter method is called.
+     */
+    public final boolean isValid() {
+        return mRect != null || mPath != null;
+    }
+
+    /**
+     * @hide
+     */
+    public final boolean canClip() {
+        return mPath == null;
+    }
+
+    /**
+     * Replace the contents of this Outline with the contents of src.
+     */
+    public void set(Outline src) {
+        if (src.mPath != null) {
+            if (mPath == null) {
+                mPath = new Path();
+            }
+            mPath.set(src.mPath);
+            mRect = null;
+        }
+        if (src.mRect != null) {
+            if (mRect == null) {
+                mRect = new Rect();
+            }
+            mRect.set(src.mRect);
+        }
+        mRadius = src.mRadius;
+    }
+
+    /**
+     * Sets the Outline to the rounded rect defined by the input rect, and corner radius.
+     * <p>
+     * Outlines produced by this method support
+     * {@link View#setClipToOutline(boolean) View clipping.}
+     */
+    public void setRoundRect(int left, int top, int right, int bottom, float radius) {
+        if (mRect == null) mRect = new Rect();
+        mRect.set(left, top, right, bottom);
+        mRadius = radius;
+        mPath = null;
+    }
+
+    /**
+     * Sets the Constructs an Outline from a {@link android.graphics.Path#isConvex() convex path}.
+     *
+     * @hide
+     */
+    public void setConvexPath(Path convexPath) {
+        if (!convexPath.isConvex()) {
+            throw new IllegalArgumentException("path must be convex");
+        }
+        if (mPath == null) mPath = new Path();
+
+        mRect = null;
+        mRadius = -1.0f;
+        mPath.set(convexPath);
+    }
+}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 33832a7..916cb5a 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -33,6 +33,10 @@
      * @hide
      */
     public long mNativePaint;
+    /**
+     * @hide
+     */
+    public long mNativeTypeface;
 
     private ColorFilter mColorFilter;
     private MaskFilter  mMaskFilter;
@@ -481,6 +485,7 @@
         mRasterizer = null;
         mShader = null;
         mTypeface = null;
+        mNativeTypeface = 0;
         mXfermode = null;
 
         mHasCompatScaling = false;
@@ -525,6 +530,7 @@
             mShader = null;
         }
         mTypeface = paint.mTypeface;
+        mNativeTypeface = paint.mNativeTypeface;
         mXfermode = paint.mXfermode;
 
         mHasCompatScaling = paint.mHasCompatScaling;
@@ -1087,6 +1093,7 @@
         }
         native_setTypeface(mNativePaint, typefaceNative);
         mTypeface = typeface;
+        mNativeTypeface = typefaceNative;
         return typeface;
     }
     
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index b5a1f64..c07a6da 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -16,8 +16,6 @@
 
 package android.graphics;
 
-import android.view.HardwareRenderer;
-
 /**
  * The Path class encapsulates compound (multiple contour) geometric paths
  * consisting of straight line segments, quadratic curves, and cubic curves.
@@ -39,7 +37,6 @@
      * @hide
      */
     public Region rects;
-    private boolean mDetectSimplePaths;
     private Direction mLastDirection = null;
 
     /**
@@ -47,7 +44,6 @@
      */
     public Path() {
         mNativePath = init1();
-        mDetectSimplePaths = HardwareRenderer.isAvailable();
     }
 
     /**
@@ -65,7 +61,6 @@
             }
         }
         mNativePath = init2(valNative);
-        mDetectSimplePaths = HardwareRenderer.isAvailable();
     }
     
     /**
@@ -74,10 +69,8 @@
      */
     public void reset() {
         isSimplePath = true;
-        if (mDetectSimplePaths) {
-            mLastDirection = null;
-            if (rects != null) rects.setEmpty();
-        }
+        mLastDirection = null;
+        if (rects != null) rects.setEmpty();
         // We promised not to change this, so preserve it around the native
         // call, which does now reset fill type.
         final FillType fillType = getFillType();
@@ -91,10 +84,8 @@
      */
     public void rewind() {
         isSimplePath = true;
-        if (mDetectSimplePaths) {
-            mLastDirection = null;
-            if (rects != null) rects.setEmpty();
-        }
+        mLastDirection = null;
+        if (rects != null) rects.setEmpty();
         native_rewind(mNativePath);
     }
 
@@ -177,6 +168,21 @@
     }
 
     /**
+     * Returns the path's convexity, as defined by the content of the path.
+     * <p>
+     * A path is convex if it has a single contour, and only ever curves in a
+     * single direction.
+     * <p>
+     * This function will calculate the convexity of the path from its control
+     * points, and cache the result.
+     *
+     * @return True if the path is convex.
+     */
+    public boolean isConvex() {
+        return native_isConvex(mNativePath);
+    }
+
+    /**
      * Enum for the ways a path may be filled.
      */
     public enum FillType {
@@ -233,7 +239,7 @@
     public void setFillType(FillType ft) {
         native_setFillType(mNativePath, ft.nativeInt);
     }
-    
+
     /**
      * Returns true if the filltype is one of the INVERSE variants
      *
@@ -241,18 +247,18 @@
      */
     public boolean isInverseFillType() {
         final int ft = native_getFillType(mNativePath);
-        return (ft & 2) != 0;
+        return (ft & FillType.INVERSE_WINDING.nativeInt) != 0;
     }
-    
+
     /**
      * Toggles the INVERSE state of the filltype
      */
     public void toggleInverseFillType() {
         int ft = native_getFillType(mNativePath);
-        ft ^= 2;
+        ft ^= FillType.INVERSE_WINDING.nativeInt;
         native_setFillType(mNativePath, ft);
     }
-    
+
     /**
      * Returns true if the path is empty (contains no lines or curves)
      *
@@ -475,16 +481,14 @@
     }
     
     private void detectSimplePath(float left, float top, float right, float bottom, Direction dir) {
-        if (mDetectSimplePaths) {
-            if (mLastDirection == null) {
-                mLastDirection = dir;
-            }
-            if (mLastDirection != dir) {
-                isSimplePath = false;
-            } else {
-                if (rects == null) rects = new Region();
-                rects.op((int) left, (int) top, (int) right, (int) bottom, Region.Op.UNION);
-            }
+        if (mLastDirection == null) {
+            mLastDirection = dir;
+        }
+        if (mLastDirection != dir) {
+            isSimplePath = false;
+        } else {
+            if (rects == null) rects = new Region();
+            rects.op((int) left, (int) top, (int) right, (int) bottom, Region.Op.UNION);
         }
     }
 
@@ -703,11 +707,34 @@
         return mNativePath;
     }
 
+    /**
+     * Approximate the <code>Path</code> with a series of line segments.
+     * This returns float[] with the array containing point components.
+     * There are three components for each point, in order:
+     * <ul>
+     *     <li>Fraction along the length of the path that the point resides</li>
+     *     <li>The x coordinate of the point</li>
+     *     <li>The y coordinate of the point</li>
+     * </ul>
+     * <p>Two points may share the same fraction along its length when there is
+     * a move action within the Path.</p>
+     *
+     * @param acceptableError The acceptable error for a line on the
+     *                        Path. Typically this would be 0.5 so that
+     *                        the error is less than half a pixel.
+     * @return An array of components for points approximating the Path.
+     * @hide
+     */
+    public float[] approximate(float acceptableError) {
+        return native_approximate(mNativePath, acceptableError);
+    }
+
     private static native long init1();
     private static native long init2(long nPath);
     private static native void native_reset(long nPath);
     private static native void native_rewind(long nPath);
     private static native void native_set(long native_dst, long native_src);
+    private static native boolean native_isConvex(long nPath);
     private static native int native_getFillType(long nPath);
     private static native void native_setFillType(long nPath, int ft);
     private static native boolean native_isEmpty(long nPath);
@@ -749,4 +776,5 @@
     private static native void native_transform(long nPath, long matrix);
     private static native boolean native_op(long path1, long path2, int op, long result);
     private static native void finalizer(long nPath);
+    private static native float[] native_approximate(long nPath, float error);
 }
diff --git a/graphics/java/android/graphics/PathMeasure.java b/graphics/java/android/graphics/PathMeasure.java
index e56716f..ba2228c 100644
--- a/graphics/java/android/graphics/PathMeasure.java
+++ b/graphics/java/android/graphics/PathMeasure.java
@@ -113,9 +113,15 @@
      * segment(s). If the segment is zero-length, return false, else return
      * true. startD and stopD are pinned to legal values (0..getLength()).
      * If startD <= stopD then return false (and leave dst untouched).
-     * Begin the segment with a moveTo if startWithMoveTo is true
+     * Begin the segment with a moveTo if startWithMoveTo is true.
+     *
+     * <p>On {@link android.os.Build.VERSION_CODES#KITKAT} and earlier
+     * releases, the resulting path may not display on a hardware-accelerated
+     * Canvas. A simple workaround is to add a single operation to this path,
+     * such as <code>dst.rLineTo(0, 0)</code>.</p>
      */
     public boolean getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) {
+        dst.isSimplePath = false;
         return native_getSegment(native_instance, startD, stopD, dst.ni(), startWithMoveTo);
     }
 
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index 894284f..c078c1c 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -16,20 +16,84 @@
 
 package android.graphics;
 
+/**
+ * A color filter that can be used to tint the source pixels using a single
+ * color and a specific {@link PorterDuff Porter-Duff composite mode}.
+ */
 public class PorterDuffColorFilter extends ColorFilter {
+    private int mColor;
+    private PorterDuff.Mode mMode;
+
     /**
-     * Create a colorfilter that uses the specified color and porter-duff mode.
+     * Create a color filter that uses the specified color and Porter-Duff mode.
      *
-     * @param srcColor       The source color used with the specified
-     *                       porter-duff mode
-     * @param mode           The porter-duff mode that is applied
+     * @param color The ARGB source color used with the specified Porter-Duff mode
+     * @param mode The porter-duff mode that is applied
+     *
+     * @see Color
+     * @see #setColor(int)
+     * @see #setMode(android.graphics.PorterDuff.Mode)
      */
-    public PorterDuffColorFilter(int srcColor, PorterDuff.Mode mode) {
-        native_instance = native_CreatePorterDuffFilter(srcColor, mode.nativeInt);
-        nativeColorFilter = nCreatePorterDuffFilter(native_instance, srcColor, mode.nativeInt);
+    public PorterDuffColorFilter(int color, PorterDuff.Mode mode) {
+        mColor = color;
+        mMode = mode;
+        update();
+    }
+
+    /**
+     * Returns the ARGB color used to tint the source pixels when this filter
+     * is applied.
+     *
+     * @see Color
+     * @see #setColor(int)
+     */
+    public int getColor() {
+        return mColor;
+    }
+
+    /**
+     * Specifies the color to tint the source pixels with when this color
+     * filter is applied.
+     *
+     * @param color An ARGB {@link Color color}
+     *
+     * @see Color
+     * @see #getColor()
+     * @see #getMode()
+     */
+    public void setColor(int color) {
+        mColor = color;
+        update();
+    }
+
+    /**
+     * Returns the Porter-Duff mode used to composite this color filter's
+     * color with the source pixel when this filter is applied.
+     *
+     * @see PorterDuff
+     * @see #setMode(android.graphics.PorterDuff.Mode)
+     */
+    public PorterDuff.Mode getMode() {
+        return mMode;
+    }
+
+    /**
+     * Specifies the Porter-Duff mode to use when compositing this color
+     * filter's color with the source pixel at draw time.
+     *
+     * @see PorterDuff
+     * @see #getMode()
+     * @see #getColor()
+     */
+    public void setMode(PorterDuff.Mode mode) {
+        mMode = mode;
+        update();
+    }
+
+    private void update() {
+        destroyFilter(native_instance);
+        native_instance = native_CreatePorterDuffFilter(mColor, mMode.nativeInt);
     }
 
     private static native long native_CreatePorterDuffFilter(int srcColor, int porterDuffMode);
-    private static native long nCreatePorterDuffFilter(long nativeFilter, int srcColor,
-            int porterDuffMode);
 }
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index f10e5d6..c00c612 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -37,17 +37,17 @@
 
     private TileMode mTileMode;
 
-	/**	Create a shader that draws a radial gradient given the center and radius.
+    /** 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
-		@param radius   Must be positive. The radius of the circle for this gradient
+        @param radius   Must be positive. The radius of the circle for this gradient
         @param colors   The colors to be distributed between the center and edge of the circle
         @param positions May be NULL. The relative position of
                         each corresponding color in the colors array. If this is NULL,
                         the the colors are distributed evenly between the center and edge of the circle.
         @param  tile    The Shader tiling mode
-	*/
-	public RadialGradient(float x, float y, float radius,
+    */
+    public RadialGradient(float x, float y, float radius,
                           int colors[], float positions[], TileMode tile) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
@@ -70,15 +70,15 @@
                 tile.nativeInt);
     }
 
-	/**	Create a shader that draws a radial gradient given the center and radius.
+    /** 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
-		@param radius   Must be positive. The radius of the circle for this gradient
+        @param radius   Must be positive. The radius of the circle for this gradient
         @param color0   The color at the center of the circle.
         @param color1   The color at the edge of the circle.
         @param tile     The Shader tiling mode
-	*/
-	public RadialGradient(float x, float y, float radius,
+    */
+    public RadialGradient(float x, float y, float radius,
                           int color0, int color1, TileMode tile) {
         if (radius <= 0) {
             throw new IllegalArgumentException("radius must be > 0");
@@ -119,7 +119,7 @@
 
     private static native long nativeCreate1(float x, float y, float radius,
             int colors[], float positions[], int tileMode);
-	private static native long nativeCreate2(float x, float y, float radius,
+    private static native long nativeCreate2(float x, float y, float radius,
             int color0, int color1, int tileMode);
 
     private static native long nativePostCreate1(long native_shader, float x, float y, float radius,
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 1f8e223..d877502 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -70,7 +70,7 @@
      * These fields are used by native code, do not access or modify.
      */
     private long mSurfaceTexture;
-    private long mBufferQueue;
+    private long mProducer;
     private long mFrameAvailableListener;
 
     /**
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 936ea4f..73e0e8d 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -49,7 +49,10 @@
     private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache =
             new LongSparseArray<SparseArray<Typeface>>(3);
 
-    long native_instance;
+    /**
+     * @hide
+     */
+    public long native_instance;
 
     // Style
     public static final int NORMAL = 0;
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index bde978d..02b2588 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -81,6 +81,7 @@
 public class AnimationDrawable extends DrawableContainer implements Runnable, Animatable {
     private final AnimationState mAnimationState;
     private int mCurFrame = -1;
+    private boolean mAnimating;
     private boolean mMutated;
 
     public AnimationDrawable() {
@@ -137,7 +138,7 @@
      * @return true if the animation is running, false otherwise
      */
     public boolean isRunning() {
-        return mCurFrame > -1;
+        return mAnimating;
     }
 
     /**
@@ -153,6 +154,7 @@
     @Override
     public void unscheduleSelf(Runnable what) {
         mCurFrame = -1;
+        mAnimating = false;
         super.unscheduleSelf(what);
     }
 
@@ -222,12 +224,13 @@
         }
         mCurFrame = frame;
         selectDrawable(frame);
-        if (unschedule) {
+        if (unschedule || animate) {
             unscheduleSelf(this);
         }
         if (animate) {
-            // Unscheduling may have clobbered this value; restore it to record that we're animating
+            // Unscheduling may have clobbered these values; restore them
             mCurFrame = frame;
+            mAnimating = true;
             scheduleSelf(this, SystemClock.uptimeMillis() + mAnimationState.mDurations[frame]);
         }
     }
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 98e3386..fe08f4b 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
@@ -26,6 +27,8 @@
 import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.graphics.Xfermode;
@@ -33,6 +36,7 @@
 import android.util.DisplayMetrics;
 import android.util.LayoutDirection;
 import android.view.Gravity;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -46,8 +50,8 @@
  * information, see the guide to <a
  * href="{@docRoot}guide/topics/resources/drawable-resource.html">Drawable Resources</a>.</p>
  * <p>
- * Also see the {@link android.graphics.Bitmap} class, which handles the management and 
- * transformation of raw bitmap graphics, and should be used when drawing to a 
+ * Also see the {@link android.graphics.Bitmap} class, which handles the management and
+ * transformation of raw bitmap graphics, and should be used when drawing to a
  * {@link android.graphics.Canvas}.
  * </p>
  *
@@ -65,13 +69,14 @@
             Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG;
     private BitmapState mBitmapState;
     private Bitmap mBitmap;
+    private PorterDuffColorFilter mTintFilter;
     private int mTargetDensity;
 
     private final Rect mDstRect = new Rect();   // Gravity.apply() sets this
 
     private boolean mApplyGravity;
     private boolean mMutated;
-    
+
      // These are scaled to match the target density.
     private int mBitmapWidth;
     private int mBitmapHeight;
@@ -189,7 +194,7 @@
         mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);
         mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);
     }
-    
+
     private void setBitmap(Bitmap bitmap) {
         if (bitmap != mBitmap) {
             mBitmap = bitmap;
@@ -274,7 +279,7 @@
      *
      * @param mipMap True if the bitmap should use mipmaps, false otherwise.
      *
-     * @see #hasMipMap() 
+     * @see #hasMipMap()
      */
     public void setMipMap(boolean mipMap) {
         if (mBitmapState.mBitmap != null) {
@@ -289,7 +294,7 @@
      * @return True if the mipmap hint is set, false otherwise. If the bitmap
      *         is null, this method always returns false.
      *
-     * @see #setMipMap(boolean) 
+     * @see #setMipMap(boolean)
      * @attr ref android.R.styleable#BitmapDrawable_mipMap
      */
     public boolean hasMipMap() {
@@ -299,10 +304,10 @@
     /**
      * Enables or disables anti-aliasing for this drawable. Anti-aliasing affects
      * the edges of the bitmap only so it applies only when the drawable is rotated.
-     * 
+     *
      * @param aa True if the bitmap should be anti-aliased, false otherwise.
      *
-     * @see #hasAntiAlias() 
+     * @see #hasAntiAlias()
      */
     public void setAntiAlias(boolean aa) {
         mBitmapState.mPaint.setAntiAlias(aa);
@@ -334,7 +339,7 @@
 
     /**
      * Indicates the repeat behavior of this drawable on the X axis.
-     * 
+     *
      * @return {@link Shader.TileMode#CLAMP} if the bitmap does not repeat,
      *         {@link Shader.TileMode#REPEAT} or {@link Shader.TileMode#MIRROR} otherwise.
      */
@@ -344,10 +349,10 @@
 
     /**
      * Indicates the repeat behavior of this drawable on the Y axis.
-     * 
+     *
      * @return {@link Shader.TileMode#CLAMP} if the bitmap does not repeat,
      *         {@link Shader.TileMode#REPEAT} or {@link Shader.TileMode#MIRROR} otherwise.
-     */    
+     */
     public Shader.TileMode getTileModeY() {
         return mBitmapState.mTileModeY;
     }
@@ -357,11 +362,11 @@
      * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or
      * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap
      * is smaller than this drawable.
-     * 
+     *
      * @param mode The repeat mode for this drawable.
-     * 
-     * @see #setTileModeY(android.graphics.Shader.TileMode) 
-     * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode) 
+     *
+     * @see #setTileModeY(android.graphics.Shader.TileMode)
+     * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode)
      */
     public void setTileModeX(Shader.TileMode mode) {
         setTileModeXY(mode, mBitmapState.mTileModeY);
@@ -372,12 +377,12 @@
      * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or
      * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap
      * is smaller than this drawable.
-     * 
+     *
      * @param mode The repeat mode for this drawable.
-     * 
-     * @see #setTileModeX(android.graphics.Shader.TileMode) 
-     * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode) 
-     */    
+     *
+     * @see #setTileModeX(android.graphics.Shader.TileMode)
+     * @see #setTileModeXY(android.graphics.Shader.TileMode, android.graphics.Shader.TileMode)
+     */
     public final void setTileModeY(Shader.TileMode mode) {
         setTileModeXY(mBitmapState.mTileModeX, mode);
     }
@@ -387,12 +392,12 @@
      * does not repeat its bitmap. Using {@link Shader.TileMode#REPEAT} or
      * {@link Shader.TileMode#MIRROR} the bitmap can be repeated (or tiled) if the bitmap
      * is smaller than this drawable.
-     * 
+     *
      * @param xmode The X repeat mode for this drawable.
      * @param ymode The Y repeat mode for this drawable.
-     * 
+     *
      * @see #setTileModeX(android.graphics.Shader.TileMode)
-     * @see #setTileModeY(android.graphics.Shader.TileMode) 
+     * @see #setTileModeY(android.graphics.Shader.TileMode)
      */
     public void setTileModeXY(Shader.TileMode xmode, Shader.TileMode ymode) {
         final BitmapState state = mBitmapState;
@@ -454,66 +459,86 @@
 
     @Override
     public void draw(Canvas canvas) {
-        Bitmap bitmap = mBitmap;
-        if (bitmap != null) {
-            final BitmapState state = mBitmapState;
-            if (state.mRebuildShader) {
-                Shader.TileMode tmx = state.mTileModeX;
-                Shader.TileMode tmy = state.mTileModeY;
+        final Bitmap bitmap = mBitmap;
+        if (bitmap == null) {
+            return;
+        }
 
-                if (tmx == null && tmy == null) {
-                    state.mPaint.setShader(null);
-                } else {
-                    state.mPaint.setShader(new BitmapShader(bitmap,
-                            tmx == null ? Shader.TileMode.CLAMP : tmx,
-                            tmy == null ? Shader.TileMode.CLAMP : tmy));
-                }
-                state.mRebuildShader = false;
-                copyBounds(mDstRect);
-            }
-
-            Shader shader = state.mPaint.getShader();
-            final boolean needMirroring = needMirroring();
-            if (shader == null) {
-                if (mApplyGravity) {
-                    final int layoutDirection = getLayoutDirection();
-                    Gravity.apply(state.mGravity, mBitmapWidth, mBitmapHeight,
-                            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();
-                }
+        final BitmapState state = mBitmapState;
+        final Paint paint = state.mPaint;
+        if (state.mRebuildShader) {
+            final Shader.TileMode tmx = state.mTileModeX;
+            final Shader.TileMode tmy = state.mTileModeY;
+            if (tmx == null && tmy == null) {
+                paint.setShader(null);
             } 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);
+                paint.setShader(new BitmapShader(bitmap,
+                        tmx == null ? Shader.TileMode.CLAMP : tmx,
+                        tmy == null ? Shader.TileMode.CLAMP : tmy));
             }
+
+            state.mRebuildShader = false;
+            copyBounds(mDstRect);
+        }
+
+        final boolean clearColorFilter;
+        if (mTintFilter != null && paint.getColorFilter() == null) {
+            paint.setColorFilter(mTintFilter);
+            clearColorFilter = true;
+        } else {
+            clearColorFilter = false;
+        }
+
+        final Shader shader = paint.getShader();
+        final boolean needMirroring = needMirroring();
+        if (shader == null) {
+            if (mApplyGravity) {
+                final int layoutDirection = getLayoutDirection();
+                Gravity.apply(state.mGravity, mBitmapWidth, mBitmapHeight,
+                        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, paint);
+
+            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, paint);
+        }
+
+        if (clearColorFilter) {
+            paint.setColorFilter(null);
         }
     }
 
     @Override
     public void setAlpha(int alpha) {
-        int oldAlpha = mBitmapState.mPaint.getAlpha();
+        final int oldAlpha = mBitmapState.mPaint.getAlpha();
         if (alpha != oldAlpha) {
             mBitmapState.mPaint.setAlpha(alpha);
             invalidateSelf();
@@ -531,6 +556,80 @@
         invalidateSelf();
     }
 
+    @Override
+    public ColorFilter getColorFilter() {
+        return mBitmapState.mPaint.getColorFilter();
+    }
+
+    /**
+     * Specifies a tint for this drawable.
+     * <p>
+     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
+     * tint.
+     *
+     * @param tint Color state list to use for tinting this drawable, or null to
+     *            clear the tint
+     */
+    public void setTint(ColorStateList tint) {
+        if (mBitmapState.mTint != tint) {
+            mBitmapState.mTint = tint;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Returns the tint color for this drawable.
+     *
+     * @return Color state list to use for tinting this drawable, or null if
+     *         none set
+     */
+    public ColorStateList getTint() {
+        return mBitmapState.mTint;
+    }
+
+    /**
+     * Specifies the blending mode used to apply tint.
+     *
+     * @param tintMode A Porter-Duff blending mode
+     * @hide Pending finalization of supported Modes
+     */
+    public void setTintMode(Mode tintMode) {
+        if (mBitmapState.mTintMode != tintMode) {
+            mBitmapState.mTintMode = tintMode;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Returns the tint mode for this drawable, or {@code null} if none set.
+     *
+     * @return the tint mode for this drawable, or {@code null} if none set
+     * @hide
+     */
+    public Mode getTintMode() {
+        return mBitmapState.mTintMode;
+    }
+
+    /**
+     * Ensures the tint filter is consistent with the current tint color and
+     * mode.
+     */
+    private void updateTintFilter() {
+        final ColorStateList tint = mBitmapState.mTint;
+        final Mode tintMode = mBitmapState.mTintMode;
+        if (tint != null && tintMode != null) {
+            if (mTintFilter == null) {
+                mTintFilter = new PorterDuffColorFilter(0, tintMode);
+            } else {
+                mTintFilter.setMode(tintMode);
+            }
+        } else {
+            mTintFilter = null;
+        }
+    }
+
     /**
      * @hide Candidate for future API inclusion
      */
@@ -555,11 +654,34 @@
     }
 
     @Override
+    protected boolean onStateChange(int[] stateSet) {
+        final ColorStateList tint = mBitmapState.mTint;
+        if (tint != null) {
+            final int newColor = tint.getColorForState(stateSet, 0);
+            final int oldColor = mTintFilter.getColor();
+            if (oldColor != newColor) {
+                mTintFilter.setColor(newColor);
+                invalidateSelf();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isStateful() {
+        final BitmapState s = mBitmapState;
+        return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
+    }
+
+    @Override
     public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
             throws XmlPullParserException, IOException {
         super.inflate(r, parser, attrs);
 
-        TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.BitmapDrawable);
+        final BitmapState state = mBitmapState;
+        final TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.BitmapDrawable);
 
         final int id = a.getResourceId(com.android.internal.R.styleable.BitmapDrawable_src, 0);
         if (id == 0) {
@@ -571,7 +693,7 @@
             throw new XmlPullParserException(parser.getPositionDescription() +
                     ": <bitmap> requires a valid src attribute");
         }
-        mBitmapState.mBitmap = bitmap;
+        state.mBitmap = bitmap;
         setBitmap(bitmap);
         setTargetDensity(r.getDisplayMetrics());
         setMipMap(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_mipMap,
@@ -579,7 +701,16 @@
         setAutoMirrored(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_autoMirrored,
                 false));
 
-        final Paint paint = mBitmapState.mPaint;
+        final int tintModeValue = a.getInt(
+                com.android.internal.R.styleable.BitmapDrawable_tintMode, -1);
+        state.mTintMode = Drawable.parseTintMode(tintModeValue, Mode.SRC_IN);
+        state.mTint = a.getColorStateList(com.android.internal.R.styleable.BitmapDrawable_tint);
+        if (state.mTint != null) {
+            final int color = state.mTint.getColorForState(getState(), 0);
+            mTintFilter = new PorterDuffColorFilter(color, mBitmapState.mTintMode);
+        }
+
+        final Paint paint = state.mPaint;
         paint.setAntiAlias(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_antialias,
                 paint.isAntiAlias()));
         paint.setFilterBitmap(a.getBoolean(com.android.internal.R.styleable.BitmapDrawable_filter,
@@ -633,6 +764,8 @@
 
     final static class BitmapState extends ConstantState {
         Bitmap mBitmap;
+        ColorStateList mTint;
+        Mode mTintMode = Mode.SRC_IN;
         int mChangingConfigurations;
         int mGravity = Gravity.FILL;
         Paint mPaint = new Paint(DEFAULT_PAINT_FLAGS);
@@ -647,7 +780,9 @@
         }
 
         BitmapState(BitmapState bitmapState) {
-            this(bitmapState.mBitmap);
+            mBitmap = bitmapState.mBitmap;
+            mTint = bitmapState.mTint;
+            mTintMode = bitmapState.mTintMode;
             mChangingConfigurations = bitmapState.mChangingConfigurations;
             mGravity = bitmapState.mGravity;
             mTileModeX = bitmapState.mTileModeX;
@@ -681,11 +816,18 @@
 
     private BitmapDrawable(BitmapState state, Resources res) {
         mBitmapState = state;
+
         if (res != null) {
             mTargetDensity = res.getDisplayMetrics().densityDpi;
         } else {
             mTargetDensity = state.mTargetDensity;
         }
+
+        if (state.mTint != null) {
+            final int color = state.mTint.getColorForState(getState(), 0);
+            mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
+        }
+
         setBitmap(state != null ? state.mBitmap : null);
     }
 }
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 93738b0..eb6b536 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -19,6 +19,7 @@
 import android.graphics.Insets;
 import android.graphics.Xfermode;
 import android.os.Trace;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -29,16 +30,19 @@
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.graphics.NinePatch;
+import android.graphics.Outline;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.graphics.PorterDuff.Mode;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.StateSet;
 import android.util.TypedValue;
 import android.util.Xml;
+import android.view.View;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -82,7 +86,7 @@
  *     through the {@link Callback} interface.  All clients should support this
  *     interface (via {@link #setCallback}) so that animations will work.  A
  *     simple way to do this is through the system facilities such as
- *     {@link android.view.View#setBackgroundDrawable(Drawable)} and
+ *     {@link android.view.View#setBackground(Drawable)} and
  *     {@link android.widget.ImageView}.
  * </ul>
  *
@@ -116,6 +120,20 @@
  * document.</p></div>
  */
 public abstract class Drawable {
+    /**
+     * Hotspot identifier mask for tracking touch points.
+     *
+     * @hide until hotspot APIs are finalized
+     */
+    public static final int HOTSPOT_TOUCH_MASK = 0xFF;
+
+    /**
+     * Hotspot identifier for tracking keyboard focus.
+     *
+     * @hide until hotspot APIs are finalized
+     */
+    public static final int HOTSPOT_FOCUS = 0x100;
+
     private static final Rect ZERO_BOUNDS_RECT = new Rect();
 
     private int[] mStateSet = StateSet.WILD_CARD;
@@ -213,6 +231,20 @@
     }
 
     /**
+     * Return the drawable's dirty bounds Rect. Note: for efficiency, the
+     * returned object may be the same object stored in the drawable (though
+     * this is not guaranteed).
+     * <p>
+     * By default, this returns the full drawable bounds. Custom drawables may
+     * override this method to perform more precise invalidation.
+     *
+     * @hide
+     */
+    public Rect getDirtyBounds() {
+        return getBounds();
+    }
+
+    /**
      * Set a mask of the configuration parameters for which this drawable
      * may change, requiring that it be re-created.
      *
@@ -399,7 +431,7 @@
      *
      * @hide
      */
-    public void setLayoutDirection(int layoutDirection) {
+    public void setLayoutDirection(@View.ResolvedLayoutDir int layoutDirection) {
         if (getLayoutDirection() != layoutDirection) {
             mLayoutDirection = layoutDirection;
         }
@@ -423,12 +455,6 @@
     }
 
     /**
-     * Specify an optional colorFilter for the drawable. Pass null to remove
-     * any filters.
-    */
-    public abstract void setColorFilter(ColorFilter cf);
-
-    /**
      * @hide Consider for future API inclusion
      */
     public void setXfermode(Xfermode mode) {
@@ -438,18 +464,88 @@
     }
 
     /**
-     * Specify a color and porterduff mode to be the colorfilter for this
+     * Specify an optional color filter for the drawable. Pass {@code null} to
+     * remove any existing color filter.
+     *
+     * @param cf the color filter to apply, or {@code null} to remove the
+     *            existing color filter
+     */
+    public abstract void setColorFilter(ColorFilter cf);
+
+    /**
+     * Specify a color and Porter-Duff mode to be the color filter for this
      * drawable.
      */
     public void setColorFilter(int color, PorterDuff.Mode mode) {
         setColorFilter(new PorterDuffColorFilter(color, mode));
     }
 
+    /**
+     * Returns the current color filter, or {@code null} if none set.
+     *
+     * @return the current color filter, or {@code null} if none set
+     */
+    public ColorFilter getColorFilter() {
+        return null;
+    }
+
+    /**
+     * Removes the color filter for this drawable.
+     */
     public void clearColorFilter() {
         setColorFilter(null);
     }
 
     /**
+     * Indicates whether the drawable supports hotspots. Hotspots are uniquely
+     * identifiable coordinates the may be added, updated and removed within the
+     * drawable.
+     *
+     * @return true if hotspots are supported
+     * @see #setHotspot(int, float, float)
+     * @see #removeHotspot(int)
+     * @see #clearHotspots()
+     * @hide until hotspot APIs are finalized
+     */
+    public boolean supportsHotspots() {
+        return false;
+    }
+
+    /**
+     * Specifies a hotspot's location within the drawable.
+     *
+     * @param id unique identifier for the hotspot
+     * @param x x-coordinate
+     * @param y y-coordinate
+     * @hide until hotspot APIs are finalized
+     */
+    public void setHotspot(int id, float x, float y) {}
+
+    /**
+     * Removes the specified hotspot from the drawable.
+     *
+     * @param id unique identifier for the hotspot
+     * @hide until hotspot APIs are finalized
+     */
+    public void removeHotspot(int id) {}
+
+    /**
+     * Removes all hotspots from the drawable.
+     *
+     * @hide until hotspot APIs are finalized
+     */
+    public void clearHotspots() {}
+
+    /**
+     * Whether this drawable requests projection.
+     *
+     * @hide
+     */
+    public boolean isProjected() {
+        return false;
+    }
+
+    /**
      * Indicates whether this view will change its appearance based on state.
      * Clients can use this to determine whether it is necessary to calculate
      * their state and call setState.
@@ -765,6 +861,24 @@
     }
 
     /**
+     * Returns the outline for this drawable if defined, null if not.
+     * <p>
+     * This method will be called by a View on its background Drawable after
+     * bounds change, if the View's Outline isn't set explicitly. This allows
+     * the background Drawable to provide the shape of the shadow casting
+     * portion of the View. It can also serve to clip the area of the View if
+     * if {@link View#setClipToOutline(boolean)} is set on the View.
+     * <p>
+     * The Outline queried by the View will not be modified, and is treated as
+     * a static shape that only needs to be requeried when the drawable's bounds
+     * change.
+     *
+     * @see View#setOutline(android.view.Outline)
+     * @see View#setClipToOutline(boolean)
+     */
+    public Outline getOutline() { return null; }
+
+    /**
      * Make this drawable mutable. This operation cannot be reversed. A mutable
      * drawable is guaranteed to not share its state with any other drawable.
      * This is especially useful when you need to modify properties of drawables
@@ -902,6 +1016,10 @@
             drawable = new LayerDrawable();
         } else if (name.equals("transition")) {
             drawable = new TransitionDrawable();
+        } else if (name.equals("reveal")) {
+            drawable = new RevealDrawable();
+        } else if (name.equals("touch-feedback")) {
+            drawable = new TouchFeedbackDrawable();
         } else if (name.equals("color")) {
             drawable = new ColorDrawable();
         } else if (name.equals("shape")) {
@@ -1032,7 +1150,7 @@
 
     /**
      * Return a {@link ConstantState} instance that holds the shared state of this Drawable.
-     *q
+     *
      * @return The ConstantState associated to that Drawable.
      * @see ConstantState
      * @see Drawable#mutate()
@@ -1050,5 +1168,23 @@
 
         return new BitmapDrawable(res, bm);
     }
+
+    /**
+     * Parses a {@link android.graphics.PorterDuff.Mode} from a tintMode
+     * attribute's enum value.
+     */
+    static PorterDuff.Mode parseTintMode(int value, Mode defaultMode) {
+        switch (value) {
+            case 0:
+                return Mode.SRC_IN;
+            case 1:
+                return Mode.SRC_ATOP;
+            case 2:
+                return Mode.MULTIPLY;
+            case 3:
+                return Mode.SCREEN;
+        }
+        return defaultMode;
+    }
 }
 
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index aac7876..6144e69 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -49,7 +49,9 @@
     private DrawableContainerState mDrawableContainerState;
     private Drawable mCurrDrawable;
     private int mAlpha = 0xFF;
-    private ColorFilter mColorFilter;
+
+    /** Whether setAlpha() has been called at least once. */
+    private boolean mHasAlpha;
 
     private int mCurIndex = -1;
     private boolean mMutated;
@@ -118,7 +120,8 @@
 
     @Override
     public void setAlpha(int alpha) {
-        if (mAlpha != alpha) {
+        if (!mHasAlpha || mAlpha != alpha) {
+            mHasAlpha = true;
             mAlpha = alpha;
             if (mCurrDrawable != null) {
                 if (mEnterAnimationEnd == 0) {
@@ -147,8 +150,11 @@
 
     @Override
     public void setColorFilter(ColorFilter cf) {
-        if (mColorFilter != cf) {
-            mColorFilter = cf;
+        mDrawableContainerState.mHasColorFilter = true;
+
+        if (mDrawableContainerState.mColorFilter != cf) {
+            mDrawableContainerState.mColorFilter = cf;
+
             if (mCurrDrawable != null) {
                 mCurrDrawable.mutate().setColorFilter(cf);
             }
@@ -190,9 +196,11 @@
 
     @Override
     public void setAutoMirrored(boolean mirrored) {
-        mDrawableContainerState.mAutoMirrored = mirrored;
-        if (mCurrDrawable != null) {
-            mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+        if (mDrawableContainerState.mAutoMirrored != mirrored) {
+            mDrawableContainerState.mAutoMirrored = mirrored;
+            if (mCurrDrawable != null) {
+                mCurrDrawable.mutate().setAutoMirrored(mDrawableContainerState.mAutoMirrored);
+            }
         }
     }
 
@@ -211,7 +219,9 @@
         }
         if (mCurrDrawable != null) {
             mCurrDrawable.jumpToCurrentState();
-            mCurrDrawable.mutate().setAlpha(mAlpha);
+            if (mHasAlpha) {
+                mCurrDrawable.mutate().setAlpha(mAlpha);
+            }
         }
         if (mExitAnimationEnd != 0) {
             mExitAnimationEnd = 0;
@@ -354,12 +364,14 @@
                 d.mutate();
                 if (mDrawableContainerState.mEnterFadeDuration > 0) {
                     mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
-                } else {
+                } else if (mHasAlpha) {
                     d.setAlpha(mAlpha);
                 }
+                if (mDrawableContainerState.mHasColorFilter) {
+                    d.setColorFilter(mDrawableContainerState.mColorFilter);
+                }
                 d.setVisible(isVisible(), true);
                 d.setDither(mDrawableContainerState.mDither);
-                d.setColorFilter(mColorFilter);
                 d.setState(getState());
                 d.setLevel(getLevel());
                 d.setBounds(getBounds());
@@ -395,6 +407,8 @@
     }
 
     void animate(boolean schedule) {
+        mHasAlpha = true;
+
         final long now = SystemClock.uptimeMillis();
         boolean animating = false;
         if (mCurrDrawable != null) {
@@ -507,6 +521,9 @@
 
         boolean mAutoMirrored;
 
+        ColorFilter mColorFilter;
+        boolean mHasColorFilter;
+
         DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
                 Resources res) {
             mOwner = owner;
@@ -527,6 +544,8 @@
                 mEnterFadeDuration = orig.mEnterFadeDuration;
                 mExitFadeDuration = orig.mExitFadeDuration;
                 mAutoMirrored = orig.mAutoMirrored;
+                mColorFilter = orig.mColorFilter;
+                mHasColorFilter = orig.mHasColorFilter;
 
                 // Cloning the following values may require creating futures.
                 mConstantPadding = orig.getConstantPadding();
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
new file mode 100644
index 0000000..e6a755f
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Rect;
+import android.graphics.Xfermode;
+
+/**
+ * A Drawable that wraps another Drawable.
+ */
+class DrawableWrapper extends Drawable implements Drawable.Callback {
+    private WrapperState mWrapperState;
+
+    /** Local drawable backed by its own constant state. */
+    private Drawable mWrappedDrawable;
+
+    private boolean mMutated;
+
+    /** @hide */
+    @Override
+    public boolean isProjected() {
+        return mWrappedDrawable.isProjected();
+    }
+
+    @Override
+    public void setAutoMirrored(boolean mirrored) {
+        mWrappedDrawable.setAutoMirrored(mirrored);
+    }
+
+    @Override
+    public boolean isAutoMirrored() {
+        return mWrappedDrawable.isAutoMirrored();
+    }
+
+    @Override
+    public int getMinimumWidth() {
+        return mWrappedDrawable.getMinimumWidth();
+    }
+
+    @Override
+    public int getMinimumHeight() {
+        return mWrappedDrawable.getMinimumHeight();
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mWrappedDrawable.getIntrinsicWidth();
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mWrappedDrawable.getIntrinsicHeight();
+    }
+
+    @Override
+    public Drawable getCurrent() {
+        return mWrappedDrawable.getCurrent();
+    }
+
+    @Override
+    public void invalidateDrawable(Drawable who) {
+        final Callback callback = getCallback();
+        if (callback != null) {
+            callback.invalidateDrawable(this);
+        }
+    }
+
+    @Override
+    public void scheduleDrawable(Drawable who, Runnable what, long when) {
+        final Callback callback = getCallback();
+        if (callback != null) {
+            callback.scheduleDrawable(this, what, when);
+        }
+    }
+
+    @Override
+    public void unscheduleDrawable(Drawable who, Runnable what) {
+        final Callback callback = getCallback();
+        if (callback != null) {
+            callback.unscheduleDrawable(this, what);
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        mWrappedDrawable.draw(canvas);
+    }
+
+    @Override
+    public int getChangingConfigurations() {
+        return mWrappedDrawable.getChangingConfigurations();
+    }
+
+    @Override
+    public boolean getPadding(Rect padding) {
+        return mWrappedDrawable.getPadding(padding);
+    }
+
+    @Override
+    public Rect getDirtyBounds() {
+        return mWrappedDrawable.getDirtyBounds();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean supportsHotspots() {
+        return mWrappedDrawable.supportsHotspots();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void setHotspot(int id, float x, float y) {
+        mWrappedDrawable.setHotspot(id, x, y);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void removeHotspot(int id) {
+        mWrappedDrawable.removeHotspot(id);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void clearHotspots() {
+        mWrappedDrawable.clearHotspots();
+    }
+
+    @Override
+    public boolean setVisible(boolean visible, boolean restart) {
+        // Must call through to super().
+        super.setVisible(visible, restart);
+        return mWrappedDrawable.setVisible(visible, restart);
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mWrappedDrawable.setAlpha(alpha);
+    }
+
+    @Override
+    public int getAlpha() {
+        return mWrappedDrawable.getAlpha();
+    }
+
+    /** {@hide} */
+    @Override
+    public void setLayoutDirection(int layoutDirection) {
+        mWrappedDrawable.setLayoutDirection(layoutDirection);
+    }
+
+    /** {@hide} */
+    @Override
+    public int getLayoutDirection() {
+        return mWrappedDrawable.getLayoutDirection();
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter cf) {
+        mWrappedDrawable.setColorFilter(cf);
+    }
+
+    @Override
+    public ColorFilter getColorFilter() {
+        return mWrappedDrawable.getColorFilter();
+    }
+
+    @Override
+    public void setFilterBitmap(boolean filter) {
+        mWrappedDrawable.setFilterBitmap(filter);
+    }
+
+    @Override
+    public void setXfermode(Xfermode mode) {
+        mWrappedDrawable.setXfermode(mode);
+    }
+
+    @Override
+    public int getOpacity() {
+        return mWrappedDrawable.getOpacity();
+    }
+
+    @Override
+    public boolean isStateful() {
+        return mWrappedDrawable.isStateful();
+    }
+    
+    @Override
+    public final boolean setState(int[] stateSet) {
+        return super.setState(stateSet);
+    }
+
+    @Override
+    public final int[] getState() {
+        return super.getState();
+    }
+
+    @Override
+    protected boolean onStateChange(int[] state) {
+        // Don't override setState(), getState().
+        return mWrappedDrawable.setState(state);
+    }
+
+    @Override
+    protected boolean onLevelChange(int level) {
+        // Don't override setLevel(), getLevel().
+        return mWrappedDrawable.setLevel(level);
+    }
+    
+    @Override
+    public final void setBounds(int left, int top, int right, int bottom) {
+        super.setBounds(left, top, right, bottom);
+    }
+    
+    @Override
+    public final void setBounds(Rect bounds) {
+        super.setBounds(bounds);
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        // Don't override setBounds(), getBounds().
+        mWrappedDrawable.setBounds(bounds);
+    }
+
+    protected void setConstantState(WrapperState wrapperState, Resources res) {
+        mWrapperState = wrapperState;
+
+        // Load a new drawable from the constant state.
+        if (wrapperState == null || wrapperState.mWrappedConstantState == null) {
+            mWrappedDrawable = null;
+        } else if (res != null) {
+            mWrappedDrawable = wrapperState.mWrappedConstantState.newDrawable(res);
+        } else {
+            mWrappedDrawable = wrapperState.mWrappedConstantState.newDrawable();
+        }
+    }
+
+    @Override
+    public ConstantState getConstantState() {
+        return mWrapperState;
+    }
+
+    @Override
+    public Drawable mutate() {
+        if (!mMutated) {
+            mWrappedDrawable = mWrappedDrawable.mutate();
+            mMutated = true;
+        }
+        return this;
+    }
+
+    /**
+     * Sets the wrapped drawable and update the constant state.
+     *
+     * @param drawable
+     * @param res
+     */
+    protected final void setDrawable(Drawable drawable, Resources res) {
+        if (mWrappedDrawable != null) {
+            mWrappedDrawable.setCallback(null);
+        }
+
+        mWrappedDrawable = drawable;
+
+        if (drawable != null) {
+            drawable.setCallback(this);
+
+            mWrapperState.mWrappedConstantState = drawable.getConstantState();
+        } else {
+            mWrapperState.mWrappedConstantState = null;
+        }
+    }
+
+    protected final Drawable getDrawable() {
+        return mWrappedDrawable;
+    }
+
+    static abstract class WrapperState extends ConstantState {
+        ConstantState mWrappedConstantState;
+
+        WrapperState(WrapperState orig) {
+            if (orig != null) {
+                mWrappedConstantState = orig.mWrappedConstantState;
+            }
+        }
+
+        @Override
+        public int getChangingConfigurations() {
+            return mWrappedConstantState.getChangingConfigurations();
+        }
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index b340777..8f22add 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -23,14 +24,16 @@
 import android.graphics.ColorFilter;
 import android.graphics.DashPathEffect;
 import android.graphics.LinearGradient;
+import android.graphics.Outline;
 import android.graphics.Paint;
+import android.graphics.Path;
 import android.graphics.PixelFormat;
+import android.graphics.RadialGradient;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Shader;
-import android.graphics.Path;
-import android.graphics.RadialGradient;
 import android.graphics.SweepGradient;
+import android.os.Build;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.TypedValue;
@@ -111,6 +114,15 @@
      */
     public static final int SWEEP_GRADIENT  = 2;
 
+    /** Radius is in pixels. */
+    private static final int RADIUS_TYPE_PIXELS = 0;
+
+    /** Radius is a fraction of the base size. */
+    private static final int RADIUS_TYPE_FRACTION = 1;
+
+    /** Radius is a fraction of the bounds size. */
+    private static final int RADIUS_TYPE_FRACTION_PARENT = 2;
+
     private GradientState mGradientState;
     
     private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -122,6 +134,7 @@
 
     private final Path mPath = new Path();
     private final RectF mRect = new RectF();
+    private Outline mOutline;
     
     private Paint mLayerPaint;    // internal, used if we use saveLayer()
     private boolean mRectIsDirty;   // internal state
@@ -129,6 +142,9 @@
     private Path mRingPath;
     private boolean mPathIsDirty = true;
 
+    /** Current gradient radius, valid when {@link #mRectIsDirty} is false. */
+    private float mGradientRadius;
+
     /**
      * Controls how the gradient is oriented relative to the drawable's bounds
      */
@@ -233,6 +249,23 @@
     }
 
     /**
+     * <p>Set the stroke width and color state list for the drawable. If width
+     * is zero, then no stroke is drawn.</p>
+     * <p><strong>Note</strong>: changing this property will affect all instances
+     * of a drawable loaded from a resource. It is recommended to invoke
+     * {@link #mutate()} before changing this property.</p>
+     *
+     * @param width The width in pixels of the stroke
+     * @param colorStateList The color state list of the stroke
+     *
+     * @see #mutate()
+     * @see #setStroke(int, ColorStateList, float, float)
+     */
+    public void setStroke(int width, ColorStateList colorStateList) {
+        setStroke(width, colorStateList, 0, 0);
+    }
+
+    /**
      * <p>Set the stroke width and color for the drawable. If width is zero,
      * then no stroke is drawn. This method can also be used to dash the stroke.</p>
      * <p><strong>Note</strong>: changing this property will affect all instances
@@ -248,8 +281,40 @@
      * @see #setStroke(int, int) 
      */
     public void setStroke(int width, int color, float dashWidth, float dashGap) {
-        mGradientState.setStroke(width, color, dashWidth, dashGap);
+        mGradientState.setStroke(width, ColorStateList.valueOf(color), dashWidth, dashGap);
+        setStrokeInternal(width, color, dashWidth, dashGap);
+    }
 
+    /**
+     * <p>Set the stroke width and color state list for the drawable. If width
+     * is zero, then no stroke is drawn. This method can also be used to dash
+     * the stroke.</p>
+     * <p><strong>Note</strong>: changing this property will affect all instances
+     * of a drawable loaded from a resource. It is recommended to invoke
+     * {@link #mutate()} before changing this property.</p>
+     *
+     * @param width The width in pixels of the stroke
+     * @param colorStateList The color state list of the stroke
+     * @param dashWidth The length in pixels of the dashes, set to 0 to disable dashes
+     * @param dashGap The gap in pixels between dashes
+     *
+     * @see #mutate()
+     * @see #setStroke(int, ColorStateList)
+     */
+    public void setStroke(
+            int width, ColorStateList colorStateList, float dashWidth, float dashGap) {
+        mGradientState.setStroke(width, colorStateList, dashWidth, dashGap);
+        final int color;
+        if (colorStateList == null) {
+            color = Color.TRANSPARENT;
+        } else {
+            final int[] stateSet = getState();
+            color = colorStateList.getColorForState(stateSet, 0);
+        }
+        setStrokeInternal(width, color, dashWidth, dashGap);
+    }
+
+    private void setStrokeInternal(int width, int color, float dashWidth, float dashGap) {
         if (mStrokePaint == null)  {
             mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
             mStrokePaint.setStyle(Paint.Style.STROKE);
@@ -351,12 +416,27 @@
      * @see #setGradientType(int) 
      */
     public void setGradientRadius(float gradientRadius) {
-        mGradientState.setGradientRadius(gradientRadius);
+        mGradientState.setGradientRadius(gradientRadius, TypedValue.COMPLEX_UNIT_PX);
         mRectIsDirty = true;
         invalidateSelf();
     }
 
     /**
+     * Returns the radius of the gradient in pixels. The radius is valid only
+     * when the gradient type is set to {@link #RADIAL_GRADIENT}.
+     *
+     * @return Radius in pixels.
+     */
+    public float getGradientRadius() {
+        if (mGradientState.mGradient != RADIAL_GRADIENT) {
+            return 0;
+        }
+
+        ensureValidRect();
+        return mGradientRadius;
+    }
+
+    /**
      * <p>Sets whether or not this drawable will honor its <code>level</code>
      * property.</p>
      * <p><strong>Note</strong>: changing this property will affect all instances
@@ -479,7 +559,7 @@
             mFillPaint.setAlpha(currFillAlpha);
             mFillPaint.setDither(mDither);
             mFillPaint.setColorFilter(mColorFilter);
-            if (mColorFilter != null && !mGradientState.mHasSolidColor) {
+            if (mColorFilter != null && mGradientState.mColorStateList == null) {
                 mFillPaint.setColor(mAlpha << 24);
             }
             if (haveStroke) {
@@ -507,11 +587,8 @@
                     // to show it. If we did nothing, Skia would clamp the rad
                     // independently along each axis, giving us a thin ellipse
                     // if the rect were very wide but not very tall
-                    float rad = st.mRadius;
-                    float r = Math.min(mRect.width(), mRect.height()) * 0.5f;
-                    if (rad > r) {
-                        rad = r;
-                    }
+                    float rad = Math.min(st.mRadius,
+                            Math.min(mRect.width(), mRect.height()) * 0.5f);
                     canvas.drawRoundRect(mRect, rad, rad, mFillPaint);
                     if (haveStroke) {
                         canvas.drawRoundRect(mRect, rad, rad, mStrokePaint);
@@ -583,7 +660,7 @@
         if (mRingPath == null) {
             mRingPath = new Path();
         } else {
-            mRingPath.reset();            
+            mRingPath.reset();
         }
 
         final Path ringPath = mRingPath;
@@ -610,7 +687,7 @@
     }
 
     /**
-     * <p>Changes this drawbale to use a single color instead of a gradient.</p>
+     * <p>Changes this drawable to use a single color instead of a gradient.</p>
      * <p><strong>Note</strong>: changing color will affect all instances
      * of a drawable loaded from a resource. It is recommended to invoke
      * {@link #mutate()} before changing the color.</p>
@@ -621,11 +698,81 @@
      * @see #setColors(int[]) 
      */
     public void setColor(int argb) {
-        mGradientState.setSolidColor(argb);
+        mGradientState.setColorStateList(ColorStateList.valueOf(argb));
         mFillPaint.setColor(argb);
         invalidateSelf();
     }
 
+    /**
+     * Changes this drawable to use a single color state list instead of a
+     * gradient. Calling this method with a null argument will clear the color
+     * and is equivalent to calling {@link #setColor(int)} with the argument
+     * {@link Color#TRANSPARENT}.
+     * <p>
+     * <strong>Note</strong>: changing color will affect all instances of a
+     * drawable loaded from a resource. It is recommended to invoke
+     * {@link #mutate()} before changing the color.</p>
+     *
+     * @param colorStateList The color state list used to fill the shape
+     * @see #mutate()
+     */
+    public void setColor(ColorStateList colorStateList) {
+        mGradientState.setColorStateList(colorStateList);
+        final int color;
+        if (colorStateList == null) {
+            color = Color.TRANSPARENT;
+        } else {
+            final int[] stateSet = getState();
+            color = colorStateList.getColorForState(stateSet, 0);
+        }
+        mFillPaint.setColor(color);
+        invalidateSelf();
+    }
+
+    @Override
+    protected boolean onStateChange(int[] stateSet) {
+        boolean invalidateSelf = false;
+
+        final GradientState s = mGradientState;
+        final ColorStateList stateList = s.mColorStateList;
+        if (stateList != null) {
+            final int newColor = stateList.getColorForState(stateSet, 0);
+            final int oldColor = mFillPaint.getColor();
+            if (oldColor != newColor) {
+                mFillPaint.setColor(newColor);
+                invalidateSelf = true;
+            }
+        }
+
+        final Paint strokePaint = mStrokePaint;
+        if (strokePaint != null) {
+            final ColorStateList strokeStateList = s.mStrokeColorStateList;
+            if (strokeStateList != null) {
+                final int newStrokeColor = strokeStateList.getColorForState(stateSet, 0);
+                final int oldStrokeColor = strokePaint.getColor();
+                if (oldStrokeColor != newStrokeColor) {
+                    strokePaint.setColor(newStrokeColor);
+                    invalidateSelf = true;
+                }
+            }
+        }
+
+        if (invalidateSelf) {
+            invalidateSelf();
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isStateful() {
+        final GradientState s = mGradientState;
+        return super.isStateful()
+                || (s.mColorStateList != null && s.mColorStateList.isStateful())
+                || (s.mStrokeColorStateList != null && s.mStrokeColorStateList.isStateful());
+    }
+
     @Override
     public int getChangingConfigurations() {
         return super.getChangingConfigurations() | mGradientState.mChangingConfigurations;
@@ -752,11 +899,27 @@
                     x0 = r.left + (r.right - r.left) * st.mCenterX;
                     y0 = r.top + (r.bottom - r.top) * st.mCenterY;
 
-                    final float level = st.mUseLevel ? (float) getLevel() / 10000.0f : 1.0f;
+                    float radius = st.mGradientRadius;
+                    if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
+                        radius *= Math.min(st.mWidth, st.mHeight);
+                    } else if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION_PARENT) {
+                        radius *= Math.min(r.width(), r.height());
+                    }
 
-                    mFillPaint.setShader(new RadialGradient(x0, y0,
-                            level * st.mGradientRadius, colors, null,
-                            Shader.TileMode.CLAMP));
+                    if (st.mUseLevel) {
+                        radius *= getLevel() / 10000.0f;
+                    }
+
+                    mGradientRadius = radius;
+
+                    if (radius == 0) {
+                        // We can't have a shader with zero radius, so let's
+                        // have a very, very small radius.
+                        radius = 0.001f;
+                    }
+
+                    mFillPaint.setShader(new RadialGradient(
+                            x0, y0, radius, colors, null, Shader.TileMode.CLAMP));
                 } else if (st.mGradient == SWEEP_GRADIENT) {
                     x0 = r.left + (r.right - r.left) * st.mCenterX;
                     y0 = r.top + (r.bottom - r.top) * st.mCenterY;
@@ -791,7 +954,7 @@
 
                 // If we don't have a solid color, the alpha channel must be
                 // maxed out so that alpha modulation works correctly.
-                if (!st.mHasSolidColor) {
+                if (st.mColorStateList == null) {
                     mFillPaint.setColor(Color.BLACK);
                 }
             }
@@ -931,12 +1094,28 @@
                         break;
                     }
                 } else {
-                    TypedValue tv = a.peekValue(
+                    final TypedValue tv = a.peekValue(
                             com.android.internal.R.styleable.GradientDrawableGradient_gradientRadius);
                     if (tv != null) {
-                        boolean radiusRel = tv.type == TypedValue.TYPE_FRACTION;
-                        st.mGradientRadius = radiusRel ?
-                                tv.getFraction(1.0f, 1.0f) : tv.getFloat();
+                        final float radius;
+                        final int radiusType;
+                        if (tv.type == TypedValue.TYPE_FRACTION) {
+                            radius = tv.getFraction(1.0f, 1.0f);
+
+                            final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
+                                    & TypedValue.COMPLEX_UNIT_MASK;
+                            if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
+                                radiusType = RADIUS_TYPE_FRACTION_PARENT;
+                            } else {
+                                radiusType = RADIUS_TYPE_FRACTION;
+                            }
+                        } else {
+                            radius = tv.getDimension(r.getDisplayMetrics());
+                            radiusType = RADIUS_TYPE_PIXELS;
+                        }
+
+                        st.mGradientRadius = radius;
+                        st.mGradientRadiusType = radiusType;
                     } else if (gradientType == RADIAL_GRADIENT) {
                         throw new XmlPullParserException(
                                 a.getPositionDescription()
@@ -967,25 +1146,25 @@
             } else if (name.equals("solid")) {
                 a = r.obtainAttributes(attrs,
                         com.android.internal.R.styleable.GradientDrawableSolid);
-                int argb = a.getColor(
-                        com.android.internal.R.styleable.GradientDrawableSolid_color, 0);
+                final ColorStateList colorStateList = a.getColorStateList(
+                        com.android.internal.R.styleable.GradientDrawableSolid_color);
                 a.recycle();
-                setColor(argb);
+                setColor(colorStateList);
             } else if (name.equals("stroke")) {
                 a = r.obtainAttributes(attrs,
                         com.android.internal.R.styleable.GradientDrawableStroke);
-                int width = a.getDimensionPixelSize(
+                final int width = a.getDimensionPixelSize(
                         com.android.internal.R.styleable.GradientDrawableStroke_width, 0);
-                int color = a.getColor(
-                        com.android.internal.R.styleable.GradientDrawableStroke_color, 0);
-                float dashWidth = a.getDimension(
+                final ColorStateList colorStateList = a.getColorStateList(
+                        com.android.internal.R.styleable.GradientDrawableStroke_color);
+                final float dashWidth = a.getDimension(
                         com.android.internal.R.styleable.GradientDrawableStroke_dashWidth, 0);
                 if (dashWidth != 0.0f) {
-                    float dashGap = a.getDimension(
+                    final float dashGap = a.getDimension(
                             com.android.internal.R.styleable.GradientDrawableStroke_dashGap, 0);
-                    setStroke(width, color, dashWidth, dashGap);
+                    setStroke(width, colorStateList, dashWidth, dashGap);
                 } else {
-                    setStroke(width, color);
+                    setStroke(width, colorStateList);
                 }
                 a.recycle();
             } else if (name.equals("corners")) {
@@ -1063,6 +1242,46 @@
     }
 
     @Override
+    public Outline getOutline() {
+        final GradientState st = mGradientState;
+        final Rect bounds = getBounds();
+
+        switch (st.mShape) {
+            case RECTANGLE:
+                if (st.mRadiusArray != null) {
+                    return null;
+                }
+                float rad = 0;
+                if (st.mRadius > 0.0f) {
+                    // clamp the radius based on width & height, matching behavior in draw()
+                    rad = Math.min(st.mRadius,
+                            Math.min(bounds.width(), bounds.height()) * 0.5f);
+                }
+                if (mOutline == null) {
+                    mOutline = new Outline();
+                }
+                mOutline.setRoundRect(bounds.left, bounds.top,
+                        bounds.right, bounds.bottom, rad);
+                return mOutline;
+            case LINE: {
+                float halfStrokeWidth = mStrokePaint.getStrokeWidth() * 0.5f;
+                float centerY = bounds.centerY();
+                int top = (int) Math.floor(centerY - halfStrokeWidth);
+                int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
+
+                if (mOutline == null) {
+                    mOutline = new Outline();
+                }
+                mOutline.setRoundRect(bounds.left, top, bounds.right, bottom, 0);
+                return mOutline;
+            }
+            default:
+                // TODO: investigate
+                return null;
+        }
+    }
+
+    @Override
     public Drawable mutate() {
         if (!mMutated && super.mutate() == this) {
             mGradientState = new GradientState(mGradientState);
@@ -1077,14 +1296,13 @@
         public int mShape = RECTANGLE;
         public int mGradient = LINEAR_GRADIENT;
         public Orientation mOrientation;
+        public ColorStateList mColorStateList;
+        public ColorStateList mStrokeColorStateList;
         public int[] mColors;
         public int[] mTempColors; // no need to copy
         public float[] mTempPositions; // no need to copy
         public float[] mPositions;
-        public boolean mHasSolidColor;
-        public int mSolidColor;
         public int mStrokeWidth = -1;   // if >= 0 use stroking.
-        public int mStrokeColor;
         public float mStrokeDashWidth;
         public float mStrokeDashGap;
         public float mRadius;    // use this if mRadiusArray is null
@@ -1099,6 +1317,7 @@
         private float mCenterX = 0.5f;
         private float mCenterY = 0.5f;
         private float mGradientRadius = 0.5f;
+        private int mGradientRadiusType = RADIUS_TYPE_PIXELS;
         private boolean mUseLevel;
         private boolean mUseLevelForShape;
         private boolean mOpaque;
@@ -1113,16 +1332,15 @@
             mShape = state.mShape;
             mGradient = state.mGradient;
             mOrientation = state.mOrientation;
+            mColorStateList = state.mColorStateList;
             if (state.mColors != null) {
                 mColors = state.mColors.clone();
             }
             if (state.mPositions != null) {
                 mPositions = state.mPositions.clone();
             }
-            mHasSolidColor = state.mHasSolidColor;
-            mSolidColor = state.mSolidColor;
+            mStrokeColorStateList = state.mStrokeColorStateList;
             mStrokeWidth = state.mStrokeWidth;
-            mStrokeColor = state.mStrokeColor;
             mStrokeDashWidth = state.mStrokeDashWidth;
             mStrokeDashGap = state.mStrokeDashGap;
             mRadius = state.mRadius;
@@ -1141,6 +1359,7 @@
             mCenterX = state.mCenterX;
             mCenterY = state.mCenterY;
             mGradientRadius = state.mGradientRadius;
+            mGradientRadiusType = state.mGradientRadiusType;
             mUseLevel = state.mUseLevel;
             mUseLevelForShape = state.mUseLevelForShape;
             mOpaque = state.mOpaque;
@@ -1176,15 +1395,14 @@
         }
 
         public void setColors(int[] colors) {
-            mHasSolidColor = false;
             mColors = colors;
+            mColorStateList = null;
             computeOpacity();
         }
-        
-        public void setSolidColor(int argb) {
-            mHasSolidColor = true;
-            mSolidColor = argb;
+
+        public void setColorStateList(ColorStateList colorStateList) {
             mColors = null;
+            mColorStateList = colorStateList;
             computeOpacity();
         }
 
@@ -1199,13 +1417,17 @@
                 return;
             }
 
-            if (mStrokeWidth > 0 && !isOpaque(mStrokeColor)) {
-                mOpaque = false;
-                return;
+            if (mStrokeWidth > 0) {
+                if (mStrokeColorStateList != null) {
+                    if (!mStrokeColorStateList.isOpaque()) {
+                        mOpaque = false;
+                        return;
+                    }
+                }
             }
-            
-            if (mHasSolidColor) {
-                mOpaque = isOpaque(mSolidColor);
+
+            if (mColorStateList != null && !mColorStateList.isOpaque()) {
+                mOpaque = false;
                 return;
             }
 
@@ -1225,15 +1447,10 @@
             return ((color >> 24) & 0xff) == 0xff;
         }
 
-        public void setStroke(int width, int color) {
+        public void setStroke(
+                int width, ColorStateList colorStateList, float dashWidth, float dashGap) {
             mStrokeWidth = width;
-            mStrokeColor = color;
-            computeOpacity();
-        }
-
-        public void setStroke(int width, int color, float dashWidth, float dashGap) {
-            mStrokeWidth = width;
-            mStrokeColor = color;
+            mStrokeColorStateList = colorStateList;
             mStrokeDashWidth = dashWidth;
             mStrokeDashGap = dashGap;
             computeOpacity();
@@ -1259,8 +1476,9 @@
             mHeight = height;
         }
 
-        public void setGradientRadius(float gradientRadius) {
+        public void setGradientRadius(float gradientRadius, int type) {
             mGradientRadius = gradientRadius;
+            mGradientRadiusType = type;
         }
     }
 
@@ -1272,8 +1490,10 @@
     }
 
     private void initializeWithState(GradientState state) {
-        if (state.mHasSolidColor) {
-            mFillPaint.setColor(state.mSolidColor);
+        if (state.mColorStateList != null) {
+            final int[] currentState = getState();
+            final int stateColor = state.mColorStateList.getColorForState(currentState, 0);
+            mFillPaint.setColor(stateColor);
         } else if (state.mColors == null) {
             // If we don't have a solid color and we don't have a gradient,
             // the app is stroking the shape, set the color to the default
@@ -1288,7 +1508,12 @@
             mStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
             mStrokePaint.setStyle(Paint.Style.STROKE);
             mStrokePaint.setStrokeWidth(state.mStrokeWidth);
-            mStrokePaint.setColor(state.mStrokeColor);
+            if (state.mStrokeColorStateList != null) {
+                final int[] currentState = getState();
+                final int strokeStateColor = state.mStrokeColorStateList.getColorForState(
+                        currentState, 0);
+                mStrokePaint.setColor(strokeStateColor);
+            }
 
             if (state.mStrokeDashWidth != 0.0f) {
                 DashPathEffect e = new DashPathEffect(
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 8188782..f841d6a 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -182,6 +182,38 @@
         }
     }
 
+    /**
+     * @hide
+     */
+    @Override
+    public boolean supportsHotspots() {
+        return mInsetState.mDrawable.supportsHotspots();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void setHotspot(int id, float x, float y) {
+        mInsetState.mDrawable.setHotspot(id, x, y);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void removeHotspot(int id) {
+        mInsetState.mDrawable.removeHotspot(id);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void clearHotspots() {
+        mInsetState.mDrawable.clearHotspots();
+    }
+
     @Override
     public boolean setVisible(boolean visible, boolean restart) {
         mInsetState.mDrawable.setVisible(visible, restart);
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 81cc11b..2e098a0 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -30,7 +30,7 @@
 
 import java.io.IOException;
 
-/** 
+/**
  * A Drawable that manages an array of other Drawables. These are drawn in array
  * order, so the element with the largest index will be drawn on top.
  * <p>
@@ -47,6 +47,15 @@
  * @attr ref android.R.styleable#LayerDrawableItem_id
 */
 public class LayerDrawable extends Drawable implements Drawable.Callback {
+    /**
+     * Padding mode used to nest each layer inside the padding of the previous
+     * layer.
+     */
+    public static final int PADDING_MODE_NEST = 0;
+
+    /** Padding mode used to stack each layer directly atop the previous layer. */
+    public static final int PADDING_MODE_STACK = 1;
+
     LayerState mLayerState;
 
     private int mOpacityOverride = PixelFormat.UNKNOWN;
@@ -90,7 +99,7 @@
 
         ensurePadding();
     }
-    
+
     LayerDrawable() {
         this((LayerState) null, null);
     }
@@ -122,6 +131,9 @@
         setAutoMirrored(a.getBoolean(com.android.internal.R.styleable.LayerDrawable_autoMirrored,
                 false));
 
+        mLayerState.mPaddingMode = a.getInteger(
+                com.android.internal.R.styleable.LayerDrawableItem_drawable, PADDING_MODE_NEST);
+
         a.recycle();
 
         final int innerDepth = parser.getDepth() + 1;
@@ -187,19 +199,20 @@
      */
     private void addLayer(Drawable layer, int id, int left, int top, int right, int bottom) {
         final LayerState st = mLayerState;
-        int N = st.mChildren != null ? st.mChildren.length : 0;
-        int i = st.mNum;
+        final int N = st.mChildren != null ? st.mChildren.length : 0;
+        final int i = st.mNum;
         if (i >= N) {
-            ChildDrawable[] nu = new ChildDrawable[N + 10];
+            final ChildDrawable[] nu = new ChildDrawable[N + 10];
             if (i > 0) {
                 System.arraycopy(st.mChildren, 0, nu, 0, i);
             }
+
             st.mChildren = nu;
         }
 
         mLayerState.mChildrenChangingConfigurations |= layer.getChangingConfigurations();
-        
-        ChildDrawable childDrawable = new ChildDrawable();
+
+        final ChildDrawable childDrawable = new ChildDrawable();
         st.mChildren[i] = childDrawable;
         childDrawable.mId = id;
         childDrawable.mDrawable = layer;
@@ -214,33 +227,36 @@
     }
 
     /**
-     * Look for a layer with the given id, and returns its {@link Drawable}.
+     * Looks for a layer with the given ID and returns its {@link Drawable}.
+     * <p>
+     * If multiple layers are found for the given ID, returns the
+     * {@link Drawable} for the matching layer at the highest index.
      *
      * @param id The layer ID to search for.
-     * @return The {@link Drawable} of the layer that has the given id in the hierarchy or null.
+     * @return The {@link Drawable} for the highest-indexed layer that has the
+     *         given ID, or null if not found.
      */
     public Drawable findDrawableByLayerId(int id) {
         final ChildDrawable[] layers = mLayerState.mChildren;
-        
         for (int i = mLayerState.mNum - 1; i >= 0; i--) {
             if (layers[i].mId == id) {
                 return layers[i].mDrawable;
             }
         }
-        
+
         return null;
     }
-    
+
     /**
      * Sets the ID of a layer.
-     * 
-     * @param index The index of the layer which will received the ID. 
+     *
+     * @param index The index of the layer which will received the ID.
      * @param id The ID to assign to the layer.
      */
     public void setId(int index, int id) {
         mLayerState.mChildren[index].mId = id;
     }
-    
+
     /**
      * Returns the number of layers contained within this.
      * @return The number of layers.
@@ -265,15 +281,15 @@
      *
      * @param index The index of the layer.
      *
-     * @return The id of the layer or {@link android.view.View#NO_ID} if the layer has no id. 
+     * @return The id of the layer or {@link android.view.View#NO_ID} if the layer has no id.
      */
     public int getId(int index) {
         return mLayerState.mChildren[index].mId;
     }
-    
+
     /**
      * Sets (or replaces) the {@link Drawable} for the layer with the given id.
-     * 
+     *
      * @param id The layer ID to search for.
      * @param drawable The replacement {@link Drawable}.
      * @return Whether the {@link Drawable} was replaced (could return false if
@@ -281,71 +297,91 @@
      */
     public boolean setDrawableByLayerId(int id, Drawable drawable) {
         final ChildDrawable[] layers = mLayerState.mChildren;
-        
-        for (int i = mLayerState.mNum - 1; i >= 0; i--) {
-            if (layers[i].mId == id) {
-                if (layers[i].mDrawable != null) {
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            final ChildDrawable childDrawable = layers[i];
+            if (childDrawable.mId == id) {
+                if (childDrawable.mDrawable != null) {
                     if (drawable != null) {
-                        Rect bounds = layers[i].mDrawable.getBounds();
+                        final Rect bounds = childDrawable.mDrawable.getBounds();
                         drawable.setBounds(bounds);
                     }
-                    layers[i].mDrawable.setCallback(null);
+
+                    childDrawable.mDrawable.setCallback(null);
                 }
+
                 if (drawable != null) {
                     drawable.setCallback(this);
                 }
-                layers[i].mDrawable = drawable;
+
+                childDrawable.mDrawable = drawable;
                 return true;
             }
         }
-        
+
         return false;
     }
-    
-    /** Specify modifiers to the bounds for the drawable[index].
-        left += l
-        top += t;
-        right -= r;
-        bottom -= b;
-    */
+
+    /**
+     * Specifies the insets in pixels for the drawable at the specified index.
+     *
+     * @param index the index of the drawable to adjust
+     * @param l number of pixels to add to the left bound
+     * @param t number of pixels to add to the top bound
+     * @param r number of pixels to subtract from the right bound
+     * @param b number of pixels to subtract from the bottom bound
+     */
     public void setLayerInset(int index, int l, int t, int r, int b) {
-        ChildDrawable childDrawable = mLayerState.mChildren[index];
+        final ChildDrawable childDrawable = mLayerState.mChildren[index];
         childDrawable.mInsetL = l;
         childDrawable.mInsetT = t;
         childDrawable.mInsetR = r;
         childDrawable.mInsetB = b;
     }
 
-    // overrides from Drawable.Callback
+    /**
+     * Specifies how layer padding should affect the bounds of subsequent
+     * layers. The default value is {@link #PADDING_MODE_NEST}.
+     *
+     * @param mode padding mode, one of:
+     *            <ul>
+     *            <li>{@link #PADDING_MODE_NEST} <li>{@link #PADDING_MODE_STACK}
+     *            </ul>
+     */
+    public void setPaddingMode(int mode) {
+        if (mLayerState.mPaddingMode != mode) {
+            mLayerState.mPaddingMode = mode;
+        }
+    }
 
+    /**
+     * @return the current padding mode
+     * @see #setPaddingMode(int)
+     */
+    public int getPaddingMode() {
+      return mLayerState.mPaddingMode;
+    }
+
+    @Override
     public void invalidateDrawable(Drawable who) {
-        final Callback callback = getCallback();
-        if (callback != null) {
-            callback.invalidateDrawable(this);
-        }
+        invalidateSelf();
     }
 
+    @Override
     public void scheduleDrawable(Drawable who, Runnable what, long when) {
-        final Callback callback = getCallback();
-        if (callback != null) {
-            callback.scheduleDrawable(this, what, when);
-        }
+        scheduleSelf(what, when);
     }
 
+    @Override
     public void unscheduleDrawable(Drawable who, Runnable what) {
-        final Callback callback = getCallback();
-        if (callback != null) {
-            callback.unscheduleDrawable(this, what);
-        }
+        unscheduleSelf(what);
     }
 
-    // overrides from Drawable
-
     @Override
     public void draw(Canvas canvas) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.draw(canvas);
         }
     }
@@ -356,36 +392,117 @@
                 | mLayerState.mChangingConfigurations
                 | mLayerState.mChildrenChangingConfigurations;
     }
-    
+
     @Override
     public boolean getPadding(Rect padding) {
-        // Arbitrarily get the padding from the first image.
-        // Technically we should maybe do something more intelligent,
-        // like take the max padding of all the images.
+        if (mLayerState.mPaddingMode == PADDING_MODE_NEST) {
+            computeNestedPadding(padding);
+        } else {
+            computeStackedPadding(padding);
+        }
+
+        return padding.left != 0 || padding.top != 0 || padding.right != 0 || padding.bottom != 0;
+    }
+
+    private void computeNestedPadding(Rect padding) {
         padding.left = 0;
         padding.top = 0;
         padding.right = 0;
         padding.bottom = 0;
+
+        // Add all the padding.
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
-            reapplyPadding(i, array[i]);
+        for (int i = 0; i < N; i++) {
+            refreshChildPadding(i, array[i]);
+
             padding.left += mPaddingL[i];
             padding.top += mPaddingT[i];
             padding.right += mPaddingR[i];
             padding.bottom += mPaddingB[i];
         }
-        return true;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean supportsHotspots() {
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            if (array[i].mDrawable.supportsHotspots()) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void setHotspot(int id, float x, float y) {
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            array[i].mDrawable.setHotspot(id, x, y);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void removeHotspot(int id) {
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            array[i].mDrawable.removeHotspot(id);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void clearHotspots() {
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            array[i].mDrawable.clearHotspots();
+        }
+    }
+
+    private void computeStackedPadding(Rect padding) {
+        padding.left = 0;
+        padding.top = 0;
+        padding.right = 0;
+        padding.bottom = 0;
+
+        // Take the max padding.
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
+            refreshChildPadding(i, array[i]);
+
+            padding.left = Math.max(padding.left, mPaddingL[i]);
+            padding.top = Math.max(padding.top, mPaddingT[i]);
+            padding.right = Math.max(padding.right, mPaddingR[i]);
+            padding.bottom = Math.max(padding.bottom, mPaddingB[i]);
+        }
     }
 
     @Override
     public boolean setVisible(boolean visible, boolean restart) {
-        boolean changed = super.setVisible(visible, restart);
+        final boolean changed = super.setVisible(visible, restart);
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setVisible(visible, restart);
         }
+
         return changed;
     }
 
@@ -393,7 +510,7 @@
     public void setDither(boolean dither) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setDither(dither);
         }
     }
@@ -402,7 +519,7 @@
     public void setAlpha(int alpha) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setAlpha(alpha);
         }
     }
@@ -422,7 +539,7 @@
     public void setColorFilter(ColorFilter cf) {
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setColorFilter(cf);
         }
     }
@@ -442,7 +559,7 @@
     public void setOpacity(int opacity) {
         mOpacityOverride = opacity;
     }
-    
+
     @Override
     public int getOpacity() {
         if (mOpacityOverride != PixelFormat.UNKNOWN) {
@@ -454,9 +571,10 @@
     @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++) {
+        for (int i = 0; i < N; i++) {
             array[i].mDrawable.setAutoMirrored(mirrored);
         }
     }
@@ -470,105 +588,137 @@
     public boolean isStateful() {
         return mLayerState.isStateful();
     }
-    
+
     @Override
     protected boolean onStateChange(int[] state) {
-        final ChildDrawable[] array = mLayerState.mChildren;
-        final int N = mLayerState.mNum;
         boolean paddingChanged = false;
         boolean changed = false;
-        for (int i=0; i<N; i++) {
+
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
             if (r.mDrawable.setState(state)) {
                 changed = true;
             }
-            if (reapplyPadding(i, r)) {
+
+            if (refreshChildPadding(i, r)) {
                 paddingChanged = true;
             }
         }
+
         if (paddingChanged) {
             onBoundsChange(getBounds());
         }
+
         return changed;
     }
-    
+
     @Override
     protected boolean onLevelChange(int level) {
-        final ChildDrawable[] array = mLayerState.mChildren;
-        final int N = mLayerState.mNum;
         boolean paddingChanged = false;
         boolean changed = false;
-        for (int i=0; i<N; i++) {
+
+        final ChildDrawable[] array = mLayerState.mChildren;
+        final int N = mLayerState.mNum;
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
             if (r.mDrawable.setLevel(level)) {
                 changed = true;
             }
-            if (reapplyPadding(i, r)) {
+
+            if (refreshChildPadding(i, r)) {
                 paddingChanged = true;
             }
         }
+
         if (paddingChanged) {
             onBoundsChange(getBounds());
         }
+
         return changed;
     }
 
     @Override
     protected void onBoundsChange(Rect bounds) {
+        int padL = 0;
+        int padT = 0;
+        int padR = 0;
+        int padB = 0;
+
+        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        int padL=0, padT=0, padR=0, padB=0;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
-            r.mDrawable.setBounds(bounds.left + r.mInsetL + padL,
-                                  bounds.top + r.mInsetT + padT,
-                                  bounds.right - r.mInsetR - padR,
-                                  bounds.bottom - r.mInsetB - padB);
-            padL += mPaddingL[i];
-            padR += mPaddingR[i];
-            padT += mPaddingT[i];
-            padB += mPaddingB[i];
+            r.mDrawable.setBounds(bounds.left + r.mInsetL + padL, bounds.top + r.mInsetT + padT,
+                    bounds.right - r.mInsetR - padR, bounds.bottom - r.mInsetB - padB);
+
+            if (nest) {
+                padL += mPaddingL[i];
+                padR += mPaddingR[i];
+                padT += mPaddingT[i];
+                padB += mPaddingB[i];
+            }
         }
     }
 
     @Override
     public int getIntrinsicWidth() {
         int width = -1;
+        int padL = 0;
+        int padR = 0;
+
+        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        int padL=0, padR=0;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
-            int w = r.mDrawable.getIntrinsicWidth()
-                  + r.mInsetL + r.mInsetR + padL + padR;
+            final int w = r.mDrawable.getIntrinsicWidth() + r.mInsetL + r.mInsetR + padL + padR;
             if (w > width) {
                 width = w;
             }
-            padL += mPaddingL[i];
-            padR += mPaddingR[i];
+
+            if (nest) {
+                padL += mPaddingL[i];
+                padR += mPaddingR[i];
+            }
         }
+
         return width;
     }
 
     @Override
     public int getIntrinsicHeight() {
         int height = -1;
+        int padT = 0;
+        int padB = 0;
+
+        final boolean nest = mLayerState.mPaddingMode == PADDING_MODE_NEST;
         final ChildDrawable[] array = mLayerState.mChildren;
         final int N = mLayerState.mNum;
-        int padT=0, padB=0;
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             final ChildDrawable r = array[i];
-            int h = r.mDrawable.getIntrinsicHeight() + r.mInsetT + r.mInsetB + + padT + padB;
+            int h = r.mDrawable.getIntrinsicHeight() + r.mInsetT + r.mInsetB + padT + padB;
             if (h > height) {
                 height = h;
             }
-            padT += mPaddingT[i];
-            padB += mPaddingB[i];
+
+            if (nest) {
+                padT += mPaddingT[i];
+                padB += mPaddingB[i];
+            }
         }
+
         return height;
     }
 
-    private boolean reapplyPadding(int i, ChildDrawable r) {
+    /**
+     * Refreshes the cached padding values for the specified child.
+     *
+     * @return true if the child's padding has changed
+     */
+    private boolean refreshChildPadding(int i, ChildDrawable r) {
         final Rect rect = mTmpRect;
         r.mDrawable.getPadding(rect);
         if (rect.left != mPaddingL[i] || rect.top != mPaddingT[i] ||
@@ -582,11 +732,15 @@
         return false;
     }
 
+    /**
+     * Ensures the child padding caches are large enough.
+     */
     private void ensurePadding() {
         final int N = mLayerState.mNum;
         if (mPaddingL != null && mPaddingL.length >= N) {
             return;
         }
+
         mPaddingL = new int[N];
         mPaddingT = new int[N];
         mPaddingR = new int[N];
@@ -639,7 +793,7 @@
 
         int mChangingConfigurations;
         int mChildrenChangingConfigurations;
-        
+
         private boolean mHaveOpacity = false;
         private int mOpacity;
 
@@ -651,6 +805,8 @@
 
         private boolean mAutoMirrored;
 
+        private int mPaddingMode = PADDING_MODE_NEST;
+
         LayerState(LayerState orig, LayerDrawable owner, Resources res) {
             if (orig != null) {
                 final ChildDrawable[] origChildDrawable = orig.mChildren;
@@ -661,7 +817,7 @@
 
                 mChangingConfigurations = orig.mChangingConfigurations;
                 mChildrenChangingConfigurations = orig.mChildrenChangingConfigurations;
-                
+
                 for (int i = 0; i < N; i++) {
                     final ChildDrawable r = mChildren[i] = new ChildDrawable();
                     final ChildDrawable or = origChildDrawable[i];
@@ -685,6 +841,7 @@
                 mStateful = orig.mStateful;
                 mCheckedConstantState = mCanConstantState = true;
                 mAutoMirrored = orig.mAutoMirrored;
+                mPaddingMode = orig.mPaddingMode;
             } else {
                 mNum = 0;
                 mChildren = null;
@@ -695,12 +852,12 @@
         public Drawable newDrawable() {
             return new LayerDrawable(this, null);
         }
-        
+
         @Override
         public Drawable newDrawable(Resources res) {
             return new LayerDrawable(this, res);
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
@@ -720,12 +877,12 @@
             mHaveOpacity = true;
             return op;
         }
-        
+
         public final boolean isStateful() {
             if (mHaveStateful) {
                 return mStateful;
             }
-            
+
             boolean stateful = false;
             final int N = mNum;
             for (int i = 0; i < N; i++) {
@@ -734,7 +891,7 @@
                     break;
                 }
             }
-            
+
             mStateful = stateful;
             mHaveStateful = true;
             return stateful;
@@ -744,7 +901,7 @@
             if (!mCheckedConstantState && mChildren != null) {
                 mCanConstantState = true;
                 final int N = mNum;
-                for (int i=0; i<N; i++) {
+                for (int i = 0; i < N; i++) {
                     if (mChildren[i].mDrawable.getConstantState() == null) {
                         mCanConstantState = false;
                         break;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 9c57a2c..44584a7 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable;
 
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
@@ -26,12 +27,15 @@
 import android.graphics.NinePatch;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.Rect;
 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;
 
@@ -56,6 +60,7 @@
     private static final boolean DEFAULT_DITHER = false;
     private NinePatchState mNinePatchState;
     private NinePatch mNinePatch;
+    private PorterDuffColorFilter mTintFilter;
     private Rect mPadding;
     private Insets mOpticalInsets = Insets.NONE;
     private Paint mPaint;
@@ -133,7 +138,14 @@
             // lazy allocation of a paint
             setDither(state.mDither);
         }
+
+        if (state.mTint != null) {
+            final int color = state.mTint.getColorForState(getState(), 0);
+            mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
+        }
+
         setAutoMirrored(state.mAutoMirrored);
+
         if (mNinePatch != null) {
             computeBitmapSize();
         }
@@ -219,6 +231,15 @@
     @Override
     public void draw(Canvas canvas) {
         final Rect bounds = getBounds();
+
+        final boolean clearColorFilter;
+        if (mTintFilter != null && getPaint().getColorFilter() == null) {
+            mPaint.setColorFilter(mTintFilter);
+            clearColorFilter = true;
+        } else {
+            clearColorFilter = false;
+        }
+
         final boolean needsMirroring = needsMirroring();
         if (needsMirroring) {
             canvas.save();
@@ -226,10 +247,16 @@
             canvas.translate(bounds.right - bounds.left, 0);
             canvas.scale(-1.0f, 1.0f);
         }
+
         mNinePatch.draw(canvas, bounds, mPaint);
+
         if (needsMirroring) {
             canvas.restore();
         }
+
+        if (clearColorFilter) {
+            mPaint.setColorFilter(null);
+        }
     }
 
     @Override
@@ -289,6 +316,65 @@
         invalidateSelf();
     }
 
+    /**
+     * Specifies a tint for this drawable.
+     * <p>
+     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
+     * tint.
+     *
+     * @param tint Color state list to use for tinting this drawable, or null to
+     *            clear the tint
+     */
+    public void setTint(ColorStateList tint) {
+        if (mNinePatchState.mTint != tint) {
+            mNinePatchState.mTint = tint;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Returns the tint color for this drawable.
+     *
+     * @return Color state list to use for tinting this drawable, or null if
+     *         none set
+     */
+    public ColorStateList getTint() {
+        return mNinePatchState.mTint;
+    }
+
+    /**
+     * Specifies the blending mode used to apply tint.
+     *
+     * @param tintMode A Porter-Duff blending mode
+     * @hide Pending finalization of supported Modes
+     */
+    public void setTintMode(Mode tintMode) {
+        if (mNinePatchState.mTintMode != tintMode) {
+            mNinePatchState.mTintMode = tintMode;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Ensures the tint filter is consistent with the current tint color and
+     * mode.
+     */
+    private void updateTintFilter() {
+        final ColorStateList tint = mNinePatchState.mTint;
+        final Mode tintMode = mNinePatchState.mTintMode;
+        if (tint != null && tintMode != null) {
+            if (mTintFilter == null) {
+                mTintFilter = new PorterDuffColorFilter(0, tintMode);
+            } else {
+                mTintFilter.setMode(tintMode);
+            }
+        } else {
+            mTintFilter = null;
+        }
+    }
+
     @Override
     public void setDither(boolean dither) {
         //noinspection PointlessBooleanExpression
@@ -296,6 +382,7 @@
             // Fast common case -- leave at default dither.
             return;
         }
+
         getPaint().setDither(dither);
         invalidateSelf();
     }
@@ -366,9 +453,22 @@
 
         final boolean automirrored = a.getBoolean(
                 com.android.internal.R.styleable.NinePatchDrawable_autoMirrored, false);
+        final NinePatchState ninePatchState = new NinePatchState(
+                new NinePatch(bitmap, bitmap.getNinePatchChunk()), padding, opticalInsets, dither,
+                automirrored);
 
-        setNinePatchState(new NinePatchState(new NinePatch(bitmap, bitmap.getNinePatchChunk()),
-                padding, opticalInsets, dither, automirrored), r);
+        final int tintModeValue = a.getInt(
+                com.android.internal.R.styleable.NinePatchDrawable_tintMode, -1);
+        ninePatchState.mTintMode = Drawable.parseTintMode(tintModeValue, Mode.SRC_IN);
+        ninePatchState.mTint = a.getColorStateList(
+                com.android.internal.R.styleable.NinePatchDrawable_tint);
+        if (ninePatchState.mTint != null) {
+            final int color = ninePatchState.mTint.getColorForState(getState(), 0);
+            mTintFilter = new PorterDuffColorFilter(color, ninePatchState.mTintMode);
+        }
+
+        setNinePatchState(ninePatchState, r);
+
         mNinePatchState.mTargetDensity = mTargetDensity;
 
         a.recycle();
@@ -439,11 +539,35 @@
         return this;
     }
 
+    @Override
+    protected boolean onStateChange(int[] stateSet) {
+        final ColorStateList tint = mNinePatchState.mTint;
+        if (tint != null) {
+            final int newColor = tint.getColorForState(stateSet, 0);
+            final int oldColor = mTintFilter.getColor();
+            if (oldColor != newColor) {
+                mTintFilter.setColor(newColor);
+                invalidateSelf();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isStateful() {
+        final NinePatchState s = mNinePatchState;
+        return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
+    }
+
     final static class NinePatchState extends ConstantState {
-        final NinePatch mNinePatch;
-        final Rect mPadding;
-        final Insets mOpticalInsets;
-        final boolean mDither;
+        NinePatch mNinePatch;
+        ColorStateList mTint;
+        Mode mTintMode = Mode.SRC_IN;
+        Rect mPadding;
+        Insets mOpticalInsets;
+        boolean mDither;
         int mChangingConfigurations;
         int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
         boolean mAutoMirrored;
@@ -468,9 +592,10 @@
         // Copy constructor
 
         NinePatchState(NinePatchState state) {
-            // Note we don't copy the nine patch because it is immutable.
+            // We don't deep-copy any fields because they are all immutable.
             mNinePatch = state.mNinePatch;
-            // Note we don't copy the padding because it is immutable.
+            mTint = state.mTint;
+            mTintMode = state.mTintMode;
             mPadding = state.mPadding;
             mOpticalInsets = state.mOpticalInsets;
             mDither = state.mDither;
diff --git a/graphics/java/android/graphics/drawable/PictureDrawable.java b/graphics/java/android/graphics/drawable/PictureDrawable.java
index 1f5d4d8..cb2d8f6 100644
--- a/graphics/java/android/graphics/drawable/PictureDrawable.java
+++ b/graphics/java/android/graphics/drawable/PictureDrawable.java
@@ -16,16 +16,12 @@
 
 package android.graphics.drawable;
 
-import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
-import android.graphics.Matrix;
-import android.graphics.Matrix.ScaleToFit;
 import android.graphics.drawable.Drawable;
 import android.graphics.Picture;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
-import android.view.Gravity;
 
 /**
  * Drawable subclass that wraps a Picture, allowing the picture to be used
diff --git a/graphics/java/android/graphics/drawable/RevealDrawable.java b/graphics/java/android/graphics/drawable/RevealDrawable.java
new file mode 100644
index 0000000..91de638
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/RevealDrawable.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.SparseArray;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * An extension of LayerDrawable that is intended to react to touch hotspots
+ * and reveal the second layer atop the first.
+ * <p>
+ * It can be defined in an XML file with the <code>&lt;reveal&gt;</code> element.
+ * Each Drawable in the transition is defined in a nested <code>&lt;item&gt;</code>.
+ * For more information, see the guide to <a href="{@docRoot}
+ * guide/topics/resources/drawable-resource.html">Drawable Resources</a>.
+ *
+ * @attr ref android.R.styleable#LayerDrawableItem_left
+ * @attr ref android.R.styleable#LayerDrawableItem_top
+ * @attr ref android.R.styleable#LayerDrawableItem_right
+ * @attr ref android.R.styleable#LayerDrawableItem_bottom
+ * @attr ref android.R.styleable#LayerDrawableItem_drawable
+ * @attr ref android.R.styleable#LayerDrawableItem_id
+ */
+public class RevealDrawable extends LayerDrawable {
+    private final Rect mTempRect = new Rect();
+
+    /** Lazily-created map of touch hotspot IDs to ripples. */
+    private SparseArray<Ripple> mTouchedRipples;
+
+    /** Lazily-created list of actively animating ripples. */
+    private ArrayList<Ripple> mActiveRipples;
+
+    /** Lazily-created runnable for scheduling invalidation. */
+    private Runnable mAnimationRunnable;
+
+    /** Whether the animation runnable has been posted. */
+    private boolean mAnimating;
+
+    /** Target density, used to scale density-independent pixels. */
+    private float mDensity = 1.0f;
+
+    /** Paint used to control appearance of ripples. */
+    private Paint mRipplePaint;
+
+    /** Paint used to control reveal layer masking. */
+    private Paint mMaskingPaint;
+
+    /**
+     * Create a new reveal drawable with the specified list of layers. At least
+     * two layers are required for this drawable to work properly.
+     */
+    public RevealDrawable(Drawable[] layers) {
+        this(new RevealState(null, null, null), layers);
+    }
+
+    /**
+     * Create a new reveal drawable with no layers. To work correctly, at least
+     * two layers must be added to this drawable.
+     *
+     * @see #RevealDrawable(Drawable[])
+     */
+    RevealDrawable() {
+        this(new RevealState(null, null, null), (Resources) null);
+    }
+
+    private RevealDrawable(RevealState state, Resources res) {
+        super(state, res);
+    }
+
+    private RevealDrawable(RevealState state, Drawable[] layers) {
+        super(layers, state);
+    }
+
+    @Override
+    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
+            throws XmlPullParserException, IOException {
+        super.inflate(r, parser, attrs);
+
+        setTargetDensity(r.getDisplayMetrics());
+        setPaddingMode(PADDING_MODE_STACK);
+    }
+
+    @Override
+    LayerState createConstantState(LayerState state, Resources res) {
+        return new RevealState((RevealState) state, this, res);
+    }
+
+    /**
+     * Set the density at which this drawable will be rendered.
+     *
+     * @param metrics The display metrics for this drawable.
+     */
+    private void setTargetDensity(DisplayMetrics metrics) {
+        if (mDensity != metrics.density) {
+            mDensity = metrics.density;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public boolean supportsHotspots() {
+        return true;
+    }
+
+    /**
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public void setHotspot(int id, float x, float y) {
+        if (mTouchedRipples == null) {
+            mTouchedRipples = new SparseArray<Ripple>();
+            mActiveRipples = new ArrayList<Ripple>();
+        }
+
+        final Ripple ripple = mTouchedRipples.get(id);
+        if (ripple == null) {
+            final Rect padding = mTempRect;
+            getPadding(padding);
+
+            final Ripple newRipple = new Ripple(getBounds(), padding, x, y, mDensity);
+            newRipple.enter();
+
+            mActiveRipples.add(newRipple);
+            mTouchedRipples.put(id, newRipple);
+        } else {
+            ripple.move(x, y);
+        }
+
+        scheduleAnimation();
+    }
+
+    /**
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public void removeHotspot(int id) {
+        if (mTouchedRipples == null) {
+            return;
+        }
+
+        final Ripple ripple = mTouchedRipples.get(id);
+        if (ripple != null) {
+            ripple.exit();
+
+            mTouchedRipples.remove(id);
+            scheduleAnimation();
+        }
+    }
+
+    /**
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public void clearHotspots() {
+        if (mTouchedRipples == null) {
+            return;
+        }
+
+        final int n = mTouchedRipples.size();
+        for (int i = 0; i < n; i++) {
+            final Ripple ripple = mTouchedRipples.valueAt(i);
+            ripple.exit();
+        }
+
+        if (n > 0) {
+            mTouchedRipples.clear();
+            scheduleAnimation();
+        }
+    }
+
+    /**
+     * Schedules the next animation, if necessary.
+     */
+    private void scheduleAnimation() {
+        if (mActiveRipples == null || mActiveRipples.isEmpty()) {
+            mAnimating = false;
+        } else if (!mAnimating) {
+            mAnimating = true;
+
+            if (mAnimationRunnable == null) {
+                mAnimationRunnable = new Runnable() {
+                    @Override
+                    public void run() {
+                        mAnimating = false;
+                        scheduleAnimation();
+                        invalidateSelf();
+                    }
+                };
+            }
+
+            scheduleSelf(mAnimationRunnable, SystemClock.uptimeMillis() + 1000 / 60);
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        final int layerCount = getNumberOfLayers();
+        if (layerCount == 0) {
+            return;
+        }
+
+        getDrawable(0).draw(canvas);
+
+        final Rect bounds = getBounds();
+        final ArrayList<Ripple> activeRipples = mActiveRipples;
+        if (layerCount == 1 || bounds.isEmpty() || activeRipples == null
+                || activeRipples.isEmpty()) {
+            // Nothing to reveal, we're done here.
+            return;
+        }
+
+        if (mRipplePaint == null) {
+            mRipplePaint = new Paint();
+            mRipplePaint.setAntiAlias(true);
+        }
+
+        // Draw ripple mask into a buffer that merges using SRC_OVER.
+        boolean needsMask = false;
+        int layerSaveCount = -1;
+        int n = activeRipples.size();
+        for (int i = 0; i < n; i++) {
+            final Ripple ripple = activeRipples.get(i);
+            if (!ripple.active()) {
+                activeRipples.remove(i);
+                i--;
+                n--;
+            } else {
+                if (layerSaveCount < 0) {
+                    layerSaveCount = canvas.saveLayer(
+                            bounds.left, bounds.top, bounds.right, bounds.bottom, null, 0);
+                    // Ripples must be clipped to bounds, otherwise SRC_IN will
+                    // miss them and we'll get artifacts.
+                    canvas.clipRect(bounds);
+                }
+
+                needsMask |= ripple.draw(canvas, mRipplePaint);
+            }
+        }
+
+        // If a layer was saved, it contains the ripple mask. Draw the reveal
+        // into another layer and composite using SRC_IN, then composite onto
+        // the original canvas.
+        if (layerSaveCount >= 0) {
+            if (needsMask) {
+                if (mMaskingPaint == null) {
+                    mMaskingPaint = new Paint();
+                    mMaskingPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
+                }
+
+                // TODO: When Drawable.setXfermode() is supported by all drawables,
+                // we won't need an extra layer.
+                canvas.saveLayer(
+                        bounds.left, bounds.top, bounds.right, bounds.bottom, mMaskingPaint, 0);
+                getDrawable(1).draw(canvas);
+            }
+
+            canvas.restoreToCount(layerSaveCount);
+        }
+    }
+
+    private static class RevealState extends LayerState {
+        public RevealState(RevealState orig, RevealDrawable owner, Resources res) {
+            super(orig, owner, res);
+        }
+
+        @Override
+        public Drawable newDrawable() {
+            return newDrawable(null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new RevealDrawable(this, res);
+        }
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java
new file mode 100644
index 0000000..618afb8
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/Ripple.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 android.graphics.drawable;
+
+import android.animation.TimeInterpolator;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.graphics.Rect;
+import android.util.MathUtils;
+import android.view.animation.AnimationUtils;
+import android.view.animation.DecelerateInterpolator;
+
+/**
+ * Draws a Quantum Paper ripple.
+ */
+class Ripple {
+    private static final TimeInterpolator INTERPOLATOR = new DecelerateInterpolator(2.0f);
+
+    /** Starting radius for a ripple. */
+    private static final int STARTING_RADIUS_DP = 16;
+
+    /** Radius when finger is outside view bounds. */
+    private static final int OUTSIDE_RADIUS_DP = 16;
+
+    /** Margin when constraining outside touches (fraction of outer radius). */
+    private static final float OUTSIDE_MARGIN = 0.8f;
+
+    /** Resistance factor when constraining outside touches. */
+    private static final float OUTSIDE_RESISTANCE = 0.7f;
+
+    /** Duration for animating the trailing edge of the ripple. */
+    private static final int EXIT_DURATION = 600;
+
+    /** Duration for animating the leading edge of the ripple. */
+    private static final int ENTER_DURATION = 400;
+
+    /** Minimum elapsed time between start of enter and exit animations. */
+    private static final int EXIT_MIN_DELAY = 200;
+
+    /** Duration for animating between inside and outside touch. */
+    private static final int OUTSIDE_DURATION = 300;
+
+    /** Duration for animating pulses. */
+    private static final int PULSE_DURATION = 400;
+
+    /** Interval between pulses while inside and fully entered. */
+    private static final int PULSE_INTERVAL = 400;
+
+    /** Minimum alpha value during a pulse animation. */
+    private static final int PULSE_MIN_ALPHA = 128;
+
+    /** Delay before pulses start. */
+    private static final int PULSE_DELAY = 500;
+
+    private final Rect mBounds;
+    private final Rect mPadding;
+    private final int mMinRadius;
+    private final int mOutsideRadius;
+
+    /** Center x-coordinate. */
+    private float mX;
+
+    /** Center y-coordinate. */
+    private float mY;
+
+    /** Whether the center is within the parent bounds. */
+    private boolean mInside;
+
+    /** When the ripple started appearing. */
+    private long mEnterTime = -1;
+
+    /** When the ripple started vanishing. */
+    private long mExitTime = -1;
+
+    /** When the ripple last transitioned between inside and outside touch. */
+    private long mOutsideTime = -1;
+
+    /**
+     * Creates a new ripple with the specified parent bounds, padding, initial
+     * position, and screen density.
+     */
+    public Ripple(Rect bounds, Rect padding, float x, float y, float density) {
+        mBounds = bounds;
+        mPadding = padding;
+        mInside = mBounds.contains((int) x, (int) y);
+
+        mX = x;
+        mY = y;
+
+        mMinRadius = (int) (density * STARTING_RADIUS_DP + 0.5f);
+        mOutsideRadius = (int) (density * OUTSIDE_RADIUS_DP + 0.5f);
+    }
+
+    /**
+     * Updates the center coordinates.
+     */
+    public void move(float x, float y) {
+        mX = x;
+        mY = y;
+
+        final boolean inside = mBounds.contains((int) x, (int) y);
+        if (mInside != inside) {
+            mOutsideTime = AnimationUtils.currentAnimationTimeMillis();
+            mInside = inside;
+        }
+    }
+
+    /**
+     * Starts the enter animation.
+     */
+    public void enter() {
+        mEnterTime = AnimationUtils.currentAnimationTimeMillis();
+    }
+
+    /**
+     * Starts the exit animation. If {@link #enter()} was called recently, the
+     * animation may be postponed.
+     */
+    public void exit() {
+        final long minTime = mEnterTime + EXIT_MIN_DELAY;
+        mExitTime = Math.max(minTime, AnimationUtils.currentAnimationTimeMillis());
+    }
+
+    /**
+     * Returns whether this ripple is currently animating.
+     */
+    public boolean active() {
+        final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+        return mEnterTime >= 0 && mEnterTime <= currentTime
+                && (mExitTime < 0 || currentTime <= mExitTime + EXIT_DURATION);
+    }
+
+    /**
+     * Constrains a value within a specified asymptotic margin outside a minimum
+     * and maximum.
+     */
+    private static float looseConstrain(float value, float min, float max, float margin,
+            float factor) {
+        if (value < min) {
+            return min - Math.min(margin, (float) Math.pow(min - value, factor));
+        } else if (value > max) {
+            return max + Math.min(margin, (float) Math.pow(value - max, factor));
+        } else {
+            return value;
+        }
+    }
+
+    public boolean draw(Canvas c, Paint p) {
+        final Rect bounds = mBounds;
+        final Rect padding = mPadding;
+        final float dX = Math.max(mX, bounds.right - mX);
+        final float dY = Math.max(mY, bounds.bottom - mY);
+        final int maxRadius = (int) Math.ceil(Math.sqrt(dX * dX + dY * dY));
+
+        // Track three states:
+        // - Enter: touch begins, affects outer radius
+        // - Outside: touch moves outside bounds, affects maximum outer radius
+        // - Exit: touch ends, affects inner radius
+        final long currentTime = AnimationUtils.currentAnimationTimeMillis();
+        final float enterState = mEnterTime < 0 ? 0 : INTERPOLATOR.getInterpolation(
+                MathUtils.constrain((currentTime - mEnterTime) / (float) ENTER_DURATION, 0, 1));
+        final float outsideState = mOutsideTime < 0 ? 1 : INTERPOLATOR.getInterpolation(
+                MathUtils.constrain((currentTime - mOutsideTime) / (float) OUTSIDE_DURATION, 0, 1));
+        final float exitState = mExitTime < 0 ? 0 : INTERPOLATOR.getInterpolation(
+                MathUtils.constrain((currentTime - mExitTime) / (float) EXIT_DURATION, 0, 1));
+        final float insideRadius = MathUtils.lerp(mMinRadius, maxRadius, enterState);
+        final float outerRadius = MathUtils.lerp(mOutsideRadius, insideRadius,
+                mInside ? outsideState : 1 - outsideState);
+
+        // Apply resistance effect when outside bounds.
+        final float x = looseConstrain(mX, bounds.left + padding.left, bounds.right - padding.right,
+                outerRadius * OUTSIDE_MARGIN, OUTSIDE_RESISTANCE);
+        final float y = looseConstrain(mY, bounds.top + padding.top, bounds.bottom - padding.bottom,
+                outerRadius * OUTSIDE_MARGIN, OUTSIDE_RESISTANCE);
+
+        // Compute maximum alpha, taking pulse into account when active.
+        final long pulseTime = (currentTime - mEnterTime - ENTER_DURATION - PULSE_DELAY);
+        final int maxAlpha;
+        if (pulseTime < 0) {
+            maxAlpha = 255;
+        } else {
+            final float pulseState = (pulseTime % (PULSE_INTERVAL + PULSE_DURATION))
+                    / (float) PULSE_DURATION;
+            if (pulseState >= 1) {
+                maxAlpha = 255;
+            } else {
+                final float pulseAlpha;
+                if (pulseState > 0.5) {
+                    // Pulsing in to max alpha.
+                    pulseAlpha = MathUtils.lerp(PULSE_MIN_ALPHA, 255, (pulseState - .5f) * 2);
+                } else {
+                    // Pulsing out to min alpha.
+                    pulseAlpha = MathUtils.lerp(255, PULSE_MIN_ALPHA, pulseState * 2f);
+                }
+
+                if (exitState > 0) {
+                    // Animating exit, interpolate pulse with exit state.
+                    maxAlpha = (int) (MathUtils.lerp(255, pulseAlpha, exitState) + 0.5f);
+                } else if (mInside) {
+                    // No animation, no need to interpolate.
+                    maxAlpha = (int) (pulseAlpha + 0.5f);
+                } else {
+                    // Animating inside, interpolate pulse with inside state.
+                    maxAlpha = (int) (MathUtils.lerp(pulseAlpha, 255, outsideState) + 0.5f);
+                }
+            }
+        }
+
+        if (maxAlpha > 0) {
+            if (exitState <= 0) {
+                // Exit state isn't showing, so we can simplify to a solid
+                // circle.
+                if (outerRadius > 0) {
+                    p.setAlpha(maxAlpha);
+                    p.setStyle(Style.FILL);
+                    c.drawCircle(x, y, outerRadius, p);
+                    return true;
+                }
+            } else {
+                // Both states are showing, so we need a circular stroke.
+                final float innerRadius = MathUtils.lerp(0, outerRadius, exitState);
+                final float strokeWidth = outerRadius - innerRadius;
+                if (strokeWidth > 0) {
+                    final float strokeRadius = innerRadius + strokeWidth / 2f;
+                    final int alpha = (int) (MathUtils.lerp(maxAlpha, 0, exitState) + 0.5f);
+                    if (alpha > 0) {
+                        p.setAlpha(alpha);
+                        p.setStyle(Style.STROKE);
+                        p.setStrokeWidth(strokeWidth);
+                        c.drawCircle(x, y, strokeRadius, p);
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public void getBounds(Rect bounds) {
+        final int x = (int) mX;
+        final int y = (int) mY;
+        final int dX = Math.max(x, mBounds.right - x);
+        final int dY = Math.max(x, mBounds.bottom - y);
+        final int maxRadius = (int) Math.ceil(Math.sqrt(dX * dX + dY * dY));
+        bounds.set(x - maxRadius, y - maxRadius, x + maxRadius, y + maxRadius);
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index aec3a4b..630dc2e 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -31,13 +31,14 @@
 import java.io.IOException;
 
 /**
- * <p>A Drawable that can rotate another Drawable based on the current level
- * value. The start and end angles of rotation can be controlled to map any
- * circular arc to the level values range.</p>
- *
- * <p>It can be defined in an XML file with the <code>&lt;rotate></code> element. For more
- * information, see the guide to <a
- * href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+ * <p>
+ * A Drawable that can rotate another Drawable based on the current level value.
+ * The start and end angles of rotation can be controlled to map any circular
+ * arc to the level values range.
+ * <p>
+ * It can be defined in an XML file with the <code>&lt;rotate&gt;</code> element.
+ * For more information, see the guide to
+ * <a href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.
  *
  * @attr ref android.R.styleable#RotateDrawable_visible
  * @attr ref android.R.styleable#RotateDrawable_fromDegrees
@@ -49,20 +50,21 @@
 public class RotateDrawable extends Drawable implements Drawable.Callback {
     private static final float MAX_LEVEL = 10000.0f;
 
-    private RotateState mState;
+    private final RotateState mState;
+
     private boolean mMutated;
 
     /**
-     * <p>Create a new rotating drawable with an empty state.</p>
+     * Create a new rotating drawable with an empty state.
      */
     public RotateDrawable() {
         this(null, null);
     }
 
     /**
-     * <p>Create a new rotating drawable with the specified state. A copy of
+     * Create a new rotating drawable with the specified state. A copy of
      * this state is used as the internal state for the newly created
-     * drawable.</p>
+     * drawable.
      *
      * @param rotateState the state for this drawable
      */
@@ -70,28 +72,42 @@
         mState = new RotateState(rotateState, this, res);
     }
 
+    @Override
     public void draw(Canvas canvas) {
-        int saveCount = canvas.save();
-
-        Rect bounds = mState.mDrawable.getBounds();
-
-        int w = bounds.right - bounds.left;
-        int h = bounds.bottom - bounds.top;
-
         final RotateState st = mState;
-        
-        float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
-        float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
+        final Drawable d = st.mDrawable;
+        final Rect bounds = d.getBounds();
+        final int w = bounds.right - bounds.left;
+        final int h = bounds.bottom - bounds.top;
+        final float px = st.mPivotXRel ? (w * st.mPivotX) : st.mPivotX;
+        final float py = st.mPivotYRel ? (h * st.mPivotY) : st.mPivotY;
 
+        final int saveCount = canvas.save();
         canvas.rotate(st.mCurrentDegrees, px + bounds.left, py + bounds.top);
-
-        st.mDrawable.draw(canvas);
-
+        d.draw(canvas);
         canvas.restoreToCount(saveCount);
     }
 
     /**
-     * Returns the drawable rotated by this RotateDrawable.
+     * Sets the drawable rotated by this RotateDrawable.
+     *
+     * @param drawable The drawable to rotate
+     */
+    public void setDrawable(Drawable drawable) {
+        final Drawable oldDrawable = mState.mDrawable;
+        if (oldDrawable != drawable) {
+            if (oldDrawable != null) {
+                oldDrawable.setCallback(null);
+            }
+            mState.mDrawable = drawable;
+            if (drawable != null) {
+                drawable.setCallback(this);
+            }
+        }
+    }
+
+    /**
+     * @return The drawable rotated by this RotateDrawable
      */
     public Drawable getDrawable() {
         return mState.mDrawable;
@@ -103,7 +119,8 @@
                 | mState.mChangingConfigurations
                 | mState.mDrawable.getChangingConfigurations();
     }
-    
+
+    @Override
     public void setAlpha(int alpha) {
         mState.mDrawable.setAlpha(alpha);
     }
@@ -113,14 +130,149 @@
         return mState.mDrawable.getAlpha();
     }
 
+    @Override
     public void setColorFilter(ColorFilter cf) {
         mState.mDrawable.setColorFilter(cf);
     }
 
+    @Override
     public int getOpacity() {
         return mState.mDrawable.getOpacity();
     }
 
+    /**
+     * Sets the start angle for rotation.
+     *
+     * @param fromDegrees Starting angle in degrees
+     */
+    public void setFromDegrees(float fromDegrees) {
+        if (mState.mFromDegrees != fromDegrees) {
+            mState.mFromDegrees = fromDegrees;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return The starting angle for rotation in degrees
+     */
+    public float getFromDegrees() {
+        return mState.mFromDegrees;
+    }
+
+    /**
+     * Sets the end angle for rotation.
+     *
+     * @param toDegrees Ending angle in degrees
+     */
+    public void setToDegrees(float toDegrees) {
+        if (mState.mToDegrees != toDegrees) {
+            mState.mToDegrees = toDegrees;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return The ending angle for rotation in degrees
+     */
+    public float getToDegrees() {
+        return mState.mToDegrees;
+    }
+
+    /**
+     * Sets the X position around which the drawable is rotated.
+     *
+     * @param pivotX X position around which to rotate. If the X pivot is
+     *            relative, the position represents a fraction of the drawable
+     *            width. Otherwise, the position represents an absolute value in
+     *            pixels.
+     * @see #setPivotXRelative(boolean)
+     */
+    public void setPivotX(float pivotX) {
+        if (mState.mPivotX == pivotX) {
+            mState.mPivotX = pivotX;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return X position around which to rotate
+     * @see #setPivotX(float)
+     */
+    public float getPivotX() {
+        return mState.mPivotX;
+    }
+
+    /**
+     * Sets whether the X pivot value represents a fraction of the drawable
+     * width or an absolute value in pixels.
+     *
+     * @param relative True if the X pivot represents a fraction of the drawable
+     *            width, or false if it represents an absolute value in pixels
+     */
+    public void setPivotXRelative(boolean relative) {
+        if (mState.mPivotXRel == relative) {
+            mState.mPivotXRel = relative;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return True if the X pivot represents a fraction of the drawable width,
+     *         or false if it represents an absolute value in pixels
+     * @see #setPivotXRelative(boolean)
+     */
+    public boolean isPivotXRelative() {
+        return mState.mPivotXRel;
+    }
+
+    /**
+     * Sets the Y position around which the drawable is rotated.
+     *
+     * @param pivotY Y position around which to rotate. If the Y pivot is
+     *            relative, the position represents a fraction of the drawable
+     *            height. Otherwise, the position represents an absolute value
+     *            in pixels.
+     * @see #setPivotYRelative(boolean)
+     */
+    public void setPivotY(float pivotY) {
+        if (mState.mPivotY == pivotY) {
+            mState.mPivotY = pivotY;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return Y position around which to rotate
+     * @see #setPivotY(float)
+     */
+    public float getPivotY() {
+        return mState.mPivotY;
+    }
+
+    /**
+     * Sets whether the Y pivot value represents a fraction of the drawable
+     * height or an absolute value in pixels.
+     *
+     * @param relative True if the Y pivot represents a fraction of the drawable
+     *            height, or false if it represents an absolute value in pixels
+     */
+    public void setPivotYRelative(boolean relative) {
+        if (mState.mPivotYRel == relative) {
+            mState.mPivotYRel = relative;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @return True if the Y pivot represents a fraction of the drawable height,
+     *         or false if it represents an absolute value in pixels
+     * @see #setPivotYRelative(boolean)
+     */
+    public boolean isPivotYRelative() {
+        return mState.mPivotYRel;
+    }
+
+    @Override
     public void invalidateDrawable(Drawable who) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -128,6 +280,7 @@
         }
     }
 
+    @Override
     public void scheduleDrawable(Drawable who, Runnable what, long when) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -135,6 +288,7 @@
         }
     }
 
+    @Override
     public void unscheduleDrawable(Drawable who, Runnable what) {
         final Callback callback = getCallback();
         if (callback != null) {
@@ -157,10 +311,10 @@
     public boolean isStateful() {
         return mState.mDrawable.isStateful();
     }
-    
+
     @Override
     protected boolean onStateChange(int[] state) {
-        boolean changed = mState.mDrawable.setState(state);
+        final boolean changed = mState.mDrawable.setState(state);
         onBoundsChange(getBounds());
         return changed;
     }
@@ -172,7 +326,7 @@
 
         mState.mCurrentDegrees = mState.mFromDegrees +
                 (mState.mToDegrees - mState.mFromDegrees) *
-                        ((float) level / MAX_LEVEL);
+                        (level / MAX_LEVEL);
 
         invalidateSelf();
         return true;
@@ -206,16 +360,15 @@
     @Override
     public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
             throws XmlPullParserException, IOException {
-
-        TypedArray a = r.obtainAttributes(attrs,
+        final TypedArray a = r.obtainAttributes(attrs,
                 com.android.internal.R.styleable.RotateDrawable);
 
         super.inflateWithAttributes(r, parser, a,
                 com.android.internal.R.styleable.RotateDrawable_visible);
-        
+
         TypedValue tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotX);
-        boolean pivotXRel;
-        float pivotX;
+        final boolean pivotXRel;
+        final float pivotX;
         if (tv == null) {
             pivotXRel = true;
             pivotX = 0.5f;
@@ -223,10 +376,10 @@
             pivotXRel = tv.type == TypedValue.TYPE_FRACTION;
             pivotX = pivotXRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
         }
-        
+
         tv = a.peekValue(com.android.internal.R.styleable.RotateDrawable_pivotY);
-        boolean pivotYRel;
-        float pivotY;
+        final boolean pivotYRel;
+        final float pivotY;
         if (tv == null) {
             pivotYRel = true;
             pivotY = 0.5f;
@@ -235,12 +388,12 @@
             pivotY = pivotYRel ? tv.getFraction(1.0f, 1.0f) : tv.getFloat();
         }
 
-        float fromDegrees = a.getFloat(
+        final float fromDegrees = a.getFloat(
                 com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f);
-        float toDegrees = a.getFloat(
+        final float toDegrees = a.getFloat(
                 com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);
 
-        int res = a.getResourceId(
+        final int res = a.getResourceId(
                 com.android.internal.R.styleable.RotateDrawable_drawable, 0);
         Drawable drawable = null;
         if (res > 0) {
@@ -248,8 +401,8 @@
         }
 
         a.recycle();
-        
-        int outerDepth = parser.getDepth();
+
+        final int outerDepth = parser.getDepth();
         int type;
         while ((type = parser.next()) != XmlPullParser.END_DOCUMENT &&
                (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
@@ -268,13 +421,15 @@
             Log.w("drawable", "No drawable specified for <rotate>");
         }
 
-        mState.mDrawable = drawable;
-        mState.mPivotXRel = pivotXRel;
-        mState.mPivotX = pivotX;
-        mState.mPivotYRel = pivotYRel;
-        mState.mPivotY = pivotY;
-        mState.mFromDegrees = mState.mCurrentDegrees = fromDegrees;
-        mState.mToDegrees = toDegrees;
+        final RotateState st = mState;
+        st.mDrawable = drawable;
+        st.mPivotXRel = pivotXRel;
+        st.mPivotX = pivotX;
+        st.mPivotYRel = pivotYRel;
+        st.mPivotY = pivotY;
+        st.mFromDegrees = fromDegrees;
+        st.mCurrentDegrees = fromDegrees;
+        st.mToDegrees = toDegrees;
 
         if (drawable != null) {
             drawable.setCallback(this);
@@ -291,15 +446,15 @@
     }
 
     /**
-     * <p>Represents the state of a rotation for a given drawable. The same
+     * Represents the state of a rotation for a given drawable. The same
      * rotate drawable can be invoked with different states to drive several
-     * rotations at the same time.</p>
+     * rotations at the same time.
      */
     final static class RotateState extends Drawable.ConstantState {
         Drawable mDrawable;
 
         int mChangingConfigurations;
-        
+
         boolean mPivotXRel;
         float mPivotX;
         boolean mPivotYRel;
@@ -311,7 +466,7 @@
         float mCurrentDegrees;
 
         private boolean mCanConstantState;
-        private boolean mCheckedConstantState;        
+        private boolean mCheckedConstantState;
 
         public RotateState(RotateState source, RotateDrawable owner, Resources res) {
             if (source != null) {
@@ -336,12 +491,12 @@
         public Drawable newDrawable() {
             return new RotateDrawable(this, null);
         }
-        
+
         @Override
         public Drawable newDrawable(Resources res) {
             return new RotateDrawable(this, res);
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 93f2dc60..16de9f3 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -16,10 +16,18 @@
 
 package android.graphics.drawable;
 
-import android.graphics.*;
-import android.graphics.drawable.shapes.Shape;
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.graphics.drawable.shapes.Shape;
 import android.util.AttributeSet;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -28,22 +36,24 @@
 import java.io.IOException;
 
 /**
- * A Drawable object that draws primitive shapes. 
- * A ShapeDrawable takes a {@link android.graphics.drawable.shapes.Shape}
- * object and manages its presence on the screen. If no Shape is given, then
- * the ShapeDrawable will default to a 
- * {@link android.graphics.drawable.shapes.RectShape}.
- *
- * <p>This object can be defined in an XML file with the <code>&lt;shape></code> element.</p>
- *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about how to use ShapeDrawable, read the
- * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#shape-drawable">
- * Canvas and Drawables</a> document. For more information about defining a ShapeDrawable in
- * XML, read the
- * <a href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
- * document.</p></div>
+ * A Drawable object that draws primitive shapes. A ShapeDrawable takes a
+ * {@link android.graphics.drawable.shapes.Shape} object and manages its
+ * presence on the screen. If no Shape is given, then the ShapeDrawable will
+ * default to a {@link android.graphics.drawable.shapes.RectShape}.
+ * <p>
+ * This object can be defined in an XML file with the <code>&lt;shape></code>
+ * element.
+ * </p>
+ * <div class="special reference"> <h3>Developer Guides</h3>
+ * <p>
+ * For more information about how to use ShapeDrawable, read the <a
+ * href="{@docRoot}guide/topics/graphics/2d-graphics.html#shape-drawable">
+ * Canvas and Drawables</a> document. For more information about defining a
+ * ShapeDrawable in XML, read the <a href="{@docRoot}
+ * guide/topics/resources/drawable-resource.html#Shape">Drawable Resources</a>
+ * document.
+ * </p>
+ * </div>
  *
  * @attr ref android.R.styleable#ShapeDrawablePadding_left
  * @attr ref android.R.styleable#ShapeDrawablePadding_top
@@ -55,6 +65,7 @@
  */
 public class ShapeDrawable extends Drawable {
     private ShapeState mShapeState;
+    private PorterDuffColorFilter mTintFilter;
     private boolean mMutated;
 
     /**
@@ -63,20 +74,25 @@
     public ShapeDrawable() {
         this((ShapeState) null);
     }
-    
+
     /**
      * Creates a ShapeDrawable with a specified Shape.
-     * 
+     *
      * @param s the Shape that this ShapeDrawable should be
      */
     public ShapeDrawable(Shape s) {
         this((ShapeState) null);
-        
+
         mShapeState.mShape = s;
     }
-    
+
     private ShapeDrawable(ShapeState state) {
         mShapeState = new ShapeState(state);
+
+        if (state != null && state.mTint != null) {
+            final int color = state.mTint.getColorForState(getState(), 0);
+            mTintFilter = new PorterDuffColorFilter(color, state.mTintMode);
+        }
     }
 
     /**
@@ -85,7 +101,7 @@
     public Shape getShape() {
         return mShapeState.mShape;
     }
-    
+
     /**
      * Sets the Shape of this ShapeDrawable.
      */
@@ -93,19 +109,19 @@
         mShapeState.mShape = s;
         updateShape();
     }
-    
+
     /**
-     * Sets a ShaderFactory to which requests for a 
+     * Sets a ShaderFactory to which requests for a
      * {@link android.graphics.Shader} object will be made.
-     * 
+     *
      * @param fact an instance of your ShaderFactory implementation
      */
     public void setShaderFactory(ShaderFactory fact) {
         mShapeState.mShaderFactory = fact;
     }
-    
+
     /**
-     * Returns the ShaderFactory used by this ShapeDrawable for requesting a 
+     * Returns the ShaderFactory used by this ShapeDrawable for requesting a
      * {@link android.graphics.Shader}.
      */
     public ShaderFactory getShaderFactory() {
@@ -118,14 +134,14 @@
     public Paint getPaint() {
         return mShapeState.mPaint;
     }
-    
+
     /**
      * Sets padding for the shape.
-     * 
-     * @param left    padding for the left side (in pixels)
-     * @param top     padding for the top (in pixels)
-     * @param right   padding for the right side (in pixels)
-     * @param bottom  padding for the bottom (in pixels)
+     *
+     * @param left padding for the left side (in pixels)
+     * @param top padding for the top (in pixels)
+     * @param right padding for the right side (in pixels)
+     * @param bottom padding for the bottom (in pixels)
      */
     public void setPadding(int left, int top, int right, int bottom) {
         if ((left | top | right | bottom) == 0) {
@@ -138,10 +154,10 @@
         }
         invalidateSelf();
     }
-    
+
     /**
-     * Sets padding for this shape, defined by a Rect object.
-     * Define the padding in the Rect object as: left, top, right, bottom.
+     * Sets padding for this shape, defined by a Rect object. Define the padding
+     * in the Rect object as: left, top, right, bottom.
      */
     public void setPadding(Rect padding) {
         if (padding == null) {
@@ -154,37 +170,37 @@
         }
         invalidateSelf();
     }
-    
+
     /**
      * Sets the intrinsic (default) width for this shape.
-     * 
+     *
      * @param width the intrinsic width (in pixels)
      */
     public void setIntrinsicWidth(int width) {
         mShapeState.mIntrinsicWidth = width;
         invalidateSelf();
     }
-    
+
     /**
      * Sets the intrinsic (default) height for this shape.
-     * 
+     *
      * @param height the intrinsic height (in pixels)
      */
     public void setIntrinsicHeight(int height) {
         mShapeState.mIntrinsicHeight = height;
         invalidateSelf();
     }
-    
+
     @Override
     public int getIntrinsicWidth() {
         return mShapeState.mIntrinsicWidth;
     }
-    
+
     @Override
     public int getIntrinsicHeight() {
         return mShapeState.mIntrinsicHeight;
     }
-    
+
     @Override
     public boolean getPadding(Rect padding) {
         if (mShapeState.mPadding != null) {
@@ -196,14 +212,14 @@
     }
 
     private static int modulateAlpha(int paintAlpha, int alpha) {
-        int scale = alpha + (alpha >>> 7);  // convert to 0..256
+        int scale = alpha + (alpha >>> 7); // convert to 0..256
         return paintAlpha * scale >>> 8;
     }
 
     /**
-     * Called from the drawable's draw() method after the canvas has been set
-     * to draw the shape at (0,0). Subclasses can override for special effects
-     * such as multiple layers, stroking, etc.
+     * Called from the drawable's draw() method after the canvas has been set to
+     * draw the shape at (0,0). Subclasses can override for special effects such
+     * as multiple layers, stroking, etc.
      */
     protected void onDraw(Shape shape, Canvas canvas, Paint paint) {
         shape.draw(canvas, paint);
@@ -211,23 +227,37 @@
 
     @Override
     public void draw(Canvas canvas) {
-        Rect r = getBounds();
-        Paint paint = mShapeState.mPaint;
+        final Rect r = getBounds();
+        final ShapeState state = mShapeState;
+        final Paint paint = state.mPaint;
 
-        int prevAlpha = paint.getAlpha();
-        paint.setAlpha(modulateAlpha(prevAlpha, mShapeState.mAlpha));
+        final int prevAlpha = paint.getAlpha();
+        paint.setAlpha(modulateAlpha(prevAlpha, state.mAlpha));
 
         // only draw shape if it may affect output
         if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadow) {
-            if (mShapeState.mShape != null) {
-                // need the save both for the translate, and for the (unknown) Shape
-                int count = canvas.save();
+            final boolean clearColorFilter;
+            if (mTintFilter != null && paint.getColorFilter() == null) {
+                paint.setColorFilter(mTintFilter);
+                clearColorFilter = true;
+            } else {
+                clearColorFilter = false;
+            }
+
+            if (state.mShape != null) {
+                // need the save both for the translate, and for the (unknown)
+                // Shape
+                final int count = canvas.save();
                 canvas.translate(r.left, r.top);
-                onDraw(mShapeState.mShape, canvas, paint);
+                onDraw(state.mShape, canvas, paint);
                 canvas.restoreToCount(count);
             } else {
                 canvas.drawRect(r, paint);
             }
+
+            if (clearColorFilter) {
+                paint.setColorFilter(null);
+            }
         }
 
         // restore
@@ -239,16 +269,17 @@
         return super.getChangingConfigurations()
                 | mShapeState.mChangingConfigurations;
     }
-    
+
     /**
      * Set the alpha level for this drawable [0..255]. Note that this drawable
      * also has a color in its paint, which has an alpha as well. These two
      * values are automatically combined during drawing. Thus if the color's
      * alpha is 75% (i.e. 192) and the drawable's alpha is 50% (i.e. 128), then
-     * the combined alpha that will be used during drawing will be 37.5%
-     * (i.e. 96).
+     * the combined alpha that will be used during drawing will be 37.5% (i.e.
+     * 96).
      */
-    @Override public void setAlpha(int alpha) {
+    @Override
+    public void setAlpha(int alpha) {
         mShapeState.mAlpha = alpha;
         invalidateSelf();
     }
@@ -258,12 +289,81 @@
         return mShapeState.mAlpha;
     }
 
+    /**
+     * Specifies a tint for this drawable.
+     * <p>
+     * Setting a color filter via {@link #setColorFilter(ColorFilter)} overrides
+     * tint.
+     *
+     * @param tint Color state list to use for tinting this drawable, or null to
+     *            clear the tint
+     */
+    public void setTint(ColorStateList tint) {
+        if (mShapeState.mTint != tint) {
+            mShapeState.mTint = tint;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Returns the tint color for this drawable.
+     *
+     * @return Color state list to use for tinting this drawable, or null if
+     *         none set
+     */
+    public ColorStateList getTint() {
+        return mShapeState.mTint;
+    }
+
+    /**
+     * Specifies the blending mode used to apply tint.
+     *
+     * @param tintMode A Porter-Duff blending mode
+     * @hide Pending finalization of supported Modes
+     */
+    public void setTintMode(Mode tintMode) {
+        if (mShapeState.mTintMode != tintMode) {
+            mShapeState.mTintMode = tintMode;
+            updateTintFilter();
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * Ensures the tint filter is consistent with the current tint color and
+     * mode.
+     */
+    private void updateTintFilter() {
+        final ColorStateList tint = mShapeState.mTint;
+        final Mode tintMode = mShapeState.mTintMode;
+        if (tint != null && tintMode != null) {
+            if (mTintFilter == null) {
+                mTintFilter = new PorterDuffColorFilter(0, tintMode);
+            } else {
+                mTintFilter.setMode(tintMode);
+            }
+        } else {
+            mTintFilter = null;
+        }
+    }
+
+    /**
+     * Returns the blending mode used to apply tint.
+     *
+     * @return The Porter-Duff blending mode used to apply tint.
+     * @hide Pending finalization of supported Modes
+     */
+    public Mode getTintMode() {
+        return mShapeState.mTintMode;
+    }
+
     @Override
     public void setColorFilter(ColorFilter cf) {
         mShapeState.mPaint.setColorFilter(cf);
         invalidateSelf();
     }
-    
+
     @Override
     public int getOpacity() {
         if (mShapeState.mShape == null) {
@@ -294,9 +394,31 @@
         updateShape();
     }
 
+    @Override
+    protected boolean onStateChange(int[] stateSet) {
+        final ColorStateList tint = mShapeState.mTint;
+        if (tint != null) {
+            final int newColor = tint.getColorForState(stateSet, 0);
+            final int oldColor = mTintFilter.getColor();
+            if (oldColor != newColor) {
+                mTintFilter.setColor(newColor);
+                invalidateSelf();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    @Override
+    public boolean isStateful() {
+        final ShapeState s = mShapeState;
+        return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
+    }
+
     /**
-     * Subclasses override this to parse custom subelements.
-     * If you handle it, return true, else return <em>super.inflateTag(...)</em>.
+     * Subclasses override this to parse custom subelements. If you handle it,
+     * return true, else return <em>super.inflateTag(...)</em>.
      */
     protected boolean inflateTag(String name, Resources r, XmlPullParser parser,
             AttributeSet attrs) {
@@ -322,7 +444,7 @@
 
     @Override
     public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
-                        throws XmlPullParserException, IOException {
+            throws XmlPullParserException, IOException {
         super.inflate(r, parser, attrs);
 
         TypedArray a = r.obtainAttributes(attrs, com.android.internal.R.styleable.ShapeDrawable);
@@ -343,12 +465,12 @@
 
         int type;
         final int outerDepth = parser.getDepth();
-        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-               && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
             if (type != XmlPullParser.START_TAG) {
                 continue;
             }
-            
+
             final String name = parser.getName();
             // call our subclass
             if (!inflateTag(name, r, parser, attrs)) {
@@ -371,7 +493,7 @@
         }
         invalidateSelf();
     }
-    
+
     @Override
     public ConstantState getConstantState() {
         mShapeState.mChangingConfigurations = getChangingConfigurations();
@@ -408,16 +530,20 @@
         int mChangingConfigurations;
         Paint mPaint;
         Shape mShape;
+        ColorStateList mTint;
+        Mode mTintMode = Mode.SRC_IN;
         Rect mPadding;
         int mIntrinsicWidth;
         int mIntrinsicHeight;
         int mAlpha = 255;
         ShaderFactory mShaderFactory;
-        
+
         ShapeState(ShapeState orig) {
             if (orig != null) {
                 mPaint = orig.mPaint;
                 mShape = orig.mShape;
+                mTint = orig.mTint;
+                mTintMode = orig.mTintMode;
                 mPadding = orig.mPadding;
                 mIntrinsicWidth = orig.mIntrinsicWidth;
                 mIntrinsicHeight = orig.mIntrinsicHeight;
@@ -427,48 +553,45 @@
                 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
             }
         }
-        
+
         @Override
         public Drawable newDrawable() {
             return new ShapeDrawable(this);
         }
-        
+
         @Override
         public Drawable newDrawable(Resources res) {
             return new ShapeDrawable(this);
         }
-        
+
         @Override
         public int getChangingConfigurations() {
             return mChangingConfigurations;
         }
     }
-    
+
     /**
      * Base class defines a factory object that is called each time the drawable
      * is resized (has a new width or height). Its resize() method returns a
-     * corresponding shader, or null.
-     * Implement this class if you'd like your ShapeDrawable to use a special
-     * {@link android.graphics.Shader}, such as a 
-     * {@link android.graphics.LinearGradient}. 
-     * 
+     * corresponding shader, or null. Implement this class if you'd like your
+     * ShapeDrawable to use a special {@link android.graphics.Shader}, such as a
+     * {@link android.graphics.LinearGradient}.
      */
     public static abstract class ShaderFactory {
         /**
-         * Returns the Shader to be drawn when a Drawable is drawn.
-         * The dimensions of the Drawable are passed because they may be needed
-         * to adjust how the Shader is configured for drawing.
-         * This is called by ShapeDrawable.setShape().
-         * 
-         * @param width  the width of the Drawable being drawn
+         * Returns the Shader to be drawn when a Drawable is drawn. The
+         * dimensions of the Drawable are passed because they may be needed to
+         * adjust how the Shader is configured for drawing. This is called by
+         * ShapeDrawable.setShape().
+         *
+         * @param width the width of the Drawable being drawn
          * @param height the heigh of the Drawable being drawn
-         * @return       the Shader to be drawn
+         * @return the Shader to be drawn
          */
         public abstract Shader resize(int width, int height);
     }
-    
+
     // other subclass could wack the Shader's localmatrix based on the
     // resize params (e.g. scaletofit, etc.). This could be used to scale
     // a bitmap to fill the bounds without needing any other special casing.
 }
-
diff --git a/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
new file mode 100644
index 0000000..f4f545c
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/TouchFeedbackDrawable.java
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.content.res.ColorStateList;
+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.PixelFormat;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.SparseArray;
+
+import com.android.internal.R;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * @hide
+ */
+public class TouchFeedbackDrawable extends DrawableWrapper {
+    private final Rect mTempRect = new Rect();
+    private final Rect mPaddingRect = new Rect();
+
+    /** Current drawing bounds, used to compute dirty region. */
+    private final Rect mDrawingBounds = new Rect();
+
+    /** Current dirty bounds, union of current and previous drawing bounds. */
+    private final Rect mDirtyBounds = new Rect();
+
+    private final TouchFeedbackState mState;
+
+    /** Lazily-created map of touch hotspot IDs to ripples. */
+    private SparseArray<Ripple> mTouchedRipples;
+
+    /** Lazily-created list of actively animating ripples. */
+    private ArrayList<Ripple> mActiveRipples;
+
+    /** Lazily-created runnable for scheduling invalidation. */
+    private Runnable mAnimationRunnable;
+
+    /** Paint used to control appearance of ripples. */
+    private Paint mRipplePaint;
+
+    /** Paint used to control reveal layer masking. */
+    private Paint mMaskingPaint;
+
+    /** Target density of the display into which ripples are drawn. */
+    private float mDensity = 1.0f;
+
+    /** Whether the animation runnable has been posted. */
+    private boolean mAnimating;
+
+    /** The drawable to use as the mask. */
+    private Drawable mMask;
+
+    /* package */TouchFeedbackDrawable() {
+        this(null, null);
+    }
+
+    TouchFeedbackDrawable(TouchFeedbackState state, Resources res) {
+        mState = new TouchFeedbackState(state);
+        
+        setConstantState(mState, res);
+
+        if (res != null) {
+            mDensity = res.getDisplayMetrics().density;
+        }
+    }
+    
+    private void setConstantState(TouchFeedbackState wrapperState, Resources res) {
+        super.setConstantState(wrapperState, res);
+
+        // Load a new mask drawable from the constant state.
+        if (wrapperState == null || wrapperState.mMaskState == null) {
+            mMask = null;
+        } else if (res != null) {
+            mMask = wrapperState.mMaskState.newDrawable(res);
+        } else {
+            mMask = wrapperState.mMaskState.newDrawable();
+        }
+    }
+
+    @Override
+    public int getOpacity() {
+        return mActiveRipples != null && !mActiveRipples.isEmpty() ?
+                PixelFormat.TRANSLUCENT : PixelFormat.TRANSPARENT;
+    }
+
+    @Override
+    protected void onBoundsChange(Rect bounds) {
+        super.onBoundsChange(bounds);
+
+        if (mMask != null) {
+            mMask.setBounds(bounds);
+        }
+    }
+
+    @Override
+    protected boolean onStateChange(int[] stateSet) {
+        super.onStateChange(stateSet);
+
+        if (mRipplePaint != null) {
+            final ColorStateList stateList = mState.mTint;
+            final int newColor = stateList.getColorForState(stateSet, 0);
+            final int oldColor = mRipplePaint.getColor();
+            if (oldColor != newColor) {
+                mRipplePaint.setColor(newColor);
+                invalidateSelf();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean isProjected() {
+        return mState.mProjected;
+    }
+
+    @Override
+    public boolean isStateful() {
+        return super.isStateful() || mState.mTint.isStateful();
+    }
+
+    @Override
+    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
+            throws XmlPullParserException, IOException {
+        super.inflate(r, parser, attrs);
+
+        final TypedArray a = r.obtainAttributes(attrs, R.styleable.TouchFeedbackDrawable);
+
+        mState.mTint = a.getColorStateList(R.styleable.TouchFeedbackDrawable_tint);
+        mState.mTintMode = Drawable.parseTintMode(
+                a.getInt(R.styleable.TouchFeedbackDrawable_tintMode, -1), Mode.SRC_ATOP);
+        mState.mPinned = a.getBoolean(R.styleable.TouchFeedbackDrawable_pinned, false);
+
+        if (mState.mTint == null) {
+            throw new XmlPullParserException(parser.getPositionDescription()
+                    + ": <touch-feedback> tag requires a 'tint' attribute");
+        }
+        
+        Drawable mask = a.getDrawable(R.styleable.TouchFeedbackDrawable_mask);
+        final int drawableRes = a.getResourceId(R.styleable.TouchFeedbackDrawable_drawable, 0);
+        a.recycle();
+
+        final Drawable dr;
+        if (drawableRes != 0) {
+            dr = r.getDrawable(drawableRes);
+        } else {
+            int type;
+            while ((type = parser.next()) == XmlPullParser.TEXT) {
+                // Find the next non-text element.
+            }
+
+            if (type == XmlPullParser.START_TAG) {
+                dr = Drawable.createFromXmlInner(r, parser, attrs);
+            } else {
+                dr = null;
+            }
+        }
+
+        // If no mask is set, implicitly use the lower drawable.
+        if (mask == null) {
+            mask = dr;
+        }
+
+        // If neither a mask not a bottom layer was specified, assume we're
+        // projecting onto a parent surface.
+        mState.mProjected = mask == null && dr == null;
+
+        if (dr != null) {
+            setDrawable(dr, r);
+        } else {
+            // For now at least, we MUST have a wrapped drawable.
+            setDrawable(new ColorDrawable(Color.TRANSPARENT), r);
+        }
+
+        setMaskDrawable(mask, r);
+        setTargetDensity(r.getDisplayMetrics());
+    }
+
+    /**
+     * Sets the wrapped drawable and update the constant state.
+     *
+     * @param drawable
+     * @param res
+     */
+    void setMaskDrawable(Drawable drawable, Resources res) {
+        mMask = drawable;
+
+        if (drawable != null) {
+            // Nobody cares if the mask has a callback.
+            drawable.setCallback(null);
+
+            mState.mMaskState = drawable.getConstantState();
+        } else {
+            mState.mMaskState = null;
+        }
+    }
+
+    /**
+     * Set the density at which this drawable will be rendered.
+     *
+     * @param metrics The display metrics for this drawable.
+     */
+    private void setTargetDensity(DisplayMetrics metrics) {
+        if (mDensity != metrics.density) {
+            mDensity = metrics.density;
+            invalidateSelf();
+        }
+    }
+
+    /**
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public boolean supportsHotspots() {
+        return true;
+    }
+
+    /**
+     * TODO: Maybe we should set hotspots for state/id combinations? So touch
+     * would be state_pressed and the pointer ID.
+     *
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public void setHotspot(int id, float x, float y) {
+        if (mTouchedRipples == null) {
+            mTouchedRipples = new SparseArray<Ripple>();
+            mActiveRipples = new ArrayList<Ripple>();
+        }
+
+        final Ripple ripple = mTouchedRipples.get(id);
+        if (ripple == null) {
+            final Rect bounds = getBounds();
+            final Rect padding = mPaddingRect;
+            getPadding(padding);
+
+            if (mState.mPinned) {
+                x = bounds.exactCenterX();
+                y = bounds.exactCenterY();
+            }
+
+            final Ripple newRipple = new Ripple(bounds, padding, x, y, mDensity);
+            newRipple.enter();
+
+            mActiveRipples.add(newRipple);
+            mTouchedRipples.put(id, newRipple);
+        } else if (!mState.mPinned) {
+            ripple.move(x, y);
+        }
+
+        scheduleAnimation();
+    }
+
+    /**
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public void removeHotspot(int id) {
+        if (mTouchedRipples == null) {
+            return;
+        }
+
+        final Ripple ripple = mTouchedRipples.get(id);
+        if (ripple != null) {
+            ripple.exit();
+
+            mTouchedRipples.remove(id);
+            scheduleAnimation();
+        }
+    }
+
+    /**
+     * @hide until hotspot APIs are finalized
+     */
+    @Override
+    public void clearHotspots() {
+        if (mTouchedRipples == null) {
+            return;
+        }
+
+        final int n = mTouchedRipples.size();
+        for (int i = 0; i < n; i++) {
+            final Ripple ripple = mTouchedRipples.valueAt(i);
+            ripple.exit();
+        }
+
+        if (n > 0) {
+            mTouchedRipples.clear();
+            scheduleAnimation();
+        }
+    }
+
+    /**
+     * Schedules the next animation, if necessary.
+     */
+    private void scheduleAnimation() {
+        if (mActiveRipples == null || mActiveRipples.isEmpty()) {
+            mAnimating = false;
+        } else if (!mAnimating) {
+            mAnimating = true;
+
+            if (mAnimationRunnable == null) {
+                mAnimationRunnable = new Runnable() {
+                        @Override
+                    public void run() {
+                        mAnimating = false;
+                        scheduleAnimation();
+                        invalidateSelf();
+                    }
+                };
+            }
+
+            scheduleSelf(mAnimationRunnable, SystemClock.uptimeMillis() + 1000 / 60);
+        }
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        // The lower layer always draws normally.
+        super.draw(canvas);
+
+        if (mActiveRipples == null || mActiveRipples.size() == 0) {
+            // No ripples to draw.
+            return;
+        }
+
+        final ArrayList<Ripple> activeRipples = mActiveRipples;
+        final Drawable mask = mMask;
+        final Rect bounds = mask == null ? null : mask.getBounds();
+
+        // Draw ripples into a layer that merges using SRC_IN.
+        boolean hasRipples = false;
+        int rippleRestoreCount = -1;
+        int n = activeRipples.size();
+        for (int i = 0; i < n; i++) {
+            final Ripple ripple = activeRipples.get(i);
+            if (!ripple.active()) {
+                // TODO: Mark and sweep is more efficient.
+                activeRipples.remove(i);
+                i--;
+                n--;
+            } else {
+                // If we're masking the ripple layer, make sure we have a layer first.
+                if (mask != null && rippleRestoreCount < 0) {
+                    rippleRestoreCount = canvas.saveLayer(bounds.left, bounds.top,
+                            bounds.right, bounds.bottom, getMaskingPaint(SRC_ATOP), 0);
+                    canvas.clipRect(bounds);
+                }
+
+                hasRipples |= ripple.draw(canvas, getRipplePaint());
+            }
+        }
+
+        // If we have ripples, mask them.
+        if (mask != null && hasRipples) {
+            canvas.saveLayer(bounds.left, bounds.top, bounds.right,
+                    bounds.bottom, getMaskingPaint(DST_IN), 0);
+            mask.draw(canvas);
+        }
+
+        // Composite the layers if needed:
+        // 1. Mask     DST_IN
+        // 2. Ripples  SRC_ATOP
+        // 3. Lower    n/a
+        if (rippleRestoreCount > 0) {
+            canvas.restoreToCount(rippleRestoreCount);
+        }
+    }
+
+    private Paint getRipplePaint() {
+        if (mRipplePaint == null) {
+            mRipplePaint = new Paint();
+            mRipplePaint.setAntiAlias(true);
+            
+            final int color = mState.mTint.getColorForState(getState(), Color.TRANSPARENT);
+            mRipplePaint.setColor(color);
+        }
+        return mRipplePaint;
+    }
+    
+    private static final PorterDuffXfermode SRC_ATOP = new PorterDuffXfermode(Mode.SRC_ATOP);
+    private static final PorterDuffXfermode DST_IN = new PorterDuffXfermode(Mode.DST_IN);
+
+    private Paint getMaskingPaint(PorterDuffXfermode mode) {
+        if (mMaskingPaint == null) {
+            mMaskingPaint = new Paint();
+        }
+        mMaskingPaint.setXfermode(mode);
+        return mMaskingPaint;
+    }
+
+    @Override
+    public Rect getDirtyBounds() {
+        final Rect dirtyBounds = mDirtyBounds;
+        final Rect drawingBounds = mDrawingBounds;
+        dirtyBounds.set(drawingBounds);
+        drawingBounds.setEmpty();
+
+        final Rect rippleBounds = mTempRect;
+        final ArrayList<Ripple> activeRipples = mActiveRipples;
+        if (activeRipples != null) {
+            final int N = activeRipples.size();
+            for (int i = 0; i < N; i++) {
+                activeRipples.get(i).getBounds(rippleBounds);
+                drawingBounds.union(rippleBounds);
+            }
+        }
+
+        dirtyBounds.union(drawingBounds);
+        dirtyBounds.union(super.getDirtyBounds());
+        return dirtyBounds;
+    }
+
+    @Override
+    public ConstantState getConstantState() {
+        // TODO: Can we just rely on super.getConstantState()?
+        return mState;
+    }
+
+    static class TouchFeedbackState extends WrapperState {
+        ConstantState mMaskState;
+        ColorStateList mTint;
+        Mode mTintMode;
+        boolean mPinned;
+        boolean mProjected;
+
+        public TouchFeedbackState(TouchFeedbackState orig) {
+            super(orig);
+
+            if (orig != null) {
+                mTint = orig.mTint;
+                mTintMode = orig.mTintMode;
+                mMaskState = orig.mMaskState;
+                mPinned = orig.mPinned;
+                mProjected = orig.mProjected;
+            }
+        }
+
+        @Override
+        public Drawable newDrawable() {
+            return new TouchFeedbackDrawable(this, null);
+        }
+
+        @Override
+        public Drawable newDrawable(Resources res) {
+            return new TouchFeedbackDrawable(this, res);
+        }
+    }
+}
diff --git a/graphics/java/android/graphics/drawable/shapes/ArcShape.java b/graphics/java/android/graphics/drawable/shapes/ArcShape.java
index b90e853..84731b0 100644
--- a/graphics/java/android/graphics/drawable/shapes/ArcShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/ArcShape.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.RectF;
 
 /**
  * Creates an arc shape. The arc shape starts at a specified
diff --git a/include/androidfw/PowerManager.h b/include/androidfw/PowerManager.h
deleted file mode 100644
index ba98db0..0000000
--- a/include/androidfw/PowerManager.h
+++ /dev/null
@@ -1,33 +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_POWER_MANAGER_H
-#define _ANDROIDFW_POWER_MANAGER_H
-
-
-namespace android {
-
-enum {
-    USER_ACTIVITY_EVENT_OTHER = 0,
-    USER_ACTIVITY_EVENT_BUTTON = 1,
-    USER_ACTIVITY_EVENT_TOUCH = 2,
-
-    USER_ACTIVITY_EVENT_LAST = USER_ACTIVITY_EVENT_TOUCH, // Last valid event code.
-};
-
-} // namespace android
-
-#endif // _ANDROIDFW_POWER_MANAGER_H
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 1ab0aeb..458a46c 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -35,7 +35,6 @@
 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;
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index 767647c..af76d9d 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -27,7 +27,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
-import java.io.ObjectOutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 8ad973d..9d6d76e 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -89,11 +89,21 @@
     public static final String ACCOUNT_TYPE = "com.android.keychain";
 
     /**
+     * Package name for KeyChain chooser.
+     */
+    private static final String KEYCHAIN_PACKAGE = "com.android.keychain";
+
+    /**
      * Action to bring up the KeyChainActivity
      */
     private static final String ACTION_CHOOSER = "com.android.keychain.CHOOSER";
 
     /**
+     * Package name for the Certificate Installer.
+     */
+    private static final String CERT_INSTALLER_PACKAGE = "com.android.certinstaller";
+
+    /**
      * Extra for use with {@link #ACTION_CHOOSER}
      * @hide Also used by KeyChainActivity implementation
      */
@@ -201,7 +211,7 @@
      */
     public static Intent createInstallIntent() {
         Intent intent = new Intent(ACTION_INSTALL);
-        intent.setClassName("com.android.certinstaller",
+        intent.setClassName(CERT_INSTALLER_PACKAGE,
                             "com.android.certinstaller.CertInstallerMain");
         return intent;
     }
@@ -267,6 +277,7 @@
             throw new NullPointerException("response == null");
         }
         Intent intent = new Intent(ACTION_CHOOSER);
+        intent.setPackage(KEYCHAIN_PACKAGE);
         intent.putExtra(EXTRA_RESPONSE, new AliasResponse(response));
         intent.putExtra(EXTRA_HOST, host);
         intent.putExtra(EXTRA_PORT, port);
diff --git a/keystore/java/android/security/KeyChainAliasCallback.java b/keystore/java/android/security/KeyChainAliasCallback.java
index fc9e64b..2500863 100644
--- a/keystore/java/android/security/KeyChainAliasCallback.java
+++ b/keystore/java/android/security/KeyChainAliasCallback.java
@@ -15,10 +15,6 @@
  */
 package android.security;
 
-import android.content.Intent;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
 /**
  * The KeyChainAliasCallback is the callback for {@link
  * KeyChain#choosePrivateKeyAlias}.
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 621a605..b71efc4 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -17,12 +17,9 @@
 package android.security;
 
 import android.content.Context;
-import android.security.KeyPairGeneratorSpec.Builder;
 
 import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
 import java.security.KeyStore.ProtectionParameter;
-import java.security.cert.Certificate;
 
 /**
  * This provides the optional parameters that can be specified for
diff --git a/keystore/java/android/security/SystemKeyStore.java b/keystore/java/android/security/SystemKeyStore.java
index bca8f68..e07eaa2 100644
--- a/keystore/java/android/security/SystemKeyStore.java
+++ b/keystore/java/android/security/SystemKeyStore.java
@@ -18,10 +18,8 @@
 
 import android.os.Environment;
 import android.os.FileUtils;
-import android.os.Process;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.security.NoSuchAlgorithmException;
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index b4d482a..64363d4 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -356,7 +356,7 @@
         delete[] mLocale;
     }
     mLocale = strdupNew(locale);
-
+    
     updateResourceParamsLocked();
 }
 
@@ -593,7 +593,7 @@
                             mZipSet.setZipResourceTableAsset(ap.path, ass);
                     }
                 }
-
+                
                 if (i == 0 && ass != NULL) {
                     // If this is the first resource table in the asset
                     // manager, then we are going to cache it so that we
@@ -846,7 +846,7 @@
             /* look at the filesystem on disk */
             String8 path(createPathNameLocked(ap, locale, vendor));
             path.appendPath(fileName);
-
+    
             String8 excludeName(path);
             excludeName.append(kExcludeExtension);
             if (::getFileType(excludeName.string()) != kFileTypeNonexistent) {
@@ -854,28 +854,28 @@
                 //printf("+++ excluding '%s'\n", (const char*) excludeName);
                 return kExcludedAsset;
             }
-
+    
             pAsset = openAssetFromFileLocked(path, mode);
-
+    
             if (pAsset == NULL) {
                 /* try again, this time with ".gz" */
                 path.append(".gz");
                 pAsset = openAssetFromFileLocked(path, mode);
             }
-
+    
             if (pAsset != NULL)
                 pAsset->setAssetSource(path);
         } else {
             /* find in cache */
             String8 path(createPathNameLocked(ap, locale, vendor));
             path.appendPath(fileName);
-
+    
             AssetDir::FileInfo tmpInfo;
             bool found = false;
-
+    
             String8 excludeName(path);
             excludeName.append(kExcludeExtension);
-
+    
             if (mCache.indexOf(excludeName) != NAME_NOT_FOUND) {
                 /* go no farther */
                 //printf("+++ Excluding '%s'\n", (const char*) excludeName);
@@ -1699,7 +1699,7 @@
 
     // XXX This is broken -- the filename cache needs to hold the base
     // asset path separately from its filename.
-
+    
     partialPath = createPathNameLocked(ap, locale, vendor);
     if (dirName[0] != '\0') {
         partialPath.appendPath(dirName);
diff --git a/libs/androidfw/BackupData.cpp b/libs/androidfw/BackupData.cpp
index 2d0f755..a5b9416 100644
--- a/libs/androidfw/BackupData.cpp
+++ b/libs/androidfw/BackupData.cpp
@@ -59,9 +59,10 @@
 BackupDataWriter::BackupDataWriter(int fd)
     :m_fd(fd),
      m_status(NO_ERROR),
-     m_pos(0),
      m_entityCount(0)
 {
+    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
+    if (DEBUG) ALOGI("BackupDataWriter(%d) @ %ld", fd, (long)m_pos);
 }
 
 BackupDataWriter::~BackupDataWriter()
@@ -184,10 +185,11 @@
     :m_fd(fd),
      m_done(false),
      m_status(NO_ERROR),
-     m_pos(0),
      m_entityCount(0)
 {
     memset(&m_header, 0, sizeof(m_header));
+    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
+    if (DEBUG) ALOGI("BackupDataReader(%d) @ %ld", fd, (long)m_pos);
 }
 
 BackupDataReader::~BackupDataReader()
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
index 977ba80..9e9649c 100644
--- a/libs/androidfw/tests/Android.mk
+++ b/libs/androidfw/tests/Android.mk
@@ -4,6 +4,7 @@
 
 # Build the unit tests.
 test_src_files := \
+    BackupData_test.cpp \
     ObbFile_test.cpp \
     ZipUtils_test.cpp \
     ResourceTypes_test.cpp
diff --git a/libs/androidfw/tests/BackupData_test.cpp b/libs/androidfw/tests/BackupData_test.cpp
new file mode 100644
index 0000000..17f91ca
--- /dev/null
+++ b/libs/androidfw/tests/BackupData_test.cpp
@@ -0,0 +1,438 @@
+/*
+ * 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 "ObbFile_test"
+#include <androidfw/BackupHelpers.h>
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+namespace android {
+
+#define TEST_FILENAME "/test.bd"
+
+// keys of different lengths to test padding
+#define KEY1 "key1"
+#define KEY2 "key2a"
+#define KEY3 "key3bc"
+#define KEY4 "key4def"
+
+// payloads of different lengths to test padding
+#define DATA1 "abcdefg"
+#define DATA2 "hijklmnopq"
+#define DATA3 "rstuvwxyz"
+// KEY4 is only ever deleted
+
+class BackupDataTest : public testing::Test {
+protected:
+    char* m_external_storage;
+    char* m_filename;
+    String8 mKey1;
+    String8 mKey2;
+    String8 mKey3;
+    String8 mKey4;
+
+    virtual void SetUp() {
+        m_external_storage = getenv("EXTERNAL_STORAGE");
+
+        const int totalLen = strlen(m_external_storage) + strlen(TEST_FILENAME) + 1;
+        m_filename = new char[totalLen];
+        snprintf(m_filename, totalLen, "%s%s", m_external_storage, TEST_FILENAME);
+
+        ::unlink(m_filename);
+        int fd = ::open(m_filename, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+        if (fd < 0) {
+            FAIL() << "Couldn't create " << m_filename << " for writing";
+        }
+        mKey1 = String8(KEY1);
+        mKey2 = String8(KEY2);
+        mKey3 = String8(KEY3);
+        mKey4 = String8(KEY4);
+   }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(BackupDataTest, WriteAndReadSingle) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+
+  EXPECT_EQ(NO_ERROR, writer->WriteEntityHeader(mKey1, sizeof(DATA1)))
+          << "WriteEntityHeader returned an error";
+  EXPECT_EQ(NO_ERROR, writer->WriteEntityData(DATA1, sizeof(DATA1)))
+          << "WriteEntityData returned an error";
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+  EXPECT_EQ(NO_ERROR, reader->Status())
+          << "Reader ctor failed";
+
+  bool done;
+  int type;
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader";
+
+  String8 key;
+  size_t dataSize;
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error";
+  EXPECT_EQ(mKey1, key)
+          << "wrong key from ReadEntityHeader";
+  EXPECT_EQ(sizeof(DATA1), dataSize)
+          << "wrong size from ReadEntityHeader";
+
+  char* dataBytes = new char[dataSize];
+  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error";
+  for (unsigned int i = 0; i < sizeof(DATA1); i++) {
+    EXPECT_EQ(DATA1[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, WriteAndReadMultiple) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, sizeof(DATA2));
+  writer->WriteEntityData(DATA2, sizeof(DATA2));
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // read and verify second entity
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(sizeof(DATA2), dataSize)
+          << "wrong size from ReadEntityHeader on second entity";
+
+  dataBytes = new char[dataSize];
+  EXPECT_EQ((int)dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error on second entity";
+  for (unsigned int i = 0; i < sizeof(DATA2); i++) {
+    EXPECT_EQ(DATA2[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, SkipEntity) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, sizeof(DATA2));
+  writer->WriteEntityData(DATA2, sizeof(DATA2));
+  writer->WriteEntityHeader(mKey3, sizeof(DATA3));
+  writer->WriteEntityData(DATA3, sizeof(DATA3));
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // skip second entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  reader->SkipEntityData();
+
+  // read and verify third entity
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader after skip";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on third entity";
+  EXPECT_EQ(mKey3, key)
+          << "wrong key from ReadEntityHeader on third entity";
+  EXPECT_EQ(sizeof(DATA3), dataSize)
+          << "wrong size from ReadEntityHeader on third entity";
+
+  dataBytes = new char[dataSize];
+  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error on third entity";
+  for (unsigned int i = 0; i < sizeof(DATA3); i++) {
+    EXPECT_EQ(DATA3[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, DeleteEntity) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, -1);
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // read and verify deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader on deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on second entity";
+
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, EneityAfterDelete) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, sizeof(DATA1));
+  writer->WriteEntityData(DATA1, sizeof(DATA1));
+  writer->WriteEntityHeader(mKey2, -1);
+  writer->WriteEntityHeader(mKey3, sizeof(DATA3));
+  writer->WriteEntityData(DATA3, sizeof(DATA3));
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  char* dataBytes;
+  // read first entity
+  reader->ReadNextHeader(&done, &type);
+  reader->ReadEntityHeader(&key, &dataSize);
+  dataBytes = new char[dataSize];
+  reader->ReadEntityData(dataBytes, dataSize);
+  delete dataBytes;
+
+  // read and verify deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader on deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int)dataSize)
+          << "not recognizing deletion on second entity";
+
+  // read and verify third entity
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader after deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on third entity";
+  EXPECT_EQ(mKey3, key)
+          << "wrong key from ReadEntityHeader on third entity";
+  EXPECT_EQ(sizeof(DATA3), dataSize)
+          << "wrong size from ReadEntityHeader on third entity";
+
+  dataBytes = new char[dataSize];
+  EXPECT_EQ((int) dataSize, reader->ReadEntityData(dataBytes, dataSize))
+          << "ReadEntityData returned an error on third entity";
+  for (unsigned int i = 0; i < sizeof(DATA3); i++) {
+    EXPECT_EQ(DATA3[i], dataBytes[i])
+             << "data character " << i << " should be equal";
+  }
+  delete dataBytes;
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, OnlyDeleteEntities) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, -1);
+  writer->WriteEntityHeader(mKey2, -1);
+  writer->WriteEntityHeader(mKey3, -1);
+  writer->WriteEntityHeader(mKey4, -1);
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  // read and verify first deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader first deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on first entity";
+  EXPECT_EQ(mKey1, key)
+          << "wrong key from ReadEntityHeader on first entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on first entity";
+
+  // read and verify second deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader second deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on second entity";
+
+  // read and verify third deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader third deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on third entity";
+  EXPECT_EQ(mKey3, key)
+          << "wrong key from ReadEntityHeader on third entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on third entity";
+
+  // read and verify fourth deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader fourth deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on fourth entity";
+  EXPECT_EQ(mKey4, key)
+          << "wrong key from ReadEntityHeader on fourth entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on fourth entity";
+
+  delete writer;
+  delete reader;
+}
+
+TEST_F(BackupDataTest, ReadDeletedEntityData) {
+  int fd = ::open(m_filename, O_WRONLY);
+  BackupDataWriter* writer = new BackupDataWriter(fd);
+  writer->WriteEntityHeader(mKey1, -1);
+  writer->WriteEntityHeader(mKey2, -1);
+
+  ::close(fd);
+  fd = ::open(m_filename, O_RDONLY);
+  BackupDataReader* reader = new BackupDataReader(fd);
+
+  bool done;
+  int type;
+  String8 key;
+  size_t dataSize;
+  // read and verify first deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader first deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on first entity";
+  EXPECT_EQ(mKey1, key)
+          << "wrong key from ReadEntityHeader on first entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on first entity";
+
+  // erroneously try to read first entity data
+  char* dataBytes = new char[10];
+  dataBytes[0] = 'A';
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityData(dataBytes, dataSize));
+  // expect dataBytes to be unmodofied
+  EXPECT_EQ('A', dataBytes[0]);
+
+  // read and verify second deletion
+  reader->ReadNextHeader(&done, &type);
+  EXPECT_EQ(BACKUP_HEADER_ENTITY_V1, type)
+          << "wrong type from ReadNextHeader second deletion";
+
+  EXPECT_EQ(NO_ERROR, reader->ReadEntityHeader(&key, &dataSize))
+          << "ReadEntityHeader returned an error on second entity";
+  EXPECT_EQ(mKey2, key)
+          << "wrong key from ReadEntityHeader on second entity";
+  EXPECT_EQ(-1, (int) dataSize)
+          << "not recognizing deletion on second entity";
+
+  delete writer;
+  delete reader;
+}
+
+}
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
new file mode 100644
index 0000000..c0b5402
--- /dev/null
+++ b/libs/hwui/AmbientShadow.cpp
@@ -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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <math.h>
+#include <utils/Log.h>
+#include <utils/Vector.h>
+
+#include "AmbientShadow.h"
+#include "ShadowTessellator.h"
+#include "Vertex.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Calculate the shadows as a triangle strips while alpha value as the
+ * shadow values.
+ *
+ * @param isCasterOpaque Whether the caster is opaque.
+ * @param vertices The shadow caster's polygon, which is represented in a Vector3
+ *                  array.
+ * @param vertexCount The length of caster's polygon in terms of number of
+ *                    vertices.
+ * @param centroid3d The centroid of the shadow caster.
+ * @param heightFactor The factor showing the higher the object, the lighter the
+ *                     shadow.
+ * @param geomFactor The factor scaling the geometry expansion along the normal.
+ *
+ * @param shadowVertexBuffer Return an floating point array of (x, y, a)
+ *               triangle strips mode.
+ */
+VertexBufferMode AmbientShadow::createAmbientShadow(bool isCasterOpaque,
+        const Vector3* vertices, int vertexCount, const Vector3& centroid3d,
+        float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) {
+    const int rays = SHADOW_RAY_COUNT;
+    VertexBufferMode mode = kVertexBufferMode_OnePolyRingShadow;
+    // Validate the inputs.
+    if (vertexCount < 3 || heightFactor <= 0 || rays <= 0
+        || geomFactor <= 0) {
+#if DEBUG_SHADOW
+        ALOGW("Invalid input for createAmbientShadow(), early return!");
+#endif
+        return mode; // vertex buffer is empty, so any mode doesn't matter.
+    }
+
+    Vector<Vector2> dir; // TODO: use C++11 unique_ptr
+    dir.setCapacity(rays);
+    float rayDist[rays];
+    float rayHeight[rays];
+    calculateRayDirections(rays, dir.editArray());
+
+    // Calculate the length and height of the points along the edge.
+    //
+    // The math here is:
+    // Intersect each ray (starting from the centroid) with the polygon.
+    for (int i = 0; i < rays; i++) {
+        int edgeIndex;
+        float edgeFraction;
+        float rayDistance;
+        calculateIntersection(vertices, vertexCount, centroid3d, dir[i], edgeIndex,
+                edgeFraction, rayDistance);
+        rayDist[i] = rayDistance;
+        if (edgeIndex < 0 || edgeIndex >= vertexCount) {
+#if DEBUG_SHADOW
+            ALOGW("Invalid edgeIndex!");
+#endif
+            edgeIndex = 0;
+        }
+        float h1 = vertices[edgeIndex].z;
+        float h2 = vertices[((edgeIndex + 1) % vertexCount)].z;
+        rayHeight[i] = h1 + edgeFraction * (h2 - h1);
+    }
+
+    // The output buffer length basically is roughly rays * layers, but since we
+    // need triangle strips, so we need to duplicate vertices to accomplish that.
+    AlphaVertex* shadowVertices =
+            shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
+
+    // Calculate the vertex of the shadows.
+    //
+    // The math here is:
+    // Along the edges of the polygon, for each intersection point P (generated above),
+    // calculate the normal N, which should be perpendicular to the edge of the
+    // polygon (represented by the neighbor intersection points) .
+    // Shadow's vertices will be generated as : P + N * scale.
+    const Vector2 centroid2d = Vector2(centroid3d.x, centroid3d.y);
+    for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+        Vector2 normal(1.0f, 0.0f);
+        calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);
+
+        // The vertex should be start from rayDist[i] then scale the
+        // normalizeNormal!
+        Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
+                centroid2d;
+
+        // outer ring of points, expanded based upon height of each ray intersection
+        float expansionDist = rayHeight[rayIndex] * heightFactor *
+                geomFactor;
+        AlphaVertex::set(&shadowVertices[rayIndex],
+                intersection.x + normal.x * expansionDist,
+                intersection.y + normal.y * expansionDist,
+                0.0f);
+
+        // inner ring of points
+        float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor);
+        AlphaVertex::set(&shadowVertices[rays + rayIndex],
+                intersection.x,
+                intersection.y,
+                opacity);
+    }
+
+    // If caster isn't opaque, we need to to fill the umbra by storing the umbra's
+    // centroid in the innermost ring of vertices.
+    if (!isCasterOpaque) {
+        mode = kVertexBufferMode_TwoPolyRingShadow;
+        float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor);
+        AlphaVertex centroidXYA;
+        AlphaVertex::set(&centroidXYA, centroid2d.x, centroid2d.y, centroidAlpha);
+        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+            shadowVertices[2 * rays + rayIndex] = centroidXYA;
+        }
+    }
+
+#if DEBUG_SHADOW
+    for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) {
+        ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
+                shadowVertices[i].y, shadowVertices[i].alpha);
+    }
+#endif
+    return mode;
+}
+
+/**
+ * Generate an array of rays' direction vectors.
+ *
+ * @param rays The number of rays shooting out from the centroid.
+ * @param dir Return the array of ray vectors.
+ */
+void AmbientShadow::calculateRayDirections(int rays, Vector2* dir) {
+    float deltaAngle = 2 * M_PI / rays;
+
+    for (int i = 0; i < rays; i++) {
+        dir[i].x = sinf(deltaAngle * i);
+        dir[i].y = cosf(deltaAngle * i);
+    }
+}
+
+/**
+ * Calculate the intersection of a ray hitting the polygon.
+ *
+ * @param vertices The shadow caster's polygon, which is represented in a
+ *                 Vector3 array.
+ * @param vertexCount The length of caster's polygon in terms of number of vertices.
+ * @param start The starting point of the ray.
+ * @param dir The direction vector of the ray.
+ *
+ * @param outEdgeIndex Return the index of the segment (or index of the starting
+ *                     vertex) that ray intersect with.
+ * @param outEdgeFraction Return the fraction offset from the segment starting
+ *                        index.
+ * @param outRayDist Return the ray distance from centroid to the intersection.
+ */
+void AmbientShadow::calculateIntersection(const Vector3* vertices, int vertexCount,
+        const Vector3& start, const Vector2& dir, int& outEdgeIndex,
+        float& outEdgeFraction, float& outRayDist) {
+    float startX = start.x;
+    float startY = start.y;
+    float dirX = dir.x;
+    float dirY = dir.y;
+    // Start the search from the last edge from poly[len-1] to poly[0].
+    int p1 = vertexCount - 1;
+
+    for (int p2 = 0; p2 < vertexCount; p2++) {
+        float p1x = vertices[p1].x;
+        float p1y = vertices[p1].y;
+        float p2x = vertices[p2].x;
+        float p2y = vertices[p2].y;
+
+        // The math here is derived from:
+        // f(t, v) = p1x * (1 - t) + p2x * t - (startX + dirX * v) = 0;
+        // g(t, v) = p1y * (1 - t) + p2y * t - (startY + dirY * v) = 0;
+        float div = (dirX * (p1y - p2y) + dirY * p2x - dirY * p1x);
+        if (div != 0) {
+            float t = (dirX * (p1y - startY) + dirY * startX - dirY * p1x) / (div);
+            if (t > 0 && t <= 1) {
+                float t2 = (p1x * (startY - p2y)
+                            + p2x * (p1y - startY)
+                            + startX * (p2y - p1y)) / div;
+                if (t2 > 0) {
+                    outEdgeIndex = p1;
+                    outRayDist = t2;
+                    outEdgeFraction = t;
+                    return;
+                }
+            }
+        }
+        p1 = p2;
+    }
+    return;
+};
+
+/**
+ * Calculate the normal at the intersection point between a ray and the polygon.
+ *
+ * @param rays The total number of rays.
+ * @param currentRayIndex The index of the ray which the normal is based on.
+ * @param dir The array of the all the rays directions.
+ * @param rayDist The pre-computed ray distances array.
+ *
+ * @param normal Return the normal.
+ */
+void AmbientShadow::calculateNormal(int rays, int currentRayIndex,
+        const Vector2* dir, const float* rayDist, Vector2& normal) {
+    int preIndex = (currentRayIndex - 1 + rays) % rays;
+    int postIndex = (currentRayIndex + 1) % rays;
+    Vector2 p1 = dir[preIndex] * rayDist[preIndex];
+    Vector2 p2 = dir[postIndex] * rayDist[postIndex];
+
+    // Now the V (deltaX, deltaY) is the vector going CW around the poly.
+    Vector2 delta = p2 - p1;
+    if (delta.length() != 0) {
+        delta.normalize();
+        // Calculate the normal , which is CCW 90 rotate to the V.
+        // 90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z)
+        normal.x = -delta.y;
+        normal.y = delta.x;
+    }
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h
new file mode 100644
index 0000000..45b8bef
--- /dev/null
+++ b/libs/hwui/AmbientShadow.h
@@ -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.
+ */
+
+#ifndef ANDROID_HWUI_AMBIENT_SHADOW_H
+#define ANDROID_HWUI_AMBIENT_SHADOW_H
+
+#include "Debug.h"
+#include "OpenGLRenderer.h"
+#include "Vector.h"
+#include "VertexBuffer.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * AmbientShadow is used to calculate the ambient shadow value around a polygon.
+ *
+ * TODO: calculateIntersection() now is O(N*M), where N is the number of
+ * polygon's vertics and M is the number of rays. In fact, by staring tracing
+ * the vertex from the previous intersection, the algorithm can be O(N + M);
+ */
+class AmbientShadow {
+public:
+    static VertexBufferMode createAmbientShadow(bool isCasterOpaque, const Vector3* poly,
+            int polyLength, const Vector3& centroid3d, float heightFactor,
+            float geomFactor, VertexBuffer& shadowVertexBuffer);
+
+private:
+    static void calculateRayDirections(int rays, Vector2* dir);
+
+    static void calculateIntersection(const Vector3* poly, int nbVertices,
+            const Vector3& start, const Vector2& dir, int& outEdgeIndex,
+            float& outEdgeFraction, float& outRayDist);
+
+    static void calculateNormal(int rays, int currentRayIndex, const Vector2* dir,
+            const float* rayDist, Vector2& normal);
+}; // AmbientShadow
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_AMBIENT_SHADOW_H
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 411c133..4de755d 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -4,18 +4,20 @@
 # Only build libhwui when USE_OPENGL_RENDERER is
 # defined in the current device/board configuration
 ifeq ($(USE_OPENGL_RENDERER),true)
-	LOCAL_SRC_FILES:= \
+	LOCAL_SRC_FILES := \
 		utils/Blur.cpp \
 		utils/SortedListImpl.cpp \
 		thread/TaskManager.cpp \
 		font/CacheTexture.cpp \
 		font/Font.cpp \
+		AmbientShadow.cpp \
 		AssetAtlas.cpp \
 		FontRenderer.cpp \
 		GammaFontRenderer.cpp \
 		Caches.cpp \
 		DisplayList.cpp \
 		DeferredDisplayList.cpp \
+		DeferredLayerUpdater.cpp \
 		DisplayListLogBuffer.cpp \
 		DisplayListRenderer.cpp \
 		Dither.cpp \
@@ -36,30 +38,37 @@
 		Program.cpp \
 		ProgramCache.cpp \
 		RenderBufferCache.cpp \
+		RenderNode.cpp \
+		RenderProperties.cpp \
 		ResourceCache.cpp \
-		SkiaColorFilter.cpp \
+		ShadowTessellator.cpp \
 		SkiaShader.cpp \
 		Snapshot.cpp \
+		SpotShadow.cpp \
+		StatefulBaseRenderer.cpp \
 		Stencil.cpp \
 		Texture.cpp \
 		TextureCache.cpp \
 		TextDropShadowCache.cpp
 
+	# RenderThread stuff
+	LOCAL_SRC_FILES += \
+		renderthread/CanvasContext.cpp \
+		renderthread/RenderProxy.cpp \
+		renderthread/RenderTask.cpp \
+		renderthread/RenderThread.cpp
+
 	intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,)
 
 	LOCAL_C_INCLUDES += \
 		$(JNI_H_INCLUDE) \
 		$(LOCAL_PATH)/../../include/utils \
-		external/skia/include/core \
-		external/skia/include/effects \
-		external/skia/include/images \
-		external/skia/src/core \
-		external/skia/src/ports \
-		external/skia/include/utils
+		external/skia/src/core
 
 	LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES
+	LOCAL_CFLAGS += -Wno-unused-parameter
 	LOCAL_MODULE_CLASS := SHARED_LIBRARIES
-	LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libEGL libGLESv2 libskia libui
+	LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libEGL libGLESv2 libskia libui libgui
 	LOCAL_MODULE := libhwui
 	LOCAL_MODULE_TAGS := optional
 
diff --git a/libs/hwui/AssetAtlas.cpp b/libs/hwui/AssetAtlas.cpp
index e8c3d3c..fc86e4f 100644
--- a/libs/hwui/AssetAtlas.cpp
+++ b/libs/hwui/AssetAtlas.cpp
@@ -74,12 +74,12 @@
 // Entries
 ///////////////////////////////////////////////////////////////////////////////
 
-AssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const {
+AssetAtlas::Entry* AssetAtlas::getEntry(const SkBitmap* bitmap) const {
     ssize_t index = mEntries.indexOfKey(bitmap);
     return index >= 0 ? mEntries.valueAt(index) : NULL;
 }
 
-Texture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const {
+Texture* AssetAtlas::getEntryTexture(const SkBitmap* bitmap) const {
     ssize_t index = mEntries.indexOfKey(bitmap);
     return index >= 0 ? mEntries.valueAt(index)->texture : NULL;
 }
diff --git a/libs/hwui/AssetAtlas.h b/libs/hwui/AssetAtlas.h
index 163bdbc..2ec556e 100644
--- a/libs/hwui/AssetAtlas.h
+++ b/libs/hwui/AssetAtlas.h
@@ -160,13 +160,13 @@
      * 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;
+    Entry* getEntry(const SkBitmap* 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;
+    Texture* getEntryTexture(const SkBitmap* bitmap) const;
 
     /**
      * Returns the current generation id of the atlas.
@@ -186,7 +186,7 @@
     const bool mBlendKey;
     const bool mOpaqueKey;
 
-    KeyedVector<SkBitmap*, Entry*> mEntries;
+    KeyedVector<const SkBitmap*, Entry*> mEntries;
 }; // class AssetAtlas
 
 }; // namespace uirenderer
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f8d3589..477d691 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -23,6 +23,7 @@
 #include "DisplayListRenderer.h"
 #include "Properties.h"
 #include "LayerRenderer.h"
+#include "ShadowTessellator.h"
 
 namespace android {
 
@@ -55,6 +56,7 @@
     initProperties();
     initStaticProperties();
     initExtensions();
+    initTempProperties();
 
     mDebugLevel = readDebugLevel();
     ALOGD("Enabling debug mode %d", mDebugLevel);
@@ -85,7 +87,7 @@
 
     mRegionMesh = NULL;
     mMeshIndices = 0;
-
+    mShadowStripsIndices = 0;
     blend = false;
     lastSrcMode = GL_ZERO;
     lastDstMode = GL_ZERO;
@@ -222,6 +224,9 @@
     mMeshIndices = 0;
     mRegionMesh = NULL;
 
+    glDeleteBuffers(1, &mShadowStripsIndices);
+    mShadowStripsIndices = 0;
+
     fboCache.clear();
 
     programCache.clear();
@@ -310,7 +315,7 @@
     pathCache.clearGarbage();
     patchCache.clearGarbage();
 
-    Vector<DisplayList*> displayLists;
+    Vector<RenderNode*> displayLists;
     Vector<Layer*> layers;
 
     { // scope for the lock
@@ -323,7 +328,7 @@
 
     size_t count = displayLists.size();
     for (size_t i = 0; i < count; i++) {
-        DisplayList* displayList = displayLists.itemAt(i);
+        RenderNode* displayList = displayLists.itemAt(i);
         delete displayList;
     }
 
@@ -340,7 +345,7 @@
     mLayerGarbage.push(layer);
 }
 
-void Caches::deleteDisplayListDeferred(DisplayList* displayList) {
+void Caches::deleteDisplayListDeferred(RenderNode* displayList) {
     Mutex::Autolock _l(mGarbageLock);
     mDisplayListGarbage.push(displayList);
 }
@@ -403,7 +408,7 @@
     return false;
 }
 
-bool Caches::bindIndicesBuffer(const GLuint buffer) {
+bool Caches::bindIndicesBufferInternal(const GLuint buffer) {
     if (mCurrentIndicesBuffer != buffer) {
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
         mCurrentIndicesBuffer = buffer;
@@ -412,7 +417,7 @@
     return false;
 }
 
-bool Caches::bindIndicesBuffer() {
+bool Caches::bindQuadIndicesBuffer() {
     if (!mMeshIndices) {
         uint16_t* regionIndices = new uint16_t[gMaxNumberOfQuads * 6];
         for (uint32_t i = 0; i < gMaxNumberOfQuads; i++) {
@@ -427,7 +432,7 @@
         }
 
         glGenBuffers(1, &mMeshIndices);
-        bool force = bindIndicesBuffer(mMeshIndices);
+        bool force = bindIndicesBufferInternal(mMeshIndices);
         glBufferData(GL_ELEMENT_ARRAY_BUFFER, gMaxNumberOfQuads * 6 * sizeof(uint16_t),
                 regionIndices, GL_STATIC_DRAW);
 
@@ -435,7 +440,23 @@
         return force;
     }
 
-    return bindIndicesBuffer(mMeshIndices);
+    return bindIndicesBufferInternal(mMeshIndices);
+}
+
+bool Caches::bindShadowIndicesBuffer() {
+    if (!mShadowStripsIndices) {
+        uint16_t* shadowIndices = new uint16_t[MAX_SHADOW_INDEX_COUNT];
+        ShadowTessellator::generateShadowIndices(shadowIndices);
+        glGenBuffers(1, &mShadowStripsIndices);
+        bool force = bindIndicesBufferInternal(mShadowStripsIndices);
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t),
+            shadowIndices, GL_STATIC_DRAW);
+
+        delete[] shadowIndices;
+        return force;
+    }
+
+    return bindIndicesBufferInternal(mShadowStripsIndices);
 }
 
 bool Caches::unbindIndicesBuffer() {
@@ -473,7 +494,7 @@
 // Meshes and textures
 ///////////////////////////////////////////////////////////////////////////////
 
-void Caches::bindPositionVertexPointer(bool force, GLvoid* vertices, GLsizei stride) {
+void Caches::bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
     if (force || vertices != mCurrentPositionPointer || stride != mCurrentPositionStride) {
         GLuint slot = currentProgram->position;
         glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
@@ -482,7 +503,7 @@
     }
 }
 
-void Caches::bindTexCoordsVertexPointer(bool force, GLvoid* vertices, GLsizei stride) {
+void Caches::bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride) {
     if (force || vertices != mCurrentTexCoordsPointer || stride != mCurrentTexCoordsStride) {
         GLuint slot = currentProgram->texCoords;
         glVertexAttribPointer(slot, 2, GL_FLOAT, GL_FALSE, stride, vertices);
@@ -676,5 +697,44 @@
     return mRegionMesh;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+// Temporary Properties
+///////////////////////////////////////////////////////////////////////////////
+
+void Caches::initTempProperties() {
+    propertyAmbientShadowStrength = 25;
+    propertySpotShadowStrength = 25;
+
+    propertyLightPosXScale = 0.5f;
+    propertyLightPosYScale = 0.0f;
+    propertyLightPosZScale = 1.0f;
+}
+
+void Caches::setTempProperty(const char* name, const char* value) {
+    ALOGD("setting property %s to %s", name, value);
+    if (!strcmp(name, "ambientShadowStrength")) {
+        propertyAmbientShadowStrength = atoi(value);
+        ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength);
+        return;
+    } else if (!strcmp(name, "spotShadowStrength")) {
+        propertySpotShadowStrength = atoi(value);
+        ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength);
+        return;
+    } else if (!strcmp(name, "lightPosXScale")) {
+        propertyLightPosXScale = fmin(fmax(atof(value), 0.0), 1.0);
+        ALOGD("lightPos X Scale = %.2f", propertyLightPosXScale);
+        return;
+    }  else if (!strcmp(name, "lightPosYScale")) {
+        propertyLightPosYScale = fmin(fmax(atof(value), 0.0), 1.0);
+        ALOGD("lightPos Y Scale = %.2f", propertyLightPosXScale);
+        return;
+    }  else if (!strcmp(name, "lightPosZScale")) {
+        propertyLightPosZScale = fmin(fmax(atof(value), 0.0), 1.0);
+        ALOGD("lightPos Z Scale = %.2f", propertyLightPosXScale);
+        return;
+    }
+    ALOGD("    failed");
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 282aee9..50c5fef 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -62,7 +62,7 @@
 static const uint32_t gMaxNumberOfQuads = 2048;
 
 // Generates simple and textured vertices
-#define FV(x, y, u, v) { { x, y }, { u, v } }
+#define FV(x, y, u, v) { x, y, u, v }
 
 // This array is never used directly but used as a memcpy source in the
 // OpenGLRenderer constructor
@@ -102,7 +102,7 @@
 // Caches
 ///////////////////////////////////////////////////////////////////////////////
 
-class DisplayList;
+class RenderNode;
 
 class ANDROID_API Caches: public Singleton<Caches> {
     Caches();
@@ -169,7 +169,7 @@
     /*
      * Can be used to delete a display list from a non EGL thread.
      */
-    void deleteDisplayListDeferred(DisplayList* layer);
+    void deleteDisplayListDeferred(RenderNode* layer);
 
     /**
      * Binds the VBO used to render simple textured quads.
@@ -190,8 +190,8 @@
      * Binds a global indices buffer that can draw up to
      * gMaxNumberOfQuads quads.
      */
-    bool bindIndicesBuffer();
-    bool bindIndicesBuffer(const GLuint buffer);
+    bool bindQuadIndicesBuffer();
+    bool bindShadowIndicesBuffer();
     bool unbindIndicesBuffer();
 
     /**
@@ -208,13 +208,13 @@
      * Binds an attrib to the specified float vertex pointer.
      * Assumes a stride of gMeshStride and a size of 2.
      */
-    void bindPositionVertexPointer(bool force, GLvoid* vertices, GLsizei stride = gMeshStride);
+    void bindPositionVertexPointer(bool force, const GLvoid* vertices, GLsizei stride = gMeshStride);
 
     /**
      * Binds an attrib to the specified float vertex pointer.
      * Assumes a stride of gMeshStride and a size of 2.
      */
-    void bindTexCoordsVertexPointer(bool force, GLvoid* vertices, GLsizei stride = gMeshStride);
+    void bindTexCoordsVertexPointer(bool force, const GLvoid* vertices, GLsizei stride = gMeshStride);
 
     /**
      * Resets the vertex pointers.
@@ -353,6 +353,20 @@
     PFNGLLABELOBJECTEXTPROC setLabel;
     PFNGLGETOBJECTLABELEXTPROC getLabel;
 
+    // TEMPORARY properties
+    void initTempProperties();
+    void setTempProperty(const char* name, const char* value);
+
+    // These scaling factors range from 0 to 1, to scale the light position
+    // within the bound of (screenwidth, screenheight, max(screenwidth, screenheight));
+    // The default scale is (0.5, 0, 1) which put the light at
+    // (screenwidth / 2, 0, max(screenwidth, screenheight)).
+    float propertyLightPosXScale;
+    float propertyLightPosYScale;
+    float propertyLightPosZScale;
+    int propertyAmbientShadowStrength;
+    int propertySpotShadowStrength;
+
 private:
     enum OverdrawColorSet {
         kColorSet_Default = 0,
@@ -364,6 +378,8 @@
     void initConstraints();
     void initStaticProperties();
 
+    bool bindIndicesBufferInternal(const GLuint buffer);
+
     static void eventMarkNull(GLsizei length, const GLchar* marker) { }
     static void startMarkNull(GLsizei length, const GLchar* marker) { }
     static void endMarkNull() { }
@@ -379,9 +395,9 @@
     GLuint mCurrentBuffer;
     GLuint mCurrentIndicesBuffer;
     GLuint mCurrentPixelBuffer;
-    void* mCurrentPositionPointer;
+    const void* mCurrentPositionPointer;
     GLsizei mCurrentPositionStride;
-    void* mCurrentTexCoordsPointer;
+    const void* mCurrentTexCoordsPointer;
     GLsizei mCurrentTexCoordsStride;
 
     bool mTexCoordsArrayEnabled;
@@ -400,10 +416,11 @@
 
     // Global index buffer
     GLuint mMeshIndices;
+    GLuint mShadowStripsIndices;
 
     mutable Mutex mGarbageLock;
     Vector<Layer*> mLayerGarbage;
-    Vector<DisplayList*> mDisplayListGarbage;
+    Vector<RenderNode*> mDisplayListGarbage;
 
     DebugLevel mDebugLevel;
     bool mInitialized;
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 786f12a..d6dc6ad 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -85,6 +85,9 @@
 // Turn on to highlight drawing batches and merged batches with different colors
 #define DEBUG_MERGE_BEHAVIOR 0
 
+// Turn on to enable debugging shadow
+#define DEBUG_SHADOW 0
+
 #if DEBUG_INIT
     #define INIT_LOGD(...) ALOGD(__VA_ARGS__)
 #else
diff --git a/libs/hwui/DeferredDisplayList.cpp b/libs/hwui/DeferredDisplayList.cpp
index 7eb7028..3d58964 100644
--- a/libs/hwui/DeferredDisplayList.cpp
+++ b/libs/hwui/DeferredDisplayList.cpp
@@ -224,6 +224,11 @@
 
         if (op->getPaintAlpha() != mOps[0].op->getPaintAlpha()) return false;
 
+        if (op->mPaint && mOps[0].op->mPaint &&
+            op->mPaint->getColorFilter() != mOps[0].op->mPaint->getColorFilter()) {
+            return false;
+        }
+
         /* Draw Modifiers compatibility check
          *
          * Shadows are ignored, as only text uses them, and in that case they are drawn
@@ -239,7 +244,6 @@
         const DrawModifiers& lhsMod = lhs->mDrawModifiers;
         const DrawModifiers& rhsMod = rhs->mDrawModifiers;
         if (lhsMod.mShader != rhsMod.mShader) return false;
-        if (lhsMod.mColorFilter != rhsMod.mColorFilter) return false;
 
         // Draw filter testing expects bit fields to be clear if filter not set.
         if (lhsMod.mHasDrawFilter != rhsMod.mHasDrawFilter) return false;
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 3dcbd0b..fca3588 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -79,13 +79,13 @@
 };
 
 class DeferredDisplayList {
+    friend class DeferStateStruct; // used to give access to allocator
 public:
     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
@@ -120,6 +120,8 @@
     void addDrawOp(OpenGLRenderer& renderer, DrawOp* op);
 
 private:
+    DeferredDisplayList(const DeferredDisplayList& other); // disallow copy
+
     DeferredDisplayState* createState() {
         return new (mAllocator) DeferredDisplayState();
     }
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
new file mode 100644
index 0000000..7a83967
--- /dev/null
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "DeferredLayerUpdater.h"
+
+#include "OpenGLRenderer.h"
+
+#include "LayerRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer)
+        : mDisplayList(0)
+        , mSurfaceTexture(0)
+        , mTransform(0)
+        , mNeedsGLContextAttach(false)
+        , mUpdateTexImage(false)
+        , mLayer(layer)
+        , mRenderer(renderer)
+        , mCaches(Caches::getInstance()) {
+    mWidth = mLayer->layer.getWidth();
+    mHeight = mLayer->layer.getHeight();
+    mBlend = mLayer->isBlend();
+    mColorFilter = SkSafeRef(mLayer->getColorFilter());
+    mAlpha = mLayer->getAlpha();
+    mMode = mLayer->getMode();
+    mDirtyRect.setEmpty();
+}
+
+DeferredLayerUpdater::~DeferredLayerUpdater() {
+    SkSafeUnref(mColorFilter);
+    if (mLayer) {
+        mCaches.resourceCache.decrementRefcount(mLayer);
+    }
+    delete mRenderer;
+}
+
+void DeferredLayerUpdater::setPaint(const SkPaint* paint) {
+    OpenGLRenderer::getAlphaAndModeDirect(paint, &mAlpha, &mMode);
+    SkColorFilter* colorFilter = (paint) ? paint->getColorFilter() : NULL;
+    SkRefCnt_SafeAssign(mColorFilter, colorFilter);
+}
+
+void DeferredLayerUpdater::setDisplayList(RenderNode* displayList,
+        int left, int top, int right, int bottom) {
+    mDisplayList = displayList;
+    if (mDirtyRect.isEmpty()) {
+        mDirtyRect.set(left, top, right, bottom);
+    } else {
+        mDirtyRect.unionWith(Rect(left, top, right, bottom));
+    }
+}
+
+bool DeferredLayerUpdater::apply() {
+    bool success = true;
+    // These properties are applied the same to both layer types
+    mLayer->setColorFilter(mColorFilter);
+    mLayer->setAlpha(mAlpha, mMode);
+
+    if (mDisplayList) {
+        if (mWidth != mLayer->layer.getWidth() || mHeight != mLayer->layer.getHeight()) {
+            success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
+        }
+        mLayer->setBlend(mBlend);
+        mLayer->updateDeferred(mRenderer, mDisplayList,
+                mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
+        mDirtyRect.setEmpty();
+        mDisplayList = 0;
+    } else if (mSurfaceTexture.get()) {
+        if (mNeedsGLContextAttach) {
+            mNeedsGLContextAttach = false;
+            mSurfaceTexture->attachToContext(mLayer->getTexture());
+        }
+        if (mUpdateTexImage) {
+            mUpdateTexImage = false;
+            doUpdateTexImage();
+        }
+        if (mTransform) {
+            mLayer->getTransform().load(*mTransform);
+            setTransform(0);
+        }
+    }
+    return success;
+}
+
+void DeferredLayerUpdater::doUpdateTexImage() {
+    if (mSurfaceTexture->updateTexImage() == NO_ERROR) {
+        float transform[16];
+
+        int64_t frameNumber = mSurfaceTexture->getFrameNumber();
+        // If the GLConsumer queue is in synchronous mode, need to discard all
+        // but latest frame, using the frame number to tell when we no longer
+        // have newer frames to target. Since we can't tell which mode it is in,
+        // do this unconditionally.
+        int dropCounter = 0;
+        while (mSurfaceTexture->updateTexImage() == NO_ERROR) {
+            int64_t newFrameNumber = mSurfaceTexture->getFrameNumber();
+            if (newFrameNumber == frameNumber) break;
+            frameNumber = newFrameNumber;
+            dropCounter++;
+        }
+
+        bool forceFilter = false;
+        sp<GraphicBuffer> buffer = mSurfaceTexture->getCurrentBuffer();
+        if (buffer != NULL) {
+            // force filtration if buffer size != layer size
+            forceFilter = mWidth != buffer->getWidth()
+                    || mHeight != buffer->getHeight();
+        }
+
+        #if DEBUG_RENDERER
+        if (dropCounter > 0) {
+            RENDERER_LOGD("Dropped %d frames on texture layer update", dropCounter);
+        }
+        #endif
+        mSurfaceTexture->getTransformMatrix(transform);
+        GLenum renderTarget = mSurfaceTexture->getCurrentTextureTarget();
+
+        LayerRenderer::updateTextureLayer(mLayer, mWidth, mHeight,
+                !mBlend, forceFilter, renderTarget, transform);
+    }
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
new file mode 100644
index 0000000..cf745ee
--- /dev/null
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef DEFERREDLAYERUPDATE_H_
+#define DEFERREDLAYERUPDATE_H_
+
+#include <cutils/compiler.h>
+#include <gui/GLConsumer.h>
+#include <SkColorFilter.h>
+#include <SkMatrix.h>
+#include <utils/StrongPointer.h>
+
+#include "Layer.h"
+#include "OpenGLRenderer.h"
+#include "Rect.h"
+#include "RenderNode.h"
+
+namespace android {
+namespace uirenderer {
+
+// Container to hold the properties a layer should be set to at the start
+// of a render pass
+class DeferredLayerUpdater {
+public:
+    // Note that DeferredLayerUpdater assumes it is taking ownership of the layer
+    // and will not call incrementRef on it as a result.
+    ANDROID_API DeferredLayerUpdater(Layer* layer, OpenGLRenderer* renderer = 0);
+    ANDROID_API ~DeferredLayerUpdater();
+
+    ANDROID_API bool setSize(uint32_t width, uint32_t height) {
+        if (mWidth != width || mHeight != height) {
+            mWidth = width;
+            mHeight = height;
+            return true;
+        }
+        return false;
+    }
+
+    ANDROID_API bool setBlend(bool blend) {
+        if (blend != mBlend) {
+            mBlend = blend;
+            return true;
+        }
+        return false;
+    }
+
+    ANDROID_API void setSurfaceTexture(const sp<GLConsumer>& texture, bool needsAttach) {
+        if (texture.get() != mSurfaceTexture.get()) {
+            mNeedsGLContextAttach = needsAttach;
+            mSurfaceTexture = texture;
+        }
+    }
+
+    ANDROID_API void updateTexImage() {
+        mUpdateTexImage = true;
+    }
+
+    ANDROID_API void setTransform(const SkMatrix* matrix) {
+        delete mTransform;
+        mTransform = matrix ? new SkMatrix(*matrix) : 0;
+    }
+
+    ANDROID_API void setDisplayList(RenderNode* displayList,
+                int left, int top, int right, int bottom);
+
+    ANDROID_API void setPaint(const SkPaint* paint);
+
+    ANDROID_API bool apply();
+
+    ANDROID_API Layer* backingLayer() {
+        return mLayer;
+    }
+
+    ANDROID_API Layer* detachBackingLayer() {
+        Layer* layer = mLayer;
+        mLayer = 0;
+        return layer;
+    }
+
+private:
+    // Generic properties
+    uint32_t mWidth;
+    uint32_t mHeight;
+    bool mBlend;
+    SkColorFilter* mColorFilter;
+    int mAlpha;
+    SkXfermode::Mode mMode;
+
+    // Layer type specific properties
+    // displayList and surfaceTexture are mutually exclusive, only 1 may be set
+    // dirtyRect is only valid if displayList is set
+    RenderNode* mDisplayList;
+    Rect mDirtyRect;
+    sp<GLConsumer> mSurfaceTexture;
+    SkMatrix* mTransform;
+    bool mNeedsGLContextAttach;
+    bool mUpdateTexImage;
+
+    Layer* mLayer;
+    OpenGLRenderer* mRenderer;
+    Caches& mCaches;
+
+    void doUpdateTexImage();
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* DEFERREDLAYERUPDATE_H_ */
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index bb6526e..9e6a96d 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -14,7 +14,12 @@
  * limitations under the License.
  */
 
+#define ATRACE_TAG ATRACE_TAG_VIEW
+
 #include <SkCanvas.h>
+#include <algorithm>
+
+#include <utils/Trace.h>
 
 #include "Debug.h"
 #include "DisplayList.h"
@@ -24,533 +29,66 @@
 namespace android {
 namespace uirenderer {
 
-void DisplayList::outputLogBuffer(int fd) {
-    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
-    if (logBuffer.isEmpty()) {
-        return;
-    }
-
-    FILE *file = fdopen(fd, "a");
-
-    fprintf(file, "\nRecent DisplayList operations\n");
-    logBuffer.outputCommands(file);
-
-    String8 cachesLog;
-    Caches::getInstance().dumpMemoryUsage(cachesLog);
-    fprintf(file, "\nCaches:\n%s", cachesLog.string());
-    fprintf(file, "\n");
-
-    fflush(file);
-}
-
-DisplayList::DisplayList(const DisplayListRenderer& recorder) :
-    mDestroyed(false), mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
-    mStaticMatrix(NULL), mAnimationMatrix(NULL) {
-
-    initFromDisplayListRenderer(recorder);
-}
-
-DisplayList::~DisplayList() {
-    mDestroyed = true;
-    clearResources();
-}
-
-void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
-    if (displayList) {
-        DISPLAY_LIST_LOGD("Deferring display list destruction");
-        Caches::getInstance().deleteDisplayListDeferred(displayList);
-    }
-}
-
-void DisplayList::clearResources() {
-    mDisplayListData = NULL;
-
-    mClipRectOp = NULL;
-    mSaveLayerOp = NULL;
-    mSaveOp = NULL;
-    mRestoreToCountOp = NULL;
-
-    delete mTransformMatrix;
-    delete mTransformCamera;
-    delete mTransformMatrix3D;
-    delete mStaticMatrix;
-    delete mAnimationMatrix;
-
-    mTransformMatrix = NULL;
-    mTransformCamera = NULL;
-    mTransformMatrix3D = NULL;
-    mStaticMatrix = NULL;
-    mAnimationMatrix = NULL;
-
+void DisplayListData::cleanupResources() {
     Caches& caches = Caches::getInstance();
-    caches.unregisterFunctors(mFunctorCount);
+    caches.unregisterFunctors(functorCount);
     caches.resourceCache.lock();
 
-    for (size_t i = 0; i < mBitmapResources.size(); i++) {
-        caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
+    for (size_t i = 0; i < bitmapResources.size(); i++) {
+        caches.resourceCache.decrementRefcountLocked(bitmapResources.itemAt(i));
     }
 
-    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
-        SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
+    for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
+        const SkBitmap* bitmap = ownedBitmapResources.itemAt(i);
         caches.resourceCache.decrementRefcountLocked(bitmap);
         caches.resourceCache.destructorLocked(bitmap);
     }
 
-    for (size_t i = 0; i < mFilterResources.size(); i++) {
-        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));
-    }
-
-    for (size_t i = 0; i < mSourcePaths.size(); i++) {
-        caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
-    }
-
-    for (size_t i = 0; i < mLayers.size(); i++) {
-        caches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i));
-    }
-
-    caches.resourceCache.unlock();
-
-    for (size_t i = 0; i < mPaints.size(); i++) {
-        delete mPaints.itemAt(i);
-    }
-
-    for (size_t i = 0; i < mRegions.size(); i++) {
-        delete mRegions.itemAt(i);
-    }
-
-    for (size_t i = 0; i < mPaths.size(); i++) {
-        delete mPaths.itemAt(i);
-    }
-
-    for (size_t i = 0; i < mMatrices.size(); i++) {
-        delete mMatrices.itemAt(i);
-    }
-
-    mBitmapResources.clear();
-    mOwnedBitmapResources.clear();
-    mFilterResources.clear();
-    mPatchResources.clear();
-    mShaders.clear();
-    mSourcePaths.clear();
-    mPaints.clear();
-    mRegions.clear();
-    mPaths.clear();
-    mMatrices.clear();
-    mLayers.clear();
-}
-
-void DisplayList::reset() {
-    clearResources();
-    init();
-}
-
-void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
-    if (reusing) {
-        // re-using display list - clear out previous allocations
-        clearResources();
-    }
-
-    init();
-
-    mDisplayListData = recorder.getDisplayListData();
-    mSize = mDisplayListData->allocator.usedSize();
-
-    if (mSize == 0) {
-        return;
-    }
-
-    // allocate reusable ops for state-deferral
-    LinearAllocator& alloc = mDisplayListData->allocator;
-    mClipRectOp = new (alloc) ClipRectOp();
-    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();
-
-    Caches& caches = Caches::getInstance();
-    caches.registerFunctors(mFunctorCount);
-    caches.resourceCache.lock();
-
-    const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
-    for (size_t i = 0; i < bitmapResources.size(); i++) {
-        SkBitmap* resource = bitmapResources.itemAt(i);
-        mBitmapResources.add(resource);
-        caches.resourceCache.incrementRefcountLocked(resource);
-    }
-
-    const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
-    for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
-        SkBitmap* resource = ownedBitmapResources.itemAt(i);
-        mOwnedBitmapResources.add(resource);
-        caches.resourceCache.incrementRefcountLocked(resource);
-    }
-
-    const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
-    for (size_t i = 0; i < filterResources.size(); i++) {
-        SkiaColorFilter* resource = filterResources.itemAt(i);
-        mFilterResources.add(resource);
-        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);
+        caches.resourceCache.decrementRefcountLocked(patchResources.itemAt(i));
     }
 
-    const Vector<SkiaShader*>& shaders = recorder.getShaders();
     for (size_t i = 0; i < shaders.size(); i++) {
-        SkiaShader* resource = shaders.itemAt(i);
-        mShaders.add(resource);
-        caches.resourceCache.incrementRefcountLocked(resource);
+        caches.resourceCache.decrementRefcountLocked(shaders.itemAt(i));
+        caches.resourceCache.destructorLocked(shaders.itemAt(i));
     }
 
-    const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
     for (size_t i = 0; i < sourcePaths.size(); i++) {
-        mSourcePaths.add(sourcePaths.itemAt(i));
-        caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
+        caches.resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i));
     }
 
-    const Vector<Layer*>& layers = recorder.getLayers();
     for (size_t i = 0; i < layers.size(); i++) {
-        mLayers.add(layers.itemAt(i));
-        caches.resourceCache.incrementRefcountLocked(layers.itemAt(i));
+        caches.resourceCache.decrementRefcountLocked(layers.itemAt(i));
     }
 
     caches.resourceCache.unlock();
 
-    mPaints.appendVector(recorder.getPaints());
-    mRegions.appendVector(recorder.getRegions());
-    mPaths.appendVector(recorder.getPaths());
-    mMatrices.appendVector(recorder.getMatrices());
-}
-
-void DisplayList::init() {
-    mSize = 0;
-    mIsRenderable = true;
-    mFunctorCount = 0;
-    mLeft = 0;
-    mTop = 0;
-    mRight = 0;
-    mBottom = 0;
-    mClipToBounds = true;
-    mAlpha = 1;
-    mHasOverlappingRendering = true;
-    mTranslationX = 0;
-    mTranslationY = 0;
-    mRotation = 0;
-    mRotationX = 0;
-    mRotationY= 0;
-    mScaleX = 1;
-    mScaleY = 1;
-    mPivotX = 0;
-    mPivotY = 0;
-    mCameraDistance = 0;
-    mMatrixDirty = false;
-    mMatrixFlags = 0;
-    mPrevWidth = -1;
-    mPrevHeight = -1;
-    mWidth = 0;
-    mHeight = 0;
-    mPivotExplicitlySet = false;
-    mCaching = false;
-}
-
-size_t DisplayList::getSize() {
-    return mSize;
-}
-
-/**
- * This function is a simplified version of replay(), where we simply retrieve and log the
- * display list. This function should remain in sync with the replay() function.
- */
-void DisplayList::output(uint32_t level) {
-    ALOGD("%*sStart display list (%p, %s, render=%d)", (level - 1) * 2, "", this,
-            mName.string(), isRenderable());
-    ALOGD("%*s%s %d", level * 2, "", "Save",
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
-
-    outputViewProperties(level);
-    int flags = DisplayListOp::kOpLogFlag_Recurse;
-    for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
-        mDisplayListData->displayListOps[i]->output(level, flags);
+    for (size_t i = 0; i < paints.size(); i++) {
+        delete paints.itemAt(i);
     }
 
-    ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
-}
-
-float DisplayList::getPivotX() {
-    updateMatrix();
-    return mPivotX;
-}
-
-float DisplayList::getPivotY() {
-    updateMatrix();
-    return mPivotY;
-}
-
-void DisplayList::updateMatrix() {
-    if (mMatrixDirty) {
-        if (!mTransformMatrix) {
-            mTransformMatrix = new SkMatrix();
-        }
-        if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
-            mTransformMatrix->reset();
-        } else {
-            if (!mPivotExplicitlySet) {
-                if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
-                    mPrevWidth = mWidth;
-                    mPrevHeight = mHeight;
-                    mPivotX = mPrevWidth / 2.0f;
-                    mPivotY = mPrevHeight / 2.0f;
-                }
-            }
-            if ((mMatrixFlags & ROTATION_3D) == 0) {
-                mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
-                mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
-                mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
-            } else {
-                if (!mTransformCamera) {
-                    mTransformCamera = new Sk3DView();
-                    mTransformMatrix3D = new SkMatrix();
-                }
-                mTransformMatrix->reset();
-                mTransformCamera->save();
-                mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
-                mTransformCamera->rotateX(mRotationX);
-                mTransformCamera->rotateY(mRotationY);
-                mTransformCamera->rotateZ(-mRotation);
-                mTransformCamera->getMatrix(mTransformMatrix3D);
-                mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
-                mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
-                        mPivotY + mTranslationY);
-                mTransformMatrix->postConcat(*mTransformMatrix3D);
-                mTransformCamera->restore();
-            }
-        }
-        mMatrixDirty = false;
-    }
-}
-
-void DisplayList::outputViewProperties(const int level) {
-    updateMatrix();
-    if (mLeft != 0 || mTop != 0) {
-        ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
-    }
-    if (mStaticMatrix) {
-        ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING,
-                level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix));
-    }
-    if (mAnimationMatrix) {
-        ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING,
-                level * 2, "", mAnimationMatrix, MATRIX_ARGS(mAnimationMatrix));
-    }
-    if (mMatrixFlags != 0) {
-        if (mMatrixFlags == TRANSLATION) {
-            ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY);
-        } else {
-            ALOGD("%*sConcatMatrix %p: " MATRIX_STRING,
-                    level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
-        }
+    for (size_t i = 0; i < regions.size(); i++) {
+        delete regions.itemAt(i);
     }
 
-    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
-    if (mAlpha < 1) {
-        if (mCaching) {
-            ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha);
-        } else if (!mHasOverlappingRendering) {
-            ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha);
-        } else {
-            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
-            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 (clipToBoundsNeeded) {
-        ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
-                (float) mRight - mLeft, (float) mBottom - mTop);
-    }
-}
-
-/*
- * For property operations, we pass a savecount of 0, since the operations aren't part of the
- * displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
- * base saveCount (i.e., how RestoreToCount uses saveCount + mCount)
- */
-#define PROPERTY_SAVECOUNT 0
-
-template <class T>
-void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler,
-        const int level) {
-#if DEBUG_DISPLAY_LIST
-    outputViewProperties(level);
-#endif
-    updateMatrix();
-    if (mLeft != 0 || mTop != 0) {
-        renderer.translate(mLeft, mTop);
-    }
-    if (mStaticMatrix) {
-        renderer.concatMatrix(mStaticMatrix);
-    } else if (mAnimationMatrix) {
-        renderer.concatMatrix(mAnimationMatrix);
-    }
-    if (mMatrixFlags != 0) {
-        if (mMatrixFlags == TRANSLATION) {
-            renderer.translate(mTranslationX, mTranslationY);
-        } else {
-            renderer.concatMatrix(mTransformMatrix);
-        }
-    }
-    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
-    if (mAlpha < 1) {
-        if (mCaching) {
-            renderer.setOverrideLayerAlpha(mAlpha);
-        } else if (!mHasOverlappingRendering) {
-            renderer.scaleAlpha(mAlpha);
-        } else {
-            // TODO: should be able to store the size of a DL at record time and not
-            // 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 (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 (clipToBoundsNeeded) {
-        handler(mClipRectOp->reinit(0, 0, mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op),
-                PROPERTY_SAVECOUNT, mClipToBounds);
-    }
-}
-
-class DeferOperationHandler {
-public:
-    DeferOperationHandler(DeferStateStruct& deferStruct, int level)
-        : mDeferStruct(deferStruct), mLevel(level) {}
-    inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
-        operation->defer(mDeferStruct, saveCount, mLevel, clipToBounds);
-    }
-private:
-    DeferStateStruct& mDeferStruct;
-    const int mLevel;
-};
-
-void DisplayList::defer(DeferStateStruct& deferStruct, const int level) {
-    DeferOperationHandler handler(deferStruct, level);
-    iterate<DeferOperationHandler>(deferStruct.mRenderer, handler, level);
-}
-
-class ReplayOperationHandler {
-public:
-    ReplayOperationHandler(ReplayStateStruct& replayStruct, int level)
-        : mReplayStruct(replayStruct), mLevel(level) {}
-    inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
-#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-        mReplayStruct.mRenderer.eventMark(operation->name());
-#endif
-        operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds);
-    }
-private:
-    ReplayStateStruct& mReplayStruct;
-    const int mLevel;
-};
-
-void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) {
-    ReplayOperationHandler handler(replayStruct, level);
-
-    replayStruct.mRenderer.startMark(mName.string());
-    iterate<ReplayOperationHandler>(replayStruct.mRenderer, handler, level);
-    replayStruct.mRenderer.endMark();
-
-    DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", level * 2, "", this, mName.string(),
-            replayStruct.mDrawGlStatus);
-}
-
-/**
- * This function serves both defer and replay modes, and will organize the displayList's component
- * operations for a single frame:
- *
- * Every 'simple' operation that affects just the matrix and alpha (or other factors of
- * DeferredDisplayState) may be issued directly to the renderer, but complex operations (with custom
- * defer logic) and operations in displayListOps are issued through the 'handler' which handles the
- * defer vs replay logic, per operation
- */
-template <class T>
-void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
-    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;
+    for (size_t i = 0; i < paths.size(); i++) {
+        delete paths.itemAt(i);
     }
 
-#if DEBUG_DISPLAY_LIST
-    Rect* clipRect = renderer.getClipRect();
-    DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.0f, %.0f, %.0f",
-            level * 2, "", this, mName.string(), clipRect->left, clipRect->top,
-            clipRect->right, clipRect->bottom);
-#endif
-
-    int restoreTo = renderer.getSaveCount();
-    handler(mSaveOp->reinit(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
-            PROPERTY_SAVECOUNT, mClipToBounds);
-
-    DISPLAY_LIST_LOGD("%*sSave %d %d", (level + 1) * 2, "",
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
-
-    setViewProperties<T>(renderer, handler, level + 1);
-
-    if (mClipToBounds && renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
-        DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
-        handler(mRestoreToCountOp->reinit(restoreTo), PROPERTY_SAVECOUNT, mClipToBounds);
-        renderer.restoreToCount(restoreTo);
-        renderer.setOverrideLayerAlpha(1.0f);
-        return;
+    for (size_t i = 0; i < matrices.size(); i++) {
+        delete matrices.itemAt(i);
     }
 
-    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
-    int saveCount = renderer.getSaveCount() - 1;
-    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);
-    }
-
-    DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
-    handler(mRestoreToCountOp->reinit(restoreTo), PROPERTY_SAVECOUNT, mClipToBounds);
-    renderer.restoreToCount(restoreTo);
-    renderer.setOverrideLayerAlpha(1.0f);
+    bitmapResources.clear();
+    ownedBitmapResources.clear();
+    patchResources.clear();
+    shaders.clear();
+    sourcePaths.clear();
+    paints.clear();
+    regions.clear();
+    paths.clear();
+    matrices.clear();
+    layers.clear();
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 1cd5f1c..df5cba6 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -26,6 +26,7 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
+#include <utils/KeyedVector.h>
 #include <utils/LinearAllocator.h>
 #include <utils/RefBase.h>
 #include <utils/SortedVector.h>
@@ -37,12 +38,9 @@
 #include <androidfw/ResourceTypes.h>
 
 #include "Debug.h"
-
-#define TRANSLATION 0x0001
-#define ROTATION    0x0002
-#define ROTATION_3D 0x0004
-#define SCALE       0x0008
-#define PIVOT       0x0010
+#include "Matrix.h"
+#include "DeferredDisplayList.h"
+#include "RenderProperties.h"
 
 class SkBitmap;
 class SkPaint;
@@ -58,492 +56,92 @@
 class OpenGLRenderer;
 class Rect;
 class Layer;
-class SkiaColorFilter;
 class SkiaShader;
 
 class ClipRectOp;
 class SaveLayerOp;
 class SaveOp;
 class RestoreToCountOp;
+class DrawDisplayListOp;
 
-struct DeferStateStruct {
+/**
+ * Holds data used in the playback a tree of DisplayLists.
+ */
+class PlaybackStateStruct {
+protected:
+    PlaybackStateStruct(OpenGLRenderer& renderer, int replayFlags, LinearAllocator* allocator)
+            : mRenderer(renderer), mReplayFlags(replayFlags), mAllocator(allocator){}
+
+public:
+    OpenGLRenderer& mRenderer;
+    const int mReplayFlags;
+
+    // Allocator with the lifetime of a single frame.
+    // replay uses an Allocator owned by the struct, while defer shares the DeferredDisplayList's Allocator
+    LinearAllocator * const mAllocator;
+};
+
+class DeferStateStruct : public PlaybackStateStruct {
+public:
     DeferStateStruct(DeferredDisplayList& deferredList, OpenGLRenderer& renderer, int replayFlags)
-            : mDeferredList(deferredList), mRenderer(renderer), mReplayFlags(replayFlags) {}
+            : PlaybackStateStruct(renderer, replayFlags, &(deferredList.mAllocator)),
+            mDeferredList(deferredList) {}
+
     DeferredDisplayList& mDeferredList;
-    OpenGLRenderer& mRenderer;
-    const int mReplayFlags;
 };
 
-struct ReplayStateStruct {
+class ReplayStateStruct : public PlaybackStateStruct {
+public:
     ReplayStateStruct(OpenGLRenderer& renderer, Rect& dirty, int replayFlags)
-            : mRenderer(renderer), mDirty(dirty), mReplayFlags(replayFlags),
-            mDrawGlStatus(DrawGlInfo::kStatusDone) {}
-    OpenGLRenderer& mRenderer;
+            : PlaybackStateStruct(renderer, replayFlags, &mReplayAllocator),
+            mDirty(dirty), mDrawGlStatus(DrawGlInfo::kStatusDone) {}
+
     Rect& mDirty;
-    const int mReplayFlags;
     status_t mDrawGlStatus;
+    LinearAllocator mReplayAllocator;
 };
 
 /**
- * Refcounted structure that holds data used in display list stream
+ * Data structure that holds the list of commands used in display list stream
  */
-class DisplayListData : public LightRefBase<DisplayListData> {
+class DisplayListData {
 public:
+    DisplayListData() : projectionReceiveIndex(-1), functorCount(0), hasDrawOps(false) {}
+    virtual ~DisplayListData() { cleanupResources(); }
+
+    // allocator into which all ops were allocated
     LinearAllocator allocator;
+
+    // pointers to all ops within display list, pointing into allocator data
     Vector<DisplayListOp*> displayListOps;
-};
 
-/**
- * Replays recorded drawing commands.
- */
-class DisplayList {
-public:
-    DisplayList(const DisplayListRenderer& recorder);
-    ANDROID_API ~DisplayList();
+    // list of children display lists for quick, non-drawing traversal
+    Vector<DrawDisplayListOp*> children;
 
-    // See flags defined in DisplayList.java
-    enum ReplayFlag {
-        kReplayFlag_ClipChildren = 0x1
-    };
+    // index of DisplayListOp restore, after which projected descendents should be drawn
+    int projectionReceiveIndex;
 
+    Vector<const SkBitmap*> bitmapResources;
+    Vector<const SkBitmap*> ownedBitmapResources;
+    Vector<const Res_png_9patch*> patchResources;
 
-    ANDROID_API size_t getSize();
-    ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
-    ANDROID_API static void outputLogBuffer(int fd);
+    Vector<const SkPaint*> paints;
+    Vector<const SkPath*> paths;
+    SortedVector<const SkPath*> sourcePaths;
+    Vector<const SkRegion*> regions;
+    Vector<const SkMatrix*> matrices;
+    Vector<SkiaShader*> shaders;
+    Vector<Layer*> layers;
+    uint32_t functorCount;
+    bool hasDrawOps;
 
-    void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
-
-    void defer(DeferStateStruct& deferStruct, const int level);
-    void replay(ReplayStateStruct& replayStruct, const int level);
-
-    void output(uint32_t level = 0);
-
-    ANDROID_API void reset();
-
-    void setRenderable(bool renderable) {
-        mIsRenderable = renderable;
-    }
-
-    bool isRenderable() const {
-        return mIsRenderable;
-    }
-
-    void setName(const char* name) {
-        if (name) {
-            char* lastPeriod = strrchr(name, '.');
-            if (lastPeriod) {
-                mName.setTo(lastPeriod + 1);
-            } else {
-                mName.setTo(name);
-            }
-        }
-    }
-
-    const char* getName() const {
-        return mName.string();
-    }
-
-    void setClipToBounds(bool clipToBounds) {
-        mClipToBounds = clipToBounds;
-    }
-
-    void setStaticMatrix(SkMatrix* matrix) {
-        delete mStaticMatrix;
-        mStaticMatrix = new SkMatrix(*matrix);
-    }
-
-    // Can return NULL
-    SkMatrix* getStaticMatrix() {
-        return mStaticMatrix;
-    }
-
-    void setAnimationMatrix(SkMatrix* matrix) {
-        delete mAnimationMatrix;
-        if (matrix) {
-            mAnimationMatrix = new SkMatrix(*matrix);
-        } else {
-            mAnimationMatrix = NULL;
-        }
-    }
-
-    void setAlpha(float alpha) {
-        alpha = fminf(1.0f, fmaxf(0.0f, alpha));
-        if (alpha != mAlpha) {
-            mAlpha = alpha;
-        }
-    }
-
-    float getAlpha() const {
-        return mAlpha;
-    }
-
-    void setHasOverlappingRendering(bool hasOverlappingRendering) {
-        mHasOverlappingRendering = hasOverlappingRendering;
-    }
-
-    bool hasOverlappingRendering() const {
-        return mHasOverlappingRendering;
-    }
-
-    void setTranslationX(float translationX) {
-        if (translationX != mTranslationX) {
-            mTranslationX = translationX;
-            mMatrixDirty = true;
-            if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
-                mMatrixFlags &= ~TRANSLATION;
-            } else {
-                mMatrixFlags |= TRANSLATION;
-            }
-        }
-    }
-
-    float getTranslationX() const {
-        return mTranslationX;
-    }
-
-    void setTranslationY(float translationY) {
-        if (translationY != mTranslationY) {
-            mTranslationY = translationY;
-            mMatrixDirty = true;
-            if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
-                mMatrixFlags &= ~TRANSLATION;
-            } else {
-                mMatrixFlags |= TRANSLATION;
-            }
-        }
-    }
-
-    float getTranslationY() const {
-        return mTranslationY;
-    }
-
-    void setRotation(float rotation) {
-        if (rotation != mRotation) {
-            mRotation = rotation;
-            mMatrixDirty = true;
-            if (mRotation == 0.0f) {
-                mMatrixFlags &= ~ROTATION;
-            } else {
-                mMatrixFlags |= ROTATION;
-            }
-        }
-    }
-
-    float getRotation() const {
-        return mRotation;
-    }
-
-    void setRotationX(float rotationX) {
-        if (rotationX != mRotationX) {
-            mRotationX = rotationX;
-            mMatrixDirty = true;
-            if (mRotationX == 0.0f && mRotationY == 0.0f) {
-                mMatrixFlags &= ~ROTATION_3D;
-            } else {
-                mMatrixFlags |= ROTATION_3D;
-            }
-        }
-    }
-
-    float getRotationX() const {
-        return mRotationX;
-    }
-
-    void setRotationY(float rotationY) {
-        if (rotationY != mRotationY) {
-            mRotationY = rotationY;
-            mMatrixDirty = true;
-            if (mRotationX == 0.0f && mRotationY == 0.0f) {
-                mMatrixFlags &= ~ROTATION_3D;
-            } else {
-                mMatrixFlags |= ROTATION_3D;
-            }
-        }
-    }
-
-    float getRotationY() const {
-        return mRotationY;
-    }
-
-    void setScaleX(float scaleX) {
-        if (scaleX != mScaleX) {
-            mScaleX = scaleX;
-            mMatrixDirty = true;
-            if (mScaleX == 1.0f && mScaleY == 1.0f) {
-                mMatrixFlags &= ~SCALE;
-            } else {
-                mMatrixFlags |= SCALE;
-            }
-        }
-    }
-
-    float getScaleX() const {
-        return mScaleX;
-    }
-
-    void setScaleY(float scaleY) {
-        if (scaleY != mScaleY) {
-            mScaleY = scaleY;
-            mMatrixDirty = true;
-            if (mScaleX == 1.0f && mScaleY == 1.0f) {
-                mMatrixFlags &= ~SCALE;
-            } else {
-                mMatrixFlags |= SCALE;
-            }
-        }
-    }
-
-    float getScaleY() const {
-        return mScaleY;
-    }
-
-    void setPivotX(float pivotX) {
-        mPivotX = pivotX;
-        mMatrixDirty = true;
-        if (mPivotX == 0.0f && mPivotY == 0.0f) {
-            mMatrixFlags &= ~PIVOT;
-        } else {
-            mMatrixFlags |= PIVOT;
-        }
-        mPivotExplicitlySet = true;
-    }
-
-    ANDROID_API float getPivotX();
-
-    void setPivotY(float pivotY) {
-        mPivotY = pivotY;
-        mMatrixDirty = true;
-        if (mPivotX == 0.0f && mPivotY == 0.0f) {
-            mMatrixFlags &= ~PIVOT;
-        } else {
-            mMatrixFlags |= PIVOT;
-        }
-        mPivotExplicitlySet = true;
-    }
-
-    ANDROID_API float getPivotY();
-
-    void setCameraDistance(float distance) {
-        if (distance != mCameraDistance) {
-            mCameraDistance = distance;
-            mMatrixDirty = true;
-            if (!mTransformCamera) {
-                mTransformCamera = new Sk3DView();
-                mTransformMatrix3D = new SkMatrix();
-            }
-            mTransformCamera->setCameraLocation(0, 0, distance);
-        }
-    }
-
-    float getCameraDistance() const {
-        return mCameraDistance;
-    }
-
-    void setLeft(int left) {
-        if (left != mLeft) {
-            mLeft = left;
-            mWidth = mRight - mLeft;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getLeft() const {
-        return mLeft;
-    }
-
-    void setTop(int top) {
-        if (top != mTop) {
-            mTop = top;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getTop() const {
-        return mTop;
-    }
-
-    void setRight(int right) {
-        if (right != mRight) {
-            mRight = right;
-            mWidth = mRight - mLeft;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getRight() const {
-        return mRight;
-    }
-
-    void setBottom(int bottom) {
-        if (bottom != mBottom) {
-            mBottom = bottom;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getBottom() const {
-        return mBottom;
-    }
-
-    void setLeftTop(int left, int top) {
-        if (left != mLeft || top != mTop) {
-            mLeft = left;
-            mTop = top;
-            mWidth = mRight - mLeft;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void setLeftTopRightBottom(int left, int top, int right, int bottom) {
-        if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
-            mLeft = left;
-            mTop = top;
-            mRight = right;
-            mBottom = bottom;
-            mWidth = mRight - mLeft;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void offsetLeftRight(float offset) {
-        if (offset != 0) {
-            mLeft += offset;
-            mRight += offset;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void offsetTopBottom(float offset) {
-        if (offset != 0) {
-            mTop += offset;
-            mBottom += offset;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void setCaching(bool caching) {
-        mCaching = caching;
-    }
-
-    int getWidth() {
-        return mWidth;
-    }
-
-    int getHeight() {
-        return mHeight;
+    bool isEmpty() {
+        return !displayListOps.size();
     }
 
 private:
-    void outputViewProperties(const int level);
-
-    template <class T>
-    inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level);
-
-    template <class T>
-    inline void iterate(OpenGLRenderer& renderer, T& handler, const int level);
-
-    void init();
-
-    void clearResources();
-
-    void updateMatrix();
-
-    class TextContainer {
-    public:
-        size_t length() const {
-            return mByteLength;
-        }
-
-        const char* text() const {
-            return (const char*) mText;
-        }
-
-        size_t mByteLength;
-        const char* mText;
-    };
-
-    Vector<SkBitmap*> mBitmapResources;
-    Vector<SkBitmap*> mOwnedBitmapResources;
-    Vector<SkiaColorFilter*> mFilterResources;
-    Vector<Res_png_9patch*> mPatchResources;
-
-    Vector<SkPaint*> mPaints;
-    Vector<SkPath*> mPaths;
-    SortedVector<SkPath*> mSourcePaths;
-    Vector<SkRegion*> mRegions;
-    Vector<SkMatrix*> mMatrices;
-    Vector<SkiaShader*> mShaders;
-    Vector<Layer*> mLayers;
-
-    sp<DisplayListData> mDisplayListData;
-
-    size_t mSize;
-
-    bool mIsRenderable;
-    uint32_t mFunctorCount;
-
-    String8 mName;
-    bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
-
-    // View properties
-    bool mClipToBounds;
-    float mAlpha;
-    bool mHasOverlappingRendering;
-    float mTranslationX, mTranslationY;
-    float mRotation, mRotationX, mRotationY;
-    float mScaleX, mScaleY;
-    float mPivotX, mPivotY;
-    float mCameraDistance;
-    int mLeft, mTop, mRight, mBottom;
-    int mWidth, mHeight;
-    int mPrevWidth, mPrevHeight;
-    bool mPivotExplicitlySet;
-    bool mMatrixDirty;
-    bool mMatrixIsIdentity;
-    uint32_t mMatrixFlags;
-    SkMatrix* mTransformMatrix;
-    Sk3DView* mTransformCamera;
-    SkMatrix* mTransformMatrix3D;
-    SkMatrix* mStaticMatrix;
-    SkMatrix* mAnimationMatrix;
-    bool mCaching;
-
-    /**
-     * State operations - needed to defer displayList property operations (for example, when setting
-     * an alpha causes a SaveLayerAlpha to occur). These operations point into mDisplayListData's
-     * allocation, or null if uninitialized.
-     *
-     * 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') to avoid overwriting data
-     */
-    ClipRectOp* mClipRectOp;
-    SaveLayerOp* mSaveLayerOp;
-    SaveOp* mSaveOp;
-    RestoreToCountOp* mRestoreToCountOp;
-}; // class DisplayList
+    void cleanupResources();
+};
 
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 842e028..549b786 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -111,7 +111,7 @@
 class DrawOp : public DisplayListOp {
 friend class MergingDrawBatch;
 public:
-    DrawOp(SkPaint* paint)
+    DrawOp(const SkPaint* paint)
             : mPaint(paint), mQuickRejected(false) {}
 
     virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
@@ -182,13 +182,16 @@
     }
 
     inline float strokeWidthOutset() {
-        float width = mPaint->getStrokeWidth();
-        if (width == 0) return 0.5f; // account for hairline
-        return width * 0.5f;
+        // since anything AA stroke with less than 1.0 pixel width is drawn with an alpha-reduced
+        // 1.0 stroke, treat 1.0 as minimum.
+
+        // TODO: it would be nice if this could take scale into account, but scale isn't stable
+        // since higher levels of the view hierarchy can change scale out from underneath it.
+        return fmaxf(mPaint->getStrokeWidth(), 1) * 0.5f;
     }
 
 protected:
-    SkPaint* getPaint(OpenGLRenderer& renderer) {
+    const SkPaint* getPaint(OpenGLRenderer& renderer) {
         return renderer.filterPaint(mPaint);
     }
 
@@ -209,22 +212,22 @@
 
     }
 
-    SkPaint* mPaint; // should be accessed via getPaint() when applying
+    const SkPaint* mPaint; // should be accessed via getPaint() when applying
     bool mQuickRejected;
 };
 
 class DrawBoundedOp : public DrawOp {
 public:
-    DrawBoundedOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawBoundedOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawOp(paint), mLocalBounds(left, top, right, bottom) {}
 
-    DrawBoundedOp(const Rect& localBounds, SkPaint* paint)
+    DrawBoundedOp(const Rect& localBounds, const 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)
-    DrawBoundedOp(const float* points, int count, SkPaint* paint)
+    DrawBoundedOp(const float* points, int count, const SkPaint* paint)
             : DrawOp(paint), mLocalBounds(points[0], points[1], points[0], points[1]) {
         for (int i = 2; i < count; i += 2) {
             mLocalBounds.left = fminf(mLocalBounds.left, points[i]);
@@ -235,7 +238,7 @@
     }
 
     // default empty constructor for bounds, to be overridden in child constructor body
-    DrawBoundedOp(SkPaint* paint): DrawOp(paint) { }
+    DrawBoundedOp(const SkPaint* paint): DrawOp(paint) { }
 
     bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
         localBounds.set(mLocalBounds);
@@ -259,7 +262,6 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 class SaveOp : public StateOp {
-    friend class DisplayList; // give DisplayList private constructor/reinit access
 public:
     SaveOp(int flags)
             : mFlags(flags) {}
@@ -292,7 +294,6 @@
 };
 
 class RestoreToCountOp : public StateOp {
-    friend class DisplayList; // give DisplayList private constructor/reinit access
 public:
     RestoreToCountOp(int count)
             : mCount(count) {}
@@ -325,11 +326,14 @@
 };
 
 class SaveLayerOp : public StateOp {
-    friend class DisplayList; // give DisplayList private constructor/reinit access
 public:
-    SaveLayerOp(float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode, int flags)
-            : mArea(left, top, right, bottom), mAlpha(alpha), mMode(mode), mFlags(flags) {}
+    SaveLayerOp(float left, float top, float right, float bottom, int alpha, int flags)
+            : mArea(left, top, right, bottom), mPaint(&mCachedPaint), mFlags(flags) {
+        mCachedPaint.setAlpha(alpha);
+    }
+
+    SaveLayerOp(float left, float top, float right, float bottom, const SkPaint* paint, int flags)
+            : mArea(left, top, right, bottom), mPaint(paint), mFlags(flags) {}
 
     virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
             bool useQuickReject) {
@@ -340,11 +344,11 @@
         // NOTE: don't issue full saveLayer, since that has side effects/is costly. instead just
         // setup the snapshot for deferral, and re-issue the op at flush time
         deferStruct.mRenderer.saveLayerDeferred(mArea.left, mArea.top, mArea.right, mArea.bottom,
-                mAlpha, mMode, mFlags);
+                mPaint, mFlags);
     }
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
-        renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, mAlpha, mMode, mFlags);
+        renderer.saveLayer(mArea.left, mArea.top, mArea.right, mArea.bottom, mPaint, mFlags);
     }
 
     virtual void output(int level, uint32_t logFlags) const {
@@ -357,21 +361,15 @@
     int getFlags() { return mFlags; }
 
 private:
-    // Special case, reserved for direct DisplayList usage
-    SaveLayerOp() {}
-    DisplayListOp* reinit(float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode, int flags) {
-        mArea.set(left, top, right, bottom);
-        mAlpha = alpha;
-        mMode = mode;
-        mFlags = flags;
-        return this;
+    bool isSaveLayerAlpha() const {
+        SkXfermode::Mode mode = OpenGLRenderer::getXfermodeDirect(mPaint);
+        int alpha = OpenGLRenderer::getAlphaDirect(mPaint);
+        return alpha < 255 && mode == SkXfermode::kSrcOver_Mode;
     }
 
-    bool isSaveLayerAlpha() const { return mAlpha < 255 && mMode == SkXfermode::kSrcOver_Mode; }
     Rect mArea;
-    int mAlpha;
-    SkXfermode::Mode mMode;
+    const SkPaint* mPaint;
+    SkPaint mCachedPaint;
     int mFlags;
 };
 
@@ -456,7 +454,7 @@
 
 class SetMatrixOp : public StateOp {
 public:
-    SetMatrixOp(SkMatrix* matrix)
+    SetMatrixOp(const SkMatrix* matrix)
             : mMatrix(matrix) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -465,7 +463,7 @@
 
     virtual void output(int level, uint32_t logFlags) const {
         if (mMatrix) {
-            OP_LOG("SetMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+            OP_LOG("SetMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(mMatrix));
         } else {
             OP_LOGS("SetMatrix (reset)");
         }
@@ -474,12 +472,12 @@
     virtual const char* name() { return "SetMatrix"; }
 
 private:
-    SkMatrix* mMatrix;
+    const SkMatrix* mMatrix;
 };
 
 class ConcatMatrixOp : public StateOp {
 public:
-    ConcatMatrixOp(SkMatrix* matrix)
+    ConcatMatrixOp(const SkMatrix* matrix)
             : mMatrix(matrix) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -487,13 +485,13 @@
     }
 
     virtual void output(int level, uint32_t logFlags) const {
-        OP_LOG("ConcatMatrix " MATRIX_STRING, MATRIX_ARGS(mMatrix));
+        OP_LOG("ConcatMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(mMatrix));
     }
 
     virtual const char* name() { return "ConcatMatrix"; }
 
 private:
-    SkMatrix* mMatrix;
+    const SkMatrix* mMatrix;
 };
 
 class ClipOp : public StateOp {
@@ -521,7 +519,6 @@
 };
 
 class ClipRectOp : public ClipOp {
-    friend class DisplayList; // give DisplayList private constructor/reinit access
 public:
     ClipRectOp(float left, float top, float right, float bottom, SkRegion::Op op)
             : ClipOp(op), mArea(left, top, right, bottom) {}
@@ -552,7 +549,7 @@
 
 class ClipPathOp : public ClipOp {
 public:
-    ClipPathOp(SkPath* path, SkRegion::Op op)
+    ClipPathOp(const SkPath* path, SkRegion::Op op)
             : ClipOp(op), mPath(path) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -568,12 +565,12 @@
     virtual const char* name() { return "ClipPath"; }
 
 private:
-    SkPath* mPath;
+    const SkPath* mPath;
 };
 
 class ClipRegionOp : public ClipOp {
 public:
-    ClipRegionOp(SkRegion* region, SkRegion::Op op)
+    ClipRegionOp(const SkRegion* region, SkRegion::Op op)
             : ClipOp(op), mRegion(region) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -589,7 +586,7 @@
     virtual const char* name() { return "ClipRegion"; }
 
 private:
-    SkRegion* mRegion;
+    const SkRegion* mRegion;
 };
 
 class ResetShaderOp : public StateOp {
@@ -623,38 +620,6 @@
     SkiaShader* mShader;
 };
 
-class ResetColorFilterOp : public StateOp {
-public:
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
-        renderer.resetColorFilter();
-    }
-
-    virtual void output(int level, uint32_t logFlags) const {
-        OP_LOGS("ResetColorFilter");
-    }
-
-    virtual const char* name() { return "ResetColorFilter"; }
-};
-
-class SetupColorFilterOp : public StateOp {
-public:
-    SetupColorFilterOp(SkiaColorFilter* colorFilter)
-            : mColorFilter(colorFilter) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
-        renderer.setupColorFilter(mColorFilter);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const {
-        OP_LOG("SetupColorFilter, filter %p", mColorFilter);
-    }
-
-    virtual const char* name() { return "SetupColorFilter"; }
-
-private:
-    SkiaColorFilter* mColorFilter;
-};
-
 class ResetShadowOp : public StateOp {
 public:
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const {
@@ -729,7 +694,7 @@
 
 class DrawBitmapOp : public DrawBoundedOp {
 public:
-    DrawBitmapOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+    DrawBitmapOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
             : DrawBoundedOp(left, top, left + bitmap->width(), top + bitmap->height(), paint),
             mBitmap(bitmap), mAtlas(Caches::getInstance().assetAtlas) {
         mEntry = mAtlas.getEntry(bitmap);
@@ -823,12 +788,12 @@
         deferInfo.mergeable = state.mMatrix.isSimple() && state.mMatrix.positiveScale() &&
                 !state.mClipSideFlags &&
                 OpenGLRenderer::getXfermodeDirect(mPaint) == SkXfermode::kSrcOver_Mode &&
-                (mBitmap->getConfig() != SkBitmap::kA8_Config);
+                (mBitmap->config() != SkBitmap::kA8_Config);
     }
 
     const SkBitmap* bitmap() { return mBitmap; }
 protected:
-    SkBitmap* mBitmap;
+    const SkBitmap* mBitmap;
     const AssetAtlas& mAtlas;
     uint32_t mEntryGenerationId;
     AssetAtlas::Entry* mEntry;
@@ -837,7 +802,7 @@
 
 class DrawBitmapMatrixOp : public DrawBoundedOp {
 public:
-    DrawBitmapMatrixOp(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint)
+    DrawBitmapMatrixOp(const SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint)
             : DrawBoundedOp(paint), mBitmap(bitmap), mMatrix(matrix) {
         mLocalBounds.set(0, 0, bitmap->width(), bitmap->height());
         const mat4 transform(*matrix);
@@ -849,7 +814,7 @@
     }
 
     virtual void output(int level, uint32_t logFlags) const {
-        OP_LOG("Draw bitmap %p matrix " MATRIX_STRING, mBitmap, MATRIX_ARGS(mMatrix));
+        OP_LOG("Draw bitmap %p matrix " SK_MATRIX_STRING, mBitmap, SK_MATRIX_ARGS(mMatrix));
     }
 
     virtual const char* name() { return "DrawBitmapMatrix"; }
@@ -860,14 +825,15 @@
     }
 
 private:
-    SkBitmap* mBitmap;
-    SkMatrix* mMatrix;
+    const SkBitmap* mBitmap;
+    const SkMatrix* mMatrix;
 };
 
 class DrawBitmapRectOp : public DrawBoundedOp {
 public:
-    DrawBitmapRectOp(SkBitmap* bitmap, float srcLeft, float srcTop, float srcRight, float srcBottom,
-            float dstLeft, float dstTop, float dstRight, float dstBottom, SkPaint* paint)
+    DrawBitmapRectOp(const SkBitmap* bitmap,
+            float srcLeft, float srcTop, float srcRight, float srcBottom,
+            float dstLeft, float dstTop, float dstRight, float dstBottom, const SkPaint* paint)
             : DrawBoundedOp(dstLeft, dstTop, dstRight, dstBottom, paint),
             mBitmap(bitmap), mSrc(srcLeft, srcTop, srcRight, srcBottom) {}
 
@@ -890,13 +856,13 @@
     }
 
 private:
-    SkBitmap* mBitmap;
+    const SkBitmap* mBitmap;
     Rect mSrc;
 };
 
 class DrawBitmapDataOp : public DrawBitmapOp {
 public:
-    DrawBitmapDataOp(SkBitmap* bitmap, float left, float top, SkPaint* paint)
+    DrawBitmapDataOp(const SkBitmap* bitmap, float left, float top, const SkPaint* paint)
             : DrawBitmapOp(bitmap, left, top, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -918,8 +884,8 @@
 
 class DrawBitmapMeshOp : public DrawBoundedOp {
 public:
-    DrawBitmapMeshOp(SkBitmap* bitmap, int meshWidth, int meshHeight,
-            float* vertices, int* colors, SkPaint* paint)
+    DrawBitmapMeshOp(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint)
             : DrawBoundedOp(vertices, 2 * (meshWidth + 1) * (meshHeight + 1), paint),
             mBitmap(bitmap), mMeshWidth(meshWidth), mMeshHeight(meshHeight),
             mVertices(vertices), mColors(colors) {}
@@ -941,17 +907,17 @@
     }
 
 private:
-    SkBitmap* mBitmap;
+    const SkBitmap* mBitmap;
     int mMeshWidth;
     int mMeshHeight;
-    float* mVertices;
-    int* mColors;
+    const float* mVertices;
+    const int* mColors;
 };
 
 class DrawPatchOp : public DrawBoundedOp {
 public:
-    DrawPatchOp(SkBitmap* bitmap, Res_png_9patch* patch,
-            float left, float top, float right, float bottom, SkPaint* paint)
+    DrawPatchOp(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint),
             mBitmap(bitmap), mPatch(patch), mGenerationId(0), mMesh(NULL),
             mAtlas(Caches::getInstance().assetAtlas) {
@@ -1028,8 +994,8 @@
             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]);
+                        opVertices->x + tx, opVertices->y + ty,
+                        opVertices->u, opVertices->v);
             }
 
             // Dirty the current layer if possible. When the 9-patch does not
@@ -1083,8 +1049,8 @@
     }
 
 private:
-    SkBitmap* mBitmap;
-    Res_png_9patch* mPatch;
+    const SkBitmap* mBitmap;
+    const Res_png_9patch* mPatch;
 
     uint32_t mGenerationId;
     const Patch* mMesh;
@@ -1097,7 +1063,7 @@
 class DrawColorOp : public DrawOp {
 public:
     DrawColorOp(int color, SkXfermode::Mode mode)
-            : DrawOp(0), mColor(color), mMode(mode) {};
+            : DrawOp(NULL), mColor(color), mMode(mode) {};
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         return renderer.drawColor(mColor, mMode);
@@ -1116,7 +1082,7 @@
 
 class DrawStrokableOp : public DrawBoundedOp {
 public:
-    DrawStrokableOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawStrokableOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawBoundedOp(left, top, right, bottom, paint) {};
 
     bool getLocalBounds(const DrawModifiers& drawModifiers, Rect& localBounds) {
@@ -1141,7 +1107,7 @@
 
 class DrawRectOp : public DrawStrokableOp {
 public:
-    DrawRectOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawRectOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1165,7 +1131,7 @@
 
 class DrawRectsOp : public DrawBoundedOp {
 public:
-    DrawRectsOp(const float* rects, int count, SkPaint* paint)
+    DrawRectsOp(const float* rects, int count, const SkPaint* paint)
             : DrawBoundedOp(rects, count, paint),
             mRects(rects), mCount(count) {}
 
@@ -1192,7 +1158,7 @@
 class DrawRoundRectOp : public DrawStrokableOp {
 public:
     DrawRoundRectOp(float left, float top, float right, float bottom,
-            float rx, float ry, SkPaint* paint)
+            float rx, float ry, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint), mRx(rx), mRy(ry) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1213,7 +1179,7 @@
 
 class DrawCircleOp : public DrawStrokableOp {
 public:
-    DrawCircleOp(float x, float y, float radius, SkPaint* paint)
+    DrawCircleOp(float x, float y, float radius, const SkPaint* paint)
             : DrawStrokableOp(x - radius, y - radius, x + radius, y + radius, paint),
             mX(x), mY(y), mRadius(radius) {}
 
@@ -1235,7 +1201,7 @@
 
 class DrawOvalOp : public DrawStrokableOp {
 public:
-    DrawOvalOp(float left, float top, float right, float bottom, SkPaint* paint)
+    DrawOvalOp(float left, float top, float right, float bottom, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1253,7 +1219,7 @@
 class DrawArcOp : public DrawStrokableOp {
 public:
     DrawArcOp(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint)
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint)
             : DrawStrokableOp(left, top, right, bottom, paint),
             mStartAngle(startAngle), mSweepAngle(sweepAngle), mUseCenter(useCenter) {}
 
@@ -1278,7 +1244,7 @@
 
 class DrawPathOp : public DrawBoundedOp {
 public:
-    DrawPathOp(SkPath* path, SkPaint* paint)
+    DrawPathOp(const SkPath* path, const SkPaint* paint)
             : DrawBoundedOp(paint), mPath(path) {
         float left, top, offset;
         uint32_t width, height;
@@ -1294,7 +1260,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
-        SkPaint* paint = getPaint(renderer);
+        const SkPaint* paint = getPaint(renderer);
         renderer.getCaches().pathCache.precache(mPath, paint);
 
         deferInfo.batchId = DeferredDisplayList::kOpBatch_AlphaMaskTexture;
@@ -1307,12 +1273,12 @@
     virtual const char* name() { return "DrawPath"; }
 
 private:
-    SkPath* mPath;
+    const SkPath* mPath;
 };
 
 class DrawLinesOp : public DrawBoundedOp {
 public:
-    DrawLinesOp(float* points, int count, SkPaint* paint)
+    DrawLinesOp(const float* points, int count, const SkPaint* paint)
             : DrawBoundedOp(points, count, paint),
             mPoints(points), mCount(count) {
         mLocalBounds.outset(strokeWidthOutset());
@@ -1336,13 +1302,13 @@
     }
 
 protected:
-    float* mPoints;
+    const float* mPoints;
     int mCount;
 };
 
 class DrawPointsOp : public DrawLinesOp {
 public:
-    DrawPointsOp(float* points, int count, SkPaint* paint)
+    DrawPointsOp(const float* points, int count, const SkPaint* paint)
             : DrawLinesOp(points, count, paint) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
@@ -1358,7 +1324,7 @@
 
 class DrawSomeTextOp : public DrawOp {
 public:
-    DrawSomeTextOp(const char* text, int bytesCount, int count, SkPaint* paint)
+    DrawSomeTextOp(const char* text, int bytesCount, int count, const SkPaint* paint)
             : DrawOp(paint), mText(text), mBytesCount(bytesCount), mCount(count) {};
 
     virtual void output(int level, uint32_t logFlags) const {
@@ -1367,7 +1333,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
-        SkPaint* paint = getPaint(renderer);
+        const SkPaint* paint = getPaint(renderer);
         FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
         fontRenderer.precache(paint, mText, mCount, mat4::identity());
 
@@ -1385,7 +1351,7 @@
 class DrawTextOnPathOp : public DrawSomeTextOp {
 public:
     DrawTextOnPathOp(const char* text, int bytesCount, int count,
-            SkPath* path, float hOffset, float vOffset, SkPaint* paint)
+            const SkPath* path, float hOffset, float vOffset, const SkPaint* paint)
             : DrawSomeTextOp(text, bytesCount, count, paint),
             mPath(path), mHOffset(hOffset), mVOffset(vOffset) {
         /* TODO: inherit from DrawBounded and init mLocalBounds */
@@ -1399,7 +1365,7 @@
     virtual const char* name() { return "DrawTextOnPath"; }
 
 private:
-    SkPath* mPath;
+    const SkPath* mPath;
     float mHOffset;
     float mVOffset;
 };
@@ -1407,7 +1373,7 @@
 class DrawPosTextOp : public DrawSomeTextOp {
 public:
     DrawPosTextOp(const char* text, int bytesCount, int count,
-            const float* positions, SkPaint* paint)
+            const float* positions, const SkPaint* paint)
             : DrawSomeTextOp(text, bytesCount, count, paint), mPositions(positions) {
         /* TODO: inherit from DrawBounded and init mLocalBounds */
     }
@@ -1425,7 +1391,7 @@
 class DrawTextOp : public DrawBoundedOp {
 public:
     DrawTextOp(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds)
+            const float* positions, const 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));
@@ -1433,7 +1399,7 @@
 
     virtual void onDefer(OpenGLRenderer& renderer, DeferInfo& deferInfo,
             const DeferredDisplayState& state) {
-        SkPaint* paint = getPaint(renderer);
+        const SkPaint* paint = getPaint(renderer);
         FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
         const mat4& transform = renderer.findBestFontTransform(state.mMatrix);
         if (mPrecacheTransform != transform) {
@@ -1502,7 +1468,7 @@
 class DrawFunctorOp : public DrawOp {
 public:
     DrawFunctorOp(Functor* functor)
-            : DrawOp(0), mFunctor(functor) {}
+            : DrawOp(NULL), mFunctor(functor) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         renderer.startMark("GL functor");
@@ -1522,20 +1488,21 @@
 };
 
 class DrawDisplayListOp : public DrawBoundedOp {
+    friend class RenderNode; // grant DisplayList access to info of child
 public:
-    DrawDisplayListOp(DisplayList* displayList, int flags)
+    DrawDisplayListOp(RenderNode* displayList, int flags, const mat4& transformFromParent)
             : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0),
-            mDisplayList(displayList), mFlags(flags) {}
+            mDisplayList(displayList), mFlags(flags), mTransformFromParent(transformFromParent) {}
 
     virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level,
             bool useQuickReject) {
-        if (mDisplayList && mDisplayList->isRenderable()) {
+        if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) {
             mDisplayList->defer(deferStruct, level + 1);
         }
     }
     virtual void replay(ReplayStateStruct& replayStruct, int saveCount, int level,
             bool useQuickReject) {
-        if (mDisplayList && mDisplayList->isRenderable()) {
+        if (mDisplayList && mDisplayList->isRenderable() && !mSkipInOrderDraw) {
             mDisplayList->replay(replayStruct, level + 1);
         }
     }
@@ -1555,14 +1522,69 @@
     virtual const char* name() { return "DrawDisplayList"; }
 
 private:
-    DisplayList* mDisplayList;
-    int mFlags;
+    RenderNode* mDisplayList;
+    const int mFlags;
+
+    ///////////////////////////
+    // Properties below are used by DisplayList::computeOrderingImpl() and iterate()
+    ///////////////////////////
+    /**
+     * Records transform vs parent, used for computing total transform without rerunning DL contents
+     */
+    const mat4 mTransformFromParent;
+
+    /**
+     * Holds the transformation between the projection surface ViewGroup and this DisplayList
+     * drawing instance. Represents any translations / transformations done within the drawing of
+     * the compositing ancestor ViewGroup's draw, before the draw of the View represented by this
+     * DisplayList draw instance.
+     *
+     * Note: doesn't include any transformation recorded within the DisplayList and its properties.
+     */
+    mat4 mTransformFromCompositingAncestor;
+    bool mSkipInOrderDraw;
+};
+
+/**
+ * Not a canvas operation, used only by 3d / z ordering logic in DisplayList::iterate()
+ */
+class DrawShadowOp : public DrawOp {
+public:
+    DrawShadowOp(const mat4& transformXY, const mat4& transformZ, float alpha, const SkPath* outline,
+            float fallbackWidth, float fallbackHeight)
+            : DrawOp(NULL), mTransformXY(transformXY), mTransformZ(transformZ),
+            mAlpha(alpha), mOutline(outline),
+            mFallbackWidth(fallbackWidth), mFallbackHeight(fallbackHeight) {}
+
+    virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
+        if (mOutline->isEmpty()) {
+            SkPath fakeOutline;
+            fakeOutline.addRect(0, 0, mFallbackWidth, mFallbackHeight);
+            return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, &fakeOutline);
+        }
+
+        return renderer.drawShadow(mTransformXY, mTransformZ, mAlpha, mOutline);
+    }
+
+    virtual void output(int level, uint32_t logFlags) const {
+        OP_LOG("DrawShadow of outline %p", mOutline);
+    }
+
+    virtual const char* name() { return "DrawShadow"; }
+
+private:
+    const mat4 mTransformXY;
+    const mat4 mTransformZ;
+    const float mAlpha;
+    const SkPath* mOutline;
+    const float mFallbackWidth;
+    const float mFallbackHeight;
 };
 
 class DrawLayerOp : public DrawOp {
 public:
     DrawLayerOp(Layer* layer, float x, float y)
-            : DrawOp(0), mLayer(layer), mX(x), mY(y) {}
+            : DrawOp(NULL), mLayer(layer), mX(x), mY(y) {}
 
     virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty) {
         return renderer.drawLayer(mLayer, mX, mY);
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 8866029..78c97e1 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -21,120 +21,58 @@
 
 #include <private/hwui/DrawGlInfo.h>
 
-#include "DisplayList.h"
+#include "Caches.h"
 #include "DeferredDisplayList.h"
 #include "DisplayListLogBuffer.h"
 #include "DisplayListOp.h"
 #include "DisplayListRenderer.h"
-#include "Caches.h"
+#include "RenderNode.h"
 
 namespace android {
 namespace uirenderer {
 
 DisplayListRenderer::DisplayListRenderer():
-        mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData),
+        mCaches(Caches::getInstance()), mDisplayListData(0),
         mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false),
-        mHasDrawOps(false), mFunctorCount(0) {
+        mRestoreSaveCount(-1) {
 }
 
 DisplayListRenderer::~DisplayListRenderer() {
-    reset();
-}
-
-void DisplayListRenderer::reset() {
-    mDisplayListData = new DisplayListData();
-    mCaches.resourceCache.lock();
-
-    for (size_t i = 0; i < mBitmapResources.size(); i++) {
-        mCaches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
-    }
-
-    for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
-        mCaches.resourceCache.decrementRefcountLocked(mOwnedBitmapResources.itemAt(i));
-    }
-
-    for (size_t i = 0; i < mFilterResources.size(); i++) {
-        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));
-    }
-
-    for (size_t i = 0; i < mSourcePaths.size(); i++) {
-        mCaches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
-    }
-
-    for (size_t i = 0; i < mLayers.size(); i++) {
-        mCaches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i));
-    }
-
-    mCaches.resourceCache.unlock();
-
-    mBitmapResources.clear();
-    mOwnedBitmapResources.clear();
-    mFilterResources.clear();
-    mPatchResources.clear();
-    mSourcePaths.clear();
-
-    mShaders.clear();
-    mShaderMap.clear();
-
-    mPaints.clear();
-    mPaintMap.clear();
-
-    mRegions.clear();
-    mRegionMap.clear();
-
-    mPaths.clear();
-    mPathMap.clear();
-
-    mMatrices.clear();
-
-    mLayers.clear();
-
-    mHasDrawOps = false;
-    mFunctorCount = 0;
+    LOG_ALWAYS_FATAL_IF(mDisplayListData,
+            "Destroyed a DisplayListRenderer during a record!");
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Operations
 ///////////////////////////////////////////////////////////////////////////////
 
-DisplayList* DisplayListRenderer::getDisplayList(DisplayList* displayList) {
-    if (!displayList) {
-        displayList = new DisplayList(*this);
-    } else {
-        displayList->initFromDisplayListRenderer(*this, true);
-    }
-    displayList->setRenderable(mHasDrawOps);
-    return displayList;
-}
-
-bool DisplayListRenderer::isDeferred() {
-    return true;
+DisplayListData* DisplayListRenderer::finishRecording() {
+    mShaderMap.clear();
+    mPaintMap.clear();
+    mRegionMap.clear();
+    mPathMap.clear();
+    DisplayListData* data = mDisplayListData;
+    mDisplayListData = 0;
+    return data;
 }
 
 void DisplayListRenderer::setViewport(int width, int height) {
-    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
+    // TODO: DisplayListRenderer shouldn't have a projection matrix, as it should never be used
+    mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1);
 
-    mWidth = width;
-    mHeight = height;
+    initializeViewport(width, height);
 }
 
 status_t DisplayListRenderer::prepareDirty(float left, float top,
         float right, float bottom, bool opaque) {
-    mSnapshot = new Snapshot(mFirstSnapshot,
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
-    mSaveCount = 1;
 
-    mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
+    LOG_ALWAYS_FATAL_IF(mDisplayListData,
+            "prepareDirty called a second time during a recording!");
+    mDisplayListData = new DisplayListData();
+
+    initializeSaveStack(0, 0, getWidth(), getHeight());
+
     mDirtyClip = opaque;
-
     mRestoreSaveCount = -1;
 
     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
@@ -154,13 +92,13 @@
 status_t DisplayListRenderer::callDrawGLFunction(Functor *functor, Rect& dirty) {
     // Ignore dirty during recording, it matters only when we replay
     addDrawOp(new (alloc()) DrawFunctorOp(functor));
-    mFunctorCount++;
+    mDisplayListData->functorCount++;
     return DrawGlInfo::kStatusDone; // No invalidate needed at record-time
 }
 
 int DisplayListRenderer::save(int flags) {
     addStateOp(new (alloc()) SaveOp(flags));
-    return OpenGLRenderer::save(flags);
+    return StatefulBaseRenderer::save(flags);
 }
 
 void DisplayListRenderer::restore() {
@@ -171,75 +109,77 @@
 
     mRestoreSaveCount--;
     insertTranslate();
-    OpenGLRenderer::restore();
+    StatefulBaseRenderer::restore();
 }
 
 void DisplayListRenderer::restoreToCount(int saveCount) {
     mRestoreSaveCount = saveCount;
     insertTranslate();
-    OpenGLRenderer::restoreToCount(saveCount);
+    StatefulBaseRenderer::restoreToCount(saveCount);
 }
 
 int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
-        int alpha, SkXfermode::Mode mode, int flags) {
-    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, alpha, mode, flags));
-    return OpenGLRenderer::save(flags);
+        const SkPaint* paint, int flags) {
+    paint = refPaint(paint);
+    addStateOp(new (alloc()) SaveLayerOp(left, top, right, bottom, paint, flags));
+    return StatefulBaseRenderer::save(flags);
 }
 
-void DisplayListRenderer::translate(float dx, float dy) {
+void DisplayListRenderer::translate(float dx, float dy, float dz) {
+    // ignore dz, not used at defer time
     mHasTranslate = true;
     mTranslateX += dx;
     mTranslateY += dy;
     insertRestoreToCount();
-    OpenGLRenderer::translate(dx, dy);
+    StatefulBaseRenderer::translate(dx, dy, dz);
 }
 
 void DisplayListRenderer::rotate(float degrees) {
     addStateOp(new (alloc()) RotateOp(degrees));
-    OpenGLRenderer::rotate(degrees);
+    StatefulBaseRenderer::rotate(degrees);
 }
 
 void DisplayListRenderer::scale(float sx, float sy) {
     addStateOp(new (alloc()) ScaleOp(sx, sy));
-    OpenGLRenderer::scale(sx, sy);
+    StatefulBaseRenderer::scale(sx, sy);
 }
 
 void DisplayListRenderer::skew(float sx, float sy) {
     addStateOp(new (alloc()) SkewOp(sx, sy));
-    OpenGLRenderer::skew(sx, sy);
+    StatefulBaseRenderer::skew(sx, sy);
 }
 
-void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
+void DisplayListRenderer::setMatrix(const SkMatrix* matrix) {
     matrix = refMatrix(matrix);
     addStateOp(new (alloc()) SetMatrixOp(matrix));
-    OpenGLRenderer::setMatrix(matrix);
+    StatefulBaseRenderer::setMatrix(matrix);
 }
 
-void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
+void DisplayListRenderer::concatMatrix(const SkMatrix* matrix) {
     matrix = refMatrix(matrix);
     addStateOp(new (alloc()) ConcatMatrixOp(matrix));
-    OpenGLRenderer::concatMatrix(matrix);
+    StatefulBaseRenderer::concatMatrix(matrix);
 }
 
 bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
         SkRegion::Op op) {
     addStateOp(new (alloc()) ClipRectOp(left, top, right, bottom, op));
-    return OpenGLRenderer::clipRect(left, top, right, bottom, op);
+    return StatefulBaseRenderer::clipRect(left, top, right, bottom, op);
 }
 
-bool DisplayListRenderer::clipPath(SkPath* path, SkRegion::Op op) {
+bool DisplayListRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
     path = refPath(path);
     addStateOp(new (alloc()) ClipPathOp(path, op));
-    return OpenGLRenderer::clipPath(path, op);
+    return StatefulBaseRenderer::clipPath(path, op);
 }
 
-bool DisplayListRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
+bool DisplayListRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
     region = refRegion(region);
     addStateOp(new (alloc()) ClipRegionOp(region, op));
-    return OpenGLRenderer::clipRegion(region, op);
+    return StatefulBaseRenderer::clipRegion(region, op);
 }
 
-status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
+status_t DisplayListRenderer::drawDisplayList(RenderNode* displayList,
         Rect& dirty, int32_t flags) {
     // dirty is an out parameter and should not be recorded,
     // it matters only when replaying the display list
@@ -248,7 +188,14 @@
     //       resources cache, but we rely on the caller (UI toolkit) to
     //       do the right thing for now
 
-    addDrawOp(new (alloc()) DrawDisplayListOp(displayList, flags));
+    DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList,
+            flags, *currentTransform());
+    addDrawOp(op);
+    mDisplayListData->children.push(op);
+    if (displayList->isProjectionReceiver()) {
+        mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1;
+    }
+
     return DrawGlInfo::kStatusDone;
 }
 
@@ -258,7 +205,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     paint = refPaint(paint);
 
@@ -266,7 +214,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+        const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     matrix = refMatrix(matrix);
     paint = refPaint(paint);
@@ -275,9 +224,9 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
+status_t DisplayListRenderer::drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
         float srcRight, float srcBottom, float dstLeft, float dstTop,
-        float dstRight, float dstBottom, SkPaint* paint) {
+        float dstRight, float dstBottom, const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     paint = refPaint(paint);
 
@@ -296,8 +245,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top,
-        SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     bitmap = refBitmapData(bitmap);
     paint = refPaint(paint);
 
@@ -305,8 +254,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
-        float* vertices, int* colors, SkPaint* paint) {
+status_t DisplayListRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+        const float* vertices, const int* colors, const SkPaint* paint) {
     int count = (meshWidth + 1) * (meshHeight + 1) * 2;
     bitmap = refBitmap(bitmap);
     vertices = refBuffer<float>(vertices, count);
@@ -318,8 +267,8 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
-        float left, float top, float right, float bottom, SkPaint* paint) {
+status_t DisplayListRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+        float left, float top, float right, float bottom, const SkPaint* paint) {
     bitmap = refBitmap(bitmap);
     patch = refPatch(patch);
     paint = refPaint(paint);
@@ -334,41 +283,41 @@
 }
 
 status_t DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
-        SkPaint* paint) {
+        const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawRectOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
-        float rx, float ry, SkPaint* paint) {
+        float rx, float ry, const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawRoundRectOp(left, top, right, bottom, rx, ry, paint));
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawCircleOp(x, y, radius, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawOval(float left, float top, float right, float bottom,
-        SkPaint* paint) {
+        const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawOvalOp(left, top, right, bottom, paint));
     return DrawGlInfo::kStatusDone;
 }
 
 status_t DisplayListRenderer::drawArc(float left, float top, float right, float bottom,
-        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
+        float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
     paint = refPaint(paint);
     addDrawOp(new (alloc()) DrawArcOp(left, top, right, bottom,
                     startAngle, sweepAngle, useCenter, paint));
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
+status_t DisplayListRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
     path = refPath(path);
     paint = refPaint(paint);
 
@@ -376,7 +325,7 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
     points = refBuffer<float>(points, count);
     paint = refPaint(paint);
 
@@ -384,7 +333,7 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawPoints(float* points, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
     points = refBuffer<float>(points, count);
     paint = refPaint(paint);
 
@@ -393,7 +342,7 @@
 }
 
 status_t DisplayListRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
-        SkPath* path, float hOffset, float vOffset, SkPaint* paint) {
+        const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
 
     text = refText(text, bytesCount);
@@ -407,7 +356,7 @@
 }
 
 status_t DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
-        const float* positions, SkPaint* paint) {
+        const float* positions, const SkPaint* paint) {
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
 
     text = refText(text, bytesCount);
@@ -420,7 +369,7 @@
 }
 
 status_t DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
-        float x, float y, const float* positions, SkPaint* paint,
+        float x, float y, const float* positions, const SkPaint* paint,
         float totalAdvance, const Rect& bounds, DrawOpMode drawOpMode) {
 
     if (!text || count <= 0) return DrawGlInfo::kStatusDone;
@@ -435,7 +384,7 @@
     return DrawGlInfo::kStatusDone;
 }
 
-status_t DisplayListRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
+status_t DisplayListRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
     if (count <= 0) return DrawGlInfo::kStatusDone;
 
     rects = refBuffer<float>(rects, count);
@@ -453,15 +402,6 @@
     addStateOp(new (alloc()) SetupShaderOp(shader));
 }
 
-void DisplayListRenderer::resetColorFilter() {
-    addStateOp(new (alloc()) ResetColorFilterOp());
-}
-
-void DisplayListRenderer::setupColorFilter(SkiaColorFilter* filter) {
-    filter = refColorFilter(filter);
-    addStateOp(new (alloc()) SetupColorFilterOp(filter));
-}
-
 void DisplayListRenderer::resetShadow() {
     addStateOp(new (alloc()) ResetShadowOp());
     OpenGLRenderer::resetShadow();
@@ -506,12 +446,12 @@
 void DisplayListRenderer::addDrawOp(DrawOp* op) {
     Rect localBounds;
     if (op->getLocalBounds(mDrawModifiers, localBounds)) {
-        bool rejected = quickRejectNoScissor(localBounds.left, localBounds.top,
+        bool rejected = quickRejectConservative(localBounds.left, localBounds.top,
                 localBounds.right, localBounds.bottom);
         op->setQuickRejected(rejected);
     }
 
-    mHasDrawOps = true;
+    mDisplayListData->hasDrawOps = true;
     addOpInternal(op);
 }
 
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index d233150..04c5a73 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -22,9 +22,9 @@
 #include <SkPath.h>
 #include <cutils/compiler.h>
 
-#include "DisplayList.h"
 #include "DisplayListLogBuffer.h"
 #include "OpenGLRenderer.h"
+#include "RenderNode.h"
 
 namespace android {
 namespace uirenderer {
@@ -54,143 +54,113 @@
 class StateOp;
 
 /**
- * Records drawing commands in a display list for latter playback.
+ * Records drawing commands in a display list for later playback into an OpenGLRenderer.
  */
 class DisplayListRenderer: public OpenGLRenderer {
 public:
     ANDROID_API DisplayListRenderer();
     virtual ~DisplayListRenderer();
 
-    ANDROID_API DisplayList* getDisplayList(DisplayList* displayList);
+    ANDROID_API DisplayListData* finishRecording();
 
-    virtual bool isDeferred();
+    virtual bool isRecording() const { return true; }
 
+// ----------------------------------------------------------------------------
+// Frame state operations
+// ----------------------------------------------------------------------------
     virtual void setViewport(int width, int height);
     virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
     virtual void finish();
-
-    virtual status_t callDrawGLFunction(Functor *functor, Rect& dirty);
-
     virtual void interrupt();
     virtual void resume();
 
+// ----------------------------------------------------------------------------
+// Canvas state operations
+// ----------------------------------------------------------------------------
+    // Save (layer)
     virtual int save(int flags);
     virtual void restore();
     virtual void restoreToCount(int saveCount);
-
     virtual int saveLayer(float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode, int flags);
+            const SkPaint* paint, int flags);
 
-    virtual void translate(float dx, float dy);
+    // Matrix
+    virtual void translate(float dx, float dy, float dz);
     virtual void rotate(float degrees);
     virtual void scale(float sx, float sy);
     virtual void skew(float sx, float sy);
 
-    virtual void setMatrix(SkMatrix* matrix);
-    virtual void concatMatrix(SkMatrix* matrix);
+    virtual void setMatrix(const SkMatrix* matrix);
+    virtual void concatMatrix(const SkMatrix* matrix);
 
+    // Clip
     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);
+    virtual bool clipPath(const SkPath* path, SkRegion::Op op);
+    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
 
-    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t flags);
-    virtual status_t drawLayer(Layer* layer, float x, float y);
-    virtual status_t drawBitmap(SkBitmap* bitmap, float left, float top, 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,
-            float dstRight, float dstBottom, SkPaint* paint);
-    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, 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);
-    virtual status_t drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, SkPaint* paint);
-    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
-    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
-    virtual status_t drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
-    virtual status_t drawPath(SkPath* path, SkPaint* paint);
-    virtual status_t drawLines(float* points, int count, SkPaint* paint);
-    virtual status_t drawPoints(float* points, int count, SkPaint* paint);
-    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
-            float hOffset, float vOffset, SkPaint* paint);
-    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 totalAdvance, const Rect& bounds,
-            DrawOpMode drawOpMode);
-
-    virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
-
+    // Misc - should be implemented with SkPaint inspection
     virtual void resetShader();
     virtual void setupShader(SkiaShader* shader);
 
-    virtual void resetColorFilter();
-    virtual void setupColorFilter(SkiaColorFilter* filter);
-
     virtual void resetShadow();
     virtual void setupShadow(float radius, float dx, float dy, int color);
 
     virtual void resetPaintFilter();
     virtual void setupPaintFilter(int clearBits, int setBits);
 
-    ANDROID_API void reset();
+// ----------------------------------------------------------------------------
+// Canvas draw operations
+// ----------------------------------------------------------------------------
+    virtual status_t drawColor(int color, SkXfermode::Mode mode);
 
-    sp<DisplayListData> getDisplayListData() const {
-        return mDisplayListData;
-    }
+    // Bitmap-based
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
+            float srcRight, float srcBottom, float dstLeft, float dstTop,
+            float dstRight, float dstBottom, const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint);
+    virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint);
 
-    const Vector<SkBitmap*>& getBitmapResources() const {
-        return mBitmapResources;
-    }
+    // Shapes
+    virtual status_t drawRect(float left, float top, float right, float bottom,
+            const SkPaint* paint);
+    virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
+    virtual status_t drawRoundRect(float left, float top, float right, float bottom,
+            float rx, float ry, const SkPaint* paint);
+    virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
+    virtual status_t drawOval(float left, float top, float right, float bottom,
+            const SkPaint* paint);
+    virtual status_t drawArc(float left, float top, float right, float bottom,
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
+    virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
+    virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
+    virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
 
-    const Vector<SkBitmap*>& getOwnedBitmapResources() const {
-        return mOwnedBitmapResources;
-    }
+    // Text
+    virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
+            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
+            DrawOpMode drawOpMode = kDrawOpMode_Immediate);
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+            float hOffset, float vOffset, const SkPaint* paint);
+    virtual status_t drawPosText(const char* text, int bytesCount, int count,
+            const float* positions, const SkPaint* paint);
 
-    const Vector<SkiaColorFilter*>& getFilterResources() const {
-        return mFilterResources;
-    }
+// ----------------------------------------------------------------------------
+// Canvas draw operations - special
+// ----------------------------------------------------------------------------
+    virtual status_t drawLayer(Layer* layer, float x, float y);
+    virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty,
+            int32_t replayFlags);
 
-    const Vector<Res_png_9patch*>& getPatchResources() const {
-        return mPatchResources;
-    }
-
-    const Vector<SkiaShader*>& getShaders() const {
-        return mShaders;
-    }
-
-    const Vector<SkPaint*>& getPaints() const {
-        return mPaints;
-    }
-
-    const Vector<SkPath*>& getPaths() const {
-        return mPaths;
-    }
-
-    const SortedVector<SkPath*>& getSourcePaths() const {
-        return mSourcePaths;
-    }
-
-    const Vector<SkRegion*>& getRegions() const {
-        return mRegions;
-    }
-
-    const Vector<Layer*>& getLayers() const {
-        return mLayers;
-    }
-
-    const Vector<SkMatrix*>& getMatrices() const {
-        return mMatrices;
-    }
-
-    uint32_t getFunctorCount() const {
-        return mFunctorCount;
-    }
+    // TODO: rename for consistency
+    virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty);
 
 private:
     void insertRestoreToCount();
@@ -206,8 +176,9 @@
     }
 
     template<class T>
-    inline T* refBuffer(const T* srcBuffer, int32_t count) {
-        if (srcBuffer == NULL) return NULL;
+    inline const T* refBuffer(const T* srcBuffer, int32_t count) {
+        if (!srcBuffer) return NULL;
+
         T* dstBuffer = (T*) mDisplayListData->allocator.alloc(count * sizeof(T));
         memcpy(dstBuffer, srcBuffer, count * sizeof(T));
         return dstBuffer;
@@ -217,86 +188,88 @@
         return (char*) refBuffer<uint8_t>((uint8_t*)text, byteLength);
     }
 
-    inline SkPath* refPath(SkPath* path) {
+    inline const SkPath* refPath(const SkPath* path) {
         if (!path) return NULL;
 
-        SkPath* pathCopy = mPathMap.valueFor(path);
+        const SkPath* pathCopy = mPathMap.valueFor(path);
         if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
-            pathCopy = new SkPath(*path);
-            pathCopy->setSourcePath(path);
+            SkPath* newPathCopy = new SkPath(*path);
+            newPathCopy->setSourcePath(path);
+
+            pathCopy = newPathCopy;
             // replaceValueFor() performs an add if the entry doesn't exist
             mPathMap.replaceValueFor(path, pathCopy);
-            mPaths.add(pathCopy);
+            mDisplayListData->paths.add(pathCopy);
         }
-        if (mSourcePaths.indexOf(path) < 0) {
+        if (mDisplayListData->sourcePaths.indexOf(path) < 0) {
             mCaches.resourceCache.incrementRefcount(path);
-            mSourcePaths.add(path);
+            mDisplayListData->sourcePaths.add(path);
         }
         return pathCopy;
     }
 
-    inline SkPaint* refPaint(SkPaint* paint) {
+    inline const SkPaint* refPaint(const SkPaint* paint) {
         if (!paint) {
             return paint;
         }
 
-        SkPaint* paintCopy = mPaintMap.valueFor(paint);
+        const SkPaint* paintCopy = mPaintMap.valueFor(paint);
         if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
             paintCopy = new SkPaint(*paint);
             // replaceValueFor() performs an add if the entry doesn't exist
             mPaintMap.replaceValueFor(paint, paintCopy);
-            mPaints.add(paintCopy);
+            mDisplayListData->paints.add(paintCopy);
         }
 
         return paintCopy;
     }
 
-    inline SkRegion* refRegion(SkRegion* region) {
+    inline const SkRegion* refRegion(const SkRegion* region) {
         if (!region) {
             return region;
         }
 
-        SkRegion* regionCopy = mRegionMap.valueFor(region);
+        const SkRegion* regionCopy = mRegionMap.valueFor(region);
         // TODO: Add generation ID to SkRegion
         if (regionCopy == NULL) {
             regionCopy = new SkRegion(*region);
             // replaceValueFor() performs an add if the entry doesn't exist
             mRegionMap.replaceValueFor(region, regionCopy);
-            mRegions.add(regionCopy);
+            mDisplayListData->regions.add(regionCopy);
         }
 
         return regionCopy;
     }
 
-    inline SkMatrix* refMatrix(SkMatrix* matrix) {
+    inline const SkMatrix* refMatrix(const SkMatrix* matrix) {
         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);
+            const SkMatrix* copy = new SkMatrix(*matrix);
+            mDisplayListData->matrices.add(copy);
             return copy;
         }
         return matrix;
     }
 
     inline Layer* refLayer(Layer* layer) {
-        mLayers.add(layer);
+        mDisplayListData->layers.add(layer);
         mCaches.resourceCache.incrementRefcount(layer);
         return layer;
     }
 
-    inline SkBitmap* refBitmap(SkBitmap* bitmap) {
+    inline const SkBitmap* refBitmap(const SkBitmap* bitmap) {
         // Note that this assumes the bitmap is immutable. There are cases this won't handle
         // correctly, such as creating the bitmap from scratch, drawing with it, changing its
         // contents, and drawing again. The only fix would be to always copy it the first time,
         // which doesn't seem worth the extra cycles for this unlikely case.
-        mBitmapResources.add(bitmap);
+        mDisplayListData->bitmapResources.add(bitmap);
         mCaches.resourceCache.incrementRefcount(bitmap);
         return bitmap;
     }
 
-    inline SkBitmap* refBitmapData(SkBitmap* bitmap) {
-        mOwnedBitmapResources.add(bitmap);
+    inline const SkBitmap* refBitmapData(const SkBitmap* bitmap) {
+        mDisplayListData->ownedBitmapResources.add(bitmap);
         mCaches.resourceCache.incrementRefcount(bitmap);
         return bitmap;
     }
@@ -310,60 +283,33 @@
             shaderCopy = shader->copy();
             // replaceValueFor() performs an add if the entry doesn't exist
             mShaderMap.replaceValueFor(shader, shaderCopy);
-            mShaders.add(shaderCopy);
+            mDisplayListData->shaders.add(shaderCopy);
             mCaches.resourceCache.incrementRefcount(shaderCopy);
         }
         return shaderCopy;
     }
 
-    inline SkiaColorFilter* refColorFilter(SkiaColorFilter* colorFilter) {
-        mFilterResources.add(colorFilter);
-        mCaches.resourceCache.incrementRefcount(colorFilter);
-        return colorFilter;
-    }
-
-    inline Res_png_9patch* refPatch(Res_png_9patch* patch) {
-        mPatchResources.add(patch);
+    inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
+        mDisplayListData->patchResources.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;
-
-    Vector<SkPath*> mPaths;
-    DefaultKeyedVector<SkPath*, SkPath*> mPathMap;
-
-    SortedVector<SkPath*> mSourcePaths;
-
-    Vector<SkRegion*> mRegions;
-    DefaultKeyedVector<SkRegion*, SkRegion*> mRegionMap;
-
-    Vector<SkiaShader*> mShaders;
+    DefaultKeyedVector<const SkPaint*, const SkPaint*> mPaintMap;
+    DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
+    DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
     DefaultKeyedVector<SkiaShader*, SkiaShader*> mShaderMap;
 
-    Vector<SkMatrix*> mMatrices;
-
-    Vector<Layer*> mLayers;
-
-    int mRestoreSaveCount;
-
     Caches& mCaches;
-    sp<DisplayListData> mDisplayListData;
+    DisplayListData* mDisplayListData;
 
     float mTranslateX;
     float mTranslateY;
     bool mHasTranslate;
-    bool mHasDrawOps;
 
-    uint32_t mFunctorCount;
+    int mRestoreSaveCount;
 
-    friend class DisplayList;
+    friend class RenderNode;
 
 }; // class DisplayListRenderer
 
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 0be17ff..b52003c 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -72,18 +72,19 @@
             break;
         }
     }
-    renderer->setupDrawColorFilter();
+    renderer->setupDrawColorFilter(paint->getColorFilter());
     renderer->setupDrawShader();
-    renderer->setupDrawBlending(true, mode);
+    renderer->setupDrawBlending(paint);
     renderer->setupDrawProgram();
-    renderer->setupDrawModelView(x, y, x, y, pureTranslate, true);
+    renderer->setupDrawModelView(kModelViewMode_Translate, false,
+            0.0f, 0.0f, 0.0f, 0.0f, pureTranslate);
     // 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->setupDrawColorFilterUniforms(paint->getColorFilter());
     renderer->setupDrawShaderUniforms(pureTranslate);
     renderer->setupDrawTextGammaUniforms();
 
@@ -497,7 +498,7 @@
                 }
 
                 checkTextureUpdate();
-                caches.bindIndicesBuffer();
+                caches.bindQuadIndicesBuffer();
 
                 if (!mDrawn) {
                     // If returns true, a VBO was bound and we must
@@ -514,8 +515,8 @@
             texture->setLinearFiltering(mLinearFiltering, false);
 
             TextureVertex* mesh = texture->mesh();
-            caches.bindPositionVertexPointer(force, &mesh[0].position[0]);
-            caches.bindTexCoordsVertexPointer(force, &mesh[0].texture[0]);
+            caches.bindPositionVertexPointer(force, &mesh[0].x);
+            caches.bindTexCoordsVertexPointer(force, &mesh[0].u);
             force = false;
 
             glDrawElements(GL_TRIANGLES, texture->meshElementCount(),
@@ -586,11 +587,11 @@
     }
 }
 
-void FontRenderer::setFont(SkPaint* paint, const mat4& matrix) {
+void FontRenderer::setFont(const SkPaint* paint, const mat4& matrix) {
     mCurrentFont = Font::create(this, paint, matrix);
 }
 
-FontRenderer::DropShadow FontRenderer::renderDropShadow(SkPaint* paint, const char *text,
+FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const char *text,
         uint32_t startIndex, uint32_t len, int numGlyphs, uint32_t radius, const float* positions) {
     checkInit();
 
@@ -675,7 +676,8 @@
     issueDrawCommand();
 }
 
-void FontRenderer::precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix) {
+void FontRenderer::precache(const SkPaint* paint, const char* text, int numGlyphs,
+        const mat4& matrix) {
     Font* font = Font::create(this, paint, matrix);
     font->precache(paint, text, numGlyphs);
 }
@@ -684,7 +686,7 @@
     checkTextureUpdate();
 }
 
-bool FontRenderer::renderPosText(SkPaint* paint, const Rect* clip, const char *text,
+bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
         uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
         const float* positions, Rect* bounds, Functor* functor, bool forceFinish) {
     if (!mCurrentFont) {
@@ -702,8 +704,8 @@
     return mDrawn;
 }
 
-bool FontRenderer::renderTextOnPath(SkPaint* paint, const Rect* clip, const char *text,
-        uint32_t startIndex, uint32_t len, int numGlyphs, SkPath* path,
+bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
+        uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path,
         float hOffset, float vOffset, Rect* bounds, Functor* functor) {
     if (!mCurrentFont) {
         ALOGE("No font set");
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index aa7e776..9259028 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -44,8 +44,6 @@
 }
 #endif
 
-class Functor;
-
 namespace android {
 namespace uirenderer {
 
@@ -64,7 +62,7 @@
     };
 
     TextSetupFunctor(OpenGLRenderer* renderer, float x, float y, bool pureTranslate,
-            int alpha, SkXfermode::Mode mode, SkPaint* paint): Functor(),
+            int alpha, SkXfermode::Mode mode, const SkPaint* paint): Functor(),
             renderer(renderer), x(x), y(y), pureTranslate(pureTranslate),
             alpha(alpha), mode(mode), paint(paint) {
     }
@@ -78,7 +76,7 @@
     bool pureTranslate;
     int alpha;
     SkXfermode::Mode mode;
-    SkPaint* paint;
+    const SkPaint* paint;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -97,20 +95,20 @@
         mGammaTable = gammaTable;
     }
 
-    void setFont(SkPaint* paint, const mat4& matrix);
+    void setFont(const SkPaint* paint, const mat4& matrix);
 
-    void precache(SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix);
+    void precache(const SkPaint* paint, const char* text, int numGlyphs, const mat4& matrix);
     void endPrecaching();
 
     // bounds is an out parameter
-    bool renderPosText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
-            uint32_t len, int numGlyphs, int x, int y, const float* positions, Rect* bounds,
-            Functor* functor, bool forceFinish = true);
+    bool renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
+            uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, const float* positions,
+            Rect* bounds, Functor* functor, bool forceFinish = true);
 
     // 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,
-            Functor* functor);
+    bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
+            uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path,
+            float hOffset, float vOffset, Rect* bounds, Functor* functor);
 
     struct DropShadow {
         DropShadow() { };
@@ -130,7 +128,7 @@
 
     // After renderDropShadow returns, the called owns the memory in DropShadow.image
     // and is responsible for releasing it when it's done with it
-    DropShadow renderDropShadow(SkPaint* paint, const char *text, uint32_t startIndex,
+    DropShadow renderDropShadow(const SkPaint* paint, const char *text, uint32_t startIndex,
             uint32_t len, int numGlyphs, uint32_t radius, const float* positions);
 
     void setTextureFiltering(bool linearFiltering) {
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index 0916942..ffd1e8c 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -115,7 +115,7 @@
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
 
-void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) {
+void GradientCache::operator()(GradientCacheEntry&, Texture*& texture) {
     if (texture) {
         const uint32_t size = texture->width * texture->height * bytesPerPixel();
         mSize -= size;
@@ -185,7 +185,7 @@
         mCache.removeOldest();
     }
 
-    generateTexture(colors, positions, count, texture);
+    generateTexture(colors, positions, texture);
 
     mSize += size;
     mCache.put(gradient, texture);
@@ -238,8 +238,7 @@
     dst += 4 * sizeof(float);
 }
 
-void GradientCache::generateTexture(uint32_t* colors, float* positions,
-        int count, Texture* texture) {
+void GradientCache::generateTexture(uint32_t* colors, float* positions, Texture* texture) {
     const uint32_t width = texture->width;
     const GLsizei rowBytes = width * bytesPerPixel();
     uint8_t pixels[rowBytes * texture->height];
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 43934d9..6a783b1 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -151,7 +151,7 @@
     Texture* addLinearGradient(GradientCacheEntry& gradient,
             uint32_t* colors, float* positions, int count);
 
-    void generateTexture(uint32_t* colors, float* positions, int count, Texture* texture);
+    void generateTexture(uint32_t* colors, float* positions, Texture* texture);
 
     struct GradientInfo {
         uint32_t width;
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index bd371a3..bd9bfe9 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -18,12 +18,12 @@
 
 #include <utils/Log.h>
 
-#include "DisplayList.h"
+#include "Caches.h"
 #include "DeferredDisplayList.h"
 #include "Layer.h"
 #include "LayerRenderer.h"
 #include "OpenGLRenderer.h"
-#include "Caches.h"
+#include "RenderNode.h"
 
 namespace android {
 namespace uirenderer {
@@ -46,12 +46,13 @@
     stencil = NULL;
     debugDrawUpdate = false;
     hasDrawnSinceUpdate = false;
+    forceFilter = false;
     deferredList = NULL;
     caches.resourceCache.incrementRefcount(this);
 }
 
 Layer::~Layer() {
-    if (colorFilter) caches.resourceCache.decrementRefcount(colorFilter);
+    SkSafeUnref(colorFilter);
     removeFbo();
     deleteTexture();
 
@@ -131,18 +132,13 @@
     }
 }
 
-void Layer::setPaint(SkPaint* paint) {
+void Layer::setPaint(const SkPaint* paint) {
     OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
+    setColorFilter((paint) ? paint->getColorFilter() : NULL);
 }
 
-void Layer::setColorFilter(SkiaColorFilter* filter) {
-    if (colorFilter) {
-        caches.resourceCache.decrementRefcount(colorFilter);
-    }
-    colorFilter = filter;
-    if (colorFilter) {
-        caches.resourceCache.incrementRefcount(colorFilter);
-    }
+void Layer::setColorFilter(SkColorFilter* filter) {
+    SkRefCnt_SafeAssign(colorFilter, filter);
 }
 
 void Layer::bindTexture() const {
@@ -194,18 +190,17 @@
         dirtyRect.set(0, 0, width, height);
     }
 
-    if (deferredList) {
-        deferredList->reset(dirtyRect);
-    } else {
-        deferredList = new DeferredDisplayList(dirtyRect);
-    }
+    delete deferredList;
+    deferredList = new DeferredDisplayList(dirtyRect);
+
     DeferStateStruct deferredState(*deferredList, *renderer,
-            DisplayList::kReplayFlag_ClipChildren);
+            RenderNode::kReplayFlag_ClipChildren);
 
     renderer->initViewport(width, height);
     renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
             dirtyRect.right, dirtyRect.bottom, !isBlend());
 
+    displayList->computeOrdering();
     displayList->defer(deferredState, 0);
 
     deferredUpdateScheduled = false;
@@ -243,7 +238,7 @@
     renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
             !isBlend());
 
-    renderer->drawDisplayList(displayList, dirtyRect, DisplayList::kReplayFlag_ClipChildren);
+    renderer->drawDisplayList(displayList, dirtyRect, RenderNode::kReplayFlag_ClipChildren);
 
     renderer->finish();
     renderer = NULL;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index b70042f..d8440ea 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HWUI_LAYER_H
 #define ANDROID_HWUI_LAYER_H
 
+#include <cutils/compiler.h>
 #include <sys/types.h>
 
 #include <GLES2/gl2.h>
@@ -26,9 +27,9 @@
 #include <SkPaint.h>
 #include <SkXfermode.h>
 
+#include "Matrix.h"
 #include "Rect.h"
 #include "RenderBuffer.h"
-#include "SkiaColorFilter.h"
 #include "Texture.h"
 #include "Vertex.h"
 
@@ -42,14 +43,15 @@
 // Forward declarations
 class Caches;
 class OpenGLRenderer;
-class DisplayList;
+class RenderNode;
 class DeferredDisplayList;
 class DeferStateStruct;
 
 /**
  * A layer has dimensions and is backed by an OpenGL texture or FBO.
  */
-struct Layer {
+class Layer {
+public:
     Layer(const uint32_t layerWidth, const uint32_t layerHeight);
     ~Layer();
 
@@ -82,7 +84,7 @@
         regionRect.translate(layer.left, layer.top);
     }
 
-    void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
+    void updateDeferred(OpenGLRenderer* renderer, RenderNode* displayList,
             int left, int top, int right, int bottom) {
         this->renderer = renderer;
         this->displayList = displayList;
@@ -115,7 +117,7 @@
         texture.height = height;
     }
 
-    ANDROID_API void setPaint(SkPaint* paint);
+    ANDROID_API void setPaint(const SkPaint* paint);
 
     inline void setBlend(bool blend) {
         texture.blend = blend;
@@ -125,6 +127,14 @@
         return texture.blend;
     }
 
+    inline void setForceFilter(bool forceFilter) {
+        this->forceFilter = forceFilter;
+    }
+
+    inline bool getForceFilter() const {
+        return forceFilter;
+    }
+
     inline void setAlpha(int alpha) {
         this->alpha = alpha;
     }
@@ -216,11 +226,11 @@
         this->textureLayer = textureLayer;
     }
 
-    inline SkiaColorFilter* getColorFilter() const {
+    inline SkColorFilter* getColorFilter() const {
         return colorFilter;
     }
 
-    ANDROID_API void setColorFilter(SkiaColorFilter* filter);
+    ANDROID_API void setColorFilter(SkColorFilter* filter);
 
     void bindStencilRenderBuffer() const;
 
@@ -284,7 +294,7 @@
      */
     bool deferredUpdateScheduled;
     OpenGLRenderer* renderer;
-    DisplayList* displayList;
+    RenderNode* displayList;
     Rect dirtyRect;
     bool debugDrawUpdate;
     bool hasDrawnSinceUpdate;
@@ -338,12 +348,18 @@
     /**
      * Color filter used to draw this layer. Optional.
      */
-    SkiaColorFilter* colorFilter;
+    SkColorFilter* colorFilter;
+
+    /**
+     * Indicates raster data backing the layer is scaled, requiring filtration.
+     */
+    bool forceFilter;
 
     /**
      * Opacity of the layer.
      */
     int alpha;
+
     /**
      * Blending mode of the layer.
      */
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index f8076cc..e0ac2ba 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -92,7 +92,7 @@
     // who will invoke OpenGLRenderer::resume()
 }
 
-GLint LayerRenderer::getTargetFbo() const {
+GLuint LayerRenderer::getTargetFbo() const {
     return mLayer->getFbo();
 }
 
@@ -117,7 +117,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 Region* LayerRenderer::getRegion() const {
-    if (getSnapshot()->flags & Snapshot::kFlagFboTarget) {
+    if (currentSnapshot()->flags & Snapshot::kFlagFboTarget) {
         return OpenGLRenderer::getRegion();
     }
     return &mLayer->region;
@@ -184,7 +184,7 @@
 // Layers management
 ///////////////////////////////////////////////////////////////////////////////
 
-Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque) {
+Layer* LayerRenderer::createRenderLayer(uint32_t width, uint32_t height) {
     LAYER_RENDERER_LOGD("Requesting new render layer %dx%d", width, height);
 
     Caches& caches = Caches::getInstance();
@@ -221,7 +221,6 @@
     layer->texCoords.set(0.0f, height / float(layer->getHeight()),
             width / float(layer->getWidth()), 0.0f);
     layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
-    layer->setBlend(!isOpaque);
     layer->setColorFilter(NULL);
     layer->setDirty(true);
     layer->region.clear();
@@ -270,13 +269,12 @@
     return true;
 }
 
-Layer* LayerRenderer::createTextureLayer(bool isOpaque) {
+Layer* LayerRenderer::createTextureLayer() {
     LAYER_RENDERER_LOGD("Creating new texture layer");
 
     Layer* layer = new Layer(0, 0);
     layer->setCacheable(false);
     layer->setTextureLayer(true);
-    layer->setBlend(!isOpaque);
     layer->setEmpty(true);
     layer->setFbo(0);
     layer->setAlpha(255, SkXfermode::kSrcOver_Mode);
@@ -292,14 +290,15 @@
 }
 
 void LayerRenderer::updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
-        bool isOpaque, GLenum renderTarget, float* transform) {
+        bool isOpaque, bool forceFilter, GLenum renderTarget, float* textureTransform) {
     if (layer) {
         layer->setBlend(!isOpaque);
+        layer->setForceFilter(forceFilter);
         layer->setSize(width, height);
         layer->layer.set(0.0f, 0.0f, width, height);
         layer->region.set(width, height);
         layer->regionRect.set(0.0f, 0.0f, width, height);
-        layer->getTexTransform().load(transform);
+        layer->getTexTransform().load(textureTransform);
 
         if (renderTarget != layer->getRenderTarget()) {
             layer->setRenderTarget(renderTarget);
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 5f86731..40e461a 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -52,11 +52,11 @@
     virtual status_t clear(float left, float top, float right, float bottom, bool opaque);
     virtual void finish();
 
-    ANDROID_API static Layer* createTextureLayer(bool isOpaque);
-    ANDROID_API static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
+    ANDROID_API static Layer* createTextureLayer();
+    ANDROID_API static Layer* createRenderLayer(uint32_t width, uint32_t height);
     ANDROID_API static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
     ANDROID_API static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
-            bool isOpaque, GLenum renderTarget, float* transform);
+            bool isOpaque, bool forceFilter, GLenum renderTarget, float* textureTransform);
     ANDROID_API static void destroyLayer(Layer* layer);
     ANDROID_API static void destroyLayerDeferred(Layer* layer);
     ANDROID_API static bool copyLayer(Layer* layer, SkBitmap* bitmap);
@@ -67,7 +67,7 @@
     virtual void ensureStencilBuffer();
     virtual bool hasLayer() const;
     virtual Region* getRegion() const;
-    virtual GLint getTargetFbo() const;
+    virtual GLuint getTargetFbo() const;
     virtual bool suppressErrorChecks() const;
 
 private:
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index ba22071..f06106b 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -89,8 +89,9 @@
         float m01 = data[kSkewX];
         float m10 = data[kSkewY];
         float m11 = data[kScaleY];
+        float m32 = data[kTranslateZ];
 
-        if (m01 != 0.0f || m10 != 0.0f) {
+        if (m01 != 0.0f || m10 != 0.0f || m32 != 0.0f) {
             mType |= kTypeAffine;
         }
 
@@ -131,11 +132,13 @@
 }
 
 bool Matrix4::isPureTranslate() const {
-    return getGeometryType() <= kTypeTranslate;
+    // NOTE: temporary hack to workaround ignoreTransform behavior with Z values
+    // TODO: separate this into isPure2dTranslate vs isPure3dTranslate
+    return getGeometryType() <= kTypeTranslate && (data[kTranslateZ] == 0.0f);
 }
 
 bool Matrix4::isSimple() const {
-    return getGeometryType() <= (kTypeScale | kTypeTranslate);
+    return getGeometryType() <= (kTypeScale | kTypeTranslate) && (data[kTranslateZ] == 0.0f);
 }
 
 bool Matrix4::isIdentity() const {
@@ -382,6 +385,19 @@
     mType = kTypeTranslate | kTypeScale | kTypeRectToRect;
 }
 
+float Matrix4::mapZ(const Vector3& orig) const {
+    // duplicates logic for mapPoint3d's z coordinate
+    return orig.x * data[2] + orig.y * data[6] + orig.z * data[kScaleZ] + data[kTranslateZ];
+}
+
+void Matrix4::mapPoint3d(Vector3& vec) const {
+    //TODO: optimize simple case
+    const Vector3 orig(vec);
+    vec.x = orig.x * data[kScaleX] + orig.y * data[kSkewX] + orig.z * data[8] + data[kTranslateX];
+    vec.y = orig.x * data[kSkewY] + orig.y * data[kScaleY] + orig.z * data[9] + data[kTranslateY];
+    vec.z = orig.x * data[2] + orig.y * data[6] + orig.z * data[kScaleZ] + data[kTranslateZ];
+}
+
 #define MUL_ADD_STORE(a, b, c) a = (a) * (b) + (c)
 
 void Matrix4::mapPoint(float& x, float& y) const {
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index b861ba4..26cb05f 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -26,12 +26,20 @@
 namespace android {
 namespace uirenderer {
 
-#define MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
-#define MATRIX_ARGS(m) \
+#define SK_MATRIX_STRING "[%.2f %.2f %.2f] [%.2f %.2f %.2f] [%.2f %.2f %.2f]"
+#define SK_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 MATRIX_4_STRING "[%.2f %.2f %.2f %.2f] [%.2f %.2f %.2f %.2f]" \
+    " [%.2f %.2f %.2f %.2f] [%.2f %.2f %.2f %.2f]"
+#define MATRIX_4_ARGS(m) \
+    (m)->data[0], (m)->data[4], (m)->data[8], (m)->data[12], \
+    (m)->data[1], (m)->data[5], (m)->data[9], (m)->data[13], \
+    (m)->data[2], (m)->data[6], (m)->data[10], (m)->data[14], \
+    (m)->data[3], (m)->data[7], (m)->data[11], (m)->data[15] \
+
 ///////////////////////////////////////////////////////////////////////////////
 // Classes
 ///////////////////////////////////////////////////////////////////////////////
@@ -134,17 +142,18 @@
 
     void multiply(float v);
 
-    void translate(float x, float y) {
+    void translate(float x, float y, float z = 0) {
         if ((getType() & sGeometryMask) <= kTypeTranslate) {
             data[kTranslateX] += x;
             data[kTranslateY] += y;
+            data[kTranslateZ] += z;
         } 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);
+            u.loadTranslate(x, y, z);
             multiply(u);
 
             // Restore the type and fix the translate bit
@@ -190,8 +199,10 @@
     void copyTo(float* v) const;
     void copyTo(SkMatrix& v) const;
 
-    void mapRect(Rect& r) const;
-    void mapPoint(float& x, float& y) const;
+    float mapZ(const Vector3& orig) const;
+    void mapPoint3d(Vector3& vec) const;
+    void mapPoint(float& x, float& y) const; // 2d only
+    void mapRect(Rect& r) const; // 2d only
 
     float getTranslateX() const;
     float getTranslateY() const;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 4d76bed..cdd789d 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -36,7 +36,9 @@
 #include "Fence.h"
 #include "PathTessellator.h"
 #include "Properties.h"
+#include "ShadowTessellator.h"
 #include "Vector.h"
+#include "VertexBuffer.h"
 
 namespace android {
 namespace uirenderer {
@@ -50,7 +52,12 @@
 
 #define ALPHA_THRESHOLD 0
 
-#define FILTER(paint) (!paint || paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
+static GLenum getFilter(const SkPaint* paint) {
+    if (!paint || paint->getFilterLevel() != SkPaint::kNone_FilterLevel) {
+        return GL_LINEAR;
+    }
+    return GL_NEAREST;
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 // Globals
@@ -127,7 +134,6 @@
 
     memcpy(mMeshVertices, gMeshVertices, sizeof(gMeshVertices));
 
-    mFirstSnapshot = new Snapshot;
     mFrameStarted = false;
     mCountOverdraw = false;
 
@@ -154,22 +160,6 @@
 // Setup
 ///////////////////////////////////////////////////////////////////////////////
 
-void OpenGLRenderer::setName(const char* name) {
-    if (name) {
-        mName.setTo(name);
-    } else {
-        mName.clear();
-    }
-}
-
-const char* OpenGLRenderer::getName() const {
-    return mName.string();
-}
-
-bool OpenGLRenderer::isDeferred() {
-    return false;
-}
-
 void OpenGLRenderer::setViewport(int width, int height) {
     initViewport(width, height);
 
@@ -180,26 +170,17 @@
 }
 
 void OpenGLRenderer::initViewport(int width, int height) {
-    mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
+    mViewProjMatrix.loadOrtho(0, width, height, 0, -1, 1);
 
-    mWidth = width;
-    mHeight = height;
-
-    mFirstSnapshot->height = height;
-    mFirstSnapshot->viewport.set(0, 0, width, height);
+    initializeViewport(width, height);
 }
 
 void OpenGLRenderer::setupFrameState(float left, float top,
         float right, float bottom, bool opaque) {
     mCaches.clearGarbage();
 
+    initializeSaveStack(left, top, right, bottom);
     mOpaque = opaque;
-    mSnapshot = new Snapshot(mFirstSnapshot,
-            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
-    mSnapshot->fbo = getTargetFbo();
-    mSaveCount = 1;
-
-    mSnapshot->setClip(left, top, right, bottom);
     mTilingClip.set(left, top, right, bottom);
 }
 
@@ -211,14 +192,14 @@
 
     discardFramebuffer(mTilingClip.left, mTilingClip.top, mTilingClip.right, mTilingClip.bottom);
 
-    glViewport(0, 0, mWidth, mHeight);
+    glViewport(0, 0, getWidth(), getHeight());
 
     // Functors break the tiling extension in pretty spectacular ways
     // This ensures we don't use tiling when a functor is going to be
     // invoked during the frame
     mSuppressTiling = mCaches.hasRegisteredFunctors();
 
-    startTiling(mSnapshot, true);
+    startTilingCurrentClip(true);
 
     debugOverdraw(true, true);
 
@@ -226,10 +207,6 @@
             mTilingClip.right, mTilingClip.bottom, mOpaque);
 }
 
-status_t OpenGLRenderer::prepare(bool opaque) {
-    return prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
-}
-
 status_t OpenGLRenderer::prepareDirty(float left, float top,
         float right, float bottom, bool opaque) {
 
@@ -239,7 +216,7 @@
     // The framebuffer renderer will first defer the display list
     // for each layer and wait until the first drawing command
     // to start the frame
-    if (mSnapshot->fbo == 0) {
+    if (currentSnapshot()->fbo == 0) {
         syncState();
         updateLayers();
     } else {
@@ -254,7 +231,7 @@
     // perform a discard to let the driver know we don't need to preserve
     // the back buffer for this frame.
     if (mExtensions.hasDiscardFramebuffer() &&
-            left <= 0.0f && top <= 0.0f && right >= mWidth && bottom >= mHeight) {
+            left <= 0.0f && top <= 0.0f && right >= getWidth() && bottom >= getHeight()) {
         const bool isFbo = getTargetFbo() == 0;
         const GLenum attachments[] = {
                 isFbo ? (const GLenum) GL_COLOR_EXT : (const GLenum) GL_COLOR_ATTACHMENT0,
@@ -266,7 +243,7 @@
 status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) {
     if (!opaque || mCountOverdraw) {
         mCaches.enableScissor();
-        mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
+        mCaches.setScissor(left, currentSnapshot()->height - bottom, right - left, bottom - top);
         glClear(GL_COLOR_BUFFER_BIT);
         return DrawGlInfo::kStatusDrew;
     }
@@ -283,14 +260,16 @@
     }
 }
 
-void OpenGLRenderer::startTiling(const sp<Snapshot>& s, bool opaque) {
+void OpenGLRenderer::startTilingCurrentClip(bool opaque) {
     if (!mSuppressTiling) {
-        Rect* clip = &mTilingClip;
-        if (s->flags & Snapshot::kFlagFboTarget) {
-            clip = &(s->layer->clipRect);
+        const Snapshot* snapshot = currentSnapshot();
+
+        const Rect* clip = &mTilingClip;
+        if (snapshot->flags & Snapshot::kFlagFboTarget) {
+            clip = &(snapshot->layer->clipRect);
         }
 
-        startTiling(*clip, s->height, opaque);
+        startTiling(*clip, snapshot->height, opaque);
     }
 }
 
@@ -369,7 +348,7 @@
 }
 
 void OpenGLRenderer::resume() {
-    sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
+    const Snapshot* snapshot = currentSnapshot();
     glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
     glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
     debugOverdraw(true, false);
@@ -391,7 +370,7 @@
 }
 
 void OpenGLRenderer::resumeAfterLayer() {
-    sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
+    const Snapshot* snapshot = currentSnapshot();
     glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
     glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
     debugOverdraw(true, false);
@@ -447,16 +426,16 @@
 }
 
 status_t OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) {
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
 
     detachFunctor(functor);
 
 
-    Rect clip(*mSnapshot->clipRect);
+    Rect clip(*currentClipRect());
     clip.snapToPixelBoundaries();
 
     // Since we don't know what the functor will draw, let's dirty
-    // tne entire clip region
+    // the entire clip region
     if (hasLayer()) {
         dirtyLayerUnchecked(clip, getRegion());
     }
@@ -467,9 +446,9 @@
     info.clipRight = clip.right;
     info.clipBottom = clip.bottom;
     info.isLayer = hasLayer();
-    info.width = getSnapshot()->viewport.getWidth();
-    info.height = getSnapshot()->height;
-    getSnapshot()->transform->copyTo(&info.transform[0]);
+    info.width = currentSnapshot()->viewport.getWidth();
+    info.height = currentSnapshot()->height;
+    currentTransform()->copyTo(&info.transform[0]);
 
     bool dirtyClip = mDirtyClip;
     // setup GL state for functor
@@ -532,7 +511,7 @@
         const Rect* clip = &mTilingClip;
 
         mCaches.enableScissor();
-        mCaches.setScissor(clip->left, mFirstSnapshot->height - clip->bottom,
+        mCaches.setScissor(clip->left, firstSnapshot()->height - clip->bottom,
                 clip->right - clip->left, clip->bottom - clip->top);
 
         // 1x overdraw
@@ -556,9 +535,9 @@
 }
 
 void OpenGLRenderer::countOverdraw() {
-    size_t count = mWidth * mHeight;
+    size_t count = getWidth() * getHeight();
     uint32_t* buffer = new uint32_t[count];
-    glReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]);
+    glReadPixels(0, 0, getWidth(), getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]);
 
     size_t total = 0;
     for (size_t i = 0; i < count; i++) {
@@ -594,7 +573,7 @@
 
         if (inFrame) {
             resumeAfterLayer();
-            startTiling(mSnapshot);
+            startTilingCurrentClip();
         }
 
         layer->debugDrawUpdate = mCaches.debugLayersUpdates;
@@ -715,50 +694,17 @@
 // State management
 ///////////////////////////////////////////////////////////////////////////////
 
-int OpenGLRenderer::getSaveCount() const {
-    return mSaveCount;
-}
-
-int OpenGLRenderer::save(int flags) {
-    return saveSnapshot(flags);
-}
-
-void OpenGLRenderer::restore() {
-    if (mSaveCount > 1) {
-        restoreSnapshot();
-    }
-}
-
-void OpenGLRenderer::restoreToCount(int saveCount) {
-    if (saveCount < 1) saveCount = 1;
-
-    while (mSaveCount > saveCount) {
-        restoreSnapshot();
-    }
-}
-
-int OpenGLRenderer::saveSnapshot(int flags) {
-    mSnapshot = new Snapshot(mSnapshot, flags);
-    return mSaveCount++;
-}
-
-bool OpenGLRenderer::restoreSnapshot() {
-    bool restoreClip = mSnapshot->flags & Snapshot::kFlagClipSet;
-    bool restoreLayer = mSnapshot->flags & Snapshot::kFlagIsLayer;
-    bool restoreOrtho = mSnapshot->flags & Snapshot::kFlagDirtyOrtho;
-
-    sp<Snapshot> current = mSnapshot;
-    sp<Snapshot> previous = mSnapshot->previous;
+void OpenGLRenderer::onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {
+    bool restoreOrtho = removed.flags & Snapshot::kFlagDirtyOrtho;
+    bool restoreClip = removed.flags & Snapshot::kFlagClipSet;
+    bool restoreLayer = removed.flags & Snapshot::kFlagIsLayer;
 
     if (restoreOrtho) {
-        Rect& r = previous->viewport;
+        const Rect& r = restored.viewport;
         glViewport(r.left, r.top, r.right, r.bottom);
-        mOrthoMatrix.load(current->orthoMatrix);
+        mViewProjMatrix.load(removed.orthoMatrix); // TODO: should ortho be stored in 'restored'?
     }
 
-    mSaveCount--;
-    mSnapshot = previous;
-
     if (restoreClip) {
         dirtyClip();
     }
@@ -766,11 +712,9 @@
     if (restoreLayer) {
         endMark(); // Savelayer
         startMark("ComposeLayer");
-        composeLayer(current, previous);
+        composeLayer(removed, restored);
         endMark();
     }
-
-    return restoreClip;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -778,12 +722,11 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 int OpenGLRenderer::saveLayer(float left, float top, float right, float bottom,
-        int alpha, SkXfermode::Mode mode, int flags) {
-    const GLuint previousFbo = mSnapshot->fbo;
+        const SkPaint* paint, int flags) {
     const int count = saveSnapshot(flags);
 
-    if (!mSnapshot->isIgnored()) {
-        createLayer(left, top, right, bottom, alpha, mode, flags, previousFbo);
+    if (!currentSnapshot()->isIgnored()) {
+        createLayer(left, top, right, bottom, paint, flags);
     }
 
     return count;
@@ -792,22 +735,22 @@
 void OpenGLRenderer::calculateLayerBoundsAndClip(Rect& bounds, Rect& clip, bool fboLayer) {
     const Rect untransformedBounds(bounds);
 
-    currentTransform().mapRect(bounds);
+    currentTransform()->mapRect(bounds);
 
     // Layers only make sense if they are in the framebuffer's bounds
-    if (bounds.intersect(*mSnapshot->clipRect)) {
+    if (bounds.intersect(*currentClipRect())) {
         // We cannot work with sub-pixels in this case
         bounds.snapToPixelBoundaries();
 
         // When the layer is not an FBO, we may use glCopyTexImage so we
         // need to make sure the layer does not extend outside the bounds
         // of the framebuffer
-        if (!bounds.intersect(mSnapshot->previous->viewport)) {
+        if (!bounds.intersect(currentSnapshot()->previous->viewport)) {
             bounds.setEmpty();
         } else if (fboLayer) {
             clip.set(bounds);
             mat4 inverse;
-            inverse.loadInverse(currentTransform());
+            inverse.loadInverse(*currentTransform());
             inverse.mapRect(clip);
             clip.snapToPixelBoundaries();
             if (clip.intersect(untransformedBounds)) {
@@ -834,11 +777,10 @@
 }
 
 int OpenGLRenderer::saveLayerDeferred(float left, float top, float right, float bottom,
-        int alpha, SkXfermode::Mode mode, int flags) {
-    const GLuint previousFbo = mSnapshot->fbo;
+        const SkPaint* paint, int flags) {
     const int count = saveSnapshot(flags);
 
-    if (!mSnapshot->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
+    if (!currentSnapshot()->isIgnored() && (flags & SkCanvas::kClipToLayer_SaveFlag)) {
         // initialize the snapshot as though it almost represents an FBO layer so deferred draw
         // operations will be able to store and restore the current clip and transform info, and
         // quick rejection will be correct (for display lists)
@@ -846,9 +788,9 @@
         Rect bounds(left, top, right, bottom);
         Rect clip;
         calculateLayerBoundsAndClip(bounds, clip, true);
-        updateSnapshotIgnoreForLayer(bounds, clip, true, alpha);
+        updateSnapshotIgnoreForLayer(bounds, clip, true, getAlphaDirect(paint));
 
-        if (!mSnapshot->isIgnored()) {
+        if (!currentSnapshot()->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());
@@ -911,7 +853,7 @@
  *     something actually gets drawn are the layers regions cleared.
  */
 bool OpenGLRenderer::createLayer(float left, float top, float right, float bottom,
-        int alpha, SkXfermode::Mode mode, int flags, GLuint previousFbo) {
+        const SkPaint* paint, int flags) {
     LAYER_LOGD("Requesting layer %.2fx%.2f", right - left, bottom - top);
     LAYER_LOGD("Layer cache size = %d", mCaches.layerCache.getSize());
 
@@ -921,10 +863,10 @@
     Rect clip;
     Rect bounds(left, top, right, bottom);
     calculateLayerBoundsAndClip(bounds, clip, fboLayer);
-    updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, alpha);
+    updateSnapshotIgnoreForLayer(bounds, clip, fboLayer, getAlphaDirect(paint));
 
     // Bail out if we won't draw in this snapshot
-    if (mSnapshot->isIgnored()) {
+    if (currentSnapshot()->isIgnored()) {
         return false;
     }
 
@@ -934,11 +876,11 @@
         return false;
     }
 
-    layer->setAlpha(alpha, mode);
+    layer->setPaint(paint);
     layer->layer.set(bounds);
     layer->texCoords.set(0.0f, bounds.getHeight() / float(layer->getHeight()),
             bounds.getWidth() / float(layer->getWidth()), 0.0f);
-    layer->setColorFilter(mDrawModifiers.mColorFilter);
+
     layer->setBlend(true);
     layer->setDirty(false);
 
@@ -948,7 +890,7 @@
 
     startMark("SaveLayer");
     if (fboLayer) {
-        return createFboLayer(layer, bounds, clip, previousFbo);
+        return createFboLayer(layer, bounds, clip);
     } else {
         // Copy the framebuffer into the layer
         layer->bindTexture();
@@ -974,7 +916,7 @@
     return true;
 }
 
-bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLuint previousFbo) {
+bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) {
     layer->clipRect.set(clip);
     layer->setFbo(mCaches.fboCache.get());
 
@@ -986,7 +928,7 @@
     mSnapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
     mSnapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
     mSnapshot->height = bounds.getHeight();
-    mSnapshot->orthoMatrix.load(mOrthoMatrix);
+    mSnapshot->orthoMatrix.load(mViewProjMatrix);
 
     endTiling();
     debugOverdraw(false, false);
@@ -1003,7 +945,7 @@
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
             layer->getTexture(), 0);
 
-    startTiling(mSnapshot, true);
+    startTilingCurrentClip(true);
 
     // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
     mCaches.enableScissor();
@@ -1015,7 +957,9 @@
 
     // Change the ortho projection
     glViewport(0, 0, bounds.getWidth(), bounds.getHeight());
-    mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f);
+
+    // TODO: determine best way to support 3d drawing within HW layers
+    mViewProjMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f);
 
     return true;
 }
@@ -1023,18 +967,19 @@
 /**
  * Read the documentation of createLayer() before doing anything in this method.
  */
-void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
-    if (!current->layer) {
+void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& restored) {
+    if (!removed.layer) {
         ALOGE("Attempting to compose a layer that does not exist");
         return;
     }
 
-    Layer* layer = current->layer;
+    Layer* layer = removed.layer;
     const Rect& rect = layer->layer;
-    const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;
+    const bool fboLayer = removed.flags & Snapshot::kFlagIsFboLayer;
 
     bool clipRequired = false;
-    quickRejectNoScissor(rect, &clipRequired); // safely ignore return, should never be rejected
+    calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom,
+            &clipRequired, false); // safely ignore return, should never be rejected
     mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
 
     if (fboLayer) {
@@ -1046,15 +991,19 @@
         layer->removeFbo(false);
 
         // Unbind current FBO and restore previous one
-        glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
+        glBindFramebuffer(GL_FRAMEBUFFER, restored.fbo);
         debugOverdraw(true, false);
 
-        startTiling(previous);
+        startTilingCurrentClip();
     }
 
     if (!fboLayer && layer->getAlpha() < 255) {
-        drawColorRect(rect.left, rect.top, rect.right, rect.bottom,
-                layer->getAlpha() << 24, SkXfermode::kDstIn_Mode, true);
+        SkPaint layerPaint;
+        layerPaint.setAlpha(layer->getAlpha());
+        layerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
+        layerPaint.setColorFilter(layer->getColorFilter());
+
+        drawColorRect(rect.left, rect.top, rect.right, rect.bottom, &layerPaint, true);
         // Required below, composeLayerRect() will divide by 255
         layer->setAlpha(255);
     }
@@ -1066,14 +1015,8 @@
     // When the layer is stored in an FBO, we can save a bit of fillrate by
     // drawing only the dirty region
     if (fboLayer) {
-        dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *previous->transform);
-        if (layer->getColorFilter()) {
-            setupColorFilter(layer->getColorFilter());
-        }
+        dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *restored.transform);
         composeLayerRegion(layer, rect);
-        if (layer->getColorFilter()) {
-            resetColorFilter();
-        }
     } else if (!rect.isEmpty()) {
         dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
 
@@ -1105,30 +1048,33 @@
     }
     setupDrawTextureTransform();
     setupDrawColor(alpha, alpha, alpha, alpha);
-    setupDrawColorFilter();
-    setupDrawBlending(layer->isBlend() || alpha < 1.0f, layer->getMode());
+    setupDrawColorFilter(layer->getColorFilter());
+    setupDrawBlending(layer);
     setupDrawProgram();
     setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
+    setupDrawColorFilterUniforms(layer->getColorFilter());
     if (layer->getRenderTarget() == GL_TEXTURE_2D) {
         setupDrawTexture(layer->getTexture());
     } else {
         setupDrawExternalTexture(layer->getTexture());
     }
-    if (currentTransform().isPureTranslate() &&
+    if (currentTransform()->isPureTranslate() &&
+            !layer->getForceFilter() &&
             layer->getWidth() == (uint32_t) rect.getWidth() &&
             layer->getHeight() == (uint32_t) rect.getHeight()) {
-        const float x = (int) floorf(rect.left + currentTransform().getTranslateX() + 0.5f);
-        const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
+        const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
+        const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
 
         layer->setFilter(GL_NEAREST);
-        setupDrawModelView(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
+        setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+                x, y, x + rect.getWidth(), y + rect.getHeight(), true);
     } else {
         layer->setFilter(GL_LINEAR);
-        setupDrawModelView(rect.left, rect.top, rect.right, rect.bottom);
+        setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+                rect.left, rect.top, rect.right, rect.bottom);
     }
     setupDrawTextureTransformUniforms(layer->getTexTransform());
-    setupDrawMesh(&mMeshVertices[0].position[0], &mMeshVertices[0].texture[0]);
+    setupDrawMesh(&mMeshVertices[0].x, &mMeshVertices[0].u);
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
 }
@@ -1141,15 +1087,15 @@
 
         float x = rect.left;
         float y = rect.top;
-        bool simpleTransform = currentTransform().isPureTranslate() &&
+        bool simpleTransform = currentTransform()->isPureTranslate() &&
                 layer->getWidth() == (uint32_t) rect.getWidth() &&
                 layer->getHeight() == (uint32_t) rect.getHeight();
 
         if (simpleTransform) {
             // When we're swapping, the layer is already in screen coordinates
             if (!swap) {
-                x = (int) floorf(rect.left + currentTransform().getTranslateX() + 0.5f);
-                y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
+                x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
+                y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
             }
 
             layer->setFilter(GL_NEAREST, true);
@@ -1157,11 +1103,15 @@
             layer->setFilter(GL_LINEAR, true);
         }
 
-        float alpha = getLayerAlpha(layer);
-        bool blend = layer->isBlend() || alpha < 1.0f;
+        SkPaint layerPaint;
+        layerPaint.setAlpha(getLayerAlpha(layer) * 255);
+        layerPaint.setXfermodeMode(layer->getMode());
+        layerPaint.setColorFilter(layer->getColorFilter());
+
+        bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f;
         drawTextureMesh(x, y, x + rect.getWidth(), y + rect.getHeight(),
-                layer->getTexture(), alpha, layer->getMode(), blend,
-                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
+                layer->getTexture(), &layerPaint, blend,
+                &mMeshVertices[0].x, &mMeshVertices[0].u,
                 GL_TRIANGLE_STRIP, gMeshCount, swap, swap || simpleTransform);
 
         resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
@@ -1225,24 +1175,26 @@
 
         setupDrawWithTexture();
         setupDrawColor(alpha, alpha, alpha, alpha);
-        setupDrawColorFilter();
-        setupDrawBlending(layer->isBlend() || alpha < 1.0f, layer->getMode(), false);
+        setupDrawColorFilter(layer->getColorFilter());
+        setupDrawBlending(layer);
         setupDrawProgram();
         setupDrawDirtyRegionsDisabled();
         setupDrawPureColorUniforms();
-        setupDrawColorFilterUniforms();
+        setupDrawColorFilterUniforms(layer->getColorFilter());
         setupDrawTexture(layer->getTexture());
-        if (currentTransform().isPureTranslate()) {
-            const float x = (int) floorf(rect.left + currentTransform().getTranslateX() + 0.5f);
-            const float y = (int) floorf(rect.top + currentTransform().getTranslateY() + 0.5f);
+        if (currentTransform()->isPureTranslate()) {
+            const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
+            const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
 
             layer->setFilter(GL_NEAREST);
-            setupDrawModelViewTranslate(x, y, x + rect.getWidth(), y + rect.getHeight(), true);
+            setupDrawModelView(kModelViewMode_Translate, false,
+                    x, y, x + rect.getWidth(), y + rect.getHeight(), true);
         } else {
             layer->setFilter(GL_LINEAR);
-            setupDrawModelViewTranslate(rect.left, rect.top, rect.right, rect.bottom);
+            setupDrawModelView(kModelViewMode_Translate, false,
+                    rect.left, rect.top, rect.right, rect.bottom);
         }
-        setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
+        setupDrawMeshIndices(&mesh[0].x, &mesh[0].u);
 
         for (size_t i = 0; i < count; i++) {
             const android::Rect* r = &rects[i];
@@ -1274,15 +1226,15 @@
         }
 
 #if DEBUG_LAYERS_AS_REGIONS
-        drawRegionRects(layer->region);
+        drawRegionRectsDebug(layer->region);
 #endif
 
         layer->region.clear();
     }
 }
 
-void OpenGLRenderer::drawRegionRects(const Region& region) {
 #if DEBUG_LAYERS_AS_REGIONS
+void OpenGLRenderer::drawRegionRectsDebug(const Region& region) {
     size_t count;
     const android::Rect* rects = region.getArray(&count);
 
@@ -1300,15 +1252,15 @@
             top = rects[i].top;
         }
 
+        SkPaint paint;
+        paint.setColor(colors[offset + (i & 0x1)]);
         Rect r(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
-        drawColorRect(r.left, r.top, r.right, r.bottom, colors[offset + (i & 0x1)],
-                SkXfermode::kSrcOver_Mode);
+        drawColorRect(r.left, r.top, r.right, r.bottom, paint);
     }
-#endif
 }
+#endif
 
-void OpenGLRenderer::drawRegionRects(const SkRegion& region, int color,
-        SkXfermode::Mode mode, bool dirty) {
+void OpenGLRenderer::drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty) {
     Vector<float> rects;
 
     SkRegion::Iterator it(region);
@@ -1321,7 +1273,7 @@
         it.next();
     }
 
-    drawColorRects(rects.array(), rects.size(), color, mode, true, dirty, false);
+    drawColorRects(rects.array(), rects.size(), &paint, true, dirty, false);
 }
 
 void OpenGLRenderer::dirtyLayer(const float left, const float top,
@@ -1342,7 +1294,7 @@
 }
 
 void OpenGLRenderer::dirtyLayerUnchecked(Rect& bounds, Region* region) {
-    if (bounds.intersect(*mSnapshot->clipRect)) {
+    if (bounds.intersect(*currentClipRect())) {
         bounds.snapToPixelBoundaries();
         android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
         if (!dirty.isEmpty()) {
@@ -1351,12 +1303,12 @@
     }
 }
 
-void OpenGLRenderer::drawIndexedQuads(Vertex* mesh, GLsizei quadsCount) {
+void OpenGLRenderer::issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount) {
     GLsizei elementsCount = quadsCount * 6;
     while (elementsCount > 0) {
         GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
 
-        setupDrawIndexedVertices(&mesh[0].position[0]);
+        setupDrawIndexedVertices(&mesh[0].x);
         glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL);
 
         elementsCount -= drawCount;
@@ -1370,7 +1322,7 @@
     const size_t count = mLayers.size();
     if (count == 0) return;
 
-    if (!mSnapshot->isIgnored()) {
+    if (!currentSnapshot()->isIgnored()) {
         // Doing several glScissor/glClear here can negatively impact
         // GPUs with a tiler architecture, instead we draw quads with
         // the Clear blending mode
@@ -1398,14 +1350,18 @@
         // the same thing again
         mLayers.clear();
 
+        SkPaint clearPaint;
+        clearPaint.setXfermodeMode(SkXfermode::kClear_Mode);
+
         setupDraw(false);
         setupDrawColor(0.0f, 0.0f, 0.0f, 1.0f);
-        setupDrawBlending(true, SkXfermode::kClear_Mode);
+        setupDrawBlending(&clearPaint, true);
         setupDrawProgram();
         setupDrawPureColorUniforms();
-        setupDrawModelViewTranslate(0.0f, 0.0f, 0.0f, 0.0f, true);
+        setupDrawModelView(kModelViewMode_Translate, false,
+                0.0f, 0.0f, 0.0f, 0.0f, true);
 
-        drawIndexedQuads(&mesh[0], count);
+        issueIndexedQuadDraw(&mesh[0], count);
 
         if (scissorChanged) mCaches.enableScissor();
     } else {
@@ -1421,58 +1377,58 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool OpenGLRenderer::storeDisplayState(DeferredDisplayState& state, int stateDeferFlags) {
-    const Rect& currentClip = *(mSnapshot->clipRect);
-    const mat4& currentMatrix = *(mSnapshot->transform);
+    const Rect* currentClip = currentClipRect();
+    const mat4* currentMatrix = currentTransform();
 
     if (stateDeferFlags & kStateDeferFlag_Draw) {
         // state has bounds initialized in local coordinates
         if (!state.mBounds.isEmpty()) {
-            currentMatrix.mapRect(state.mBounds);
+            currentMatrix->mapRect(state.mBounds);
             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)) {
+            if(!clippedBounds.intersect(*currentClip)) {
                 // quick rejected
                 return true;
             }
 
             state.mClipSideFlags = kClipSide_None;
-            if (!currentClip.contains(state.mBounds)) {
+            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;
+                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);
+            state.mBounds.set(*currentClip);
         }
     }
 
     state.mClipValid = (stateDeferFlags & kStateDeferFlag_Clip);
     if (state.mClipValid) {
-        state.mClip.set(currentClip);
+        state.mClip.set(*currentClip);
     }
 
     // Transform, drawModifiers, and alpha always deferred, since they are used by state operations
     // (Note: saveLayer/restore use colorFilter and alpha, so we just save restore everything)
-    state.mMatrix.load(currentMatrix);
+    state.mMatrix.load(*currentMatrix);
     state.mDrawModifiers = mDrawModifiers;
-    state.mAlpha = mSnapshot->alpha;
+    state.mAlpha = currentSnapshot()->alpha;
     return false;
 }
 
 void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) {
-    currentTransform().load(state.mMatrix);
-    mDrawModifiers = state.mDrawModifiers;
+    setMatrix(state.mMatrix);
     mSnapshot->alpha = state.mAlpha;
+    mDrawModifiers = state.mDrawModifiers;
 
     if (state.mClipValid && !skipClipRestore) {
         mSnapshot->setClip(state.mClip.left, state.mClip.top,
@@ -1492,64 +1448,21 @@
     if (clipRect != NULL) {
         mSnapshot->setClip(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom);
     } else {
-        mSnapshot->setClip(0, 0, mWidth, mHeight);
+        mSnapshot->setClip(0, 0, getWidth(), getHeight());
     }
     dirtyClip();
     mCaches.setScissorEnabled(clipRect != NULL || mScissorOptimizationDisabled);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// Transforms
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::translate(float dx, float dy) {
-    currentTransform().translate(dx, dy);
-}
-
-void OpenGLRenderer::rotate(float degrees) {
-    currentTransform().rotate(degrees, 0.0f, 0.0f, 1.0f);
-}
-
-void OpenGLRenderer::scale(float sx, float sy) {
-    currentTransform().scale(sx, sy, 1.0f);
-}
-
-void OpenGLRenderer::skew(float sx, float sy) {
-    currentTransform().skew(sx, sy);
-}
-
-void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
-    if (matrix) {
-        currentTransform().load(*matrix);
-    } else {
-        currentTransform().loadIdentity();
-    }
-}
-
-bool OpenGLRenderer::hasRectToRectTransform() {
-    return CC_LIKELY(currentTransform().rectToRect());
-}
-
-void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
-    currentTransform().copyTo(*matrix);
-}
-
-void OpenGLRenderer::concatMatrix(SkMatrix* matrix) {
-    SkMatrix transform;
-    currentTransform().copyTo(transform);
-    transform.preConcat(*matrix);
-    currentTransform().load(transform);
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // Clipping
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::setScissorFromClip() {
-    Rect clip(*mSnapshot->clipRect);
+    Rect clip(*currentClipRect());
     clip.snapToPixelBoundaries();
 
-    if (mCaches.setScissor(clip.left, mSnapshot->height - clip.bottom,
+    if (mCaches.setScissor(clip.left, currentSnapshot()->height - clip.bottom,
             clip.getWidth(), clip.getHeight())) {
         mDirtyClip = false;
     }
@@ -1560,7 +1473,7 @@
     // cannot attach a stencil buffer to fbo0 dynamically. Let's
     // just hope we have one when hasLayer() returns false.
     if (hasLayer()) {
-        attachStencilBufferToLayer(mSnapshot->layer);
+        attachStencilBufferToLayer(currentSnapshot()->layer);
     }
 }
 
@@ -1582,7 +1495,7 @@
 
 void OpenGLRenderer::setStencilFromClip() {
     if (!mCaches.debugOverdraw) {
-        if (!mSnapshot->clipRegion->isEmpty()) {
+        if (!currentSnapshot()->clipRegion->isEmpty()) {
             // NOTE: The order here is important, we must set dirtyClip to false
             //       before any draw call to avoid calling back into this method
             mDirtyClip = false;
@@ -1601,20 +1514,26 @@
             mCaches.stencil.clear();
             if (resetScissor) mCaches.disableScissor();
 
+            SkPaint paint;
+            paint.setColor(0xff000000);
+            paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+
             // NOTE: We could use the region contour path to generate a smaller mesh
             //       Since we are using the stencil we could use the red book path
             //       drawing technique. It might increase bandwidth usage though.
 
             // The last parameter is important: we are not drawing in the color buffer
             // so we don't want to dirty the current layer, if any
-            drawRegionRects(*mSnapshot->clipRegion, 0xff000000, SkXfermode::kSrc_Mode, false);
+            drawRegionRects(*(currentSnapshot()->clipRegion), paint, false);
 
             mCaches.stencil.enableTest();
 
             // Draw the region used to generate the stencil if the appropriate debug
             // mode is enabled
             if (mCaches.debugStencilClip == Caches::kStencilShowRegion) {
-                drawRegionRects(*mSnapshot->clipRegion, 0x7f0000ff, SkXfermode::kSrcOver_Mode);
+                paint.setColor(0x7f0000ff);
+                paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
+                drawRegionRects(*(currentSnapshot()->clipRegion), paint);
             }
         } else {
             mCaches.stencil.disable();
@@ -1622,50 +1541,31 @@
     }
 }
 
-const Rect& OpenGLRenderer::getClipBounds() {
-    return mSnapshot->getLocalClip();
-}
-
-bool OpenGLRenderer::quickRejectNoScissor(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.snapGeometryToPixelBoundaries(snapOut);
-
-    Rect clipRect(*mSnapshot->clipRect);
-    clipRect.snapToPixelBoundaries();
-
-    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) {
+/**
+ * Returns false and sets scissor enable based upon bounds if drawing won't be clipped out.
+ *
+ * @param paint if not null, the bounds will be expanded to account for stroke depending on paint
+ *         style, and tessellated AA ramp
+ */
+bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, float bottom,
+        const SkPaint* paint) {
     bool clipRequired = false;
-    if (quickRejectNoScissor(left, top, right, bottom, snapOut, &clipRequired)) {
+    bool snapOut = paint && paint->isAntiAlias();
+
+    if (paint && paint->getStyle() != SkPaint::kFill_Style) {
+        float outset = paint->getStrokeWidth() * 0.5f;
+        left -= outset;
+        top -= outset;
+        right += outset;
+        bottom += outset;
+    }
+
+    if (calculateQuickRejectForScissor(left, top, right, bottom, &clipRequired, snapOut)) {
         return true;
     }
 
-    if (!isDeferred()) {
+    if (!isRecording()) {
+        // not quick rejected, so enable the scissor if clipRequired
         mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired);
     }
     return false;
@@ -1673,74 +1573,21 @@
 
 void OpenGLRenderer::debugClip() {
 #if DEBUG_CLIP_REGIONS
-    if (!isDeferred() && !mSnapshot->clipRegion->isEmpty()) {
-        drawRegionRects(*mSnapshot->clipRegion, 0x7f00ff00, SkXfermode::kSrcOver_Mode);
+    if (!isRecording() && !currentSnapshot()->clipRegion->isEmpty()) {
+        SkPaint paint;
+        paint.setColor(0x7f00ff00);
+        drawRegionRects(*(currentSnapshot()->clipRegion, paint);
+
     }
 #endif
 }
 
-bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
-    if (CC_LIKELY(currentTransform().rectToRect())) {
-        bool clipped = mSnapshot->clip(left, top, right, bottom, op);
-        if (clipped) {
-            dirtyClip();
-        }
-        return !mSnapshot->clipRect->isEmpty();
-    }
-
-    SkPath path;
-    path.addRect(left, top, right, bottom);
-
-    return OpenGLRenderer::clipPath(&path, op);
-}
-
-bool OpenGLRenderer::clipPath(SkPath* path, SkRegion::Op op) {
-    SkMatrix transform;
-    currentTransform().copyTo(transform);
-
-    SkPath transformed;
-    path->transform(transform, &transformed);
-
-    SkRegion clip;
-    if (!mSnapshot->previous->clipRegion->isEmpty()) {
-        clip.setRegion(*mSnapshot->previous->clipRegion);
-    } else {
-        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;
-    region.setPath(transformed, clip);
-
-    bool clipped = mSnapshot->clipRegionTransformed(region, op);
-    if (clipped) {
-        dirtyClip();
-    }
-    return !mSnapshot->clipRect->isEmpty();
-}
-
-bool OpenGLRenderer::clipRegion(SkRegion* region, SkRegion::Op op) {
-    bool clipped = mSnapshot->clipRegionTransformed(*region, op);
-    if (clipped) {
-        dirtyClip();
-    }
-    return !mSnapshot->clipRect->isEmpty();
-}
-
-Rect* OpenGLRenderer::getClipRect() {
-    return mSnapshot->clipRect;
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // Drawing commands
 ///////////////////////////////////////////////////////////////////////////////
 
 void OpenGLRenderer::setupDraw(bool clear) {
-    // TODO: It would be best if we could do this before quickReject()
+    // TODO: It would be best if we could do this before quickRejectSetupScissor()
     //       changes the scissor test state
     if (clear) clearLayerRegions();
     // Make sure setScissor & setStencil happen at the beginning of
@@ -1798,7 +1645,7 @@
     mColorG = mColorA * ((color >>  8) & 0xFF) / 255.0f;
     mColorB = mColorA * ((color      ) & 0xFF) / 255.0f;
     mColorSet = true;
-    mSetShaderColor = mDescription.setColor(mColorR, mColorG, mColorB, mColorA);
+    mSetShaderColor = mDescription.setColorModulate(mColorA);
 }
 
 void OpenGLRenderer::setupDrawAlpha8Color(int color, int alpha) {
@@ -1807,7 +1654,7 @@
     mColorG = mColorA * ((color >>  8) & 0xFF) / 255.0f;
     mColorB = mColorA * ((color      ) & 0xFF) / 255.0f;
     mColorSet = true;
-    mSetShaderColor = mDescription.setAlpha8Color(mColorR, mColorG, mColorB, mColorA);
+    mSetShaderColor = mDescription.setAlpha8ColorModulate(mColorR, mColorG, mColorB, mColorA);
 }
 
 void OpenGLRenderer::setupDrawTextGamma(const SkPaint* paint) {
@@ -1820,7 +1667,7 @@
     mColorG = g;
     mColorB = b;
     mColorSet = true;
-    mSetShaderColor = mDescription.setColor(r, g, b, a);
+    mSetShaderColor = mDescription.setColorModulate(a);
 }
 
 void OpenGLRenderer::setupDrawShader() {
@@ -1829,9 +1676,17 @@
     }
 }
 
-void OpenGLRenderer::setupDrawColorFilter() {
-    if (mDrawModifiers.mColorFilter) {
-        mDrawModifiers.mColorFilter->describe(mDescription, mExtensions);
+void OpenGLRenderer::setupDrawColorFilter(const SkColorFilter* filter) {
+    if (filter == NULL) {
+        return;
+    }
+
+    SkXfermode::Mode mode;
+    if (filter->asColorMode(NULL, &mode)) {
+        mDescription.colorOp = ProgramDescription::kColorBlend;
+        mDescription.colorMode = mode;
+    } else if (filter->asColorMatrix(NULL)) {
+        mDescription.colorOp = ProgramDescription::kColorMatrix;
     }
 }
 
@@ -1843,22 +1698,26 @@
     }
 }
 
-void OpenGLRenderer::setupDrawBlending(SkXfermode::Mode mode, bool swapSrcDst) {
+void OpenGLRenderer::setupDrawBlending(const Layer* layer, bool swapSrcDst) {
+    SkXfermode::Mode mode = layer->getMode();
     // When the blending mode is kClear_Mode, we need to use a modulate color
     // argb=1,0,0,0
     accountForClear(mode);
-    bool blend = (mColorSet && mColorA < 1.0f) ||
-            (mDrawModifiers.mShader && mDrawModifiers.mShader->blend());
+    bool blend = layer->isBlend() || getLayerAlpha(layer) < 1.0f ||
+            (mColorSet && mColorA < 1.0f) ||
+            (mDrawModifiers.mShader && mDrawModifiers.mShader->blend()) ||
+            layer->getColorFilter();
     chooseBlending(blend, mode, mDescription, swapSrcDst);
 }
 
-void OpenGLRenderer::setupDrawBlending(bool blend, SkXfermode::Mode mode, bool swapSrcDst) {
+void OpenGLRenderer::setupDrawBlending(const SkPaint* paint, bool blend, bool swapSrcDst) {
+    SkXfermode::Mode mode = getXfermodeDirect(paint);
     // When the blending mode is kClear_Mode, we need to use a modulate color
     // argb=1,0,0,0
     accountForClear(mode);
     blend |= (mColorSet && mColorA < 1.0f) ||
             (mDrawModifiers.mShader && mDrawModifiers.mShader->blend()) ||
-            (mDrawModifiers.mColorFilter && mDrawModifiers.mColorFilter->blend());
+            (paint && paint->getColorFilter());
     chooseBlending(blend, mode, mDescription, swapSrcDst);
 }
 
@@ -1870,39 +1729,20 @@
     mTrackDirtyRegions = false;
 }
 
-void OpenGLRenderer::setupDrawModelViewTranslate(float left, float top, float right, float bottom,
-        bool ignoreTransform) {
+void OpenGLRenderer::setupDrawModelView(ModelViewMode mode, bool offset,
+        float left, float top, float right, float bottom, bool ignoreTransform) {
     mModelView.loadTranslate(left, top, 0.0f);
-    if (!ignoreTransform) {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform());
-        if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, currentTransform());
-    } else {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity());
-        if (mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
-    }
-}
-
-void OpenGLRenderer::setupDrawModelViewIdentity(bool offset) {
-    mCaches.currentProgram->set(mOrthoMatrix, mat4::identity(), currentTransform(), offset);
-}
-
-void OpenGLRenderer::setupDrawModelView(float left, float top, float right, float bottom,
-        bool ignoreTransform, bool ignoreModelView) {
-    if (!ignoreModelView) {
-        mModelView.loadTranslate(left, top, 0.0f);
+    if (mode == kModelViewMode_TranslateAndScale) {
         mModelView.scale(right - left, bottom - top, 1.0f);
-    } else {
-        mModelView.loadIdentity();
     }
+
     bool dirty = right - left > 0.0f && bottom - top > 0.0f;
     if (!ignoreTransform) {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, currentTransform());
-        if (mTrackDirtyRegions && dirty) {
-            dirtyLayer(left, top, right, bottom, currentTransform());
-        }
+        mCaches.currentProgram->set(mViewProjMatrix, mModelView, *currentTransform(), offset);
+        if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom, *currentTransform());
     } else {
-        mCaches.currentProgram->set(mOrthoMatrix, mModelView, mat4::identity());
-        if (mTrackDirtyRegions && dirty) dirtyLayer(left, top, right, bottom);
+        mCaches.currentProgram->set(mViewProjMatrix, mModelView, mat4::identity(), offset);
+        if (dirty && mTrackDirtyRegions) dirtyLayer(left, top, right, bottom);
     }
 }
 
@@ -1921,24 +1761,60 @@
 void OpenGLRenderer::setupDrawShaderUniforms(bool ignoreTransform) {
     if (mDrawModifiers.mShader) {
         if (ignoreTransform) {
-            mModelView.loadInverse(currentTransform());
+            // if ignoreTransform=true was passed to setupDrawModelView, undo currentTransform()
+            // because it was built into modelView / the geometry, and the SkiaShader needs to
+            // compensate.
+            mat4 modelViewWithoutTransform;
+            modelViewWithoutTransform.loadInverse(*currentTransform());
+            modelViewWithoutTransform.multiply(mModelView);
+            mModelView.load(modelViewWithoutTransform);
         }
         mDrawModifiers.mShader->setupProgram(mCaches.currentProgram,
                 mModelView, *mSnapshot, &mTextureUnit);
     }
 }
 
-void OpenGLRenderer::setupDrawShaderIdentityUniforms() {
-    if (mDrawModifiers.mShader) {
-        mDrawModifiers.mShader->setupProgram(mCaches.currentProgram,
-                mat4::identity(), *mSnapshot, &mTextureUnit);
+void OpenGLRenderer::setupDrawColorFilterUniforms(const SkColorFilter* filter) {
+    if (NULL == filter) {
+        return;
     }
-}
 
-void OpenGLRenderer::setupDrawColorFilterUniforms() {
-    if (mDrawModifiers.mColorFilter) {
-        mDrawModifiers.mColorFilter->setupProgram(mCaches.currentProgram);
+    SkColor color;
+    SkXfermode::Mode mode;
+    if (filter->asColorMode(&color, &mode)) {
+        const int alpha = SkColorGetA(color);
+        const GLfloat a = alpha / 255.0f;
+        const GLfloat r = a * SkColorGetR(color) / 255.0f;
+        const GLfloat g = a * SkColorGetG(color) / 255.0f;
+        const GLfloat b = a * SkColorGetB(color) / 255.0f;
+        glUniform4f(mCaches.currentProgram->getUniform("colorBlend"), r, g, b, a);
+        return;
     }
+
+    SkScalar srcColorMatrix[20];
+    if (filter->asColorMatrix(srcColorMatrix)) {
+
+        float colorMatrix[16];
+        memcpy(colorMatrix, srcColorMatrix, 4 * sizeof(float));
+        memcpy(&colorMatrix[4], &srcColorMatrix[5], 4 * sizeof(float));
+        memcpy(&colorMatrix[8], &srcColorMatrix[10], 4 * sizeof(float));
+        memcpy(&colorMatrix[12], &srcColorMatrix[15], 4 * sizeof(float));
+
+        // Skia uses the range [0..255] for the addition vector, but we need
+        // the [0..1] range to apply the vector in GLSL
+        float colorVector[4];
+        colorVector[0] = srcColorMatrix[4] / 255.0f;
+        colorVector[1] = srcColorMatrix[9] / 255.0f;
+        colorVector[2] = srcColorMatrix[14] / 255.0f;
+        colorVector[3] = srcColorMatrix[19] / 255.0f;
+
+        glUniformMatrix4fv(mCaches.currentProgram->getUniform("colorMatrix"), 1,
+                GL_FALSE, colorMatrix);
+        glUniform4fv(mCaches.currentProgram->getUniform("colorMatrixVector"), 1, colorVector);
+        return;
+    }
+
+    // it is an error if we ever get here
 }
 
 void OpenGLRenderer::setupDrawTextGammaUniforms() {
@@ -1972,7 +1848,8 @@
             GL_FALSE, &transform.data[0]);
 }
 
-void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
+void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices,
+        const GLvoid* texCoords, GLuint vbo) {
     bool force = false;
     if (!vertices || vbo) {
         force = mCaches.bindMeshBuffer(vbo == 0 ? mCaches.meshBuffer : vbo);
@@ -1988,7 +1865,8 @@
     mCaches.unbindIndicesBuffer();
 }
 
-void OpenGLRenderer::setupDrawMesh(GLvoid* vertices, GLvoid* texCoords, GLvoid* colors) {
+void OpenGLRenderer::setupDrawMesh(const GLvoid* vertices,
+        const GLvoid* texCoords, const GLvoid* colors) {
     bool force = mCaches.unbindMeshBuffer();
     GLsizei stride = sizeof(ColorTextureVertex);
 
@@ -2005,7 +1883,8 @@
     mCaches.unbindIndicesBuffer();
 }
 
-void OpenGLRenderer::setupDrawMeshIndices(GLvoid* vertices, GLvoid* texCoords, GLuint vbo) {
+void OpenGLRenderer::setupDrawMeshIndices(const GLvoid* vertices,
+        const 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
@@ -2015,7 +1894,7 @@
     } else {
         force = mCaches.unbindMeshBuffer();
     }
-    mCaches.bindIndicesBuffer();
+    mCaches.bindQuadIndicesBuffer();
 
     mCaches.bindPositionVertexPointer(force, vertices);
     if (mCaches.currentProgram->texCoords >= 0) {
@@ -2025,7 +1904,7 @@
 
 void OpenGLRenderer::setupDrawIndexedVertices(GLvoid* vertices) {
     bool force = mCaches.unbindMeshBuffer();
-    mCaches.bindIndicesBuffer();
+    mCaches.bindQuadIndicesBuffer();
     mCaches.bindPositionVertexPointer(force, vertices, gVertexStride);
 }
 
@@ -2033,12 +1912,14 @@
 // Drawing
 ///////////////////////////////////////////////////////////////////////////////
 
-status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty,
+status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty,
         int32_t replayFlags) {
     status_t status;
     // All the usual checks and setup operations (quickReject, setupDraw, etc.)
     // will be performed by the display list itself
     if (displayList && displayList->isRenderable()) {
+        // compute 3d ordering
+        displayList->computeOrdering();
         if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
             status = startFrame();
             ReplayStateStruct replayStruct(*this, dirty, replayFlags);
@@ -2047,30 +1928,20 @@
         }
 
         bool avoidOverdraw = !mCaches.debugOverdraw && !mCountOverdraw; // shh, don't tell devs!
-        DeferredDisplayList deferredList(*(mSnapshot->clipRect), avoidOverdraw);
+        DeferredDisplayList deferredList(*currentClipRect(), avoidOverdraw);
         DeferStateStruct deferStruct(deferredList, *this, replayFlags);
         displayList->defer(deferStruct, 0);
 
         flushLayers();
         status = startFrame();
 
-        return status | deferredList.flush(*this, dirty);
+        return deferredList.flush(*this, dirty) | status;
     }
 
     return DrawGlInfo::kStatusDone;
 }
 
-void OpenGLRenderer::outputDisplayList(DisplayList* displayList) {
-    if (displayList) {
-        displayList->output(1);
-    }
-}
-
-void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint) {
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-
+void OpenGLRenderer::drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint) {
     int color = paint != NULL ? paint->getColor() : 0;
 
     float x = left;
@@ -2079,20 +1950,20 @@
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
 
     bool ignoreTransform = false;
-    if (currentTransform().isPureTranslate()) {
-        x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
-        y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
+    if (currentTransform()->isPureTranslate()) {
+        x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
+        y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
         ignoreTransform = true;
 
         texture->setFilter(GL_NEAREST, true);
     } else {
-        texture->setFilter(FILTER(paint), true);
+        texture->setFilter(getFilter(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,
+            paint, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset,
             GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform);
 }
 
@@ -2101,44 +1972,41 @@
  * 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 pureTranslate, const Rect& bounds, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+        int bitmapCount, TextureVertex* vertices, bool pureTranslate,
+        const Rect& bounds, const SkPaint* paint) {
     mCaches.activeTexture(0);
     Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
 
     const AutoTexture autoCleanup(texture);
 
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(pureTranslate ? GL_NEAREST : FILTER(paint), true);
+    texture->setFilter(pureTranslate ? GL_NEAREST : getFilter(paint), true);
 
     const float x = (int) floorf(bounds.left + 0.5f);
     const float y = (int) floorf(bounds.top + 0.5f);
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
-        int color = paint != NULL ? paint->getColor() : 0;
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         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, false);
+                texture->id, paint, &vertices[0].x, &vertices[0].u,
+                GL_TRIANGLES, bitmapCount * 6, true,
+                kModelViewMode_Translate, 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, false);
+                texture->id, paint, texture->blend, &vertices[0].x, &vertices[0].u,
+                GL_TRIANGLES, bitmapCount * 6, false, true, 0,
+                kModelViewMode_Translate, false);
     }
 
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2147,7 +2015,7 @@
     if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         drawAlphaBitmap(texture, left, top, paint);
     } else {
         drawTextureRect(left, top, right, bottom, texture, paint);
@@ -2156,12 +2024,13 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+        const SkPaint* paint) {
     Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
     const mat4 transform(*matrix);
     transform.mapRect(r);
 
-    if (quickReject(r.left, r.top, r.right, r.bottom)) {
+    if (quickRejectSetupScissor(r.left, r.top, r.right, r.bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2174,7 +2043,7 @@
     // to the vertex shader. The save/restore is a bit overkill.
     save(SkCanvas::kMatrix_SaveFlag);
     concatMatrix(matrix);
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         drawAlphaBitmap(texture, 0.0f, 0.0f, paint);
     } else {
         drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint);
@@ -2184,11 +2053,12 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmapData(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+status_t OpenGLRenderer::drawBitmapData(const SkBitmap* bitmap, float left, float top,
+        const SkPaint* paint) {
     const float right = left + bitmap->width();
     const float bottom = top + bitmap->height();
 
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2196,7 +2066,7 @@
     Texture* texture = mCaches.textureCache.getTransient(bitmap);
     const AutoTexture autoCleanup(texture);
 
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         drawAlphaBitmap(texture, left, top, paint);
     } else {
         drawTextureRect(left, top, right, bottom, texture, paint);
@@ -2205,9 +2075,9 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
-        float* vertices, int* colors, SkPaint* paint) {
-    if (!vertices || mSnapshot->isIgnored()) {
+status_t OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+        const float* vertices, const int* colors, const SkPaint* paint) {
+    if (!vertices || currentSnapshot()->isIgnored()) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2221,14 +2091,16 @@
 
     const uint32_t count = meshWidth * meshHeight * 6;
 
-    ColorTextureVertex mesh[count];
-    ColorTextureVertex* vertex = mesh;
+    Vector<ColorTextureVertex> mesh; // TODO: use C++11 unique_ptr
+    mesh.setCapacity(count);
+    ColorTextureVertex* vertex = mesh.editArray();
 
     bool cleanupColors = false;
     if (!colors) {
         uint32_t colorsCount = (meshWidth + 1) * (meshHeight + 1);
-        colors = new int[colorsCount];
-        memset(colors, 0xff, colorsCount * sizeof(int));
+        int* newColors = new int[colorsCount];
+        memset(newColors, 0xff, colorsCount * sizeof(int));
+        colors = newColors;
         cleanupColors = true;
     }
 
@@ -2271,7 +2143,7 @@
         }
     }
 
-    if (quickReject(left, top, right, bottom)) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         if (cleanupColors) delete[] colors;
         return DrawGlInfo::kStatusDone;
     }
@@ -2286,7 +2158,7 @@
     const AutoTexture autoCleanup(texture);
 
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
-    texture->setFilter(FILTER(paint), true);
+    texture->setFilter(getFilter(paint), true);
 
     int alpha;
     SkXfermode::Mode mode;
@@ -2295,21 +2167,21 @@
     float a = alpha / 255.0f;
 
     if (hasLayer()) {
-        dirtyLayer(left, top, right, bottom, currentTransform());
+        dirtyLayer(left, top, right, bottom, *currentTransform());
     }
 
     setupDraw();
     setupDrawWithTextureAndColor();
     setupDrawColor(a, a, a, a);
-    setupDrawColorFilter();
-    setupDrawBlending(true, mode, false);
+    setupDrawColorFilter(getColorFilter(paint));
+    setupDrawBlending(paint, true);
     setupDrawProgram();
     setupDrawDirtyRegionsDisabled();
-    setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, false);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false, 0.0f, 0.0f, 1.0f, 1.0f);
     setupDrawTexture(texture->id);
     setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
-    setupDrawMesh(&mesh[0].position[0], &mesh[0].texture[0], &mesh[0].color[0]);
+    setupDrawColorFilterUniforms(getColorFilter(paint));
+    setupDrawMesh(&mesh[0].x, &mesh[0].u, &mesh[0].r);
 
     glDrawArrays(GL_TRIANGLES, 0, count);
 
@@ -2323,11 +2195,11 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
+status_t OpenGLRenderer::drawBitmap(const SkBitmap* bitmap,
          float srcLeft, float srcTop, float srcRight, float srcBottom,
          float dstLeft, float dstTop, float dstRight, float dstBottom,
-         SkPaint* paint) {
-    if (quickReject(dstLeft, dstTop, dstRight, dstBottom)) {
+         const SkPaint* paint) {
+    if (quickRejectSetupScissor(dstLeft, dstTop, dstRight, dstBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2349,10 +2221,6 @@
     mCaches.unbindMeshBuffer();
     resetDrawTextureTexCoords(u1, v1, u2, v2);
 
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-
     texture->setWrap(GL_CLAMP_TO_EDGE, true);
 
     float scaleX = (dstRight - dstLeft) / (srcRight - srcLeft);
@@ -2365,9 +2233,9 @@
     bool useScaleTransform = mDrawModifiers.mShader && scaled;
     bool ignoreTransform = false;
 
-    if (CC_LIKELY(currentTransform().isPureTranslate() && !useScaleTransform)) {
-        float x = (int) floorf(dstLeft + currentTransform().getTranslateX() + 0.5f);
-        float y = (int) floorf(dstTop + currentTransform().getTranslateY() + 0.5f);
+    if (CC_LIKELY(currentTransform()->isPureTranslate() && !useScaleTransform)) {
+        float x = (int) floorf(dstLeft + currentTransform()->getTranslateX() + 0.5f);
+        float y = (int) floorf(dstTop + currentTransform()->getTranslateY() + 0.5f);
 
         dstRight = x + (dstRight - dstLeft);
         dstBottom = y + (dstBottom - dstTop);
@@ -2375,10 +2243,10 @@
         dstLeft = x;
         dstTop = y;
 
-        texture->setFilter(scaled ? FILTER(paint) : GL_NEAREST, true);
+        texture->setFilter(scaled ? getFilter(paint) : GL_NEAREST, true);
         ignoreTransform = true;
     } else {
-        texture->setFilter(FILTER(paint), true);
+        texture->setFilter(getFilter(paint), true);
     }
 
     if (CC_UNLIKELY(useScaleTransform)) {
@@ -2393,16 +2261,15 @@
         dstBottom = srcBottom - srcTop;
     }
 
-    if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
-        int color = paint ? paint->getColor() : 0;
+    if (CC_UNLIKELY(bitmap->config() == SkBitmap::kA8_Config)) {
         drawAlpha8TextureMesh(dstLeft, dstTop, dstRight, dstBottom,
-                texture->id, paint != NULL, color, alpha, mode,
-                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
+                texture->id, paint,
+                &mMeshVertices[0].x, &mMeshVertices[0].u,
                 GL_TRIANGLE_STRIP, gMeshCount, ignoreTransform);
     } else {
         drawTextureMesh(dstLeft, dstTop, dstRight, dstBottom,
-                texture->id, alpha / 255.0f, mode, texture->blend,
-                &mMeshVertices[0].position[0], &mMeshVertices[0].texture[0],
+                texture->id, paint, texture->blend,
+                &mMeshVertices[0].x, &mMeshVertices[0].u,
                 GL_TRIANGLE_STRIP, gMeshCount, false, ignoreTransform);
     }
 
@@ -2415,9 +2282,9 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, Res_png_9patch* patch,
-        float left, float top, float right, float bottom, SkPaint* paint) {
-    if (quickReject(left, top, right, bottom)) {
+status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+        float left, float top, float right, float bottom, const SkPaint* paint) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2428,9 +2295,10 @@
     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)) {
+status_t OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
+        AssetAtlas::Entry* entry, float left, float top, float right, float bottom,
+        const SkPaint* paint) {
+    if (quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2443,15 +2311,11 @@
         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();
+        const bool pureTranslate = currentTransform()->isPureTranslate();
         // Mark the current layer dirty where we are going to draw the patch
         if (hasLayer() && mesh->hasEmptyQuads) {
-            const float offsetX = left + currentTransform().getTranslateX();
-            const float offsetY = top + currentTransform().getTranslateY();
+            const float offsetX = left + currentTransform()->getTranslateX();
+            const float offsetY = top + currentTransform()->getTranslateY();
             const size_t count = mesh->quads.size();
             for (size_t i = 0; i < count; i++) {
                 const Rect& bounds = mesh->quads.itemAt(i);
@@ -2461,27 +2325,26 @@
                     dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight());
                 } else {
                     dirtyLayer(left + bounds.left, top + bounds.top,
-                            left + bounds.right, top + bounds.bottom, currentTransform());
+                            left + bounds.right, top + bounds.bottom, *currentTransform());
                 }
             }
         }
 
+        bool ignoreTransform = false;
         if (CC_LIKELY(pureTranslate)) {
-            const float x = (int) floorf(left + currentTransform().getTranslateX() + 0.5f);
-            const float y = (int) floorf(top + currentTransform().getTranslateY() + 0.5f);
+            const float x = (int) floorf(left + currentTransform()->getTranslateX() + 0.5f);
+            const float y = (int) floorf(top + currentTransform()->getTranslateY() + 0.5f);
 
             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 {
-            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);
+            left = x;
+            top = y;
+            ignoreTransform = true;
         }
+        drawIndexedTextureMesh(left, top, right, bottom, texture->id, paint,
+                texture->blend, (GLvoid*) mesh->offset, (GLvoid*) mesh->textureOffset,
+                GL_TRIANGLES, mesh->indexCount, false, ignoreTransform,
+                mCaches.patchCache.getMeshBuffer(), kModelViewMode_Translate, !mesh->hasEmptyQuads);
     }
 
     return DrawGlInfo::kStatusDrew;
@@ -2492,8 +2355,8 @@
  * 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) {
+status_t OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+        TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint) {
     mCaches.activeTexture(0);
     Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
     if (!texture) return DrawGlInfo::kStatusDone;
@@ -2502,58 +2365,62 @@
     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);
+    drawIndexedTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, paint,
+            texture->blend, &vertices[0].x, &vertices[0].u,
+            GL_TRIANGLES, indexCount, false, true, 0, kModelViewMode_Translate, false);
 
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
-        bool useOffset) {
+status_t OpenGLRenderer::drawVertexBuffer(VertexBufferMode mode,
+        const VertexBuffer& vertexBuffer, const SkPaint* paint, bool useOffset) {
+    // not missing call to quickReject/dirtyLayer, always done at a higher level
     if (!vertexBuffer.getVertexCount()) {
         // no vertices to draw
         return DrawGlInfo::kStatusDone;
     }
 
     int color = paint->getColor();
-    SkXfermode::Mode mode = getXfermode(paint->getXfermode());
     bool isAA = paint->isAntiAlias();
 
     setupDraw();
     setupDrawNoTexture();
     if (isAA) setupDrawAA();
     setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
-    setupDrawColorFilter();
+    setupDrawColorFilter(getColorFilter(paint));
     setupDrawShader();
-    setupDrawBlending(isAA, mode);
+    setupDrawBlending(paint, isAA);
     setupDrawProgram();
-    setupDrawModelViewIdentity(useOffset);
+    setupDrawModelView(kModelViewMode_Translate, useOffset, 0, 0, 0, 0);
     setupDrawColorUniforms();
-    setupDrawColorFilterUniforms();
-    setupDrawShaderIdentityUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
+    setupDrawShaderUniforms();
 
-    void* vertices = vertexBuffer.getBuffer();
+    const void* vertices = vertexBuffer.getBuffer();
     bool force = mCaches.unbindMeshBuffer();
     mCaches.bindPositionVertexPointer(true, vertices, isAA ? gAlphaVertexStride : gVertexStride);
     mCaches.resetTexCoordsVertexPointer();
-    mCaches.unbindIndicesBuffer();
+
 
     int alphaSlot = -1;
     if (isAA) {
         void* alphaCoords = ((GLbyte*) vertices) + gVertexAlphaOffset;
         alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha");
-
         // TODO: avoid enable/disable in back to back uses of the alpha attribute
         glEnableVertexAttribArray(alphaSlot);
         glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
     }
 
-    glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
+    if (mode == kVertexBufferMode_Standard) {
+        mCaches.unbindIndicesBuffer();
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
+    } else if (mode == kVertexBufferMode_OnePolyRingShadow) {
+        mCaches.bindShadowIndicesBuffer();
+        glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
+    } else if (mode == kVertexBufferMode_TwoPolyRingShadow) {
+        mCaches.bindShadowIndicesBuffer();
+        glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
+    }
 
     if (isAA) {
         glDisableVertexAttribArray(alphaSlot);
@@ -2571,18 +2438,18 @@
  *
  * Doesn't yet support joins, caps, or path effects.
  */
-status_t OpenGLRenderer::drawConvexPath(const SkPath& path, SkPaint* paint) {
+status_t OpenGLRenderer::drawConvexPath(const SkPath& path, const SkPaint* paint) {
     VertexBuffer vertexBuffer;
     // TODO: try clipping large paths to viewport
-    PathTessellator::tessellatePath(path, paint, mSnapshot->transform, vertexBuffer);
+    PathTessellator::tessellatePath(path, paint, *currentTransform(), vertexBuffer);
 
     if (hasLayer()) {
         SkRect bounds = path.getBounds();
-        PathTessellator::expandBoundsForStroke(bounds, paint, false);
-        dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
+        PathTessellator::expandBoundsForStroke(bounds, paint);
+        dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
     }
 
-    return drawVertexBuffer(vertexBuffer, paint);
+    return drawVertexBuffer(kVertexBufferMode_Standard, vertexBuffer, paint);
 }
 
 /**
@@ -2596,58 +2463,64 @@
  * TODO: try using a fixed input buffer for non-capped lines as in text rendering. this may reduce
  * memory transfer by removing need for degenerate vertices.
  */
-status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored() || count < 4) return DrawGlInfo::kStatusDone;
+status_t OpenGLRenderer::drawLines(const float* points, int count, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored() || count < 4) return DrawGlInfo::kStatusDone;
 
     count &= ~0x3; // round down to nearest four
 
     VertexBuffer buffer;
     SkRect bounds;
-    PathTessellator::tessellateLines(points, count, paint, mSnapshot->transform, bounds, buffer);
+    PathTessellator::tessellateLines(points, count, paint, *currentTransform(), bounds, buffer);
 
-    if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
+    // can't pass paint, since style would be checked for outset. outset done by tessellation.
+    if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
-    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
+    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    return drawVertexBuffer(kVertexBufferMode_Standard, buffer, paint, useOffset);
 }
 
-status_t OpenGLRenderer::drawPoints(float* points, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored() || count < 2) return DrawGlInfo::kStatusDone;
+status_t OpenGLRenderer::drawPoints(const float* points, int count, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored() || count < 2) return DrawGlInfo::kStatusDone;
 
     count &= ~0x1; // round down to nearest two
 
     VertexBuffer buffer;
     SkRect bounds;
-    PathTessellator::tessellatePoints(points, count, paint, mSnapshot->transform, bounds, buffer);
+    PathTessellator::tessellatePoints(points, count, paint, *currentTransform(), bounds, buffer);
 
-    if (quickReject(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
+    // can't pass paint, since style would be checked for outset. outset done by tessellation.
+    if (quickRejectSetupScissor(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
-    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, currentTransform());
+    dirtyLayer(bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, *currentTransform());
 
     bool useOffset = !paint->isAntiAlias();
-    return drawVertexBuffer(buffer, paint, useOffset);
+    return drawVertexBuffer(kVertexBufferMode_Standard, buffer, paint, useOffset);
 }
 
 status_t OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
     // No need to check against the clip, we fill the clip region
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
 
-    Rect& clip(*mSnapshot->clipRect);
+    Rect clip(*currentClipRect());
     clip.snapToPixelBoundaries();
 
-    drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
+    SkPaint paint;
+    paint.setColor(color);
+    paint.setXfermodeMode(mode);
+
+    drawColorRect(clip.left, clip.top, clip.right, clip.bottom, &paint, true);
 
     return DrawGlInfo::kStatusDrew;
 }
 
 status_t OpenGLRenderer::drawShape(float left, float top, const PathTexture* texture,
-        SkPaint* paint) {
+        const SkPaint* paint) {
     if (!texture) return DrawGlInfo::kStatusDone;
     const AutoTexture autoCleanup(texture);
 
@@ -2660,8 +2533,8 @@
 }
 
 status_t OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
-        float rx, float ry, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+        float rx, float ry, const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2685,8 +2558,8 @@
     return drawConvexPath(path, p);
 }
 
-status_t OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(x - radius, y - radius,
+status_t OpenGLRenderer::drawCircle(float x, float y, float radius, const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(x - radius, y - radius,
             x + radius, y + radius, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
@@ -2707,8 +2580,8 @@
 }
 
 status_t OpenGLRenderer::drawOval(float left, float top, float right, float bottom,
-        SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+        const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2729,8 +2602,8 @@
 }
 
 status_t OpenGLRenderer::drawArc(float left, float top, float right, float bottom,
-        float startAngle, float sweepAngle, bool useCenter, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+        float startAngle, float sweepAngle, bool useCenter, const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2766,8 +2639,9 @@
 // See SkPaintDefaults.h
 #define SkPaintDefaults_MiterLimit SkIntToScalar(4)
 
-status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
-    if (mSnapshot->isIgnored() || quickRejectPreStroke(left, top, right, bottom, p) ||
+status_t OpenGLRenderer::drawRect(float left, float top, float right, float bottom,
+        const SkPaint* p) {
+    if (currentSnapshot()->isIgnored() || quickRejectSetupScissor(left, top, right, bottom, p) ||
             (p->getAlpha() == 0 && getXfermode(p->getXfermode()) != SkXfermode::kClear_Mode)) {
         return DrawGlInfo::kStatusDone;
     }
@@ -2791,19 +2665,19 @@
         return drawConvexPath(path, p);
     }
 
-    if (p->isAntiAlias() && !currentTransform().isSimple()) {
+    if (p->isAntiAlias() && !currentTransform()->isSimple()) {
         SkPath path;
         path.addRect(left, top, right, bottom);
         return drawConvexPath(path, p);
     } else {
-        drawColorRect(left, top, right, bottom, p->getColor(), getXfermode(p->getXfermode()));
+        drawColorRect(left, top, right, bottom, p);
         return DrawGlInfo::kStatusDrew;
     }
 }
 
-void OpenGLRenderer::drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count,
-        const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode,
-        float x, float y) {
+void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text,
+        int bytesCount, int count, const float* positions,
+        FontRenderer& fontRenderer, int alpha, float x, float y) {
     mCaches.activeTexture(0);
 
     // NOTE: The drop shadow will not perform gamma correction
@@ -2828,14 +2702,15 @@
     setupDraw();
     setupDrawWithTexture(true);
     setupDrawAlpha8Color(shadowColor, shadowAlpha < 255 ? shadowAlpha : alpha);
-    setupDrawColorFilter();
+    setupDrawColorFilter(getColorFilter(paint));
     setupDrawShader();
-    setupDrawBlending(true, mode);
+    setupDrawBlending(paint, true);
     setupDrawProgram();
-    setupDrawModelView(sx, sy, sx + shadow->width, sy + shadow->height);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+            sx, sy, sx + shadow->width, sy + shadow->height);
     setupDrawTexture(shadow->id);
     setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
     setupDrawShaderUniforms();
     setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
 
@@ -2848,13 +2723,13 @@
 }
 
 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)) {
+        const float* positions, const SkPaint* paint) {
+    if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) {
         return DrawGlInfo::kStatusDone;
     }
 
     // NOTE: Skia does not support perspective transform on drawPosText yet
-    if (!currentTransform().isSimple()) {
+    if (!currentTransform()->isSimple()) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -2862,10 +2737,10 @@
 
     float x = 0.0f;
     float y = 0.0f;
-    const bool pureTranslate = currentTransform().isPureTranslate();
+    const bool pureTranslate = currentTransform()->isPureTranslate();
     if (pureTranslate) {
-        x = (int) floorf(x + currentTransform().getTranslateX() + 0.5f);
-        y = (int) floorf(y + currentTransform().getTranslateY() + 0.5f);
+        x = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f);
+        y = (int) floorf(y + currentTransform()->getTranslateY() + 0.5f);
     }
 
     FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint);
@@ -2877,11 +2752,11 @@
 
     if (CC_UNLIKELY(mDrawModifiers.mHasShadow)) {
         drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer,
-                alpha, mode, 0.0f, 0.0f);
+                alpha, 0.0f, 0.0f);
     }
 
     // Pick the appropriate texture filtering
-    bool linearFilter = currentTransform().changesBounds();
+    bool linearFilter = currentTransform()->changesBounds();
     if (pureTranslate && !linearFilter) {
         linearFilter = fabs(y - (int) y) > 0.0f || fabs(x - (int) x) > 0.0f;
     }
@@ -2897,7 +2772,7 @@
             positions, hasActiveLayer ? &bounds : NULL, &functor)) {
         if (hasActiveLayer) {
             if (!pureTranslate) {
-                currentTransform().mapRect(bounds);
+                currentTransform()->mapRect(bounds);
             }
             dirtyLayerUnchecked(bounds, getRegion());
         }
@@ -2915,7 +2790,7 @@
             fontTransform = mat4::identity();
         } else {
             float sx, sy;
-            currentTransform().decomposeScale(sx, sy);
+            currentTransform()->decomposeScale(sx, sy);
             fontTransform.loadScale(sx, sy, 1.0f);
         }
     }
@@ -2923,14 +2798,14 @@
 }
 
 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,
+        const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
         DrawOpMode drawOpMode) {
 
     if (drawOpMode == kDrawOpMode_Immediate) {
         // 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)) {
+        if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint) ||
+                quickRejectSetupScissor(bounds)) {
             return DrawGlInfo::kStatusDone;
         }
     }
@@ -2938,7 +2813,7 @@
     const float oldX = x;
     const float oldY = y;
 
-    const mat4& transform = currentTransform();
+    const mat4& transform = *currentTransform();
     const bool pureTranslate = transform.isPureTranslate();
 
     if (CC_LIKELY(pureTranslate)) {
@@ -2955,7 +2830,7 @@
     if (CC_UNLIKELY(mDrawModifiers.mHasShadow)) {
         fontRenderer.setFont(paint, mat4::identity());
         drawTextShadow(paint, text, bytesCount, count, positions, fontRenderer,
-                alpha, mode, oldX, oldY);
+                alpha, oldX, oldY);
     }
 
     const bool hasActiveLayer = hasLayer();
@@ -2979,7 +2854,7 @@
     fontRenderer.setTextureFiltering(linearFilter);
 
     // TODO: Implement better clipping for scaled/rotated text
-    const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect;
+    const Rect* clip = !pureTranslate ? NULL : currentClipRect();
     Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
 
     bool status;
@@ -3004,14 +2879,14 @@
         dirtyLayerUnchecked(layerBounds, getRegion());
     }
 
-    drawTextDecorations(text, bytesCount, totalAdvance, oldX, oldY, paint);
+    drawTextDecorations(totalAdvance, oldX, oldY, paint);
 
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
-        float hOffset, float vOffset, SkPaint* paint) {
-    if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint)) {
+status_t OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count,
+        const SkPath* path, float hOffset, float vOffset, const SkPaint* paint) {
+    if (text == NULL || count == 0 || currentSnapshot()->isIgnored() || canSkipText(paint)) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -3035,7 +2910,7 @@
     if (fontRenderer.renderTextOnPath(paint, clip, text, 0, bytesCount, count, path,
             hOffset, vOffset, hasActiveLayer ? &bounds : NULL, &functor)) {
         if (hasActiveLayer) {
-            currentTransform().mapRect(bounds);
+            currentTransform()->mapRect(bounds);
             dirtyLayerUnchecked(bounds, getRegion());
         }
     }
@@ -3043,8 +2918,8 @@
     return DrawGlInfo::kStatusDrew;
 }
 
-status_t OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) return DrawGlInfo::kStatusDone;
+status_t OpenGLRenderer::drawPath(const SkPath* path, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
 
     mCaches.activeTexture(0);
 
@@ -3070,13 +2945,13 @@
         transform = &layer->getTransform();
         if (!transform->isIdentity()) {
             save(0);
-            currentTransform().multiply(*transform);
+            concatMatrix(*transform);
         }
     }
 
     bool clipRequired = false;
-    const bool rejected = quickRejectNoScissor(x, y,
-            x + layer->layer.getWidth(), y + layer->layer.getHeight(), false, &clipRequired);
+    const bool rejected = calculateQuickRejectForScissor(x, y,
+            x + layer->layer.getWidth(), y + layer->layer.getHeight(), &clipRequired, false);
 
     if (rejected) {
         if (transform && !transform->isIdentity()) {
@@ -3091,33 +2966,31 @@
     mCaches.activeTexture(0);
 
     if (CC_LIKELY(!layer->region.isEmpty())) {
-        SkiaColorFilter* oldFilter = mDrawModifiers.mColorFilter;
-        mDrawModifiers.mColorFilter = layer->getColorFilter();
-
         if (layer->region.isRect()) {
             DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
                     composeLayerRect(layer, layer->regionRect));
         } else if (layer->mesh) {
+
             const float a = getLayerAlpha(layer);
             setupDraw();
             setupDrawWithTexture();
             setupDrawColor(a, a, a, a);
-            setupDrawColorFilter();
-            setupDrawBlending(layer->isBlend() || a < 1.0f, layer->getMode(), false);
+            setupDrawColorFilter(layer->getColorFilter());
+            setupDrawBlending(layer);
             setupDrawProgram();
             setupDrawPureColorUniforms();
-            setupDrawColorFilterUniforms();
+            setupDrawColorFilterUniforms(layer->getColorFilter());
             setupDrawTexture(layer->getTexture());
-            if (CC_LIKELY(currentTransform().isPureTranslate())) {
-                int tx = (int) floorf(x + currentTransform().getTranslateX() + 0.5f);
-                int ty = (int) floorf(y + currentTransform().getTranslateY() + 0.5f);
+            if (CC_LIKELY(currentTransform()->isPureTranslate())) {
+                int tx = (int) floorf(x + currentTransform()->getTranslateX() + 0.5f);
+                int ty = (int) floorf(y + currentTransform()->getTranslateY() + 0.5f);
 
                 layer->setFilter(GL_NEAREST);
-                setupDrawModelViewTranslate(tx, ty,
+                setupDrawModelView(kModelViewMode_Translate, false, tx, ty,
                         tx + layer->layer.getWidth(), ty + layer->layer.getHeight(), true);
             } else {
                 layer->setFilter(GL_LINEAR);
-                setupDrawModelViewTranslate(x, y,
+                setupDrawModelView(kModelViewMode_Translate, false, x, y,
                         x + layer->layer.getWidth(), y + layer->layer.getHeight());
             }
 
@@ -3127,7 +3000,7 @@
             while (elementsCount > 0) {
                 GLsizei drawCount = min(elementsCount, (GLsizei) gMaxNumberOfQuads * 6);
 
-                setupDrawMeshIndices(&mesh[0].position[0], &mesh[0].texture[0]);
+                setupDrawMeshIndices(&mesh[0].x, &mesh[0].u);
                 DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate,
                         glDrawElements(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, NULL));
 
@@ -3138,16 +3011,16 @@
             }
 
 #if DEBUG_LAYERS_AS_REGIONS
-            drawRegionRects(layer->region);
+            drawRegionRectsDebug(layer->region);
 #endif
         }
 
-        mDrawModifiers.mColorFilter = oldFilter;
-
         if (layer->debugDrawUpdate) {
             layer->debugDrawUpdate = false;
-            drawColorRect(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(),
-                    0x7f00ff00, SkXfermode::kSrcOver_Mode);
+
+            SkPaint paint;
+            paint.setColor(0x7f00ff00);
+            drawColorRect(x, y, x + layer->layer.getWidth(), y + layer->layer.getHeight(), &paint);
         }
     }
     layer->hasDrawnSinceUpdate = true;
@@ -3175,18 +3048,6 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// Color filters
-///////////////////////////////////////////////////////////////////////////////
-
-void OpenGLRenderer::resetColorFilter() {
-    mDrawModifiers.mColorFilter = NULL;
-}
-
-void OpenGLRenderer::setupColorFilter(SkiaColorFilter* filter) {
-    mDrawModifiers.mColorFilter = filter;
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // Drop shadow
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -3220,7 +3081,7 @@
     mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags;
 }
 
-SkPaint* OpenGLRenderer::filterPaint(SkPaint* paint) {
+const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) {
     if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) {
         return paint;
     }
@@ -3238,7 +3099,7 @@
 // Drawing implementation
 ///////////////////////////////////////////////////////////////////////////////
 
-Texture* OpenGLRenderer::getTexture(SkBitmap* bitmap) {
+Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) {
     Texture* texture = mCaches.assetAtlas.getEntryTexture(bitmap);
     if (!texture) {
         return mCaches.textureCache.get(bitmap);
@@ -3247,8 +3108,8 @@
 }
 
 void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
-        float x, float y, SkPaint* paint) {
-    if (quickReject(x, y, x + texture->width, y + texture->height)) {
+        float x, float y, const SkPaint* paint) {
+    if (quickRejectSetupScissor(x, y, x + texture->width, y + texture->height)) {
         return;
     }
 
@@ -3259,14 +3120,15 @@
     setupDraw();
     setupDrawWithTexture(true);
     setupDrawAlpha8Color(paint->getColor(), alpha);
-    setupDrawColorFilter();
+    setupDrawColorFilter(getColorFilter(paint));
     setupDrawShader();
-    setupDrawBlending(true, mode);
+    setupDrawBlending(paint, true);
     setupDrawProgram();
-    setupDrawModelView(x, y, x + texture->width, y + texture->height);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+            x, y, x + texture->width, y + texture->height);
     setupDrawTexture(texture->id);
     setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
     setupDrawShaderUniforms();
     setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
 
@@ -3278,8 +3140,8 @@
 #define kStdUnderline_Offset    (1.0f / 9.0f)
 #define kStdUnderline_Thickness (1.0f / 18.0f)
 
-void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float underlineWidth,
-        float x, float y, SkPaint* paint) {
+void OpenGLRenderer::drawTextDecorations(float underlineWidth, float x, float y,
+        const SkPaint* paint) {
     // Handle underline and strike-through
     uint32_t flags = paint->getFlags();
     if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
@@ -3323,8 +3185,109 @@
     }
 }
 
-status_t OpenGLRenderer::drawRects(const float* rects, int count, SkPaint* paint) {
-    if (mSnapshot->isIgnored()) {
+status_t OpenGLRenderer::drawRects(const float* rects, int count, const SkPaint* paint) {
+    if (currentSnapshot()->isIgnored()) {
+        return DrawGlInfo::kStatusDone;
+    }
+
+    return drawColorRects(rects, count, paint, false, true, true);
+}
+
+static void mapPointFakeZ(Vector3& point, const mat4& transformXY, const mat4& transformZ) {
+    // map z coordinate with true 3d matrix
+    point.z = transformZ.mapZ(point);
+
+    // map x,y coordinates with draw/Skia matrix
+    transformXY.mapPoint(point.x, point.y);
+}
+
+status_t OpenGLRenderer::drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ,
+        float casterAlpha, const SkPath* casterOutline) {
+    if (currentSnapshot()->isIgnored()) return DrawGlInfo::kStatusDone;
+
+    // TODO: use quickRejectWithScissor. For now, always force enable scissor.
+    mCaches.enableScissor();
+
+    SkPaint paint;
+    paint.setAntiAlias(true); // want to use AlphaVertex
+
+    // tessellate caster outline into a 2d polygon
+    Vector<Vertex> casterVertices2d;
+    const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value
+    PathTessellator::approximatePathOutlineVertices(*casterOutline,
+            casterRefinementThresholdSquared, casterVertices2d);
+
+    if (casterVertices2d.size() == 0) {
+        // empty caster polygon computed from path
+        return DrawGlInfo::kStatusDone;
+    }
+
+    // map 2d caster poly into 3d
+    const int casterVertexCount = casterVertices2d.size();
+    Vector3 casterPolygon[casterVertexCount];
+    float minZ = FLT_MAX;
+    float maxZ = -FLT_MAX;
+    for (int i = 0; i < casterVertexCount; i++) {
+        const Vertex& point2d = casterVertices2d[i];
+        casterPolygon[i] = Vector3(point2d.x, point2d.y, 0);
+        mapPointFakeZ(casterPolygon[i], casterTransformXY, casterTransformZ);
+        minZ = fmin(minZ, casterPolygon[i].z);
+        maxZ = fmax(maxZ, casterPolygon[i].z);
+    }
+
+    // map the centroid of the caster into 3d
+    Vector2 centroid =  ShadowTessellator::centroid2d(
+            reinterpret_cast<const Vector2*>(casterVertices2d.array()),
+            casterVertexCount);
+    Vector3 centroid3d(centroid.x, centroid.y, 0);
+    mapPointFakeZ(centroid3d, casterTransformXY, casterTransformZ);
+
+    // if the caster intersects the z=0 plane, lift it in Z so it doesn't
+    if (minZ < SHADOW_MIN_CASTER_Z) {
+        float casterLift = SHADOW_MIN_CASTER_Z - minZ;
+        for (int i = 0; i < casterVertexCount; i++) {
+            casterPolygon[i].z += casterLift;
+        }
+        centroid3d.z += casterLift;
+    }
+
+    // Check whether we want to draw the shadow at all by checking the caster's
+    // bounds against clip.
+    // We only have ortho projection, so we can just ignore the Z in caster for
+    // simple rejection calculation.
+    Rect localClip = mSnapshot->getLocalClip();
+    Rect casterBounds(casterOutline->getBounds());
+    casterTransformXY.mapRect(casterBounds);
+
+    bool isCasterOpaque = (casterAlpha == 1.0f);
+    // draw caster's shadows
+    if (mCaches.propertyAmbientShadowStrength > 0) {
+        paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0);
+        VertexBuffer ambientShadowVertexBuffer;
+        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow(
+                isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
+                casterBounds, localClip, maxZ, ambientShadowVertexBuffer);
+        drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint);
+    }
+
+    if (mCaches.propertySpotShadowStrength > 0) {
+        paint.setARGB(casterAlpha * mCaches.propertySpotShadowStrength, 0, 0, 0);
+        VertexBuffer spotShadowVertexBuffer;
+        Vector3 lightPosScale(mCaches.propertyLightPosXScale,
+                mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
+        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow(
+                isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale,
+                *currentTransform(), getWidth(), getHeight(), casterBounds, localClip,
+                spotShadowVertexBuffer);
+        drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint);
+    }
+
+    return DrawGlInfo::kStatusDrew;
+}
+
+status_t OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint* paint,
+        bool ignoreTransform, bool dirty, bool clip) {
+    if (count == 0) {
         return DrawGlInfo::kStatusDone;
     }
 
@@ -3333,16 +3296,6 @@
     if (mDrawModifiers.mShader) {
         color |= 0x00ffffff;
     }
-    SkXfermode::Mode mode = getXfermode(paint->getXfermode());
-
-    return drawColorRects(rects, count, color, mode);
-}
-
-status_t OpenGLRenderer::drawColorRects(const float* rects, int count, int color,
-        SkXfermode::Mode mode, bool ignoreTransform, bool dirty, bool clip) {
-    if (count == 0) {
-        return DrawGlInfo::kStatusDone;
-    }
 
     float left = FLT_MAX;
     float top = FLT_MAX;
@@ -3369,34 +3322,36 @@
         bottom = fmaxf(bottom, b);
     }
 
-    if (clip && quickReject(left, top, right, bottom)) {
+    if (clip && quickRejectSetupScissor(left, top, right, bottom)) {
         return DrawGlInfo::kStatusDone;
     }
 
     setupDraw();
     setupDrawNoTexture();
-    setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
+    setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha);
     setupDrawShader();
-    setupDrawColorFilter();
-    setupDrawBlending(mode);
+    setupDrawColorFilter(getColorFilter(paint));
+    setupDrawBlending(paint);
     setupDrawProgram();
     setupDrawDirtyRegionsDisabled();
-    setupDrawModelView(0.0f, 0.0f, 1.0f, 1.0f, ignoreTransform, true);
+    setupDrawModelView(kModelViewMode_Translate, false,
+            0.0f, 0.0f, 0.0f, 0.0f, ignoreTransform);
     setupDrawColorUniforms();
     setupDrawShaderUniforms();
-    setupDrawColorFilterUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
 
     if (dirty && hasLayer()) {
-        dirtyLayer(left, top, right, bottom, currentTransform());
+        dirtyLayer(left, top, right, bottom, *currentTransform());
     }
 
-    drawIndexedQuads(&mesh[0], count / 4);
+    issueIndexedQuadDraw(&mesh[0], count / 4);
 
     return DrawGlInfo::kStatusDrew;
 }
 
 void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom,
-        int color, SkXfermode::Mode mode, bool ignoreTransform) {
+        const SkPaint* paint, bool ignoreTransform) {
+    int color = paint->getColor();
     // If a shader is set, preserve only the alpha
     if (mDrawModifiers.mShader) {
         color |= 0x00ffffff;
@@ -3404,34 +3359,31 @@
 
     setupDraw();
     setupDrawNoTexture();
-    setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
+    setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha);
     setupDrawShader();
-    setupDrawColorFilter();
-    setupDrawBlending(mode);
+    setupDrawColorFilter(getColorFilter(paint));
+    setupDrawBlending(paint);
     setupDrawProgram();
-    setupDrawModelView(left, top, right, bottom, ignoreTransform);
+    setupDrawModelView(kModelViewMode_TranslateAndScale, false,
+            left, top, right, bottom, ignoreTransform);
     setupDrawColorUniforms();
     setupDrawShaderUniforms(ignoreTransform);
-    setupDrawColorFilterUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
     setupDrawSimpleMesh();
 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
 }
 
 void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
-        Texture* texture, SkPaint* paint) {
-    int alpha;
-    SkXfermode::Mode mode;
-    getAlphaAndMode(paint, &alpha, &mode);
-
+        Texture* texture, const SkPaint* paint) {
     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];
+        vertices = &mMeshVertices[0].x;
+        texCoords = &mMeshVertices[0].u;
 
         Rect uvs(0.0f, 0.0f, 1.0f, 1.0f);
         texture->uvMapper->map(uvs);
@@ -3439,17 +3391,17 @@
         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);
+    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, vertices, texCoords,
+                paint, 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->setFilter(getFilter(paint), true);
+        drawTextureMesh(left, top, right, bottom, texture->id, paint,
                 texture->blend, vertices, texCoords, GL_TRIANGLE_STRIP, gMeshCount);
     }
 
@@ -3458,86 +3410,85 @@
     }
 }
 
-void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom,
-        GLuint texture, float alpha, SkXfermode::Mode mode, bool blend) {
-    drawTextureMesh(left, top, right, bottom, texture, alpha, mode, blend,
-            (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount);
-}
-
 void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
-        GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
+        GLuint texture, const SkPaint* paint, bool blend,
         GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-        bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) {
+        bool swapSrcDst, bool ignoreTransform, GLuint vbo,
+        ModelViewMode modelViewMode, bool dirty) {
+
+    int a;
+    SkXfermode::Mode mode;
+    getAlphaAndMode(paint, &a, &mode);
+    const float alpha = a / 255.0f;
 
     setupDraw();
     setupDrawWithTexture();
     setupDrawColor(alpha, alpha, alpha, alpha);
-    setupDrawColorFilter();
-    setupDrawBlending(blend, mode, swapSrcDst);
+    setupDrawColorFilter(getColorFilter(paint));
+    setupDrawBlending(paint, blend, swapSrcDst);
     setupDrawProgram();
     if (!dirty) setupDrawDirtyRegionsDisabled();
-    if (!ignoreScale) {
-        setupDrawModelView(left, top, right, bottom, ignoreTransform);
-    } else {
-        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
-    }
+    setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
     setupDrawTexture(texture);
     setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
     setupDrawMesh(vertices, texCoords, vbo);
 
     glDrawArrays(drawMode, 0, elementsCount);
 }
 
 void OpenGLRenderer::drawIndexedTextureMesh(float left, float top, float right, float bottom,
-        GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
+        GLuint texture, const SkPaint* paint, bool blend,
         GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-        bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) {
+        bool swapSrcDst, bool ignoreTransform, GLuint vbo,
+        ModelViewMode modelViewMode, bool dirty) {
+
+    int a;
+    SkXfermode::Mode mode;
+    getAlphaAndMode(paint, &a, &mode);
+    const float alpha = a / 255.0f;
 
     setupDraw();
     setupDrawWithTexture();
     setupDrawColor(alpha, alpha, alpha, alpha);
-    setupDrawColorFilter();
-    setupDrawBlending(blend, mode, swapSrcDst);
+    setupDrawColorFilter(getColorFilter(paint));
+    setupDrawBlending(paint, blend, swapSrcDst);
     setupDrawProgram();
     if (!dirty) setupDrawDirtyRegionsDisabled();
-    if (!ignoreScale) {
-        setupDrawModelView(left, top, right, bottom, ignoreTransform);
-    } else {
-        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
-    }
+    setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
     setupDrawTexture(texture);
     setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
     setupDrawMeshIndices(vertices, texCoords, vbo);
 
     glDrawElements(drawMode, elementsCount, GL_UNSIGNED_SHORT, NULL);
 }
 
 void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, float bottom,
-        GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode,
+        GLuint texture, const SkPaint* paint,
         GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-        bool ignoreTransform, bool ignoreScale, bool dirty) {
+        bool ignoreTransform, ModelViewMode modelViewMode, bool dirty) {
+
+    int color = paint != NULL ? paint->getColor() : 0;
+    int alpha;
+    SkXfermode::Mode mode;
+    getAlphaAndMode(paint, &alpha, &mode);
 
     setupDraw();
     setupDrawWithTexture(true);
-    if (hasColor) {
+    if (paint != NULL) {
         setupDrawAlpha8Color(color, alpha);
     }
-    setupDrawColorFilter();
+    setupDrawColorFilter(getColorFilter(paint));
     setupDrawShader();
-    setupDrawBlending(true, mode);
+    setupDrawBlending(paint, true);
     setupDrawProgram();
     if (!dirty) setupDrawDirtyRegionsDisabled();
-    if (!ignoreScale) {
-        setupDrawModelView(left, top, right, bottom, ignoreTransform);
-    } else {
-        setupDrawModelViewTranslate(left, top, right, bottom, ignoreTransform);
-    }
+    setupDrawModelView(modelViewMode, false, left, top, right, bottom, ignoreTransform);
     setupDrawTexture(texture);
     setupDrawPureColorUniforms();
-    setupDrawColorFilterUniforms();
-    setupDrawShaderUniforms();
+    setupDrawColorFilterUniforms(getColorFilter(paint));
+    setupDrawShaderUniforms(ignoreTransform);
     setupDrawMesh(vertices, texCoords);
 
     glDrawArrays(drawMode, 0, elementsCount);
@@ -3618,23 +3569,23 @@
     TextureVertex::setUV(v++, u2, v2);
 }
 
-void OpenGLRenderer::getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const {
+void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const {
     getAlphaAndModeDirect(paint, alpha,  mode);
     if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) {
         // if drawing a layer, ignore the paint's alpha
         *alpha = mDrawModifiers.mOverrideLayerAlpha * 255;
     }
-    *alpha *= mSnapshot->alpha;
+    *alpha *= currentSnapshot()->alpha;
 }
 
-float OpenGLRenderer::getLayerAlpha(Layer* layer) const {
+float OpenGLRenderer::getLayerAlpha(const Layer* layer) const {
     float alpha;
     if (mDrawModifiers.mOverrideLayerAlpha < 1.0f) {
         alpha = mDrawModifiers.mOverrideLayerAlpha;
     } else {
         alpha = layer->getAlpha() / 255.0f;
     }
-    return alpha * mSnapshot->alpha;
+    return alpha * currentSnapshot()->alpha;
 }
 
 }; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 9afb7ad..059c64f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -21,6 +21,8 @@
 #include <GLES2/gl2ext.h>
 
 #include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkColorFilter.h>
 #include <SkMatrix.h>
 #include <SkPaint.h>
 #include <SkRegion.h>
@@ -41,16 +43,22 @@
 #include "Matrix.h"
 #include "Program.h"
 #include "Rect.h"
+#include "Renderer.h"
+#include "StatefulBaseRenderer.h"
 #include "Snapshot.h"
-#include "Vertex.h"
-#include "SkiaShader.h"
-#include "SkiaColorFilter.h"
 #include "UvMapper.h"
+#include "Vertex.h"
 #include "Caches.h"
 
 namespace android {
 namespace uirenderer {
 
+class DeferredDisplayState;
+class RenderNode;
+class TextSetupFunctor;
+class VertexBuffer;
+class SkiaShader;
+
 struct DrawModifiers {
     DrawModifiers() {
         reset();
@@ -61,7 +69,6 @@
     }
 
     SkiaShader* mShader;
-    SkiaColorFilter* mColorFilter;
     float mOverrideLayerAlpha;
 
     // Drop shadow
@@ -82,12 +89,6 @@
     kStateDeferFlag_Clip = 0x2
 };
 
-enum DrawOpMode {
-    kDrawOpMode_Immediate,
-    kDrawOpMode_Defer,
-    kDrawOpMode_Flush
-};
-
 enum ClipSideFlags {
     kClipSide_None = 0x0,
     kClipSide_Left = 0x1,
@@ -98,105 +99,47 @@
     kClipSide_ConservativeFull = 0x1F
 };
 
+/**
+ * Defines additional transformation that should be applied by the model view matrix, beyond that of
+ * the currentTransform()
+ */
+enum ModelViewMode {
+    /**
+     * Used when the model view should simply translate geometry passed to the shader. The resulting
+     * matrix will be a simple translation.
+     */
+    kModelViewMode_Translate = 0,
+
+    /**
+     * Used when the model view should translate and scale geometry. The resulting matrix will be a
+     * translation + scale. This is frequently used together with VBO 0, the (0,0,1,1) rect.
+     */
+    kModelViewMode_TranslateAndScale = 1,
+};
+
+enum VertexBufferMode {
+    kVertexBufferMode_Standard = 0,
+    kVertexBufferMode_OnePolyRingShadow = 1,
+    kVertexBufferMode_TwoPolyRingShadow = 2
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 // Renderer
 ///////////////////////////////////////////////////////////////////////////////
-
-class DeferredDisplayState;
-class DisplayList;
-class TextSetupFunctor;
-class VertexBuffer;
-
 /**
- * OpenGL renderer used to draw accelerated 2D graphics. The API is a
- * simplified version of Skia's Canvas API.
+ * OpenGL Renderer implementation.
  */
-class OpenGLRenderer {
+class OpenGLRenderer : public StatefulBaseRenderer {
 public:
     ANDROID_API OpenGLRenderer();
     virtual ~OpenGLRenderer();
 
-    /**
-     * Sets the name of this renderer. The name is optional and
-     * empty by default. If the pointer is null the name is set
-     * to the empty string.
-     */
-    ANDROID_API void setName(const char* name);
-
-    /**
-     * Returns the name of this renderer as UTF8 string.
-     * The returned pointer is never null.
-     */
-    ANDROID_API const char* getName() const;
-
-    /**
-     * Read externally defined properties to control the behavior
-     * of the renderer.
-     */
     ANDROID_API void initProperties();
 
-    /**
-     * Indicates whether this renderer executes drawing commands immediately.
-     * If this method returns true, the drawing commands will be executed
-     * later.
-     */
-    virtual bool isDeferred();
-
-    /**
-     * Sets the dimension of the underlying drawing surface. This method must
-     * be called at least once every time the drawing surface changes size.
-     *
-     * @param width The width in pixels of the underlysing surface
-     * @param height The height in pixels of the underlysing surface
-     */
     virtual void setViewport(int width, int height);
-
-    /**
-     * Prepares the renderer to draw a frame. This method must be invoked
-     * at the beginning of each frame. When this method is invoked, the
-     * entire drawing surface is assumed to be redrawn.
-     *
-     * @param opaque If true, the target surface is considered opaque
-     *               and will not be cleared. If false, the target surface
-     *               will be cleared
-     */
-    ANDROID_API status_t prepare(bool opaque);
-
-    /**
-     * Prepares the renderer to draw a frame. This method must be invoked
-     * at the beginning of each frame. Only the specified rectangle of the
-     * frame is assumed to be dirty. A clip will automatically be set to
-     * the specified rectangle.
-     *
-     * @param left The left coordinate of the dirty rectangle
-     * @param top The top coordinate of the dirty rectangle
-     * @param right The right coordinate of the dirty rectangle
-     * @param bottom The bottom coordinate of the dirty rectangle
-     * @param opaque If true, the target surface is considered opaque
-     *               and will not be cleared. If false, the target surface
-     *               will be cleared in the specified dirty rectangle
-     */
     virtual status_t prepareDirty(float left, float top, float right, float bottom, bool opaque);
-
-    /**
-     * Indicates the end of a frame. This method must be invoked whenever
-     * the caller is done rendering a frame.
-     */
     virtual void finish();
-
-    /**
-     * This method must be invoked before handing control over to a draw functor.
-     * See callDrawGLFunction() for instance.
-     *
-     * This command must not be recorded inside display lists.
-     */
     virtual void interrupt();
-
-    /**
-     * This method must be invoked after getting control back from a draw functor.
-     *
-     * This command must not be recorded inside display lists.
-     */
     virtual void resume();
 
     ANDROID_API void setCountOverdrawEnabled(bool enabled) {
@@ -217,114 +160,61 @@
     ANDROID_API void clearLayerUpdates();
     ANDROID_API void flushLayerUpdates();
 
-    ANDROID_API int getSaveCount() const;
-    virtual int save(int flags);
-    virtual void restore();
-    virtual void restoreToCount(int saveCount);
-
-    ANDROID_API int saveLayer(float left, float top, float right, float bottom,
-            SkPaint* paint, int flags) {
-        SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
-        if (paint) mode = getXfermode(paint->getXfermode());
-        return saveLayer(left, top, right, bottom, paint ? paint->getAlpha() : 255, mode, flags);
-    }
-    ANDROID_API int saveLayerAlpha(float left, float top, float right, float bottom,
-            int alpha, int flags) {
-        return saveLayer(left, top, right, bottom, alpha, SkXfermode::kSrcOver_Mode, flags);
-    }
-    virtual int saveLayer(float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode, int flags);
+    ANDROID_API virtual int saveLayer(float left, float top, float right, float bottom,
+            const SkPaint* paint, int flags);
 
     int saveLayerDeferred(float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode, int flags);
+            const SkPaint* paint, int flags);
 
-    virtual void translate(float dx, float dy);
-    virtual void rotate(float degrees);
-    virtual void scale(float sx, float sy);
-    virtual void skew(float sx, float sy);
-
-    bool hasRectToRectTransform();
-    ANDROID_API void getMatrix(SkMatrix* matrix);
-    virtual void setMatrix(SkMatrix* matrix);
-    virtual void concatMatrix(SkMatrix* matrix);
-
-    ANDROID_API const Rect& getClipBounds();
-
-    /**
-     * 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);
-    virtual Rect* getClipRect();
-
-    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t replayFlags);
-    virtual void outputDisplayList(DisplayList* displayList);
+    virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
     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, AssetAtlas::Entry* entry, int bitmapCount,
-            TextureVertex* vertices, bool pureTranslate, 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,
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    status_t drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entry, int bitmapCount,
+            TextureVertex* vertices, bool pureTranslate, const Rect& bounds, const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+            const SkPaint* paint);
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
             float srcRight, float srcBottom, float dstLeft, float dstTop,
-            float dstRight, float dstBottom, SkPaint* paint);
-    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);
-    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 Patch* mesh, AssetAtlas::Entry* entry,
-            float left, float top, float right, float bottom, SkPaint* paint);
+            float dstRight, float dstBottom, const SkPaint* paint);
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint);
+    virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint);
+    status_t drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entry,
+            TextureVertex* vertices, uint32_t indexCount, const SkPaint* paint);
+    virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint);
+    status_t drawPatch(const SkBitmap* bitmap, const Patch* mesh, AssetAtlas::Entry* entry,
+            float left, float top, float right, float bottom, const 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 drawRect(float left, float top, float right, float bottom,
+            const SkPaint* paint);
     virtual status_t drawRoundRect(float left, float top, float right, float bottom,
-            float rx, float ry, SkPaint* paint);
-    virtual status_t drawCircle(float x, float y, float radius, SkPaint* paint);
-    virtual status_t drawOval(float left, float top, float right, float bottom, SkPaint* paint);
+            float rx, float ry, const SkPaint* paint);
+    virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint);
+    virtual status_t drawOval(float left, float top, float right, float bottom,
+            const SkPaint* paint);
     virtual status_t drawArc(float left, float top, float right, float bottom,
-            float startAngle, float sweepAngle, bool useCenter, SkPaint* paint);
-    virtual status_t drawPath(SkPath* path, SkPaint* paint);
-    virtual status_t drawLines(float* points, int count, SkPaint* paint);
-    virtual status_t drawPoints(float* points, int count, SkPaint* paint);
-    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, SkPath* path,
-            float hOffset, float vOffset, SkPaint* paint);
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint);
+    virtual status_t drawPath(const SkPath* path, const SkPaint* paint);
+    virtual status_t drawLines(const float* points, int count, const SkPaint* paint);
+    virtual status_t drawPoints(const float* points, int count, const SkPaint* paint);
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+            float hOffset, float vOffset, const SkPaint* paint);
     virtual status_t drawPosText(const char* text, int bytesCount, int count,
-            const float* positions, SkPaint* paint);
+            const float* positions, const SkPaint* paint);
     virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
-            const float* positions, SkPaint* paint, float totalAdvance, const Rect& bounds,
+            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
             DrawOpMode drawOpMode = kDrawOpMode_Immediate);
-    virtual status_t drawRects(const float* rects, int count, SkPaint* paint);
+    virtual status_t drawRects(const float* rects, int count, const SkPaint* paint);
+
+    status_t drawShadow(const mat4& casterTransformXY, const mat4& casterTransformZ,
+            float casterAlpha, const SkPath* casterOutline);
 
     virtual void resetShader();
     virtual void setupShader(SkiaShader* shader);
 
-    virtual void resetColorFilter();
-    virtual void setupColorFilter(SkiaColorFilter* filter);
-
     virtual void resetShadow();
     virtual void setupShadow(float radius, float dx, float dy, int color);
 
@@ -334,7 +224,7 @@
     // If this value is set to < 1.0, it overrides alpha set on layer (see drawBitmap, drawLayer)
     void setOverrideLayerAlpha(float alpha) { mDrawModifiers.mOverrideLayerAlpha = alpha; }
 
-    SkPaint* filterPaint(SkPaint* paint);
+    const SkPaint* filterPaint(const SkPaint* paint);
 
     /**
      * Store the current display state (most importantly, the current clip and transform), and
@@ -350,7 +240,7 @@
     void setDrawModifiers(const DrawModifiers& drawModifiers) { mDrawModifiers = drawModifiers; }
 
     ANDROID_API bool isCurrentTransformSimple() {
-        return mSnapshot->transform->isSimple();
+        return currentTransform()->isSimple();
     }
 
     Caches& getCaches() {
@@ -362,8 +252,8 @@
         return mSnapshot->clipRegion->isEmpty();
     }
 
-    int getViewportWidth() { return getSnapshot()->viewport.getWidth(); }
-    int getViewportHeight() { return getSnapshot()->viewport.getHeight(); }
+    int getViewportWidth() { return currentSnapshot()->viewport.getWidth(); }
+    int getViewportHeight() { return currentSnapshot()->viewport.getHeight(); }
 
     /**
      * Scales the alpha on the current snapshot. This alpha value will be modulated
@@ -400,12 +290,12 @@
      * @param alpha Where to store the resulting alpha
      * @param mode Where to store the resulting xfermode
      */
-    static inline void getAlphaAndModeDirect(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
+    static inline void getAlphaAndModeDirect(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) {
         *mode = getXfermodeDirect(paint);
         *alpha = getAlphaDirect(paint);
     }
 
-    static inline SkXfermode::Mode getXfermodeDirect(SkPaint* paint) {
+    static inline SkXfermode::Mode getXfermodeDirect(const SkPaint* paint) {
         if (!paint) return SkXfermode::kSrcOver_Mode;
         return getXfermode(paint->getXfermode());
     }
@@ -477,6 +367,13 @@
      */
     void attachStencilBufferToLayer(Layer* layer);
 
+    bool quickRejectSetupScissor(float left, float top, float right, float bottom,
+            const SkPaint* paint = NULL);
+    bool quickRejectSetupScissor(const Rect& bounds, const SkPaint* paint = NULL) {
+        return quickRejectSetupScissor(bounds.left, bounds.top,
+                bounds.right, bounds.bottom, paint);
+    }
+
     /**
      * Compose the layer defined in the current snapshot with the layer
      * defined by the previous snapshot.
@@ -486,7 +383,7 @@
      * @param curent The current snapshot containing the layer to compose
      * @param previous The previous snapshot to compose the current layer with
      */
-    virtual void composeLayer(sp<Snapshot> current, sp<Snapshot> previous);
+    virtual void composeLayer(const Snapshot& current, const Snapshot& previous);
 
     /**
      * Marks the specified region as dirty at the specified bounds.
@@ -494,13 +391,6 @@
     void dirtyLayerUnchecked(Rect& bounds, Region* region);
 
     /**
-     * Returns the current snapshot.
-     */
-    sp<Snapshot> getSnapshot() const {
-        return mSnapshot;
-    }
-
-    /**
      * Returns the region of the current layer.
      */
     virtual Region* getRegion() const {
@@ -517,7 +407,7 @@
     /**
      * Returns the name of the FBO this renderer is rendering into.
      */
-    virtual GLint getTargetFbo() const {
+    virtual GLuint getTargetFbo() const {
         return 0;
     }
 
@@ -538,25 +428,21 @@
      * @param alpha Where to store the resulting alpha
      * @param mode Where to store the resulting xfermode
      */
-    inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const;
+    inline void getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) const;
 
     /**
      * Gets the alpha from a layer, accounting for snapshot alpha and overrideLayerAlpha
      *
      * @param layer The layer from which the alpha is extracted
      */
-    inline float getLayerAlpha(Layer* layer) const;
+    inline float getLayerAlpha(const Layer* layer) const;
 
     /**
-     * Safely retrieves the mode from the specified xfermode. If the specified
-     * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
+     * Safely retrieves the ColorFilter from the given Paint. If the paint is
+     * null then null is returned.
      */
-    static inline SkXfermode::Mode getXfermode(SkXfermode* mode) {
-        SkXfermode::Mode resultMode;
-        if (!SkXfermode::AsMode(mode, &resultMode)) {
-            resultMode = SkXfermode::kSrcOver_Mode;
-        }
-        return resultMode;
+    static inline SkColorFilter* getColorFilter(const SkPaint* paint) {
+        return paint ? paint->getColorFilter() : NULL;
     }
 
     /**
@@ -582,12 +468,11 @@
 
     /**
      * Tells the GPU what part of the screen is about to be redrawn.
-     * This method will use the clip rect that we started drawing the
-     * frame with.
+     * This method will use the current layer space clip rect.
      * This method needs to be invoked every time getTargetFbo() is
      * bound again.
      */
-    void startTiling(const sp<Snapshot>& snapshot, bool opaque = false);
+    void startTilingCurrentClip(bool opaque = false);
 
     /**
      * Tells the GPU what part of the screen is about to be redrawn.
@@ -602,23 +487,7 @@
      */
     void endTiling();
 
-    /**
-     * Saves the current state of the renderer as a new snapshot.
-     * The new snapshot is saved in mSnapshot and the previous snapshot
-     * is linked from mSnapshot->previous.
-     *
-     * @param flags The save flags; see SkCanvas for more information
-     *
-     * @return The new save count. This value can be passed to #restoreToCount()
-     */
-    int saveSnapshot(int flags);
-
-    /**
-     * Restores the current snapshot; mSnapshot becomes mSnapshot->previous.
-     *
-     * @return True if the clip was modified.
-     */
-    bool restoreSnapshot();
+    void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored);
 
     /**
      * Sets the clipping rectangle using glScissor. The clip is defined by
@@ -654,12 +523,11 @@
      * @param alpha The translucency of the layer
      * @param mode The blending mode of the layer
      * @param flags The layer save flags
-     * @param previousFbo The name of the current framebuffer
      *
      * @return True if the layer was successfully created, false otherwise
      */
     bool createLayer(float left, float top, float right, float bottom,
-            int alpha, SkXfermode::Mode mode, int flags, GLuint previousFbo);
+            const SkPaint* paint, int flags);
 
     /**
      * Creates a new layer stored in the specified snapshot as an FBO.
@@ -667,9 +535,8 @@
      * @param layer The layer to store as an FBO
      * @param snapshot The snapshot associated with the new layer
      * @param bounds The bounds of the layer
-     * @param previousFbo The name of the current framebuffer
      */
-    bool createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLuint previousFbo);
+    bool createFboLayer(Layer* layer, Rect& bounds, Rect& clip);
 
     /**
      * Compose the specified layer as a region.
@@ -716,12 +583,11 @@
      * @param top The top coordinate of the rectangle
      * @param right The right coordinate of the rectangle
      * @param bottom The bottom coordinate of the rectangle
-     * @param color The rectangle's ARGB color, defined as a packed 32 bits word
-     * @param mode The Skia xfermode to use
+     * @param paint The paint containing the color, blending mode, etc.
      * @param ignoreTransform True if the current transform should be ignored
      */
     void drawColorRect(float left, float top, float right, float bottom,
-            int color, SkXfermode::Mode mode, bool ignoreTransform = false);
+            const SkPaint* paint, bool ignoreTransform = false);
 
     /**
      * Draws a series of colored rectangles with the specified color. The specified
@@ -730,15 +596,13 @@
      *
      * @param rects A list of rectangles, 4 floats (left, top, right, bottom)
      *              per rectangle
-     * @param color The rectangles' ARGB color, defined as a packed 32 bits word
-     * @param mode The Skia xfermode to use
+     * @param paint The paint containing the color, blending mode, etc.
      * @param ignoreTransform True if the current transform should be ignored
      * @param dirty True if calling this method should dirty the current layer
      * @param clip True if the rects should be clipped, false otherwise
      */
-    status_t drawColorRects(const float* rects, int count, int color,
-            SkXfermode::Mode mode, bool ignoreTransform = false,
-            bool dirty = true, bool clip = true);
+    status_t drawColorRects(const float* rects, int count, const SkPaint* paint,
+            bool ignoreTransform = false, bool dirty = true, bool clip = true);
 
     /**
      * Draws the shape represented by the specified path texture.
@@ -751,7 +615,7 @@
      * @param texture The texture reprsenting the shape
      * @param paint The paint to draw the shape with
      */
-    status_t drawShape(float left, float top, const PathTexture* texture, SkPaint* paint);
+    status_t drawShape(float left, float top, const PathTexture* texture, const SkPaint* paint);
 
     /**
      * Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
@@ -762,7 +626,7 @@
      * @param top The y coordinate of the bitmap
      * @param paint The paint to render with
      */
-    void drawAlphaBitmap(Texture* texture, float left, float top, SkPaint* paint);
+    void drawAlphaBitmap(Texture* texture, float left, float top, const SkPaint* paint);
 
     /**
      * Renders a strip of polygons with the specified paint, used for tessellated geometry.
@@ -771,8 +635,8 @@
      * @param paint The paint to render with
      * @param useOffset Offset the vertexBuffer (used in drawing non-AA lines)
      */
-    status_t drawVertexBuffer(const VertexBuffer& vertexBuffer, SkPaint* paint,
-            bool useOffset = false);
+    status_t drawVertexBuffer(VertexBufferMode mode, const VertexBuffer& vertexBuffer,
+            const SkPaint* paint, bool useOffset = false);
 
     /**
      * Renders the convex hull defined by the specified path as a strip of polygons.
@@ -780,23 +644,7 @@
      * @param path The hull of the path to draw
      * @param paint The paint to render with
      */
-    status_t drawConvexPath(const SkPath& path, SkPaint* paint);
-
-    /**
-     * Draws a textured rectangle with the specified texture. The specified coordinates
-     * are transformed by the current snapshot's transform matrix.
-     *
-     * @param left The left coordinate of the rectangle
-     * @param top The top coordinate of the rectangle
-     * @param right The right coordinate of the rectangle
-     * @param bottom The bottom coordinate of the rectangle
-     * @param texture The texture name to map onto the rectangle
-     * @param alpha An additional translucency parameter, between 0.0f and 1.0f
-     * @param mode The blending mode
-     * @param blend True if the texture contains an alpha channel
-     */
-    void drawTextureRect(float left, float top, float right, float bottom, GLuint texture,
-            float alpha, SkXfermode::Mode mode, bool blend);
+    status_t drawConvexPath(const SkPath& path, const SkPaint* paint);
 
     /**
      * Draws a textured rectangle with the specified texture. The specified coordinates
@@ -810,7 +658,7 @@
      * @param paint The paint containing the alpha, blending mode, etc.
      */
     void drawTextureRect(float left, float top, float right, float bottom,
-            Texture* texture, SkPaint* paint);
+            Texture* texture, const SkPaint* paint);
 
     /**
      * Draws a textured mesh with the specified texture. If the indices are omitted,
@@ -822,8 +670,7 @@
      * @param right The right coordinate of the rectangle
      * @param bottom The bottom coordinate of the rectangle
      * @param texture The texture name to map onto the rectangle
-     * @param alpha An additional translucency parameter, between 0.0f and 1.0f
-     * @param mode The blending mode
+     * @param paint The paint containing the alpha, blending mode, colorFilter, etc.
      * @param blend True if the texture contains an alpha channel
      * @param vertices The vertices that define the mesh
      * @param texCoords The texture coordinates of each vertex
@@ -831,32 +678,33 @@
      * @param swapSrcDst Whether or not the src and dst blending operations should be swapped
      * @param ignoreTransform True if the current transform should be ignored
      * @param vbo The VBO used to draw the mesh
-     * @param ignoreScale True if the model view matrix should not be scaled
+     * @param modelViewMode Defines whether the model view matrix should be scaled
      * @param dirty True if calling this method should dirty the current layer
      */
     void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
-            float alpha, SkXfermode::Mode mode, bool blend,
+            const SkPaint* paint, 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);
+            ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
 
     void drawIndexedTextureMesh(float left, float top, float right, float bottom, GLuint texture,
-            float alpha, SkXfermode::Mode mode, bool blend,
+            const SkPaint* paint, 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);
+            ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
 
     void drawAlpha8TextureMesh(float left, float top, float right, float bottom,
-            GLuint texture, bool hasColor, int color, int alpha, SkXfermode::Mode mode,
+            GLuint texture, const SkPaint* paint,
             GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
-            bool ignoreTransform, bool ignoreScale = false, bool dirty = true);
+            bool ignoreTransform, ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale,
+            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);
+    void issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount);
 
     /**
      * Draws text underline and strike-through if needed.
@@ -868,8 +716,7 @@
      * @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 totalAdvance,
-            float x, float y, SkPaint* paint);
+    void drawTextDecorations(float totalAdvance, float x, float y, const SkPaint* paint);
 
    /**
      * Draws shadow layer on text (with optional positions).
@@ -881,12 +728,11 @@
      * @param positions The x, y positions of individual glyphs (or NULL)
      * @param fontRenderer The font renderer object
      * @param alpha The alpha value for drawing the shadow
-     * @param mode The xfermode for drawing the shadow
      * @param x The x coordinate where the shadow will be drawn
      * @param y The y coordinate where the shadow will be drawn
      */
-    void drawTextShadow(SkPaint* paint, const char* text, int bytesCount, int count,
-            const float* positions, FontRenderer& fontRenderer, int alpha, SkXfermode::Mode mode,
+    void drawTextShadow(const SkPaint* paint, const char* text, int bytesCount, int count,
+            const float* positions, FontRenderer& fontRenderer, int alpha,
             float x, float y);
 
     /**
@@ -898,7 +744,7 @@
      * @param y The y coordinate where the texture will be drawn
      * @param paint The paint to draw the texture with
      */
-     void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
+     void drawPathTexture(const PathTexture* texture, float x, float y, const SkPaint* paint);
 
     /**
      * Resets the texture coordinates stored in mMeshVertices. Setting the values
@@ -971,32 +817,42 @@
     void setupDrawAlpha8Color(int color, int alpha);
     void setupDrawTextGamma(const SkPaint* paint);
     void setupDrawShader();
-    void setupDrawColorFilter();
-    void setupDrawBlending(SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
-            bool swapSrcDst = false);
-    void setupDrawBlending(bool blend = true, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode,
-            bool swapSrcDst = false);
+    void setupDrawColorFilter(const SkColorFilter* filter);
+    void setupDrawBlending(const Layer* layer, bool swapSrcDst = false);
+    void setupDrawBlending(const SkPaint* paint, bool blend = true, bool swapSrcDst = false);
     void setupDrawProgram();
     void setupDrawDirtyRegionsDisabled();
-    void setupDrawModelViewIdentity(bool offset = false);
-    void setupDrawModelView(float left, float top, float right, float bottom,
-            bool ignoreTransform = false, bool ignoreModelView = false);
-    void setupDrawModelViewTranslate(float left, float top, float right, float bottom,
-            bool ignoreTransform = false);
+
+    /**
+     * Setup the current program matrices based upon the nature of the geometry.
+     *
+     * @param mode If kModelViewMode_Translate, the geometry must be translated by the left and top
+     * parameters. If kModelViewMode_TranslateAndScale, the geometry that exists in the (0,0, 1,1)
+     * space must be scaled up and translated to fill the quad provided in (l,t,r,b). These
+     * transformations are stored in the modelView matrix and uploaded to the shader.
+     *
+     * @param offset Set to true if the the matrix should be fudged (translated) slightly to disambiguate
+     * geometry pixel positioning. See Vertex::GeometryFudgeFactor().
+     *
+     * @param ignoreTransform Set to true if l,t,r,b coordinates already in layer space,
+     * currentTransform() will be ignored. (e.g. when drawing clip in layer coordinates to stencil,
+     * or when simple translation has been extracted)
+     */
+    void setupDrawModelView(ModelViewMode mode, bool offset,
+            float left, float top, float right, float bottom, bool ignoreTransform = false);
     void setupDrawColorUniforms();
     void setupDrawPureColorUniforms();
-    void setupDrawShaderIdentityUniforms();
     void setupDrawShaderUniforms(bool ignoreTransform = false);
-    void setupDrawColorFilterUniforms();
+    void setupDrawColorFilterUniforms(const SkColorFilter* paint);
     void setupDrawSimpleMesh();
     void setupDrawTexture(GLuint texture);
     void setupDrawExternalTexture(GLuint texture);
     void setupDrawTextureTransform();
     void setupDrawTextureTransformUniforms(mat4& transform);
     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, GLuint vbo = 0);
+    void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords = NULL, GLuint vbo = 0);
+    void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords, const GLvoid* colors);
+    void setupDrawMeshIndices(const GLvoid* vertices, const GLvoid* texCoords, GLuint vbo = 0);
     void setupDrawIndexedVertices(GLvoid* vertices);
     void accountForClear(SkXfermode::Mode mode);
 
@@ -1004,18 +860,19 @@
     void updateLayers();
     void flushLayers();
 
+#if DEBUG_LAYERS_AS_REGIONS
     /**
      * Renders the specified region as a series of rectangles. This method
      * is used for debugging only.
      */
-    void drawRegionRects(const Region& region);
+    void drawRegionRectsDebug(const Region& region);
+#endif
 
     /**
      * Renders the specified region as a series of rectangles. The region
      * must be in screen-space coordinates.
      */
-    void drawRegionRects(const SkRegion& region, int color, SkXfermode::Mode mode,
-            bool dirty = false);
+    void drawRegionRects(const SkRegion& region, const SkPaint& paint, bool dirty = false);
 
     /**
      * Draws the current clip region if any. Only when DEBUG_CLIP_REGIONS
@@ -1034,10 +891,6 @@
         mDirtyClip = true;
     }
 
-    inline mat4& currentTransform() const {
-        return *mSnapshot->transform;
-    }
-
     inline const UvMapper& getMapper(const Texture* texture) {
         return texture && texture->uvMapper ? *texture->uvMapper : mUvMapper;
     }
@@ -1047,23 +900,27 @@
      * 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);
+    Texture* getTexture(const SkBitmap* bitmap);
 
-    // Dimensions of the drawing surface
-    int mWidth, mHeight;
+    // Matrix used for view/projection in shaders
+    mat4 mViewProjMatrix;
 
-    // Matrix used for ortho projection in shaders
-    mat4 mOrthoMatrix;
-
-    // Model-view matrix used to position/size objects
+    /**
+     * Model-view matrix used to position/size objects
+     *
+     * Stores operation-local modifications to the draw matrix that aren't incorporated into the
+     * currentTransform().
+     *
+     * If generated with kModelViewMode_Translate, the mModelView will reflect an x/y offset,
+     * e.g. the offset in drawLayer(). If generated with kModelViewMode_TranslateAndScale,
+     * mModelView will reflect a translation and scale, e.g. the translation and scale required to
+     * make VBO 0 (a rect of (0,0,1,1)) scaled to match the x,y offset, and width/height of a
+     * bitmap.
+     *
+     * Used as input to SkiaShader transformation.
+     */
     mat4 mModelView;
 
-    // Number of saved states
-    int mSaveCount;
-    // Base state
-    sp<Snapshot> mFirstSnapshot;
-    // Current state
-    sp<Snapshot> mSnapshot;
     // State used to define the clipping region
     Rect mTilingClip;
     // Is the target render surface opaque
@@ -1092,9 +949,6 @@
     // List of layers to update at the beginning of a frame
     Vector<Layer*> mLayerUpdates;
 
-    // Indicates whether the clip must be restored
-    bool mDirtyClip;
-
     // The following fields are used to setup drawing
     // Used to describe the shaders to generate
     ProgramDescription mDescription;
@@ -1122,9 +976,6 @@
     bool mCountOverdraw;
     float mOverdraw;
 
-    // Optional name of the renderer
-    String8 mName;
-
     friend class DisplayListRenderer;
     friend class Layer;
     friend class TextSetupFunctor;
diff --git a/libs/hwui/Outline.h b/libs/hwui/Outline.h
new file mode 100644
index 0000000..f42be50
--- /dev/null
+++ b/libs/hwui/Outline.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef OUTLINE_H
+#define OUTLINE_H
+
+#include <SkPath.h>
+
+#include "Rect.h"
+
+namespace android {
+namespace uirenderer {
+
+class Outline {
+public:
+    Outline()
+            : mShouldClip(false)
+            , mType(kOutlineType_None)
+            , mRadius(0) {}
+
+    void setRoundRect(int left, int top, int right, int bottom, int radius) {
+        mType = kOutlineType_RoundRect;
+        mBounds.set(left, top, right, bottom);
+        mRadius = radius;
+        mPath.reset();
+        mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom),
+                radius, radius);
+    }
+
+    void setConvexPath(const SkPath* outline) {
+        if (!outline) {
+            setEmpty();
+            return;
+        }
+        mType = kOutlineType_ConvexPath;
+        mPath = *outline;
+        mBounds.set(outline->getBounds());
+    }
+
+    void setEmpty() {
+        mType = kOutlineType_None;
+        mPath.reset();
+    }
+
+    void setShouldClip(bool clip) {
+        mShouldClip = clip;
+    }
+
+
+    bool willClip() const {
+        // only round rect outlines can be used for clipping
+        return mShouldClip && (mType == kOutlineType_RoundRect);
+    }
+
+    const SkPath* getPath() {
+        if (mType == kOutlineType_None) return NULL;
+
+        return &mPath;
+    }
+
+private:
+    enum OutlineType {
+        kOutlineType_None = 0,
+        kOutlineType_ConvexPath = 1,
+        kOutlineType_RoundRect = 2
+    };
+
+    bool mShouldClip;
+    OutlineType mType;
+    Rect mBounds;
+    float mRadius;
+    SkPath mPath;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* OUTLINE_H */
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index b5e8838..1ba045d 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -36,7 +36,8 @@
 // 9-patch structures
 ///////////////////////////////////////////////////////////////////////////////
 
-struct Patch {
+class Patch {
+public:
     Patch();
     ~Patch();
 
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index cf8adf8..5a49f38 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -51,7 +51,7 @@
     memset(&shape, 0, sizeof(Shape));
 }
 
-PathDescription::PathDescription(ShapeType type, SkPaint* paint):
+PathDescription::PathDescription(ShapeType type, const SkPaint* paint):
         type(type),
         join(paint->getStrokeJoin()),
         cap(paint->getStrokeCap()),
@@ -82,7 +82,7 @@
 // Utilities
 ///////////////////////////////////////////////////////////////////////////////
 
-bool PathCache::canDrawAsConvexPath(SkPath* path, SkPaint* paint) {
+bool PathCache::canDrawAsConvexPath(SkPath* path, const SkPaint* paint) {
     // NOTE: This should only be used after PathTessellator handles joins properly
     return paint->getPathEffect() == NULL && path->getConvexity() == SkPath::kConvex_Convexity;
 }
@@ -415,7 +415,7 @@
  * in the cache. The source path is also used to reclaim garbage when a
  * Dalvik Path object is collected.
  */
-static SkPath* getSourcePath(SkPath* path) {
+static const SkPath* getSourcePath(const SkPath* path) {
     const SkPath* sourcePath = path->getSourcePath();
     if (sourcePath && sourcePath->getGenerationID() == path->getGenerationID()) {
         return const_cast<SkPath*>(sourcePath);
@@ -423,7 +423,7 @@
     return path;
 }
 
-PathTexture* PathCache::get(SkPath* path, SkPaint* paint) {
+PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
     path = getSourcePath(path);
 
     PathDescription entry(kShapePath, paint);
@@ -461,7 +461,7 @@
     return texture;
 }
 
-void PathCache::precache(SkPath* path, SkPaint* paint) {
+void PathCache::precache(const SkPath* path, const SkPaint* paint) {
     if (!Caches::getInstance().tasks.canRunTasks()) {
         return;
     }
@@ -509,7 +509,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PathTexture* PathCache::getRoundRect(float width, float height,
-        float rx, float ry, SkPaint* paint) {
+        float rx, float ry, const SkPaint* paint) {
     PathDescription entry(kShapeRoundRect, paint);
     entry.shape.roundRect.mWidth = width;
     entry.shape.roundRect.mHeight = height;
@@ -534,7 +534,7 @@
 // Circles
 ///////////////////////////////////////////////////////////////////////////////
 
-PathTexture* PathCache::getCircle(float radius, SkPaint* paint) {
+PathTexture* PathCache::getCircle(float radius, const SkPaint* paint) {
     PathDescription entry(kShapeCircle, paint);
     entry.shape.circle.mRadius = radius;
 
@@ -554,7 +554,7 @@
 // Ovals
 ///////////////////////////////////////////////////////////////////////////////
 
-PathTexture* PathCache::getOval(float width, float height, SkPaint* paint) {
+PathTexture* PathCache::getOval(float width, float height, const SkPaint* paint) {
     PathDescription entry(kShapeOval, paint);
     entry.shape.oval.mWidth = width;
     entry.shape.oval.mHeight = height;
@@ -577,7 +577,7 @@
 // Rects
 ///////////////////////////////////////////////////////////////////////////////
 
-PathTexture* PathCache::getRect(float width, float height, SkPaint* paint) {
+PathTexture* PathCache::getRect(float width, float height, const SkPaint* paint) {
     PathDescription entry(kShapeRect, paint);
     entry.shape.rect.mWidth = width;
     entry.shape.rect.mHeight = height;
@@ -601,7 +601,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 PathTexture* PathCache::getArc(float width, float height,
-        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
+        float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) {
     PathDescription entry(kShapeArc, paint);
     entry.shape.arc.mWidth = width;
     entry.shape.arc.mHeight = height;
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 16d20a8..847853a 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -32,7 +32,7 @@
 class SkCanvas;
 class SkPaint;
 class SkPath;
-class SkRect;
+struct SkRect;
 
 namespace android {
 namespace uirenderer {
@@ -116,7 +116,7 @@
     SkPathEffect* pathEffect;
     union Shape {
         struct Path {
-            SkPath* mPath;
+            const SkPath* mPath;
         } path;
         struct RoundRect {
             float mWidth;
@@ -145,7 +145,7 @@
     } shape;
 
     PathDescription();
-    PathDescription(ShapeType shapeType, SkPaint* paint);
+    PathDescription(ShapeType shapeType, const SkPaint* paint);
 
     hash_t hash() const;
 
@@ -207,13 +207,13 @@
      */
     uint32_t getSize();
 
-    PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
-    PathTexture* getCircle(float radius, SkPaint* paint);
-    PathTexture* getOval(float width, float height, SkPaint* paint);
-    PathTexture* getRect(float width, float height, SkPaint* paint);
+    PathTexture* getRoundRect(float width, float height, float rx, float ry, const SkPaint* paint);
+    PathTexture* getCircle(float radius, const SkPaint* paint);
+    PathTexture* getOval(float width, float height, const SkPaint* paint);
+    PathTexture* getRect(float width, float height, const SkPaint* paint);
     PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
-            bool useCenter, SkPaint* paint);
-    PathTexture* get(SkPath* path, SkPaint* paint);
+            bool useCenter, const SkPaint* paint);
+    PathTexture* get(const SkPath* path, const SkPaint* paint);
 
     /**
      * Removes the specified path. This is meant to be called from threads
@@ -239,9 +239,9 @@
     /**
      * Precaches the specified path using background threads.
      */
-    void precache(SkPath* path, SkPaint* paint);
+    void precache(const SkPath* path, const SkPaint* paint);
 
-    static bool canDrawAsConvexPath(SkPath* path, SkPaint* paint);
+    static bool canDrawAsConvexPath(SkPath* path, const SkPaint* paint);
     static void computePathBounds(const SkPath* path, const SkPaint* paint,
             float& left, float& top, float& offset, uint32_t& width, uint32_t& height);
     static void computeBounds(const SkRect& bounds, const SkPaint* paint,
@@ -292,7 +292,7 @@
 
     class PathTask: public Task<SkBitmap*> {
     public:
-        PathTask(SkPath* path, SkPaint* paint, PathTexture* texture):
+        PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
             path(path), paint(paint), texture(texture) {
         }
 
@@ -300,8 +300,8 @@
             delete future()->get();
         }
 
-        SkPath* path;
-        SkPaint* paint;
+        const SkPath* path;
+        const SkPaint* paint;
         PathTexture* texture;
     };
 
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 3970913..4ef2158 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "PathTessellator"
+#define LOG_TAG "OpenGLRenderer"
 #define LOG_NDEBUG 1
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+#define ATRACE_TAG ATRACE_TAG_VIEW
 
 #define VERTEX_DEBUG 0
 
@@ -24,11 +24,11 @@
 #define DEBUG_DUMP_ALPHA_BUFFER() \
     for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) { \
         ALOGD("point %d at %f %f, alpha %f", \
-        i, buffer[i].position[0], buffer[i].position[1], buffer[i].alpha); \
+        i, buffer[i].x, buffer[i].y, buffer[i].alpha); \
     }
 #define DEBUG_DUMP_BUFFER() \
     for (unsigned int i = 0; i < vertexBuffer.getSize(); i++) { \
-        ALOGD("point %d at %f %f", i, buffer[i].position[0], buffer[i].position[1]); \
+        ALOGD("point %d at %f %f", i, buffer[i].x, buffer[i].y); \
     }
 #else
 #define DEBUG_DUMP_ALPHA_BUFFER()
@@ -53,27 +53,22 @@
 namespace android {
 namespace uirenderer {
 
-#define THRESHOLD 0.5f
+#define OUTLINE_REFINE_THRESHOLD_SQUARED (0.5f * 0.5f)
 #define ROUND_CAP_THRESH 0.25f
 #define PI 3.1415926535897932f
 
-void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint,
-        bool forceExpand) {
-    if (forceExpand || paint->getStyle() != SkPaint::kFill_Style) {
+/**
+ * Note: this function doesn't account for the AA case with sub-pixel line thickness (not just 0 <
+ * width < 1.0, canvas scale factors in as well) so this can't be used for points/lines
+ */
+void PathTessellator::expandBoundsForStroke(SkRect& bounds, const SkPaint* paint) {
+    if (paint->getStyle() != SkPaint::kFill_Style) {
         float outset = paint->getStrokeWidth() * 0.5f;
         if (outset == 0) outset = 0.5f; // account for hairline
         bounds.outset(outset, outset);
     }
 }
 
-inline static void copyVertex(Vertex* destPtr, const Vertex* srcPtr) {
-    Vertex::set(destPtr, srcPtr->position[0], srcPtr->position[1]);
-}
-
-inline static void copyAlphaVertex(AlphaVertex* destPtr, const AlphaVertex* srcPtr) {
-    AlphaVertex::set(destPtr, srcPtr->position[0], srcPtr->position[1], srcPtr->alpha);
-}
-
 /**
  * Produces a pseudo-normal for a vertex, given the normals of the two incoming lines. If the offset
  * from each vertex in a perimeter is calculated, the resultant lines connecting the offset vertices
@@ -93,16 +88,16 @@
  */
 struct PaintInfo {
 public:
-    PaintInfo(const SkPaint* paint, const mat4 *transform) :
+    PaintInfo(const SkPaint* paint, const mat4& transform) :
             style(paint->getStyle()), cap(paint->getStrokeCap()), isAA(paint->isAntiAlias()),
             inverseScaleX(1.0f), inverseScaleY(1.0f),
             halfStrokeWidth(paint->getStrokeWidth() * 0.5f), maxAlpha(1.0f) {
         // compute inverse scales
-        if (CC_UNLIKELY(!transform->isPureTranslate())) {
-            float m00 = transform->data[Matrix4::kScaleX];
-            float m01 = transform->data[Matrix4::kSkewY];
-            float m10 = transform->data[Matrix4::kSkewX];
-            float m11 = transform->data[Matrix4::kScaleY];
+        if (CC_UNLIKELY(!transform.isPureTranslate())) {
+            float m00 = transform.data[Matrix4::kScaleX];
+            float m01 = transform.data[Matrix4::kSkewY];
+            float m10 = transform.data[Matrix4::kSkewX];
+            float m11 = transform.data[Matrix4::kScaleY];
             float scaleX = sqrt(m00 * m00 + m01 * m01);
             float scaleY = sqrt(m10 * m10 + m11 * m11);
             inverseScaleX = (scaleX != 0) ? (1.0f / scaleX) : 1.0f;
@@ -159,6 +154,17 @@
         }
         return 0;
     }
+
+    /**
+     * Outset the bounds of point data (for line endpoints or points) to account for AA stroke
+     * geometry.
+     */
+    void expandBoundsForStrokeAA(SkRect& bounds) const {
+        float outset = halfStrokeWidth;
+        if (outset == 0) outset = 0.5f;
+        bounds.outset(outset * inverseScaleX + Vertex::GeometryFudgeFactor(),
+                outset * inverseScaleY + Vertex::GeometryFudgeFactor());
+    }
 };
 
 void getFillVerticesFromPerimeter(const Vector<Vertex>& perimeter, VertexBuffer& vertexBuffer) {
@@ -170,9 +176,9 @@
     int srcAindex = 0;
     int srcBindex = perimeter.size() - 1;
     while (srcAindex <= srcBindex) {
-        copyVertex(&buffer[currentIndex++], &perimeter[srcAindex]);
+        buffer[currentIndex++] = perimeter[srcAindex];
         if (srcAindex == srcBindex) break;
-        copyVertex(&buffer[currentIndex++], &perimeter[srcBindex]);
+        buffer[currentIndex++] = perimeter[srcBindex];
         srcAindex++;
         srcBindex--;
     }
@@ -192,25 +198,25 @@
     int currentIndex = 0;
     const Vertex* last = &(perimeter[perimeter.size() - 1]);
     const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
     for (unsigned int i = 0; i < perimeter.size(); i++) {
         const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
         paintInfo.scaleOffsetForStrokeWidth(totalOffset);
 
         Vertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y);
+                current->x + totalOffset.x,
+                current->y + totalOffset.y);
 
         Vertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y);
+                current->x - totalOffset.x,
+                current->y - totalOffset.y);
 
         last = current;
         current = next;
@@ -218,8 +224,8 @@
     }
 
     // wrap around to beginning
-    copyVertex(&buffer[currentIndex++], &buffer[0]);
-    copyVertex(&buffer[currentIndex++], &buffer[1]);
+    buffer[currentIndex++] = buffer[0];
+    buffer[currentIndex++] = buffer[1];
 
     DEBUG_DUMP_BUFFER();
 }
@@ -229,7 +235,7 @@
     vec2 strokeOffset = normal;
     paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
 
-    vec2 referencePoint(center.position[0], center.position[1]);
+    vec2 referencePoint(center.x, center.y);
     if (paintInfo.cap == SkPaint::kSquare_Cap) {
         referencePoint += vec2(-strokeOffset.y, strokeOffset.x) * (begin ? -1 : 1);
     }
@@ -255,11 +261,11 @@
     if (extra > 0) {
         // tessellate both round caps
         float beginTheta = atan2(
-                    - (vertices[0].position[0] - vertices[1].position[0]),
-                    vertices[0].position[1] - vertices[1].position[1]);
+                    - (vertices[0].x - vertices[1].x),
+                    vertices[0].y - vertices[1].y);
         float endTheta = atan2(
-                    - (vertices[lastIndex].position[0] - vertices[lastIndex - 1].position[0]),
-                    vertices[lastIndex].position[1] - vertices[lastIndex - 1].position[1]);
+                    - (vertices[lastIndex].x - vertices[lastIndex - 1].x),
+                    vertices[lastIndex].y - vertices[lastIndex - 1].y);
         const float dTheta = PI / (extra + 1);
         const float radialScale = 2.0f / (1 + cos(dTheta));
 
@@ -275,37 +281,37 @@
             vec2 beginRadialOffset(cos(beginTheta), sin(beginTheta));
             paintInfo.scaleOffsetForStrokeWidth(beginRadialOffset);
             Vertex::set(&buffer[capOffset],
-                    vertices[0].position[0] + beginRadialOffset.x,
-                    vertices[0].position[1] + beginRadialOffset.y);
+                    vertices[0].x + beginRadialOffset.x,
+                    vertices[0].y + beginRadialOffset.y);
 
             endTheta += dTheta;
             vec2 endRadialOffset(cos(endTheta), sin(endTheta));
             paintInfo.scaleOffsetForStrokeWidth(endRadialOffset);
             Vertex::set(&buffer[allocSize - 1 - capOffset],
-                    vertices[lastIndex].position[0] + endRadialOffset.x,
-                    vertices[lastIndex].position[1] + endRadialOffset.y);
+                    vertices[lastIndex].x + endRadialOffset.x,
+                    vertices[lastIndex].y + endRadialOffset.y);
         }
     }
 
     int currentIndex = extra;
     const Vertex* last = &(vertices[0]);
     const Vertex* current = &(vertices[1]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-                last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+                last->x - current->x);
     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]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 strokeOffset  = totalOffsetFromNormals(lastNormal, nextNormal);
         paintInfo.scaleOffsetForStrokeWidth(strokeOffset);
 
-        vec2 center(current->position[0], current->position[1]);
+        vec2 center(current->x, current->y);
         Vertex::set(&buffer[currentIndex++], center + strokeOffset);
         Vertex::set(&buffer[currentIndex++], center - strokeOffset);
 
@@ -329,7 +335,7 @@
  * 3 - zig zag back and forth inside the shape to fill it (using perimeter.size() vertices)
  */
 void getFillVerticesFromPerimeterAA(const PaintInfo& paintInfo, const Vector<Vertex>& perimeter,
-        VertexBuffer& vertexBuffer) {
+        VertexBuffer& vertexBuffer, float maxAlpha = 1.0f) {
     AlphaVertex* buffer = vertexBuffer.alloc<AlphaVertex>(perimeter.size() * 3 + 2);
 
     // generate alpha points - fill Alpha vertex gaps in between each point with
@@ -337,13 +343,13 @@
     int currentIndex = 0;
     const Vertex* last = &(perimeter[perimeter.size() - 1]);
     const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
     for (unsigned int i = 0; i < perimeter.size(); i++) {
         const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         // AA point offset from original point is that point's normal, such that each side is offset
@@ -351,13 +357,13 @@
         vec2 totalOffset = paintInfo.deriveAAOffset(totalOffsetFromNormals(lastNormal, nextNormal));
 
         AlphaVertex::set(&buffer[currentIndex++],
-                current->position[0] + totalOffset.x,
-                current->position[1] + totalOffset.y,
+                current->x + totalOffset.x,
+                current->y + totalOffset.y,
                 0.0f);
         AlphaVertex::set(&buffer[currentIndex++],
-                current->position[0] - totalOffset.x,
-                current->position[1] - totalOffset.y,
-                1.0f);
+                current->x - totalOffset.x,
+                current->y - totalOffset.y,
+                maxAlpha);
 
         last = current;
         current = next;
@@ -365,8 +371,8 @@
     }
 
     // wrap around to beginning
-    copyAlphaVertex(&buffer[currentIndex++], &buffer[0]);
-    copyAlphaVertex(&buffer[currentIndex++], &buffer[1]);
+    buffer[currentIndex++] = buffer[0];
+    buffer[currentIndex++] = buffer[1];
 
     // zig zag between all previous points on the inside of the hull to create a
     // triangle strip that fills the hull, repeating the first inner point to
@@ -374,9 +380,9 @@
     int srcAindex = 0;
     int srcBindex = perimeter.size() - 1;
     while (srcAindex <= srcBindex) {
-        copyAlphaVertex(&buffer[currentIndex++], &buffer[srcAindex * 2 + 1]);
+        buffer[currentIndex++] = buffer[srcAindex * 2 + 1];
         if (srcAindex == srcBindex) break;
-        copyAlphaVertex(&buffer[currentIndex++], &buffer[srcBindex * 2 + 1]);
+        buffer[currentIndex++] = buffer[srcBindex * 2 + 1];
         srcAindex++;
         srcBindex--;
     }
@@ -416,7 +422,7 @@
 
     // determine referencePoint, the center point for the 4 primary cap vertices
     const Vertex* point = isFirst ? vertices.begin() : (vertices.end() - 1);
-    vec2 referencePoint(point->position[0], point->position[1]);
+    vec2 referencePoint(point->x, point->y);
     if (paintInfo.cap == SkPaint::kSquare_Cap) {
         // To account for square cap, move the primary cap vertices (that create the AA edge) by the
         // stroke offset vector (rotated to be parallel to the stroke)
@@ -471,8 +477,8 @@
 
             if (isFirst && i == extra - extraOffset) {
                 //copy most recent two points to first two points
-                copyAlphaVertex(&buffer[0], &buffer[capPerimIndex - 2]);
-                copyAlphaVertex(&buffer[1], &buffer[capPerimIndex - 1]);
+                buffer[0] = buffer[capPerimIndex - 2];
+                buffer[1] = buffer[capPerimIndex - 1];
 
                 capPerimIndex = 2; // start writing the rest of the round cap at index 2
             }
@@ -482,28 +488,28 @@
             const int startCapFillIndex = capIndex + 2 * (extra - extraOffset) + 4;
             int capFillIndex = startCapFillIndex;
             for (int i = 0; i < extra + 2; i += 2) {
-                copyAlphaVertex(&buffer[capFillIndex++], &buffer[1 + i]);
+                buffer[capFillIndex++] = buffer[1 + i];
                 // TODO: to support odd numbers of divisions, break here on the last iteration
-                copyAlphaVertex(&buffer[capFillIndex++], &buffer[startCapFillIndex - 3 - i]);
+                buffer[capFillIndex++] = buffer[startCapFillIndex - 3 - i];
             }
         } else {
             int capFillIndex = 6 * vertices.size() + 2 + 6 * extra - (extra + 2);
             for (int i = 0; i < extra + 2; i += 2) {
-                copyAlphaVertex(&buffer[capFillIndex++], &buffer[capIndex + 1 + i]);
+                buffer[capFillIndex++] = buffer[capIndex + 1 + i];
                 // TODO: to support odd numbers of divisions, break here on the last iteration
-                copyAlphaVertex(&buffer[capFillIndex++], &buffer[capIndex + 3 + 2 * extra - i]);
+                buffer[capFillIndex++] = buffer[capIndex + 3 + 2 * extra - i];
             }
         }
         return;
     }
     if (isFirst) {
-        copyAlphaVertex(&buffer[0], &buffer[postCapIndex + 2]);
-        copyAlphaVertex(&buffer[1], &buffer[postCapIndex + 3]);
-        copyAlphaVertex(&buffer[postCapIndex + 4], &buffer[1]); // degenerate tris (the only two!)
-        copyAlphaVertex(&buffer[postCapIndex + 5], &buffer[postCapIndex + 1]);
+        buffer[0] = buffer[postCapIndex + 2];
+        buffer[1] = buffer[postCapIndex + 3];
+        buffer[postCapIndex + 4] = buffer[1]; // degenerate tris (the only two!)
+        buffer[postCapIndex + 5] = buffer[postCapIndex + 1];
     } else {
-        copyAlphaVertex(&buffer[6 * vertices.size()], &buffer[postCapIndex + 1]);
-        copyAlphaVertex(&buffer[6 * vertices.size() + 1], &buffer[postCapIndex + 3]);
+        buffer[6 * vertices.size()] = buffer[postCapIndex + 1];
+        buffer[6 * vertices.size() + 1] = buffer[postCapIndex + 3];
     }
 }
 
@@ -576,8 +582,8 @@
 
     const Vertex* last = &(vertices[0]);
     const Vertex* current = &(vertices[1]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
 
     // TODO: use normal from bezier traversal for cap, instead of from vertices
@@ -585,8 +591,8 @@
 
     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]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
@@ -598,30 +604,30 @@
         innerOffset -= AAOffset;
 
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + outerOffset.x,
-                current->position[1] + outerOffset.y,
+                current->x + outerOffset.x,
+                current->y + outerOffset.y,
                 0.0f);
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentAAInnerIndex--],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentAAInnerIndex--],
-                current->position[0] - outerOffset.x,
-                current->position[1] - outerOffset.y,
+                current->x - outerOffset.x,
+                current->y - outerOffset.y,
                 0.0f);
 
         current = next;
@@ -646,13 +652,13 @@
 
     const Vertex* last = &(perimeter[perimeter.size() - 1]);
     const Vertex* current = &(perimeter[0]);
-    vec2 lastNormal(current->position[1] - last->position[1],
-            last->position[0] - current->position[0]);
+    vec2 lastNormal(current->y - last->y,
+            last->x - current->x);
     lastNormal.normalize();
     for (unsigned int i = 0; i < perimeter.size(); i++) {
         const Vertex* next = &(perimeter[i + 1 >= perimeter.size() ? 0 : i + 1]);
-        vec2 nextNormal(next->position[1] - current->position[1],
-                current->position[0] - next->position[0]);
+        vec2 nextNormal(next->y - current->y,
+                current->x - next->x);
         nextNormal.normalize();
 
         vec2 totalOffset = totalOffsetFromNormals(lastNormal, nextNormal);
@@ -664,30 +670,30 @@
         innerOffset -= AAOffset;
 
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + outerOffset.x,
-                current->position[1] + outerOffset.y,
+                current->x + outerOffset.x,
+                current->y + outerOffset.y,
                 0.0f);
         AlphaVertex::set(&buffer[currentAAOuterIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] + innerOffset.x,
-                current->position[1] + innerOffset.y,
+                current->x + innerOffset.x,
+                current->y + innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentStrokeIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
 
         AlphaVertex::set(&buffer[currentAAInnerIndex++],
-                current->position[0] - innerOffset.x,
-                current->position[1] - innerOffset.y,
+                current->x - innerOffset.x,
+                current->y - innerOffset.y,
                 paintInfo.maxAlpha);
         AlphaVertex::set(&buffer[currentAAInnerIndex++],
-                current->position[0] - outerOffset.x,
-                current->position[1] - outerOffset.y,
+                current->x - outerOffset.x,
+                current->y - outerOffset.y,
                 0.0f);
 
         last = current;
@@ -696,23 +702,23 @@
     }
 
     // wrap each strip around to beginning, creating degenerate tris to bridge strips
-    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[0]);
-    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[1]);
-    copyAlphaVertex(&buffer[currentAAOuterIndex++], &buffer[1]);
+    buffer[currentAAOuterIndex++] = buffer[0];
+    buffer[currentAAOuterIndex++] = buffer[1];
+    buffer[currentAAOuterIndex++] = buffer[1];
 
-    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset]);
-    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset + 1]);
-    copyAlphaVertex(&buffer[currentStrokeIndex++], &buffer[offset + 1]);
+    buffer[currentStrokeIndex++] = buffer[offset];
+    buffer[currentStrokeIndex++] = buffer[offset + 1];
+    buffer[currentStrokeIndex++] = buffer[offset + 1];
 
-    copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset]);
-    copyAlphaVertex(&buffer[currentAAInnerIndex++], &buffer[2 * offset + 1]);
+    buffer[currentAAInnerIndex++] = buffer[2 * offset];
+    buffer[currentAAInnerIndex++] = buffer[2 * offset + 1];
     // don't need to create last degenerate tri
 
     DEBUG_DUMP_ALPHA_BUFFER();
 }
 
 void PathTessellator::tessellatePath(const SkPath &path, const SkPaint* paint,
-        const mat4 *transform, VertexBuffer& vertexBuffer) {
+        const mat4& transform, VertexBuffer& vertexBuffer) {
     ATRACE_CALL();
 
     const PaintInfo paintInfo(paint, transform);
@@ -733,7 +739,8 @@
     // force close if we're filling the path, since fill path expects closed perimeter.
     bool forceClose = paintInfo.style != SkPaint::kStroke_Style;
     bool wasClosed = approximatePathOutlineVertices(path, forceClose,
-            threshInvScaleX * threshInvScaleX, threshInvScaleY * threshInvScaleY, tempVertices);
+            threshInvScaleX * threshInvScaleX, threshInvScaleY * threshInvScaleY,
+            OUTLINE_REFINE_THRESHOLD_SQUARED, tempVertices);
 
     if (!tempVertices.size()) {
         // path was empty, return without allocating vertex buffer
@@ -743,7 +750,7 @@
 #if VERTEX_DEBUG
     for (unsigned int i = 0; i < tempVertices.size(); i++) {
         ALOGD("orig path: point at %f %f",
-                tempVertices[i].position[0], tempVertices[i].position[1]);
+                tempVertices[i].x, tempVertices[i].y);
     }
 #endif
 
@@ -780,7 +787,7 @@
     rect.fBottom = fmaxf(rect.fBottom, y);
 }
 static void expandRectToCoverVertex(SkRect& rect, const Vertex& vertex) {
-    expandRectToCoverVertex(rect, vertex.position[0], vertex.position[1]);
+    expandRectToCoverVertex(rect, vertex.x, vertex.y);
 }
 
 template <class TYPE>
@@ -799,8 +806,8 @@
     dstBuffer.createDegenerateSeparators<TYPE>(verticesPerPoint);
 }
 
-void PathTessellator::tessellatePoints(const float* points, int count, SkPaint* paint,
-        const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
+void PathTessellator::tessellatePoints(const float* points, int count, const SkPaint* paint,
+        const mat4& transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
     const PaintInfo paintInfo(paint, transform);
 
     // determine point shape
@@ -818,7 +825,8 @@
     Vector<Vertex> outlineVertices;
     approximatePathOutlineVertices(path, true,
             paintInfo.inverseScaleX * paintInfo.inverseScaleX,
-            paintInfo.inverseScaleY * paintInfo.inverseScaleY, outlineVertices);
+            paintInfo.inverseScaleY * paintInfo.inverseScaleY,
+            OUTLINE_REFINE_THRESHOLD_SQUARED, outlineVertices);
 
     if (!outlineVertices.size()) return;
 
@@ -829,15 +837,18 @@
         getFillVerticesFromPerimeter(outlineVertices, tempBuffer);
         instanceVertices<Vertex>(tempBuffer, vertexBuffer, points, count, bounds);
     } else {
-        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer);
+        // note: pass maxAlpha directly, since we want fill to be alpha modulated
+        getFillVerticesFromPerimeterAA(paintInfo, outlineVertices, tempBuffer, paintInfo.maxAlpha);
         instanceVertices<AlphaVertex>(tempBuffer, vertexBuffer, points, count, bounds);
     }
 
-    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
+    // expand bounds from vertex coords to pixel data
+    paintInfo.expandBoundsForStrokeAA(bounds);
+
 }
 
-void PathTessellator::tessellateLines(const float* points, int count, SkPaint* paint,
-        const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
+void PathTessellator::tessellateLines(const float* points, int count, const SkPaint* paint,
+        const mat4& transform, SkRect& bounds, VertexBuffer& vertexBuffer) {
     ATRACE_CALL();
     const PaintInfo paintInfo(paint, transform);
 
@@ -873,20 +884,26 @@
         expandRectToCoverVertex(bounds, tempVerticesData[1]);
     }
 
-    expandBoundsForStroke(bounds, paint, true); // force-expand bounds to incorporate stroke
-
     // since multiple objects tessellated into buffer, separate them with degen tris
     if (paintInfo.isAA) {
         vertexBuffer.createDegenerateSeparators<AlphaVertex>(lineAllocSize);
     } else {
         vertexBuffer.createDegenerateSeparators<Vertex>(lineAllocSize);
     }
+
+    // expand bounds from vertex coords to pixel data
+    paintInfo.expandBoundsForStrokeAA(bounds);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 // Simple path line approximation
 ///////////////////////////////////////////////////////////////////////////////
 
+bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, float thresholdSquared,
+        Vector<Vertex>& outputVertices) {
+    return approximatePathOutlineVertices(path, true, 1.0f, 1.0f, thresholdSquared, outputVertices);
+}
+
 void pushToVector(Vector<Vertex>& vertices, float x, float y) {
     // TODO: make this not yuck
     vertices.push();
@@ -895,7 +912,8 @@
 }
 
 bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool forceClose,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
+        float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
+        Vector<Vertex>& outputVertices) {
     ATRACE_CALL();
 
     // TODO: to support joins other than sharp miter, join vertices should be labelled in the
@@ -922,7 +940,7 @@
                         pts[0].x(), pts[0].y(),
                         pts[2].x(), pts[2].y(),
                         pts[1].x(), pts[1].y(),
-                        sqrInvScaleX, sqrInvScaleY, outputVertices);
+                        sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
                 break;
             case SkPath::kCubic_Verb:
                 ALOGV("kCubic_Verb");
@@ -931,7 +949,7 @@
                         pts[1].x(), pts[1].y(),
                         pts[3].x(), pts[3].y(),
                         pts[2].x(), pts[2].y(),
-                        sqrInvScaleX, sqrInvScaleY, outputVertices);
+                        sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
                 break;
             default:
                 break;
@@ -939,8 +957,8 @@
     }
 
     int size = outputVertices.size();
-    if (size >= 2 && outputVertices[0].position[0] == outputVertices[size - 1].position[0] &&
-            outputVertices[0].position[1] == outputVertices[size - 1].position[1]) {
+    if (size >= 2 && outputVertices[0].x == outputVertices[size - 1].x &&
+            outputVertices[0].y == outputVertices[size - 1].y) {
         outputVertices.pop();
         return true;
     }
@@ -954,7 +972,8 @@
 void PathTessellator::recursiveCubicBezierVertices(
         float p1x, float p1y, float c1x, float c1y,
         float p2x, float p2y, float c2x, float c2y,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
+        float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
+        Vector<Vertex>& outputVertices) {
     float dx = p2x - p1x;
     float dy = p2y - p1y;
     float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx);
@@ -963,7 +982,7 @@
 
     // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors
 
-    if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+    if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
         pushToVector(outputVertices, p2x, p2y);
     } else {
@@ -987,11 +1006,11 @@
         recursiveCubicBezierVertices(
                 p1x, p1y, p1c1x, p1c1y,
                 mx, my, p1c1c2x, p1c1c2y,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
         recursiveCubicBezierVertices(
                 mx, my, p2c1c2x, p2c1c2y,
                 p2x, p2y, p2c2x, p2c2y,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
     }
 }
 
@@ -999,12 +1018,13 @@
         float ax, float ay,
         float bx, float by,
         float cx, float cy,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex>& outputVertices) {
+        float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
+        Vector<Vertex>& outputVertices) {
     float dx = bx - ax;
     float dy = by - ay;
     float d = (cx - bx) * dy - (cy - by) * dx;
 
-    if (d * d < THRESHOLD * THRESHOLD * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
+    if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) {
         // below thresh, draw line by adding endpoint
         pushToVector(outputVertices, bx, by);
     } else {
@@ -1018,9 +1038,9 @@
         float my = (acy + bcy) * 0.5f;
 
         recursiveQuadraticBezierVertices(ax, ay, mx, my, acx, acy,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
         recursiveQuadraticBezierVertices(mx, my, bx, by, bcx, bcy,
-                sqrInvScaleX, sqrInvScaleY, outputVertices);
+                sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
     }
 }
 
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index 85797fc..a215b7a 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -22,100 +22,73 @@
 #include "Matrix.h"
 #include "Rect.h"
 #include "Vertex.h"
+#include "VertexBuffer.h"
 
 namespace android {
 namespace uirenderer {
 
-class VertexBuffer {
-public:
-    VertexBuffer():
-        mBuffer(0),
-        mVertexCount(0),
-        mCleanupMethod(NULL)
-    {}
-
-    ~VertexBuffer() {
-        if (mCleanupMethod) mCleanupMethod(mBuffer);
-    }
-
-    /**
-       This should be the only method used by the PathTessellator. Subsequent calls to alloc will
-       allocate space within the first allocation (useful if you want to eventually allocate
-       multiple regions within a single VertexBuffer, such as with PathTessellator::tesselateLines()
-     */
-    template <class TYPE>
-    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 + vertexCount;
-            return reallocBuffer;
-        }
-        mVertexCount = vertexCount;
-        mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
-        mCleanupMethod = &(cleanup<TYPE>);
-
-        return (TYPE*)mBuffer;
-    }
-
-    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 + 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));
-        }
-    }
-
-private:
-    template <class TYPE>
-    static void cleanup(void* buffer) {
-        delete[] (TYPE*)buffer;
-    }
-
-    void* mBuffer;
-    unsigned int mVertexCount;
-
-    void* mReallocBuffer; // used for multi-allocation
-
-    void (*mCleanupMethod)(void*);
-};
-
 class PathTessellator {
 public:
-    static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint, bool forceExpand);
+    static void expandBoundsForStroke(SkRect& bounds, const SkPaint* paint);
 
+    /**
+     * Populates a VertexBuffer with a tessellated approximation of the input convex path, as a single
+     * triangle strip. Note: joins are not currently supported.
+     *
+     * @param path The path to be approximated
+     * @param paint The paint the path will be drawn with, indicating AA, painting style
+     *        (stroke vs fill), stroke width, stroke cap & join style, etc.
+     * @param transform The transform the path is to be drawn with, used to drive stretch-aware path
+     *        vertex approximation, and correct AA ramp offsetting.
+     * @param vertexBuffer The output buffer
+     */
     static void tessellatePath(const SkPath& path, const SkPaint* paint,
-            const mat4 *transform, VertexBuffer& vertexBuffer);
+            const mat4& transform, VertexBuffer& vertexBuffer);
 
-    static void tessellatePoints(const float* points, int count, SkPaint* paint,
-            const mat4* transform, SkRect& bounds, VertexBuffer& vertexBuffer);
+    /**
+     * Populates a VertexBuffer with a tessellated approximation of points as a single triangle
+     * strip (with degenerate tris separating), respecting the shape defined by the paint cap.
+     *
+     * @param points The center vertices of the points to be drawn
+     * @param count The number of floats making up the point vertices
+     * @param paint The paint the points will be drawn with indicating AA, stroke width & cap
+     * @param transform The transform the points will be drawn with, used to drive stretch-aware path
+     *        vertex approximation, and correct AA ramp offsetting
+     * @param bounds An output rectangle, which returns the total area covered by the output buffer
+     * @param vertexBuffer The output buffer
+     */
+    static void tessellatePoints(const float* points, int count, const 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);
+    /**
+     * Populates a VertexBuffer with a tessellated approximation of lines as a single triangle
+     * strip (with degenerate tris separating).
+     *
+     * @param points Pairs of endpoints defining the lines to be drawn
+     * @param count The number of floats making up the line vertices
+     * @param paint The paint the lines will be drawn with indicating AA, stroke width & cap
+     * @param transform The transform the points will be drawn with, used to drive stretch-aware path
+     *        vertex approximation, and correct AA ramp offsetting
+     * @param bounds An output rectangle, which returns the total area covered by the output buffer
+     * @param vertexBuffer The output buffer
+     */
+    static void tessellateLines(const float* points, int count, const SkPaint* paint,
+            const mat4& transform, SkRect& bounds, VertexBuffer& vertexBuffer);
+
+    /**
+     * Approximates a convex, CW outline into a Vector of 2d vertices.
+     *
+     * @param path The outline to be approximated
+     * @param thresholdSquared The threshold of acceptable error (in pixels) when approximating
+     * @param outputVertices An empty Vector which will be populated with the output
+     */
+    static bool approximatePathOutlineVertices(const SkPath &path, float thresholdSquared,
+            Vector<Vertex> &outputVertices);
 
 private:
     static bool approximatePathOutlineVertices(const SkPath &path, bool forceClose,
-        float sqrInvScaleX, float sqrInvScaleY, Vector<Vertex> &outputVertices);
+            float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
+            Vector<Vertex> &outputVertices);
 
 /*
   endpoints a & b,
@@ -125,7 +98,7 @@
             float ax, float ay,
             float bx, float by,
             float cx, float cy,
-            float sqrInvScaleX, float sqrInvScaleY,
+            float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
             Vector<Vertex> &outputVertices);
 
 /*
@@ -137,7 +110,7 @@
             float c1x, float c1y,
             float p2x, float p2y,
             float c2x, float c2y,
-            float sqrInvScaleX, float sqrInvScaleY,
+            float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared,
             Vector<Vertex> &outputVertices);
 };
 
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 58f5325..ee77897 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -173,7 +173,7 @@
             // 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(Vertex::gGeometryFudgeFactor, Vertex::gGeometryFudgeFactor);
+            p.translate(Vertex::GeometryFudgeFactor(), Vertex::GeometryFudgeFactor());
             glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]);
         }
         mProjection = projectionMatrix;
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index f6ac8ec..33c91b3 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -51,9 +51,8 @@
 #define PROGRAM_KEY_GRADIENT 0x8
 #define PROGRAM_KEY_BITMAP_FIRST 0x10
 #define PROGRAM_KEY_COLOR_MATRIX 0x20
-#define PROGRAM_KEY_COLOR_LIGHTING 0x40
-#define PROGRAM_KEY_COLOR_BLEND 0x80
-#define PROGRAM_KEY_BITMAP_NPOT 0x100
+#define PROGRAM_KEY_COLOR_BLEND 0x40
+#define PROGRAM_KEY_BITMAP_NPOT 0x80
 #define PROGRAM_KEY_SWAP_SRC_DST 0x2000
 
 #define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
@@ -104,7 +103,6 @@
     enum ColorModifier {
         kColorNone = 0,
         kColorMatrix,
-        kColorLighting,
         kColorBlend
     };
 
@@ -207,7 +205,7 @@
      * the fragment shader. When this method returns true, the program should
      * be provided with a modulation color.
      */
-    bool setColor(const float r, const float g, const float b, const float a) {
+    bool setColorModulate(const float a) {
         modulate = a < COLOR_COMPONENT_THRESHOLD;
         return modulate;
     }
@@ -217,7 +215,7 @@
      * the fragment shader. When this method returns true, the program should
      * be provided with a modulation color.
      */
-    bool setAlpha8Color(const float r, const float g, const float b, const float a) {
+    bool setAlpha8ColorModulate(const float r, const float g, const float b, const float a) {
         modulate = a < COLOR_COMPONENT_THRESHOLD || r > COLOR_COMPONENT_INV_THRESHOLD ||
                 g > COLOR_COMPONENT_INV_THRESHOLD || b > COLOR_COMPONENT_INV_THRESHOLD;
         return modulate;
@@ -248,9 +246,6 @@
             case kColorMatrix:
                 key |= PROGRAM_KEY_COLOR_MATRIX;
                 break;
-            case kColorLighting:
-                key |= PROGRAM_KEY_COLOR_LIGHTING;
-                break;
             case kColorBlend:
                 key |= PROGRAM_KEY_COLOR_BLEND;
                 key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index a5ce6f6..6d50410 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -148,15 +148,12 @@
 };
 const char* gFS_Uniforms_BitmapSampler =
         "uniform sampler2D bitmapSampler;\n";
-const char* gFS_Uniforms_ColorOp[4] = {
+const char* gFS_Uniforms_ColorOp[3] = {
         // None
         "",
         // Matrix
         "uniform mat4 colorMatrix;\n"
         "uniform vec4 colorMatrixVector;\n",
-        // Lighting
-        "uniform vec4 lightingMul;\n"
-        "uniform vec4 lightingAdd;\n",
         // PorterDuff
         "uniform vec4 colorBlend;\n"
 };
@@ -311,17 +308,13 @@
         "    gl_FragColor = blendFramebuffer(fragColor, gl_LastFragColor);\n";
 const char* gFS_Main_FragColor_Blend_Swap =
         "    gl_FragColor = blendFramebuffer(gl_LastFragColor, fragColor);\n";
-const char* gFS_Main_ApplyColorOp[4] = {
+const char* gFS_Main_ApplyColorOp[3] = {
         // None
         "",
         // Matrix
         "    fragColor *= colorMatrix;\n"
         "    fragColor += colorMatrixVector;\n"
         "    fragColor.rgb *= fragColor.a;\n",
-        // Lighting
-        "    float lightingAlpha = fragColor.a;\n"
-        "    fragColor = min(fragColor * lightingMul + (lightingAdd * lightingAlpha), lightingAlpha);\n"
-        "    fragColor.a = lightingAlpha;\n",
         // PorterDuff
         "    fragColor = blendColors(colorBlend, fragColor);\n"
 };
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index dabd8d4..0083b77 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -18,6 +18,7 @@
 #define ANDROID_HWUI_RECT_H
 
 #include <cmath>
+#include <SkRect.h>
 
 #include <utils/Log.h>
 
@@ -68,6 +69,13 @@
             bottom(height) {
     }
 
+    inline Rect(const SkRect& rect):
+            left(rect.fLeft),
+            top(rect.fTop),
+            right(rect.fRight),
+            bottom(rect.fBottom) {
+    }
+
     friend int operator==(const Rect& a, const Rect& b) {
         return !memcmp(&a, &b, sizeof(a));
     }
@@ -190,19 +198,19 @@
              * from this inset will only incur similarly small errors in output, due to transparency
              * in extreme outside of the geometry.
              */
-            left = floorf(left + Vertex::gGeometryFudgeFactor);
-            top = floorf(top + Vertex::gGeometryFudgeFactor);
-            right = ceilf(right - Vertex::gGeometryFudgeFactor);
-            bottom = ceilf(bottom - Vertex::gGeometryFudgeFactor);
+            left = floorf(left + Vertex::GeometryFudgeFactor());
+            top = floorf(top + Vertex::GeometryFudgeFactor());
+            right = ceilf(right - Vertex::GeometryFudgeFactor());
+            bottom = ceilf(bottom - Vertex::GeometryFudgeFactor());
         } else {
             /* For other geometry, we do the regular rounding in order to snap, but also outset the
              * bounds by a fudge factor. This ensures that ambiguous geometry (e.g. a non-AA Rect
              * with top left at (0.5, 0.5)) will err on the side of a larger damage rect.
              */
-            left = floorf(left + 0.5f - Vertex::gGeometryFudgeFactor);
-            top = floorf(top + 0.5f - Vertex::gGeometryFudgeFactor);
-            right = floorf(right + 0.5f + Vertex::gGeometryFudgeFactor);
-            bottom = floorf(bottom + 0.5f + Vertex::gGeometryFudgeFactor);
+            left = floorf(left + 0.5f - Vertex::GeometryFudgeFactor());
+            top = floorf(top + 0.5f - Vertex::GeometryFudgeFactor());
+            right = floorf(right + 0.5f + Vertex::GeometryFudgeFactor());
+            bottom = floorf(bottom + 0.5f + Vertex::GeometryFudgeFactor());
         }
     }
 
@@ -213,6 +221,13 @@
         bottom = floorf(bottom + 0.5f);
     }
 
+    void roundOut() {
+        left = floorf(left);
+        top = floorf(top);
+        right = ceilf(right);
+        bottom = ceilf(bottom);
+    }
+
     void dump() const {
         ALOGD("Rect[l=%f t=%f r=%f b=%f]", left, top, right, bottom);
     }
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
new file mode 100644
index 0000000..8aed857
--- /dev/null
+++ b/libs/hwui/RenderNode.cpp
@@ -0,0 +1,574 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define ATRACE_TAG ATRACE_TAG_VIEW
+
+#include "RenderNode.h"
+
+#include <SkCanvas.h>
+#include <algorithm>
+
+#include <utils/Trace.h>
+
+#include "Debug.h"
+#include "DisplayListOp.h"
+#include "DisplayListLogBuffer.h"
+
+namespace android {
+namespace uirenderer {
+
+void RenderNode::outputLogBuffer(int fd) {
+    DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
+    if (logBuffer.isEmpty()) {
+        return;
+    }
+
+    FILE *file = fdopen(fd, "a");
+
+    fprintf(file, "\nRecent DisplayList operations\n");
+    logBuffer.outputCommands(file);
+
+    String8 cachesLog;
+    Caches::getInstance().dumpMemoryUsage(cachesLog);
+    fprintf(file, "\nCaches:\n%s", cachesLog.string());
+    fprintf(file, "\n");
+
+    fflush(file);
+}
+
+RenderNode::RenderNode() : mDestroyed(false), mDisplayListData(0) {
+}
+
+RenderNode::~RenderNode() {
+    LOG_ALWAYS_FATAL_IF(mDestroyed, "Double destroyed DisplayList %p", this);
+
+    mDestroyed = true;
+    delete mDisplayListData;
+}
+
+void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) {
+    if (displayList) {
+        DISPLAY_LIST_LOGD("Deferring display list destruction");
+        Caches::getInstance().deleteDisplayListDeferred(displayList);
+    }
+}
+
+void RenderNode::setData(DisplayListData* data) {
+    delete mDisplayListData;
+    mDisplayListData = data;
+    if (mDisplayListData) {
+        Caches::getInstance().registerFunctors(mDisplayListData->functorCount);
+    }
+}
+
+/**
+ * This function is a simplified version of replay(), where we simply retrieve and log the
+ * display list. This function should remain in sync with the replay() function.
+ */
+void RenderNode::output(uint32_t level) {
+    ALOGD("%*sStart display list (%p, %s, render=%d)", (level - 1) * 2, "", this,
+            mName.string(), isRenderable());
+    ALOGD("%*s%s %d", level * 2, "", "Save",
+            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+
+    outputViewProperties(level);
+    int flags = DisplayListOp::kOpLogFlag_Recurse;
+    for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+        mDisplayListData->displayListOps[i]->output(level, flags);
+    }
+
+    ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
+}
+
+void RenderNode::outputViewProperties(const int level) {
+    properties().updateMatrix();
+    if (properties().mLeft != 0 || properties().mTop != 0) {
+        ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", properties().mLeft, properties().mTop);
+    }
+    if (properties().mStaticMatrix) {
+        ALOGD("%*sConcatMatrix (static) %p: " SK_MATRIX_STRING,
+                level * 2, "", properties().mStaticMatrix, SK_MATRIX_ARGS(properties().mStaticMatrix));
+    }
+    if (properties().mAnimationMatrix) {
+        ALOGD("%*sConcatMatrix (animation) %p: " SK_MATRIX_STRING,
+                level * 2, "", properties().mAnimationMatrix, SK_MATRIX_ARGS(properties().mAnimationMatrix));
+    }
+    if (properties().mMatrixFlags != 0) {
+        if (properties().mMatrixFlags == TRANSLATION) {
+            ALOGD("%*sTranslate %.2f, %.2f, %.2f",
+                    level * 2, "", properties().mTranslationX, properties().mTranslationY, properties().mTranslationZ);
+        } else {
+            ALOGD("%*sConcatMatrix %p: " MATRIX_4_STRING,
+                    level * 2, "", properties().mTransformMatrix, MATRIX_4_ARGS(properties().mTransformMatrix));
+        }
+    }
+
+    bool clipToBoundsNeeded = properties().mCaching ? false : properties().mClipToBounds;
+    if (properties().mAlpha < 1) {
+        if (properties().mCaching) {
+            ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", properties().mAlpha);
+        } else if (!properties().mHasOverlappingRendering) {
+            ALOGD("%*sScaleAlpha %.2f", level * 2, "", properties().mAlpha);
+        } else {
+            int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+            if (clipToBoundsNeeded) {
+                flags |= SkCanvas::kClipToLayer_SaveFlag;
+                clipToBoundsNeeded = false; // clipping done by save layer
+            }
+            ALOGD("%*sSaveLayerAlpha %d, %d, %d, %d, %d, 0x%x", level * 2, "",
+                    0, 0, properties().mWidth, properties().mHeight,
+                    (int)(properties().mAlpha * 255), flags);
+        }
+    }
+    if (clipToBoundsNeeded) {
+        ALOGD("%*sClipRect %d, %d, %d, %d", level * 2, "",
+                0, 0, properties().mWidth, properties().mHeight);
+    }
+}
+
+/*
+ * For property operations, we pass a savecount of 0, since the operations aren't part of the
+ * displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
+ * base saveCount (i.e., how RestoreToCount uses saveCount + properties().mCount)
+ */
+#define PROPERTY_SAVECOUNT 0
+
+template <class T>
+void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
+        const int level) {
+#if DEBUG_DISPLAY_LIST
+    outputViewProperties(level);
+#endif
+    properties().updateMatrix();
+    if (properties().mLeft != 0 || properties().mTop != 0) {
+        renderer.translate(properties().mLeft, properties().mTop);
+    }
+    if (properties().mStaticMatrix) {
+        renderer.concatMatrix(properties().mStaticMatrix);
+    } else if (properties().mAnimationMatrix) {
+        renderer.concatMatrix(properties().mAnimationMatrix);
+    }
+    if (properties().mMatrixFlags != 0) {
+        if (properties().mMatrixFlags == TRANSLATION) {
+            renderer.translate(properties().mTranslationX, properties().mTranslationY);
+        } else {
+            renderer.concatMatrix(*properties().mTransformMatrix);
+        }
+    }
+    bool clipToBoundsNeeded = properties().mCaching ? false : properties().mClipToBounds;
+    if (properties().mAlpha < 1) {
+        if (properties().mCaching) {
+            renderer.setOverrideLayerAlpha(properties().mAlpha);
+        } else if (!properties().mHasOverlappingRendering) {
+            renderer.scaleAlpha(properties().mAlpha);
+        } else {
+            // TODO: should be able to store the size of a DL at record time and not
+            // 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 (clipToBoundsNeeded) {
+                saveFlags |= SkCanvas::kClipToLayer_SaveFlag;
+                clipToBoundsNeeded = false; // clipping done by saveLayer
+            }
+
+            SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
+                    0, 0, properties().mWidth, properties().mHeight,
+                    properties().mAlpha * 255, saveFlags);
+            handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+        }
+    }
+    if (clipToBoundsNeeded) {
+        ClipRectOp* op = new (handler.allocator()) ClipRectOp(
+                0, 0, properties().mWidth, properties().mHeight, SkRegion::kIntersect_Op);
+        handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+    }
+    if (CC_UNLIKELY(properties().mOutline.willClip())) {
+        // TODO: optimize RR case
+        ClipPathOp* op = new (handler.allocator()) ClipPathOp(properties().mOutline.getPath(),
+                SkRegion::kIntersect_Op);
+        handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+    }
+}
+
+/**
+ * Apply property-based transformations to input matrix
+ *
+ * If true3dTransform is set to true, the transform applied to the input matrix will use true 4x4
+ * matrix computation instead of the Skia 3x3 matrix + camera hackery.
+ */
+void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) {
+    if (properties().mLeft != 0 || properties().mTop != 0) {
+        matrix.translate(properties().mLeft, properties().mTop);
+    }
+    if (properties().mStaticMatrix) {
+        mat4 stat(*properties().mStaticMatrix);
+        matrix.multiply(stat);
+    } else if (properties().mAnimationMatrix) {
+        mat4 anim(*properties().mAnimationMatrix);
+        matrix.multiply(anim);
+    }
+    if (properties().mMatrixFlags != 0) {
+        properties().updateMatrix();
+        if (properties().mMatrixFlags == TRANSLATION) {
+            matrix.translate(properties().mTranslationX, properties().mTranslationY,
+                    true3dTransform ? properties().mTranslationZ : 0.0f);
+        } else {
+            if (!true3dTransform) {
+                matrix.multiply(*properties().mTransformMatrix);
+            } else {
+                mat4 true3dMat;
+                true3dMat.loadTranslate(
+                        properties().mPivotX + properties().mTranslationX,
+                        properties().mPivotY + properties().mTranslationY,
+                        properties().mTranslationZ);
+                true3dMat.rotate(properties().mRotationX, 1, 0, 0);
+                true3dMat.rotate(properties().mRotationY, 0, 1, 0);
+                true3dMat.rotate(properties().mRotation, 0, 0, 1);
+                true3dMat.scale(properties().mScaleX, properties().mScaleY, 1);
+                true3dMat.translate(-properties().mPivotX, -properties().mPivotY);
+
+                matrix.multiply(true3dMat);
+            }
+        }
+    }
+}
+
+/**
+ * Organizes the DisplayList hierarchy to prepare for background projection reordering.
+ *
+ * This should be called before a call to defer() or drawDisplayList()
+ *
+ * Each DisplayList that serves as a 3d root builds its list of composited children,
+ * which are flagged to not draw in the standard draw loop.
+ */
+void RenderNode::computeOrdering() {
+    ATRACE_CALL();
+    mProjectedNodes.clear();
+
+    // TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that
+    // transform properties are applied correctly to top level children
+    if (mDisplayListData == NULL) return;
+    for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
+        DrawDisplayListOp* childOp = mDisplayListData->children[i];
+        childOp->mDisplayList->computeOrderingImpl(childOp,
+                &mProjectedNodes, &mat4::identity());
+    }
+}
+
+void RenderNode::computeOrderingImpl(
+        DrawDisplayListOp* opState,
+        Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface,
+        const mat4* transformFromProjectionSurface) {
+    mProjectedNodes.clear();
+    if (mDisplayListData == NULL || mDisplayListData->isEmpty()) return;
+
+    // TODO: should avoid this calculation in most cases
+    // TODO: just calculate single matrix, down to all leaf composited elements
+    Matrix4 localTransformFromProjectionSurface(*transformFromProjectionSurface);
+    localTransformFromProjectionSurface.multiply(opState->mTransformFromParent);
+
+    if (properties().mProjectBackwards) {
+        // composited projectee, flag for out of order draw, save matrix, and store in proj surface
+        opState->mSkipInOrderDraw = true;
+        opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface);
+        compositedChildrenOfProjectionSurface->add(opState);
+    } else {
+        // standard in order draw
+        opState->mSkipInOrderDraw = false;
+    }
+
+    if (mDisplayListData->children.size() > 0) {
+        const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0;
+        bool haveAppliedPropertiesToProjection = false;
+        for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
+            DrawDisplayListOp* childOp = mDisplayListData->children[i];
+            RenderNode* child = childOp->mDisplayList;
+
+            Vector<DrawDisplayListOp*>* projectionChildren = NULL;
+            const mat4* projectionTransform = NULL;
+            if (isProjectionReceiver && !child->properties().mProjectBackwards) {
+                // if receiving projections, collect projecting descendent
+
+                // Note that if a direct descendent is projecting backwards, we pass it's
+                // grandparent projection collection, since it shouldn't project onto it's
+                // parent, where it will already be drawing.
+                projectionChildren = &mProjectedNodes;
+                projectionTransform = &mat4::identity();
+            } else {
+                if (!haveAppliedPropertiesToProjection) {
+                    applyViewPropertyTransforms(localTransformFromProjectionSurface);
+                    haveAppliedPropertiesToProjection = true;
+                }
+                projectionChildren = compositedChildrenOfProjectionSurface;
+                projectionTransform = &localTransformFromProjectionSurface;
+            }
+            child->computeOrderingImpl(childOp, projectionChildren, projectionTransform);
+        }
+    }
+
+}
+
+class DeferOperationHandler {
+public:
+    DeferOperationHandler(DeferStateStruct& deferStruct, int level)
+        : mDeferStruct(deferStruct), mLevel(level) {}
+    inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
+        operation->defer(mDeferStruct, saveCount, mLevel, clipToBounds);
+    }
+    inline LinearAllocator& allocator() { return *(mDeferStruct.mAllocator); }
+
+private:
+    DeferStateStruct& mDeferStruct;
+    const int mLevel;
+};
+
+void RenderNode::defer(DeferStateStruct& deferStruct, const int level) {
+    DeferOperationHandler handler(deferStruct, level);
+    iterate<DeferOperationHandler>(deferStruct.mRenderer, handler, level);
+}
+
+class ReplayOperationHandler {
+public:
+    ReplayOperationHandler(ReplayStateStruct& replayStruct, int level)
+        : mReplayStruct(replayStruct), mLevel(level) {}
+    inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
+#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
+        properties().mReplayStruct.mRenderer.eventMark(operation->name());
+#endif
+        operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds);
+    }
+    inline LinearAllocator& allocator() { return *(mReplayStruct.mAllocator); }
+
+private:
+    ReplayStateStruct& mReplayStruct;
+    const int mLevel;
+};
+
+void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) {
+    ReplayOperationHandler handler(replayStruct, level);
+
+    replayStruct.mRenderer.startMark(mName.string());
+    iterate<ReplayOperationHandler>(replayStruct.mRenderer, handler, level);
+    replayStruct.mRenderer.endMark();
+
+    DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", level * 2, "", this, mName.string(),
+            replayStruct.mDrawGlStatus);
+}
+
+void RenderNode::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes) {
+    if (mDisplayListData == NULL || mDisplayListData->children.size() == 0) return;
+
+    for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
+        DrawDisplayListOp* childOp = mDisplayListData->children[i];
+        RenderNode* child = childOp->mDisplayList;
+        float childZ = child->properties().mTranslationZ;
+
+        if (childZ != 0.0f) {
+            zTranslatedNodes.add(ZDrawDisplayListOpPair(childZ, childOp));
+            childOp->mSkipInOrderDraw = true;
+        } else if (!child->properties().mProjectBackwards) {
+            // regular, in order drawing DisplayList
+            childOp->mSkipInOrderDraw = false;
+        }
+    }
+
+    // Z sort 3d children (stable-ness makes z compare fall back to standard drawing order)
+    std::stable_sort(zTranslatedNodes.begin(), zTranslatedNodes.end());
+}
+
+#define SHADOW_DELTA 0.1f
+
+template <class T>
+void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
+        ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler) {
+    const int size = zTranslatedNodes.size();
+    if (size == 0
+            || (mode == kNegativeZChildren && zTranslatedNodes[0].key > 0.0f)
+            || (mode == kPositiveZChildren && zTranslatedNodes[size - 1].key < 0.0f)) {
+        // no 3d children to draw
+        return;
+    }
+
+    int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    LinearAllocator& alloc = handler.allocator();
+    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().mWidth, properties().mHeight,
+            SkRegion::kIntersect_Op); // clip to 3d root bounds
+    handler(clipOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+
+    /**
+     * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
+     * with very similar Z heights to draw together.
+     *
+     * This way, if Views A & B have the same Z height and are both casting shadows, the shadows are
+     * underneath both, and neither's shadow is drawn on top of the other.
+     */
+    const size_t nonNegativeIndex = findNonNegativeIndex(zTranslatedNodes);
+    size_t drawIndex, shadowIndex, endIndex;
+    if (mode == kNegativeZChildren) {
+        drawIndex = 0;
+        endIndex = nonNegativeIndex;
+        shadowIndex = endIndex; // draw no shadows
+    } else {
+        drawIndex = nonNegativeIndex;
+        endIndex = size;
+        shadowIndex = drawIndex; // potentially draw shadow for each pos Z child
+    }
+    float lastCasterZ = 0.0f;
+    while (shadowIndex < endIndex || drawIndex < endIndex) {
+        if (shadowIndex < endIndex) {
+            DrawDisplayListOp* casterOp = zTranslatedNodes[shadowIndex].value;
+            RenderNode* caster = casterOp->mDisplayList;
+            const float casterZ = zTranslatedNodes[shadowIndex].key;
+            // attempt to render the shadow if the caster about to be drawn is its caster,
+            // OR if its caster's Z value is similar to the previous potential caster
+            if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) {
+
+                if (caster->properties().mAlpha > 0.0f) {
+                    mat4 shadowMatrixXY(casterOp->mTransformFromParent);
+                    caster->applyViewPropertyTransforms(shadowMatrixXY);
+
+                    // Z matrix needs actual 3d transformation, so mapped z values will be correct
+                    mat4 shadowMatrixZ(casterOp->mTransformFromParent);
+                    caster->applyViewPropertyTransforms(shadowMatrixZ, true);
+
+                    DisplayListOp* shadowOp  = new (alloc) DrawShadowOp(
+                            shadowMatrixXY, shadowMatrixZ,
+                            caster->properties().mAlpha, caster->properties().mOutline.getPath(),
+                            caster->properties().mWidth, caster->properties().mHeight);
+                    handler(shadowOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+                }
+
+                lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
+                shadowIndex++;
+                continue;
+            }
+        }
+
+        // only the actual child DL draw needs to be in save/restore,
+        // since it modifies the renderer's matrix
+        int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
+
+        DrawDisplayListOp* childOp = zTranslatedNodes[drawIndex].value;
+        RenderNode* child = childOp->mDisplayList;
+
+        renderer.concatMatrix(childOp->mTransformFromParent);
+        childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
+        handler(childOp, renderer.getSaveCount() - 1, properties().mClipToBounds);
+        childOp->mSkipInOrderDraw = true;
+
+        renderer.restoreToCount(restoreTo);
+        drawIndex++;
+    }
+    handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().mClipToBounds);
+}
+
+template <class T>
+void RenderNode::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) {
+    int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    LinearAllocator& alloc = handler.allocator();
+    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().mWidth, properties().mHeight,
+            SkRegion::kReplace_Op); // clip to projection surface root bounds
+    handler(clipOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
+
+    for (size_t i = 0; i < mProjectedNodes.size(); i++) {
+        DrawDisplayListOp* childOp = mProjectedNodes[i];
+
+        // matrix save, concat, and restore can be done safely without allocating operations
+        int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
+        renderer.concatMatrix(childOp->mTransformFromCompositingAncestor);
+        childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
+        handler(childOp, renderer.getSaveCount() - 1, properties().mClipToBounds);
+        childOp->mSkipInOrderDraw = true;
+        renderer.restoreToCount(restoreTo);
+    }
+    handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().mClipToBounds);
+}
+
+/**
+ * This function serves both defer and replay modes, and will organize the displayList's component
+ * operations for a single frame:
+ *
+ * Every 'simple' state operation that affects just the matrix and alpha (or other factors of
+ * DeferredDisplayState) may be issued directly to the renderer, but complex operations (with custom
+ * defer logic) and operations in displayListOps are issued through the 'handler' which handles the
+ * defer vs replay logic, per operation
+ */
+template <class T>
+void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
+    if (CC_UNLIKELY(mDestroyed)) { // temporary debug logging
+        ALOGW("Error: %s is drawing after destruction", mName.string());
+        CRASH();
+    }
+    if (mDisplayListData->isEmpty() || properties().mAlpha <= 0) {
+        DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string());
+        return;
+    }
+
+#if DEBUG_DISPLAY_LIST
+    Rect* clipRect = renderer.getClipRect();
+    DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.0f, %.0f, %.0f",
+            level * 2, "", this, mName.string(), clipRect->left, clipRect->top,
+            clipRect->right, clipRect->bottom);
+#endif
+
+    LinearAllocator& alloc = handler.allocator();
+    int restoreTo = renderer.getSaveCount();
+    handler(new (alloc) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
+            PROPERTY_SAVECOUNT, properties().mClipToBounds);
+
+    DISPLAY_LIST_LOGD("%*sSave %d %d", (level + 1) * 2, "",
+            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
+
+    setViewProperties<T>(renderer, handler, level + 1);
+
+    bool quickRejected = properties().mClipToBounds && renderer.quickRejectConservative(0, 0, properties().mWidth, properties().mHeight);
+    if (!quickRejected) {
+        Vector<ZDrawDisplayListOpPair> zTranslatedNodes;
+        buildZSortedChildList(zTranslatedNodes);
+
+        // for 3d root, draw children with negative z values
+        iterate3dChildren(zTranslatedNodes, kNegativeZChildren, renderer, handler);
+
+        DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
+        const int saveCountOffset = renderer.getSaveCount() - 1;
+        const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex;
+        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, saveCountOffset, properties().mClipToBounds);
+
+            if (CC_UNLIKELY(i == projectionReceiveIndex && mProjectedNodes.size() > 0)) {
+                iterateProjectedChildren(renderer, handler, level);
+            }
+        }
+
+        // for 3d root, draw children with positive z values
+        iterate3dChildren(zTranslatedNodes, kPositiveZChildren, renderer, handler);
+    }
+
+    DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
+    handler(new (alloc) RestoreToCountOp(restoreTo),
+            PROPERTY_SAVECOUNT, properties().mClipToBounds);
+    renderer.setOverrideLayerAlpha(1.0f);
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
new file mode 100644
index 0000000..177f33e
--- /dev/null
+++ b/libs/hwui/RenderNode.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef RENDERNODE_H
+#define RENDERNODE_H
+
+#ifndef LOG_TAG
+    #define LOG_TAG "OpenGLRenderer"
+#endif
+
+#include <SkCamera.h>
+#include <SkMatrix.h>
+
+#include <private/hwui/DrawGlInfo.h>
+
+#include <utils/KeyedVector.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 <androidfw/ResourceTypes.h>
+
+#include "Debug.h"
+#include "Matrix.h"
+#include "DeferredDisplayList.h"
+#include "DisplayList.h"
+#include "RenderProperties.h"
+
+class SkBitmap;
+class SkPaint;
+class SkPath;
+class SkRegion;
+
+namespace android {
+namespace uirenderer {
+
+class DeferredDisplayList;
+class DisplayListOp;
+class DisplayListRenderer;
+class OpenGLRenderer;
+class Rect;
+class Layer;
+class SkiaShader;
+
+class ClipRectOp;
+class SaveLayerOp;
+class SaveOp;
+class RestoreToCountOp;
+class DrawDisplayListOp;
+
+/**
+ * Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
+ *
+ * Recording of canvas commands is somewhat similar to SkPicture, except the canvas-recording
+ * functionality is split between DisplayListRenderer (which manages the recording), DisplayListData
+ * (which holds the actual data), and DisplayList (which holds properties and performs playback onto
+ * a renderer).
+ *
+ * Note that DisplayListData is swapped out from beneath an individual DisplayList when a view's
+ * recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay
+ * attached.
+ */
+class RenderNode {
+public:
+    ANDROID_API RenderNode();
+    ANDROID_API ~RenderNode();
+
+    // See flags defined in DisplayList.java
+    enum ReplayFlag {
+        kReplayFlag_ClipChildren = 0x1
+    };
+
+    ANDROID_API static void destroyDisplayListDeferred(RenderNode* displayList);
+    ANDROID_API static void outputLogBuffer(int fd);
+
+    ANDROID_API void setData(DisplayListData* newData);
+
+    void computeOrdering();
+    void defer(DeferStateStruct& deferStruct, const int level);
+    void replay(ReplayStateStruct& replayStruct, const int level);
+
+    ANDROID_API void output(uint32_t level = 1);
+
+    bool isRenderable() const {
+        return mDisplayListData && mDisplayListData->hasDrawOps;
+    }
+
+    void setName(const char* name) {
+        if (name) {
+            char* lastPeriod = strrchr(name, '.');
+            if (lastPeriod) {
+                mName.setTo(lastPeriod + 1);
+            } else {
+                mName.setTo(name);
+            }
+        }
+    }
+
+    RenderProperties& properties() {
+        return mProperties;
+    }
+
+    bool isProjectionReceiver() {
+        return properties().isProjectionReceiver();
+    }
+
+    int getWidth() {
+        return properties().getWidth();
+    }
+
+    int getHeight() {
+        return properties().getHeight();
+    }
+
+private:
+    typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
+
+    static size_t findNonNegativeIndex(const Vector<ZDrawDisplayListOpPair>& nodes) {
+        for (size_t i = 0; i < nodes.size(); i++) {
+            if (nodes[i].key >= 0.0f) return i;
+        }
+        return nodes.size();
+    }
+
+    enum ChildrenSelectMode {
+        kNegativeZChildren,
+        kPositiveZChildren
+    };
+
+    void outputViewProperties(const int level);
+
+    void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false);
+
+    void computeOrderingImpl(DrawDisplayListOp* opState,
+            Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface,
+            const mat4* transformFromProjectionSurface);
+
+    template <class T>
+    inline void setViewProperties(OpenGLRenderer& renderer, T& handler, const int level);
+
+    void buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes);
+
+    template <class T>
+    inline void iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
+            ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler);
+
+    template <class T>
+    inline void iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level);
+
+    template <class T>
+    inline void iterate(OpenGLRenderer& renderer, T& handler, const int level);
+
+    class TextContainer {
+    public:
+        size_t length() const {
+            return mByteLength;
+        }
+
+        const char* text() const {
+            return (const char*) mText;
+        }
+
+        size_t mByteLength;
+        const char* mText;
+    };
+
+    String8 mName;
+    bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
+
+    RenderProperties mProperties;
+    DisplayListData* mDisplayListData;
+
+    /**
+     * Draw time state - these properties are only set and used during rendering
+     */
+
+    // for projection surfaces, contains a list of all children items
+    Vector<DrawDisplayListOp*> mProjectedNodes;
+}; // class RenderNode
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* RENDERNODE_H */
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
new file mode 100644
index 0000000..902a748
--- /dev/null
+++ b/libs/hwui/RenderProperties.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "RenderProperties.h"
+
+#include <SkMatrix.h>
+
+#include "Matrix.h"
+
+namespace android {
+namespace uirenderer {
+
+RenderProperties::RenderProperties()
+        : mClipToBounds(true)
+        , mProjectBackwards(false)
+        , mProjectionReceiver(false)
+        , mAlpha(1)
+        , mHasOverlappingRendering(true)
+        , mTranslationX(0), mTranslationY(0), mTranslationZ(0)
+        , mRotation(0), mRotationX(0), mRotationY(0)
+        , mScaleX(1), mScaleY(1)
+        , mPivotX(0), mPivotY(0)
+        , mCameraDistance(0)
+        , mLeft(0), mTop(0), mRight(0), mBottom(0)
+        , mWidth(0), mHeight(0)
+        , mPrevWidth(-1), mPrevHeight(-1)
+        , mPivotExplicitlySet(false)
+        , mMatrixDirty(false)
+        , mMatrixIsIdentity(true)
+        , mTransformMatrix(NULL)
+        , mMatrixFlags(0)
+        , mTransformCamera(NULL)
+        , mTransformMatrix3D(NULL)
+        , mStaticMatrix(NULL)
+        , mAnimationMatrix(NULL)
+        , mCaching(false) {
+}
+
+RenderProperties::~RenderProperties() {
+    delete mTransformMatrix;
+    delete mTransformCamera;
+    delete mTransformMatrix3D;
+    delete mStaticMatrix;
+    delete mAnimationMatrix;
+}
+
+float RenderProperties::getPivotX() {
+    updateMatrix();
+    return mPivotX;
+}
+
+float RenderProperties::getPivotY() {
+    updateMatrix();
+    return mPivotY;
+}
+
+void RenderProperties::updateMatrix() {
+    if (mMatrixDirty) {
+        // NOTE: mTransformMatrix won't be up to date if a DisplayList goes from a complex transform
+        // to a pure translate. This is safe because the matrix isn't read in pure translate cases.
+        if (mMatrixFlags && mMatrixFlags != TRANSLATION) {
+            if (!mTransformMatrix) {
+                // only allocate a matrix if we have a complex transform
+                mTransformMatrix = new Matrix4();
+            }
+            if (!mPivotExplicitlySet) {
+                if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
+                    mPrevWidth = mWidth;
+                    mPrevHeight = mHeight;
+                    mPivotX = mPrevWidth / 2.0f;
+                    mPivotY = mPrevHeight / 2.0f;
+                }
+            }
+
+            if ((mMatrixFlags & ROTATION_3D) == 0) {
+                mTransformMatrix->loadTranslate(
+                        mPivotX + mTranslationX,
+                        mPivotY + mTranslationY,
+                        0);
+                mTransformMatrix->rotate(mRotation, 0, 0, 1);
+                mTransformMatrix->scale(mScaleX, mScaleY, 1);
+                mTransformMatrix->translate(-mPivotX, -mPivotY);
+            } else {
+                if (!mTransformCamera) {
+                    mTransformCamera = new Sk3DView();
+                    mTransformMatrix3D = new SkMatrix();
+                }
+                SkMatrix transformMatrix;
+                transformMatrix.reset();
+                mTransformCamera->save();
+                transformMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+                mTransformCamera->rotateX(mRotationX);
+                mTransformCamera->rotateY(mRotationY);
+                mTransformCamera->rotateZ(-mRotation);
+                mTransformCamera->getMatrix(mTransformMatrix3D);
+                mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
+                mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
+                        mPivotY + mTranslationY);
+                transformMatrix.postConcat(*mTransformMatrix3D);
+                mTransformCamera->restore();
+
+                mTransformMatrix->load(transformMatrix);
+            }
+        }
+        mMatrixDirty = false;
+    }
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
new file mode 100644
index 0000000..57fa4ba
--- /dev/null
+++ b/libs/hwui/RenderProperties.h
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef RENDERNODEPROPERTIES_H
+#define RENDERNODEPROPERTIES_H
+
+#include <stddef.h>
+#include <cutils/compiler.h>
+#include <androidfw/ResourceTypes.h>
+
+#include <SkCamera.h>
+#include <SkMatrix.h>
+
+#include "Rect.h"
+#include "Outline.h"
+
+#define TRANSLATION 0x0001
+#define ROTATION    0x0002
+#define ROTATION_3D 0x0004
+#define SCALE       0x0008
+#define PIVOT       0x0010
+
+class SkBitmap;
+class SkPaint;
+class SkRegion;
+
+namespace android {
+namespace uirenderer {
+
+class Matrix4;
+class RenderNode;
+
+/*
+ * Data structure that holds the properties for a RenderNode
+ */
+class RenderProperties {
+public:
+    RenderProperties();
+    virtual ~RenderProperties();
+
+    void setClipToBounds(bool clipToBounds) {
+        mClipToBounds = clipToBounds;
+    }
+
+    void setProjectBackwards(bool shouldProject) {
+        mProjectBackwards = shouldProject;
+    }
+
+    void setProjectionReceiver(bool shouldRecieve) {
+        mProjectionReceiver = shouldRecieve;
+    }
+
+    bool isProjectionReceiver() {
+        return mProjectionReceiver;
+    }
+
+    void setStaticMatrix(SkMatrix* matrix) {
+        delete mStaticMatrix;
+        mStaticMatrix = new SkMatrix(*matrix);
+    }
+
+    // Can return NULL
+    SkMatrix* getStaticMatrix() {
+        return mStaticMatrix;
+    }
+
+    void setAnimationMatrix(SkMatrix* matrix) {
+        delete mAnimationMatrix;
+        if (matrix) {
+            mAnimationMatrix = new SkMatrix(*matrix);
+        } else {
+            mAnimationMatrix = NULL;
+        }
+    }
+
+    void setAlpha(float alpha) {
+        alpha = fminf(1.0f, fmaxf(0.0f, alpha));
+        if (alpha != mAlpha) {
+            mAlpha = alpha;
+        }
+    }
+
+    float getAlpha() const {
+        return mAlpha;
+    }
+
+    void setHasOverlappingRendering(bool hasOverlappingRendering) {
+        mHasOverlappingRendering = hasOverlappingRendering;
+    }
+
+    bool hasOverlappingRendering() const {
+        return mHasOverlappingRendering;
+    }
+
+    void setTranslationX(float translationX) {
+        if (translationX != mTranslationX) {
+            mTranslationX = translationX;
+            onTranslationUpdate();
+        }
+    }
+
+    float getTranslationX() const {
+        return mTranslationX;
+    }
+
+    void setTranslationY(float translationY) {
+        if (translationY != mTranslationY) {
+            mTranslationY = translationY;
+            onTranslationUpdate();
+        }
+    }
+
+    float getTranslationY() const {
+        return mTranslationY;
+    }
+
+    void setTranslationZ(float translationZ) {
+        if (translationZ != mTranslationZ) {
+            mTranslationZ = translationZ;
+            onTranslationUpdate();
+        }
+    }
+
+    float getTranslationZ() const {
+        return mTranslationZ;
+    }
+
+    void setRotation(float rotation) {
+        if (rotation != mRotation) {
+            mRotation = rotation;
+            mMatrixDirty = true;
+            if (mRotation == 0.0f) {
+                mMatrixFlags &= ~ROTATION;
+            } else {
+                mMatrixFlags |= ROTATION;
+            }
+        }
+    }
+
+    float getRotation() const {
+        return mRotation;
+    }
+
+    void setRotationX(float rotationX) {
+        if (rotationX != mRotationX) {
+            mRotationX = rotationX;
+            mMatrixDirty = true;
+            if (mRotationX == 0.0f && mRotationY == 0.0f) {
+                mMatrixFlags &= ~ROTATION_3D;
+            } else {
+                mMatrixFlags |= ROTATION_3D;
+            }
+        }
+    }
+
+    float getRotationX() const {
+        return mRotationX;
+    }
+
+    void setRotationY(float rotationY) {
+        if (rotationY != mRotationY) {
+            mRotationY = rotationY;
+            mMatrixDirty = true;
+            if (mRotationX == 0.0f && mRotationY == 0.0f) {
+                mMatrixFlags &= ~ROTATION_3D;
+            } else {
+                mMatrixFlags |= ROTATION_3D;
+            }
+        }
+    }
+
+    float getRotationY() const {
+        return mRotationY;
+    }
+
+    void setScaleX(float scaleX) {
+        if (scaleX != mScaleX) {
+            mScaleX = scaleX;
+            mMatrixDirty = true;
+            if (mScaleX == 1.0f && mScaleY == 1.0f) {
+                mMatrixFlags &= ~SCALE;
+            } else {
+                mMatrixFlags |= SCALE;
+            }
+        }
+    }
+
+    float getScaleX() const {
+        return mScaleX;
+    }
+
+    void setScaleY(float scaleY) {
+        if (scaleY != mScaleY) {
+            mScaleY = scaleY;
+            mMatrixDirty = true;
+            if (mScaleX == 1.0f && mScaleY == 1.0f) {
+                mMatrixFlags &= ~SCALE;
+            } else {
+                mMatrixFlags |= SCALE;
+            }
+        }
+    }
+
+    float getScaleY() const {
+        return mScaleY;
+    }
+
+    void setPivotX(float pivotX) {
+        mPivotX = pivotX;
+        mMatrixDirty = true;
+        if (mPivotX == 0.0f && mPivotY == 0.0f) {
+            mMatrixFlags &= ~PIVOT;
+        } else {
+            mMatrixFlags |= PIVOT;
+        }
+        mPivotExplicitlySet = true;
+    }
+
+    ANDROID_API float getPivotX();
+
+    void setPivotY(float pivotY) {
+        mPivotY = pivotY;
+        mMatrixDirty = true;
+        if (mPivotX == 0.0f && mPivotY == 0.0f) {
+            mMatrixFlags &= ~PIVOT;
+        } else {
+            mMatrixFlags |= PIVOT;
+        }
+        mPivotExplicitlySet = true;
+    }
+
+    ANDROID_API float getPivotY();
+
+    void setCameraDistance(float distance) {
+        if (distance != mCameraDistance) {
+            mCameraDistance = distance;
+            mMatrixDirty = true;
+            if (!mTransformCamera) {
+                mTransformCamera = new Sk3DView();
+                mTransformMatrix3D = new SkMatrix();
+            }
+            mTransformCamera->setCameraLocation(0, 0, distance);
+        }
+    }
+
+    float getCameraDistance() const {
+        return mCameraDistance;
+    }
+
+    void setLeft(int left) {
+        if (left != mLeft) {
+            mLeft = left;
+            mWidth = mRight - mLeft;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getLeft() const {
+        return mLeft;
+    }
+
+    void setTop(int top) {
+        if (top != mTop) {
+            mTop = top;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getTop() const {
+        return mTop;
+    }
+
+    void setRight(int right) {
+        if (right != mRight) {
+            mRight = right;
+            mWidth = mRight - mLeft;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getRight() const {
+        return mRight;
+    }
+
+    void setBottom(int bottom) {
+        if (bottom != mBottom) {
+            mBottom = bottom;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getBottom() const {
+        return mBottom;
+    }
+
+    void setLeftTop(int left, int top) {
+        if (left != mLeft || top != mTop) {
+            mLeft = left;
+            mTop = top;
+            mWidth = mRight - mLeft;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+        if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
+            mLeft = left;
+            mTop = top;
+            mRight = right;
+            mBottom = bottom;
+            mWidth = mRight - mLeft;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void offsetLeftRight(float offset) {
+        if (offset != 0) {
+            mLeft += offset;
+            mRight += offset;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void offsetTopBottom(float offset) {
+        if (offset != 0) {
+            mTop += offset;
+            mBottom += offset;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void setCaching(bool caching) {
+        mCaching = caching;
+    }
+
+    int getWidth() const {
+        return mWidth;
+    }
+
+    int getHeight() const {
+        return mHeight;
+    }
+
+    Outline& outline() {
+        return mOutline;
+    }
+
+private:
+    void onTranslationUpdate() {
+        mMatrixDirty = true;
+        if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) {
+            mMatrixFlags &= ~TRANSLATION;
+        } else {
+            mMatrixFlags |= TRANSLATION;
+        }
+    }
+
+    void updateMatrix();
+
+    // Rendering properties
+    Outline mOutline;
+    bool mClipToBounds;
+    bool mProjectBackwards;
+    bool mProjectionReceiver;
+    float mAlpha;
+    bool mHasOverlappingRendering;
+    float mTranslationX, mTranslationY, mTranslationZ;
+    float mRotation, mRotationX, mRotationY;
+    float mScaleX, mScaleY;
+    float mPivotX, mPivotY;
+    float mCameraDistance;
+    int mLeft, mTop, mRight, mBottom;
+    int mWidth, mHeight;
+    int mPrevWidth, mPrevHeight;
+    bool mPivotExplicitlySet;
+    bool mMatrixDirty;
+    bool mMatrixIsIdentity;
+
+    /**
+     * Stores the total transformation of the DisplayList based upon its scalar
+     * translate/rotate/scale properties.
+     *
+     * In the common translation-only case, the matrix isn't allocated and the mTranslation
+     * properties are used directly.
+     */
+    Matrix4* mTransformMatrix;
+    uint32_t mMatrixFlags;
+    Sk3DView* mTransformCamera;
+    SkMatrix* mTransformMatrix3D;
+    SkMatrix* mStaticMatrix;
+    SkMatrix* mAnimationMatrix;
+    bool mCaching;
+
+    friend class RenderNode;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* RENDERNODEPROPERTIES_H */
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
new file mode 100644
index 0000000..efcea5f
--- /dev/null
+++ b/libs/hwui/Renderer.h
@@ -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.
+ */
+
+#ifndef ANDROID_HWUI_RENDERER_H
+#define ANDROID_HWUI_RENDERER_H
+
+#include <SkRegion.h>
+
+#include <utils/String8.h>
+
+#include "AssetAtlas.h"
+#include "SkPaint.h"
+
+namespace android {
+
+class Functor;
+struct Res_png_9patch;
+
+namespace uirenderer {
+
+class RenderNode;
+class Layer;
+class Matrix4;
+class SkiaColorFilter;
+class SkiaShader;
+class Patch;
+
+enum DrawOpMode {
+    kDrawOpMode_Immediate,
+    kDrawOpMode_Defer,
+    kDrawOpMode_Flush
+};
+
+/**
+ * Hwui's abstract version of Canvas.
+ *
+ * Provides methods for frame state operations, as well as the SkCanvas style transform/clip state,
+ * and varied drawing operations.
+ *
+ * Should at some point interact with native SkCanvas.
+ */
+class ANDROID_API Renderer {
+public:
+    virtual ~Renderer() {}
+
+    /**
+     * Indicates whether this renderer is recording drawing commands for later playback.
+     * If this method returns true, the drawing commands are deferred.
+     */
+    virtual bool isRecording() const {
+        return false;
+    }
+
+    /**
+     * Safely retrieves the mode from the specified xfermode. If the specified
+     * xfermode is null, the mode is assumed to be SkXfermode::kSrcOver_Mode.
+     */
+    static inline SkXfermode::Mode getXfermode(SkXfermode* mode) {
+        SkXfermode::Mode resultMode;
+        if (!SkXfermode::AsMode(mode, &resultMode)) {
+            resultMode = SkXfermode::kSrcOver_Mode;
+        }
+        return resultMode;
+    }
+
+// ----------------------------------------------------------------------------
+// Frame state operations
+// ----------------------------------------------------------------------------
+    /**
+     * Sets the dimension of the underlying drawing surface. This method must
+     * be called at least once every time the drawing surface changes size.
+     *
+     * @param width The width in pixels of the underlysing surface
+     * @param height The height in pixels of the underlysing surface
+     */
+    virtual void setViewport(int width, int height) = 0;
+
+    /**
+     * Prepares the renderer to draw a frame. This method must be invoked
+     * at the beginning of each frame. When this method is invoked, the
+     * entire drawing surface is assumed to be redrawn.
+     *
+     * @param opaque If true, the target surface is considered opaque
+     *               and will not be cleared. If false, the target surface
+     *               will be cleared
+     */
+    virtual status_t prepare(bool opaque) = 0;
+
+    /**
+     * Prepares the renderer to draw a frame. This method must be invoked
+     * at the beginning of each frame. Only the specified rectangle of the
+     * frame is assumed to be dirty. A clip will automatically be set to
+     * the specified rectangle.
+     *
+     * @param left The left coordinate of the dirty rectangle
+     * @param top The top coordinate of the dirty rectangle
+     * @param right The right coordinate of the dirty rectangle
+     * @param bottom The bottom coordinate of the dirty rectangle
+     * @param opaque If true, the target surface is considered opaque
+     *               and will not be cleared. If false, the target surface
+     *               will be cleared in the specified dirty rectangle
+     */
+    virtual status_t prepareDirty(float left, float top, float right, float bottom,
+            bool opaque) = 0;
+
+    /**
+     * Indicates the end of a frame. This method must be invoked whenever
+     * the caller is done rendering a frame.
+     */
+    virtual void finish() = 0;
+
+    /**
+     * This method must be invoked before handing control over to a draw functor.
+     * See callDrawGLFunction() for instance.
+     *
+     * This command must not be recorded inside display lists.
+     */
+    virtual void interrupt() = 0;
+
+    /**
+     * This method must be invoked after getting control back from a draw functor.
+     *
+     * This command must not be recorded inside display lists.
+     */
+    virtual void resume() = 0;
+
+// ----------------------------------------------------------------------------
+// Canvas state operations
+// ----------------------------------------------------------------------------
+    // Save (layer)
+    virtual int getSaveCount() const = 0;
+    virtual int save(int flags) = 0;
+    virtual void restore() = 0;
+    virtual void restoreToCount(int saveCount) = 0;
+
+    virtual int saveLayer(float left, float top, float right, float bottom,
+            const SkPaint* paint, int flags) = 0;
+
+    int saveLayerAlpha(float left, float top, float right, float bottom,
+            int alpha, int flags) {
+        SkPaint paint;
+        paint.setAlpha(alpha);
+        return saveLayer(left, top, right, bottom, &paint, flags);
+    }
+
+    // Matrix
+    virtual void getMatrix(SkMatrix* outMatrix) const = 0;
+    virtual void translate(float dx, float dy, float dz = 0.0f) = 0;
+    virtual void rotate(float degrees) = 0;
+    virtual void scale(float sx, float sy) = 0;
+    virtual void skew(float sx, float sy) = 0;
+
+    virtual void setMatrix(const SkMatrix* matrix) = 0;
+    virtual void concatMatrix(const SkMatrix* matrix) = 0;
+
+    // clip
+    virtual const Rect& getClipBounds() const = 0;
+    virtual bool quickRejectConservative(float left, float top,
+            float right, float bottom) const = 0;
+    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op) = 0;
+    virtual bool clipPath(const SkPath* path, SkRegion::Op op) = 0;
+    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op) = 0;
+
+    // Misc - should be implemented with SkPaint inspection
+    virtual void resetShader() = 0;
+    virtual void setupShader(SkiaShader* shader) = 0;
+
+    virtual void resetShadow() = 0;
+    virtual void setupShadow(float radius, float dx, float dy, int color) = 0;
+
+    virtual void resetPaintFilter() = 0;
+    virtual void setupPaintFilter(int clearBits, int setBits) = 0;
+
+// ----------------------------------------------------------------------------
+// Canvas draw operations
+// ----------------------------------------------------------------------------
+    virtual status_t drawColor(int color, SkXfermode::Mode mode) = 0;
+
+    // Bitmap-based
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint) = 0;
+    virtual status_t drawBitmap(const SkBitmap* bitmap, const SkMatrix* matrix,
+            const SkPaint* paint) = 0;
+    virtual status_t drawBitmap(const SkBitmap* bitmap, float srcLeft, float srcTop,
+            float srcRight, float srcBottom, float dstLeft, float dstTop,
+            float dstRight, float dstBottom, const SkPaint* paint) = 0;
+    virtual status_t drawBitmapData(const SkBitmap* bitmap, float left, float top,
+            const SkPaint* paint) = 0;
+    virtual status_t drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int meshHeight,
+            const float* vertices, const int* colors, const SkPaint* paint) = 0;
+    virtual status_t drawPatch(const SkBitmap* bitmap, const Res_png_9patch* patch,
+            float left, float top, float right, float bottom, const SkPaint* paint) = 0;
+
+    // Shapes
+    virtual status_t drawRect(float left, float top, float right, float bottom,
+            const SkPaint* paint) = 0;
+    virtual status_t drawRects(const float* rects, int count, const SkPaint* paint) = 0;
+    virtual status_t drawRoundRect(float left, float top, float right, float bottom,
+            float rx, float ry, const SkPaint* paint) = 0;
+    virtual status_t drawCircle(float x, float y, float radius, const SkPaint* paint) = 0;
+    virtual status_t drawOval(float left, float top, float right, float bottom,
+            const SkPaint* paint) = 0;
+    virtual status_t drawArc(float left, float top, float right, float bottom,
+            float startAngle, float sweepAngle, bool useCenter, const SkPaint* paint) = 0;
+    virtual status_t drawPath(const SkPath* path, const SkPaint* paint) = 0;
+    virtual status_t drawLines(const float* points, int count, const SkPaint* paint) = 0;
+    virtual status_t drawPoints(const float* points, int count, const SkPaint* paint) = 0;
+
+    // Text
+    virtual status_t drawText(const char* text, int bytesCount, int count, float x, float y,
+            const float* positions, const SkPaint* paint, float totalAdvance, const Rect& bounds,
+            DrawOpMode drawOpMode = kDrawOpMode_Immediate) = 0;
+    virtual status_t drawTextOnPath(const char* text, int bytesCount, int count, const SkPath* path,
+            float hOffset, float vOffset, const SkPaint* paint) = 0;
+    virtual status_t drawPosText(const char* text, int bytesCount, int count,
+            const float* positions, const SkPaint* paint) = 0;
+
+// ----------------------------------------------------------------------------
+// Canvas draw operations - special
+// ----------------------------------------------------------------------------
+    virtual status_t drawLayer(Layer* layer, float x, float y) = 0;
+    virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty,
+            int32_t replayFlags) = 0;
+
+    // TODO: rename for consistency
+    virtual status_t callDrawGLFunction(Functor* functor, Rect& dirty) = 0;
+}; // class Renderer
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_RENDERER_H
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
index d276a29..5562f34 100644
--- a/libs/hwui/ResourceCache.cpp
+++ b/libs/hwui/ResourceCache.cpp
@@ -40,7 +40,7 @@
 
 ResourceCache::ResourceCache() {
     Mutex::Autolock _l(mLock);
-    mCache = new KeyedVector<void*, ResourceReference*>();
+    mCache = new KeyedVector<const void*, ResourceReference*>();
 }
 
 ResourceCache::~ResourceCache() {
@@ -61,13 +61,13 @@
     incrementRefcountLocked(resource, resourceType);
 }
 
-void ResourceCache::incrementRefcount(SkBitmap* bitmapResource) {
+void ResourceCache::incrementRefcount(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcount((void*) bitmapResource, kBitmap);
 }
 
-void ResourceCache::incrementRefcount(SkPath* pathResource) {
+void ResourceCache::incrementRefcount(const SkPath* pathResource) {
     incrementRefcount((void*) pathResource, kPath);
 }
 
@@ -76,12 +76,7 @@
     incrementRefcount((void*) shaderResource, kShader);
 }
 
-void ResourceCache::incrementRefcount(SkiaColorFilter* filterResource) {
-    SkSafeRef(filterResource->getSkColorFilter());
-    incrementRefcount((void*) filterResource, kColorFilter);
-}
-
-void ResourceCache::incrementRefcount(Res_png_9patch* patchResource) {
+void ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) {
     incrementRefcount((void*) patchResource, kNinePatch);
 }
 
@@ -99,13 +94,13 @@
     ref->refCount++;
 }
 
-void ResourceCache::incrementRefcountLocked(SkBitmap* bitmapResource) {
+void ResourceCache::incrementRefcountLocked(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalRef();
     SkSafeRef(bitmapResource->getColorTable());
     incrementRefcountLocked((void*) bitmapResource, kBitmap);
 }
 
-void ResourceCache::incrementRefcountLocked(SkPath* pathResource) {
+void ResourceCache::incrementRefcountLocked(const SkPath* pathResource) {
     incrementRefcountLocked((void*) pathResource, kPath);
 }
 
@@ -114,12 +109,7 @@
     incrementRefcountLocked((void*) shaderResource, kShader);
 }
 
-void ResourceCache::incrementRefcountLocked(SkiaColorFilter* filterResource) {
-    SkSafeRef(filterResource->getSkColorFilter());
-    incrementRefcountLocked((void*) filterResource, kColorFilter);
-}
-
-void ResourceCache::incrementRefcountLocked(Res_png_9patch* patchResource) {
+void ResourceCache::incrementRefcountLocked(const Res_png_9patch* patchResource) {
     incrementRefcountLocked((void*) patchResource, kNinePatch);
 }
 
@@ -132,13 +122,13 @@
     decrementRefcountLocked(resource);
 }
 
-void ResourceCache::decrementRefcount(SkBitmap* bitmapResource) {
+void ResourceCache::decrementRefcount(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcount((void*) bitmapResource);
 }
 
-void ResourceCache::decrementRefcount(SkPath* pathResource) {
+void ResourceCache::decrementRefcount(const SkPath* pathResource) {
     decrementRefcount((void*) pathResource);
 }
 
@@ -147,12 +137,7 @@
     decrementRefcount((void*) shaderResource);
 }
 
-void ResourceCache::decrementRefcount(SkiaColorFilter* filterResource) {
-    SkSafeUnref(filterResource->getSkColorFilter());
-    decrementRefcount((void*) filterResource);
-}
-
-void ResourceCache::decrementRefcount(Res_png_9patch* patchResource) {
+void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) {
     decrementRefcount((void*) patchResource);
 }
 
@@ -173,13 +158,13 @@
     }
 }
 
-void ResourceCache::decrementRefcountLocked(SkBitmap* bitmapResource) {
+void ResourceCache::decrementRefcountLocked(const SkBitmap* bitmapResource) {
     bitmapResource->pixelRef()->globalUnref();
     SkSafeUnref(bitmapResource->getColorTable());
     decrementRefcountLocked((void*) bitmapResource);
 }
 
-void ResourceCache::decrementRefcountLocked(SkPath* pathResource) {
+void ResourceCache::decrementRefcountLocked(const SkPath* pathResource) {
     decrementRefcountLocked((void*) pathResource);
 }
 
@@ -188,12 +173,7 @@
     decrementRefcountLocked((void*) shaderResource);
 }
 
-void ResourceCache::decrementRefcountLocked(SkiaColorFilter* filterResource) {
-    SkSafeUnref(filterResource->getSkColorFilter());
-    decrementRefcountLocked((void*) filterResource);
-}
-
-void ResourceCache::decrementRefcountLocked(Res_png_9patch* patchResource) {
+void ResourceCache::decrementRefcountLocked(const Res_png_9patch* patchResource) {
     decrementRefcountLocked((void*) patchResource);
 }
 
@@ -224,12 +204,12 @@
     }
 }
 
-void ResourceCache::destructor(SkBitmap* resource) {
+void ResourceCache::destructor(const SkBitmap* resource) {
     Mutex::Autolock _l(mLock);
     destructorLocked(resource);
 }
 
-void ResourceCache::destructorLocked(SkBitmap* resource) {
+void ResourceCache::destructorLocked(const SkBitmap* resource) {
     ssize_t index = mCache->indexOfKey(resource);
     ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
     if (ref == NULL) {
@@ -266,25 +246,6 @@
     }
 }
 
-void ResourceCache::destructor(SkiaColorFilter* resource) {
-    Mutex::Autolock _l(mLock);
-    destructorLocked(resource);
-}
-
-void ResourceCache::destructorLocked(SkiaColorFilter* resource) {
-    ssize_t index = mCache->indexOfKey(resource);
-    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
-    if (ref == NULL) {
-        // If we're not tracking this resource, just delete it
-        delete resource;
-        return;
-    }
-    ref->destroyed = true;
-    if (ref->refCount == 0) {
-        deleteResourceReferenceLocked(resource, ref);
-    }
-}
-
 void ResourceCache::destructor(Res_png_9patch* resource) {
     Mutex::Autolock _l(mLock);
     destructorLocked(resource);
@@ -348,7 +309,7 @@
  * This method should only be called while the mLock mutex is held (that mutex is grabbed
  * by the various destructor() and recycle() methods which call this method).
  */
-void ResourceCache::deleteResourceReferenceLocked(void* resource, ResourceReference* ref) {
+void ResourceCache::deleteResourceReferenceLocked(const void* resource, ResourceReference* ref) {
     if (ref->recycled && ref->resourceType == kBitmap) {
         ((SkBitmap*) resource)->setPixels(NULL, NULL);
     }
@@ -377,11 +338,6 @@
                 delete shader;
             }
             break;
-            case kColorFilter: {
-                SkiaColorFilter* filter = (SkiaColorFilter*) resource;
-                delete filter;
-            }
-            break;
             case kNinePatch: {
                 if (Caches::hasInstance()) {
                     Caches::getInstance().patchCache.removeDeferred((Res_png_9patch*) resource);
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index ea0c1b5..4097ba4 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -20,7 +20,6 @@
 #include <cutils/compiler.h>
 
 #include <SkBitmap.h>
-#include <SkiaColorFilter.h>
 #include <SkiaShader.h>
 
 #include <utils/KeyedVector.h>
@@ -38,7 +37,6 @@
 enum ResourceType {
     kBitmap,
     kShader,
-    kColorFilter,
     kNinePatch,
     kPath,
     kLayer
@@ -70,51 +68,45 @@
     void lock();
     void unlock();
 
-    void incrementRefcount(SkPath* resource);
-    void incrementRefcount(SkBitmap* resource);
+    void incrementRefcount(const SkPath* resource);
+    void incrementRefcount(const SkBitmap* resource);
     void incrementRefcount(SkiaShader* resource);
-    void incrementRefcount(SkiaColorFilter* resource);
-    void incrementRefcount(Res_png_9patch* resource);
+    void incrementRefcount(const Res_png_9patch* resource);
     void incrementRefcount(Layer* resource);
 
-    void incrementRefcountLocked(SkPath* resource);
-    void incrementRefcountLocked(SkBitmap* resource);
+    void incrementRefcountLocked(const SkPath* resource);
+    void incrementRefcountLocked(const SkBitmap* resource);
     void incrementRefcountLocked(SkiaShader* resource);
-    void incrementRefcountLocked(SkiaColorFilter* resource);
-    void incrementRefcountLocked(Res_png_9patch* resource);
+    void incrementRefcountLocked(const Res_png_9patch* resource);
     void incrementRefcountLocked(Layer* resource);
 
-    void decrementRefcount(SkBitmap* resource);
-    void decrementRefcount(SkPath* resource);
+    void decrementRefcount(const SkBitmap* resource);
+    void decrementRefcount(const SkPath* resource);
     void decrementRefcount(SkiaShader* resource);
-    void decrementRefcount(SkiaColorFilter* resource);
-    void decrementRefcount(Res_png_9patch* resource);
+    void decrementRefcount(const Res_png_9patch* resource);
     void decrementRefcount(Layer* resource);
 
-    void decrementRefcountLocked(SkBitmap* resource);
-    void decrementRefcountLocked(SkPath* resource);
+    void decrementRefcountLocked(const SkBitmap* resource);
+    void decrementRefcountLocked(const SkPath* resource);
     void decrementRefcountLocked(SkiaShader* resource);
-    void decrementRefcountLocked(SkiaColorFilter* resource);
-    void decrementRefcountLocked(Res_png_9patch* resource);
+    void decrementRefcountLocked(const Res_png_9patch* resource);
     void decrementRefcountLocked(Layer* resource);
 
     void destructor(SkPath* resource);
-    void destructor(SkBitmap* resource);
+    void destructor(const 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(const SkBitmap* resource);
     void destructorLocked(SkiaShader* resource);
-    void destructorLocked(SkiaColorFilter* resource);
     void destructorLocked(Res_png_9patch* resource);
 
     bool recycle(SkBitmap* resource);
     bool recycleLocked(SkBitmap* resource);
 
 private:
-    void deleteResourceReferenceLocked(void* resource, ResourceReference* ref);
+    void deleteResourceReferenceLocked(const void* resource, ResourceReference* ref);
 
     void incrementRefcount(void* resource, ResourceType resourceType);
     void incrementRefcountLocked(void* resource, ResourceType resourceType);
@@ -131,7 +123,7 @@
      */
     mutable Mutex mLock;
 
-    KeyedVector<void*, ResourceReference*>* mCache;
+    KeyedVector<const void*, ResourceReference*>* mCache;
 };
 
 }; // namespace uirenderer
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
new file mode 100644
index 0000000..4d0edfb
--- /dev/null
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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"
+#define ATRACE_TAG ATRACE_TAG_VIEW
+
+#include <math.h>
+#include <utils/Log.h>
+#include <utils/Trace.h>
+
+#include "AmbientShadow.h"
+#include "ShadowTessellator.h"
+#include "SpotShadow.h"
+
+namespace android {
+namespace uirenderer {
+
+template<typename T>
+static inline T max(T a, T b) {
+    return a > b ? a : b;
+}
+
+VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
+        const Vector3* casterPolygon, int casterVertexCount,
+        const Vector3& centroid3d, const Rect& casterBounds,
+        const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer) {
+    ATRACE_CALL();
+
+    // A bunch of parameters to tweak the shadow.
+    // TODO: Allow some of these changable by debug settings or APIs.
+    const float heightFactor = 1.0f / 128;
+    const float geomFactor = 64;
+
+    Rect ambientShadowBounds(casterBounds);
+    ambientShadowBounds.outset(maxZ * geomFactor * heightFactor);
+
+    if (!localClip.intersects(ambientShadowBounds)) {
+#if DEBUG_SHADOW
+        ALOGD("Ambient shadow is out of clip rect!");
+#endif
+        return kVertexBufferMode_OnePolyRingShadow;
+    }
+
+    return AmbientShadow::createAmbientShadow(isCasterOpaque, casterPolygon,
+            casterVertexCount, centroid3d, heightFactor, geomFactor,
+            shadowVertexBuffer);
+
+}
+
+VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
+        const Vector3* casterPolygon, int casterVertexCount,
+        const Vector3& lightPosScale, const mat4& receiverTransform,
+        int screenWidth, int screenHeight, const Rect& casterBounds,
+        const Rect& localClip, VertexBuffer& shadowVertexBuffer) {
+    ATRACE_CALL();
+
+    // A bunch of parameters to tweak the shadow.
+    // TODO: Allow some of these changable by debug settings or APIs.
+    int maximal = max(screenWidth, screenHeight);
+    Vector3 lightCenter(screenWidth * lightPosScale.x, screenHeight * lightPosScale.y,
+            maximal * lightPosScale.z);
+#if DEBUG_SHADOW
+    ALOGD("light center %f %f %f", lightCenter.x, lightCenter.y, lightCenter.z);
+#endif
+
+    // light position (because it's in local space) needs to compensate for receiver transform
+    // TODO: should apply to light orientation, not just position
+    Matrix4 reverseReceiverTransform;
+    reverseReceiverTransform.loadInverse(receiverTransform);
+    reverseReceiverTransform.mapPoint3d(lightCenter);
+
+    const float lightSize = maximal / 4;
+    const int lightVertexCount = 8;
+
+    // Now light and caster are both in local space, we will check whether
+    // the shadow is within the clip area.
+    Rect lightRect = Rect(lightCenter.x - lightSize, lightCenter.y - lightSize,
+            lightCenter.x + lightSize, lightCenter.y + lightSize);
+    lightRect.unionWith(localClip);
+    if (!lightRect.intersects(casterBounds)) {
+#if DEBUG_SHADOW
+        ALOGD("Spot shadow is out of clip rect!");
+#endif
+        return kVertexBufferMode_OnePolyRingShadow;
+    }
+
+    VertexBufferMode mode = SpotShadow::createSpotShadow(isCasterOpaque,
+            casterPolygon, casterVertexCount, lightCenter, lightSize,
+            lightVertexCount, shadowVertexBuffer);
+
+#if DEBUG_SHADOW
+     if(shadowVertexBuffer.getVertexCount() <= 0) {
+        ALOGD("Spot shadow generation failed %d", shadowVertexBuffer.getVertexCount());
+     }
+#endif
+     return mode;
+}
+
+void ShadowTessellator::generateShadowIndices(uint16_t* shadowIndices) {
+    int currentIndex = 0;
+    const int rays = SHADOW_RAY_COUNT;
+    // For the penumbra area.
+    for (int layer = 0; layer < 2; layer ++) {
+        int baseIndex = layer * rays;
+        for (int i = 0; i < rays; i++) {
+            shadowIndices[currentIndex++] = i + baseIndex;
+            shadowIndices[currentIndex++] = rays + i + baseIndex;
+        }
+        // To close the loop, back to the ray 0.
+        shadowIndices[currentIndex++] = 0 + baseIndex;
+         // Note this is the same as the first index of next layer loop.
+        shadowIndices[currentIndex++] = rays + baseIndex;
+    }
+
+#if DEBUG_SHADOW
+    if (currentIndex != MAX_SHADOW_INDEX_COUNT) {
+        ALOGW("vertex index count is wrong. current %d, expected %d",
+                currentIndex, MAX_SHADOW_INDEX_COUNT);
+    }
+    for (int i = 0; i < MAX_SHADOW_INDEX_COUNT; i++) {
+        ALOGD("vertex index is (%d, %d)", i, shadowIndices[i]);
+    }
+#endif
+}
+
+/**
+ * Calculate the centroid of a 2d polygon.
+ *
+ * @param poly The polygon, which is represented in a Vector2 array.
+ * @param polyLength The length of the polygon in terms of number of vertices.
+ * @return the centroid of the polygon.
+ */
+Vector2 ShadowTessellator::centroid2d(const Vector2* poly, int polyLength) {
+    double sumx = 0;
+    double sumy = 0;
+    int p1 = polyLength - 1;
+    double area = 0;
+    for (int p2 = 0; p2 < polyLength; p2++) {
+        double x1 = poly[p1].x;
+        double y1 = poly[p1].y;
+        double x2 = poly[p2].x;
+        double y2 = poly[p2].y;
+        double a = (x1 * y2 - x2 * y1);
+        sumx += (x1 + x2) * a;
+        sumy += (y1 + y2) * a;
+        area += a;
+        p1 = p2;
+    }
+
+    Vector2 centroid = poly[0];
+    if (area != 0) {
+        centroid = Vector2(sumx / (3 * area), sumy / (3 * area));
+    } else {
+        ALOGW("Area is 0 while computing centroid!");
+    }
+    return centroid;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
new file mode 100644
index 0000000..ff3de74
--- /dev/null
+++ b/libs/hwui/ShadowTessellator.h
@@ -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.
+ */
+
+#ifndef ANDROID_HWUI_SHADOW_TESSELLATOR_H
+#define ANDROID_HWUI_SHADOW_TESSELLATOR_H
+
+#include "Debug.h"
+#include "Matrix.h"
+#include "OpenGLRenderer.h"
+#include "VertexBuffer.h"
+
+namespace android {
+namespace uirenderer {
+
+// All SHADOW_* are used to define all the geometry property of shadows.
+// Use a simplified example to illustrate the geometry setup here.
+// Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which
+// are 0 to 5 and 6 to 11. The area between them will be the penumbra area, and
+// the area inside the 2nd hexagon is the umbra.
+// Ambient shadow is using only 1 layer for opaque caster, otherwise, spot
+// shadow and ambient shadow are using 2 layers.
+// Triange strip indices for penumbra area: (0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 0, 6)
+//                 0
+//
+//      5          6         1
+//           11         7
+//
+//           10         8
+//      4          9         2
+//
+//                 3
+
+// The total number of rays starting from the centroid of shadow area, in order
+// to generate the shadow geometry.
+#define SHADOW_RAY_COUNT 128
+
+// The total number of all the vertices representing the shadow.
+// For the case we only have 1 layer, then we will just fill only 2/3 of it.
+#define SHADOW_VERTEX_COUNT (3 * SHADOW_RAY_COUNT)
+
+// The total number of indices used for drawing the shadow geometry as triangle strips.
+// Depending on the mode we are drawing, we can have 1 layer or 2 layers.
+// Therefore, we only build the longer index buffer.
+#define TWO_POLY_RING_SHADOW_INDEX_COUNT (4 * (SHADOW_RAY_COUNT + 1))
+#define ONE_POLY_RING_SHADOW_INDEX_COUNT (2 * (SHADOW_RAY_COUNT + 1))
+
+#define MAX_SHADOW_INDEX_COUNT TWO_POLY_RING_SHADOW_INDEX_COUNT
+
+#define SHADOW_MIN_CASTER_Z 0.001f
+
+class ShadowTessellator {
+public:
+    static VertexBufferMode tessellateAmbientShadow(bool isCasterOpaque,
+            const Vector3* casterPolygon, int casterVertexCount,
+            const Vector3& centroid3d,  const Rect& casterBounds,
+            const Rect& localClip, float maxZ, VertexBuffer& shadowVertexBuffer);
+
+    static VertexBufferMode tessellateSpotShadow(bool isCasterOpaque,
+            const Vector3* casterPolygon, int casterVertexCount,
+            const Vector3& lightPosScale, const mat4& receiverTransform,
+            int screenWidth, int screenHeight, const Rect& casterBounds,
+            const Rect& localClip, VertexBuffer& shadowVertexBuffer);
+
+    static void generateShadowIndices(uint16_t*  shadowIndices);
+
+    static Vector2 centroid2d(const Vector2* poly, int polyLength);
+}; // ShadowTessellator
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_SHADOW_TESSELLATOR_H
diff --git a/libs/hwui/SkiaColorFilter.cpp b/libs/hwui/SkiaColorFilter.cpp
deleted file mode 100644
index df918be..0000000
--- a/libs/hwui/SkiaColorFilter.cpp
+++ /dev/null
@@ -1,117 +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 "SkiaColorFilter.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Base color filter
-///////////////////////////////////////////////////////////////////////////////
-
-SkiaColorFilter::SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend):
-        mType(type), mBlend(blend), mSkFilter(skFilter) {
-}
-
-SkiaColorFilter::~SkiaColorFilter() {
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Color matrix filter
-///////////////////////////////////////////////////////////////////////////////
-
-SkiaColorMatrixFilter::SkiaColorMatrixFilter(SkColorFilter* skFilter, float* matrix, float* vector):
-        SkiaColorFilter(skFilter, kColorMatrix, true), mMatrix(matrix), mVector(vector) {
-    // Skia uses the range [0..255] for the addition vector, but we need
-    // the [0..1] range to apply the vector in GLSL
-    for (int i = 0; i < 4; i++) {
-        mVector[i] /= 255.0f;
-    }
-
-    // TODO: We should be smarter about this
-    mBlend = true;
-}
-
-SkiaColorMatrixFilter::~SkiaColorMatrixFilter() {
-    delete[] mMatrix;
-    delete[] mVector;
-}
-
-void SkiaColorMatrixFilter::describe(ProgramDescription& description,
-        const Extensions& extensions) {
-    description.colorOp = ProgramDescription::kColorMatrix;
-}
-
-void SkiaColorMatrixFilter::setupProgram(Program* program) {
-    glUniformMatrix4fv(program->getUniform("colorMatrix"), 1, GL_FALSE, &mMatrix[0]);
-    glUniform4fv(program->getUniform("colorMatrixVector"), 1, mVector);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Lighting color filter
-///////////////////////////////////////////////////////////////////////////////
-
-SkiaLightingFilter::SkiaLightingFilter(SkColorFilter* skFilter, int multiply, int add):
-        SkiaColorFilter(skFilter, kLighting, true) {
-    mMulR = ((multiply >> 16) & 0xFF) / 255.0f;
-    mMulG = ((multiply >>  8) & 0xFF) / 255.0f;
-    mMulB = ((multiply      ) & 0xFF) / 255.0f;
-
-    mAddR = ((add >> 16) & 0xFF) / 255.0f;
-    mAddG = ((add >>  8) & 0xFF) / 255.0f;
-    mAddB = ((add      ) & 0xFF) / 255.0f;
-
-    // A lighting filter always ignores alpha
-    mBlend = false;
-}
-
-void SkiaLightingFilter::describe(ProgramDescription& description, const Extensions& extensions) {
-    description.colorOp = ProgramDescription::kColorLighting;
-}
-
-void SkiaLightingFilter::setupProgram(Program* program) {
-    glUniform4f(program->getUniform("lightingMul"), mMulR, mMulG, mMulB, 1.0f);
-    glUniform4f(program->getUniform("lightingAdd"), mAddR, mAddG, mAddB, 0.0f);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Blend color filter
-///////////////////////////////////////////////////////////////////////////////
-
-SkiaBlendFilter::SkiaBlendFilter(SkColorFilter* skFilter, int color, SkXfermode::Mode mode):
-        SkiaColorFilter(skFilter, kBlend, true), mMode(mode) {
-    const int alpha = (color >> 24) & 0xFF;
-    mA = alpha / 255.0f;
-    mR = mA * ((color >> 16) & 0xFF) / 255.0f;
-    mG = mA * ((color >>  8) & 0xFF) / 255.0f;
-    mB = mA * ((color      ) & 0xFF) / 255.0f;
-
-    // TODO: We should do something smarter here
-    mBlend = true;
-}
-
-void SkiaBlendFilter::describe(ProgramDescription& description, const Extensions& extensions) {
-    description.colorOp = ProgramDescription::kColorBlend;
-    description.colorMode = mMode;
-}
-
-void SkiaBlendFilter::setupProgram(Program* program) {
-    glUniform4f(program->getUniform("colorBlend"), mR, mG, mB, mA);
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/SkiaColorFilter.h b/libs/hwui/SkiaColorFilter.h
deleted file mode 100644
index 2feb834..0000000
--- a/libs/hwui/SkiaColorFilter.h
+++ /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.
- */
-
-#ifndef ANDROID_HWUI_SKIA_COLOR_FILTER_H
-#define ANDROID_HWUI_SKIA_COLOR_FILTER_H
-
-#include <GLES2/gl2.h>
-#include <SkColorFilter.h>
-
-#include <cutils/compiler.h>
-
-#include "ProgramCache.h"
-#include "Extensions.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Base color filter
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Represents a Skia color filter. A color filter modifies a ProgramDescription
- * and sets uniforms on the resulting shaders.
- */
-struct SkiaColorFilter {
-    /**
-     * Type of Skia color filter in use.
-     */
-    enum Type {
-        kNone,
-        kColorMatrix,
-        kLighting,
-        kBlend,
-    };
-
-    ANDROID_API SkiaColorFilter(SkColorFilter *skFilter, Type type, bool blend);
-    virtual ~SkiaColorFilter();
-
-    virtual void describe(ProgramDescription& description, const Extensions& extensions) = 0;
-    virtual void setupProgram(Program* program) = 0;
-
-    inline bool blend() const {
-        return mBlend;
-    }
-
-    Type type() const {
-        return mType;
-    }
-
-    SkColorFilter* getSkColorFilter() {
-        return mSkFilter;
-    }
-
-protected:
-    Type mType;
-    bool mBlend;
-
-private:
-    SkColorFilter *mSkFilter;
-}; // struct SkiaColorFilter
-
-///////////////////////////////////////////////////////////////////////////////
-// Implementations
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * A color filter that multiplies the source color with a matrix and adds a vector.
- */
-struct SkiaColorMatrixFilter: public SkiaColorFilter {
-    ANDROID_API SkiaColorMatrixFilter(SkColorFilter *skFilter, float* matrix, float* vector);
-    ~SkiaColorMatrixFilter();
-
-    void describe(ProgramDescription& description, const Extensions& extensions);
-    void setupProgram(Program* program);
-
-private:
-    float* mMatrix;
-    float* mVector;
-}; // struct SkiaColorMatrixFilter
-
-/**
- * A color filters that multiplies the source color with a fixed value and adds
- * another fixed value. Ignores the alpha channel of both arguments.
- */
-struct SkiaLightingFilter: public SkiaColorFilter {
-    ANDROID_API SkiaLightingFilter(SkColorFilter *skFilter, int multiply, int add);
-
-    void describe(ProgramDescription& description, const Extensions& extensions);
-    void setupProgram(Program* program);
-
-private:
-    GLfloat mMulR, mMulG, mMulB;
-    GLfloat mAddR, mAddG, mAddB;
-}; // struct SkiaLightingFilter
-
-/**
- * A color filters that blends the source color with a specified destination color
- * and PorterDuff blending mode.
- */
-struct SkiaBlendFilter: public SkiaColorFilter {
-    ANDROID_API SkiaBlendFilter(SkColorFilter *skFilter, int color, SkXfermode::Mode mode);
-
-    void describe(ProgramDescription& description, const Extensions& extensions);
-    void setupProgram(Program* program);
-
-private:
-    SkXfermode::Mode mMode;
-    GLfloat mR, mG, mB, mA;
-}; // struct SkiaBlendFilter
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_SKIA_COLOR_FILTER_H
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 797ed10..4f2a432 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -142,7 +142,7 @@
 }
 
 void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView,
-        const Snapshot& snapshot, GLuint* textureUnit) {
+        const Snapshot&, GLuint* textureUnit) {
     GLuint textureSlot = (*textureUnit)++;
     Caches::getInstance().activeTexture(textureSlot);
 
@@ -228,7 +228,7 @@
 }
 
 void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelView,
-        const Snapshot& snapshot, GLuint* textureUnit) {
+        const Snapshot&, GLuint* textureUnit) {
     if (CC_UNLIKELY(!mIsSimple)) {
         GLuint textureSlot = (*textureUnit)++;
         Caches::getInstance().activeTexture(textureSlot);
@@ -264,7 +264,7 @@
 SkiaCircularGradientShader::SkiaCircularGradientShader(float x, float y, float radius,
         uint32_t* colors, float* positions, int count, SkShader* key, SkShader::TileMode tileMode,
         SkMatrix* matrix, bool blend):
-        SkiaSweepGradientShader(kCircularGradient, x, y, colors, positions, count, key,
+        SkiaSweepGradientShader(kCircularGradient, colors, positions, count, key,
                 tileMode, matrix, blend) {
     SkMatrix unitMatrix;
     toCircularUnitMatrix(x, y, radius, &unitMatrix);
@@ -314,11 +314,12 @@
     mIsSimple = count == 2;
 }
 
-SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors,
+SkiaSweepGradientShader::SkiaSweepGradientShader(Type type, uint32_t* colors,
         float* positions, int count, SkShader* key, SkShader::TileMode tileMode,
         SkMatrix* matrix, bool blend):
         SkiaShader(type, key, tileMode, tileMode, matrix, blend),
         mColors(colors), mPositions(positions), mCount(count) {
+    // protected method, that doesn't setup mUnitMatrix - should be handled by subclass
 
     mIsSimple = count == 2 && tileMode == SkShader::kClamp_TileMode;
 }
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index cc56c50..6015761 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -43,7 +43,8 @@
  * Represents a Skia shader. A shader will modify the GL context and active
  * program to recreate the original effect.
  */
-struct SkiaShader {
+class SkiaShader {
+public:
     /**
      * Type of Skia shader in use.
      */
@@ -192,7 +193,7 @@
             GLuint* textureUnit);
 
 protected:
-    SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
+    SkiaSweepGradientShader(Type type, uint32_t* colors, float* positions,
             int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
     SkiaSweepGradientShader() {
     }
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
new file mode 100644
index 0000000..5fa0ba5
--- /dev/null
+++ b/libs/hwui/SpotShadow.cpp
@@ -0,0 +1,952 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#define SHADOW_SHRINK_SCALE 0.1f
+
+#include <math.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+
+#include "ShadowTessellator.h"
+#include "SpotShadow.h"
+#include "Vertex.h"
+
+namespace android {
+namespace uirenderer {
+
+static const double EPSILON = 1e-7;
+
+/**
+ * Calculate the angle between and x and a y coordinate.
+ * The atan2 range from -PI to PI.
+ */
+static float angle(const Vector2& point, const Vector2& center) {
+    return atan2(point.y - center.y, point.x - center.x);
+}
+
+/**
+ * Calculate the intersection of a ray with the line segment defined by two points.
+ *
+ * Returns a negative value in error conditions.
+
+ * @param rayOrigin The start of the ray
+ * @param dx The x vector of the ray
+ * @param dy The y vector of the ray
+ * @param p1 The first point defining the line segment
+ * @param p2 The second point defining the line segment
+ * @return The distance along the ray if it intersects with the line segment, negative if otherwise
+ */
+static float rayIntersectPoints(const Vector2& rayOrigin, float dx, float dy,
+        const Vector2& p1, const Vector2& p2) {
+    // The math below is derived from solving this formula, basically the
+    // intersection point should stay on both the ray and the edge of (p1, p2).
+    // solve([p1x+t*(p2x-p1x)=dx*t2+px,p1y+t*(p2y-p1y)=dy*t2+py],[t,t2]);
+
+    double divisor = (dx * (p1.y - p2.y) + dy * p2.x - dy * p1.x);
+    if (divisor == 0) return -1.0f; // error, invalid divisor
+
+#if DEBUG_SHADOW
+    double interpVal = (dx * (p1.y - rayOrigin.y) + dy * rayOrigin.x - dy * p1.x) / divisor;
+    if (interpVal < 0 || interpVal > 1) {
+        ALOGW("rayIntersectPoints is hitting outside the segment %f", interpVal);
+    }
+#endif
+
+    double distance = (p1.x * (rayOrigin.y - p2.y) + p2.x * (p1.y - rayOrigin.y) +
+            rayOrigin.x * (p2.y - p1.y)) / divisor;
+
+    return distance; // may be negative in error cases
+}
+
+/**
+ * Sort points by their X coordinates
+ *
+ * @param points the points as a Vector2 array.
+ * @param pointsLength the number of vertices of the polygon.
+ */
+void SpotShadow::xsort(Vector2* points, int pointsLength) {
+    quicksortX(points, 0, pointsLength - 1);
+}
+
+/**
+ * compute the convex hull of a collection of Points
+ *
+ * @param points the points as a Vector2 array.
+ * @param pointsLength the number of vertices of the polygon.
+ * @param retPoly pre allocated array of floats to put the vertices
+ * @return the number of points in the polygon 0 if no intersection
+ */
+int SpotShadow::hull(Vector2* points, int pointsLength, Vector2* retPoly) {
+    xsort(points, pointsLength);
+    int n = pointsLength;
+    Vector2 lUpper[n];
+    lUpper[0] = points[0];
+    lUpper[1] = points[1];
+
+    int lUpperSize = 2;
+
+    for (int i = 2; i < n; i++) {
+        lUpper[lUpperSize] = points[i];
+        lUpperSize++;
+
+        while (lUpperSize > 2 && !ccw(
+                lUpper[lUpperSize - 3].x, lUpper[lUpperSize - 3].y,
+                lUpper[lUpperSize - 2].x, lUpper[lUpperSize - 2].y,
+                lUpper[lUpperSize - 1].x, lUpper[lUpperSize - 1].y)) {
+            // Remove the middle point of the three last
+            lUpper[lUpperSize - 2].x = lUpper[lUpperSize - 1].x;
+            lUpper[lUpperSize - 2].y = lUpper[lUpperSize - 1].y;
+            lUpperSize--;
+        }
+    }
+
+    Vector2 lLower[n];
+    lLower[0] = points[n - 1];
+    lLower[1] = points[n - 2];
+
+    int lLowerSize = 2;
+
+    for (int i = n - 3; i >= 0; i--) {
+        lLower[lLowerSize] = points[i];
+        lLowerSize++;
+
+        while (lLowerSize > 2 && !ccw(
+                lLower[lLowerSize - 3].x, lLower[lLowerSize - 3].y,
+                lLower[lLowerSize - 2].x, lLower[lLowerSize - 2].y,
+                lLower[lLowerSize - 1].x, lLower[lLowerSize - 1].y)) {
+            // Remove the middle point of the three last
+            lLower[lLowerSize - 2] = lLower[lLowerSize - 1];
+            lLowerSize--;
+        }
+    }
+
+    // output points in CW ordering
+    const int total = lUpperSize + lLowerSize - 2;
+    int outIndex = total - 1;
+    for (int i = 0; i < lUpperSize; i++) {
+        retPoly[outIndex] = lUpper[i];
+        outIndex--;
+    }
+
+    for (int i = 1; i < lLowerSize - 1; i++) {
+        retPoly[outIndex] = lLower[i];
+        outIndex--;
+    }
+    // TODO: Add test harness which verify that all the points are inside the hull.
+    return total;
+}
+
+/**
+ * Test whether the 3 points form a counter clockwise turn.
+ *
+ * @return true if a right hand turn
+ */
+bool SpotShadow::ccw(double ax, double ay, double bx, double by,
+        double cx, double cy) {
+    return (bx - ax) * (cy - ay) - (by - ay) * (cx - ax) > EPSILON;
+}
+
+/**
+ * Calculates the intersection of poly1 with poly2 and put in poly2.
+ * Note that both poly1 and poly2 must be in CW order already!
+ *
+ * @param poly1 The 1st polygon, as a Vector2 array.
+ * @param poly1Length The number of vertices of 1st polygon.
+ * @param poly2 The 2nd and output polygon, as a Vector2 array.
+ * @param poly2Length The number of vertices of 2nd polygon.
+ * @return number of vertices in output polygon as poly2.
+ */
+int SpotShadow::intersection(const Vector2* poly1, int poly1Length,
+        Vector2* poly2, int poly2Length) {
+#if DEBUG_SHADOW
+    if (!isClockwise(poly1, poly1Length)) {
+        ALOGW("Poly1 is not clockwise! Intersection is wrong!");
+    }
+    if (!isClockwise(poly2, poly2Length)) {
+        ALOGW("Poly2 is not clockwise! Intersection is wrong!");
+    }
+#endif
+    Vector2 poly[poly1Length * poly2Length + 2];
+    int count = 0;
+    int pcount = 0;
+
+    // If one vertex from one polygon sits inside another polygon, add it and
+    // count them.
+    for (int i = 0; i < poly1Length; i++) {
+        if (testPointInsidePolygon(poly1[i], poly2, poly2Length)) {
+            poly[count] = poly1[i];
+            count++;
+            pcount++;
+
+        }
+    }
+
+    int insidePoly2 = pcount;
+    for (int i = 0; i < poly2Length; i++) {
+        if (testPointInsidePolygon(poly2[i], poly1, poly1Length)) {
+            poly[count] = poly2[i];
+            count++;
+        }
+    }
+
+    int insidePoly1 = count - insidePoly2;
+    // If all vertices from poly1 are inside poly2, then just return poly1.
+    if (insidePoly2 == poly1Length) {
+        memcpy(poly2, poly1, poly1Length * sizeof(Vector2));
+        return poly1Length;
+    }
+
+    // If all vertices from poly2 are inside poly1, then just return poly2.
+    if (insidePoly1 == poly2Length) {
+        return poly2Length;
+    }
+
+    // Since neither polygon fully contain the other one, we need to add all the
+    // intersection points.
+    Vector2 intersection;
+    for (int i = 0; i < poly2Length; i++) {
+        for (int j = 0; j < poly1Length; j++) {
+            int poly2LineStart = i;
+            int poly2LineEnd = ((i + 1) % poly2Length);
+            int poly1LineStart = j;
+            int poly1LineEnd = ((j + 1) % poly1Length);
+            bool found = lineIntersection(
+                    poly2[poly2LineStart].x, poly2[poly2LineStart].y,
+                    poly2[poly2LineEnd].x, poly2[poly2LineEnd].y,
+                    poly1[poly1LineStart].x, poly1[poly1LineStart].y,
+                    poly1[poly1LineEnd].x, poly1[poly1LineEnd].y,
+                    intersection);
+            if (found) {
+                poly[count].x = intersection.x;
+                poly[count].y = intersection.y;
+                count++;
+            } else {
+                Vector2 delta = poly2[i] - poly1[j];
+                if (delta.lengthSquared() < EPSILON) {
+                    poly[count] = poly2[i];
+                    count++;
+                }
+            }
+        }
+    }
+
+    if (count == 0) {
+        return 0;
+    }
+
+    // Sort the result polygon around the center.
+    Vector2 center(0.0f, 0.0f);
+    for (int i = 0; i < count; i++) {
+        center += poly[i];
+    }
+    center /= count;
+    sort(poly, count, center);
+
+#if DEBUG_SHADOW
+    // Since poly2 is overwritten as the result, we need to save a copy to do
+    // our verification.
+    Vector2 oldPoly2[poly2Length];
+    int oldPoly2Length = poly2Length;
+    memcpy(oldPoly2, poly2, sizeof(Vector2) * poly2Length);
+#endif
+
+    // Filter the result out from poly and put it into poly2.
+    poly2[0] = poly[0];
+    int lastOutputIndex = 0;
+    for (int i = 1; i < count; i++) {
+        Vector2 delta = poly[i] - poly2[lastOutputIndex];
+        if (delta.lengthSquared() >= EPSILON) {
+            poly2[++lastOutputIndex] = poly[i];
+        } else {
+            // If the vertices are too close, pick the inner one, because the
+            // inner one is more likely to be an intersection point.
+            Vector2 delta1 = poly[i] - center;
+            Vector2 delta2 = poly2[lastOutputIndex] - center;
+            if (delta1.lengthSquared() < delta2.lengthSquared()) {
+                poly2[lastOutputIndex] = poly[i];
+            }
+        }
+    }
+    int resultLength = lastOutputIndex + 1;
+
+#if DEBUG_SHADOW
+    testConvex(poly2, resultLength, "intersection");
+    testConvex(poly1, poly1Length, "input poly1");
+    testConvex(oldPoly2, oldPoly2Length, "input poly2");
+
+    testIntersection(poly1, poly1Length, oldPoly2, oldPoly2Length, poly2, resultLength);
+#endif
+
+    return resultLength;
+}
+
+/**
+ * Sort points about a center point
+ *
+ * @param poly The in and out polyogon as a Vector2 array.
+ * @param polyLength The number of vertices of the polygon.
+ * @param center the center ctr[0] = x , ctr[1] = y to sort around.
+ */
+void SpotShadow::sort(Vector2* poly, int polyLength, const Vector2& center) {
+    quicksortCirc(poly, 0, polyLength - 1, center);
+}
+
+/**
+ * Swap points pointed to by i and j
+ */
+void SpotShadow::swap(Vector2* points, int i, int j) {
+    Vector2 temp = points[i];
+    points[i] = points[j];
+    points[j] = temp;
+}
+
+/**
+ * quick sort implementation about the center.
+ */
+void SpotShadow::quicksortCirc(Vector2* points, int low, int high,
+        const Vector2& center) {
+    int i = low, j = high;
+    int p = low + (high - low) / 2;
+    float pivot = angle(points[p], center);
+    while (i <= j) {
+        while (angle(points[i], center) > pivot) {
+            i++;
+        }
+        while (angle(points[j], center) < pivot) {
+            j--;
+        }
+
+        if (i <= j) {
+            swap(points, i, j);
+            i++;
+            j--;
+        }
+    }
+    if (low < j) quicksortCirc(points, low, j, center);
+    if (i < high) quicksortCirc(points, i, high, center);
+}
+
+/**
+ * Sort points by x axis
+ *
+ * @param points points to sort
+ * @param low start index
+ * @param high end index
+ */
+void SpotShadow::quicksortX(Vector2* points, int low, int high) {
+    int i = low, j = high;
+    int p = low + (high - low) / 2;
+    float pivot = points[p].x;
+    while (i <= j) {
+        while (points[i].x < pivot) {
+            i++;
+        }
+        while (points[j].x > pivot) {
+            j--;
+        }
+
+        if (i <= j) {
+            swap(points, i, j);
+            i++;
+            j--;
+        }
+    }
+    if (low < j) quicksortX(points, low, j);
+    if (i < high) quicksortX(points, i, high);
+}
+
+/**
+ * Test whether a point is inside the polygon.
+ *
+ * @param testPoint the point to test
+ * @param poly the polygon
+ * @return true if the testPoint is inside the poly.
+ */
+bool SpotShadow::testPointInsidePolygon(const Vector2 testPoint,
+        const Vector2* poly, int len) {
+    bool c = false;
+    double testx = testPoint.x;
+    double testy = testPoint.y;
+    for (int i = 0, j = len - 1; i < len; j = i++) {
+        double startX = poly[j].x;
+        double startY = poly[j].y;
+        double endX = poly[i].x;
+        double endY = poly[i].y;
+
+        if (((endY > testy) != (startY > testy)) &&
+            (testx < (startX - endX) * (testy - endY)
+             / (startY - endY) + endX)) {
+            c = !c;
+        }
+    }
+    return c;
+}
+
+/**
+ * Make the polygon turn clockwise.
+ *
+ * @param polygon the polygon as a Vector2 array.
+ * @param len the number of points of the polygon
+ */
+void SpotShadow::makeClockwise(Vector2* polygon, int len) {
+    if (polygon == 0  || len == 0) {
+        return;
+    }
+    if (!isClockwise(polygon, len)) {
+        reverse(polygon, len);
+    }
+}
+
+/**
+ * Test whether the polygon is order in clockwise.
+ *
+ * @param polygon the polygon as a Vector2 array
+ * @param len the number of points of the polygon
+ */
+bool SpotShadow::isClockwise(const Vector2* polygon, int len) {
+    double sum = 0;
+    double p1x = polygon[len - 1].x;
+    double p1y = polygon[len - 1].y;
+    for (int i = 0; i < len; i++) {
+
+        double p2x = polygon[i].x;
+        double p2y = polygon[i].y;
+        sum += p1x * p2y - p2x * p1y;
+        p1x = p2x;
+        p1y = p2y;
+    }
+    return sum < 0;
+}
+
+/**
+ * Reverse the polygon
+ *
+ * @param polygon the polygon as a Vector2 array
+ * @param len the number of points of the polygon
+ */
+void SpotShadow::reverse(Vector2* polygon, int len) {
+    int n = len / 2;
+    for (int i = 0; i < n; i++) {
+        Vector2 tmp = polygon[i];
+        int k = len - 1 - i;
+        polygon[i] = polygon[k];
+        polygon[k] = tmp;
+    }
+}
+
+/**
+ * Intersects two lines in parametric form. This function is called in a tight
+ * loop, and we need double precision to get things right.
+ *
+ * @param x1 the x coordinate point 1 of line 1
+ * @param y1 the y coordinate point 1 of line 1
+ * @param x2 the x coordinate point 2 of line 1
+ * @param y2 the y coordinate point 2 of line 1
+ * @param x3 the x coordinate point 1 of line 2
+ * @param y3 the y coordinate point 1 of line 2
+ * @param x4 the x coordinate point 2 of line 2
+ * @param y4 the y coordinate point 2 of line 2
+ * @param ret the x,y location of the intersection
+ * @return true if it found an intersection
+ */
+inline bool SpotShadow::lineIntersection(double x1, double y1, double x2, double y2,
+        double x3, double y3, double x4, double y4, Vector2& ret) {
+    double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
+    if (d == 0.0) return false;
+
+    double dx = (x1 * y2 - y1 * x2);
+    double dy = (x3 * y4 - y3 * x4);
+    double x = (dx * (x3 - x4) - (x1 - x2) * dy) / d;
+    double y = (dx * (y3 - y4) - (y1 - y2) * dy) / d;
+
+    // The intersection should be in the middle of the point 1 and point 2,
+    // likewise point 3 and point 4.
+    if (((x - x1) * (x - x2) > EPSILON)
+        || ((x - x3) * (x - x4) > EPSILON)
+        || ((y - y1) * (y - y2) > EPSILON)
+        || ((y - y3) * (y - y4) > EPSILON)) {
+        // Not interesected
+        return false;
+    }
+    ret.x = x;
+    ret.y = y;
+    return true;
+
+}
+
+/**
+ * Compute a horizontal circular polygon about point (x , y , height) of radius
+ * (size)
+ *
+ * @param points number of the points of the output polygon.
+ * @param lightCenter the center of the light.
+ * @param size the light size.
+ * @param ret result polygon.
+ */
+void SpotShadow::computeLightPolygon(int points, const Vector3& lightCenter,
+        float size, Vector3* ret) {
+    // TODO: Caching all the sin / cos values and store them in a look up table.
+    for (int i = 0; i < points; i++) {
+        double angle = 2 * i * M_PI / points;
+        ret[i].x = cosf(angle) * size + lightCenter.x;
+        ret[i].y = sinf(angle) * size + lightCenter.y;
+        ret[i].z = lightCenter.z;
+    }
+}
+
+/**
+* Generate the shadow from a spot light.
+*
+* @param poly x,y,z vertexes of a convex polygon that occludes the light source
+* @param polyLength number of vertexes of the occluding polygon
+* @param lightCenter the center of the light
+* @param lightSize the radius of the light source
+* @param lightVertexCount the vertex counter for the light polygon
+* @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
+*                            empty strip if error.
+*
+*/
+VertexBufferMode SpotShadow::createSpotShadow(bool isCasterOpaque, const Vector3* poly,
+        int polyLength, const Vector3& lightCenter, float lightSize,
+        int lightVertexCount, VertexBuffer& retStrips) {
+    Vector3 light[lightVertexCount * 3];
+    computeLightPolygon(lightVertexCount, lightCenter, lightSize, light);
+    computeSpotShadow(isCasterOpaque, light, lightVertexCount, lightCenter, poly,
+            polyLength, retStrips);
+    return kVertexBufferMode_TwoPolyRingShadow;
+}
+
+/**
+ * Generate the shadow spot light of shape lightPoly and a object poly
+ *
+ * @param lightPoly x,y,z vertex of a convex polygon that is the light source
+ * @param lightPolyLength number of vertexes of the light source polygon
+ * @param poly x,y,z vertexes of a convex polygon that occludes the light source
+ * @param polyLength number of vertexes of the occluding polygon
+ * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
+ *                            empty strip if error.
+ */
+void SpotShadow::computeSpotShadow(bool isCasterOpaque, const Vector3* lightPoly,
+        int lightPolyLength, const Vector3& lightCenter, const Vector3* poly,
+        int polyLength, VertexBuffer& shadowTriangleStrip) {
+    // Point clouds for all the shadowed vertices
+    Vector2 shadowRegion[lightPolyLength * polyLength];
+    // Shadow polygon from one point light.
+    Vector2 outline[polyLength];
+    Vector2 umbraMem[polyLength * lightPolyLength];
+    Vector2* umbra = umbraMem;
+
+    int umbraLength = 0;
+
+    // Validate input, receiver is always at z = 0 plane.
+    bool inputPolyPositionValid = true;
+    for (int i = 0; i < polyLength; i++) {
+        if (poly[i].z >= lightPoly[0].z) {
+            inputPolyPositionValid = false;
+            ALOGW("polygon above the light");
+            break;
+        }
+    }
+
+    // If the caster's position is invalid, don't draw anything.
+    if (!inputPolyPositionValid) {
+        return;
+    }
+
+    // Calculate the umbra polygon based on intersections of all outlines
+    int k = 0;
+    for (int j = 0; j < lightPolyLength; j++) {
+        int m = 0;
+        for (int i = 0; i < polyLength; i++) {
+            // After validating the input, deltaZ is guaranteed to be positive.
+            float deltaZ = lightPoly[j].z - poly[i].z;
+            float ratioZ = lightPoly[j].z / deltaZ;
+            float x = lightPoly[j].x - ratioZ * (lightPoly[j].x - poly[i].x);
+            float y = lightPoly[j].y - ratioZ * (lightPoly[j].y - poly[i].y);
+
+            Vector2 newPoint = Vector2(x, y);
+            shadowRegion[k] = newPoint;
+            outline[m] = newPoint;
+
+            k++;
+            m++;
+        }
+
+        // For the first light polygon's vertex, use the outline as the umbra.
+        // Later on, use the intersection of the outline and existing umbra.
+        if (umbraLength == 0) {
+            for (int i = 0; i < polyLength; i++) {
+                umbra[i] = outline[i];
+            }
+            umbraLength = polyLength;
+        } else {
+            int col = ((j * 255) / lightPolyLength);
+            umbraLength = intersection(outline, polyLength, umbra, umbraLength);
+            if (umbraLength == 0) {
+                break;
+            }
+        }
+    }
+
+    // Generate the penumbra area using the hull of all shadow regions.
+    int shadowRegionLength = k;
+    Vector2 penumbra[k];
+    int penumbraLength = hull(shadowRegion, shadowRegionLength, penumbra);
+
+    Vector2 fakeUmbra[polyLength];
+    if (umbraLength < 3) {
+        // If there is no real umbra, make a fake one.
+        for (int i = 0; i < polyLength; i++) {
+            float deltaZ = lightCenter.z - poly[i].z;
+            float ratioZ = lightCenter.z / deltaZ;
+            float x = lightCenter.x - ratioZ * (lightCenter.x - poly[i].x);
+            float y = lightCenter.y - ratioZ * (lightCenter.y - poly[i].y);
+
+            fakeUmbra[i].x = x;
+            fakeUmbra[i].y = y;
+        }
+
+        // Shrink the centroid's shadow by 10%.
+        // TODO: Study the magic number of 10%.
+        Vector2 shadowCentroid =
+                ShadowTessellator::centroid2d(fakeUmbra, polyLength);
+        for (int i = 0; i < polyLength; i++) {
+            fakeUmbra[i] = shadowCentroid * (1.0f - SHADOW_SHRINK_SCALE) +
+                    fakeUmbra[i] * SHADOW_SHRINK_SCALE;
+        }
+#if DEBUG_SHADOW
+        ALOGD("No real umbra make a fake one, centroid2d =  %f , %f",
+                shadowCentroid.x, shadowCentroid.y);
+#endif
+        // Set the fake umbra, whose size is the same as the original polygon.
+        umbra = fakeUmbra;
+        umbraLength = polyLength;
+    }
+
+    generateTriangleStrip(isCasterOpaque, penumbra, penumbraLength, umbra,
+            umbraLength, poly, polyLength, shadowTriangleStrip);
+}
+
+/**
+ * Converts a polygon specified with CW vertices into an array of distance-from-centroid values.
+ *
+ * Returns false in error conditions
+ *
+ * @param poly Array of vertices. Note that these *must* be CW.
+ * @param polyLength The number of vertices in the polygon.
+ * @param polyCentroid The centroid of the polygon, from which rays will be cast
+ * @param rayDist The output array for the calculated distances, must be SHADOW_RAY_COUNT in size
+ */
+bool convertPolyToRayDist(const Vector2* poly, int polyLength, const Vector2& polyCentroid,
+        float* rayDist) {
+    const int rays = SHADOW_RAY_COUNT;
+    const float step = M_PI * 2 / rays;
+
+    const Vector2* lastVertex = &(poly[polyLength - 1]);
+    float startAngle = angle(*lastVertex, polyCentroid);
+
+    // Start with the ray that's closest to and less than startAngle
+    int rayIndex = floor((startAngle - EPSILON) / step);
+    rayIndex = (rayIndex + rays) % rays; // ensure positive
+
+    for (int polyIndex = 0; polyIndex < polyLength; polyIndex++) {
+        /*
+         * For a given pair of vertices on the polygon, poly[i-1] and poly[i], the rays that
+         * intersect these will be those that are between the two angles from the centroid that the
+         * vertices define.
+         *
+         * Because the polygon vertices are stored clockwise, the closest ray with an angle
+         * *smaller* than that defined by angle(poly[i], centroid) will be the first ray that does
+         * not intersect with poly[i-1], poly[i].
+         */
+        float currentAngle = angle(poly[polyIndex], polyCentroid);
+
+        // find first ray that will not intersect the line segment poly[i-1] & poly[i]
+        int firstRayIndexOnNextSegment = floor((currentAngle - EPSILON) / step);
+        firstRayIndexOnNextSegment = (firstRayIndexOnNextSegment + rays) % rays; // ensure positive
+
+        // Iterate through all rays that intersect with poly[i-1], poly[i] line segment.
+        // This may be 0 rays.
+        while (rayIndex != firstRayIndexOnNextSegment) {
+            float distanceToIntersect = rayIntersectPoints(polyCentroid,
+                    cos(rayIndex * step),
+                    sin(rayIndex * step),
+                    *lastVertex, poly[polyIndex]);
+            if (distanceToIntersect < 0) {
+#if DEBUG_SHADOW
+                ALOGW("ERROR: convertPolyToRayDist failed");
+#endif
+                return false; // error case, abort
+            }
+
+            rayDist[rayIndex] = distanceToIntersect;
+
+            rayIndex = (rayIndex - 1 + rays) % rays;
+        }
+        lastVertex = &poly[polyIndex];
+    }
+
+   return true;
+}
+
+int SpotShadow::calculateOccludedUmbra(const Vector2* umbra, int umbraLength,
+        const Vector3* poly, int polyLength, Vector2* occludedUmbra) {
+    // Occluded umbra area is computed as the intersection of the projected 2D
+    // poly and umbra.
+    for (int i = 0; i < polyLength; i++) {
+        occludedUmbra[i].x = poly[i].x;
+        occludedUmbra[i].y = poly[i].y;
+    }
+
+    // Both umbra and incoming polygon are guaranteed to be CW, so we can call
+    // intersection() directly.
+    return intersection(umbra, umbraLength,
+            occludedUmbra, polyLength);
+}
+
+#define OCLLUDED_UMBRA_SHRINK_FACTOR 0.95f
+/**
+ * Generate a triangle strip given two convex polygons
+ *
+ * @param penumbra The outer polygon x,y vertexes
+ * @param penumbraLength The number of vertexes in the outer polygon
+ * @param umbra The inner outer polygon x,y vertexes
+ * @param umbraLength The number of vertexes in the inner polygon
+ * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
+ *                            empty strip if error.
+**/
+void SpotShadow::generateTriangleStrip(bool isCasterOpaque, const Vector2* penumbra,
+        int penumbraLength, const Vector2* umbra, int umbraLength,
+        const Vector3* poly, int polyLength, VertexBuffer& shadowTriangleStrip) {
+    const int rays = SHADOW_RAY_COUNT;
+    const int size = 2 * rays;
+    const float step = M_PI * 2 / rays;
+    // Centroid of the umbra.
+    Vector2 centroid = ShadowTessellator::centroid2d(umbra, umbraLength);
+#if DEBUG_SHADOW
+    ALOGD("centroid2d =  %f , %f", centroid.x, centroid.y);
+#endif
+    // Intersection to the penumbra.
+    float penumbraDistPerRay[rays];
+    // Intersection to the umbra.
+    float umbraDistPerRay[rays];
+    // Intersection to the occluded umbra area.
+    float occludedUmbraDistPerRay[rays];
+
+    // convert CW polygons to ray distance encoding, aborting on conversion failure
+    if (!convertPolyToRayDist(umbra, umbraLength, centroid, umbraDistPerRay)) return;
+    if (!convertPolyToRayDist(penumbra, penumbraLength, centroid, penumbraDistPerRay)) return;
+
+    bool hasOccludedUmbraArea = false;
+    if (isCasterOpaque) {
+        Vector2 occludedUmbra[polyLength + umbraLength];
+        int occludedUmbraLength = calculateOccludedUmbra(umbra, umbraLength, poly, polyLength,
+                occludedUmbra);
+        // Make sure the centroid is inside the umbra, otherwise, fall back to the
+        // approach as if there is no occluded umbra area.
+        if (testPointInsidePolygon(centroid, occludedUmbra, occludedUmbraLength)) {
+            hasOccludedUmbraArea = true;
+            // Shrink the occluded umbra area to avoid pixel level artifacts.
+            for (int i = 0; i < occludedUmbraLength; i ++) {
+                occludedUmbra[i] = centroid + (occludedUmbra[i] - centroid) *
+                        OCLLUDED_UMBRA_SHRINK_FACTOR;
+            }
+            if (!convertPolyToRayDist(occludedUmbra, occludedUmbraLength, centroid,
+                    occludedUmbraDistPerRay)) {
+                return;
+            }
+        }
+    }
+
+    AlphaVertex* shadowVertices =
+            shadowTriangleStrip.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
+
+    // Calculate the vertices (x, y, alpha) in the shadow area.
+    AlphaVertex centroidXYA;
+    AlphaVertex::set(&centroidXYA, centroid.x, centroid.y, 1.0f);
+    for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+        float dx = cosf(step * rayIndex);
+        float dy = sinf(step * rayIndex);
+
+        // penumbra ring
+        float penumbraDistance = penumbraDistPerRay[rayIndex];
+        AlphaVertex::set(&shadowVertices[rayIndex],
+                dx * penumbraDistance + centroid.x,
+                dy * penumbraDistance + centroid.y, 0.0f);
+
+        // umbra ring
+        float umbraDistance = umbraDistPerRay[rayIndex];
+        AlphaVertex::set(&shadowVertices[rays + rayIndex],
+                dx * umbraDistance + centroid.x, dy * umbraDistance + centroid.y, 1.0f);
+
+        // occluded umbra ring
+        if (hasOccludedUmbraArea) {
+            float occludedUmbraDistance = occludedUmbraDistPerRay[rayIndex];
+            AlphaVertex::set(&shadowVertices[2 * rays + rayIndex],
+                    dx * occludedUmbraDistance + centroid.x,
+                    dy * occludedUmbraDistance + centroid.y, 1.0f);
+        } else {
+            // Put all vertices of the occluded umbra ring at the centroid.
+            shadowVertices[2 * rays + rayIndex] = centroidXYA;
+        }
+    }
+}
+
+/**
+ * This is only for experimental purpose.
+ * After intersections are calculated, we could smooth the polygon if needed.
+ * So far, we don't think it is more appealing yet.
+ *
+ * @param level The level of smoothness.
+ * @param rays The total number of rays.
+ * @param rayDist (In and Out) The distance for each ray.
+ *
+ */
+void SpotShadow::smoothPolygon(int level, int rays, float* rayDist) {
+    for (int k = 0; k < level; k++) {
+        for (int i = 0; i < rays; i++) {
+            float p1 = rayDist[(rays - 1 + i) % rays];
+            float p2 = rayDist[i];
+            float p3 = rayDist[(i + 1) % rays];
+            rayDist[i] = (p1 + p2 * 2 + p3) / 4;
+        }
+    }
+}
+
+#if DEBUG_SHADOW
+
+#define TEST_POINT_NUMBER 128
+
+/**
+ * Calculate the bounds for generating random test points.
+ */
+void SpotShadow::updateBound(const Vector2 inVector, Vector2& lowerBound,
+        Vector2& upperBound ) {
+    if (inVector.x < lowerBound.x) {
+        lowerBound.x = inVector.x;
+    }
+
+    if (inVector.y < lowerBound.y) {
+        lowerBound.y = inVector.y;
+    }
+
+    if (inVector.x > upperBound.x) {
+        upperBound.x = inVector.x;
+    }
+
+    if (inVector.y > upperBound.y) {
+        upperBound.y = inVector.y;
+    }
+}
+
+/**
+ * For debug purpose, when things go wrong, dump the whole polygon data.
+ */
+static void dumpPolygon(const Vector2* poly, int polyLength, const char* polyName) {
+    for (int i = 0; i < polyLength; i++) {
+        ALOGD("polygon %s i %d x %f y %f", polyName, i, poly[i].x, poly[i].y);
+    }
+}
+
+/**
+ * Test whether the polygon is convex.
+ */
+bool SpotShadow::testConvex(const Vector2* polygon, int polygonLength,
+        const char* name) {
+    bool isConvex = true;
+    for (int i = 0; i < polygonLength; i++) {
+        Vector2 start = polygon[i];
+        Vector2 middle = polygon[(i + 1) % polygonLength];
+        Vector2 end = polygon[(i + 2) % polygonLength];
+
+        double delta = (double(middle.x) - start.x) * (double(end.y) - start.y) -
+                (double(middle.y) - start.y) * (double(end.x) - start.x);
+        bool isCCWOrCoLinear = (delta >= EPSILON);
+
+        if (isCCWOrCoLinear) {
+            ALOGW("(Error Type 2): polygon (%s) is not a convex b/c start (x %f, y %f),"
+                    "middle (x %f, y %f) and end (x %f, y %f) , delta is %f !!!",
+                    name, start.x, start.y, middle.x, middle.y, end.x, end.y, delta);
+            isConvex = false;
+            break;
+        }
+    }
+    return isConvex;
+}
+
+/**
+ * Test whether or not the polygon (intersection) is within the 2 input polygons.
+ * Using Marte Carlo method, we generate a random point, and if it is inside the
+ * intersection, then it must be inside both source polygons.
+ */
+void SpotShadow::testIntersection(const Vector2* poly1, int poly1Length,
+        const Vector2* poly2, int poly2Length,
+        const Vector2* intersection, int intersectionLength) {
+    // Find the min and max of x and y.
+    Vector2 lowerBound(FLT_MAX, FLT_MAX);
+    Vector2 upperBound(-FLT_MAX, -FLT_MAX);
+    for (int i = 0; i < poly1Length; i++) {
+        updateBound(poly1[i], lowerBound, upperBound);
+    }
+    for (int i = 0; i < poly2Length; i++) {
+        updateBound(poly2[i], lowerBound, upperBound);
+    }
+
+    bool dumpPoly = false;
+    for (int k = 0; k < TEST_POINT_NUMBER; k++) {
+        // Generate a random point between minX, minY and maxX, maxY.
+        double randomX = rand() / double(RAND_MAX);
+        double randomY = rand() / double(RAND_MAX);
+
+        Vector2 testPoint;
+        testPoint.x = lowerBound.x + randomX * (upperBound.x - lowerBound.x);
+        testPoint.y = lowerBound.y + randomY * (upperBound.y - lowerBound.y);
+
+        // If the random point is in both poly 1 and 2, then it must be intersection.
+        if (testPointInsidePolygon(testPoint, intersection, intersectionLength)) {
+            if (!testPointInsidePolygon(testPoint, poly1, poly1Length)) {
+                dumpPoly = true;
+                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
+                      " not in the poly1",
+                        testPoint.x, testPoint.y);
+            }
+
+            if (!testPointInsidePolygon(testPoint, poly2, poly2Length)) {
+                dumpPoly = true;
+                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
+                      " not in the poly2",
+                        testPoint.x, testPoint.y);
+            }
+        }
+    }
+
+    if (dumpPoly) {
+        dumpPolygon(intersection, intersectionLength, "intersection");
+        for (int i = 1; i < intersectionLength; i++) {
+            Vector2 delta = intersection[i] - intersection[i - 1];
+            ALOGD("Intersetion i, %d Vs i-1 is delta %f", i, delta.lengthSquared());
+        }
+
+        dumpPolygon(poly1, poly1Length, "poly 1");
+        dumpPolygon(poly2, poly2Length, "poly 2");
+    }
+}
+#endif
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
new file mode 100644
index 0000000..599d37e
--- /dev/null
+++ b/libs/hwui/SpotShadow.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_SPOT_SHADOW_H
+#define ANDROID_HWUI_SPOT_SHADOW_H
+
+#include "Debug.h"
+#include "Vector.h"
+#include "VertexBuffer.h"
+
+namespace android {
+namespace uirenderer {
+
+class SpotShadow {
+public:
+    static VertexBufferMode createSpotShadow(bool isCasterOpaque, const Vector3* poly,
+            int polyLength, const Vector3& lightCenter, float lightSize,
+            int lightVertexCount, VertexBuffer& retStrips);
+
+private:
+    static int calculateOccludedUmbra(const Vector2* umbra, int umbraLength,
+            const Vector3* poly, int polyLength, Vector2* occludedUmbra);
+    static void computeSpotShadow(bool isCasterOpaque, const Vector3* lightPoly,
+            int lightPolyLength, const Vector3& lightCenter, const Vector3* poly,
+            int polyLength, VertexBuffer& retstrips);
+
+    static void computeLightPolygon(int points, const Vector3& lightCenter,
+            float size, Vector3* ret);
+
+    static void smoothPolygon(int level, int rays, float* rayDist);
+    static float rayIntersectPoly(const Vector2* poly, int polyLength,
+            const Vector2& point, float dx, float dy);
+
+    static void xsort(Vector2* points, int pointsLength);
+    static int hull(Vector2* points, int pointsLength, Vector2* retPoly);
+    static bool ccw(double ax, double ay, double bx, double by, double cx, double cy);
+    static int intersection(const Vector2* poly1, int poly1length, Vector2* poly2, int poly2length);
+    static void sort(Vector2* poly, int polyLength, const Vector2& center);
+
+    static void swap(Vector2* points, int i, int j);
+    static void quicksortCirc(Vector2* points, int low, int high, const Vector2& center);
+    static void quicksortX(Vector2* points, int low, int high);
+
+    static bool testPointInsidePolygon(const Vector2 testPoint, const Vector2* poly, int len);
+    static void makeClockwise(Vector2* polygon, int len);
+    static bool isClockwise(const Vector2* polygon, int len);
+    static void reverse(Vector2* polygon, int len);
+    static inline bool lineIntersection(double x1, double y1, double x2, double y2,
+            double x3, double y3, double x4, double y4, Vector2& ret);
+
+    static void generateTriangleStrip(bool isCasterOpaque, const Vector2* penumbra,
+            int penumbraLength, const Vector2* umbra, int umbraLength,
+            const Vector3* poly, int polyLength, VertexBuffer& retstrips);
+
+#if DEBUG_SHADOW
+    // Verification utility function.
+    static bool testConvex(const Vector2* polygon, int polygonLength,
+            const char* name);
+    static void testIntersection(const Vector2* poly1, int poly1Length,
+        const Vector2* poly2, int poly2Length,
+        const Vector2* intersection, int intersectionLength);
+    static void updateBound(const Vector2 inVector, Vector2& lowerBound, Vector2& upperBound );
+#endif
+
+}; // SpotShadow
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_SPOT_SHADOW_H
diff --git a/libs/hwui/StatefulBaseRenderer.cpp b/libs/hwui/StatefulBaseRenderer.cpp
new file mode 100644
index 0000000..05f6cf8
--- /dev/null
+++ b/libs/hwui/StatefulBaseRenderer.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <SkCanvas.h>
+
+#include "StatefulBaseRenderer.h"
+
+namespace android {
+namespace uirenderer {
+
+StatefulBaseRenderer::StatefulBaseRenderer() :
+        mDirtyClip(false), mWidth(-1), mHeight(-1),
+        mSaveCount(1), mFirstSnapshot(new Snapshot), mSnapshot(mFirstSnapshot) {
+}
+
+void StatefulBaseRenderer::initializeSaveStack(float clipLeft, float clipTop,
+        float clipRight, float clipBottom) {
+    mSnapshot = new Snapshot(mFirstSnapshot,
+            SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+    mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
+    mSnapshot->fbo = getTargetFbo();
+    mSaveCount = 1;
+}
+
+void StatefulBaseRenderer::initializeViewport(int width, int height) {
+    mWidth = width;
+    mHeight = height;
+
+    mFirstSnapshot->height = height;
+    mFirstSnapshot->viewport.set(0, 0, width, height);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Save (layer)
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Non-virtual implementation of save, guaranteed to save without side-effects
+ *
+ * The approach here and in restoreSnapshot(), allows subclasses to directly manipulate the save
+ * stack, and ensures restoreToCount() doesn't call back into subclass overrides.
+ */
+int StatefulBaseRenderer::saveSnapshot(int flags) {
+    mSnapshot = new Snapshot(mSnapshot, flags);
+    return mSaveCount++;
+}
+
+int StatefulBaseRenderer::save(int flags) {
+    return saveSnapshot(flags);
+}
+
+/**
+ * Non-virtual implementation of restore, guaranteed to restore without side-effects.
+ */
+void StatefulBaseRenderer::restoreSnapshot() {
+    sp<Snapshot> toRemove = mSnapshot;
+    sp<Snapshot> toRestore = mSnapshot->previous;
+
+    mSaveCount--;
+    mSnapshot = toRestore;
+
+    // subclass handles restore implementation
+    onSnapshotRestored(*toRemove, *toRestore);
+}
+
+void StatefulBaseRenderer::restore() {
+    if (mSaveCount > 1) {
+        restoreSnapshot();
+    }
+}
+
+void StatefulBaseRenderer::restoreToCount(int saveCount) {
+    if (saveCount < 1) saveCount = 1;
+
+    while (mSaveCount > saveCount) {
+        restoreSnapshot();
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Matrix
+///////////////////////////////////////////////////////////////////////////////
+
+void StatefulBaseRenderer::getMatrix(SkMatrix* matrix) const {
+    mSnapshot->transform->copyTo(*matrix);
+}
+
+void StatefulBaseRenderer::translate(float dx, float dy, float dz) {
+    mSnapshot->transform->translate(dx, dy, dz);
+}
+
+void StatefulBaseRenderer::rotate(float degrees) {
+    mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f);
+}
+
+void StatefulBaseRenderer::scale(float sx, float sy) {
+    mSnapshot->transform->scale(sx, sy, 1.0f);
+}
+
+void StatefulBaseRenderer::skew(float sx, float sy) {
+    mSnapshot->transform->skew(sx, sy);
+}
+
+void StatefulBaseRenderer::setMatrix(const SkMatrix* matrix) {
+    if (matrix) {
+        mSnapshot->transform->load(*matrix);
+    } else {
+        mSnapshot->transform->loadIdentity();
+    }
+}
+
+void StatefulBaseRenderer::setMatrix(const Matrix4& matrix) {
+    mSnapshot->transform->load(matrix);
+}
+
+void StatefulBaseRenderer::concatMatrix(const SkMatrix* matrix) {
+    mat4 transform(*matrix);
+    mSnapshot->transform->multiply(transform);
+}
+
+void StatefulBaseRenderer::concatMatrix(const Matrix4& matrix) {
+    mSnapshot->transform->multiply(matrix);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Clip
+///////////////////////////////////////////////////////////////////////////////
+
+bool StatefulBaseRenderer::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
+    if (CC_LIKELY(currentTransform()->rectToRect())) {
+        mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op);
+        return !mSnapshot->clipRect->isEmpty();
+    }
+
+    SkPath path;
+    path.addRect(left, top, right, bottom);
+
+    return StatefulBaseRenderer::clipPath(&path, op);
+}
+
+bool StatefulBaseRenderer::clipPath(const SkPath* path, SkRegion::Op op) {
+    SkMatrix transform;
+    currentTransform()->copyTo(transform);
+
+    SkPath transformed;
+    path->transform(transform, &transformed);
+
+    SkRegion clip;
+    if (!mSnapshot->previous->clipRegion->isEmpty()) {
+        clip.setRegion(*mSnapshot->previous->clipRegion);
+    } else {
+        if (mSnapshot->previous == firstSnapshot()) {
+            clip.setRect(0, 0, getWidth(), getHeight());
+        } else {
+            Rect* bounds = mSnapshot->previous->clipRect;
+            clip.setRect(bounds->left, bounds->top, bounds->right, bounds->bottom);
+        }
+    }
+
+    SkRegion region;
+    region.setPath(transformed, clip);
+
+    mDirtyClip |= mSnapshot->clipRegionTransformed(region, op);
+    return !mSnapshot->clipRect->isEmpty();
+}
+
+bool StatefulBaseRenderer::clipRegion(const SkRegion* region, SkRegion::Op op) {
+    mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op);
+    return !mSnapshot->clipRect->isEmpty();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Quick Rejection
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Calculates whether content drawn within the passed bounds would be outside of, or intersect with
+ * the clipRect. Does not modify the scissor.
+ *
+ * @param clipRequired if not null, will be set to true if element intersects clip
+ *         (and wasn't rejected)
+ *
+ * @param snapOut if set, the geometry will be treated as having an AA ramp.
+ *         See Rect::snapGeometryToPixelBoundaries()
+ */
+bool StatefulBaseRenderer::calculateQuickRejectForScissor(float left, float top,
+        float right, float bottom, bool* clipRequired, bool snapOut) const {
+    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
+        return true;
+    }
+
+    Rect r(left, top, right, bottom);
+    currentTransform()->mapRect(r);
+    r.snapGeometryToPixelBoundaries(snapOut);
+
+    Rect clipRect(*currentClipRect());
+    clipRect.snapToPixelBoundaries();
+
+    if (!clipRect.intersects(r)) return true;
+
+    // clip is required if geometry intersects clip rect
+    if (clipRequired) *clipRequired = !clipRect.contains(r);
+    return false;
+}
+
+/**
+ * Returns false if drawing won't be clipped out.
+ *
+ * Makes the decision conservatively, by rounding out the mapped rect before comparing with the
+ * clipRect. To be used when perfect, pixel accuracy is not possible (esp. with tessellation) but
+ * rejection is still desired.
+ *
+ * This function, unlike quickRejectSetupScissor, should be used where precise geometry information
+ * isn't known (esp. when geometry adjusts based on scale). Generally, this will be first pass
+ * rejection where precise rejection isn't important, or precise information isn't available.
+ */
+bool StatefulBaseRenderer::quickRejectConservative(float left, float top,
+        float right, float bottom) const {
+    if (mSnapshot->isIgnored() || bottom <= top || right <= left) {
+        return true;
+    }
+
+    Rect r(left, top, right, bottom);
+    currentTransform()->mapRect(r);
+    r.roundOut(); // rounded out to be conservative
+
+    Rect clipRect(*currentClipRect());
+    clipRect.snapToPixelBoundaries();
+
+    if (!clipRect.intersects(r)) return true;
+
+    return false;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/StatefulBaseRenderer.h b/libs/hwui/StatefulBaseRenderer.h
new file mode 100644
index 0000000..bf34bec
--- /dev/null
+++ b/libs/hwui/StatefulBaseRenderer.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_STATEFUL_BASE_RENDERER_H
+#define ANDROID_HWUI_STATEFUL_BASE_RENDERER_H
+
+#include <utils/RefBase.h>
+
+#include "Renderer.h"
+#include "Snapshot.h"
+
+namespace android {
+namespace uirenderer {
+
+/**
+ * Abstract Renderer subclass, which implements Canvas state methods.
+ *
+ * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the
+ * Renderer interface. Drawing and recording classes that extend StatefulBaseRenderer will have
+ * different use cases:
+ *
+ * Drawing subclasses (i.e. OpenGLRenderer) can query attributes (such as transform) or hook into
+ * changes (e.g. save/restore) with minimal surface area for manipulating the stack itself.
+ *
+ * Recording subclasses (i.e. DisplayListRenderer) can both record and pass through state operations
+ * to StatefulBaseRenderer, so that not only will querying operations work (getClip/Matrix), but so
+ * that quickRejection can also be used.
+ */
+class StatefulBaseRenderer : public Renderer {
+public:
+    StatefulBaseRenderer();
+
+    virtual status_t prepare(bool opaque) {
+        return prepareDirty(0.0f, 0.0f, mWidth, mHeight, opaque);
+    }
+    void initializeViewport(int width, int height);
+    void initializeSaveStack(float clipLeft, float clipTop, float clipRight, float clipBottom);
+
+    // getters
+    bool hasRectToRectTransform() const {
+        return CC_LIKELY(currentTransform()->rectToRect());
+    }
+
+    // Save (layer)
+    virtual int getSaveCount() const { return mSaveCount; }
+    virtual int save(int flags);
+    virtual void restore();
+    virtual void restoreToCount(int saveCount);
+    //virtual int saveLayer(float left, float top, float right, float bottom,
+    //        int alpha, SkXfermode::Mode mode, int flags);
+
+    // Matrix
+    virtual void getMatrix(SkMatrix* outMatrix) const;
+    virtual void translate(float dx, float dy, float dz = 0.0f);
+    virtual void rotate(float degrees);
+    virtual void scale(float sx, float sy);
+    virtual void skew(float sx, float sy);
+
+    virtual void setMatrix(const SkMatrix* matrix);
+    void setMatrix(const Matrix4& matrix); // internal only convenience method
+    virtual void concatMatrix(const SkMatrix* matrix);
+    void concatMatrix(const Matrix4& matrix); // internal only convenience method
+
+    // Clip
+    const Rect& getClipBounds() const { return mSnapshot->getLocalClip(); }
+    virtual bool quickRejectConservative(float left, float top, float right, float bottom) const;
+
+    virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
+    virtual bool clipPath(const SkPath* path, SkRegion::Op op);
+    virtual bool clipRegion(const SkRegion* region, SkRegion::Op op);
+
+protected:
+    int getWidth() { return mWidth; }
+    int getHeight() { return mHeight; }
+
+    // Save
+    int saveSnapshot(int flags);
+    void restoreSnapshot();
+
+    // allows subclasses to control what value is stored in snapshot's fbo field in
+    // initializeSaveStack
+    virtual GLuint getTargetFbo() const {
+        return -1;
+    }
+
+    // Clip
+    bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
+            bool* clipRequired, bool snapOut) const;
+
+    /**
+     * Called just after a restore has occurred. The 'removed' snapshot popped from the stack,
+     * 'restored' snapshot has become the top/current.
+     *
+     * Subclasses can override this method to handle layer restoration
+     */
+    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {};
+
+    inline const Rect* currentClipRect() const {
+        return mSnapshot->clipRect;
+    }
+
+    inline const mat4* currentTransform() const {
+        return mSnapshot->transform;
+    }
+
+    inline const Snapshot* currentSnapshot() const {
+        return mSnapshot != NULL ? mSnapshot.get() : mFirstSnapshot.get();
+    }
+
+    inline const Snapshot* firstSnapshot() const {
+        return mFirstSnapshot.get();
+    }
+
+    // indicites that the clip has been changed since the last time it was consumed
+    bool mDirtyClip;
+
+private:
+    // Dimensions of the drawing surface
+    int mWidth, mHeight;
+
+    // Number of saved states
+    int mSaveCount;
+
+    // Base state
+    sp<Snapshot> mFirstSnapshot;
+
+protected:
+    // Current state
+    // TODO: should become private, once hooks needed by OpenGLRenderer are added
+    sp<Snapshot> mSnapshot;
+
+}; // class StatefulBaseRenderer
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_STATEFUL_BASE_RENDERER_H
diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/Stencil.cpp
index 2764523..8ce57db 100644
--- a/libs/hwui/Stencil.cpp
+++ b/libs/hwui/Stencil.cpp
@@ -35,7 +35,7 @@
 Stencil::Stencil(): mState(kDisabled) {
 }
 
-uint32_t Stencil::getStencilSize() {
+uint8_t Stencil::getStencilSize() {
     return STENCIL_BUFFER_SIZE;
 }
 
diff --git a/libs/hwui/Stencil.h b/libs/hwui/Stencil.h
index 83ad668..c5e5186 100644
--- a/libs/hwui/Stencil.h
+++ b/libs/hwui/Stencil.h
@@ -40,7 +40,7 @@
      * Returns the desired size for the stencil buffer. If the returned value
      * is 0, then no stencil buffer is required.
      */
-    ANDROID_API static uint32_t getStencilSize();
+    ANDROID_API static uint8_t getStencilSize();
 
     /**
      * Returns the smallest stencil format accepted by render buffers.
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
index 0b2c130..4eec462 100644
--- a/libs/hwui/TextDropShadowCache.cpp
+++ b/libs/hwui/TextDropShadowCache.cpp
@@ -147,7 +147,7 @@
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
 
-void TextDropShadowCache::operator()(ShadowText& text, ShadowTexture*& texture) {
+void TextDropShadowCache::operator()(ShadowText&, ShadowTexture*& texture) {
     if (texture) {
         mSize -= texture->bitmapSize;
 
@@ -168,7 +168,7 @@
     mCache.clear();
 }
 
-ShadowTexture* TextDropShadowCache::get(SkPaint* paint, const char* text, uint32_t len,
+ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const char* text, uint32_t len,
         int numGlyphs, float radius, const float* positions) {
     ShadowText entry(paint, radius, len, text, positions);
     ShadowTexture* texture = mCache.get(entry);
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 04d7357..54b930b 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -38,7 +38,7 @@
     }
 
     // len is the number of bytes in text
-    ShadowText(SkPaint* paint, float radius, uint32_t len, const char* srcText,
+    ShadowText(const SkPaint* paint, float radius, uint32_t len, const char* srcText,
             const float* positions):
             len(len), radius(radius), positions(positions) {
         // TODO: Propagate this through the API, we should not cast here
@@ -135,7 +135,7 @@
      */
     void operator()(ShadowText& text, ShadowTexture*& texture);
 
-    ShadowTexture* get(SkPaint* paint, const char* text, uint32_t len,
+    ShadowTexture* get(const SkPaint* paint, const char* text, uint32_t len,
             int numGlyphs, float radius, const float* positions);
 
     /**
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index d5ba8c3..01d72d1 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -34,7 +34,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 TextureCache::TextureCache():
-        mCache(LruCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
+        mCache(LruCache<const SkBitmap*, Texture*>::kUnlimitedCapacity),
         mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
         mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
     char property[PROPERTY_VALUE_MAX];
@@ -58,7 +58,7 @@
 }
 
 TextureCache::TextureCache(uint32_t maxByteSize):
-        mCache(LruCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
+        mCache(LruCache<const SkBitmap*, Texture*>::kUnlimitedCapacity),
         mSize(0), mMaxSize(maxByteSize) {
     init();
 }
@@ -103,7 +103,7 @@
 // Callbacks
 ///////////////////////////////////////////////////////////////////////////////
 
-void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) {
+void TextureCache::operator()(const SkBitmap*&, Texture*& texture) {
     // This will be called already locked
     if (texture) {
         mSize -= texture->bitmapSize;
@@ -121,7 +121,7 @@
 // Caching
 ///////////////////////////////////////////////////////////////////////////////
 
-Texture* TextureCache::get(SkBitmap* bitmap) {
+Texture* TextureCache::get(const SkBitmap* bitmap) {
     Texture* texture = mCache.get(bitmap);
 
     if (!texture) {
@@ -161,7 +161,7 @@
     return texture;
 }
 
-Texture* TextureCache::getTransient(SkBitmap* bitmap) {
+Texture* TextureCache::getTransient(const SkBitmap* bitmap) {
     Texture* texture = new Texture();
     texture->bitmapSize = bitmap->rowBytes() * bitmap->height();
     texture->cleanup = true;
@@ -171,11 +171,11 @@
     return texture;
 }
 
-void TextureCache::remove(SkBitmap* bitmap) {
+void TextureCache::remove(const SkBitmap* bitmap) {
     mCache.remove(bitmap);
 }
 
-void TextureCache::removeDeferred(SkBitmap* bitmap) {
+void TextureCache::removeDeferred(const SkBitmap* bitmap) {
     Mutex::Autolock _l(mLock);
     mGarbage.push(bitmap);
 }
@@ -184,7 +184,7 @@
     Mutex::Autolock _l(mLock);
     size_t count = mGarbage.size();
     for (size_t i = 0; i < count; i++) {
-        SkBitmap* bitmap = mGarbage.itemAt(i);
+        const SkBitmap* bitmap = mGarbage.itemAt(i);
         mCache.remove(bitmap);
         delete bitmap;
     }
@@ -211,7 +211,7 @@
     }
 }
 
-void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {
+void TextureCache::generateTexture(const SkBitmap* bitmap, Texture* texture, bool regenerate) {
     SkAutoLockPixels alp(*bitmap);
 
     if (!bitmap->readyToDraw()) {
@@ -239,7 +239,7 @@
 
     Caches::getInstance().bindTexture(texture->id);
 
-    switch (bitmap->getConfig()) {
+    switch (bitmap->config()) {
     case SkBitmap::kA8_Config:
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(),
@@ -267,7 +267,7 @@
         texture->blend = !bitmap->isOpaque();
         break;
     default:
-        ALOGW("Unsupported bitmap config: %d", bitmap->getConfig());
+        ALOGW("Unsupported bitmap config: %d", bitmap->config());
         break;
     }
 
@@ -284,7 +284,7 @@
     }
 }
 
-void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
+void TextureCache::uploadLoFiTexture(bool resize, const SkBitmap* bitmap,
         uint32_t width, uint32_t height) {
     SkBitmap rgbaBitmap;
     rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height, 0, bitmap->alphaType());
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 57fc19a..e33c60d 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -49,7 +49,7 @@
  * Any texture added to the cache causing the cache to grow beyond the maximum
  * allowed size will also cause the oldest texture to be kicked out.
  */
-class TextureCache: public OnEntryRemoved<SkBitmap*, Texture*> {
+class TextureCache: public OnEntryRemoved<const SkBitmap*, Texture*> {
 public:
     TextureCache();
     TextureCache(uint32_t maxByteSize);
@@ -59,28 +59,28 @@
      * Used as a callback when an entry is removed from the cache.
      * Do not invoke directly.
      */
-    void operator()(SkBitmap*& bitmap, Texture*& texture);
+    void operator()(const SkBitmap*& bitmap, Texture*& texture);
 
     /**
      * Returns the texture associated with the specified bitmap. If the texture
      * cannot be found in the cache, a new texture is generated.
      */
-    Texture* get(SkBitmap* bitmap);
+    Texture* get(const SkBitmap* bitmap);
     /**
      * Returns the texture associated with the specified bitmap. The generated
      * texture is not kept in the cache. The caller must destroy the texture.
      */
-    Texture* getTransient(SkBitmap* bitmap);
+    Texture* getTransient(const SkBitmap* bitmap);
     /**
      * Removes the texture associated with the specified bitmap.
      * Upon remove the texture is freed.
      */
-    void remove(SkBitmap* bitmap);
+    void remove(const SkBitmap* bitmap);
     /**
      * Removes the texture associated with the specified bitmap. This is meant
      * to be called from threads that are not the EGL context thread.
      */
-    void removeDeferred(SkBitmap* bitmap);
+    void removeDeferred(const SkBitmap* bitmap);
     /**
      * Process deferred removals.
      */
@@ -122,15 +122,15 @@
      * @param regenerate If true, the bitmap data is reuploaded into the texture, but
      *        no new texture is generated.
      */
-    void generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate = false);
+    void generateTexture(const SkBitmap* bitmap, Texture* texture, bool regenerate = false);
 
-    void uploadLoFiTexture(bool resize, SkBitmap* bitmap, uint32_t width, uint32_t height);
+    void uploadLoFiTexture(bool resize, const SkBitmap* bitmap, uint32_t width, uint32_t height);
     void uploadToTexture(bool resize, GLenum format, GLsizei stride,
             GLsizei width, GLsizei height, GLenum type, const GLvoid * data);
 
     void init();
 
-    LruCache<SkBitmap*, Texture*> mCache;
+    LruCache<const SkBitmap*, Texture*> mCache;
 
     uint32_t mSize;
     uint32_t mMaxSize;
@@ -140,7 +140,7 @@
 
     bool mDebugEnabled;
 
-    Vector<SkBitmap*> mGarbage;
+    Vector<const SkBitmap*> mGarbage;
     mutable Mutex mLock;
 }; // class TextureCache
 
diff --git a/libs/hwui/Vector.h b/libs/hwui/Vector.h
index 497924e..c61cb61 100644
--- a/libs/hwui/Vector.h
+++ b/libs/hwui/Vector.h
@@ -36,6 +36,10 @@
         x(px), y(py) {
     }
 
+    float lengthSquared() const {
+        return x * x + y * y;
+    }
+
     float length() const {
         return sqrt(x * x + y * y);
     }
@@ -107,6 +111,25 @@
     }
 }; // class Vector2
 
+class Vector3 {
+public:
+    float x;
+    float y;
+    float z;
+
+    Vector3() :
+        x(0.0f), y(0.0f), z(0.0f) {
+    }
+
+    Vector3(float px, float py, float pz) :
+        x(px), y(py), z(pz) {
+    }
+
+    void dump() {
+        ALOGD("Vector3[%.2f, %.2f, %.2f]", x, y, z);
+    }
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 // Types
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index 790d4fc..5d7a199 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -33,13 +33,14 @@
      * Program::set()), and used to make geometry damage rect calculation conservative (see
      * Rect::snapGeometryToPixelBoundaries())
      */
-    static const float gGeometryFudgeFactor = 0.0656f;
+    static float GeometryFudgeFactor() { return 0.0656f; }
 
-    float position[2];
+
+    float x, y;
 
     static inline void set(Vertex* vertex, float x, float y) {
-        vertex[0].position[0] = x;
-        vertex[0].position[1] = y;
+        vertex[0].x = x;
+        vertex[0].y = y;
     }
 
     static inline void set(Vertex* vertex, vec2 val) {
@@ -47,7 +48,7 @@
     }
 
     static inline void copyWithOffset(Vertex* vertex, const Vertex& src, float x, float y) {
-        set(vertex, src.position[0] + x, src.position[1] + y);
+        set(vertex, src.x + x, src.y + y);
     }
 
 }; // struct Vertex
@@ -56,19 +57,19 @@
  * Simple structure to describe a vertex with a position and texture UV.
  */
 struct TextureVertex {
-    float position[2];
-    float texture[2];
+    float x, y;
+    float u, v;
 
     static inline void set(TextureVertex* vertex, float x, float y, float u, float v) {
-        vertex[0].position[0] = x;
-        vertex[0].position[1] = y;
-        vertex[0].texture[0] = u;
-        vertex[0].texture[1] = v;
+        vertex[0].x = x;
+        vertex[0].y = y;
+        vertex[0].u = u;
+        vertex[0].v = v;
     }
 
     static inline void setUV(TextureVertex* vertex, float u, float v) {
-        vertex[0].texture[0] = u;
-        vertex[0].texture[1] = v;
+        vertex[0].u = u;
+        vertex[0].v = v;
     }
 }; // struct TextureVertex
 
@@ -76,17 +77,17 @@
  * Simple structure to describe a vertex with a position, texture UV and ARGB color.
  */
 struct ColorTextureVertex : TextureVertex {
-    float color[4];
+    float r, g, b, a;
 
     static inline void set(ColorTextureVertex* vertex, float x, float y,
             float u, float v, int color) {
         TextureVertex::set(vertex, x, y, u, v);
 
         const float a = ((color >> 24) & 0xff) / 255.0f;
-        vertex[0].color[0] = a * ((color >> 16) & 0xff) / 255.0f;
-        vertex[0].color[1] = a * ((color >>  8) & 0xff) / 255.0f;
-        vertex[0].color[2] = a * ((color      ) & 0xff) / 255.0f;
-        vertex[0].color[3] = a;
+        vertex[0].r = a * ((color >> 16) & 0xff) / 255.0f;
+        vertex[0].g = a * ((color >>  8) & 0xff) / 255.0f;
+        vertex[0].b = a * ((color      ) & 0xff) / 255.0f;
+        vertex[0].a = a;
     }
 }; // struct ColorTextureVertex
 
@@ -103,7 +104,7 @@
 
     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::set(vertex, src.x + x, src.y + y);
         vertex[0].alpha = src.alpha;
     }
 
diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h
new file mode 100644
index 0000000..8b6872e
--- /dev/null
+++ b/libs/hwui/VertexBuffer.h
@@ -0,0 +1,102 @@
+/*
+ * 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 ANDROID_HWUI_VERTEX_BUFFER_H
+#define ANDROID_HWUI_VERTEX_BUFFER_H
+
+
+namespace android {
+namespace uirenderer {
+
+class VertexBuffer {
+public:
+    VertexBuffer():
+        mBuffer(0),
+        mVertexCount(0),
+        mCleanupMethod(NULL)
+    {}
+
+    ~VertexBuffer() {
+        if (mCleanupMethod) mCleanupMethod(mBuffer);
+    }
+
+    /**
+       This should be the only method used by the Tessellator. Subsequent calls to
+       alloc will allocate space within the first allocation (useful if you want to
+       eventually allocate multiple regions within a single VertexBuffer, such as
+       with PathTessellator::tesselateLines())
+     */
+    template <class TYPE>
+    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 + vertexCount;
+            return reallocBuffer;
+        }
+        mVertexCount = vertexCount;
+        mReallocBuffer = mBuffer = (void*)new TYPE[vertexCount];
+        mCleanupMethod = &(cleanup<TYPE>);
+
+        return (TYPE*)mBuffer;
+    }
+
+    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);
+        }
+    }
+
+    const void* getBuffer() const { return mBuffer; }
+    unsigned int getVertexCount() const { return mVertexCount; }
+
+    template <class TYPE>
+    void createDegenerateSeparators(int allocSize) {
+        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));
+        }
+    }
+
+private:
+    template <class TYPE>
+    static void cleanup(void* buffer) {
+        delete[] (TYPE*)buffer;
+    }
+
+    void* mBuffer;
+    unsigned int mVertexCount;
+
+    void* mReallocBuffer; // used for multi-allocation
+
+    void (*mCleanupMethod)(void*);
+};
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_VERTEX_BUFFER_H
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index d5f38b5..24ffb80 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -114,7 +114,7 @@
             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);
+            mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE);
 
     // OpenGL ES 3.0+ lets us specify the row length for unpack operations such
     // as glTexSubImage2D(). This allows us to upload a sub-rectangle of a texture.
@@ -143,7 +143,7 @@
     // reset, then create a new remainder space to start again
     reset();
     mCacheBlocks = new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
-            mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE, true);
+            mWidth - TEXTURE_BORDER_SIZE, mHeight - TEXTURE_BORDER_SIZE);
 }
 
 void CacheTexture::releaseMesh() {
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index 61b38f8..4cc4f22 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -54,7 +54,7 @@
     CacheBlock* mNext;
     CacheBlock* mPrev;
 
-    CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height, bool empty = false):
+    CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height):
             mX(x), mY(y), mWidth(width), mHeight(height), mNext(NULL), mPrev(NULL) {
     }
 
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index 436dcef..5187f8f 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -267,7 +267,7 @@
             glyph->mCacheTexture);
 }
 
-CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching) {
+CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bool precaching) {
     CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(textUnit);
     if (cachedGlyph) {
         // Is the glyph still in texture cache?
@@ -283,14 +283,14 @@
     return cachedGlyph;
 }
 
-void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+void Font::render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y, const float* positions) {
     render(paint, text, start, len, numGlyphs, x, y, FRAMEBUFFER, NULL,
             0, 0, NULL, positions);
 }
 
-void Font::render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
-        int numGlyphs, SkPath* path, float hOffset, float vOffset) {
+void Font::render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+        int numGlyphs, const SkPath* path, float hOffset, float vOffset) {
     if (numGlyphs == 0 || text == NULL || len == 0) {
         return;
     }
@@ -339,7 +339,7 @@
     }
 }
 
-void Font::measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+void Font::measure(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
         int numGlyphs, Rect *bounds, const float* positions) {
     if (bounds == NULL) {
         ALOGE("No return rectangle provided to measure text");
@@ -349,7 +349,7 @@
     render(paint, text, start, len, numGlyphs, 0, 0, MEASURE, NULL, 0, 0, bounds, positions);
 }
 
-void Font::precache(SkPaint* paint, const char* text, int numGlyphs) {
+void Font::precache(const SkPaint* paint, const char* text, int numGlyphs) {
     ATRACE_NAME("precacheText");
 
     if (numGlyphs == 0 || text == NULL) {
@@ -370,7 +370,7 @@
     }
 }
 
-void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+void Font::render(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
         int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
         uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* positions) {
     if (numGlyphs == 0 || text == NULL || len == 0) {
@@ -416,8 +416,8 @@
     }
 }
 
-void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
-        CachedGlyphInfo* glyph, bool precaching) {
+void Font::updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph,
+        SkGlyphCache* skiaGlyphCache, CachedGlyphInfo* glyph, bool precaching) {
     glyph->mAdvanceX = skiaGlyph.fAdvanceX;
     glyph->mAdvanceY = skiaGlyph.fAdvanceY;
     glyph->mBitmapLeft = skiaGlyph.fLeft;
@@ -460,7 +460,7 @@
     }
 }
 
-CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching) {
+CachedGlyphInfo* Font::cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching) {
     CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
     mCachedGlyphs.add(glyph, newGlyph);
 
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index f68b430..02197bc 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -77,11 +77,11 @@
 
     ~Font();
 
-    void render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+    void render(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y, const float* positions);
 
-    void render(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
-            int numGlyphs, SkPath* path, float hOffset, float vOffset);
+    void render(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+            int numGlyphs, const SkPath* path, float hOffset, float vOffset);
 
     const Font::FontDescription& getDescription() const {
         return mDescription;
@@ -106,20 +106,20 @@
         MEASURE,
     };
 
-    void precache(SkPaint* paint, const char* text, int numGlyphs);
+    void precache(const SkPaint* paint, const char* text, int numGlyphs);
 
-    void render(SkPaint* paint, const char *text, uint32_t start, uint32_t len,
+    void render(const SkPaint* paint, const char *text, uint32_t start, uint32_t len,
             int numGlyphs, int x, int y, RenderMode mode, uint8_t *bitmap,
             uint32_t bitmapW, uint32_t bitmapH, Rect *bounds, const float* positions);
 
-    void measure(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
+    void measure(const SkPaint* paint, const char* text, uint32_t start, uint32_t len,
             int numGlyphs, Rect *bounds, const float* positions);
 
     void invalidateTextureCache(CacheTexture* cacheTexture = NULL);
 
-    CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
-    void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, SkGlyphCache* skiaGlyphCache,
-            CachedGlyphInfo* glyph, bool precaching);
+    CachedGlyphInfo* cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching);
+    void updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph,
+            SkGlyphCache* skiaGlyphCache, CachedGlyphInfo* glyph, bool precaching);
 
     void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
             uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
@@ -136,7 +136,8 @@
     void drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
             SkPathMeasure& measure, SkPoint* position, SkVector* tangent);
 
-    CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching = false);
+    CachedGlyphInfo* getCachedGlyph(const SkPaint* paint, glyph_t textUnit,
+            bool precaching = false);
 
     FontRenderer* mState;
     FontDescription mDescription;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
new file mode 100644
index 0000000..8ebffc2
--- /dev/null
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CanvasContext"
+
+#include "CanvasContext.h"
+
+#include <cutils/properties.h>
+#include <private/hwui/DrawGlInfo.h>
+#include <strings.h>
+
+#include "RenderThread.h"
+#include "../Caches.h"
+#include "../DeferredLayerUpdater.h"
+#include "../LayerRenderer.h"
+#include "../OpenGLRenderer.h"
+#include "../Stencil.h"
+
+#define PROPERTY_RENDER_DIRTY_REGIONS "debug.hwui.render_dirty_regions"
+#define GLES_VERSION 2
+
+#ifdef USE_OPENGL_RENDERER
+// Android-specific addition that is used to show when frames began in systrace
+EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface);
+#endif
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+#define ERROR_CASE(x) case x: return #x;
+static const char* egl_error_str(EGLint error) {
+    switch (error) {
+        ERROR_CASE(EGL_SUCCESS)
+        ERROR_CASE(EGL_NOT_INITIALIZED)
+        ERROR_CASE(EGL_BAD_ACCESS)
+        ERROR_CASE(EGL_BAD_ALLOC)
+        ERROR_CASE(EGL_BAD_ATTRIBUTE)
+        ERROR_CASE(EGL_BAD_CONFIG)
+        ERROR_CASE(EGL_BAD_CONTEXT)
+        ERROR_CASE(EGL_BAD_CURRENT_SURFACE)
+        ERROR_CASE(EGL_BAD_DISPLAY)
+        ERROR_CASE(EGL_BAD_MATCH)
+        ERROR_CASE(EGL_BAD_NATIVE_PIXMAP)
+        ERROR_CASE(EGL_BAD_NATIVE_WINDOW)
+        ERROR_CASE(EGL_BAD_PARAMETER)
+        ERROR_CASE(EGL_BAD_SURFACE)
+        ERROR_CASE(EGL_CONTEXT_LOST)
+    default:
+        return "Unknown error";
+    }
+}
+static const char* egl_error_str() {
+    return egl_error_str(eglGetError());
+}
+
+static bool load_dirty_regions_property() {
+    char buf[PROPERTY_VALUE_MAX];
+    int len = property_get(PROPERTY_RENDER_DIRTY_REGIONS, buf, "true");
+    return !strncasecmp("true", buf, len);
+}
+
+// This class contains the shared global EGL objects, such as EGLDisplay
+// and EGLConfig, which are re-used by CanvasContext
+class GlobalContext {
+public:
+    static GlobalContext* get();
+
+    // Returns true on success, false on failure
+    void initialize();
+
+    void usePBufferSurface();
+    EGLSurface createSurface(EGLNativeWindowType window);
+    void destroySurface(EGLSurface surface);
+
+    void destroy();
+
+    bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; }
+    void makeCurrent(EGLSurface surface);
+    void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
+    void swapBuffers(EGLSurface surface);
+
+    bool enableDirtyRegions(EGLSurface surface);
+
+private:
+    GlobalContext();
+    // GlobalContext is never destroyed, method is purposely not implemented
+    ~GlobalContext();
+
+    void loadConfig();
+    void createContext();
+    void initAtlas();
+
+    static GlobalContext* sContext;
+
+    EGLDisplay mEglDisplay;
+    EGLConfig mEglConfig;
+    EGLContext mEglContext;
+    EGLSurface mPBufferSurface;
+
+    const bool mRequestDirtyRegions;
+    bool mCanSetDirtyRegions;
+
+    EGLSurface mCurrentSurface;
+};
+
+GlobalContext* GlobalContext::sContext = 0;
+
+GlobalContext* GlobalContext::get() {
+    if (!sContext) {
+        sContext = new GlobalContext();
+    }
+    return sContext;
+}
+
+GlobalContext::GlobalContext()
+        : mEglDisplay(EGL_NO_DISPLAY)
+        , mEglConfig(0)
+        , mEglContext(EGL_NO_CONTEXT)
+        , mPBufferSurface(EGL_NO_SURFACE)
+        , mRequestDirtyRegions(load_dirty_regions_property())
+        , mCurrentSurface(EGL_NO_SURFACE) {
+    mCanSetDirtyRegions = mRequestDirtyRegions;
+    ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false");
+}
+
+void GlobalContext::initialize() {
+    if (mEglDisplay != EGL_NO_DISPLAY) return;
+
+    mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
+            "Failed to get EGL_DEFAULT_DISPLAY! err=%s", egl_error_str());
+
+    EGLint major, minor;
+    LOG_ALWAYS_FATAL_IF(eglInitialize(mEglDisplay, &major, &minor) == EGL_FALSE,
+            "Failed to initialize display %p! err=%s", mEglDisplay, egl_error_str());
+
+    ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor);
+
+    loadConfig();
+    createContext();
+    usePBufferSurface();
+    Caches::getInstance().init();
+    initAtlas();
+}
+
+void GlobalContext::loadConfig() {
+    EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
+    EGLint attribs[] = {
+            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+            EGL_RED_SIZE, 8,
+            EGL_GREEN_SIZE, 8,
+            EGL_BLUE_SIZE, 8,
+            EGL_ALPHA_SIZE, 8,
+            EGL_DEPTH_SIZE, 0,
+            EGL_CONFIG_CAVEAT, EGL_NONE,
+            EGL_STENCIL_SIZE, Stencil::getStencilSize(),
+            EGL_SURFACE_TYPE, EGL_WINDOW_BIT | swapBehavior,
+            EGL_NONE
+    };
+
+    EGLint num_configs = 1;
+    if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs)
+            || num_configs != 1) {
+        // Failed to get a valid config
+        if (mCanSetDirtyRegions) {
+            ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...");
+            // Try again without dirty regions enabled
+            mCanSetDirtyRegions = false;
+            loadConfig();
+        } else {
+            LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str());
+        }
+    }
+}
+
+void GlobalContext::createContext() {
+    EGLint attribs[] = { EGL_CONTEXT_CLIENT_VERSION, GLES_VERSION, EGL_NONE };
+    mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, attribs);
+    LOG_ALWAYS_FATAL_IF(mEglContext == EGL_NO_CONTEXT,
+        "Failed to create context, error = %s", egl_error_str());
+}
+
+void GlobalContext::initAtlas() {
+    // TODO implement
+    // For now just run without an atlas
+}
+
+void GlobalContext::usePBufferSurface() {
+    LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
+            "usePBufferSurface() called on uninitialized GlobalContext!");
+
+    if (mPBufferSurface == EGL_NO_SURFACE) {
+        EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
+        mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs);
+    }
+    makeCurrent(mPBufferSurface);
+}
+
+EGLSurface GlobalContext::createSurface(EGLNativeWindowType window) {
+    initialize();
+    return eglCreateWindowSurface(mEglDisplay, mEglConfig, window, NULL);
+}
+
+void GlobalContext::destroySurface(EGLSurface surface) {
+    if (isCurrent(surface)) {
+        makeCurrent(EGL_NO_SURFACE);
+    }
+    if (!eglDestroySurface(mEglDisplay, surface)) {
+        ALOGW("Failed to destroy surface %p, error=%s", (void*)surface, egl_error_str());
+    }
+}
+
+void GlobalContext::destroy() {
+    if (mEglDisplay == EGL_NO_DISPLAY) return;
+
+    usePBufferSurface();
+    if (Caches::hasInstance()) {
+        Caches::getInstance().terminate();
+    }
+
+    eglDestroyContext(mEglDisplay, mEglContext);
+    eglDestroySurface(mEglDisplay, mPBufferSurface);
+    eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglTerminate(mEglDisplay);
+    eglReleaseThread();
+
+    mEglDisplay = EGL_NO_DISPLAY;
+    mEglContext = EGL_NO_CONTEXT;
+    mPBufferSurface = EGL_NO_SURFACE;
+    mCurrentSurface = EGL_NO_SURFACE;
+}
+
+void GlobalContext::makeCurrent(EGLSurface surface) {
+    if (isCurrent(surface)) return;
+
+    if (surface == EGL_NO_SURFACE) {
+        // If we are setting EGL_NO_SURFACE we don't care about any of the potential
+        // return errors, which would only happen if mEglDisplay had already been
+        // destroyed in which case the current context is already NO_CONTEXT
+        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    } else if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) {
+        LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s",
+                (void*)surface, egl_error_str());
+    }
+    mCurrentSurface = surface;
+}
+
+void GlobalContext::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {
+    LOG_ALWAYS_FATAL_IF(surface == EGL_NO_SURFACE,
+            "Tried to beginFrame on EGL_NO_SURFACE!");
+    makeCurrent(surface);
+    if (width) {
+        eglQuerySurface(mEglDisplay, surface, EGL_WIDTH, width);
+    }
+    if (height) {
+        eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
+    }
+    eglBeginFrame(mEglDisplay, surface);
+}
+
+void GlobalContext::swapBuffers(EGLSurface surface) {
+    eglSwapBuffers(mEglDisplay, surface);
+    EGLint err = eglGetError();
+    // TODO: Check whether we need to special case EGL_CONTEXT_LOST
+    LOG_ALWAYS_FATAL_IF(err != EGL_SUCCESS,
+            "Encountered EGL error %d %s during rendering", err, egl_error_str(err));
+}
+
+bool GlobalContext::enableDirtyRegions(EGLSurface surface) {
+    if (!mRequestDirtyRegions) return false;
+
+    if (mCanSetDirtyRegions) {
+        if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) {
+            ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s",
+                    (void*) surface, egl_error_str());
+            return false;
+        }
+        return true;
+    }
+    // Perhaps it is already enabled?
+    EGLint value;
+    if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) {
+        ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p",
+                (void*) surface, egl_error_str());
+        return false;
+    }
+    return value == EGL_BUFFER_PRESERVED;
+}
+
+CanvasContext::CanvasContext(bool translucent)
+        : mRenderThread(RenderThread::getInstance())
+        , mEglSurface(EGL_NO_SURFACE)
+        , mDirtyRegionsEnabled(false)
+        , mOpaque(!translucent)
+        , mCanvas(0)
+        , mHaveNewSurface(false)
+        , mInvokeFunctorsPending(false)
+        , mInvokeFunctorsTask(this) {
+    mGlobalContext = GlobalContext::get();
+}
+
+CanvasContext::~CanvasContext() {
+    removeFunctorsTask();
+    destroyCanvas();
+}
+
+void CanvasContext::destroyCanvas() {
+    if (mCanvas) {
+        delete mCanvas;
+        mCanvas = 0;
+    }
+    setSurface(NULL);
+}
+
+void CanvasContext::setSurface(EGLNativeWindowType window) {
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mGlobalContext->destroySurface(mEglSurface);
+        mEglSurface = EGL_NO_SURFACE;
+    }
+
+    if (window) {
+        mEglSurface = mGlobalContext->createSurface(window);
+        LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
+                "Failed to create EGLSurface for window %p, eglErr = %s",
+                (void*) window, egl_error_str());
+    }
+
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface);
+        mHaveNewSurface = true;
+    }
+}
+
+void CanvasContext::swapBuffers() {
+    mGlobalContext->swapBuffers(mEglSurface);
+    mHaveNewSurface = false;
+}
+
+void CanvasContext::makeCurrent() {
+    mGlobalContext->makeCurrent(mEglSurface);
+}
+
+bool CanvasContext::initialize(EGLNativeWindowType window) {
+    if (mCanvas) return false;
+    setSurface(window);
+    makeCurrent();
+    mCanvas = new OpenGLRenderer();
+    mCanvas->initProperties();
+    return true;
+}
+
+void CanvasContext::updateSurface(EGLNativeWindowType window) {
+    setSurface(window);
+    makeCurrent();
+}
+
+void CanvasContext::setup(int width, int height) {
+    if (!mCanvas) return;
+    mCanvas->setViewport(width, height);
+}
+
+void CanvasContext::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
+    displayList->setData(newData);
+}
+
+void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters) {
+    mGlobalContext->makeCurrent(mEglSurface);
+    for (size_t i = 0; i < layerUpdaters->size(); i++) {
+        DeferredLayerUpdater* update = layerUpdaters->itemAt(i);
+        LOG_ALWAYS_FATAL_IF(!update->apply(), "Failed to update layer!");
+        if (update->backingLayer()->deferredUpdateScheduled) {
+            mCanvas->pushLayerUpdate(update->backingLayer());
+        }
+    }
+}
+
+void CanvasContext::drawDisplayList(RenderNode* displayList, Rect* dirty) {
+    LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
+            "drawDisplayList called on a context with no canvas or surface!");
+
+    EGLint width, height;
+    mGlobalContext->beginFrame(mEglSurface, &width, &height);
+    if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) {
+        mCanvas->setViewport(width, height);
+        dirty = NULL;
+    } else if (!mDirtyRegionsEnabled || mHaveNewSurface) {
+        dirty = NULL;
+    }
+
+    status_t status;
+    if (dirty) {
+        status = mCanvas->prepareDirty(dirty->left, dirty->top,
+                dirty->right, dirty->bottom, mOpaque);
+    } else {
+        status = mCanvas->prepare(mOpaque);
+    }
+
+    Rect outBounds;
+    status |= mCanvas->drawDisplayList(displayList, outBounds);
+    handleFunctorStatus(status, outBounds);
+
+    // TODO: Draw debug info
+    // TODO: Performance tracking
+
+    mCanvas->finish();
+
+    if (status & DrawGlInfo::kStatusDrew) {
+        swapBuffers();
+    }
+}
+
+void InvokeFunctorsTask::run() {
+    mContext->invokeFunctors();
+}
+
+void CanvasContext::attachFunctor(Functor* functor) {
+    if (!mCanvas) return;
+
+    mCanvas->attachFunctor(functor);
+    removeFunctorsTask();
+    queueFunctorsTask(0);
+}
+
+void CanvasContext::detachFunctor(Functor* functor) {
+    if (!mCanvas) return;
+
+    mCanvas->detachFunctor(functor);
+}
+
+void CanvasContext::invokeFunctors() {
+    mInvokeFunctorsPending = false;
+
+    if (!mCanvas) return;
+
+    makeCurrent();
+    Rect dirty;
+    int status = mCanvas->invokeFunctors(dirty);
+    handleFunctorStatus(status, dirty);
+}
+
+void CanvasContext::handleFunctorStatus(int status, const Rect& redrawClip) {
+    if (status & DrawGlInfo::kStatusDraw) {
+        // TODO: Invalidate the redrawClip
+        // Do we need to post to ViewRootImpl like the current renderer?
+        // Can we just enqueue ourselves to re-invoke the same display list?
+        // Something else entirely? Does ChromiumView still want this in a
+        // RenderThread world?
+    }
+
+    if (status & DrawGlInfo::kStatusInvoke) {
+        queueFunctorsTask();
+    }
+}
+
+void CanvasContext::removeFunctorsTask() {
+    if (!mInvokeFunctorsPending) return;
+
+    mInvokeFunctorsPending = false;
+    mRenderThread.remove(&mInvokeFunctorsTask);
+}
+
+void CanvasContext::queueFunctorsTask(int delayMs) {
+    if (mInvokeFunctorsPending) return;
+
+    mInvokeFunctorsPending = true;
+    mRenderThread.queueDelayed(&mInvokeFunctorsTask, delayMs);
+}
+
+bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+    requireGlContext();
+    layer->apply();
+    return LayerRenderer::copyLayer(layer->backingLayer(), bitmap);
+}
+
+void CanvasContext::runWithGlContext(RenderTask* task) {
+    requireGlContext();
+    task->run();
+}
+
+void CanvasContext::requireGlContext() {
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mGlobalContext->makeCurrent(mEglSurface);
+    } else {
+        mGlobalContext->usePBufferSurface();
+    }
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
new file mode 100644
index 0000000..e3fdf97
--- /dev/null
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CANVASCONTEXT_H_
+#define CANVASCONTEXT_H_
+
+#include <cutils/compiler.h>
+#include <EGL/egl.h>
+#include <SkBitmap.h>
+#include <utils/Functor.h>
+#include <utils/Vector.h>
+
+#include "RenderTask.h"
+
+#define FUNCTOR_PROCESS_DELAY 4
+
+namespace android {
+namespace uirenderer {
+
+class DeferredLayerUpdater;
+class RenderNode;
+class DisplayListData;
+class OpenGLRenderer;
+class Rect;
+
+namespace renderthread {
+
+class GlobalContext;
+class CanvasContext;
+class RenderThread;
+
+class InvokeFunctorsTask : public RenderTask {
+public:
+    InvokeFunctorsTask(CanvasContext* context)
+        : mContext(context) {}
+
+    virtual void run();
+
+private:
+    CanvasContext* mContext;
+};
+
+// This per-renderer class manages the bridge between the global EGL context
+// and the render surface.
+class CanvasContext {
+public:
+    CanvasContext(bool translucent);
+    ~CanvasContext();
+
+    bool initialize(EGLNativeWindowType window);
+    void updateSurface(EGLNativeWindowType window);
+    void setup(int width, int height);
+    void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
+    void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters);
+    void drawDisplayList(RenderNode* displayList, Rect* dirty);
+    void destroyCanvas();
+
+    bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
+
+    void attachFunctor(Functor* functor);
+    void detachFunctor(Functor* functor);
+
+    void runWithGlContext(RenderTask* task);
+
+private:
+    void setSurface(EGLNativeWindowType window);
+    void swapBuffers();
+    void makeCurrent();
+
+    friend class InvokeFunctorsTask;
+    void invokeFunctors();
+    void handleFunctorStatus(int status, const Rect& redrawClip);
+    void removeFunctorsTask();
+    void queueFunctorsTask(int delayMs = FUNCTOR_PROCESS_DELAY);
+
+    void requireGlContext();
+
+    GlobalContext* mGlobalContext;
+    RenderThread& mRenderThread;
+    EGLSurface mEglSurface;
+    bool mDirtyRegionsEnabled;
+
+    bool mOpaque;
+    OpenGLRenderer* mCanvas;
+    bool mHaveNewSurface;
+
+    bool mInvokeFunctorsPending;
+    InvokeFunctorsTask mInvokeFunctorsTask;
+
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+#endif /* CANVASCONTEXT_H_ */
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
new file mode 100644
index 0000000..93360fc
--- /dev/null
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -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.
+ */
+
+#define LOG_TAG "RenderProxy"
+
+#include "RenderProxy.h"
+
+#include "CanvasContext.h"
+#include "RenderTask.h"
+#include "RenderThread.h"
+
+#include "../DeferredLayerUpdater.h"
+#include "../DisplayList.h"
+#include "../LayerRenderer.h"
+#include "../Rect.h"
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+#define ARGS(method) method ## Args
+
+#define CREATE_BRIDGE0(name) CREATE_BRIDGE(name,,,,,,,,)
+#define CREATE_BRIDGE1(name, a1) CREATE_BRIDGE(name, a1,,,,,,,)
+#define CREATE_BRIDGE2(name, a1, a2) CREATE_BRIDGE(name, a1,a2,,,,,,)
+#define CREATE_BRIDGE3(name, a1, a2, a3) CREATE_BRIDGE(name, a1,a2,a3,,,,,)
+#define CREATE_BRIDGE4(name, a1, a2, a3, a4) CREATE_BRIDGE(name, a1,a2,a3,a4,,,,)
+#define CREATE_BRIDGE(name, a1, a2, a3, a4, a5, a6, a7, a8) \
+    typedef struct { \
+        a1; a2; a3; a4; a5; a6; a7; a8; \
+    } ARGS(name); \
+    static void* Bridge_ ## name(ARGS(name)* args)
+
+#define SETUP_TASK(method) \
+    LOG_ALWAYS_FATAL_IF( METHOD_INVOKE_PAYLOAD_SIZE < sizeof(ARGS(method)), \
+        "METHOD_INVOKE_PAYLOAD_SIZE %d is smaller than sizeof(" #method "Args) %d", \
+                METHOD_INVOKE_PAYLOAD_SIZE, sizeof(ARGS(method))); \
+    MethodInvokeRenderTask* task = createTask((RunnableMethod) Bridge_ ## method); \
+    ARGS(method) *args = (ARGS(method) *) task->payload()
+
+CREATE_BRIDGE1(createContext, bool translucent) {
+    return new CanvasContext(args->translucent);
+}
+
+RenderProxy::RenderProxy(bool translucent)
+        : mRenderThread(RenderThread::getInstance())
+        , mContext(0) {
+    SETUP_TASK(createContext);
+    args->translucent = translucent;
+    mContext = (CanvasContext*) postAndWait(task);
+}
+
+RenderProxy::~RenderProxy() {
+    destroyContext();
+}
+
+CREATE_BRIDGE1(destroyContext, CanvasContext* context) {
+    delete args->context;
+    return NULL;
+}
+
+void RenderProxy::destroyContext() {
+    if (mContext) {
+        SETUP_TASK(destroyContext);
+        args->context = mContext;
+        mContext = 0;
+        post(task);
+    }
+}
+
+CREATE_BRIDGE2(initialize, CanvasContext* context, EGLNativeWindowType window) {
+    return (void*) args->context->initialize(args->window);
+}
+
+bool RenderProxy::initialize(EGLNativeWindowType window) {
+    SETUP_TASK(initialize);
+    args->context = mContext;
+    args->window = window;
+    return (bool) postAndWait(task);
+}
+
+CREATE_BRIDGE2(updateSurface, CanvasContext* context, EGLNativeWindowType window) {
+    args->context->updateSurface(args->window);
+    return NULL;
+}
+
+void RenderProxy::updateSurface(EGLNativeWindowType window) {
+    SETUP_TASK(updateSurface);
+    args->context = mContext;
+    args->window = window;
+    post(task);
+}
+
+CREATE_BRIDGE3(setup, CanvasContext* context, int width, int height) {
+    args->context->setup(args->width, args->height);
+    return NULL;
+}
+
+void RenderProxy::setup(int width, int height) {
+    SETUP_TASK(setup);
+    args->context = mContext;
+    args->width = width;
+    args->height = height;
+    post(task);
+}
+
+CREATE_BRIDGE3(setDisplayListData, CanvasContext* context, RenderNode* displayList,
+        DisplayListData* newData) {
+    args->context->setDisplayListData(args->displayList, args->newData);
+    return NULL;
+}
+
+void RenderProxy::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
+    SETUP_TASK(setDisplayListData);
+    args->context = mContext;
+    args->displayList = displayList;
+    args->newData = newData;
+    post(task);
+}
+
+CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, RenderNode* displayList,
+        Rect dirty, const Vector<DeferredLayerUpdater*>* layerUpdates) {
+    Rect* dirty = &args->dirty;
+    if (dirty->bottom == -1 && dirty->left == -1 &&
+            dirty->top == -1 && dirty->right == -1) {
+        dirty = 0;
+    }
+    args->context->processLayerUpdates(args->layerUpdates);
+    args->context->drawDisplayList(args->displayList, dirty);
+    return NULL;
+}
+
+void RenderProxy::drawDisplayList(RenderNode* displayList,
+        int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom) {
+    SETUP_TASK(drawDisplayList);
+    args->context = mContext;
+    args->displayList = displayList;
+    args->dirty.set(dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
+    args->layerUpdates = &mLayers;
+    // TODO: Switch to post() once some form of thread safety strategy is in place
+    postAndWait(task);
+}
+
+CREATE_BRIDGE1(destroyCanvas, CanvasContext* context) {
+    args->context->destroyCanvas();
+    return NULL;
+}
+
+void RenderProxy::destroyCanvas() {
+    SETUP_TASK(destroyCanvas);
+    args->context = mContext;
+    post(task);
+}
+
+CREATE_BRIDGE2(attachFunctor, CanvasContext* context, Functor* functor) {
+    args->context->attachFunctor(args->functor);
+    return NULL;
+}
+
+void RenderProxy::attachFunctor(Functor* functor) {
+    SETUP_TASK(attachFunctor);
+    args->context = mContext;
+    args->functor = functor;
+    post(task);
+}
+
+CREATE_BRIDGE2(detachFunctor, CanvasContext* context, Functor* functor) {
+    args->context->detachFunctor(args->functor);
+    return NULL;
+}
+
+void RenderProxy::detachFunctor(Functor* functor) {
+    SETUP_TASK(detachFunctor);
+    args->context = mContext;
+    args->functor = functor;
+    post(task);
+}
+
+CREATE_BRIDGE2(runWithGlContext, CanvasContext* context, RenderTask* task) {
+    args->context->runWithGlContext(args->task);
+    return NULL;
+}
+
+void RenderProxy::runWithGlContext(RenderTask* gltask) {
+    SETUP_TASK(runWithGlContext);
+    args->context = mContext;
+    args->task = gltask;
+    postAndWait(task);
+}
+
+CREATE_BRIDGE2(createDisplayListLayer, int width, int height) {
+    Layer* layer = LayerRenderer::createRenderLayer(args->width, args->height);
+    if (!layer) return 0;
+
+    OpenGLRenderer* renderer = new LayerRenderer(layer);
+    renderer->initProperties();
+    return new DeferredLayerUpdater(layer, renderer);
+}
+
+DeferredLayerUpdater* RenderProxy::createDisplayListLayer(int width, int height) {
+    SETUP_TASK(createDisplayListLayer);
+    args->width = width;
+    args->height = height;
+    void* retval = postAndWait(task);
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
+    mLayers.push(layer);
+    return layer;
+}
+
+CREATE_BRIDGE0(createTextureLayer) {
+    Layer* layer = LayerRenderer::createTextureLayer();
+    if (!layer) return 0;
+    return new DeferredLayerUpdater(layer);
+}
+
+DeferredLayerUpdater* RenderProxy::createTextureLayer() {
+    SETUP_TASK(createTextureLayer);
+    void* retval = postAndWait(task);
+    DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
+    mLayers.push(layer);
+    return layer;
+}
+
+CREATE_BRIDGE1(destroyLayer, Layer* layer) {
+    LayerRenderer::destroyLayer(args->layer);
+    return NULL;
+}
+
+CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer,
+        SkBitmap* bitmap) {
+    bool success = args->context->copyLayerInto(args->layer, args->bitmap);
+    return (void*) success;
+}
+
+bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
+    SETUP_TASK(copyLayerInto);
+    args->context = mContext;
+    args->layer = layer;
+    args->bitmap = bitmap;
+    return (bool) postAndWait(task);
+}
+
+void RenderProxy::destroyLayer(DeferredLayerUpdater* layer) {
+    for (size_t i = 0; i < mLayers.size(); i++) {
+        if (mLayers[i] == layer) {
+            mLayers.removeAt(i);
+            break;
+        }
+    }
+    SETUP_TASK(destroyLayer);
+    args->layer = layer->detachBackingLayer();
+    post(task);
+}
+
+MethodInvokeRenderTask* RenderProxy::createTask(RunnableMethod method) {
+    // TODO: Consider having a small pool of these to avoid alloc churn
+    return new MethodInvokeRenderTask(method);
+}
+
+void RenderProxy::post(RenderTask* task) {
+    mRenderThread.queue(task);
+}
+
+void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
+    void* retval;
+    task->setReturnPtr(&retval);
+    SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
+    AutoMutex _lock(mSyncMutex);
+    mRenderThread.queue(&syncTask);
+    mSyncCondition.wait(mSyncMutex);
+    return retval;
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
new file mode 100644
index 0000000..73e9805
--- /dev/null
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -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.
+ */
+
+#ifndef RENDERPROXY_H_
+#define RENDERPROXY_H_
+
+#include "RenderTask.h"
+
+#include <cutils/compiler.h>
+#include <EGL/egl.h>
+#include <SkBitmap.h>
+#include <utils/Condition.h>
+#include <utils/Functor.h>
+#include <utils/Mutex.h>
+#include <utils/StrongPointer.h>
+#include <utils/Vector.h>
+
+namespace android {
+namespace uirenderer {
+
+class DeferredLayerUpdater;
+class RenderNode;
+class DisplayListData;
+class Layer;
+class Rect;
+
+namespace renderthread {
+
+class CanvasContext;
+class ErrorChannel;
+class RenderThread;
+class RenderProxyBridge;
+
+/*
+ * RenderProxy is strictly single threaded. All methods must be invoked on the owning
+ * thread. It is important to note that RenderProxy may be deleted while it has
+ * tasks post()'d as a result. Therefore any RenderTask that is post()'d must not
+ * reference RenderProxy or any of its fields. The exception here is that postAndWait()
+ * references RenderProxy fields. This is safe as RenderProxy cannot
+ * be deleted if it is blocked inside a call.
+ */
+class ANDROID_API RenderProxy {
+public:
+    ANDROID_API RenderProxy(bool translucent);
+    ANDROID_API virtual ~RenderProxy();
+
+    ANDROID_API bool initialize(EGLNativeWindowType window);
+    ANDROID_API void updateSurface(EGLNativeWindowType window);
+    ANDROID_API void setup(int width, int height);
+    ANDROID_API void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
+    ANDROID_API void drawDisplayList(RenderNode* displayList,
+            int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
+    ANDROID_API void destroyCanvas();
+
+    ANDROID_API void attachFunctor(Functor* functor);
+    ANDROID_API void detachFunctor(Functor* functor);
+
+    ANDROID_API void runWithGlContext(RenderTask* task);
+
+    ANDROID_API DeferredLayerUpdater* createDisplayListLayer(int width, int height);
+    ANDROID_API DeferredLayerUpdater* createTextureLayer();
+    ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
+    ANDROID_API void destroyLayer(DeferredLayerUpdater* layer);
+
+private:
+    RenderThread& mRenderThread;
+    CanvasContext* mContext;
+
+    Mutex mSyncMutex;
+    Condition mSyncCondition;
+
+    Vector<DeferredLayerUpdater*> mLayers;
+
+    void destroyContext();
+
+    MethodInvokeRenderTask* createTask(RunnableMethod method);
+    void post(RenderTask* task);
+    void* postAndWait(MethodInvokeRenderTask* task);
+
+    // Friend class to help with bridging
+    friend class RenderProxyBridge;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+#endif /* RENDERPROXY_H_ */
diff --git a/libs/hwui/renderthread/RenderTask.cpp b/libs/hwui/renderthread/RenderTask.cpp
new file mode 100644
index 0000000..7ca61e4
--- /dev/null
+++ b/libs/hwui/renderthread/RenderTask.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 "RenderTask"
+
+#include "RenderTask.h"
+
+#include <utils/Log.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+void SignalingRenderTask::run() {
+    mTask->run();
+    mLock->lock();
+    mSignal->signal();
+    mLock->unlock();
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderTask.h b/libs/hwui/renderthread/RenderTask.h
new file mode 100644
index 0000000..1554a16
--- /dev/null
+++ b/libs/hwui/renderthread/RenderTask.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 RENDERTASK_H_
+#define RENDERTASK_H_
+
+#include <cutils/compiler.h>
+#include <utils/Timers.h>
+
+namespace android {
+class Mutex;
+class Condition;
+namespace uirenderer {
+namespace renderthread {
+
+#define METHOD_INVOKE_PAYLOAD_SIZE (8 * sizeof(void*))
+
+/*
+ * Notes about memory management
+ *
+ * RenderThread will only invoke RenderTask::run(). It is the responsibility
+ * of the RenderTask to know if it needs to suicide at the end of run() or
+ * if some other lifecycle is being used. As such, it is not valid to reference
+ * anything on RenderTask after the first call to run().
+ *
+ * For example SignalingRenderTask
+ * is expected to be stack allocated by the calling thread, so it does not
+ * suicide in run() but instead relies on the caller to destroy it.
+ *
+ * MethodInvokeRenderTask however is currently allocated with new, so it will
+ * suicide at the end of run(). TODO: Replace this with a small pool to avoid
+ * malloc/free churn of small objects?
+ */
+
+class ANDROID_API RenderTask {
+public:
+    ANDROID_API RenderTask() : mNext(0), mRunAt(0) {}
+    ANDROID_API virtual ~RenderTask() {}
+
+    ANDROID_API virtual void run() = 0;
+
+    RenderTask* mNext;
+    nsecs_t mRunAt; // nano-seconds on the SYSTEM_TIME_MONOTONIC clock
+};
+
+class SignalingRenderTask : public RenderTask {
+public:
+    // Takes ownership of task, caller owns lock and signal
+    SignalingRenderTask(RenderTask* task, Mutex* lock, Condition* signal)
+            : mTask(task), mLock(lock), mSignal(signal) {}
+    virtual void run();
+
+private:
+    RenderTask* mTask;
+    Mutex* mLock;
+    Condition* mSignal;
+};
+
+typedef void* (*RunnableMethod)(void* data);
+
+class MethodInvokeRenderTask : public RenderTask {
+public:
+    MethodInvokeRenderTask(RunnableMethod method)
+        : mMethod(method), mReturnPtr(0) {}
+
+    void* payload() { return mData; }
+    void setReturnPtr(void** retptr) { mReturnPtr = retptr; }
+
+    virtual void run() {
+        void* retval = mMethod(mData);
+        if (mReturnPtr) {
+            *mReturnPtr = retval;
+        }
+        // Commit suicide
+        delete this;
+    }
+private:
+    RunnableMethod mMethod;
+    char mData[METHOD_INVOKE_PAYLOAD_SIZE];
+    void** mReturnPtr;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+#endif /* RENDERTASK_H_ */
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
new file mode 100644
index 0000000..212f475
--- /dev/null
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "RenderThread"
+
+#include "RenderThread.h"
+
+#include "CanvasContext.h"
+#include "RenderProxy.h"
+#include <utils/Log.h>
+
+namespace android {
+using namespace uirenderer::renderthread;
+ANDROID_SINGLETON_STATIC_INSTANCE(RenderThread);
+
+namespace uirenderer {
+namespace renderthread {
+
+TaskQueue::TaskQueue() : mHead(0), mTail(0) {}
+
+RenderTask* TaskQueue::next() {
+    RenderTask* ret = mHead;
+    if (ret) {
+        mHead = ret->mNext;
+        if (!mHead) {
+            mTail = 0;
+        }
+        ret->mNext = 0;
+    }
+    return ret;
+}
+
+RenderTask* TaskQueue::peek() {
+    return mHead;
+}
+
+void TaskQueue::queue(RenderTask* task) {
+    // Since the RenderTask itself forms the linked list it is not allowed
+    // to have the same task queued twice
+    LOG_ALWAYS_FATAL_IF(task->mNext || mTail == task, "Task is already in the queue!");
+    if (mTail) {
+        // Fast path if we can just append
+        if (mTail->mRunAt <= task->mRunAt) {
+            mTail->mNext = task;
+            mTail = task;
+        } else {
+            // Need to find the proper insertion point
+            RenderTask* previous = 0;
+            RenderTask* next = mHead;
+            while (next && next->mRunAt <= task->mRunAt) {
+                previous = next;
+                next = next->mNext;
+            }
+            if (!previous) {
+                task->mNext = mHead;
+                mHead = task;
+            } else {
+                previous->mNext = task;
+                if (next) {
+                    task->mNext = next;
+                } else {
+                    mTail = task;
+                }
+            }
+        }
+    } else {
+        mTail = mHead = task;
+    }
+}
+
+void TaskQueue::remove(RenderTask* task) {
+    // TaskQueue is strict here to enforce that users are keeping track of
+    // their RenderTasks due to how their memory is managed
+    LOG_ALWAYS_FATAL_IF(!task->mNext && mTail != task,
+            "Cannot remove a task that isn't in the queue!");
+
+    // If task is the head we can just call next() to pop it off
+    // Otherwise we need to scan through to find the task before it
+    if (peek() == task) {
+        next();
+    } else {
+        RenderTask* previous = mHead;
+        while (previous->mNext != task) {
+            previous = previous->mNext;
+        }
+        previous->mNext = task->mNext;
+        if (mTail == task) {
+            mTail = previous;
+        }
+    }
+}
+
+RenderThread::RenderThread() : Thread(true), Singleton<RenderThread>()
+        , mNextWakeup(LLONG_MAX) {
+    mLooper = new Looper(false);
+    run("RenderThread");
+}
+
+RenderThread::~RenderThread() {
+}
+
+bool RenderThread::threadLoop() {
+    int timeoutMillis = -1;
+    for (;;) {
+        int result = mLooper->pollAll(timeoutMillis);
+        LOG_ALWAYS_FATAL_IF(result == Looper::POLL_ERROR,
+                "RenderThread Looper POLL_ERROR!");
+
+        nsecs_t nextWakeup;
+        // Process our queue, if we have anything
+        while (RenderTask* task = nextTask(&nextWakeup)) {
+            task->run();
+            // task may have deleted itself, do not reference it again
+        }
+        if (nextWakeup == LLONG_MAX) {
+            timeoutMillis = -1;
+        } else {
+            nsecs_t timeoutNanos = nextWakeup - systemTime(SYSTEM_TIME_MONOTONIC);
+            timeoutMillis = nanoseconds_to_milliseconds(timeoutNanos);
+            if (timeoutMillis < 0) {
+                timeoutMillis = 0;
+            }
+        }
+    }
+
+    return false;
+}
+
+void RenderThread::queue(RenderTask* task) {
+    AutoMutex _lock(mLock);
+    mQueue.queue(task);
+    if (mNextWakeup && task->mRunAt < mNextWakeup) {
+        mNextWakeup = 0;
+        mLooper->wake();
+    }
+}
+
+void RenderThread::queueDelayed(RenderTask* task, int delayMs) {
+    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+    task->mRunAt = now + milliseconds_to_nanoseconds(delayMs);
+    queue(task);
+}
+
+void RenderThread::remove(RenderTask* task) {
+    AutoMutex _lock(mLock);
+    mQueue.remove(task);
+}
+
+RenderTask* RenderThread::nextTask(nsecs_t* nextWakeup) {
+    AutoMutex _lock(mLock);
+    RenderTask* next = mQueue.peek();
+    if (!next) {
+        mNextWakeup = LLONG_MAX;
+    } else {
+        // Most tasks won't be delayed, so avoid unnecessary systemTime() calls
+        if (next->mRunAt <= 0 || next->mRunAt <= systemTime(SYSTEM_TIME_MONOTONIC)) {
+            next = mQueue.next();
+        }
+        mNextWakeup = next->mRunAt;
+    }
+    if (nextWakeup) {
+        *nextWakeup = mNextWakeup;
+    }
+    return next;
+}
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
new file mode 100644
index 0000000..e444aa0
--- /dev/null
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -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.
+ */
+
+#ifndef RENDERTHREAD_H_
+#define RENDERTHREAD_H_
+
+#include "RenderTask.h"
+#include <cutils/compiler.h>
+#include <utils/Looper.h>
+#include <utils/Mutex.h>
+#include <utils/Singleton.h>
+#include <utils/Thread.h>
+
+namespace android {
+namespace uirenderer {
+namespace renderthread {
+
+class TaskQueue {
+public:
+    TaskQueue();
+
+    RenderTask* next();
+    void queue(RenderTask* task);
+    RenderTask* peek();
+    void remove(RenderTask* task);
+
+private:
+    RenderTask* mHead;
+    RenderTask* mTail;
+};
+
+class ANDROID_API RenderThread : public Thread, public Singleton<RenderThread> {
+public:
+    // RenderThread takes complete ownership of tasks that are queued
+    // and will delete them after they are run
+    ANDROID_API void queue(RenderTask* task);
+    void queueDelayed(RenderTask* task, int delayMs);
+    void remove(RenderTask* task);
+
+protected:
+    virtual bool threadLoop();
+
+private:
+    friend class Singleton<RenderThread>;
+
+    RenderThread();
+    virtual ~RenderThread();
+
+    // Returns the next task to be run. If this returns NULL nextWakeup is set
+    // to the time to requery for the nextTask to run. mNextWakeup is also
+    // set to this time
+    RenderTask* nextTask(nsecs_t* nextWakeup);
+
+    sp<Looper> mLooper;
+    Mutex mLock;
+
+    nsecs_t mNextWakeup;
+    TaskQueue mQueue;
+};
+
+} /* namespace renderthread */
+} /* namespace uirenderer */
+} /* namespace android */
+#endif /* RENDERTHREAD_H_ */
diff --git a/libs/input/Android.mk b/libs/input/Android.mk
index 6e944ef..a7fb0e2 100644
--- a/libs/input/Android.mk
+++ b/libs/input/Android.mk
@@ -17,30 +17,24 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    EventHub.cpp \
-    InputApplication.cpp \
-    InputDispatcher.cpp \
-    InputListener.cpp \
-    InputManager.cpp \
-    InputReader.cpp \
-    InputWindow.cpp \
     PointerController.cpp \
     SpriteController.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     liblog \
-    libandroidfw \
     libutils \
-    libhardware \
-    libhardware_legacy \
     libskia \
     libgui \
     libui \
-    libinput
+	libinput \
+	libinputflinger
 
 LOCAL_C_INCLUDES := \
-    external/skia/include/core
+    frameworks/native/services
+
+
+LOCAL_CFLAGS += -Wno-unused-parameter
 
 LOCAL_MODULE:= libinputservice
 
diff --git a/libs/input/EventHub.cpp b/libs/input/EventHub.cpp
deleted file mode 100644
index fc324f8..0000000
--- a/libs/input/EventHub.cpp
+++ /dev/null
@@ -1,1679 +0,0 @@
-/*
- * 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 "EventHub"
-
-// #define LOG_NDEBUG 0
-
-#include "EventHub.h"
-
-#include <hardware_legacy/power.h>
-
-#include <cutils/properties.h>
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <utils/threads.h>
-#include <utils/Errors.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <input/KeyLayoutMap.h>
-#include <input/KeyCharacterMap.h>
-#include <input/VirtualKeyMap.h>
-
-#include <string.h>
-#include <stdint.h>
-#include <dirent.h>
-
-#include <sys/inotify.h>
-#include <sys/epoll.h>
-#include <sys/ioctl.h>
-#include <sys/limits.h>
-#include <sys/sha1.h>
-
-/* this macro is used to tell if "bit" is set in "array"
- * it selects a byte from the array, and does a boolean AND
- * operation with a byte that only has the relevant bit set.
- * eg. to check for the 12th bit, we do (array[1] & 1<<4)
- */
-#define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
-
-/* this macro computes the number of bytes needed to represent a bit array of the specified size */
-#define sizeof_bit_array(bits)  ((bits + 7) / 8)
-
-#define INDENT "  "
-#define INDENT2 "    "
-#define INDENT3 "      "
-
-namespace android {
-
-static const char *WAKE_LOCK_ID = "KeyEvents";
-static const char *DEVICE_PATH = "/dev/input";
-
-/* return the larger integer */
-static inline int max(int v1, int v2)
-{
-    return (v1 > v2) ? v1 : v2;
-}
-
-static inline const char* toString(bool value) {
-    return value ? "true" : "false";
-}
-
-static String8 sha1(const String8& in) {
-    SHA1_CTX ctx;
-    SHA1Init(&ctx);
-    SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size());
-    u_char digest[SHA1_DIGEST_LENGTH];
-    SHA1Final(digest, &ctx);
-
-    String8 out;
-    for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) {
-        out.appendFormat("%02x", digest[i]);
-    }
-    return out;
-}
-
-static void setDescriptor(InputDeviceIdentifier& identifier) {
-    // Compute a device descriptor that uniquely identifies the device.
-    // The descriptor is assumed to be a stable identifier.  Its value should not
-    // change between reboots, reconnections, firmware updates or new releases of Android.
-    // Ideally, we also want the descriptor to be short and relatively opaque.
-    String8 rawDescriptor;
-    rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product);
-    if (!identifier.uniqueId.isEmpty()) {
-        rawDescriptor.append("uniqueId:");
-        rawDescriptor.append(identifier.uniqueId);
-    } if (identifier.vendor == 0 && identifier.product == 0) {
-        // If we don't know the vendor and product id, then the device is probably
-        // built-in so we need to rely on other information to uniquely identify
-        // the input device.  Usually we try to avoid relying on the device name or
-        // location but for built-in input device, they are unlikely to ever change.
-        if (!identifier.name.isEmpty()) {
-            rawDescriptor.append("name:");
-            rawDescriptor.append(identifier.name);
-        } else if (!identifier.location.isEmpty()) {
-            rawDescriptor.append("location:");
-            rawDescriptor.append(identifier.location);
-        }
-    }
-    identifier.descriptor = sha1(rawDescriptor);
-    ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(),
-            identifier.descriptor.string());
-}
-
-// --- Global Functions ---
-
-uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) {
-    // Touch devices get dibs on touch-related axes.
-    if (deviceClasses & INPUT_DEVICE_CLASS_TOUCH) {
-        switch (axis) {
-        case ABS_X:
-        case ABS_Y:
-        case ABS_PRESSURE:
-        case ABS_TOOL_WIDTH:
-        case ABS_DISTANCE:
-        case ABS_TILT_X:
-        case ABS_TILT_Y:
-        case ABS_MT_SLOT:
-        case ABS_MT_TOUCH_MAJOR:
-        case ABS_MT_TOUCH_MINOR:
-        case ABS_MT_WIDTH_MAJOR:
-        case ABS_MT_WIDTH_MINOR:
-        case ABS_MT_ORIENTATION:
-        case ABS_MT_POSITION_X:
-        case ABS_MT_POSITION_Y:
-        case ABS_MT_TOOL_TYPE:
-        case ABS_MT_BLOB_ID:
-        case ABS_MT_TRACKING_ID:
-        case ABS_MT_PRESSURE:
-        case ABS_MT_DISTANCE:
-            return INPUT_DEVICE_CLASS_TOUCH;
-        }
-    }
-
-    // Joystick devices get the rest.
-    return deviceClasses & INPUT_DEVICE_CLASS_JOYSTICK;
-}
-
-// --- EventHub::Device ---
-
-EventHub::Device::Device(int fd, int32_t id, const String8& path,
-        const InputDeviceIdentifier& identifier) :
-        next(NULL),
-        fd(fd), id(id), path(path), identifier(identifier),
-        classes(0), configuration(NULL), virtualKeyMap(NULL),
-        ffEffectPlaying(false), ffEffectId(-1), controllerNumber(0),
-        timestampOverrideSec(0), timestampOverrideUsec(0) {
-    memset(keyBitmask, 0, sizeof(keyBitmask));
-    memset(absBitmask, 0, sizeof(absBitmask));
-    memset(relBitmask, 0, sizeof(relBitmask));
-    memset(swBitmask, 0, sizeof(swBitmask));
-    memset(ledBitmask, 0, sizeof(ledBitmask));
-    memset(ffBitmask, 0, sizeof(ffBitmask));
-    memset(propBitmask, 0, sizeof(propBitmask));
-}
-
-EventHub::Device::~Device() {
-    close();
-    delete configuration;
-    delete virtualKeyMap;
-}
-
-void EventHub::Device::close() {
-    if (fd >= 0) {
-        ::close(fd);
-        fd = -1;
-    }
-}
-
-
-// --- EventHub ---
-
-const uint32_t EventHub::EPOLL_ID_INOTIFY;
-const uint32_t EventHub::EPOLL_ID_WAKE;
-const int EventHub::EPOLL_SIZE_HINT;
-const int EventHub::EPOLL_MAX_EVENTS;
-
-EventHub::EventHub(void) :
-        mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD), mNextDeviceId(1), mControllerNumbers(),
-        mOpeningDevices(0), mClosingDevices(0),
-        mNeedToSendFinishedDeviceScan(false),
-        mNeedToReopenDevices(false), mNeedToScanDevices(true),
-        mPendingEventCount(0), mPendingEventIndex(0), mPendingINotify(false) {
-    acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-
-    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
-    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
-
-    mINotifyFd = inotify_init();
-    int result = inotify_add_watch(mINotifyFd, DEVICE_PATH, IN_DELETE | IN_CREATE);
-    LOG_ALWAYS_FATAL_IF(result < 0, "Could not register INotify for %s.  errno=%d",
-            DEVICE_PATH, errno);
-
-    struct epoll_event eventItem;
-    memset(&eventItem, 0, sizeof(eventItem));
-    eventItem.events = EPOLLIN;
-    eventItem.data.u32 = EPOLL_ID_INOTIFY;
-    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add INotify to epoll instance.  errno=%d", errno);
-
-    int wakeFds[2];
-    result = pipe(wakeFds);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
-
-    mWakeReadPipeFd = wakeFds[0];
-    mWakeWritePipeFd = wakeFds[1];
-
-    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
-            errno);
-
-    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
-            errno);
-
-    eventItem.data.u32 = EPOLL_ID_WAKE;
-    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
-    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
-            errno);
-}
-
-EventHub::~EventHub(void) {
-    closeAllDevicesLocked();
-
-    while (mClosingDevices) {
-        Device* device = mClosingDevices;
-        mClosingDevices = device->next;
-        delete device;
-    }
-
-    ::close(mEpollFd);
-    ::close(mINotifyFd);
-    ::close(mWakeReadPipeFd);
-    ::close(mWakeWritePipeFd);
-
-    release_wake_lock(WAKE_LOCK_ID);
-}
-
-InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device == NULL) return InputDeviceIdentifier();
-    return device->identifier;
-}
-
-uint32_t EventHub::getDeviceClasses(int32_t deviceId) const {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device == NULL) return 0;
-    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);
-    if (device && device->configuration) {
-        *outConfiguration = *device->configuration;
-    } else {
-        outConfiguration->clear();
-    }
-}
-
-status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
-        RawAbsoluteAxisInfo* outAxisInfo) const {
-    outAxisInfo->clear();
-
-    if (axis >= 0 && axis <= ABS_MAX) {
-        AutoMutex _l(mLock);
-
-        Device* device = getDeviceLocked(deviceId);
-        if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
-            struct input_absinfo info;
-            if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
-                ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
-                     axis, device->identifier.name.string(), device->fd, errno);
-                return -errno;
-            }
-
-            if (info.minimum != info.maximum) {
-                outAxisInfo->valid = true;
-                outAxisInfo->minValue = info.minimum;
-                outAxisInfo->maxValue = info.maximum;
-                outAxisInfo->flat = info.flat;
-                outAxisInfo->fuzz = info.fuzz;
-                outAxisInfo->resolution = info.resolution;
-            }
-            return OK;
-        }
-    }
-    return -1;
-}
-
-bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const {
-    if (axis >= 0 && axis <= REL_MAX) {
-        AutoMutex _l(mLock);
-
-        Device* device = getDeviceLocked(deviceId);
-        if (device) {
-            return test_bit(axis, device->relBitmask);
-        }
-    }
-    return false;
-}
-
-bool EventHub::hasInputProperty(int32_t deviceId, int property) const {
-    if (property >= 0 && property <= INPUT_PROP_MAX) {
-        AutoMutex _l(mLock);
-
-        Device* device = getDeviceLocked(deviceId);
-        if (device) {
-            return test_bit(property, device->propBitmask);
-        }
-    }
-    return false;
-}
-
-int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
-    if (scanCode >= 0 && scanCode <= KEY_MAX) {
-        AutoMutex _l(mLock);
-
-        Device* device = getDeviceLocked(deviceId);
-        if (device && !device->isVirtual() && test_bit(scanCode, device->keyBitmask)) {
-            uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
-            memset(keyState, 0, sizeof(keyState));
-            if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
-                return test_bit(scanCode, keyState) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
-            }
-        }
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
-    AutoMutex _l(mLock);
-
-    Device* device = getDeviceLocked(deviceId);
-    if (device && !device->isVirtual() && device->keyMap.haveKeyLayout()) {
-        Vector<int32_t> scanCodes;
-        device->keyMap.keyLayoutMap->findScanCodesForKey(keyCode, &scanCodes);
-        if (scanCodes.size() != 0) {
-            uint8_t keyState[sizeof_bit_array(KEY_MAX + 1)];
-            memset(keyState, 0, sizeof(keyState));
-            if (ioctl(device->fd, EVIOCGKEY(sizeof(keyState)), keyState) >= 0) {
-                for (size_t i = 0; i < scanCodes.size(); i++) {
-                    int32_t sc = scanCodes.itemAt(i);
-                    if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, keyState)) {
-                        return AKEY_STATE_DOWN;
-                    }
-                }
-                return AKEY_STATE_UP;
-            }
-        }
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
-    if (sw >= 0 && sw <= SW_MAX) {
-        AutoMutex _l(mLock);
-
-        Device* device = getDeviceLocked(deviceId);
-        if (device && !device->isVirtual() && test_bit(sw, device->swBitmask)) {
-            uint8_t swState[sizeof_bit_array(SW_MAX + 1)];
-            memset(swState, 0, sizeof(swState));
-            if (ioctl(device->fd, EVIOCGSW(sizeof(swState)), swState) >= 0) {
-                return test_bit(sw, swState) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
-            }
-        }
-    }
-    return AKEY_STATE_UNKNOWN;
-}
-
-status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const {
-    *outValue = 0;
-
-    if (axis >= 0 && axis <= ABS_MAX) {
-        AutoMutex _l(mLock);
-
-        Device* device = getDeviceLocked(deviceId);
-        if (device && !device->isVirtual() && test_bit(axis, device->absBitmask)) {
-            struct input_absinfo info;
-            if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
-                ALOGW("Error reading absolute controller %d for device %s fd %d, errno=%d",
-                     axis, device->identifier.name.string(), device->fd, errno);
-                return -errno;
-            }
-
-            *outValue = info.value;
-            return OK;
-        }
-    }
-    return -1;
-}
-
-bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) const {
-    AutoMutex _l(mLock);
-
-    Device* device = getDeviceLocked(deviceId);
-    if (device && device->keyMap.haveKeyLayout()) {
-        Vector<int32_t> scanCodes;
-        for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
-            scanCodes.clear();
-
-            status_t err = device->keyMap.keyLayoutMap->findScanCodesForKey(
-                    keyCodes[codeIndex], &scanCodes);
-            if (! err) {
-                // check the possible scan codes identified by the layout map against the
-                // map of codes actually emitted by the driver
-                for (size_t sc = 0; sc < scanCodes.size(); sc++) {
-                    if (test_bit(scanCodes[sc], device->keyBitmask)) {
-                        outFlags[codeIndex] = 1;
-                        break;
-                    }
-                }
-            }
-        }
-        return true;
-    }
-    return false;
-}
-
-status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
-        int32_t* outKeycode, uint32_t* outFlags) const {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-
-    if (device) {
-        // Check the key character map first.
-        sp<KeyCharacterMap> kcm = device->getKeyCharacterMap();
-        if (kcm != NULL) {
-            if (!kcm->mapKey(scanCode, usageCode, outKeycode)) {
-                *outFlags = 0;
-                return NO_ERROR;
-            }
-        }
-
-        // Check the key layout next.
-        if (device->keyMap.haveKeyLayout()) {
-            if (!device->keyMap.keyLayoutMap->mapKey(
-                    scanCode, usageCode, outKeycode, outFlags)) {
-                return NO_ERROR;
-            }
-        }
-    }
-
-    *outKeycode = 0;
-    *outFlags = 0;
-    return NAME_NOT_FOUND;
-}
-
-status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-
-    if (device && device->keyMap.haveKeyLayout()) {
-        status_t err = device->keyMap.keyLayoutMap->mapAxis(scanCode, outAxisInfo);
-        if (err == NO_ERROR) {
-            return NO_ERROR;
-        }
-    }
-
-    return NAME_NOT_FOUND;
-}
-
-void EventHub::setExcludedDevices(const Vector<String8>& devices) {
-    AutoMutex _l(mLock);
-
-    mExcludedDevices = devices;
-}
-
-bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device && scanCode >= 0 && scanCode <= KEY_MAX) {
-        if (test_bit(scanCode, device->keyBitmask)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool EventHub::hasLed(int32_t deviceId, int32_t led) const {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    int32_t sc;
-    if (device && mapLed(device, led, &sc) == NO_ERROR) {
-        if (test_bit(sc, device->ledBitmask)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    setLedStateLocked(device, led, on);
-}
-
-void EventHub::setLedStateLocked(Device* device, int32_t led, bool on) {
-    int32_t sc;
-    if (device && !device->isVirtual() && mapLed(device, led, &sc) != NAME_NOT_FOUND) {
-        struct input_event ev;
-        ev.time.tv_sec = 0;
-        ev.time.tv_usec = 0;
-        ev.type = EV_LED;
-        ev.code = sc;
-        ev.value = on ? 1 : 0;
-
-        ssize_t nWrite;
-        do {
-            nWrite = write(device->fd, &ev, sizeof(struct input_event));
-        } while (nWrite == -1 && errno == EINTR);
-    }
-}
-
-void EventHub::getVirtualKeyDefinitions(int32_t deviceId,
-        Vector<VirtualKeyDefinition>& outVirtualKeys) const {
-    outVirtualKeys.clear();
-
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device && device->virtualKeyMap) {
-        outVirtualKeys.appendVector(device->virtualKeyMap->getVirtualKeys());
-    }
-}
-
-sp<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device) {
-        return device->getKeyCharacterMap();
-    }
-    return NULL;
-}
-
-bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId,
-        const sp<KeyCharacterMap>& map) {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device) {
-        if (map != device->overlayKeyMap) {
-            device->overlayKeyMap = map;
-            device->combinedKeyMap = KeyCharacterMap::combine(
-                    device->keyMap.keyCharacterMap, map);
-            return true;
-        }
-    }
-    return false;
-}
-
-static String8 generateDescriptor(InputDeviceIdentifier& identifier) {
-    String8 rawDescriptor;
-    rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor,
-            identifier.product);
-    // TODO add handling for USB devices to not uniqueify kbs that show up twice
-    if (!identifier.uniqueId.isEmpty()) {
-        rawDescriptor.append("uniqueId:");
-        rawDescriptor.append(identifier.uniqueId);
-    } else if (identifier.nonce != 0) {
-        rawDescriptor.appendFormat("nonce:%04x", identifier.nonce);
-    }
-
-    if (identifier.vendor == 0 && identifier.product == 0) {
-        // If we don't know the vendor and product id, then the device is probably
-        // built-in so we need to rely on other information to uniquely identify
-        // the input device.  Usually we try to avoid relying on the device name or
-        // location but for built-in input device, they are unlikely to ever change.
-        if (!identifier.name.isEmpty()) {
-            rawDescriptor.append("name:");
-            rawDescriptor.append(identifier.name);
-        } else if (!identifier.location.isEmpty()) {
-            rawDescriptor.append("location:");
-            rawDescriptor.append(identifier.location);
-        }
-    }
-    identifier.descriptor = sha1(rawDescriptor);
-    return rawDescriptor;
-}
-
-void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) {
-    // Compute a device descriptor that uniquely identifies the device.
-    // The descriptor is assumed to be a stable identifier.  Its value should not
-    // change between reboots, reconnections, firmware updates or new releases
-    // of Android. In practice we sometimes get devices that cannot be uniquely
-    // identified. In this case we enforce uniqueness between connected devices.
-    // Ideally, we also want the descriptor to be short and relatively opaque.
-
-    identifier.nonce = 0;
-    String8 rawDescriptor = generateDescriptor(identifier);
-    if (identifier.uniqueId.isEmpty()) {
-        // If it didn't have a unique id check for conflicts and enforce
-        // uniqueness if necessary.
-        while(getDeviceByDescriptorLocked(identifier.descriptor) != NULL) {
-            identifier.nonce++;
-            rawDescriptor = generateDescriptor(identifier);
-        }
-    }
-    ALOGV("Created descriptor: raw=%s, cooked=%s", rawDescriptor.string(),
-            identifier.descriptor.string());
-}
-
-void EventHub::vibrate(int32_t deviceId, nsecs_t duration) {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device && !device->isVirtual()) {
-        ff_effect effect;
-        memset(&effect, 0, sizeof(effect));
-        effect.type = FF_RUMBLE;
-        effect.id = device->ffEffectId;
-        effect.u.rumble.strong_magnitude = 0xc000;
-        effect.u.rumble.weak_magnitude = 0xc000;
-        effect.replay.length = (duration + 999999LL) / 1000000LL;
-        effect.replay.delay = 0;
-        if (ioctl(device->fd, EVIOCSFF, &effect)) {
-            ALOGW("Could not upload force feedback effect to device %s due to error %d.",
-                    device->identifier.name.string(), errno);
-            return;
-        }
-        device->ffEffectId = effect.id;
-
-        struct input_event ev;
-        ev.time.tv_sec = 0;
-        ev.time.tv_usec = 0;
-        ev.type = EV_FF;
-        ev.code = device->ffEffectId;
-        ev.value = 1;
-        if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
-            ALOGW("Could not start force feedback effect on device %s due to error %d.",
-                    device->identifier.name.string(), errno);
-            return;
-        }
-        device->ffEffectPlaying = true;
-    }
-}
-
-void EventHub::cancelVibrate(int32_t deviceId) {
-    AutoMutex _l(mLock);
-    Device* device = getDeviceLocked(deviceId);
-    if (device && !device->isVirtual()) {
-        if (device->ffEffectPlaying) {
-            device->ffEffectPlaying = false;
-
-            struct input_event ev;
-            ev.time.tv_sec = 0;
-            ev.time.tv_usec = 0;
-            ev.type = EV_FF;
-            ev.code = device->ffEffectId;
-            ev.value = 0;
-            if (write(device->fd, &ev, sizeof(ev)) != sizeof(ev)) {
-                ALOGW("Could not stop force feedback effect on device %s due to error %d.",
-                        device->identifier.name.string(), errno);
-                return;
-            }
-        }
-    }
-}
-
-EventHub::Device* EventHub::getDeviceByDescriptorLocked(String8& descriptor) const {
-    size_t size = mDevices.size();
-    for (size_t i = 0; i < size; i++) {
-        Device* device = mDevices.valueAt(i);
-        if (descriptor.compare(device->identifier.descriptor) == 0) {
-            return device;
-        }
-    }
-    return NULL;
-}
-
-EventHub::Device* EventHub::getDeviceLocked(int32_t deviceId) const {
-    if (deviceId == BUILT_IN_KEYBOARD_ID) {
-        deviceId = mBuiltInKeyboardId;
-    }
-    ssize_t index = mDevices.indexOfKey(deviceId);
-    return index >= 0 ? mDevices.valueAt(index) : NULL;
-}
-
-EventHub::Device* EventHub::getDeviceByPathLocked(const char* devicePath) const {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        Device* device = mDevices.valueAt(i);
-        if (device->path == devicePath) {
-            return device;
-        }
-    }
-    return NULL;
-}
-
-size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
-    ALOG_ASSERT(bufferSize >= 1);
-
-    AutoMutex _l(mLock);
-
-    struct input_event readBuffer[bufferSize];
-
-    RawEvent* event = buffer;
-    size_t capacity = bufferSize;
-    bool awoken = false;
-    for (;;) {
-        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
-        // Reopen input devices if needed.
-        if (mNeedToReopenDevices) {
-            mNeedToReopenDevices = false;
-
-            ALOGI("Reopening all input devices due to a configuration change.");
-
-            closeAllDevicesLocked();
-            mNeedToScanDevices = true;
-            break; // return to the caller before we actually rescan
-        }
-
-        // Report any devices that had last been added/removed.
-        while (mClosingDevices) {
-            Device* device = mClosingDevices;
-            ALOGV("Reporting device closed: id=%d, name=%s\n",
-                 device->id, device->path.string());
-            mClosingDevices = device->next;
-            event->when = now;
-            event->deviceId = device->id == mBuiltInKeyboardId ? BUILT_IN_KEYBOARD_ID : device->id;
-            event->type = DEVICE_REMOVED;
-            event += 1;
-            delete device;
-            mNeedToSendFinishedDeviceScan = true;
-            if (--capacity == 0) {
-                break;
-            }
-        }
-
-        if (mNeedToScanDevices) {
-            mNeedToScanDevices = false;
-            scanDevicesLocked();
-            mNeedToSendFinishedDeviceScan = true;
-        }
-
-        while (mOpeningDevices != NULL) {
-            Device* device = mOpeningDevices;
-            ALOGV("Reporting device opened: id=%d, name=%s\n",
-                 device->id, device->path.string());
-            mOpeningDevices = device->next;
-            event->when = now;
-            event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
-            event->type = DEVICE_ADDED;
-            event += 1;
-            mNeedToSendFinishedDeviceScan = true;
-            if (--capacity == 0) {
-                break;
-            }
-        }
-
-        if (mNeedToSendFinishedDeviceScan) {
-            mNeedToSendFinishedDeviceScan = false;
-            event->when = now;
-            event->type = FINISHED_DEVICE_SCAN;
-            event += 1;
-            if (--capacity == 0) {
-                break;
-            }
-        }
-
-        // Grab the next input event.
-        bool deviceChanged = false;
-        while (mPendingEventIndex < mPendingEventCount) {
-            const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
-            if (eventItem.data.u32 == EPOLL_ID_INOTIFY) {
-                if (eventItem.events & EPOLLIN) {
-                    mPendingINotify = true;
-                } else {
-                    ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
-                }
-                continue;
-            }
-
-            if (eventItem.data.u32 == EPOLL_ID_WAKE) {
-                if (eventItem.events & EPOLLIN) {
-                    ALOGV("awoken after wake()");
-                    awoken = true;
-                    char buffer[16];
-                    ssize_t nRead;
-                    do {
-                        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
-                    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
-                } else {
-                    ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.",
-                            eventItem.events);
-                }
-                continue;
-            }
-
-            ssize_t deviceIndex = mDevices.indexOfKey(eventItem.data.u32);
-            if (deviceIndex < 0) {
-                ALOGW("Received unexpected epoll event 0x%08x for unknown device id %d.",
-                        eventItem.events, eventItem.data.u32);
-                continue;
-            }
-
-            Device* device = mDevices.valueAt(deviceIndex);
-            if (eventItem.events & EPOLLIN) {
-                int32_t readSize = read(device->fd, readBuffer,
-                        sizeof(struct input_event) * capacity);
-                if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
-                    // Device was removed before INotify noticed.
-                    ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d "
-                            "capacity: %d errno: %d)\n",
-                            device->fd, readSize, bufferSize, capacity, errno);
-                    deviceChanged = true;
-                    closeDeviceLocked(device);
-                } else if (readSize < 0) {
-                    if (errno != EAGAIN && errno != EINTR) {
-                        ALOGW("could not get event (errno=%d)", errno);
-                    }
-                } else if ((readSize % sizeof(struct input_event)) != 0) {
-                    ALOGE("could not get event (wrong size: %d)", readSize);
-                } else {
-                    int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
-
-                    size_t count = size_t(readSize) / sizeof(struct input_event);
-                    for (size_t i = 0; i < count; i++) {
-                        struct input_event& iev = readBuffer[i];
-                        ALOGV("%s got: time=%d.%06d, type=%d, code=%d, value=%d",
-                                device->path.string(),
-                                (int) iev.time.tv_sec, (int) iev.time.tv_usec,
-                                iev.type, iev.code, iev.value);
-
-                        // Some input devices may have a better concept of the time
-                        // when an input event was actually generated than the kernel
-                        // which simply timestamps all events on entry to evdev.
-                        // This is a custom Android extension of the input protocol
-                        // mainly intended for use with uinput based device drivers.
-                        if (iev.type == EV_MSC) {
-                            if (iev.code == MSC_ANDROID_TIME_SEC) {
-                                device->timestampOverrideSec = iev.value;
-                                continue;
-                            } else if (iev.code == MSC_ANDROID_TIME_USEC) {
-                                device->timestampOverrideUsec = iev.value;
-                                continue;
-                            }
-                        }
-                        if (device->timestampOverrideSec || device->timestampOverrideUsec) {
-                            iev.time.tv_sec = device->timestampOverrideSec;
-                            iev.time.tv_usec = device->timestampOverrideUsec;
-                            if (iev.type == EV_SYN && iev.code == SYN_REPORT) {
-                                device->timestampOverrideSec = 0;
-                                device->timestampOverrideUsec = 0;
-                            }
-                            ALOGV("applied override time %d.%06d",
-                                    int(iev.time.tv_sec), int(iev.time.tv_usec));
-                        }
-
-#ifdef HAVE_POSIX_CLOCKS
-                        // Use the time specified in the event instead of the current time
-                        // so that downstream code can get more accurate estimates of
-                        // event dispatch latency from the time the event is enqueued onto
-                        // the evdev client buffer.
-                        //
-                        // The event's timestamp fortuitously uses the same monotonic clock
-                        // time base as the rest of Android.  The kernel event device driver
-                        // (drivers/input/evdev.c) obtains timestamps using ktime_get_ts().
-                        // The systemTime(SYSTEM_TIME_MONOTONIC) function we use everywhere
-                        // calls clock_gettime(CLOCK_MONOTONIC) which is implemented as a
-                        // system call that also queries ktime_get_ts().
-                        event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL
-                                + nsecs_t(iev.time.tv_usec) * 1000LL;
-                        ALOGV("event time %lld, now %lld", event->when, now);
-
-                        // Bug 7291243: Add a guard in case the kernel generates timestamps
-                        // that appear to be far into the future because they were generated
-                        // using the wrong clock source.
-                        //
-                        // This can happen because when the input device is initially opened
-                        // it has a default clock source of CLOCK_REALTIME.  Any input events
-                        // enqueued right after the device is opened will have timestamps
-                        // generated using CLOCK_REALTIME.  We later set the clock source
-                        // to CLOCK_MONOTONIC but it is already too late.
-                        //
-                        // Invalid input event timestamps can result in ANRs, crashes and
-                        // and other issues that are hard to track down.  We must not let them
-                        // propagate through the system.
-                        //
-                        // Log a warning so that we notice the problem and recover gracefully.
-                        if (event->when >= now + 10 * 1000000000LL) {
-                            // Double-check.  Time may have moved on.
-                            nsecs_t time = systemTime(SYSTEM_TIME_MONOTONIC);
-                            if (event->when > time) {
-                                ALOGW("An input event from %s has a timestamp that appears to "
-                                        "have been generated using the wrong clock source "
-                                        "(expected CLOCK_MONOTONIC): "
-                                        "event time %lld, current time %lld, call time %lld.  "
-                                        "Using current time instead.",
-                                        device->path.string(), event->when, time, now);
-                                event->when = time;
-                            } else {
-                                ALOGV("Event time is ok but failed the fast path and required "
-                                        "an extra call to systemTime: "
-                                        "event time %lld, current time %lld, call time %lld.",
-                                        event->when, time, now);
-                            }
-                        }
-#else
-                        event->when = now;
-#endif
-                        event->deviceId = deviceId;
-                        event->type = iev.type;
-                        event->code = iev.code;
-                        event->value = iev.value;
-                        event += 1;
-                        capacity -= 1;
-                    }
-                    if (capacity == 0) {
-                        // The result buffer is full.  Reset the pending event index
-                        // so we will try to read the device again on the next iteration.
-                        mPendingEventIndex -= 1;
-                        break;
-                    }
-                }
-            } else if (eventItem.events & EPOLLHUP) {
-                ALOGI("Removing device %s due to epoll hang-up event.",
-                        device->identifier.name.string());
-                deviceChanged = true;
-                closeDeviceLocked(device);
-            } else {
-                ALOGW("Received unexpected epoll event 0x%08x for device %s.",
-                        eventItem.events, device->identifier.name.string());
-            }
-        }
-
-        // readNotify() will modify the list of devices so this must be done after
-        // processing all other events to ensure that we read all remaining events
-        // before closing the devices.
-        if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) {
-            mPendingINotify = false;
-            readNotifyLocked();
-            deviceChanged = true;
-        }
-
-        // Report added or removed devices immediately.
-        if (deviceChanged) {
-            continue;
-        }
-
-        // Return now if we have collected any events or if we were explicitly awoken.
-        if (event != buffer || awoken) {
-            break;
-        }
-
-        // Poll for events.  Mind the wake lock dance!
-        // We hold a wake lock at all times except during epoll_wait().  This works due to some
-        // subtle choreography.  When a device driver has pending (unread) events, it acquires
-        // a kernel wake lock.  However, once the last pending event has been read, the device
-        // driver will release the kernel wake lock.  To prevent the system from going to sleep
-        // when this happens, the EventHub holds onto its own user wake lock while the client
-        // is processing events.  Thus the system can only sleep if there are no events
-        // pending or currently being processed.
-        //
-        // The timeout is advisory only.  If the device is asleep, it will not wake just to
-        // service the timeout.
-        mPendingEventIndex = 0;
-
-        mLock.unlock(); // release lock before poll, must be before release_wake_lock
-        release_wake_lock(WAKE_LOCK_ID);
-
-        int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
-
-        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-        mLock.lock(); // reacquire lock after poll, must be after acquire_wake_lock
-
-        if (pollResult == 0) {
-            // Timed out.
-            mPendingEventCount = 0;
-            break;
-        }
-
-        if (pollResult < 0) {
-            // An error occurred.
-            mPendingEventCount = 0;
-
-            // Sleep after errors to avoid locking up the system.
-            // Hopefully the error is transient.
-            if (errno != EINTR) {
-                ALOGW("poll failed (errno=%d)\n", errno);
-                usleep(100000);
-            }
-        } else {
-            // Some events occurred.
-            mPendingEventCount = size_t(pollResult);
-        }
-    }
-
-    // All done, return the number of events we read.
-    return event - buffer;
-}
-
-void EventHub::wake() {
-    ALOGV("wake() called");
-
-    ssize_t nWrite;
-    do {
-        nWrite = write(mWakeWritePipeFd, "W", 1);
-    } while (nWrite == -1 && errno == EINTR);
-
-    if (nWrite != 1 && errno != EAGAIN) {
-        ALOGW("Could not write wake signal, errno=%d", errno);
-    }
-}
-
-void EventHub::scanDevicesLocked() {
-    status_t res = scanDirLocked(DEVICE_PATH);
-    if(res < 0) {
-        ALOGE("scan dir failed for %s\n", DEVICE_PATH);
-    }
-    if (mDevices.indexOfKey(VIRTUAL_KEYBOARD_ID) < 0) {
-        createVirtualKeyboardLocked();
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) {
-    const uint8_t* end = array + endIndex;
-    array += startIndex;
-    while (array != end) {
-        if (*(array++) != 0) {
-            return true;
-        }
-    }
-    return false;
-}
-
-static const int32_t GAMEPAD_KEYCODES[] = {
-        AKEYCODE_BUTTON_A, AKEYCODE_BUTTON_B, AKEYCODE_BUTTON_C,
-        AKEYCODE_BUTTON_X, AKEYCODE_BUTTON_Y, AKEYCODE_BUTTON_Z,
-        AKEYCODE_BUTTON_L1, AKEYCODE_BUTTON_R1,
-        AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2,
-        AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR,
-        AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE,
-        AKEYCODE_BUTTON_1, AKEYCODE_BUTTON_2, AKEYCODE_BUTTON_3, AKEYCODE_BUTTON_4,
-        AKEYCODE_BUTTON_5, AKEYCODE_BUTTON_6, AKEYCODE_BUTTON_7, AKEYCODE_BUTTON_8,
-        AKEYCODE_BUTTON_9, AKEYCODE_BUTTON_10, AKEYCODE_BUTTON_11, AKEYCODE_BUTTON_12,
-        AKEYCODE_BUTTON_13, AKEYCODE_BUTTON_14, AKEYCODE_BUTTON_15, AKEYCODE_BUTTON_16,
-};
-
-status_t EventHub::openDeviceLocked(const char *devicePath) {
-    char buffer[80];
-
-    ALOGV("Opening device: %s", devicePath);
-
-    int fd = open(devicePath, O_RDWR | O_CLOEXEC);
-    if(fd < 0) {
-        ALOGE("could not open %s, %s\n", devicePath, strerror(errno));
-        return -1;
-    }
-
-    InputDeviceIdentifier identifier;
-
-    // Get device name.
-    if(ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
-        //fprintf(stderr, "could not get device name for %s, %s\n", devicePath, strerror(errno));
-    } else {
-        buffer[sizeof(buffer) - 1] = '\0';
-        identifier.name.setTo(buffer);
-    }
-
-    // Check to see if the device is on our excluded list
-    for (size_t i = 0; i < mExcludedDevices.size(); i++) {
-        const String8& item = mExcludedDevices.itemAt(i);
-        if (identifier.name == item) {
-            ALOGI("ignoring event id %s driver %s\n", devicePath, item.string());
-            close(fd);
-            return -1;
-        }
-    }
-
-    // Get device driver version.
-    int driverVersion;
-    if(ioctl(fd, EVIOCGVERSION, &driverVersion)) {
-        ALOGE("could not get driver version for %s, %s\n", devicePath, strerror(errno));
-        close(fd);
-        return -1;
-    }
-
-    // Get device identifier.
-    struct input_id inputId;
-    if(ioctl(fd, EVIOCGID, &inputId)) {
-        ALOGE("could not get device input id for %s, %s\n", devicePath, strerror(errno));
-        close(fd);
-        return -1;
-    }
-    identifier.bus = inputId.bustype;
-    identifier.product = inputId.product;
-    identifier.vendor = inputId.vendor;
-    identifier.version = inputId.version;
-
-    // Get device physical location.
-    if(ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
-        //fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
-    } else {
-        buffer[sizeof(buffer) - 1] = '\0';
-        identifier.location.setTo(buffer);
-    }
-
-    // Get device unique id.
-    if(ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
-        //fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
-    } else {
-        buffer[sizeof(buffer) - 1] = '\0';
-        identifier.uniqueId.setTo(buffer);
-    }
-
-    // Fill in the descriptor.
-    assignDescriptorLocked(identifier);
-
-    // Make file descriptor non-blocking for use with poll().
-    if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
-        ALOGE("Error %d making device file descriptor non-blocking.", errno);
-        close(fd);
-        return -1;
-    }
-
-    // Allocate device.  (The device object takes ownership of the fd at this point.)
-    int32_t deviceId = mNextDeviceId++;
-    Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
-
-    ALOGV("add device %d: %s\n", deviceId, devicePath);
-    ALOGV("  bus:        %04x\n"
-         "  vendor      %04x\n"
-         "  product     %04x\n"
-         "  version     %04x\n",
-        identifier.bus, identifier.vendor, identifier.product, identifier.version);
-    ALOGV("  name:       \"%s\"\n", identifier.name.string());
-    ALOGV("  location:   \"%s\"\n", identifier.location.string());
-    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.string());
-    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.string());
-    ALOGV("  driver:     v%d.%d.%d\n",
-        driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);
-
-    // Load the configuration file for the device.
-    loadConfigurationLocked(device);
-
-    // Figure out the kinds of events the device reports.
-    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(device->keyBitmask)), device->keyBitmask);
-    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(device->absBitmask)), device->absBitmask);
-    ioctl(fd, EVIOCGBIT(EV_REL, sizeof(device->relBitmask)), device->relBitmask);
-    ioctl(fd, EVIOCGBIT(EV_SW, sizeof(device->swBitmask)), device->swBitmask);
-    ioctl(fd, EVIOCGBIT(EV_LED, sizeof(device->ledBitmask)), device->ledBitmask);
-    ioctl(fd, EVIOCGBIT(EV_FF, sizeof(device->ffBitmask)), device->ffBitmask);
-    ioctl(fd, EVIOCGPROP(sizeof(device->propBitmask)), device->propBitmask);
-
-    // See if this is a keyboard.  Ignore everything in the button range except for
-    // joystick and gamepad buttons which are handled like keyboards for the most part.
-    bool haveKeyboardKeys = containsNonZeroByte(device->keyBitmask, 0, sizeof_bit_array(BTN_MISC))
-            || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(KEY_OK),
-                    sizeof_bit_array(KEY_MAX + 1));
-    bool haveGamepadButtons = containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_MISC),
-                    sizeof_bit_array(BTN_MOUSE))
-            || containsNonZeroByte(device->keyBitmask, sizeof_bit_array(BTN_JOYSTICK),
-                    sizeof_bit_array(BTN_DIGI));
-    if (haveKeyboardKeys || haveGamepadButtons) {
-        device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
-    }
-
-    // See if this is a cursor device such as a trackball or mouse.
-    if (test_bit(BTN_MOUSE, device->keyBitmask)
-            && test_bit(REL_X, device->relBitmask)
-            && test_bit(REL_Y, device->relBitmask)) {
-        device->classes |= INPUT_DEVICE_CLASS_CURSOR;
-    }
-
-    // See if this is a touch pad.
-    // Is this a new modern multi-touch driver?
-    if (test_bit(ABS_MT_POSITION_X, device->absBitmask)
-            && test_bit(ABS_MT_POSITION_Y, device->absBitmask)) {
-        // Some joysticks such as the PS3 controller report axes that conflict
-        // with the ABS_MT range.  Try to confirm that the device really is
-        // a touch screen.
-        if (test_bit(BTN_TOUCH, device->keyBitmask) || !haveGamepadButtons) {
-            device->classes |= INPUT_DEVICE_CLASS_TOUCH | INPUT_DEVICE_CLASS_TOUCH_MT;
-        }
-    // Is this an old style single-touch driver?
-    } else if (test_bit(BTN_TOUCH, device->keyBitmask)
-            && test_bit(ABS_X, device->absBitmask)
-            && test_bit(ABS_Y, device->absBitmask)) {
-        device->classes |= INPUT_DEVICE_CLASS_TOUCH;
-    }
-
-    // See if this device is a joystick.
-    // Assumes that joysticks always have gamepad buttons in order to distinguish them
-    // from other devices such as accelerometers that also have absolute axes.
-    if (haveGamepadButtons) {
-        uint32_t assumedClasses = device->classes | INPUT_DEVICE_CLASS_JOYSTICK;
-        for (int i = 0; i <= ABS_MAX; i++) {
-            if (test_bit(i, device->absBitmask)
-                    && (getAbsAxisUsage(i, assumedClasses) & INPUT_DEVICE_CLASS_JOYSTICK)) {
-                device->classes = assumedClasses;
-                break;
-            }
-        }
-    }
-
-    // Check whether this device has switches.
-    for (int i = 0; i <= SW_MAX; i++) {
-        if (test_bit(i, device->swBitmask)) {
-            device->classes |= INPUT_DEVICE_CLASS_SWITCH;
-            break;
-        }
-    }
-
-    // Check whether this device supports the vibrator.
-    if (test_bit(FF_RUMBLE, device->ffBitmask)) {
-        device->classes |= INPUT_DEVICE_CLASS_VIBRATOR;
-    }
-
-    // Configure virtual keys.
-    if ((device->classes & INPUT_DEVICE_CLASS_TOUCH)) {
-        // Load the virtual keys for the touch screen, if any.
-        // We do this now so that we can make sure to load the keymap if necessary.
-        status_t status = loadVirtualKeyMapLocked(device);
-        if (!status) {
-            device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
-        }
-    }
-
-    // Load the key map.
-    // We need to do this for joysticks too because the key layout may specify axes.
-    status_t keyMapStatus = NAME_NOT_FOUND;
-    if (device->classes & (INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_JOYSTICK)) {
-        // Load the keymap for the device.
-        keyMapStatus = loadKeyMapLocked(device);
-    }
-
-    // Configure the keyboard, gamepad or virtual keyboard.
-    if (device->classes & INPUT_DEVICE_CLASS_KEYBOARD) {
-        // Register the keyboard as a built-in keyboard if it is eligible.
-        if (!keyMapStatus
-                && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD
-                && isEligibleBuiltInKeyboard(device->identifier,
-                        device->configuration, &device->keyMap)) {
-            mBuiltInKeyboardId = device->id;
-        }
-
-        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
-        if (hasKeycodeLocked(device, AKEYCODE_Q)) {
-            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
-        }
-
-        // See if this device has a DPAD.
-        if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) &&
-                hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) {
-            device->classes |= INPUT_DEVICE_CLASS_DPAD;
-        }
-
-        // See if this device has a gamepad.
-        for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES)/sizeof(GAMEPAD_KEYCODES[0]); i++) {
-            if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) {
-                device->classes |= INPUT_DEVICE_CLASS_GAMEPAD;
-                break;
-            }
-        }
-
-        // Disable kernel key repeat since we handle it ourselves
-        unsigned int repeatRate[] = {0,0};
-        if (ioctl(fd, EVIOCSREP, repeatRate)) {
-            ALOGW("Unable to disable kernel key repeat for %s: %s", devicePath, strerror(errno));
-        }
-    }
-
-    // If the device isn't recognized as something we handle, don't monitor it.
-    if (device->classes == 0) {
-        ALOGV("Dropping device: id=%d, path='%s', name='%s'",
-                deviceId, devicePath, device->identifier.name.string());
-        delete device;
-        return -1;
-    }
-
-    // Determine whether the device is external or internal.
-    if (isExternalDeviceLocked(device)) {
-        device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
-    }
-
-    if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_DPAD)
-            && device->classes & INPUT_DEVICE_CLASS_GAMEPAD) {
-        device->controllerNumber = getNextControllerNumberLocked(device);
-        setLedForController(device);
-    }
-
-    // Register with epoll.
-    struct epoll_event eventItem;
-    memset(&eventItem, 0, sizeof(eventItem));
-    eventItem.events = EPOLLIN;
-    eventItem.data.u32 = deviceId;
-    if (epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, &eventItem)) {
-        ALOGE("Could not add device fd to epoll instance.  errno=%d", errno);
-        delete device;
-        return -1;
-    }
-
-    // Enable wake-lock behavior on kernels that support it.
-    // TODO: Only need this for devices that can really wake the system.
-#ifndef EVIOCSSUSPENDBLOCK
-    // uapi headers don't include EVIOCSSUSPENDBLOCK, and future kernels
-    // will use an epoll flag instead, so as long as we want to support
-    // this feature, we need to be prepared to define the ioctl ourselves.
-#define EVIOCSSUSPENDBLOCK _IOW('E', 0x91, int)
-#endif
-    bool usingSuspendBlockIoctl = !ioctl(fd, EVIOCSSUSPENDBLOCK, 1);
-
-    // Tell the kernel that we want to use the monotonic clock for reporting timestamps
-    // associated with input events.  This is important because the input system
-    // uses the timestamps extensively and assumes they were recorded using the monotonic
-    // clock.
-    //
-    // In older kernel, before Linux 3.4, there was no way to tell the kernel which
-    // clock to use to input event timestamps.  The standard kernel behavior was to
-    // record a real time timestamp, which isn't what we want.  Android kernels therefore
-    // contained a patch to the evdev_event() function in drivers/input/evdev.c to
-    // replace the call to do_gettimeofday() with ktime_get_ts() to cause the monotonic
-    // clock to be used instead of the real time clock.
-    //
-    // As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock.
-    // Therefore, we no longer require the Android-specific kernel patch described above
-    // as long as we make sure to set select the monotonic clock.  We do that here.
-    int clockId = CLOCK_MONOTONIC;
-    bool usingClockIoctl = !ioctl(fd, EVIOCSCLOCKID, &clockId);
-
-    ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=0x%x, "
-            "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, "
-            "usingSuspendBlockIoctl=%s, usingClockIoctl=%s",
-         deviceId, fd, devicePath, device->identifier.name.string(),
-         device->classes,
-         device->configurationFile.string(),
-         device->keyMap.keyLayoutFile.string(),
-         device->keyMap.keyCharacterMapFile.string(),
-         toString(mBuiltInKeyboardId == deviceId),
-         toString(usingSuspendBlockIoctl), toString(usingClockIoctl));
-
-    addDeviceLocked(device);
-    return 0;
-}
-
-void EventHub::createVirtualKeyboardLocked() {
-    InputDeviceIdentifier identifier;
-    identifier.name = "Virtual";
-    identifier.uniqueId = "<virtual>";
-    assignDescriptorLocked(identifier);
-
-    Device* device = new Device(-1, VIRTUAL_KEYBOARD_ID, String8("<virtual>"), identifier);
-    device->classes = INPUT_DEVICE_CLASS_KEYBOARD
-            | INPUT_DEVICE_CLASS_ALPHAKEY
-            | INPUT_DEVICE_CLASS_DPAD
-            | INPUT_DEVICE_CLASS_VIRTUAL;
-    loadKeyMapLocked(device);
-    addDeviceLocked(device);
-}
-
-void EventHub::addDeviceLocked(Device* device) {
-    mDevices.add(device->id, device);
-    device->next = mOpeningDevices;
-    mOpeningDevices = device;
-}
-
-void EventHub::loadConfigurationLocked(Device* device) {
-    device->configurationFile = getInputDeviceConfigurationFilePathByDeviceIdentifier(
-            device->identifier, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION);
-    if (device->configurationFile.isEmpty()) {
-        ALOGD("No input device configuration file found for device '%s'.",
-                device->identifier.name.string());
-    } else {
-        status_t status = PropertyMap::load(device->configurationFile,
-                &device->configuration);
-        if (status) {
-            ALOGE("Error loading input device configuration file for device '%s'.  "
-                    "Using default configuration.",
-                    device->identifier.name.string());
-        }
-    }
-}
-
-status_t EventHub::loadVirtualKeyMapLocked(Device* device) {
-    // The virtual key map is supplied by the kernel as a system board property file.
-    String8 path;
-    path.append("/sys/board_properties/virtualkeys.");
-    path.append(device->identifier.name);
-    if (access(path.string(), R_OK)) {
-        return NAME_NOT_FOUND;
-    }
-    return VirtualKeyMap::load(path, &device->virtualKeyMap);
-}
-
-status_t EventHub::loadKeyMapLocked(Device* device) {
-    return device->keyMap.load(device->identifier, device->configuration);
-}
-
-bool EventHub::isExternalDeviceLocked(Device* device) {
-    if (device->configuration) {
-        bool value;
-        if (device->configuration->tryGetProperty(String8("device.internal"), value)) {
-            return !value;
-        }
-    }
-    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));
-}
-
-void EventHub::setLedForController(Device* device) {
-    for (int i = 0; i < MAX_CONTROLLER_LEDS; i++) {
-        setLedStateLocked(device, ALED_CONTROLLER_1 + i, device->controllerNumber == i + 1);
-    }
-}
-
-bool EventHub::hasKeycodeLocked(Device* device, int keycode) const {
-    if (!device->keyMap.haveKeyLayout() || !device->keyBitmask) {
-        return false;
-    }
-    
-    Vector<int32_t> scanCodes;
-    device->keyMap.keyLayoutMap->findScanCodesForKey(keycode, &scanCodes);
-    const size_t N = scanCodes.size();
-    for (size_t i=0; i<N && i<=KEY_MAX; i++) {
-        int32_t sc = scanCodes.itemAt(i);
-        if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) {
-            return true;
-        }
-    }
-    
-    return false;
-}
-
-status_t EventHub::mapLed(Device* device, int32_t led, int32_t* outScanCode) const {
-    if (!device->keyMap.haveKeyLayout() || !device->ledBitmask) {
-        return NAME_NOT_FOUND;
-    }
-
-    int32_t scanCode;
-    if(device->keyMap.keyLayoutMap->findScanCodeForLed(led, &scanCode) != NAME_NOT_FOUND) {
-        if(scanCode >= 0 && scanCode <= LED_MAX && test_bit(scanCode, device->ledBitmask)) {
-            *outScanCode = scanCode;
-            return NO_ERROR;
-        }
-    }
-    return NAME_NOT_FOUND;
-}
-
-status_t EventHub::closeDeviceByPathLocked(const char *devicePath) {
-    Device* device = getDeviceByPathLocked(devicePath);
-    if (device) {
-        closeDeviceLocked(device);
-        return 0;
-    }
-    ALOGV("Remove device: %s not found, device may already have been removed.", devicePath);
-    return -1;
-}
-
-void EventHub::closeAllDevicesLocked() {
-    while (mDevices.size() > 0) {
-        closeDeviceLocked(mDevices.valueAt(mDevices.size() - 1));
-    }
-}
-
-void EventHub::closeDeviceLocked(Device* device) {
-    ALOGI("Removed device: path=%s name=%s id=%d fd=%d classes=0x%x\n",
-         device->path.string(), device->identifier.name.string(), device->id,
-         device->fd, device->classes);
-
-    if (device->id == mBuiltInKeyboardId) {
-        ALOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
-                device->path.string(), mBuiltInKeyboardId);
-        mBuiltInKeyboardId = NO_BUILT_IN_KEYBOARD;
-    }
-
-    if (!device->isVirtual()) {
-        if (epoll_ctl(mEpollFd, EPOLL_CTL_DEL, device->fd, NULL)) {
-            ALOGW("Could not remove device fd from epoll instance.  errno=%d", errno);
-        }
-    }
-
-    releaseControllerNumberLocked(device);
-
-    mDevices.removeItem(device->id);
-    device->close();
-
-    // Unlink for opening devices list if it is present.
-    Device* pred = NULL;
-    bool found = false;
-    for (Device* entry = mOpeningDevices; entry != NULL; ) {
-        if (entry == device) {
-            found = true;
-            break;
-        }
-        pred = entry;
-        entry = entry->next;
-    }
-    if (found) {
-        // Unlink the device from the opening devices list then delete it.
-        // We don't need to tell the client that the device was closed because
-        // it does not even know it was opened in the first place.
-        ALOGI("Device %s was immediately closed after opening.", device->path.string());
-        if (pred) {
-            pred->next = device->next;
-        } else {
-            mOpeningDevices = device->next;
-        }
-        delete device;
-    } else {
-        // Link into closing devices list.
-        // The device will be deleted later after we have informed the client.
-        device->next = mClosingDevices;
-        mClosingDevices = device;
-    }
-}
-
-status_t EventHub::readNotifyLocked() {
-    int res;
-    char devname[PATH_MAX];
-    char *filename;
-    char event_buf[512];
-    int event_size;
-    int event_pos = 0;
-    struct inotify_event *event;
-
-    ALOGV("EventHub::readNotify nfd: %d\n", mINotifyFd);
-    res = read(mINotifyFd, event_buf, sizeof(event_buf));
-    if(res < (int)sizeof(*event)) {
-        if(errno == EINTR)
-            return 0;
-        ALOGW("could not get event, %s\n", strerror(errno));
-        return -1;
-    }
-    //printf("got %d bytes of event information\n", res);
-
-    strcpy(devname, DEVICE_PATH);
-    filename = devname + strlen(devname);
-    *filename++ = '/';
-
-    while(res >= (int)sizeof(*event)) {
-        event = (struct inotify_event *)(event_buf + event_pos);
-        //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : "");
-        if(event->len) {
-            strcpy(filename, event->name);
-            if(event->mask & IN_CREATE) {
-                openDeviceLocked(devname);
-            } else {
-                ALOGI("Removing device '%s' due to inotify event\n", devname);
-                closeDeviceByPathLocked(devname);
-            }
-        }
-        event_size = sizeof(*event) + event->len;
-        res -= event_size;
-        event_pos += event_size;
-    }
-    return 0;
-}
-
-status_t EventHub::scanDirLocked(const char *dirname)
-{
-    char devname[PATH_MAX];
-    char *filename;
-    DIR *dir;
-    struct dirent *de;
-    dir = opendir(dirname);
-    if(dir == NULL)
-        return -1;
-    strcpy(devname, dirname);
-    filename = devname + strlen(devname);
-    *filename++ = '/';
-    while((de = readdir(dir))) {
-        if(de->d_name[0] == '.' &&
-           (de->d_name[1] == '\0' ||
-            (de->d_name[1] == '.' && de->d_name[2] == '\0')))
-            continue;
-        strcpy(filename, de->d_name);
-        openDeviceLocked(devname);
-    }
-    closedir(dir);
-    return 0;
-}
-
-void EventHub::requestReopenDevices() {
-    ALOGV("requestReopenDevices() called");
-
-    AutoMutex _l(mLock);
-    mNeedToReopenDevices = true;
-}
-
-void EventHub::dump(String8& dump) {
-    dump.append("Event Hub State:\n");
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        dump.appendFormat(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId);
-
-        dump.append(INDENT "Devices:\n");
-
-        for (size_t i = 0; i < mDevices.size(); i++) {
-            const Device* device = mDevices.valueAt(i);
-            if (mBuiltInKeyboardId == device->id) {
-                dump.appendFormat(INDENT2 "%d: %s (aka device 0 - built-in keyboard)\n",
-                        device->id, device->identifier.name.string());
-            } else {
-                dump.appendFormat(INDENT2 "%d: %s\n", device->id,
-                        device->identifier.name.string());
-            }
-            dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
-            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",
-                    device->identifier.bus, device->identifier.vendor,
-                    device->identifier.product, device->identifier.version);
-            dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n",
-                    device->keyMap.keyLayoutFile.string());
-            dump.appendFormat(INDENT3 "KeyCharacterMapFile: %s\n",
-                    device->keyMap.keyCharacterMapFile.string());
-            dump.appendFormat(INDENT3 "ConfigurationFile: %s\n",
-                    device->configurationFile.string());
-            dump.appendFormat(INDENT3 "HaveKeyboardLayoutOverlay: %s\n",
-                    toString(device->overlayKeyMap != NULL));
-        }
-    } // release lock
-}
-
-void EventHub::monitor() {
-    // Acquire and release the lock to ensure that the event hub has not deadlocked.
-    mLock.lock();
-    mLock.unlock();
-}
-
-
-}; // namespace android
diff --git a/libs/input/EventHub.h b/libs/input/EventHub.h
deleted file mode 100644
index 86c05af..0000000
--- a/libs/input/EventHub.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * 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.
- */
-
-//
-#ifndef _RUNTIME_EVENT_HUB_H
-#define _RUNTIME_EVENT_HUB_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>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-#include <utils/PropertyMap.h>
-#include <utils/Vector.h>
-#include <utils/KeyedVector.h>
-#include <utils/BitSet.h>
-
-#include <linux/input.h>
-#include <sys/epoll.h>
-
-/* Convenience constants. */
-
-#define BTN_FIRST 0x100  // first button code
-#define BTN_LAST 0x15f   // last button code
-
-/*
- * These constants are used privately in Android to pass raw timestamps
- * through evdev from uinput device drivers because there is currently no
- * other way to transfer this information.  The evdev driver automatically
- * timestamps all input events with the time they were posted and clobbers
- * whatever information was passed in.
- *
- * For the purposes of this hack, the timestamp is specified in the
- * CLOCK_MONOTONIC timebase and is split into two EV_MSC events specifying
- * seconds and microseconds.
- */
-#define MSC_ANDROID_TIME_SEC 0x6
-#define MSC_ANDROID_TIME_USEC 0x7
-
-namespace android {
-
-enum {
-    // Device id of a special "virtual" keyboard that is always present.
-    VIRTUAL_KEYBOARD_ID = -1,
-    // Device id of the "built-in" keyboard if there is one.
-    BUILT_IN_KEYBOARD_ID = 0,
-};
-
-/*
- * A raw event as retrieved from the EventHub.
- */
-struct RawEvent {
-    nsecs_t when;
-    int32_t deviceId;
-    int32_t type;
-    int32_t code;
-    int32_t value;
-};
-
-/* Describes an absolute axis. */
-struct RawAbsoluteAxisInfo {
-    bool valid; // true if the information is valid, false otherwise
-
-    int32_t minValue;  // minimum value
-    int32_t maxValue;  // maximum value
-    int32_t flat;      // center flat position, eg. flat == 8 means center is between -8 and 8
-    int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
-    int32_t resolution; // resolution in units per mm or radians per mm
-
-    inline void clear() {
-        valid = false;
-        minValue = 0;
-        maxValue = 0;
-        flat = 0;
-        fuzz = 0;
-        resolution = 0;
-    }
-};
-
-/*
- * Input device classes.
- */
-enum {
-    /* The input device is a keyboard or has buttons. */
-    INPUT_DEVICE_CLASS_KEYBOARD      = 0x00000001,
-
-    /* The input device is an alpha-numeric keyboard (not just a dial pad). */
-    INPUT_DEVICE_CLASS_ALPHAKEY      = 0x00000002,
-
-    /* The input device is a touchscreen or a touchpad (either single-touch or multi-touch). */
-    INPUT_DEVICE_CLASS_TOUCH         = 0x00000004,
-
-    /* The input device is a cursor device such as a trackball or mouse. */
-    INPUT_DEVICE_CLASS_CURSOR        = 0x00000008,
-
-    /* The input device is a multi-touch touchscreen. */
-    INPUT_DEVICE_CLASS_TOUCH_MT      = 0x00000010,
-
-    /* The input device is a directional pad (implies keyboard, has DPAD keys). */
-    INPUT_DEVICE_CLASS_DPAD          = 0x00000020,
-
-    /* The input device is a gamepad (implies keyboard, has BUTTON keys). */
-    INPUT_DEVICE_CLASS_GAMEPAD       = 0x00000040,
-
-    /* The input device has switches. */
-    INPUT_DEVICE_CLASS_SWITCH        = 0x00000080,
-
-    /* The input device is a joystick (implies gamepad, has joystick absolute axes). */
-    INPUT_DEVICE_CLASS_JOYSTICK      = 0x00000100,
-
-    /* The input device has a vibrator (supports FF_RUMBLE). */
-    INPUT_DEVICE_CLASS_VIBRATOR      = 0x00000200,
-
-    /* The input device is virtual (not a real device, not part of UI configuration). */
-    INPUT_DEVICE_CLASS_VIRTUAL       = 0x40000000,
-
-    /* The input device is external (not built-in). */
-    INPUT_DEVICE_CLASS_EXTERNAL      = 0x80000000,
-};
-
-/*
- * Gets the class that owns an axis, in cases where multiple classes might claim
- * the same axis for different purposes.
- */
-extern uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses);
-
-/*
- * Grand Central Station for events.
- *
- * The event hub aggregates input events received across all known input
- * devices on the system, including devices that may be emulated by the simulator
- * environment.  In addition, the event hub generates fake input events to indicate
- * when devices are added or removed.
- *
- * The event hub provides a stream of input events (via the getEvent function).
- * It also supports querying the current actual state of input devices such as identifying
- * which keys are currently down.  Finally, the event hub keeps track of the capabilities of
- * individual input devices, such as their class and the set of key codes that they support.
- */
-class EventHubInterface : public virtual RefBase {
-protected:
-    EventHubInterface() { }
-    virtual ~EventHubInterface() { }
-
-public:
-    // Synthetic raw event type codes produced when devices are added or removed.
-    enum {
-        // Sent when a device is added.
-        DEVICE_ADDED = 0x10000000,
-        // Sent when a device is removed.
-        DEVICE_REMOVED = 0x20000000,
-        // Sent when all added/removed devices from the most recent scan have been reported.
-        // This event is always sent at least once.
-        FINISHED_DEVICE_SCAN = 0x30000000,
-
-        FIRST_SYNTHETIC_EVENT = DEVICE_ADDED,
-    };
-
-    virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
-
-    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,
-            RawAbsoluteAxisInfo* outAxisInfo) const = 0;
-
-    virtual bool hasRelativeAxis(int32_t deviceId, int axis) const = 0;
-
-    virtual bool hasInputProperty(int32_t deviceId, int property) const = 0;
-
-    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
-            int32_t* outKeycode, uint32_t* outFlags) const = 0;
-
-    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
-            AxisInfo* outAxisInfo) const = 0;
-
-    // Sets devices that are excluded from opening.
-    // This can be used to ignore input devices for sensors.
-    virtual void setExcludedDevices(const Vector<String8>& devices) = 0;
-
-    /*
-     * Wait for events to become available and returns them.
-     * After returning, the EventHub holds onto a wake lock until the next call to getEvent.
-     * This ensures that the device will not go to sleep while the event is being processed.
-     * If the device needs to remain awake longer than that, then the caller is responsible
-     * for taking care of it (say, by poking the power manager user activity timer).
-     *
-     * The timeout is advisory only.  If the device is asleep, it will not wake just to
-     * service the timeout.
-     *
-     * Returns the number of events obtained, or 0 if the timeout expired.
-     */
-    virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) = 0;
-
-    /*
-     * Query current input state.
-     */
-    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
-    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
-    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
-    virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
-            int32_t* outValue) const = 0;
-
-    /*
-     * Examine key input devices for specific framework keycode support
-     */
-    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
-            uint8_t* outFlags) const = 0;
-
-    virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const = 0;
-
-    /* LED related functions expect Android LED constants, not scan codes or HID usages */
-    virtual bool hasLed(int32_t deviceId, int32_t led) const = 0;
-    virtual void setLedState(int32_t deviceId, int32_t led, bool on) = 0;
-
-    virtual void getVirtualKeyDefinitions(int32_t deviceId,
-            Vector<VirtualKeyDefinition>& outVirtualKeys) const = 0;
-
-    virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const = 0;
-    virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) = 0;
-
-    /* Control the vibrator. */
-    virtual void vibrate(int32_t deviceId, nsecs_t duration) = 0;
-    virtual void cancelVibrate(int32_t deviceId) = 0;
-
-    /* Requests the EventHub to reopen all input devices on the next call to getEvents(). */
-    virtual void requestReopenDevices() = 0;
-
-    /* Wakes up getEvents() if it is blocked on a read. */
-    virtual void wake() = 0;
-
-    /* Dump EventHub state to a string. */
-    virtual void dump(String8& dump) = 0;
-
-    /* Called by the heatbeat to ensures that the reader has not deadlocked. */
-    virtual void monitor() = 0;
-};
-
-class EventHub : public EventHubInterface
-{
-public:
-    EventHub();
-
-    virtual uint32_t getDeviceClasses(int32_t deviceId) const;
-
-    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,
-            RawAbsoluteAxisInfo* outAxisInfo) const;
-
-    virtual bool hasRelativeAxis(int32_t deviceId, int axis) const;
-
-    virtual bool hasInputProperty(int32_t deviceId, int property) const;
-
-    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
-            int32_t* outKeycode, uint32_t* outFlags) const;
-
-    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
-            AxisInfo* outAxisInfo) const;
-
-    virtual void setExcludedDevices(const Vector<String8>& devices);
-
-    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
-    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
-    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
-    virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const;
-
-    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags) const;
-
-    virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize);
-
-    virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const;
-    virtual bool hasLed(int32_t deviceId, int32_t led) const;
-    virtual void setLedState(int32_t deviceId, int32_t led, bool on);
-
-    virtual void getVirtualKeyDefinitions(int32_t deviceId,
-            Vector<VirtualKeyDefinition>& outVirtualKeys) const;
-
-    virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const;
-    virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map);
-
-    virtual void vibrate(int32_t deviceId, nsecs_t duration);
-    virtual void cancelVibrate(int32_t deviceId);
-
-    virtual void requestReopenDevices();
-
-    virtual void wake();
-
-    virtual void dump(String8& dump);
-    virtual void monitor();
-
-protected:
-    virtual ~EventHub();
-
-private:
-    struct Device {
-        Device* next;
-
-        int fd; // may be -1 if device is virtual
-        const int32_t id;
-        const String8 path;
-        const InputDeviceIdentifier identifier;
-
-        uint32_t classes;
-
-        uint8_t keyBitmask[(KEY_MAX + 1) / 8];
-        uint8_t absBitmask[(ABS_MAX + 1) / 8];
-        uint8_t relBitmask[(REL_MAX + 1) / 8];
-        uint8_t swBitmask[(SW_MAX + 1) / 8];
-        uint8_t ledBitmask[(LED_MAX + 1) / 8];
-        uint8_t ffBitmask[(FF_MAX + 1) / 8];
-        uint8_t propBitmask[(INPUT_PROP_MAX + 1) / 8];
-
-        String8 configurationFile;
-        PropertyMap* configuration;
-        VirtualKeyMap* virtualKeyMap;
-        KeyMap keyMap;
-
-        sp<KeyCharacterMap> overlayKeyMap;
-        sp<KeyCharacterMap> combinedKeyMap;
-
-        bool ffEffectPlaying;
-        int16_t ffEffectId; // initially -1
-
-        int32_t controllerNumber;
-
-        int32_t timestampOverrideSec;
-        int32_t timestampOverrideUsec;
-
-        Device(int fd, int32_t id, const String8& path, const InputDeviceIdentifier& identifier);
-        ~Device();
-
-        void close();
-
-        inline bool isVirtual() const { return fd < 0; }
-
-        const sp<KeyCharacterMap>& getKeyCharacterMap() const {
-            if (combinedKeyMap != NULL) {
-                return combinedKeyMap;
-            }
-            return keyMap.keyCharacterMap;
-        }
-    };
-
-    status_t openDeviceLocked(const char *devicePath);
-    void createVirtualKeyboardLocked();
-    void addDeviceLocked(Device* device);
-    void assignDescriptorLocked(InputDeviceIdentifier& identifier);
-
-    status_t closeDeviceByPathLocked(const char *devicePath);
-    void closeDeviceLocked(Device* device);
-    void closeAllDevicesLocked();
-
-    status_t scanDirLocked(const char *dirname);
-    void scanDevicesLocked();
-    status_t readNotifyLocked();
-
-    Device* getDeviceByDescriptorLocked(String8& descriptor) const;
-    Device* getDeviceLocked(int32_t deviceId) const;
-    Device* getDeviceByPathLocked(const char* devicePath) const;
-
-    bool hasKeycodeLocked(Device* device, int keycode) const;
-
-    void loadConfigurationLocked(Device* device);
-    status_t loadVirtualKeyMapLocked(Device* device);
-    status_t loadKeyMapLocked(Device* device);
-
-    bool isExternalDeviceLocked(Device* device);
-
-    int32_t getNextControllerNumberLocked(Device* device);
-    void releaseControllerNumberLocked(Device* device);
-    void setLedForController(Device* device);
-
-    status_t mapLed(Device* device, int32_t led, int32_t* outScanCode) const;
-    void setLedStateLocked(Device* device, int32_t led, bool on);
-
-    // Protect all internal state.
-    mutable Mutex mLock;
-
-    // The actual id of the built-in keyboard, or NO_BUILT_IN_KEYBOARD if none.
-    // EventHub remaps the built-in keyboard to id 0 externally as required by the API.
-    enum {
-        // Must not conflict with any other assigned device ids, including
-        // the virtual keyboard id (-1).
-        NO_BUILT_IN_KEYBOARD = -2,
-    };
-    int32_t mBuiltInKeyboardId;
-
-    int32_t mNextDeviceId;
-
-    BitSet32 mControllerNumbers;
-
-    KeyedVector<int32_t, Device*> mDevices;
-
-    Device *mOpeningDevices;
-    Device *mClosingDevices;
-
-    bool mNeedToSendFinishedDeviceScan;
-    bool mNeedToReopenDevices;
-    bool mNeedToScanDevices;
-    Vector<String8> mExcludedDevices;
-
-    int mEpollFd;
-    int mINotifyFd;
-    int mWakeReadPipeFd;
-    int mWakeWritePipeFd;
-
-    // Ids used for epoll notifications not associated with devices.
-    static const uint32_t EPOLL_ID_INOTIFY = 0x80000001;
-    static const uint32_t EPOLL_ID_WAKE = 0x80000002;
-
-    // Epoll FD list size hint.
-    static const int EPOLL_SIZE_HINT = 8;
-
-    // Maximum number of signalled FDs to handle at a time.
-    static const int EPOLL_MAX_EVENTS = 16;
-
-    // The array of pending epoll events and the index of the next event to be handled.
-    struct epoll_event mPendingEventItems[EPOLL_MAX_EVENTS];
-    size_t mPendingEventCount;
-    size_t mPendingEventIndex;
-    bool mPendingINotify;
-};
-
-}; // namespace android
-
-#endif // _RUNTIME_EVENT_HUB_H
diff --git a/libs/input/InputApplication.cpp b/libs/input/InputApplication.cpp
deleted file mode 100644
index a99e637..0000000
--- a/libs/input/InputApplication.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputApplication"
-
-#include "InputApplication.h"
-
-#include <cutils/log.h>
-
-namespace android {
-
-// --- InputApplicationHandle ---
-
-InputApplicationHandle::InputApplicationHandle() :
-    mInfo(NULL) {
-}
-
-InputApplicationHandle::~InputApplicationHandle() {
-    delete mInfo;
-}
-
-void InputApplicationHandle::releaseInfo() {
-    if (mInfo) {
-        delete mInfo;
-        mInfo = NULL;
-    }
-}
-
-} // namespace android
diff --git a/libs/input/InputApplication.h b/libs/input/InputApplication.h
deleted file mode 100644
index 1f5504c..0000000
--- a/libs/input/InputApplication.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_APPLICATION_H
-#define _UI_INPUT_APPLICATION_H
-
-#include <input/Input.h>
-
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-#include <utils/String8.h>
-
-namespace android {
-
-/*
- * Describes the properties of an application that can receive input.
- */
-struct InputApplicationInfo {
-    String8 name;
-    nsecs_t dispatchingTimeout;
-};
-
-
-/*
- * Handle for an application that can receive input.
- *
- * Used by the native input dispatcher as a handle for the window manager objects
- * that describe an application.
- */
-class InputApplicationHandle : public RefBase {
-public:
-    inline const InputApplicationInfo* getInfo() const {
-        return mInfo;
-    }
-
-    inline String8 getName() const {
-        return mInfo ? mInfo->name : String8("<invalid>");
-    }
-
-    inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
-        return mInfo ? mInfo->dispatchingTimeout : defaultValue;
-    }
-
-    /**
-     * Requests that the state of this object be updated to reflect
-     * the most current available information about the application.
-     *
-     * This method should only be called from within the input dispatcher's
-     * critical section.
-     *
-     * Returns true on success, or false if the handle is no longer valid.
-     */
-    virtual bool updateInfo() = 0;
-
-    /**
-     * Releases the storage used by the associated information when it is
-     * no longer needed.
-     */
-    void releaseInfo();
-
-protected:
-    InputApplicationHandle();
-    virtual ~InputApplicationHandle();
-
-    InputApplicationInfo* mInfo;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_APPLICATION_H
diff --git a/libs/input/InputDispatcher.cpp b/libs/input/InputDispatcher.cpp
deleted file mode 100644
index 4d44787..0000000
--- a/libs/input/InputDispatcher.cpp
+++ /dev/null
@@ -1,4510 +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 "InputDispatcher"
-#define ATRACE_TAG ATRACE_TAG_INPUT
-
-//#define LOG_NDEBUG 0
-
-// Log detailed debug messages about each inbound event notification to the dispatcher.
-#define DEBUG_INBOUND_EVENT_DETAILS 0
-
-// Log detailed debug messages about each outbound event processed by the dispatcher.
-#define DEBUG_OUTBOUND_EVENT_DETAILS 0
-
-// Log debug messages about the dispatch cycle.
-#define DEBUG_DISPATCH_CYCLE 0
-
-// Log debug messages about registrations.
-#define DEBUG_REGISTRATION 0
-
-// Log debug messages about input event injection.
-#define DEBUG_INJECTION 0
-
-// Log debug messages about input focus tracking.
-#define DEBUG_FOCUS 0
-
-// Log debug messages about the app switch latency optimization.
-#define DEBUG_APP_SWITCH 0
-
-// Log debug messages about hover events.
-#define DEBUG_HOVER 0
-
-#include "InputDispatcher.h"
-
-#include <utils/Trace.h>
-#include <cutils/log.h>
-#include <androidfw/PowerManager.h>
-
-#include <stddef.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-#include <time.h>
-
-#define INDENT "  "
-#define INDENT2 "    "
-#define INDENT3 "      "
-#define INDENT4 "        "
-
-namespace android {
-
-// Default input dispatching timeout if there is no focused application or paused window
-// from which to determine an appropriate dispatching timeout.
-const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
-
-// Amount of time to allow for all pending events to be processed when an app switch
-// key is on the way.  This is used to preempt input dispatch and drop input events
-// when an application takes too long to respond and the user has pressed an app switch key.
-const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
-
-// Amount of time to allow for an event to be dispatched (measured since its eventTime)
-// before considering it stale and dropping it.
-const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
-
-// Amount of time to allow touch events to be streamed out to a connection before requiring
-// that the first event be finished.  This value extends the ANR timeout by the specified
-// amount.  For example, if streaming is allowed to get ahead by one second relative to the
-// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
-const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
-
-// 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);
-}
-
-static inline const char* toString(bool value) {
-    return value ? "true" : "false";
-}
-
-static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
-    return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
-            >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-}
-
-static bool isValidKeyAction(int32_t action) {
-    switch (action) {
-    case AKEY_EVENT_ACTION_DOWN:
-    case AKEY_EVENT_ACTION_UP:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static bool validateKeyEvent(int32_t action) {
-    if (! isValidKeyAction(action)) {
-        ALOGE("Key event has invalid action code 0x%x", action);
-        return false;
-    }
-    return true;
-}
-
-static bool isValidMotionAction(int32_t action, size_t pointerCount) {
-    switch (action & AMOTION_EVENT_ACTION_MASK) {
-    case AMOTION_EVENT_ACTION_DOWN:
-    case AMOTION_EVENT_ACTION_UP:
-    case AMOTION_EVENT_ACTION_CANCEL:
-    case AMOTION_EVENT_ACTION_MOVE:
-    case AMOTION_EVENT_ACTION_OUTSIDE:
-    case AMOTION_EVENT_ACTION_HOVER_ENTER:
-    case AMOTION_EVENT_ACTION_HOVER_MOVE:
-    case AMOTION_EVENT_ACTION_HOVER_EXIT:
-    case AMOTION_EVENT_ACTION_SCROLL:
-        return true;
-    case AMOTION_EVENT_ACTION_POINTER_DOWN:
-    case AMOTION_EVENT_ACTION_POINTER_UP: {
-        int32_t index = getMotionEventActionPointerIndex(action);
-        return index >= 0 && size_t(index) < pointerCount;
-    }
-    default:
-        return false;
-    }
-}
-
-static bool validateMotionEvent(int32_t action, size_t pointerCount,
-        const PointerProperties* pointerProperties) {
-    if (! isValidMotionAction(action, pointerCount)) {
-        ALOGE("Motion event has invalid action code 0x%x", action);
-        return false;
-    }
-    if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
-        ALOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
-                pointerCount, MAX_POINTERS);
-        return false;
-    }
-    BitSet32 pointerIdBits;
-    for (size_t i = 0; i < pointerCount; i++) {
-        int32_t id = pointerProperties[i].id;
-        if (id < 0 || id > MAX_POINTER_ID) {
-            ALOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
-                    id, MAX_POINTER_ID);
-            return false;
-        }
-        if (pointerIdBits.hasBit(id)) {
-            ALOGE("Motion event has duplicate pointer id %d", id);
-            return false;
-        }
-        pointerIdBits.markBit(id);
-    }
-    return true;
-}
-
-static bool isMainDisplay(int32_t displayId) {
-    return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
-}
-
-static void dumpRegion(String8& dump, const SkRegion& region) {
-    if (region.isEmpty()) {
-        dump.append("<empty>");
-        return;
-    }
-
-    bool first = true;
-    for (SkRegion::Iterator it(region); !it.done(); it.next()) {
-        if (first) {
-            first = false;
-        } else {
-            dump.append("|");
-        }
-        const SkIRect& rect = it.rect();
-        dump.appendFormat("[%d,%d][%d,%d]", rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
-    }
-}
-
-
-// --- InputDispatcher ---
-
-InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
-    mPolicy(policy),
-    mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
-    mNextUnblockedEvent(NULL),
-    mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
-    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
-    mLooper = new Looper(false);
-
-    mKeyRepeatState.lastKeyEntry = NULL;
-
-    policy->getDispatcherConfiguration(&mConfig);
-}
-
-InputDispatcher::~InputDispatcher() {
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        resetKeyRepeatLocked();
-        releasePendingEventLocked();
-        drainInboundQueueLocked();
-    }
-
-    while (mConnectionsByFd.size() != 0) {
-        unregisterInputChannel(mConnectionsByFd.valueAt(0)->inputChannel);
-    }
-}
-
-void InputDispatcher::dispatchOnce() {
-    nsecs_t nextWakeupTime = LONG_LONG_MAX;
-    { // acquire lock
-        AutoMutex _l(mLock);
-        mDispatcherIsAliveCondition.broadcast();
-
-        // Run a dispatch loop if there are no pending commands.
-        // The dispatch loop might enqueue commands to run afterwards.
-        if (!haveCommandsLocked()) {
-            dispatchOnceInnerLocked(&nextWakeupTime);
-        }
-
-        // Run all pending commands if there are any.
-        // If any commands were run then force the next poll to wake up immediately.
-        if (runCommandsLockedInterruptible()) {
-            nextWakeupTime = LONG_LONG_MIN;
-        }
-    } // release lock
-
-    // Wait for callback or timeout or wake.  (make sure we round up, not down)
-    nsecs_t currentTime = now();
-    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
-    mLooper->pollOnce(timeoutMillis);
-}
-
-void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
-    nsecs_t currentTime = now();
-
-    // Reset the key repeat timer whenever we disallow key events, even if the next event
-    // is not a key.  This is to ensure that we abort a key repeat if the device is just coming
-    // out of sleep.
-    if (!mPolicy->isKeyRepeatEnabled()) {
-        resetKeyRepeatLocked();
-    }
-
-    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
-    if (mDispatchFrozen) {
-#if DEBUG_FOCUS
-        ALOGD("Dispatch frozen.  Waiting some more.");
-#endif
-        return;
-    }
-
-    // Optimize latency of app switches.
-    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
-    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
-    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
-    if (mAppSwitchDueTime < *nextWakeupTime) {
-        *nextWakeupTime = mAppSwitchDueTime;
-    }
-
-    // Ready to start a new event.
-    // If we don't already have a pending event, go grab one.
-    if (! mPendingEvent) {
-        if (mInboundQueue.isEmpty()) {
-            if (isAppSwitchDue) {
-                // The inbound queue is empty so the app switch key we were waiting
-                // for will never arrive.  Stop waiting for it.
-                resetPendingAppSwitchLocked(false);
-                isAppSwitchDue = false;
-            }
-
-            // Synthesize a key repeat if appropriate.
-            if (mKeyRepeatState.lastKeyEntry) {
-                if (currentTime >= mKeyRepeatState.nextRepeatTime) {
-                    mPendingEvent = synthesizeKeyRepeatLocked(currentTime);
-                } else {
-                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
-                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
-                    }
-                }
-            }
-
-            // Nothing to do if there is no pending event.
-            if (!mPendingEvent) {
-                return;
-            }
-        } else {
-            // Inbound queue has at least one entry.
-            mPendingEvent = mInboundQueue.dequeueAtHead();
-            traceInboundQueueLengthLocked();
-        }
-
-        // Poke user activity for this event.
-        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
-            pokeUserActivityLocked(mPendingEvent);
-        }
-
-        // Get ready to dispatch the event.
-        resetANRTimeoutsLocked();
-    }
-
-    // Now we have an event to dispatch.
-    // All events are eventually dequeued and processed this way, even if we intend to drop them.
-    ALOG_ASSERT(mPendingEvent != NULL);
-    bool done = false;
-    DropReason dropReason = DROP_REASON_NOT_DROPPED;
-    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
-        dropReason = DROP_REASON_POLICY;
-    } else if (!mDispatchEnabled) {
-        dropReason = DROP_REASON_DISABLED;
-    }
-
-    if (mNextUnblockedEvent == mPendingEvent) {
-        mNextUnblockedEvent = NULL;
-    }
-
-    switch (mPendingEvent->type) {
-    case EventEntry::TYPE_CONFIGURATION_CHANGED: {
-        ConfigurationChangedEntry* typedEntry =
-                static_cast<ConfigurationChangedEntry*>(mPendingEvent);
-        done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
-        dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
-        break;
-    }
-
-    case EventEntry::TYPE_DEVICE_RESET: {
-        DeviceResetEntry* typedEntry =
-                static_cast<DeviceResetEntry*>(mPendingEvent);
-        done = dispatchDeviceResetLocked(currentTime, typedEntry);
-        dropReason = DROP_REASON_NOT_DROPPED; // device resets are never dropped
-        break;
-    }
-
-    case EventEntry::TYPE_KEY: {
-        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
-        if (isAppSwitchDue) {
-            if (isAppSwitchKeyEventLocked(typedEntry)) {
-                resetPendingAppSwitchLocked(true);
-                isAppSwitchDue = false;
-            } else if (dropReason == DROP_REASON_NOT_DROPPED) {
-                dropReason = DROP_REASON_APP_SWITCH;
-            }
-        }
-        if (dropReason == DROP_REASON_NOT_DROPPED
-                && isStaleEventLocked(currentTime, typedEntry)) {
-            dropReason = DROP_REASON_STALE;
-        }
-        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
-            dropReason = DROP_REASON_BLOCKED;
-        }
-        done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
-        break;
-    }
-
-    case EventEntry::TYPE_MOTION: {
-        MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
-        if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
-            dropReason = DROP_REASON_APP_SWITCH;
-        }
-        if (dropReason == DROP_REASON_NOT_DROPPED
-                && isStaleEventLocked(currentTime, typedEntry)) {
-            dropReason = DROP_REASON_STALE;
-        }
-        if (dropReason == DROP_REASON_NOT_DROPPED && mNextUnblockedEvent) {
-            dropReason = DROP_REASON_BLOCKED;
-        }
-        done = dispatchMotionLocked(currentTime, typedEntry,
-                &dropReason, nextWakeupTime);
-        break;
-    }
-
-    default:
-        ALOG_ASSERT(false);
-        break;
-    }
-
-    if (done) {
-        if (dropReason != DROP_REASON_NOT_DROPPED) {
-            dropInboundEventLocked(mPendingEvent, dropReason);
-        }
-
-        releasePendingEventLocked();
-        *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
-    }
-}
-
-bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
-    bool needWake = mInboundQueue.isEmpty();
-    mInboundQueue.enqueueAtTail(entry);
-    traceInboundQueueLengthLocked();
-
-    switch (entry->type) {
-    case EventEntry::TYPE_KEY: {
-        // Optimize app switch latency.
-        // If the application takes too long to catch up then we drop all events preceding
-        // the app switch key.
-        KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
-        if (isAppSwitchKeyEventLocked(keyEntry)) {
-            if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
-                mAppSwitchSawKeyDown = true;
-            } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
-                if (mAppSwitchSawKeyDown) {
-#if DEBUG_APP_SWITCH
-                    ALOGD("App switch is pending!");
-#endif
-                    mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
-                    mAppSwitchSawKeyDown = false;
-                    needWake = true;
-                }
-            }
-        }
-        break;
-    }
-
-    case EventEntry::TYPE_MOTION: {
-        // Optimize case where the current application is unresponsive and the user
-        // decides to touch a window in a different application.
-        // If the application takes too long to catch up then we drop all events preceding
-        // the touch into the other window.
-        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
-        if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN
-                && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
-                && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
-                && mInputTargetWaitApplicationHandle != NULL) {
-            int32_t displayId = motionEntry->displayId;
-            int32_t x = int32_t(motionEntry->pointerCoords[0].
-                    getAxisValue(AMOTION_EVENT_AXIS_X));
-            int32_t y = int32_t(motionEntry->pointerCoords[0].
-                    getAxisValue(AMOTION_EVENT_AXIS_Y));
-            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
-            if (touchedWindowHandle != NULL
-                    && touchedWindowHandle->inputApplicationHandle
-                            != mInputTargetWaitApplicationHandle) {
-                // User touched a different application than the one we are waiting on.
-                // Flag the event, and start pruning the input queue.
-                mNextUnblockedEvent = motionEntry;
-                needWake = true;
-            }
-        }
-        break;
-    }
-    }
-
-    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.
-    size_t numWindows = mWindowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
-        const InputWindowInfo* windowInfo = windowHandle->getInfo();
-        if (windowInfo->displayId == displayId) {
-            int32_t flags = windowInfo->layoutParamsFlags;
-            int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
-
-            if (windowInfo->visible) {
-                if (!(flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
-                    bool isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
-                            | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
-                    if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
-                        // Found window.
-                        return windowHandle;
-                    }
-                }
-            }
-
-            if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
-                // Error window is on top but not visible, so touch is dropped.
-                return NULL;
-            }
-        }
-    }
-    return NULL;
-}
-
-void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
-    const char* reason;
-    switch (dropReason) {
-    case DROP_REASON_POLICY:
-#if DEBUG_INBOUND_EVENT_DETAILS
-        ALOGD("Dropped event because policy consumed it.");
-#endif
-        reason = "inbound event was dropped because the policy consumed it";
-        break;
-    case DROP_REASON_DISABLED:
-        ALOGI("Dropped event because input dispatch is disabled.");
-        reason = "inbound event was dropped because input dispatch is disabled";
-        break;
-    case DROP_REASON_APP_SWITCH:
-        ALOGI("Dropped event because of pending overdue app switch.");
-        reason = "inbound event was dropped because of pending overdue app switch";
-        break;
-    case DROP_REASON_BLOCKED:
-        ALOGI("Dropped event because the current application is not responding and the user "
-                "has started interacting with a different application.");
-        reason = "inbound event was dropped because the current application is not responding "
-                "and the user has started interacting with a different application";
-        break;
-    case DROP_REASON_STALE:
-        ALOGI("Dropped event because it is stale.");
-        reason = "inbound event was dropped because it is stale";
-        break;
-    default:
-        ALOG_ASSERT(false);
-        return;
-    }
-
-    switch (entry->type) {
-    case EventEntry::TYPE_KEY: {
-        CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
-        synthesizeCancelationEventsForAllConnectionsLocked(options);
-        break;
-    }
-    case EventEntry::TYPE_MOTION: {
-        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
-        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
-            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS, reason);
-            synthesizeCancelationEventsForAllConnectionsLocked(options);
-        } else {
-            CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS, reason);
-            synthesizeCancelationEventsForAllConnectionsLocked(options);
-        }
-        break;
-    }
-    }
-}
-
-bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
-    return keyCode == AKEYCODE_HOME
-            || keyCode == AKEYCODE_ENDCALL
-            || keyCode == AKEYCODE_APP_SWITCH;
-}
-
-bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
-    return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
-            && isAppSwitchKeyCode(keyEntry->keyCode)
-            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
-            && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
-}
-
-bool InputDispatcher::isAppSwitchPendingLocked() {
-    return mAppSwitchDueTime != LONG_LONG_MAX;
-}
-
-void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
-    mAppSwitchDueTime = LONG_LONG_MAX;
-
-#if DEBUG_APP_SWITCH
-    if (handled) {
-        ALOGD("App switch has arrived.");
-    } else {
-        ALOGD("App switch was abandoned.");
-    }
-#endif
-}
-
-bool InputDispatcher::isStaleEventLocked(nsecs_t currentTime, EventEntry* entry) {
-    return currentTime - entry->eventTime >= STALE_EVENT_TIMEOUT;
-}
-
-bool InputDispatcher::haveCommandsLocked() const {
-    return !mCommandQueue.isEmpty();
-}
-
-bool InputDispatcher::runCommandsLockedInterruptible() {
-    if (mCommandQueue.isEmpty()) {
-        return false;
-    }
-
-    do {
-        CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
-
-        Command command = commandEntry->command;
-        (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
-
-        commandEntry->connection.clear();
-        delete commandEntry;
-    } while (! mCommandQueue.isEmpty());
-    return true;
-}
-
-InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
-    CommandEntry* commandEntry = new CommandEntry(command);
-    mCommandQueue.enqueueAtTail(commandEntry);
-    return commandEntry;
-}
-
-void InputDispatcher::drainInboundQueueLocked() {
-    while (! mInboundQueue.isEmpty()) {
-        EventEntry* entry = mInboundQueue.dequeueAtHead();
-        releaseInboundEventLocked(entry);
-    }
-    traceInboundQueueLengthLocked();
-}
-
-void InputDispatcher::releasePendingEventLocked() {
-    if (mPendingEvent) {
-        resetANRTimeoutsLocked();
-        releaseInboundEventLocked(mPendingEvent);
-        mPendingEvent = NULL;
-    }
-}
-
-void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
-#if DEBUG_DISPATCH_CYCLE
-        ALOGD("Injected inbound event was dropped.");
-#endif
-        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
-    }
-    if (entry == mNextUnblockedEvent) {
-        mNextUnblockedEvent = NULL;
-    }
-    addRecentEventLocked(entry);
-    entry->release();
-}
-
-void InputDispatcher::resetKeyRepeatLocked() {
-    if (mKeyRepeatState.lastKeyEntry) {
-        mKeyRepeatState.lastKeyEntry->release();
-        mKeyRepeatState.lastKeyEntry = NULL;
-    }
-}
-
-InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(nsecs_t currentTime) {
-    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
-
-    // Reuse the repeated key entry if it is otherwise unreferenced.
-    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
-            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
-    if (entry->refCount == 1) {
-        entry->recycle();
-        entry->eventTime = currentTime;
-        entry->policyFlags = policyFlags;
-        entry->repeatCount += 1;
-    } else {
-        KeyEntry* newEntry = new KeyEntry(currentTime,
-                entry->deviceId, entry->source, policyFlags,
-                entry->action, entry->flags, entry->keyCode, entry->scanCode,
-                entry->metaState, entry->repeatCount + 1, entry->downTime);
-
-        mKeyRepeatState.lastKeyEntry = newEntry;
-        entry->release();
-
-        entry = newEntry;
-    }
-    entry->syntheticRepeat = true;
-
-    // Increment reference count since we keep a reference to the event in
-    // mKeyRepeatState.lastKeyEntry in addition to the one we return.
-    entry->refCount += 1;
-
-    mKeyRepeatState.nextRepeatTime = currentTime + mConfig.keyRepeatDelay;
-    return entry;
-}
-
-bool InputDispatcher::dispatchConfigurationChangedLocked(
-        nsecs_t currentTime, ConfigurationChangedEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-    ALOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
-#endif
-
-    // Reset key repeating in case a keyboard device was added or removed or something.
-    resetKeyRepeatLocked();
-
-    // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doNotifyConfigurationChangedInterruptible);
-    commandEntry->eventTime = entry->eventTime;
-    return true;
-}
-
-bool InputDispatcher::dispatchDeviceResetLocked(
-        nsecs_t currentTime, DeviceResetEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-    ALOGD("dispatchDeviceReset - eventTime=%lld, deviceId=%d", entry->eventTime, entry->deviceId);
-#endif
-
-    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
-            "device was reset");
-    options.deviceId = entry->deviceId;
-    synthesizeCancelationEventsForAllConnectionsLocked(options);
-    return true;
-}
-
-bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, KeyEntry* entry,
-        DropReason* dropReason, nsecs_t* nextWakeupTime) {
-    // Preprocessing.
-    if (! entry->dispatchInProgress) {
-        if (entry->repeatCount == 0
-                && entry->action == AKEY_EVENT_ACTION_DOWN
-                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
-                && (!(entry->policyFlags & POLICY_FLAG_DISABLE_KEY_REPEAT))) {
-            if (mKeyRepeatState.lastKeyEntry
-                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
-                // We have seen two identical key downs in a row which indicates that the device
-                // driver is automatically generating key repeats itself.  We take note of the
-                // repeat here, but we disable our own next key repeat timer since it is clear that
-                // we will not need to synthesize key repeats ourselves.
-                entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
-                resetKeyRepeatLocked();
-                mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
-            } else {
-                // Not a repeat.  Save key down state in case we do see a repeat later.
-                resetKeyRepeatLocked();
-                mKeyRepeatState.nextRepeatTime = entry->eventTime + mConfig.keyRepeatTimeout;
-            }
-            mKeyRepeatState.lastKeyEntry = entry;
-            entry->refCount += 1;
-        } else if (! entry->syntheticRepeat) {
-            resetKeyRepeatLocked();
-        }
-
-        if (entry->repeatCount == 1) {
-            entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
-        } else {
-            entry->flags &= ~AKEY_EVENT_FLAG_LONG_PRESS;
-        }
-
-        entry->dispatchInProgress = true;
-
-        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
-    }
-
-    // Handle case where the policy asked us to try again later last time.
-    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER) {
-        if (currentTime < entry->interceptKeyWakeupTime) {
-            if (entry->interceptKeyWakeupTime < *nextWakeupTime) {
-                *nextWakeupTime = entry->interceptKeyWakeupTime;
-            }
-            return false; // wait until next wakeup
-        }
-        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
-        entry->interceptKeyWakeupTime = 0;
-    }
-
-    // Give the policy a chance to intercept the key.
-    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
-        if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
-            CommandEntry* commandEntry = postCommandLocked(
-                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
-            if (mFocusedWindowHandle != NULL) {
-                commandEntry->inputWindowHandle = mFocusedWindowHandle;
-            }
-            commandEntry->keyEntry = entry;
-            entry->refCount += 1;
-            return false; // wait for the command to run
-        } else {
-            entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
-        }
-    } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
-        if (*dropReason == DROP_REASON_NOT_DROPPED) {
-            *dropReason = DROP_REASON_POLICY;
-        }
-    }
-
-    // Clean up if dropping the event.
-    if (*dropReason != DROP_REASON_NOT_DROPPED) {
-        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
-                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
-        return true;
-    }
-
-    // Identify targets.
-    Vector<InputTarget> inputTargets;
-    int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
-            entry, inputTargets, nextWakeupTime);
-    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
-        return false;
-    }
-
-    setInjectionResultLocked(entry, injectionResult);
-    if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
-        return true;
-    }
-
-    addMonitoringTargetsLocked(inputTargets);
-
-    // Dispatch the key.
-    dispatchEventLocked(currentTime, entry, inputTargets);
-    return true;
-}
-
-void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-    ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
-            "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
-            "repeatCount=%d, downTime=%lld",
-            prefix,
-            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
-            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
-            entry->repeatCount, entry->downTime);
-#endif
-}
-
-bool InputDispatcher::dispatchMotionLocked(
-        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
-    // Preprocessing.
-    if (! entry->dispatchInProgress) {
-        entry->dispatchInProgress = true;
-
-        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
-    }
-
-    // Clean up if dropping the event.
-    if (*dropReason != DROP_REASON_NOT_DROPPED) {
-        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
-                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
-        return true;
-    }
-
-    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
-
-    // Identify targets.
-    Vector<InputTarget> inputTargets;
-
-    bool conflictingPointerActions = false;
-    int32_t injectionResult;
-    if (isPointerEvent) {
-        // Pointer event.  (eg. touchscreen)
-        injectionResult = findTouchedWindowTargetsLocked(currentTime,
-                entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
-    } else {
-        // Non touch event.  (eg. trackball)
-        injectionResult = findFocusedWindowTargetsLocked(currentTime,
-                entry, inputTargets, nextWakeupTime);
-    }
-    if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
-        return false;
-    }
-
-    setInjectionResultLocked(entry, injectionResult);
-    if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
-        return true;
-    }
-
-    // TODO: support sending secondary display events to input monitors
-    if (isMainDisplay(entry->displayId)) {
-        addMonitoringTargetsLocked(inputTargets);
-    }
-
-    // Dispatch the motion.
-    if (conflictingPointerActions) {
-        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
-                "conflicting pointer actions");
-        synthesizeCancelationEventsForAllConnectionsLocked(options);
-    }
-    dispatchEventLocked(currentTime, entry, inputTargets);
-    return true;
-}
-
-
-void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-    ALOGD("%seventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
-            "action=0x%x, flags=0x%x, "
-            "metaState=0x%x, buttonState=0x%x, "
-            "edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
-            prefix,
-            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
-            entry->action, entry->flags,
-            entry->metaState, entry->buttonState,
-            entry->edgeFlags, entry->xPrecision, entry->yPrecision,
-            entry->downTime);
-
-    for (uint32_t i = 0; i < entry->pointerCount; i++) {
-        ALOGD("  Pointer %d: id=%d, toolType=%d, "
-                "x=%f, y=%f, pressure=%f, size=%f, "
-                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
-                "orientation=%f",
-                i, entry->pointerProperties[i].id,
-                entry->pointerProperties[i].toolType,
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
-                entry->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
-    }
-#endif
-}
-
-void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
-        EventEntry* eventEntry, const Vector<InputTarget>& inputTargets) {
-#if DEBUG_DISPATCH_CYCLE
-    ALOGD("dispatchEventToCurrentInputTargets");
-#endif
-
-    ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
-
-    pokeUserActivityLocked(eventEntry);
-
-    for (size_t i = 0; i < inputTargets.size(); i++) {
-        const InputTarget& inputTarget = inputTargets.itemAt(i);
-
-        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
-        if (connectionIndex >= 0) {
-            sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
-            prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
-        } else {
-#if DEBUG_FOCUS
-            ALOGD("Dropping event delivery to target with channel '%s' because it "
-                    "is no longer registered with the input dispatcher.",
-                    inputTarget.inputChannel->getName().string());
-#endif
-        }
-    }
-}
-
-int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
-        const EventEntry* entry,
-        const sp<InputApplicationHandle>& applicationHandle,
-        const sp<InputWindowHandle>& windowHandle,
-        nsecs_t* nextWakeupTime, const char* reason) {
-    if (applicationHandle == NULL && windowHandle == NULL) {
-        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
-#if DEBUG_FOCUS
-            ALOGD("Waiting for system to become ready for input.  Reason: %s", reason);
-#endif
-            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
-            mInputTargetWaitStartTime = currentTime;
-            mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
-            mInputTargetWaitTimeoutExpired = false;
-            mInputTargetWaitApplicationHandle.clear();
-        }
-    } else {
-        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
-#if DEBUG_FOCUS
-            ALOGD("Waiting for application to become ready for input: %s.  Reason: %s",
-                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
-                    reason);
-#endif
-            nsecs_t timeout;
-            if (windowHandle != NULL) {
-                timeout = windowHandle->getDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT);
-            } else if (applicationHandle != NULL) {
-                timeout = applicationHandle->getDispatchingTimeout(
-                        DEFAULT_INPUT_DISPATCHING_TIMEOUT);
-            } else {
-                timeout = DEFAULT_INPUT_DISPATCHING_TIMEOUT;
-            }
-
-            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
-            mInputTargetWaitStartTime = currentTime;
-            mInputTargetWaitTimeoutTime = currentTime + timeout;
-            mInputTargetWaitTimeoutExpired = false;
-            mInputTargetWaitApplicationHandle.clear();
-
-            if (windowHandle != NULL) {
-                mInputTargetWaitApplicationHandle = windowHandle->inputApplicationHandle;
-            }
-            if (mInputTargetWaitApplicationHandle == NULL && applicationHandle != NULL) {
-                mInputTargetWaitApplicationHandle = applicationHandle;
-            }
-        }
-    }
-
-    if (mInputTargetWaitTimeoutExpired) {
-        return INPUT_EVENT_INJECTION_TIMED_OUT;
-    }
-
-    if (currentTime >= mInputTargetWaitTimeoutTime) {
-        onANRLocked(currentTime, applicationHandle, windowHandle,
-                entry->eventTime, mInputTargetWaitStartTime, reason);
-
-        // Force poll loop to wake up immediately on next iteration once we get the
-        // ANR response back from the policy.
-        *nextWakeupTime = LONG_LONG_MIN;
-        return INPUT_EVENT_INJECTION_PENDING;
-    } else {
-        // Force poll loop to wake up when timeout is due.
-        if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
-            *nextWakeupTime = mInputTargetWaitTimeoutTime;
-        }
-        return INPUT_EVENT_INJECTION_PENDING;
-    }
-}
-
-void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
-        const sp<InputChannel>& inputChannel) {
-    if (newTimeout > 0) {
-        // Extend the timeout.
-        mInputTargetWaitTimeoutTime = now() + newTimeout;
-    } else {
-        // Give up.
-        mInputTargetWaitTimeoutExpired = true;
-
-        // Input state will not be realistic.  Mark it out of sync.
-        if (inputChannel.get()) {
-            ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
-            if (connectionIndex >= 0) {
-                sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
-                sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
-
-                if (windowHandle != NULL) {
-                    const InputWindowInfo* info = windowHandle->getInfo();
-                    if (info) {
-                        ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(info->displayId);
-                        if (stateIndex >= 0) {
-                            mTouchStatesByDisplay.editValueAt(stateIndex).removeWindow(
-                                    windowHandle);
-                        }
-                    }
-                }
-
-                if (connection->status == Connection::STATUS_NORMAL) {
-                    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
-                            "application not responding");
-                    synthesizeCancelationEventsForConnectionLocked(connection, options);
-                }
-            }
-        }
-    }
-}
-
-nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
-        nsecs_t currentTime) {
-    if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
-        return currentTime - mInputTargetWaitStartTime;
-    }
-    return 0;
-}
-
-void InputDispatcher::resetANRTimeoutsLocked() {
-#if DEBUG_FOCUS
-        ALOGD("Resetting ANR timeouts.");
-#endif
-
-    // Reset input target wait timeout.
-    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
-    mInputTargetWaitApplicationHandle.clear();
-}
-
-int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
-        const EventEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime) {
-    int32_t injectionResult;
-
-    // If there is no currently focused window and no focused application
-    // then drop the event.
-    if (mFocusedWindowHandle == NULL) {
-        if (mFocusedApplicationHandle != NULL) {
-            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                    mFocusedApplicationHandle, NULL, nextWakeupTime,
-                    "Waiting because no window has focus but there is a "
-                    "focused application that may eventually add a window "
-                    "when it finishes starting up.");
-            goto Unresponsive;
-        }
-
-        ALOGI("Dropping event because there is no focused window or focused application.");
-        injectionResult = INPUT_EVENT_INJECTION_FAILED;
-        goto Failed;
-    }
-
-    // Check permissions.
-    if (! checkInjectionPermission(mFocusedWindowHandle, entry->injectionState)) {
-        injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
-        goto Failed;
-    }
-
-    // If the currently focused window is paused then keep waiting.
-    if (mFocusedWindowHandle->getInfo()->paused) {
-        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
-                "Waiting because the focused window is paused.");
-        goto Unresponsive;
-    }
-
-    // If the currently focused window is still working on previous events then keep waiting.
-    if (!isWindowReadyForMoreInputLocked(currentTime, mFocusedWindowHandle, entry)) {
-        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
-                "Waiting because the focused window has not finished "
-                "processing the input events that were previously delivered to it.");
-        goto Unresponsive;
-    }
-
-    // Success!  Output targets.
-    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-    addWindowTargetLocked(mFocusedWindowHandle,
-            InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS, BitSet32(0),
-            inputTargets);
-
-    // Done.
-Failed:
-Unresponsive:
-    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
-    updateDispatchStatisticsLocked(currentTime, entry,
-            injectionResult, timeSpentWaitingForApplication);
-#if DEBUG_FOCUS
-    ALOGD("findFocusedWindow finished: injectionResult=%d, "
-            "timeSpentWaitingForApplication=%0.1fms",
-            injectionResult, timeSpentWaitingForApplication / 1000000.0);
-#endif
-    return injectionResult;
-}
-
-int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
-        const MotionEntry* entry, Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
-        bool* outConflictingPointerActions) {
-    enum InjectionPermission {
-        INJECTION_PERMISSION_UNKNOWN,
-        INJECTION_PERMISSION_GRANTED,
-        INJECTION_PERMISSION_DENIED
-    };
-
-    nsecs_t startTime = now();
-
-    // For security reasons, we defer updating the touch state until we are sure that
-    // event injection will be allowed.
-    //
-    // FIXME In the original code, screenWasOff could never be set to true.
-    //       The reason is that the POLICY_FLAG_WOKE_HERE
-    //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
-    //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was
-    //       actually enqueued using the policyFlags that appeared in the final EV_SYN
-    //       events upon which no preprocessing took place.  So policyFlags was always 0.
-    //       In the new native input dispatcher we're a bit more careful about event
-    //       preprocessing so the touches we receive can actually have non-zero policyFlags.
-    //       Unfortunately we obtain undesirable behavior.
-    //
-    //       Here's what happens:
-    //
-    //       When the device dims in anticipation of going to sleep, touches
-    //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
-    //       the device to brighten and reset the user activity timer.
-    //       Touches on other windows (such as the launcher window)
-    //       are dropped.  Then after a moment, the device goes to sleep.  Oops.
-    //
-    //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
-    //       instead of POLICY_FLAG_WOKE_HERE...
-    //
-    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
-
-    int32_t displayId = entry->displayId;
-    int32_t action = entry->action;
-    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
-
-    // Update the touch state as needed based on the properties of the touch event.
-    int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
-    InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
-    sp<InputWindowHandle> newHoverWindowHandle;
-
-    // Copy current touch state into mTempTouchState.
-    // This state is always reset at the end of this function, so if we don't find state
-    // for the specified display then our initial state will be empty.
-    const TouchState* oldState = NULL;
-    ssize_t oldStateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
-    if (oldStateIndex >= 0) {
-        oldState = &mTouchStatesByDisplay.valueAt(oldStateIndex);
-        mTempTouchState.copyFrom(*oldState);
-    }
-
-    bool isSplit = mTempTouchState.split;
-    bool switchedDevice = mTempTouchState.deviceId >= 0 && mTempTouchState.displayId >= 0
-            && (mTempTouchState.deviceId != entry->deviceId
-                    || mTempTouchState.source != entry->source
-                    || mTempTouchState.displayId != displayId);
-    bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
-            || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
-            || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
-    bool newGesture = (maskedAction == AMOTION_EVENT_ACTION_DOWN
-            || maskedAction == AMOTION_EVENT_ACTION_SCROLL
-            || isHoverAction);
-    bool wrongDevice = false;
-    if (newGesture) {
-        bool down = maskedAction == AMOTION_EVENT_ACTION_DOWN;
-        if (switchedDevice && mTempTouchState.down && !down) {
-#if DEBUG_FOCUS
-            ALOGD("Dropping event because a pointer for a different device is already down.");
-#endif
-            injectionResult = INPUT_EVENT_INJECTION_FAILED;
-            switchedDevice = false;
-            wrongDevice = true;
-            goto Failed;
-        }
-        mTempTouchState.reset();
-        mTempTouchState.down = down;
-        mTempTouchState.deviceId = entry->deviceId;
-        mTempTouchState.source = entry->source;
-        mTempTouchState.displayId = displayId;
-        isSplit = false;
-    }
-
-    if (newGesture || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
-        /* Case 1: New splittable pointer going down, or need target for hover or scroll. */
-
-        int32_t pointerIndex = getMotionEventActionPointerIndex(action);
-        int32_t x = int32_t(entry->pointerCoords[pointerIndex].
-                getAxisValue(AMOTION_EVENT_AXIS_X));
-        int32_t y = int32_t(entry->pointerCoords[pointerIndex].
-                getAxisValue(AMOTION_EVENT_AXIS_Y));
-        sp<InputWindowHandle> newTouchedWindowHandle;
-        sp<InputWindowHandle> topErrorWindowHandle;
-        bool isTouchModal = false;
-
-        // Traverse windows from front to back to find touched window and outside targets.
-        size_t numWindows = mWindowHandles.size();
-        for (size_t i = 0; i < numWindows; i++) {
-            sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
-            const InputWindowInfo* windowInfo = windowHandle->getInfo();
-            if (windowInfo->displayId != displayId) {
-                continue; // wrong display
-            }
-
-            int32_t privateFlags = windowInfo->layoutParamsPrivateFlags;
-            if (privateFlags & InputWindowInfo::PRIVATE_FLAG_SYSTEM_ERROR) {
-                if (topErrorWindowHandle == NULL) {
-                    topErrorWindowHandle = windowHandle;
-                }
-            }
-
-            int32_t flags = windowInfo->layoutParamsFlags;
-            if (windowInfo->visible) {
-                if (! (flags & InputWindowInfo::FLAG_NOT_TOUCHABLE)) {
-                    isTouchModal = (flags & (InputWindowInfo::FLAG_NOT_FOCUSABLE
-                            | InputWindowInfo::FLAG_NOT_TOUCH_MODAL)) == 0;
-                    if (isTouchModal || windowInfo->touchableRegionContainsPoint(x, y)) {
-                        if (! screenWasOff
-                                || (flags & InputWindowInfo::FLAG_TOUCHABLE_WHEN_WAKING)) {
-                            newTouchedWindowHandle = windowHandle;
-                        }
-                        break; // found touched window, exit window loop
-                    }
-                }
-
-                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
-                        && (flags & InputWindowInfo::FLAG_WATCH_OUTSIDE_TOUCH)) {
-                    int32_t outsideTargetFlags = InputTarget::FLAG_DISPATCH_AS_OUTSIDE;
-                    if (isWindowObscuredAtPointLocked(windowHandle, x, y)) {
-                        outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
-                    }
-
-                    mTempTouchState.addOrUpdateWindow(
-                            windowHandle, outsideTargetFlags, BitSet32(0));
-                }
-            }
-        }
-
-        // If there is an error window but it is not taking focus (typically because
-        // it is invisible) then wait for it.  Any other focused window may in
-        // fact be in ANR state.
-        if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
-            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                    NULL, NULL, nextWakeupTime,
-                    "Waiting because a system error window is about to be displayed.");
-            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
-            goto Unresponsive;
-        }
-
-        // Figure out whether splitting will be allowed for this window.
-        if (newTouchedWindowHandle != NULL
-                && newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
-            // New window supports splitting.
-            isSplit = true;
-        } else if (isSplit) {
-            // New window does not support splitting but we have already split events.
-            // Ignore the new window.
-            newTouchedWindowHandle = NULL;
-        }
-
-        // Handle the case where we did not find a window.
-        if (newTouchedWindowHandle == NULL) {
-            // Try to assign the pointer to the first foreground window we find, if there is one.
-            newTouchedWindowHandle = mTempTouchState.getFirstForegroundWindowHandle();
-            if (newTouchedWindowHandle == NULL) {
-                ALOGI("Dropping event because there is no touchable window at (%d, %d).", x, y);
-                injectionResult = INPUT_EVENT_INJECTION_FAILED;
-                goto Failed;
-            }
-        }
-
-        // Set target flags.
-        int32_t targetFlags = InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_DISPATCH_AS_IS;
-        if (isSplit) {
-            targetFlags |= InputTarget::FLAG_SPLIT;
-        }
-        if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
-            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
-        }
-
-        // Update hover state.
-        if (isHoverAction) {
-            newHoverWindowHandle = newTouchedWindowHandle;
-        } else if (maskedAction == AMOTION_EVENT_ACTION_SCROLL) {
-            newHoverWindowHandle = mLastHoverWindowHandle;
-        }
-
-        // Update the temporary touch state.
-        BitSet32 pointerIds;
-        if (isSplit) {
-            uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
-            pointerIds.markBit(pointerId);
-        }
-        mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
-    } else {
-        /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
-
-        // If the pointer is not currently down, then ignore the event.
-        if (! mTempTouchState.down) {
-#if DEBUG_FOCUS
-            ALOGD("Dropping event because the pointer is not down or we previously "
-                    "dropped the pointer down event.");
-#endif
-            injectionResult = INPUT_EVENT_INJECTION_FAILED;
-            goto Failed;
-        }
-
-        // Check whether touches should slip outside of the current foreground window.
-        if (maskedAction == AMOTION_EVENT_ACTION_MOVE
-                && entry->pointerCount == 1
-                && mTempTouchState.isSlippery()) {
-            int32_t x = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
-            int32_t y = int32_t(entry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
-
-            sp<InputWindowHandle> oldTouchedWindowHandle =
-                    mTempTouchState.getFirstForegroundWindowHandle();
-            sp<InputWindowHandle> newTouchedWindowHandle =
-                    findTouchedWindowAtLocked(displayId, x, y);
-            if (oldTouchedWindowHandle != newTouchedWindowHandle
-                    && newTouchedWindowHandle != NULL) {
-#if DEBUG_FOCUS
-                ALOGD("Touch is slipping out of window %s into window %s.",
-                        oldTouchedWindowHandle->getName().string(),
-                        newTouchedWindowHandle->getName().string());
-#endif
-                // Make a slippery exit from the old window.
-                mTempTouchState.addOrUpdateWindow(oldTouchedWindowHandle,
-                        InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT, BitSet32(0));
-
-                // Make a slippery entrance into the new window.
-                if (newTouchedWindowHandle->getInfo()->supportsSplitTouch()) {
-                    isSplit = true;
-                }
-
-                int32_t targetFlags = InputTarget::FLAG_FOREGROUND
-                        | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER;
-                if (isSplit) {
-                    targetFlags |= InputTarget::FLAG_SPLIT;
-                }
-                if (isWindowObscuredAtPointLocked(newTouchedWindowHandle, x, y)) {
-                    targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
-                }
-
-                BitSet32 pointerIds;
-                if (isSplit) {
-                    pointerIds.markBit(entry->pointerProperties[0].id);
-                }
-                mTempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds);
-            }
-        }
-    }
-
-    if (newHoverWindowHandle != mLastHoverWindowHandle) {
-        // Let the previous window know that the hover sequence is over.
-        if (mLastHoverWindowHandle != NULL) {
-#if DEBUG_HOVER
-            ALOGD("Sending hover exit event to window %s.",
-                    mLastHoverWindowHandle->getName().string());
-#endif
-            mTempTouchState.addOrUpdateWindow(mLastHoverWindowHandle,
-                    InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT, BitSet32(0));
-        }
-
-        // Let the new window know that the hover sequence is starting.
-        if (newHoverWindowHandle != NULL) {
-#if DEBUG_HOVER
-            ALOGD("Sending hover enter event to window %s.",
-                    newHoverWindowHandle->getName().string());
-#endif
-            mTempTouchState.addOrUpdateWindow(newHoverWindowHandle,
-                    InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER, BitSet32(0));
-        }
-    }
-
-    // Check permission to inject into all touched foreground windows and ensure there
-    // is at least one touched foreground window.
-    {
-        bool haveForegroundWindow = false;
-        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
-            if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
-                haveForegroundWindow = true;
-                if (! checkInjectionPermission(touchedWindow.windowHandle,
-                        entry->injectionState)) {
-                    injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
-                    injectionPermission = INJECTION_PERMISSION_DENIED;
-                    goto Failed;
-                }
-            }
-        }
-        if (! haveForegroundWindow) {
-#if DEBUG_FOCUS
-            ALOGD("Dropping event because there is no touched foreground window to receive it.");
-#endif
-            injectionResult = INPUT_EVENT_INJECTION_FAILED;
-            goto Failed;
-        }
-
-        // Permission granted to injection into all touched foreground windows.
-        injectionPermission = INJECTION_PERMISSION_GRANTED;
-    }
-
-    // Check whether windows listening for outside touches are owned by the same UID. If it is
-    // set the policy flag that we will not reveal coordinate information to this window.
-    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        sp<InputWindowHandle> foregroundWindowHandle =
-                mTempTouchState.getFirstForegroundWindowHandle();
-        const int32_t foregroundWindowUid = foregroundWindowHandle->getInfo()->ownerUid;
-        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
-            if (touchedWindow.targetFlags & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
-                sp<InputWindowHandle> inputWindowHandle = touchedWindow.windowHandle;
-                if (inputWindowHandle->getInfo()->ownerUid != foregroundWindowUid) {
-                    mTempTouchState.addOrUpdateWindow(inputWindowHandle,
-                            InputTarget::FLAG_ZERO_COORDS, BitSet32(0));
-                }
-            }
-        }
-    }
-
-    // Ensure all touched foreground windows are ready for new input.
-    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-        const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
-        if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
-            // If the touched window is paused then keep waiting.
-            if (touchedWindow.windowHandle->getInfo()->paused) {
-                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        NULL, touchedWindow.windowHandle, nextWakeupTime,
-                        "Waiting because the touched window is paused.");
-                goto Unresponsive;
-            }
-
-            // If the touched window is still working on previous events then keep waiting.
-            if (!isWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry)) {
-                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
-                        NULL, touchedWindow.windowHandle, nextWakeupTime,
-                        "Waiting because the touched window has not finished "
-                        "processing the input events that were previously delivered to it.");
-                goto Unresponsive;
-            }
-        }
-    }
-
-    // If this is the first pointer going down and the touched window has a wallpaper
-    // then also add the touched wallpaper windows so they are locked in for the duration
-    // of the touch gesture.
-    // We do not collect wallpapers during HOVER_MOVE or SCROLL because the wallpaper
-    // engine only supports touch events.  We would need to add a mechanism similar
-    // to View.onGenericMotionEvent to enable wallpapers to handle these events.
-    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-        sp<InputWindowHandle> foregroundWindowHandle =
-                mTempTouchState.getFirstForegroundWindowHandle();
-        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
-            for (size_t i = 0; i < mWindowHandles.size(); i++) {
-                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
-                const InputWindowInfo* info = windowHandle->getInfo();
-                if (info->displayId == displayId
-                        && windowHandle->getInfo()->layoutParamsType
-                                == InputWindowInfo::TYPE_WALLPAPER) {
-                    mTempTouchState.addOrUpdateWindow(windowHandle,
-                            InputTarget::FLAG_WINDOW_IS_OBSCURED
-                                    | InputTarget::FLAG_DISPATCH_AS_IS,
-                            BitSet32(0));
-                }
-            }
-        }
-    }
-
-    // Success!  Output targets.
-    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-
-    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
-        const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
-        addWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.targetFlags,
-                touchedWindow.pointerIds, inputTargets);
-    }
-
-    // Drop the outside or hover touch windows since we will not care about them
-    // in the next iteration.
-    mTempTouchState.filterNonAsIsTouchWindows();
-
-Failed:
-    // Check injection permission once and for all.
-    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
-        if (checkInjectionPermission(NULL, entry->injectionState)) {
-            injectionPermission = INJECTION_PERMISSION_GRANTED;
-        } else {
-            injectionPermission = INJECTION_PERMISSION_DENIED;
-        }
-    }
-
-    // Update final pieces of touch state if the injector had permission.
-    if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
-        if (!wrongDevice) {
-            if (switchedDevice) {
-#if DEBUG_FOCUS
-                ALOGD("Conflicting pointer actions: Switched to a different device.");
-#endif
-                *outConflictingPointerActions = true;
-            }
-
-            if (isHoverAction) {
-                // Started hovering, therefore no longer down.
-                if (oldState && oldState->down) {
-#if DEBUG_FOCUS
-                    ALOGD("Conflicting pointer actions: Hover received while pointer was down.");
-#endif
-                    *outConflictingPointerActions = true;
-                }
-                mTempTouchState.reset();
-                if (maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
-                        || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
-                    mTempTouchState.deviceId = entry->deviceId;
-                    mTempTouchState.source = entry->source;
-                    mTempTouchState.displayId = displayId;
-                }
-            } else if (maskedAction == AMOTION_EVENT_ACTION_UP
-                    || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
-                // All pointers up or canceled.
-                mTempTouchState.reset();
-            } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
-                // First pointer went down.
-                if (oldState && oldState->down) {
-#if DEBUG_FOCUS
-                    ALOGD("Conflicting pointer actions: Down received while already down.");
-#endif
-                    *outConflictingPointerActions = true;
-                }
-            } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
-                // One pointer went up.
-                if (isSplit) {
-                    int32_t pointerIndex = getMotionEventActionPointerIndex(action);
-                    uint32_t pointerId = entry->pointerProperties[pointerIndex].id;
-
-                    for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
-                        TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
-                        if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
-                            touchedWindow.pointerIds.clearBit(pointerId);
-                            if (touchedWindow.pointerIds.isEmpty()) {
-                                mTempTouchState.windows.removeAt(i);
-                                continue;
-                            }
-                        }
-                        i += 1;
-                    }
-                }
-            }
-
-            // Save changes unless the action was scroll in which case the temporary touch
-            // state was only valid for this one action.
-            if (maskedAction != AMOTION_EVENT_ACTION_SCROLL) {
-                if (mTempTouchState.displayId >= 0) {
-                    if (oldStateIndex >= 0) {
-                        mTouchStatesByDisplay.editValueAt(oldStateIndex).copyFrom(mTempTouchState);
-                    } else {
-                        mTouchStatesByDisplay.add(displayId, mTempTouchState);
-                    }
-                } else if (oldStateIndex >= 0) {
-                    mTouchStatesByDisplay.removeItemsAt(oldStateIndex);
-                }
-            }
-
-            // Update hover state.
-            mLastHoverWindowHandle = newHoverWindowHandle;
-        }
-    } else {
-#if DEBUG_FOCUS
-        ALOGD("Not updating touch focus because injection was denied.");
-#endif
-    }
-
-Unresponsive:
-    // Reset temporary touch state to ensure we release unnecessary references to input channels.
-    mTempTouchState.reset();
-
-    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
-    updateDispatchStatisticsLocked(currentTime, entry,
-            injectionResult, timeSpentWaitingForApplication);
-#if DEBUG_FOCUS
-    ALOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
-            "timeSpentWaitingForApplication=%0.1fms",
-            injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
-#endif
-    return injectionResult;
-}
-
-void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
-        int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets) {
-    inputTargets.push();
-
-    const InputWindowInfo* windowInfo = windowHandle->getInfo();
-    InputTarget& target = inputTargets.editTop();
-    target.inputChannel = windowInfo->inputChannel;
-    target.flags = targetFlags;
-    target.xOffset = - windowInfo->frameLeft;
-    target.yOffset = - windowInfo->frameTop;
-    target.scaleFactor = windowInfo->scaleFactor;
-    target.pointerIds = pointerIds;
-}
-
-void InputDispatcher::addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets) {
-    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
-        inputTargets.push();
-
-        InputTarget& target = inputTargets.editTop();
-        target.inputChannel = mMonitoringChannels[i];
-        target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
-        target.xOffset = 0;
-        target.yOffset = 0;
-        target.pointerIds.clear();
-        target.scaleFactor = 1.0f;
-    }
-}
-
-bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
-        const InjectionState* injectionState) {
-    if (injectionState
-            && (windowHandle == NULL
-                    || windowHandle->getInfo()->ownerUid != injectionState->injectorUid)
-            && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
-        if (windowHandle != NULL) {
-            ALOGW("Permission denied: injecting event from pid %d uid %d to window %s "
-                    "owned by uid %d",
-                    injectionState->injectorPid, injectionState->injectorUid,
-                    windowHandle->getName().string(),
-                    windowHandle->getInfo()->ownerUid);
-        } else {
-            ALOGW("Permission denied: injecting event from pid %d uid %d",
-                    injectionState->injectorPid, injectionState->injectorUid);
-        }
-        return false;
-    }
-    return true;
-}
-
-bool InputDispatcher::isWindowObscuredAtPointLocked(
-        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
-    int32_t displayId = windowHandle->getInfo()->displayId;
-    size_t numWindows = mWindowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
-        if (otherHandle == windowHandle) {
-            break;
-        }
-
-        const InputWindowInfo* otherInfo = otherHandle->getInfo();
-        if (otherInfo->displayId == displayId
-                && otherInfo->visible && !otherInfo->isTrustedOverlay()
-                && otherInfo->frameContainsPoint(x, y)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool InputDispatcher::isWindowReadyForMoreInputLocked(nsecs_t currentTime,
-        const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry) {
-    ssize_t connectionIndex = getConnectionIndexLocked(windowHandle->getInputChannel());
-    if (connectionIndex >= 0) {
-        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
-        if (connection->inputPublisherBlocked) {
-            return false;
-        }
-        if (eventEntry->type == EventEntry::TYPE_KEY) {
-            // If the event is a key event, then we must wait for all previous events to
-            // complete before delivering it because previous events may have the
-            // side-effect of transferring focus to a different window and we want to
-            // ensure that the following keys are sent to the new window.
-            //
-            // Suppose the user touches a button in a window then immediately presses "A".
-            // If the button causes a pop-up window to appear then we want to ensure that
-            // the "A" key is delivered to the new pop-up window.  This is because users
-            // often anticipate pending UI changes when typing on a keyboard.
-            // To obtain this behavior, we must serialize key events with respect to all
-            // prior input events.
-            return connection->outboundQueue.isEmpty()
-                    && connection->waitQueue.isEmpty();
-        }
-        // Touch events can always be sent to a window immediately because the user intended
-        // to touch whatever was visible at the time.  Even if focus changes or a new
-        // window appears moments later, the touch event was meant to be delivered to
-        // whatever window happened to be on screen at the time.
-        //
-        // Generic motion events, such as trackball or joystick events are a little trickier.
-        // Like key events, generic motion events are delivered to the focused window.
-        // Unlike key events, generic motion events don't tend to transfer focus to other
-        // windows and it is not important for them to be serialized.  So we prefer to deliver
-        // generic motion events as soon as possible to improve efficiency and reduce lag
-        // through batching.
-        //
-        // The one case where we pause input event delivery is when the wait queue is piling
-        // up with lots of events because the application is not responding.
-        // This condition ensures that ANRs are detected reliably.
-        if (!connection->waitQueue.isEmpty()
-                && currentTime >= connection->waitQueue.head->deliveryTime
-                        + STREAM_AHEAD_EVENT_TIMEOUT) {
-            return false;
-        }
-    }
-    return true;
-}
-
-String8 InputDispatcher::getApplicationWindowLabelLocked(
-        const sp<InputApplicationHandle>& applicationHandle,
-        const sp<InputWindowHandle>& windowHandle) {
-    if (applicationHandle != NULL) {
-        if (windowHandle != NULL) {
-            String8 label(applicationHandle->getName());
-            label.append(" - ");
-            label.append(windowHandle->getName());
-            return label;
-        } else {
-            return applicationHandle->getName();
-        }
-    } else if (windowHandle != NULL) {
-        return windowHandle->getName();
-    } else {
-        return String8("<unknown application or window>");
-    }
-}
-
-void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
-    if (mFocusedWindowHandle != NULL) {
-        const InputWindowInfo* info = mFocusedWindowHandle->getInfo();
-        if (info->inputFeatures & InputWindowInfo::INPUT_FEATURE_DISABLE_USER_ACTIVITY) {
-#if DEBUG_DISPATCH_CYCLE
-            ALOGD("Not poking user activity: disabled by window '%s'.", info->name.string());
-#endif
-            return;
-        }
-    }
-
-    int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
-    switch (eventEntry->type) {
-    case EventEntry::TYPE_MOTION: {
-        const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
-        if (motionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
-            return;
-        }
-
-        if (MotionEvent::isTouchEvent(motionEntry->source, motionEntry->action)) {
-            eventType = USER_ACTIVITY_EVENT_TOUCH;
-        }
-        break;
-    }
-    case EventEntry::TYPE_KEY: {
-        const KeyEntry* keyEntry = static_cast<const KeyEntry*>(eventEntry);
-        if (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED) {
-            return;
-        }
-        eventType = USER_ACTIVITY_EVENT_BUTTON;
-        break;
-    }
-    }
-
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doPokeUserActivityLockedInterruptible);
-    commandEntry->eventTime = eventEntry->eventTime;
-    commandEntry->userActivityEventType = eventType;
-}
-
-void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
-#if DEBUG_DISPATCH_CYCLE
-    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
-            "xOffset=%f, yOffset=%f, scaleFactor=%f, "
-            "pointerIds=0x%x",
-            connection->getInputChannelName(), inputTarget->flags,
-            inputTarget->xOffset, inputTarget->yOffset,
-            inputTarget->scaleFactor, inputTarget->pointerIds.value);
-#endif
-
-    // Skip this event if the connection status is not normal.
-    // We don't want to enqueue additional outbound events if the connection is broken.
-    if (connection->status != Connection::STATUS_NORMAL) {
-#if DEBUG_DISPATCH_CYCLE
-        ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
-                connection->getInputChannelName(), connection->getStatusLabel());
-#endif
-        return;
-    }
-
-    // Split a motion event if needed.
-    if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
-        ALOG_ASSERT(eventEntry->type == EventEntry::TYPE_MOTION);
-
-        MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
-        if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
-            MotionEntry* splitMotionEntry = splitMotionEvent(
-                    originalMotionEntry, inputTarget->pointerIds);
-            if (!splitMotionEntry) {
-                return; // split event was dropped
-            }
-#if DEBUG_FOCUS
-            ALOGD("channel '%s' ~ Split motion event.",
-                    connection->getInputChannelName());
-            logOutboundMotionDetailsLocked("  ", splitMotionEntry);
-#endif
-            enqueueDispatchEntriesLocked(currentTime, connection,
-                    splitMotionEntry, inputTarget);
-            splitMotionEntry->release();
-            return;
-        }
-    }
-
-    // Not splitting.  Enqueue dispatch entries for the event as is.
-    enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
-}
-
-void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
-        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget) {
-    bool wasEmpty = connection->outboundQueue.isEmpty();
-
-    // Enqueue dispatch entries for the requested modes.
-    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
-            InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);
-    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
-            InputTarget::FLAG_DISPATCH_AS_OUTSIDE);
-    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
-            InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);
-    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
-            InputTarget::FLAG_DISPATCH_AS_IS);
-    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
-            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);
-    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
-            InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);
-
-    // If the outbound queue was previously empty, start the dispatch cycle going.
-    if (wasEmpty && !connection->outboundQueue.isEmpty()) {
-        startDispatchCycleLocked(currentTime, connection);
-    }
-}
-
-void InputDispatcher::enqueueDispatchEntryLocked(
-        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
-        int32_t dispatchMode) {
-    int32_t inputTargetFlags = inputTarget->flags;
-    if (!(inputTargetFlags & dispatchMode)) {
-        return;
-    }
-    inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;
-
-    // This is a new event.
-    // Enqueue a new dispatch entry onto the outbound queue for this connection.
-    DispatchEntry* dispatchEntry = new DispatchEntry(eventEntry, // increments ref
-            inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
-            inputTarget->scaleFactor);
-
-    // Apply target flags and update the connection's input state.
-    switch (eventEntry->type) {
-    case EventEntry::TYPE_KEY: {
-        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
-        dispatchEntry->resolvedAction = keyEntry->action;
-        dispatchEntry->resolvedFlags = keyEntry->flags;
-
-        if (!connection->inputState.trackKey(keyEntry,
-                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
-#if DEBUG_DISPATCH_CYCLE
-            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
-                    connection->getInputChannelName());
-#endif
-            delete dispatchEntry;
-            return; // skip the inconsistent event
-        }
-        break;
-    }
-
-    case EventEntry::TYPE_MOTION: {
-        MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
-        if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
-            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
-        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
-            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
-        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
-            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
-        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
-            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
-        } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
-            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
-        } else {
-            dispatchEntry->resolvedAction = motionEntry->action;
-        }
-        if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
-                && !connection->inputState.isHovering(
-                        motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
-#if DEBUG_DISPATCH_CYCLE
-        ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
-                connection->getInputChannelName());
-#endif
-            dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
-        }
-
-        dispatchEntry->resolvedFlags = motionEntry->flags;
-        if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
-            dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
-        }
-
-        if (!connection->inputState.trackMotion(motionEntry,
-                dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags)) {
-#if DEBUG_DISPATCH_CYCLE
-            ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent motion event",
-                    connection->getInputChannelName());
-#endif
-            delete dispatchEntry;
-            return; // skip the inconsistent event
-        }
-        break;
-    }
-    }
-
-    // Remember that we are waiting for this dispatch to complete.
-    if (dispatchEntry->hasForegroundTarget()) {
-        incrementPendingForegroundDispatchesLocked(eventEntry);
-    }
-
-    // Enqueue the dispatch entry.
-    connection->outboundQueue.enqueueAtTail(dispatchEntry);
-    traceOutboundQueueLengthLocked(connection);
-}
-
-void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection) {
-#if DEBUG_DISPATCH_CYCLE
-    ALOGD("channel '%s' ~ startDispatchCycle",
-            connection->getInputChannelName());
-#endif
-
-    while (connection->status == Connection::STATUS_NORMAL
-            && !connection->outboundQueue.isEmpty()) {
-        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
-        dispatchEntry->deliveryTime = currentTime;
-
-        // Publish the event.
-        status_t status;
-        EventEntry* eventEntry = dispatchEntry->eventEntry;
-        switch (eventEntry->type) {
-        case EventEntry::TYPE_KEY: {
-            KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
-
-            // Publish the key event.
-            status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
-                    keyEntry->deviceId, keyEntry->source,
-                    dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
-                    keyEntry->keyCode, keyEntry->scanCode,
-                    keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
-                    keyEntry->eventTime);
-            break;
-        }
-
-        case EventEntry::TYPE_MOTION: {
-            MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
-
-            PointerCoords scaledCoords[MAX_POINTERS];
-            const PointerCoords* usingCoords = motionEntry->pointerCoords;
-
-            // Set the X and Y offset depending on the input source.
-            float xOffset, yOffset, scaleFactor;
-            if ((motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
-                    && !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {
-                scaleFactor = dispatchEntry->scaleFactor;
-                xOffset = dispatchEntry->xOffset * scaleFactor;
-                yOffset = dispatchEntry->yOffset * scaleFactor;
-                if (scaleFactor != 1.0f) {
-                    for (size_t i = 0; i < motionEntry->pointerCount; i++) {
-                        scaledCoords[i] = motionEntry->pointerCoords[i];
-                        scaledCoords[i].scale(scaleFactor);
-                    }
-                    usingCoords = scaledCoords;
-                }
-            } else {
-                xOffset = 0.0f;
-                yOffset = 0.0f;
-                scaleFactor = 1.0f;
-
-                // We don't want the dispatch target to know.
-                if (dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS) {
-                    for (size_t i = 0; i < motionEntry->pointerCount; i++) {
-                        scaledCoords[i].clear();
-                    }
-                    usingCoords = scaledCoords;
-                }
-            }
-
-            // Publish the motion event.
-            status = connection->inputPublisher.publishMotionEvent(dispatchEntry->seq,
-                    motionEntry->deviceId, motionEntry->source,
-                    dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
-                    motionEntry->edgeFlags, motionEntry->metaState, motionEntry->buttonState,
-                    xOffset, yOffset,
-                    motionEntry->xPrecision, motionEntry->yPrecision,
-                    motionEntry->downTime, motionEntry->eventTime,
-                    motionEntry->pointerCount, motionEntry->pointerProperties,
-                    usingCoords);
-            break;
-        }
-
-        default:
-            ALOG_ASSERT(false);
-            return;
-        }
-
-        // Check the result.
-        if (status) {
-            if (status == WOULD_BLOCK) {
-                if (connection->waitQueue.isEmpty()) {
-                    ALOGE("channel '%s' ~ Could not publish event because the pipe is full. "
-                            "This is unexpected because the wait queue is empty, so the pipe "
-                            "should be empty and we shouldn't have any problems writing an "
-                            "event to it, status=%d", connection->getInputChannelName(), status);
-                    abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
-                } else {
-                    // Pipe is full and we are waiting for the app to finish process some events
-                    // before sending more events to it.
-#if DEBUG_DISPATCH_CYCLE
-                    ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
-                            "waiting for the application to catch up",
-                            connection->getInputChannelName());
-#endif
-                    connection->inputPublisherBlocked = true;
-                }
-            } else {
-                ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
-                        "status=%d", connection->getInputChannelName(), status);
-                abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
-            }
-            return;
-        }
-
-        // Re-enqueue the event on the wait queue.
-        connection->outboundQueue.dequeue(dispatchEntry);
-        traceOutboundQueueLengthLocked(connection);
-        connection->waitQueue.enqueueAtTail(dispatchEntry);
-        traceWaitQueueLengthLocked(connection);
-    }
-}
-
-void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection, uint32_t seq, bool handled) {
-#if DEBUG_DISPATCH_CYCLE
-    ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
-            connection->getInputChannelName(), seq, toString(handled));
-#endif
-
-    connection->inputPublisherBlocked = false;
-
-    if (connection->status == Connection::STATUS_BROKEN
-            || connection->status == Connection::STATUS_ZOMBIE) {
-        return;
-    }
-
-    // Notify other system components and prepare to start the next dispatch cycle.
-    onDispatchCycleFinishedLocked(currentTime, connection, seq, handled);
-}
-
-void InputDispatcher::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
-        const sp<Connection>& connection, bool notify) {
-#if DEBUG_DISPATCH_CYCLE
-    ALOGD("channel '%s' ~ abortBrokenDispatchCycle - notify=%s",
-            connection->getInputChannelName(), toString(notify));
-#endif
-
-    // Clear the dispatch queues.
-    drainDispatchQueueLocked(&connection->outboundQueue);
-    traceOutboundQueueLengthLocked(connection);
-    drainDispatchQueueLocked(&connection->waitQueue);
-    traceWaitQueueLengthLocked(connection);
-
-    // The connection appears to be unrecoverably broken.
-    // Ignore already broken or zombie connections.
-    if (connection->status == Connection::STATUS_NORMAL) {
-        connection->status = Connection::STATUS_BROKEN;
-
-        if (notify) {
-            // Notify other system components.
-            onDispatchCycleBrokenLocked(currentTime, connection);
-        }
-    }
-}
-
-void InputDispatcher::drainDispatchQueueLocked(Queue<DispatchEntry>* queue) {
-    while (!queue->isEmpty()) {
-        DispatchEntry* dispatchEntry = queue->dequeueAtHead();
-        releaseDispatchEntryLocked(dispatchEntry);
-    }
-}
-
-void InputDispatcher::releaseDispatchEntryLocked(DispatchEntry* dispatchEntry) {
-    if (dispatchEntry->hasForegroundTarget()) {
-        decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
-    }
-    delete dispatchEntry;
-}
-
-int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {
-    InputDispatcher* d = static_cast<InputDispatcher*>(data);
-
-    { // acquire lock
-        AutoMutex _l(d->mLock);
-
-        ssize_t connectionIndex = d->mConnectionsByFd.indexOfKey(fd);
-        if (connectionIndex < 0) {
-            ALOGE("Received spurious receive callback for unknown input channel.  "
-                    "fd=%d, events=0x%x", fd, events);
-            return 0; // remove the callback
-        }
-
-        bool notify;
-        sp<Connection> connection = d->mConnectionsByFd.valueAt(connectionIndex);
-        if (!(events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP))) {
-            if (!(events & ALOOPER_EVENT_INPUT)) {
-                ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
-                        "events=0x%x", connection->getInputChannelName(), events);
-                return 1;
-            }
-
-            nsecs_t currentTime = now();
-            bool gotOne = false;
-            status_t status;
-            for (;;) {
-                uint32_t seq;
-                bool handled;
-                status = connection->inputPublisher.receiveFinishedSignal(&seq, &handled);
-                if (status) {
-                    break;
-                }
-                d->finishDispatchCycleLocked(currentTime, connection, seq, handled);
-                gotOne = true;
-            }
-            if (gotOne) {
-                d->runCommandsLockedInterruptible();
-                if (status == WOULD_BLOCK) {
-                    return 1;
-                }
-            }
-
-            notify = status != DEAD_OBJECT || !connection->monitor;
-            if (notify) {
-                ALOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
-                        connection->getInputChannelName(), status);
-            }
-        } else {
-            // Monitor channels are never explicitly unregistered.
-            // We do it automatically when the remote endpoint is closed so don't warn
-            // about them.
-            notify = !connection->monitor;
-            if (notify) {
-                ALOGW("channel '%s' ~ Consumer closed input channel or an error occurred.  "
-                        "events=0x%x", connection->getInputChannelName(), events);
-            }
-        }
-
-        // Unregister the channel.
-        d->unregisterInputChannelLocked(connection->inputChannel, notify);
-        return 0; // remove the callback
-    } // release lock
-}
-
-void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
-        const CancelationOptions& options) {
-    for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
-        synthesizeCancelationEventsForConnectionLocked(
-                mConnectionsByFd.valueAt(i), options);
-    }
-}
-
-void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
-        const sp<InputChannel>& channel, const CancelationOptions& options) {
-    ssize_t index = getConnectionIndexLocked(channel);
-    if (index >= 0) {
-        synthesizeCancelationEventsForConnectionLocked(
-                mConnectionsByFd.valueAt(index), options);
-    }
-}
-
-void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
-        const sp<Connection>& connection, const CancelationOptions& options) {
-    if (connection->status == Connection::STATUS_BROKEN) {
-        return;
-    }
-
-    nsecs_t currentTime = now();
-
-    Vector<EventEntry*> cancelationEvents;
-    connection->inputState.synthesizeCancelationEvents(currentTime,
-            cancelationEvents, options);
-
-    if (!cancelationEvents.isEmpty()) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-        ALOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
-                "with reality: %s, mode=%d.",
-                connection->getInputChannelName(), cancelationEvents.size(),
-                options.reason, options.mode);
-#endif
-        for (size_t i = 0; i < cancelationEvents.size(); i++) {
-            EventEntry* cancelationEventEntry = cancelationEvents.itemAt(i);
-            switch (cancelationEventEntry->type) {
-            case EventEntry::TYPE_KEY:
-                logOutboundKeyDetailsLocked("cancel - ",
-                        static_cast<KeyEntry*>(cancelationEventEntry));
-                break;
-            case EventEntry::TYPE_MOTION:
-                logOutboundMotionDetailsLocked("cancel - ",
-                        static_cast<MotionEntry*>(cancelationEventEntry));
-                break;
-            }
-
-            InputTarget target;
-            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
-            if (windowHandle != NULL) {
-                const InputWindowInfo* windowInfo = windowHandle->getInfo();
-                target.xOffset = -windowInfo->frameLeft;
-                target.yOffset = -windowInfo->frameTop;
-                target.scaleFactor = windowInfo->scaleFactor;
-            } else {
-                target.xOffset = 0;
-                target.yOffset = 0;
-                target.scaleFactor = 1.0f;
-            }
-            target.inputChannel = connection->inputChannel;
-            target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
-
-            enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
-                    &target, InputTarget::FLAG_DISPATCH_AS_IS);
-
-            cancelationEventEntry->release();
-        }
-
-        startDispatchCycleLocked(currentTime, connection);
-    }
-}
-
-InputDispatcher::MotionEntry*
-InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
-    ALOG_ASSERT(pointerIds.value != 0);
-
-    uint32_t splitPointerIndexMap[MAX_POINTERS];
-    PointerProperties splitPointerProperties[MAX_POINTERS];
-    PointerCoords splitPointerCoords[MAX_POINTERS];
-
-    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
-    uint32_t splitPointerCount = 0;
-
-    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
-            originalPointerIndex++) {
-        const PointerProperties& pointerProperties =
-                originalMotionEntry->pointerProperties[originalPointerIndex];
-        uint32_t pointerId = uint32_t(pointerProperties.id);
-        if (pointerIds.hasBit(pointerId)) {
-            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
-            splitPointerProperties[splitPointerCount].copyFrom(pointerProperties);
-            splitPointerCoords[splitPointerCount].copyFrom(
-                    originalMotionEntry->pointerCoords[originalPointerIndex]);
-            splitPointerCount += 1;
-        }
-    }
-
-    if (splitPointerCount != pointerIds.count()) {
-        // This is bad.  We are missing some of the pointers that we expected to deliver.
-        // Most likely this indicates that we received an ACTION_MOVE events that has
-        // different pointer ids than we expected based on the previous ACTION_DOWN
-        // or ACTION_POINTER_DOWN events that caused us to decide to split the pointers
-        // in this way.
-        ALOGW("Dropping split motion event because the pointer count is %d but "
-                "we expected there to be %d pointers.  This probably means we received "
-                "a broken sequence of pointer ids from the input device.",
-                splitPointerCount, pointerIds.count());
-        return NULL;
-    }
-
-    int32_t action = originalMotionEntry->action;
-    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
-    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
-            || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
-        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
-        const PointerProperties& pointerProperties =
-                originalMotionEntry->pointerProperties[originalPointerIndex];
-        uint32_t pointerId = uint32_t(pointerProperties.id);
-        if (pointerIds.hasBit(pointerId)) {
-            if (pointerIds.count() == 1) {
-                // The first/last pointer went down/up.
-                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
-                        ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
-            } else {
-                // A secondary pointer went down/up.
-                uint32_t splitPointerIndex = 0;
-                while (pointerId != uint32_t(splitPointerProperties[splitPointerIndex].id)) {
-                    splitPointerIndex += 1;
-                }
-                action = maskedAction | (splitPointerIndex
-                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
-            }
-        } else {
-            // An unrelated pointer changed.
-            action = AMOTION_EVENT_ACTION_MOVE;
-        }
-    }
-
-    MotionEntry* splitMotionEntry = new MotionEntry(
-            originalMotionEntry->eventTime,
-            originalMotionEntry->deviceId,
-            originalMotionEntry->source,
-            originalMotionEntry->policyFlags,
-            action,
-            originalMotionEntry->flags,
-            originalMotionEntry->metaState,
-            originalMotionEntry->buttonState,
-            originalMotionEntry->edgeFlags,
-            originalMotionEntry->xPrecision,
-            originalMotionEntry->yPrecision,
-            originalMotionEntry->downTime,
-            originalMotionEntry->displayId,
-            splitPointerCount, splitPointerProperties, splitPointerCoords, 0, 0);
-
-    if (originalMotionEntry->injectionState) {
-        splitMotionEntry->injectionState = originalMotionEntry->injectionState;
-        splitMotionEntry->injectionState->refCount += 1;
-    }
-
-    return splitMotionEntry;
-}
-
-void InputDispatcher::notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    ALOGD("notifyConfigurationChanged - eventTime=%lld", args->eventTime);
-#endif
-
-    bool needWake;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        ConfigurationChangedEntry* newEntry = new ConfigurationChangedEntry(args->eventTime);
-        needWake = enqueueInboundEventLocked(newEntry);
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
-void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    ALOGD("notifyKey - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
-            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
-            args->eventTime, args->deviceId, args->source, args->policyFlags,
-            args->action, args->flags, args->keyCode, args->scanCode,
-            args->metaState, args->downTime);
-#endif
-    if (!validateKeyEvent(args->action)) {
-        return;
-    }
-
-    uint32_t policyFlags = args->policyFlags;
-    int32_t flags = args->flags;
-    int32_t metaState = args->metaState;
-    if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
-        policyFlags |= POLICY_FLAG_VIRTUAL;
-        flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
-    }
-    if (policyFlags & POLICY_FLAG_ALT) {
-        metaState |= AMETA_ALT_ON | AMETA_ALT_LEFT_ON;
-    }
-    if (policyFlags & POLICY_FLAG_ALT_GR) {
-        metaState |= AMETA_ALT_ON | AMETA_ALT_RIGHT_ON;
-    }
-    if (policyFlags & POLICY_FLAG_SHIFT) {
-        metaState |= AMETA_SHIFT_ON | AMETA_SHIFT_LEFT_ON;
-    }
-    if (policyFlags & POLICY_FLAG_CAPS_LOCK) {
-        metaState |= AMETA_CAPS_LOCK_ON;
-    }
-    if (policyFlags & POLICY_FLAG_FUNCTION) {
-        metaState |= AMETA_FUNCTION_ON;
-    }
-
-    policyFlags |= POLICY_FLAG_TRUSTED;
-
-    KeyEvent event;
-    event.initialize(args->deviceId, args->source, args->action,
-            flags, args->keyCode, args->scanCode, metaState, 0,
-            args->downTime, args->eventTime);
-
-    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
-
-    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
-        flags |= AKEY_EVENT_FLAG_WOKE_HERE;
-    }
-
-    bool needWake;
-    { // acquire lock
-        mLock.lock();
-
-        if (shouldSendKeyToInputFilterLocked(args)) {
-            mLock.unlock();
-
-            policyFlags |= POLICY_FLAG_FILTERED;
-            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
-                return; // event was consumed by the filter
-            }
-
-            mLock.lock();
-        }
-
-        int32_t repeatCount = 0;
-        KeyEntry* newEntry = new KeyEntry(args->eventTime,
-                args->deviceId, args->source, policyFlags,
-                args->action, flags, args->keyCode, args->scanCode,
-                metaState, repeatCount, args->downTime);
-
-        needWake = enqueueInboundEventLocked(newEntry);
-        mLock.unlock();
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
-bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
-    return mInputFilterEnabled;
-}
-
-void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
-            "action=0x%x, flags=0x%x, metaState=0x%x, buttonState=0x%x, edgeFlags=0x%x, "
-            "xPrecision=%f, yPrecision=%f, downTime=%lld",
-            args->eventTime, args->deviceId, args->source, args->policyFlags,
-            args->action, args->flags, args->metaState, args->buttonState,
-            args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime);
-    for (uint32_t i = 0; i < args->pointerCount; i++) {
-        ALOGD("  Pointer %d: id=%d, toolType=%d, "
-                "x=%f, y=%f, pressure=%f, size=%f, "
-                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
-                "orientation=%f",
-                i, args->pointerProperties[i].id,
-                args->pointerProperties[i].toolType,
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_X),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_Y),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_SIZE),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
-                args->pointerCoords[i].getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION));
-    }
-#endif
-    if (!validateMotionEvent(args->action, args->pointerCount, args->pointerProperties)) {
-        return;
-    }
-
-    uint32_t policyFlags = args->policyFlags;
-    policyFlags |= POLICY_FLAG_TRUSTED;
-    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
-
-    bool needWake;
-    { // acquire lock
-        mLock.lock();
-
-        if (shouldSendMotionToInputFilterLocked(args)) {
-            mLock.unlock();
-
-            MotionEvent event;
-            event.initialize(args->deviceId, args->source, args->action, args->flags,
-                    args->edgeFlags, args->metaState, args->buttonState, 0, 0,
-                    args->xPrecision, args->yPrecision,
-                    args->downTime, args->eventTime,
-                    args->pointerCount, args->pointerProperties, args->pointerCoords);
-
-            policyFlags |= POLICY_FLAG_FILTERED;
-            if (!mPolicy->filterInputEvent(&event, policyFlags)) {
-                return; // event was consumed by the filter
-            }
-
-            mLock.lock();
-        }
-
-        // Just enqueue a new motion event.
-        MotionEntry* newEntry = new MotionEntry(args->eventTime,
-                args->deviceId, args->source, policyFlags,
-                args->action, args->flags, args->metaState, args->buttonState,
-                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
-                args->displayId,
-                args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
-
-        needWake = enqueueInboundEventLocked(newEntry);
-        mLock.unlock();
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
-bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
-    // TODO: support sending secondary display events to input filter
-    return mInputFilterEnabled && isMainDisplay(args->displayId);
-}
-
-void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchValues=0x%08x, switchMask=0x%08x",
-            args->eventTime, args->policyFlags,
-            args->switchValues, args->switchMask);
-#endif
-
-    uint32_t policyFlags = args->policyFlags;
-    policyFlags |= POLICY_FLAG_TRUSTED;
-    mPolicy->notifySwitch(args->eventTime,
-            args->switchValues, args->switchMask, policyFlags);
-}
-
-void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    ALOGD("notifyDeviceReset - eventTime=%lld, deviceId=%d",
-            args->eventTime, args->deviceId);
-#endif
-
-    bool needWake;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        DeviceResetEntry* newEntry = new DeviceResetEntry(args->eventTime, args->deviceId);
-        needWake = enqueueInboundEventLocked(newEntry);
-    } // release lock
-
-    if (needWake) {
-        mLooper->wake();
-    }
-}
-
-int32_t InputDispatcher::injectInputEvent(const InputEvent* event, int32_t displayId,
-        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
-        uint32_t policyFlags) {
-#if DEBUG_INBOUND_EVENT_DETAILS
-    ALOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
-            "syncMode=%d, timeoutMillis=%d, policyFlags=0x%08x",
-            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis, policyFlags);
-#endif
-
-    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
-
-    policyFlags |= POLICY_FLAG_INJECTED;
-    if (hasInjectionPermission(injectorPid, injectorUid)) {
-        policyFlags |= POLICY_FLAG_TRUSTED;
-    }
-
-    EventEntry* firstInjectedEntry;
-    EventEntry* lastInjectedEntry;
-    switch (event->getType()) {
-    case AINPUT_EVENT_TYPE_KEY: {
-        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
-        int32_t action = keyEvent->getAction();
-        if (! validateKeyEvent(action)) {
-            return INPUT_EVENT_INJECTION_FAILED;
-        }
-
-        int32_t flags = keyEvent->getFlags();
-        if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
-            policyFlags |= POLICY_FLAG_VIRTUAL;
-        }
-
-        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
-            mPolicy->interceptKeyBeforeQueueing(keyEvent, /*byref*/ policyFlags);
-        }
-
-        if (policyFlags & POLICY_FLAG_WOKE_HERE) {
-            flags |= AKEY_EVENT_FLAG_WOKE_HERE;
-        }
-
-        mLock.lock();
-        firstInjectedEntry = new KeyEntry(keyEvent->getEventTime(),
-                keyEvent->getDeviceId(), keyEvent->getSource(),
-                policyFlags, action, flags,
-                keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
-                keyEvent->getRepeatCount(), keyEvent->getDownTime());
-        lastInjectedEntry = firstInjectedEntry;
-        break;
-    }
-
-    case AINPUT_EVENT_TYPE_MOTION: {
-        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
-        int32_t action = motionEvent->getAction();
-        size_t pointerCount = motionEvent->getPointerCount();
-        const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
-        if (! validateMotionEvent(action, pointerCount, pointerProperties)) {
-            return INPUT_EVENT_INJECTION_FAILED;
-        }
-
-        if (!(policyFlags & POLICY_FLAG_FILTERED)) {
-            nsecs_t eventTime = motionEvent->getEventTime();
-            mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
-        }
-
-        mLock.lock();
-        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
-        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
-        firstInjectedEntry = new MotionEntry(*sampleEventTimes,
-                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
-                action, motionEvent->getFlags(),
-                motionEvent->getMetaState(), motionEvent->getButtonState(),
-                motionEvent->getEdgeFlags(),
-                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
-                motionEvent->getDownTime(), displayId,
-                uint32_t(pointerCount), pointerProperties, samplePointerCoords,
-                motionEvent->getXOffset(), motionEvent->getYOffset());
-        lastInjectedEntry = firstInjectedEntry;
-        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
-            sampleEventTimes += 1;
-            samplePointerCoords += pointerCount;
-            MotionEntry* nextInjectedEntry = new MotionEntry(*sampleEventTimes,
-                    motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
-                    action, motionEvent->getFlags(),
-                    motionEvent->getMetaState(), motionEvent->getButtonState(),
-                    motionEvent->getEdgeFlags(),
-                    motionEvent->getXPrecision(), motionEvent->getYPrecision(),
-                    motionEvent->getDownTime(), displayId,
-                    uint32_t(pointerCount), pointerProperties, samplePointerCoords,
-                    motionEvent->getXOffset(), motionEvent->getYOffset());
-            lastInjectedEntry->next = nextInjectedEntry;
-            lastInjectedEntry = nextInjectedEntry;
-        }
-        break;
-    }
-
-    default:
-        ALOGW("Cannot inject event of type %d", event->getType());
-        return INPUT_EVENT_INJECTION_FAILED;
-    }
-
-    InjectionState* injectionState = new InjectionState(injectorPid, injectorUid);
-    if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
-        injectionState->injectionIsAsync = true;
-    }
-
-    injectionState->refCount += 1;
-    lastInjectedEntry->injectionState = injectionState;
-
-    bool needWake = false;
-    for (EventEntry* entry = firstInjectedEntry; entry != NULL; ) {
-        EventEntry* nextEntry = entry->next;
-        needWake |= enqueueInboundEventLocked(entry);
-        entry = nextEntry;
-    }
-
-    mLock.unlock();
-
-    if (needWake) {
-        mLooper->wake();
-    }
-
-    int32_t injectionResult;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
-            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
-        } else {
-            for (;;) {
-                injectionResult = injectionState->injectionResult;
-                if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
-                    break;
-                }
-
-                nsecs_t remainingTimeout = endTime - now();
-                if (remainingTimeout <= 0) {
-#if DEBUG_INJECTION
-                    ALOGD("injectInputEvent - Timed out waiting for injection result "
-                            "to become available.");
-#endif
-                    injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
-                    break;
-                }
-
-                mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
-            }
-
-            if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
-                    && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
-                while (injectionState->pendingForegroundDispatches != 0) {
-#if DEBUG_INJECTION
-                    ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
-                            injectionState->pendingForegroundDispatches);
-#endif
-                    nsecs_t remainingTimeout = endTime - now();
-                    if (remainingTimeout <= 0) {
-#if DEBUG_INJECTION
-                    ALOGD("injectInputEvent - Timed out waiting for pending foreground "
-                            "dispatches to finish.");
-#endif
-                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
-                        break;
-                    }
-
-                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
-                }
-            }
-        }
-
-        injectionState->release();
-    } // release lock
-
-#if DEBUG_INJECTION
-    ALOGD("injectInputEvent - Finished with result %d.  "
-            "injectorPid=%d, injectorUid=%d",
-            injectionResult, injectorPid, injectorUid);
-#endif
-
-    return injectionResult;
-}
-
-bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
-    return injectorUid == 0
-            || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
-}
-
-void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState) {
-#if DEBUG_INJECTION
-        ALOGD("Setting input event injection result to %d.  "
-                "injectorPid=%d, injectorUid=%d",
-                 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
-#endif
-
-        if (injectionState->injectionIsAsync
-                && !(entry->policyFlags & POLICY_FLAG_FILTERED)) {
-            // Log the outcome since the injector did not wait for the injection result.
-            switch (injectionResult) {
-            case INPUT_EVENT_INJECTION_SUCCEEDED:
-                ALOGV("Asynchronous input event injection succeeded.");
-                break;
-            case INPUT_EVENT_INJECTION_FAILED:
-                ALOGW("Asynchronous input event injection failed.");
-                break;
-            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
-                ALOGW("Asynchronous input event injection permission denied.");
-                break;
-            case INPUT_EVENT_INJECTION_TIMED_OUT:
-                ALOGW("Asynchronous input event injection timed out.");
-                break;
-            }
-        }
-
-        injectionState->injectionResult = injectionResult;
-        mInjectionResultAvailableCondition.broadcast();
-    }
-}
-
-void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState) {
-        injectionState->pendingForegroundDispatches += 1;
-    }
-}
-
-void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
-    InjectionState* injectionState = entry->injectionState;
-    if (injectionState) {
-        injectionState->pendingForegroundDispatches -= 1;
-
-        if (injectionState->pendingForegroundDispatches == 0) {
-            mInjectionSyncFinishedCondition.broadcast();
-        }
-    }
-}
-
-sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
-        const sp<InputChannel>& inputChannel) const {
-    size_t numWindows = mWindowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
-        if (windowHandle->getInputChannel() == inputChannel) {
-            return windowHandle;
-        }
-    }
-    return NULL;
-}
-
-bool InputDispatcher::hasWindowHandleLocked(
-        const sp<InputWindowHandle>& windowHandle) const {
-    size_t numWindows = mWindowHandles.size();
-    for (size_t i = 0; i < numWindows; i++) {
-        if (mWindowHandles.itemAt(i) == windowHandle) {
-            return true;
-        }
-    }
-    return false;
-}
-
-void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
-#if DEBUG_FOCUS
-    ALOGD("setInputWindows");
-#endif
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
-        mWindowHandles = inputWindowHandles;
-
-        sp<InputWindowHandle> newFocusedWindowHandle;
-        bool foundHoveredWindow = false;
-        for (size_t i = 0; i < mWindowHandles.size(); i++) {
-            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
-            if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == NULL) {
-                mWindowHandles.removeAt(i--);
-                continue;
-            }
-            if (windowHandle->getInfo()->hasFocus) {
-                newFocusedWindowHandle = windowHandle;
-            }
-            if (windowHandle == mLastHoverWindowHandle) {
-                foundHoveredWindow = true;
-            }
-        }
-
-        if (!foundHoveredWindow) {
-            mLastHoverWindowHandle = NULL;
-        }
-
-        if (mFocusedWindowHandle != newFocusedWindowHandle) {
-            if (mFocusedWindowHandle != NULL) {
-#if DEBUG_FOCUS
-                ALOGD("Focus left window: %s",
-                        mFocusedWindowHandle->getName().string());
-#endif
-                sp<InputChannel> focusedInputChannel = mFocusedWindowHandle->getInputChannel();
-                if (focusedInputChannel != NULL) {
-                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
-                            "focus left window");
-                    synthesizeCancelationEventsForInputChannelLocked(
-                            focusedInputChannel, options);
-                }
-            }
-            if (newFocusedWindowHandle != NULL) {
-#if DEBUG_FOCUS
-                ALOGD("Focus entered window: %s",
-                        newFocusedWindowHandle->getName().string());
-#endif
-            }
-            mFocusedWindowHandle = newFocusedWindowHandle;
-        }
-
-        for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
-            TouchState& state = mTouchStatesByDisplay.editValueAt(d);
-            for (size_t i = 0; i < state.windows.size(); i++) {
-                TouchedWindow& touchedWindow = state.windows.editItemAt(i);
-                if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
-#if DEBUG_FOCUS
-                    ALOGD("Touched window was removed: %s",
-                            touchedWindow.windowHandle->getName().string());
-#endif
-                    sp<InputChannel> touchedInputChannel =
-                            touchedWindow.windowHandle->getInputChannel();
-                    if (touchedInputChannel != NULL) {
-                        CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
-                                "touched window was removed");
-                        synthesizeCancelationEventsForInputChannelLocked(
-                                touchedInputChannel, options);
-                    }
-                    state.windows.removeAt(i--);
-                }
-            }
-        }
-
-        // Release information for windows that are no longer present.
-        // This ensures that unused input channels are released promptly.
-        // Otherwise, they might stick around until the window handle is destroyed
-        // which might not happen until the next GC.
-        for (size_t i = 0; i < oldWindowHandles.size(); i++) {
-            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
-            if (!hasWindowHandleLocked(oldWindowHandle)) {
-#if DEBUG_FOCUS
-                ALOGD("Window went away: %s", oldWindowHandle->getName().string());
-#endif
-                oldWindowHandle->releaseInfo();
-            }
-        }
-    } // release lock
-
-    // Wake up poll loop since it may need to make new input dispatching choices.
-    mLooper->wake();
-}
-
-void InputDispatcher::setFocusedApplication(
-        const sp<InputApplicationHandle>& inputApplicationHandle) {
-#if DEBUG_FOCUS
-    ALOGD("setFocusedApplication");
-#endif
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (inputApplicationHandle != NULL && inputApplicationHandle->updateInfo()) {
-            if (mFocusedApplicationHandle != inputApplicationHandle) {
-                if (mFocusedApplicationHandle != NULL) {
-                    resetANRTimeoutsLocked();
-                    mFocusedApplicationHandle->releaseInfo();
-                }
-                mFocusedApplicationHandle = inputApplicationHandle;
-            }
-        } else if (mFocusedApplicationHandle != NULL) {
-            resetANRTimeoutsLocked();
-            mFocusedApplicationHandle->releaseInfo();
-            mFocusedApplicationHandle.clear();
-        }
-
-#if DEBUG_FOCUS
-        //logDispatchStateLocked();
-#endif
-    } // release lock
-
-    // Wake up poll loop since it may need to make new input dispatching choices.
-    mLooper->wake();
-}
-
-void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
-#if DEBUG_FOCUS
-    ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
-#endif
-
-    bool changed;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
-            if (mDispatchFrozen && !frozen) {
-                resetANRTimeoutsLocked();
-            }
-
-            if (mDispatchEnabled && !enabled) {
-                resetAndDropEverythingLocked("dispatcher is being disabled");
-            }
-
-            mDispatchEnabled = enabled;
-            mDispatchFrozen = frozen;
-            changed = true;
-        } else {
-            changed = false;
-        }
-
-#if DEBUG_FOCUS
-        //logDispatchStateLocked();
-#endif
-    } // release lock
-
-    if (changed) {
-        // Wake up poll loop since it may need to make new input dispatching choices.
-        mLooper->wake();
-    }
-}
-
-void InputDispatcher::setInputFilterEnabled(bool enabled) {
-#if DEBUG_FOCUS
-    ALOGD("setInputFilterEnabled: enabled=%d", enabled);
-#endif
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (mInputFilterEnabled == enabled) {
-            return;
-        }
-
-        mInputFilterEnabled = enabled;
-        resetAndDropEverythingLocked("input filter is being enabled or disabled");
-    } // release lock
-
-    // Wake up poll loop since there might be work to do to drop everything.
-    mLooper->wake();
-}
-
-bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
-        const sp<InputChannel>& toChannel) {
-#if DEBUG_FOCUS
-    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
-            fromChannel->getName().string(), toChannel->getName().string());
-#endif
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
-        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
-        if (fromWindowHandle == NULL || toWindowHandle == NULL) {
-#if DEBUG_FOCUS
-            ALOGD("Cannot transfer focus because from or to window not found.");
-#endif
-            return false;
-        }
-        if (fromWindowHandle == toWindowHandle) {
-#if DEBUG_FOCUS
-            ALOGD("Trivial transfer to same window.");
-#endif
-            return true;
-        }
-        if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
-#if DEBUG_FOCUS
-            ALOGD("Cannot transfer focus because windows are on different displays.");
-#endif
-            return false;
-        }
-
-        bool found = false;
-        for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
-            TouchState& state = mTouchStatesByDisplay.editValueAt(d);
-            for (size_t i = 0; i < state.windows.size(); i++) {
-                const TouchedWindow& touchedWindow = state.windows[i];
-                if (touchedWindow.windowHandle == fromWindowHandle) {
-                    int32_t oldTargetFlags = touchedWindow.targetFlags;
-                    BitSet32 pointerIds = touchedWindow.pointerIds;
-
-                    state.windows.removeAt(i);
-
-                    int32_t newTargetFlags = oldTargetFlags
-                            & (InputTarget::FLAG_FOREGROUND
-                                    | InputTarget::FLAG_SPLIT | InputTarget::FLAG_DISPATCH_AS_IS);
-                    state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);
-
-                    found = true;
-                    goto Found;
-                }
-            }
-        }
-Found:
-
-        if (! found) {
-#if DEBUG_FOCUS
-            ALOGD("Focus transfer failed because from window did not have focus.");
-#endif
-            return false;
-        }
-
-        ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
-        ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
-        if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
-            sp<Connection> fromConnection = mConnectionsByFd.valueAt(fromConnectionIndex);
-            sp<Connection> toConnection = mConnectionsByFd.valueAt(toConnectionIndex);
-
-            fromConnection->inputState.copyPointerStateTo(toConnection->inputState);
-            CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
-                    "transferring touch focus from this window to another window");
-            synthesizeCancelationEventsForConnectionLocked(fromConnection, options);
-        }
-
-#if DEBUG_FOCUS
-        logDispatchStateLocked();
-#endif
-    } // release lock
-
-    // Wake up poll loop since it may need to make new input dispatching choices.
-    mLooper->wake();
-    return true;
-}
-
-void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
-#if DEBUG_FOCUS
-    ALOGD("Resetting and dropping all events (%s).", reason);
-#endif
-
-    CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS, reason);
-    synthesizeCancelationEventsForAllConnectionsLocked(options);
-
-    resetKeyRepeatLocked();
-    releasePendingEventLocked();
-    drainInboundQueueLocked();
-    resetANRTimeoutsLocked();
-
-    mTouchStatesByDisplay.clear();
-    mLastHoverWindowHandle.clear();
-}
-
-void InputDispatcher::logDispatchStateLocked() {
-    String8 dump;
-    dumpDispatchStateLocked(dump);
-
-    char* text = dump.lockBuffer(dump.size());
-    char* start = text;
-    while (*start != '\0') {
-        char* end = strchr(start, '\n');
-        if (*end == '\n') {
-            *(end++) = '\0';
-        }
-        ALOGD("%s", start);
-        start = end;
-    }
-}
-
-void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
-    dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
-    dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
-
-    if (mFocusedApplicationHandle != NULL) {
-        dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
-                mFocusedApplicationHandle->getName().string(),
-                mFocusedApplicationHandle->getDispatchingTimeout(
-                        DEFAULT_INPUT_DISPATCHING_TIMEOUT) / 1000000.0);
-    } else {
-        dump.append(INDENT "FocusedApplication: <null>\n");
-    }
-    dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
-            mFocusedWindowHandle != NULL ? mFocusedWindowHandle->getName().string() : "<null>");
-
-    if (!mTouchStatesByDisplay.isEmpty()) {
-        dump.appendFormat(INDENT "TouchStatesByDisplay:\n");
-        for (size_t i = 0; i < mTouchStatesByDisplay.size(); i++) {
-            const TouchState& state = mTouchStatesByDisplay.valueAt(i);
-            dump.appendFormat(INDENT2 "%d: down=%s, split=%s, deviceId=%d, source=0x%08x\n",
-                    state.displayId, toString(state.down), toString(state.split),
-                    state.deviceId, state.source);
-            if (!state.windows.isEmpty()) {
-                dump.append(INDENT3 "Windows:\n");
-                for (size_t i = 0; i < state.windows.size(); i++) {
-                    const TouchedWindow& touchedWindow = state.windows[i];
-                    dump.appendFormat(INDENT4 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
-                            i, touchedWindow.windowHandle->getName().string(),
-                            touchedWindow.pointerIds.value,
-                            touchedWindow.targetFlags);
-                }
-            } else {
-                dump.append(INDENT3 "Windows: <none>\n");
-            }
-        }
-    } else {
-        dump.append(INDENT "TouchStates: <no displays touched>\n");
-    }
-
-    if (!mWindowHandles.isEmpty()) {
-        dump.append(INDENT "Windows:\n");
-        for (size_t i = 0; i < mWindowHandles.size(); i++) {
-            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
-            const InputWindowInfo* windowInfo = windowHandle->getInfo();
-
-            dump.appendFormat(INDENT2 "%d: name='%s', displayId=%d, "
-                    "paused=%s, hasFocus=%s, hasWallpaper=%s, "
-                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
-                    "frame=[%d,%d][%d,%d], scale=%f, "
-                    "touchableRegion=",
-                    i, windowInfo->name.string(), windowInfo->displayId,
-                    toString(windowInfo->paused),
-                    toString(windowInfo->hasFocus),
-                    toString(windowInfo->hasWallpaper),
-                    toString(windowInfo->visible),
-                    toString(windowInfo->canReceiveKeys),
-                    windowInfo->layoutParamsFlags, windowInfo->layoutParamsType,
-                    windowInfo->layer,
-                    windowInfo->frameLeft, windowInfo->frameTop,
-                    windowInfo->frameRight, windowInfo->frameBottom,
-                    windowInfo->scaleFactor);
-            dumpRegion(dump, windowInfo->touchableRegion);
-            dump.appendFormat(", inputFeatures=0x%08x", windowInfo->inputFeatures);
-            dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
-                    windowInfo->ownerPid, windowInfo->ownerUid,
-                    windowInfo->dispatchingTimeout / 1000000.0);
-        }
-    } else {
-        dump.append(INDENT "Windows: <none>\n");
-    }
-
-    if (!mMonitoringChannels.isEmpty()) {
-        dump.append(INDENT "MonitoringChannels:\n");
-        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
-            const sp<InputChannel>& channel = mMonitoringChannels[i];
-            dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
-        }
-    } else {
-        dump.append(INDENT "MonitoringChannels: <none>\n");
-    }
-
-    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) {
-            dump.append(INDENT2);
-            entry->appendDescription(dump);
-            dump.appendFormat(", age=%0.1fms\n",
-                    (currentTime - entry->eventTime) * 0.000001f);
-        }
-    } else {
-        dump.append(INDENT "InboundQueue: <empty>\n");
-    }
-
-    if (!mConnectionsByFd.isEmpty()) {
-        dump.append(INDENT "Connections:\n");
-        for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
-            const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
-            dump.appendFormat(INDENT2 "%d: channelName='%s', windowName='%s', "
-                    "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
-                    i, connection->getInputChannelName(), connection->getWindowName(),
-                    connection->getStatusLabel(), toString(connection->monitor),
-                    toString(connection->inputPublisherBlocked));
-
-            if (!connection->outboundQueue.isEmpty()) {
-                dump.appendFormat(INDENT3 "OutboundQueue: length=%u\n",
-                        connection->outboundQueue.count());
-                for (DispatchEntry* entry = connection->outboundQueue.head; entry;
-                        entry = entry->next) {
-                    dump.append(INDENT4);
-                    entry->eventEntry->appendDescription(dump);
-                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%0.1fms\n",
-                            entry->targetFlags, entry->resolvedAction,
-                            (currentTime - entry->eventEntry->eventTime) * 0.000001f);
-                }
-            } else {
-                dump.append(INDENT3 "OutboundQueue: <empty>\n");
-            }
-
-            if (!connection->waitQueue.isEmpty()) {
-                dump.appendFormat(INDENT3 "WaitQueue: length=%u\n",
-                        connection->waitQueue.count());
-                for (DispatchEntry* entry = connection->waitQueue.head; entry;
-                        entry = entry->next) {
-                    dump.append(INDENT4);
-                    entry->eventEntry->appendDescription(dump);
-                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
-                            "age=%0.1fms, wait=%0.1fms\n",
-                            entry->targetFlags, entry->resolvedAction,
-                            (currentTime - entry->eventEntry->eventTime) * 0.000001f,
-                            (currentTime - entry->deliveryTime) * 0.000001f);
-                }
-            } else {
-                dump.append(INDENT3 "WaitQueue: <empty>\n");
-            }
-        }
-    } else {
-        dump.append(INDENT "Connections: <none>\n");
-    }
-
-    if (isAppSwitchPendingLocked()) {
-        dump.appendFormat(INDENT "AppSwitch: pending, due in %0.1fms\n",
-                (mAppSwitchDueTime - now()) / 1000000.0);
-    } else {
-        dump.append(INDENT "AppSwitch: not pending\n");
-    }
-
-    dump.append(INDENT "Configuration:\n");
-    dump.appendFormat(INDENT2 "KeyRepeatDelay: %0.1fms\n",
-            mConfig.keyRepeatDelay * 0.000001f);
-    dump.appendFormat(INDENT2 "KeyRepeatTimeout: %0.1fms\n",
-            mConfig.keyRepeatTimeout * 0.000001f);
-}
-
-status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel,
-        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
-#if DEBUG_REGISTRATION
-    ALOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
-            toString(monitor));
-#endif
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        if (getConnectionIndexLocked(inputChannel) >= 0) {
-            ALOGW("Attempted to register already registered input channel '%s'",
-                    inputChannel->getName().string());
-            return BAD_VALUE;
-        }
-
-        sp<Connection> connection = new Connection(inputChannel, inputWindowHandle, monitor);
-
-        int fd = inputChannel->getFd();
-        mConnectionsByFd.add(fd, connection);
-
-        if (monitor) {
-            mMonitoringChannels.push(inputChannel);
-        }
-
-        mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this);
-    } // release lock
-
-    // Wake the looper because some connections have changed.
-    mLooper->wake();
-    return OK;
-}
-
-status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
-#if DEBUG_REGISTRATION
-    ALOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
-#endif
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        status_t status = unregisterInputChannelLocked(inputChannel, false /*notify*/);
-        if (status) {
-            return status;
-        }
-    } // release lock
-
-    // Wake the poll loop because removing the connection may have changed the current
-    // synchronization state.
-    mLooper->wake();
-    return OK;
-}
-
-status_t InputDispatcher::unregisterInputChannelLocked(const sp<InputChannel>& inputChannel,
-        bool notify) {
-    ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
-    if (connectionIndex < 0) {
-        ALOGW("Attempted to unregister already unregistered input channel '%s'",
-                inputChannel->getName().string());
-        return BAD_VALUE;
-    }
-
-    sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
-    mConnectionsByFd.removeItemsAt(connectionIndex);
-
-    if (connection->monitor) {
-        removeMonitorChannelLocked(inputChannel);
-    }
-
-    mLooper->removeFd(inputChannel->getFd());
-
-    nsecs_t currentTime = now();
-    abortBrokenDispatchCycleLocked(currentTime, connection, notify);
-
-    connection->status = Connection::STATUS_ZOMBIE;
-    return OK;
-}
-
-void InputDispatcher::removeMonitorChannelLocked(const sp<InputChannel>& inputChannel) {
-    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
-         if (mMonitoringChannels[i] == inputChannel) {
-             mMonitoringChannels.removeAt(i);
-             break;
-         }
-    }
-}
-
-ssize_t InputDispatcher::getConnectionIndexLocked(const sp<InputChannel>& inputChannel) {
-    ssize_t connectionIndex = mConnectionsByFd.indexOfKey(inputChannel->getFd());
-    if (connectionIndex >= 0) {
-        sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
-        if (connection->inputChannel.get() == inputChannel.get()) {
-            return connectionIndex;
-        }
-    }
-
-    return -1;
-}
-
-void InputDispatcher::onDispatchCycleFinishedLocked(
-        nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled) {
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
-    commandEntry->connection = connection;
-    commandEntry->eventTime = currentTime;
-    commandEntry->seq = seq;
-    commandEntry->handled = handled;
-}
-
-void InputDispatcher::onDispatchCycleBrokenLocked(
-        nsecs_t currentTime, const sp<Connection>& connection) {
-    ALOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
-            connection->getInputChannelName());
-
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
-    commandEntry->connection = connection;
-}
-
-void InputDispatcher::onANRLocked(
-        nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
-        const sp<InputWindowHandle>& windowHandle,
-        nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
-    float dispatchLatency = (currentTime - eventTime) * 0.000001f;
-    float waitDuration = (currentTime - waitStartTime) * 0.000001f;
-    ALOGI("Application is not responding: %s.  "
-            "It has been %0.1fms since event, %0.1fms since wait started.  Reason: %s",
-            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
-            dispatchLatency, waitDuration, reason);
-
-    // Capture a record of the InputDispatcher state at the time of the ANR.
-    time_t t = time(NULL);
-    struct tm tm;
-    localtime_r(&t, &tm);
-    char timestr[64];
-    strftime(timestr, sizeof(timestr), "%F %T", &tm);
-    mLastANRState.clear();
-    mLastANRState.append(INDENT "ANR:\n");
-    mLastANRState.appendFormat(INDENT2 "Time: %s\n", timestr);
-    mLastANRState.appendFormat(INDENT2 "Window: %s\n",
-            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
-    mLastANRState.appendFormat(INDENT2 "DispatchLatency: %0.1fms\n", dispatchLatency);
-    mLastANRState.appendFormat(INDENT2 "WaitDuration: %0.1fms\n", waitDuration);
-    mLastANRState.appendFormat(INDENT2 "Reason: %s\n", reason);
-    dumpDispatchStateLocked(mLastANRState);
-
-    CommandEntry* commandEntry = postCommandLocked(
-            & InputDispatcher::doNotifyANRLockedInterruptible);
-    commandEntry->inputApplicationHandle = applicationHandle;
-    commandEntry->inputWindowHandle = windowHandle;
-    commandEntry->reason = reason;
-}
-
-void InputDispatcher::doNotifyConfigurationChangedInterruptible(
-        CommandEntry* commandEntry) {
-    mLock.unlock();
-
-    mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
-
-    mLock.lock();
-}
-
-void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
-        CommandEntry* commandEntry) {
-    sp<Connection> connection = commandEntry->connection;
-
-    if (connection->status != Connection::STATUS_ZOMBIE) {
-        mLock.unlock();
-
-        mPolicy->notifyInputChannelBroken(connection->inputWindowHandle);
-
-        mLock.lock();
-    }
-}
-
-void InputDispatcher::doNotifyANRLockedInterruptible(
-        CommandEntry* commandEntry) {
-    mLock.unlock();
-
-    nsecs_t newTimeout = mPolicy->notifyANR(
-            commandEntry->inputApplicationHandle, commandEntry->inputWindowHandle,
-            commandEntry->reason);
-
-    mLock.lock();
-
-    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout,
-            commandEntry->inputWindowHandle != NULL
-                    ? commandEntry->inputWindowHandle->getInputChannel() : NULL);
-}
-
-void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
-        CommandEntry* commandEntry) {
-    KeyEntry* entry = commandEntry->keyEntry;
-
-    KeyEvent event;
-    initializeKeyEvent(&event, entry);
-
-    mLock.unlock();
-
-    nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
-            &event, entry->policyFlags);
-
-    mLock.lock();
-
-    if (delay < 0) {
-        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
-    } else if (!delay) {
-        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
-    } else {
-        entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER;
-        entry->interceptKeyWakeupTime = now() + delay;
-    }
-    entry->release();
-}
-
-void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
-        CommandEntry* commandEntry) {
-    sp<Connection> connection = commandEntry->connection;
-    nsecs_t finishTime = commandEntry->eventTime;
-    uint32_t seq = commandEntry->seq;
-    bool handled = commandEntry->handled;
-
-    // Handle post-event policy actions.
-    DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
-    if (dispatchEntry) {
-        nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
-        if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
-            String8 msg;
-            msg.appendFormat("Window '%s' spent %0.1fms processing the last input event: ",
-                    connection->getWindowName(), eventDuration * 0.000001f);
-            dispatchEntry->eventEntry->appendDescription(msg);
-            ALOGI("%s", msg.string());
-        }
-
-        bool restartEvent;
-        if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
-            KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
-            restartEvent = afterKeyEventLockedInterruptible(connection,
-                    dispatchEntry, keyEntry, handled);
-        } else if (dispatchEntry->eventEntry->type == EventEntry::TYPE_MOTION) {
-            MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
-            restartEvent = afterMotionEventLockedInterruptible(connection,
-                    dispatchEntry, motionEntry, handled);
-        } else {
-            restartEvent = false;
-        }
-
-        // Dequeue the event and start the next cycle.
-        // Note that because the lock might have been released, it is possible that the
-        // contents of the wait queue to have been drained, so we need to double-check
-        // a few things.
-        if (dispatchEntry == connection->findWaitQueueEntry(seq)) {
-            connection->waitQueue.dequeue(dispatchEntry);
-            traceWaitQueueLengthLocked(connection);
-            if (restartEvent && connection->status == Connection::STATUS_NORMAL) {
-                connection->outboundQueue.enqueueAtHead(dispatchEntry);
-                traceOutboundQueueLengthLocked(connection);
-            } else {
-                releaseDispatchEntryLocked(dispatchEntry);
-            }
-        }
-
-        // Start the next dispatch cycle for this connection.
-        startDispatchCycleLocked(now(), connection);
-    }
-}
-
-bool InputDispatcher::afterKeyEventLockedInterruptible(const sp<Connection>& connection,
-        DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled) {
-    if (!(keyEntry->flags & AKEY_EVENT_FLAG_FALLBACK)) {
-        // Get the fallback key state.
-        // Clear it out after dispatching the UP.
-        int32_t originalKeyCode = keyEntry->keyCode;
-        int32_t fallbackKeyCode = connection->inputState.getFallbackKey(originalKeyCode);
-        if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
-            connection->inputState.removeFallbackKey(originalKeyCode);
-        }
-
-        if (handled || !dispatchEntry->hasForegroundTarget()) {
-            // If the application handles the original key for which we previously
-            // generated a fallback or if the window is not a foreground window,
-            // then cancel the associated fallback key, if any.
-            if (fallbackKeyCode != -1) {
-                // Dispatch the unhandled key to the policy with the cancel flag.
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-                ALOGD("Unhandled key event: Asking policy to cancel fallback action.  "
-                        "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
-                        keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
-                        keyEntry->policyFlags);
-#endif
-                KeyEvent event;
-                initializeKeyEvent(&event, keyEntry);
-                event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
-
-                mLock.unlock();
-
-                mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
-                        &event, keyEntry->policyFlags, &event);
-
-                mLock.lock();
-
-                // Cancel the fallback key.
-                if (fallbackKeyCode != AKEYCODE_UNKNOWN) {
-                    CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
-                            "application handled the original non-fallback key "
-                            "or is no longer a foreground target, "
-                            "canceling previously dispatched fallback key");
-                    options.keyCode = fallbackKeyCode;
-                    synthesizeCancelationEventsForConnectionLocked(connection, options);
-                }
-                connection->inputState.removeFallbackKey(originalKeyCode);
-            }
-        } else {
-            // If the application did not handle a non-fallback key, first check
-            // that we are in a good state to perform unhandled key event processing
-            // Then ask the policy what to do with it.
-            bool initialDown = keyEntry->action == AKEY_EVENT_ACTION_DOWN
-                    && keyEntry->repeatCount == 0;
-            if (fallbackKeyCode == -1 && !initialDown) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-                ALOGD("Unhandled key event: Skipping unhandled key event processing "
-                        "since this is not an initial down.  "
-                        "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
-                        originalKeyCode, keyEntry->action, keyEntry->repeatCount,
-                        keyEntry->policyFlags);
-#endif
-                return false;
-            }
-
-            // Dispatch the unhandled key to the policy.
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-            ALOGD("Unhandled key event: Asking policy to perform fallback action.  "
-                    "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
-                    keyEntry->keyCode, keyEntry->action, keyEntry->repeatCount,
-                    keyEntry->policyFlags);
-#endif
-            KeyEvent event;
-            initializeKeyEvent(&event, keyEntry);
-
-            mLock.unlock();
-
-            bool fallback = mPolicy->dispatchUnhandledKey(connection->inputWindowHandle,
-                    &event, keyEntry->policyFlags, &event);
-
-            mLock.lock();
-
-            if (connection->status != Connection::STATUS_NORMAL) {
-                connection->inputState.removeFallbackKey(originalKeyCode);
-                return false;
-            }
-
-            // Latch the fallback keycode for this key on an initial down.
-            // The fallback keycode cannot change at any other point in the lifecycle.
-            if (initialDown) {
-                if (fallback) {
-                    fallbackKeyCode = event.getKeyCode();
-                } else {
-                    fallbackKeyCode = AKEYCODE_UNKNOWN;
-                }
-                connection->inputState.setFallbackKey(originalKeyCode, fallbackKeyCode);
-            }
-
-            ALOG_ASSERT(fallbackKeyCode != -1);
-
-            // Cancel the fallback key if the policy decides not to send it anymore.
-            // We will continue to dispatch the key to the policy but we will no
-            // longer dispatch a fallback key to the application.
-            if (fallbackKeyCode != AKEYCODE_UNKNOWN
-                    && (!fallback || fallbackKeyCode != event.getKeyCode())) {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-                if (fallback) {
-                    ALOGD("Unhandled key event: Policy requested to send key %d"
-                            "as a fallback for %d, but on the DOWN it had requested "
-                            "to send %d instead.  Fallback canceled.",
-                            event.getKeyCode(), originalKeyCode, fallbackKeyCode);
-                } else {
-                    ALOGD("Unhandled key event: Policy did not request fallback for %d, "
-                            "but on the DOWN it had requested to send %d.  "
-                            "Fallback canceled.",
-                            originalKeyCode, fallbackKeyCode);
-                }
-#endif
-
-                CancelationOptions options(CancelationOptions::CANCEL_FALLBACK_EVENTS,
-                        "canceling fallback, policy no longer desires it");
-                options.keyCode = fallbackKeyCode;
-                synthesizeCancelationEventsForConnectionLocked(connection, options);
-
-                fallback = false;
-                fallbackKeyCode = AKEYCODE_UNKNOWN;
-                if (keyEntry->action != AKEY_EVENT_ACTION_UP) {
-                    connection->inputState.setFallbackKey(originalKeyCode,
-                            fallbackKeyCode);
-                }
-            }
-
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-            {
-                String8 msg;
-                const KeyedVector<int32_t, int32_t>& fallbackKeys =
-                        connection->inputState.getFallbackKeys();
-                for (size_t i = 0; i < fallbackKeys.size(); i++) {
-                    msg.appendFormat(", %d->%d", fallbackKeys.keyAt(i),
-                            fallbackKeys.valueAt(i));
-                }
-                ALOGD("Unhandled key event: %d currently tracked fallback keys%s.",
-                        fallbackKeys.size(), msg.string());
-            }
-#endif
-
-            if (fallback) {
-                // Restart the dispatch cycle using the fallback key.
-                keyEntry->eventTime = event.getEventTime();
-                keyEntry->deviceId = event.getDeviceId();
-                keyEntry->source = event.getSource();
-                keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
-                keyEntry->keyCode = fallbackKeyCode;
-                keyEntry->scanCode = event.getScanCode();
-                keyEntry->metaState = event.getMetaState();
-                keyEntry->repeatCount = event.getRepeatCount();
-                keyEntry->downTime = event.getDownTime();
-                keyEntry->syntheticRepeat = false;
-
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-                ALOGD("Unhandled key event: Dispatching fallback key.  "
-                        "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
-                        originalKeyCode, fallbackKeyCode, keyEntry->metaState);
-#endif
-                return true; // restart the event
-            } else {
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-                ALOGD("Unhandled key event: No fallback key.");
-#endif
-            }
-        }
-    }
-    return false;
-}
-
-bool InputDispatcher::afterMotionEventLockedInterruptible(const sp<Connection>& connection,
-        DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled) {
-    return false;
-}
-
-void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
-    mLock.unlock();
-
-    mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
-
-    mLock.lock();
-}
-
-void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
-    event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
-            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
-            entry->downTime, entry->eventTime);
-}
-
-void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
-        int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
-    // TODO Write some statistics about how long we spend waiting.
-}
-
-void InputDispatcher::traceInboundQueueLengthLocked() {
-    if (ATRACE_ENABLED()) {
-        ATRACE_INT("iq", mInboundQueue.count());
-    }
-}
-
-void InputDispatcher::traceOutboundQueueLengthLocked(const sp<Connection>& connection) {
-    if (ATRACE_ENABLED()) {
-        char counterName[40];
-        snprintf(counterName, sizeof(counterName), "oq:%s", connection->getWindowName());
-        ATRACE_INT(counterName, connection->outboundQueue.count());
-    }
-}
-
-void InputDispatcher::traceWaitQueueLengthLocked(const sp<Connection>& connection) {
-    if (ATRACE_ENABLED()) {
-        char counterName[40];
-        snprintf(counterName, sizeof(counterName), "wq:%s", connection->getWindowName());
-        ATRACE_INT(counterName, connection->waitQueue.count());
-    }
-}
-
-void InputDispatcher::dump(String8& dump) {
-    AutoMutex _l(mLock);
-
-    dump.append("Input Dispatcher State:\n");
-    dumpDispatchStateLocked(dump);
-
-    if (!mLastANRState.isEmpty()) {
-        dump.append("\nInput Dispatcher State at time of last ANR:\n");
-        dump.append(mLastANRState);
-    }
-}
-
-void InputDispatcher::monitor() {
-    // Acquire and release the lock to ensure that the dispatcher has not deadlocked.
-    mLock.lock();
-    mLooper->wake();
-    mDispatcherIsAliveCondition.wait(mLock);
-    mLock.unlock();
-}
-
-
-// --- InputDispatcher::Queue ---
-
-template <typename T>
-uint32_t InputDispatcher::Queue<T>::count() const {
-    uint32_t result = 0;
-    for (const T* entry = head; entry; entry = entry->next) {
-        result += 1;
-    }
-    return result;
-}
-
-
-// --- InputDispatcher::InjectionState ---
-
-InputDispatcher::InjectionState::InjectionState(int32_t injectorPid, int32_t injectorUid) :
-        refCount(1),
-        injectorPid(injectorPid), injectorUid(injectorUid),
-        injectionResult(INPUT_EVENT_INJECTION_PENDING), injectionIsAsync(false),
-        pendingForegroundDispatches(0) {
-}
-
-InputDispatcher::InjectionState::~InjectionState() {
-}
-
-void InputDispatcher::InjectionState::release() {
-    refCount -= 1;
-    if (refCount == 0) {
-        delete this;
-    } else {
-        ALOG_ASSERT(refCount > 0);
-    }
-}
-
-
-// --- InputDispatcher::EventEntry ---
-
-InputDispatcher::EventEntry::EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags) :
-        refCount(1), type(type), eventTime(eventTime), policyFlags(policyFlags),
-        injectionState(NULL), dispatchInProgress(false) {
-}
-
-InputDispatcher::EventEntry::~EventEntry() {
-    releaseInjectionState();
-}
-
-void InputDispatcher::EventEntry::release() {
-    refCount -= 1;
-    if (refCount == 0) {
-        delete this;
-    } else {
-        ALOG_ASSERT(refCount > 0);
-    }
-}
-
-void InputDispatcher::EventEntry::releaseInjectionState() {
-    if (injectionState) {
-        injectionState->release();
-        injectionState = NULL;
-    }
-}
-
-
-// --- InputDispatcher::ConfigurationChangedEntry ---
-
-InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t eventTime) :
-        EventEntry(TYPE_CONFIGURATION_CHANGED, eventTime, 0) {
-}
-
-InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
-}
-
-void InputDispatcher::ConfigurationChangedEntry::appendDescription(String8& msg) const {
-    msg.append("ConfigurationChangedEvent(), policyFlags=0x%08x",
-            policyFlags);
-}
-
-
-// --- InputDispatcher::DeviceResetEntry ---
-
-InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t deviceId) :
-        EventEntry(TYPE_DEVICE_RESET, eventTime, 0),
-        deviceId(deviceId) {
-}
-
-InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
-}
-
-void InputDispatcher::DeviceResetEntry::appendDescription(String8& msg) const {
-    msg.appendFormat("DeviceResetEvent(deviceId=%d), policyFlags=0x%08x",
-            deviceId, policyFlags);
-}
-
-
-// --- InputDispatcher::KeyEntry ---
-
-InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
-        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
-        int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
-        int32_t repeatCount, nsecs_t downTime) :
-        EventEntry(TYPE_KEY, eventTime, policyFlags),
-        deviceId(deviceId), source(source), action(action), flags(flags),
-        keyCode(keyCode), scanCode(scanCode), metaState(metaState),
-        repeatCount(repeatCount), downTime(downTime),
-        syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
-        interceptKeyWakeupTime(0) {
-}
-
-InputDispatcher::KeyEntry::~KeyEntry() {
-}
-
-void InputDispatcher::KeyEntry::appendDescription(String8& msg) const {
-    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() {
-    releaseInjectionState();
-
-    dispatchInProgress = false;
-    syntheticRepeat = false;
-    interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
-    interceptKeyWakeupTime = 0;
-}
-
-
-// --- InputDispatcher::MotionEntry ---
-
-InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
-        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
-        int32_t metaState, int32_t buttonState,
-        int32_t edgeFlags, float xPrecision, float yPrecision,
-        nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
-        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
-        float xOffset, float yOffset) :
-        EventEntry(TYPE_MOTION, eventTime, policyFlags),
-        eventTime(eventTime),
-        deviceId(deviceId), source(source), action(action), flags(flags),
-        metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
-        xPrecision(xPrecision), yPrecision(yPrecision),
-        downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        this->pointerProperties[i].copyFrom(pointerProperties[i]);
-        this->pointerCoords[i].copyFrom(pointerCoords[i]);
-        if (xOffset || yOffset) {
-            this->pointerCoords[i].applyOffset(xOffset, yOffset);
-        }
-    }
-}
-
-InputDispatcher::MotionEntry::~MotionEntry() {
-}
-
-void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
-    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);
-}
-
-
-// --- InputDispatcher::DispatchEntry ---
-
-volatile int32_t InputDispatcher::DispatchEntry::sNextSeqAtomic;
-
-InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
-        int32_t targetFlags, float xOffset, float yOffset, float scaleFactor) :
-        seq(nextSeq()),
-        eventEntry(eventEntry), targetFlags(targetFlags),
-        xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
-        deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
-    eventEntry->refCount += 1;
-}
-
-InputDispatcher::DispatchEntry::~DispatchEntry() {
-    eventEntry->release();
-}
-
-uint32_t InputDispatcher::DispatchEntry::nextSeq() {
-    // Sequence number 0 is reserved and will never be returned.
-    uint32_t seq;
-    do {
-        seq = android_atomic_inc(&sNextSeqAtomic);
-    } while (!seq);
-    return seq;
-}
-
-
-// --- InputDispatcher::InputState ---
-
-InputDispatcher::InputState::InputState() {
-}
-
-InputDispatcher::InputState::~InputState() {
-}
-
-bool InputDispatcher::InputState::isNeutral() const {
-    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
-}
-
-bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
-        int32_t displayId) const {
-    for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
-        if (memento.deviceId == deviceId
-                && memento.source == source
-                && memento.displayId == displayId
-                && memento.hovering) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool InputDispatcher::InputState::trackKey(const KeyEntry* entry,
-        int32_t action, int32_t flags) {
-    switch (action) {
-    case AKEY_EVENT_ACTION_UP: {
-        if (entry->flags & AKEY_EVENT_FLAG_FALLBACK) {
-            for (size_t i = 0; i < mFallbackKeys.size(); ) {
-                if (mFallbackKeys.valueAt(i) == entry->keyCode) {
-                    mFallbackKeys.removeItemsAt(i);
-                } else {
-                    i += 1;
-                }
-            }
-        }
-        ssize_t index = findKeyMemento(entry);
-        if (index >= 0) {
-            mKeyMementos.removeAt(index);
-            return true;
-        }
-        /* FIXME: We can't just drop the key up event because that prevents creating
-         * popup windows that are automatically shown when a key is held and then
-         * dismissed when the key is released.  The problem is that the popup will
-         * not have received the original key down, so the key up will be considered
-         * to be inconsistent with its observed state.  We could perhaps handle this
-         * by synthesizing a key down but that will cause other problems.
-         *
-         * So for now, allow inconsistent key up events to be dispatched.
-         *
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-        ALOGD("Dropping inconsistent key up event: deviceId=%d, source=%08x, "
-                "keyCode=%d, scanCode=%d",
-                entry->deviceId, entry->source, entry->keyCode, entry->scanCode);
-#endif
-        return false;
-        */
-        return true;
-    }
-
-    case AKEY_EVENT_ACTION_DOWN: {
-        ssize_t index = findKeyMemento(entry);
-        if (index >= 0) {
-            mKeyMementos.removeAt(index);
-        }
-        addKeyMemento(entry, flags);
-        return true;
-    }
-
-    default:
-        return true;
-    }
-}
-
-bool InputDispatcher::InputState::trackMotion(const MotionEntry* entry,
-        int32_t action, int32_t flags) {
-    int32_t actionMasked = action & AMOTION_EVENT_ACTION_MASK;
-    switch (actionMasked) {
-    case AMOTION_EVENT_ACTION_UP:
-    case AMOTION_EVENT_ACTION_CANCEL: {
-        ssize_t index = findMotionMemento(entry, false /*hovering*/);
-        if (index >= 0) {
-            mMotionMementos.removeAt(index);
-            return true;
-        }
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-        ALOGD("Dropping inconsistent motion up or cancel event: deviceId=%d, source=%08x, "
-                "actionMasked=%d",
-                entry->deviceId, entry->source, actionMasked);
-#endif
-        return false;
-    }
-
-    case AMOTION_EVENT_ACTION_DOWN: {
-        ssize_t index = findMotionMemento(entry, false /*hovering*/);
-        if (index >= 0) {
-            mMotionMementos.removeAt(index);
-        }
-        addMotionMemento(entry, flags, false /*hovering*/);
-        return true;
-    }
-
-    case AMOTION_EVENT_ACTION_POINTER_UP:
-    case AMOTION_EVENT_ACTION_POINTER_DOWN:
-    case AMOTION_EVENT_ACTION_MOVE: {
-        ssize_t index = findMotionMemento(entry, false /*hovering*/);
-        if (index >= 0) {
-            MotionMemento& memento = mMotionMementos.editItemAt(index);
-            memento.setPointers(entry);
-            return true;
-        }
-        if (actionMasked == AMOTION_EVENT_ACTION_MOVE
-                && (entry->source & (AINPUT_SOURCE_CLASS_JOYSTICK
-                        | AINPUT_SOURCE_CLASS_NAVIGATION))) {
-            // Joysticks and trackballs can send MOVE events without corresponding DOWN or UP.
-            return true;
-        }
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-        ALOGD("Dropping inconsistent motion pointer up/down or move event: "
-                "deviceId=%d, source=%08x, actionMasked=%d",
-                entry->deviceId, entry->source, actionMasked);
-#endif
-        return false;
-    }
-
-    case AMOTION_EVENT_ACTION_HOVER_EXIT: {
-        ssize_t index = findMotionMemento(entry, true /*hovering*/);
-        if (index >= 0) {
-            mMotionMementos.removeAt(index);
-            return true;
-        }
-#if DEBUG_OUTBOUND_EVENT_DETAILS
-        ALOGD("Dropping inconsistent motion hover exit event: deviceId=%d, source=%08x",
-                entry->deviceId, entry->source);
-#endif
-        return false;
-    }
-
-    case AMOTION_EVENT_ACTION_HOVER_ENTER:
-    case AMOTION_EVENT_ACTION_HOVER_MOVE: {
-        ssize_t index = findMotionMemento(entry, true /*hovering*/);
-        if (index >= 0) {
-            mMotionMementos.removeAt(index);
-        }
-        addMotionMemento(entry, flags, true /*hovering*/);
-        return true;
-    }
-
-    default:
-        return true;
-    }
-}
-
-ssize_t InputDispatcher::InputState::findKeyMemento(const KeyEntry* entry) const {
-    for (size_t i = 0; i < mKeyMementos.size(); i++) {
-        const KeyMemento& memento = mKeyMementos.itemAt(i);
-        if (memento.deviceId == entry->deviceId
-                && memento.source == entry->source
-                && memento.keyCode == entry->keyCode
-                && memento.scanCode == entry->scanCode) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
-        bool hovering) const {
-    for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
-        if (memento.deviceId == entry->deviceId
-                && memento.source == entry->source
-                && memento.displayId == entry->displayId
-                && memento.hovering == hovering) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-void InputDispatcher::InputState::addKeyMemento(const KeyEntry* entry, int32_t flags) {
-    mKeyMementos.push();
-    KeyMemento& memento = mKeyMementos.editTop();
-    memento.deviceId = entry->deviceId;
-    memento.source = entry->source;
-    memento.keyCode = entry->keyCode;
-    memento.scanCode = entry->scanCode;
-    memento.metaState = entry->metaState;
-    memento.flags = flags;
-    memento.downTime = entry->downTime;
-    memento.policyFlags = entry->policyFlags;
-}
-
-void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
-        int32_t flags, bool hovering) {
-    mMotionMementos.push();
-    MotionMemento& memento = mMotionMementos.editTop();
-    memento.deviceId = entry->deviceId;
-    memento.source = entry->source;
-    memento.flags = flags;
-    memento.xPrecision = entry->xPrecision;
-    memento.yPrecision = entry->yPrecision;
-    memento.downTime = entry->downTime;
-    memento.displayId = entry->displayId;
-    memento.setPointers(entry);
-    memento.hovering = hovering;
-    memento.policyFlags = entry->policyFlags;
-}
-
-void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
-    pointerCount = entry->pointerCount;
-    for (uint32_t i = 0; i < entry->pointerCount; i++) {
-        pointerProperties[i].copyFrom(entry->pointerProperties[i]);
-        pointerCoords[i].copyFrom(entry->pointerCoords[i]);
-    }
-}
-
-void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
-        Vector<EventEntry*>& outEvents, const CancelationOptions& options) {
-    for (size_t i = 0; i < mKeyMementos.size(); i++) {
-        const KeyMemento& memento = mKeyMementos.itemAt(i);
-        if (shouldCancelKey(memento, options)) {
-            outEvents.push(new KeyEntry(currentTime,
-                    memento.deviceId, memento.source, memento.policyFlags,
-                    AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
-                    memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
-        }
-    }
-
-    for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
-        if (shouldCancelMotion(memento, options)) {
-            outEvents.push(new MotionEntry(currentTime,
-                    memento.deviceId, memento.source, memento.policyFlags,
-                    memento.hovering
-                            ? AMOTION_EVENT_ACTION_HOVER_EXIT
-                            : AMOTION_EVENT_ACTION_CANCEL,
-                    memento.flags, 0, 0, 0,
-                    memento.xPrecision, memento.yPrecision, memento.downTime,
-                    memento.displayId,
-                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords,
-                    0, 0));
-        }
-    }
-}
-
-void InputDispatcher::InputState::clear() {
-    mKeyMementos.clear();
-    mMotionMementos.clear();
-    mFallbackKeys.clear();
-}
-
-void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
-    for (size_t i = 0; i < mMotionMementos.size(); i++) {
-        const MotionMemento& memento = mMotionMementos.itemAt(i);
-        if (memento.source & AINPUT_SOURCE_CLASS_POINTER) {
-            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
-                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
-                if (memento.deviceId == otherMemento.deviceId
-                        && memento.source == otherMemento.source
-                        && memento.displayId == otherMemento.displayId) {
-                    other.mMotionMementos.removeAt(j);
-                } else {
-                    j += 1;
-                }
-            }
-            other.mMotionMementos.push(memento);
-        }
-    }
-}
-
-int32_t InputDispatcher::InputState::getFallbackKey(int32_t originalKeyCode) {
-    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
-    return index >= 0 ? mFallbackKeys.valueAt(index) : -1;
-}
-
-void InputDispatcher::InputState::setFallbackKey(int32_t originalKeyCode,
-        int32_t fallbackKeyCode) {
-    ssize_t index = mFallbackKeys.indexOfKey(originalKeyCode);
-    if (index >= 0) {
-        mFallbackKeys.replaceValueAt(index, fallbackKeyCode);
-    } else {
-        mFallbackKeys.add(originalKeyCode, fallbackKeyCode);
-    }
-}
-
-void InputDispatcher::InputState::removeFallbackKey(int32_t originalKeyCode) {
-    mFallbackKeys.removeItem(originalKeyCode);
-}
-
-bool InputDispatcher::InputState::shouldCancelKey(const KeyMemento& memento,
-        const CancelationOptions& options) {
-    if (options.keyCode != -1 && memento.keyCode != options.keyCode) {
-        return false;
-    }
-
-    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
-        return false;
-    }
-
-    switch (options.mode) {
-    case CancelationOptions::CANCEL_ALL_EVENTS:
-    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
-        return true;
-    case CancelationOptions::CANCEL_FALLBACK_EVENTS:
-        return memento.flags & AKEY_EVENT_FLAG_FALLBACK;
-    default:
-        return false;
-    }
-}
-
-bool InputDispatcher::InputState::shouldCancelMotion(const MotionMemento& memento,
-        const CancelationOptions& options) {
-    if (options.deviceId != -1 && memento.deviceId != options.deviceId) {
-        return false;
-    }
-
-    switch (options.mode) {
-    case CancelationOptions::CANCEL_ALL_EVENTS:
-        return true;
-    case CancelationOptions::CANCEL_POINTER_EVENTS:
-        return memento.source & AINPUT_SOURCE_CLASS_POINTER;
-    case CancelationOptions::CANCEL_NON_POINTER_EVENTS:
-        return !(memento.source & AINPUT_SOURCE_CLASS_POINTER);
-    default:
-        return false;
-    }
-}
-
-
-// --- InputDispatcher::Connection ---
-
-InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel,
-        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) :
-        status(STATUS_NORMAL), inputChannel(inputChannel), inputWindowHandle(inputWindowHandle),
-        monitor(monitor),
-        inputPublisher(inputChannel), inputPublisherBlocked(false) {
-}
-
-InputDispatcher::Connection::~Connection() {
-}
-
-const char* InputDispatcher::Connection::getWindowName() const {
-    if (inputWindowHandle != NULL) {
-        return inputWindowHandle->getName().string();
-    }
-    if (monitor) {
-        return "monitor";
-    }
-    return "?";
-}
-
-const char* InputDispatcher::Connection::getStatusLabel() const {
-    switch (status) {
-    case STATUS_NORMAL:
-        return "NORMAL";
-
-    case STATUS_BROKEN:
-        return "BROKEN";
-
-    case STATUS_ZOMBIE:
-        return "ZOMBIE";
-
-    default:
-        return "UNKNOWN";
-    }
-}
-
-InputDispatcher::DispatchEntry* InputDispatcher::Connection::findWaitQueueEntry(uint32_t seq) {
-    for (DispatchEntry* entry = waitQueue.head; entry != NULL; entry = entry->next) {
-        if (entry->seq == seq) {
-            return entry;
-        }
-    }
-    return NULL;
-}
-
-
-// --- InputDispatcher::CommandEntry ---
-
-InputDispatcher::CommandEntry::CommandEntry(Command command) :
-    command(command), eventTime(0), keyEntry(NULL), userActivityEventType(0),
-    seq(0), handled(false) {
-}
-
-InputDispatcher::CommandEntry::~CommandEntry() {
-}
-
-
-// --- InputDispatcher::TouchState ---
-
-InputDispatcher::TouchState::TouchState() :
-    down(false), split(false), deviceId(-1), source(0), displayId(-1) {
-}
-
-InputDispatcher::TouchState::~TouchState() {
-}
-
-void InputDispatcher::TouchState::reset() {
-    down = false;
-    split = false;
-    deviceId = -1;
-    source = 0;
-    displayId = -1;
-    windows.clear();
-}
-
-void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
-    down = other.down;
-    split = other.split;
-    deviceId = other.deviceId;
-    source = other.source;
-    displayId = other.displayId;
-    windows = other.windows;
-}
-
-void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
-        int32_t targetFlags, BitSet32 pointerIds) {
-    if (targetFlags & InputTarget::FLAG_SPLIT) {
-        split = true;
-    }
-
-    for (size_t i = 0; i < windows.size(); i++) {
-        TouchedWindow& touchedWindow = windows.editItemAt(i);
-        if (touchedWindow.windowHandle == windowHandle) {
-            touchedWindow.targetFlags |= targetFlags;
-            if (targetFlags & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
-                touchedWindow.targetFlags &= ~InputTarget::FLAG_DISPATCH_AS_IS;
-            }
-            touchedWindow.pointerIds.value |= pointerIds.value;
-            return;
-        }
-    }
-
-    windows.push();
-
-    TouchedWindow& touchedWindow = windows.editTop();
-    touchedWindow.windowHandle = windowHandle;
-    touchedWindow.targetFlags = targetFlags;
-    touchedWindow.pointerIds = pointerIds;
-}
-
-void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
-    for (size_t i = 0; i < windows.size(); i++) {
-        if (windows.itemAt(i).windowHandle == windowHandle) {
-            windows.removeAt(i);
-            return;
-        }
-    }
-}
-
-void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
-    for (size_t i = 0 ; i < windows.size(); ) {
-        TouchedWindow& window = windows.editItemAt(i);
-        if (window.targetFlags & (InputTarget::FLAG_DISPATCH_AS_IS
-                | InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER)) {
-            window.targetFlags &= ~InputTarget::FLAG_DISPATCH_MASK;
-            window.targetFlags |= InputTarget::FLAG_DISPATCH_AS_IS;
-            i += 1;
-        } else {
-            windows.removeAt(i);
-        }
-    }
-}
-
-sp<InputWindowHandle> InputDispatcher::TouchState::getFirstForegroundWindowHandle() const {
-    for (size_t i = 0; i < windows.size(); i++) {
-        const TouchedWindow& window = windows.itemAt(i);
-        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
-            return window.windowHandle;
-        }
-    }
-    return NULL;
-}
-
-bool InputDispatcher::TouchState::isSlippery() const {
-    // Must have exactly one foreground window.
-    bool haveSlipperyForegroundWindow = false;
-    for (size_t i = 0; i < windows.size(); i++) {
-        const TouchedWindow& window = windows.itemAt(i);
-        if (window.targetFlags & InputTarget::FLAG_FOREGROUND) {
-            if (haveSlipperyForegroundWindow
-                    || !(window.windowHandle->getInfo()->layoutParamsFlags
-                            & InputWindowInfo::FLAG_SLIPPERY)) {
-                return false;
-            }
-            haveSlipperyForegroundWindow = true;
-        }
-    }
-    return haveSlipperyForegroundWindow;
-}
-
-
-// --- InputDispatcherThread ---
-
-InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
-        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
-}
-
-InputDispatcherThread::~InputDispatcherThread() {
-}
-
-bool InputDispatcherThread::threadLoop() {
-    mDispatcher->dispatchOnce();
-    return true;
-}
-
-} // namespace android
diff --git a/libs/input/InputDispatcher.h b/libs/input/InputDispatcher.h
deleted file mode 100644
index 29854b2..0000000
--- a/libs/input/InputDispatcher.h
+++ /dev/null
@@ -1,1124 +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 _UI_INPUT_DISPATCHER_H
-#define _UI_INPUT_DISPATCHER_H
-
-#include <input/Input.h>
-#include <input/InputTransport.h>
-#include <utils/KeyedVector.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/Looper.h>
-#include <utils/BitSet.h>
-#include <cutils/atomic.h>
-
-#include <stddef.h>
-#include <unistd.h>
-#include <limits.h>
-
-#include "InputWindow.h"
-#include "InputApplication.h"
-#include "InputListener.h"
-
-
-namespace android {
-
-/*
- * Constants used to report the outcome of input event injection.
- */
-enum {
-    /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
-    INPUT_EVENT_INJECTION_PENDING = -1,
-
-    /* Injection succeeded. */
-    INPUT_EVENT_INJECTION_SUCCEEDED = 0,
-
-    /* Injection failed because the injector did not have permission to inject
-     * into the application with input focus. */
-    INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1,
-
-    /* Injection failed because there were no available input targets. */
-    INPUT_EVENT_INJECTION_FAILED = 2,
-
-    /* Injection failed due to a timeout. */
-    INPUT_EVENT_INJECTION_TIMED_OUT = 3
-};
-
-/*
- * Constants used to determine the input event injection synchronization mode.
- */
-enum {
-    /* Injection is asynchronous and is assumed always to be successful. */
-    INPUT_EVENT_INJECTION_SYNC_NONE = 0,
-
-    /* Waits for previous events to be dispatched so that the input dispatcher can determine
-     * whether input event injection willbe permitted based on the current input focus.
-     * Does not wait for the input event to finish processing. */
-    INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1,
-
-    /* Waits for the input event to be completely processed. */
-    INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2,
-};
-
-
-/*
- * An input target specifies how an input event is to be dispatched to a particular window
- * including the window's input channel, control flags, a timeout, and an X / Y offset to
- * be added to input event coordinates to compensate for the absolute position of the
- * window area.
- */
-struct InputTarget {
-    enum {
-        /* This flag indicates that the event is being delivered to a foreground application. */
-        FLAG_FOREGROUND = 1 << 0,
-
-        /* This flag indicates that the target of a MotionEvent is partly or wholly
-         * obscured by another visible window above it.  The motion event should be
-         * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
-        FLAG_WINDOW_IS_OBSCURED = 1 << 1,
-
-        /* This flag indicates that a motion event is being split across multiple windows. */
-        FLAG_SPLIT = 1 << 2,
-
-        /* This flag indicates that the pointer coordinates dispatched to the application
-         * will be zeroed out to avoid revealing information to an application. This is
-         * used in conjunction with FLAG_DISPATCH_AS_OUTSIDE to prevent apps not sharing
-         * the same UID from watching all touches. */
-        FLAG_ZERO_COORDS = 1 << 3,
-
-        /* This flag indicates that the event should be sent as is.
-         * Should always be set unless the event is to be transmuted. */
-        FLAG_DISPATCH_AS_IS = 1 << 8,
-
-        /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside
-         * of the area of this target and so should instead be delivered as an
-         * AMOTION_EVENT_ACTION_OUTSIDE to this target. */
-        FLAG_DISPATCH_AS_OUTSIDE = 1 << 9,
-
-        /* This flag indicates that a hover sequence is starting in the given window.
-         * The event is transmuted into ACTION_HOVER_ENTER. */
-        FLAG_DISPATCH_AS_HOVER_ENTER = 1 << 10,
-
-        /* This flag indicates that a hover event happened outside of a window which handled
-         * previous hover events, signifying the end of the current hover sequence for that
-         * window.
-         * The event is transmuted into ACTION_HOVER_ENTER. */
-        FLAG_DISPATCH_AS_HOVER_EXIT = 1 << 11,
-
-        /* This flag indicates that the event should be canceled.
-         * It is used to transmute ACTION_MOVE into ACTION_CANCEL when a touch slips
-         * outside of a window. */
-        FLAG_DISPATCH_AS_SLIPPERY_EXIT = 1 << 12,
-
-        /* This flag indicates that the event should be dispatched as an initial down.
-         * It is used to transmute ACTION_MOVE into ACTION_DOWN when a touch slips
-         * into a new window. */
-        FLAG_DISPATCH_AS_SLIPPERY_ENTER = 1 << 13,
-
-        /* Mask for all dispatch modes. */
-        FLAG_DISPATCH_MASK = FLAG_DISPATCH_AS_IS
-                | FLAG_DISPATCH_AS_OUTSIDE
-                | FLAG_DISPATCH_AS_HOVER_ENTER
-                | FLAG_DISPATCH_AS_HOVER_EXIT
-                | FLAG_DISPATCH_AS_SLIPPERY_EXIT
-                | FLAG_DISPATCH_AS_SLIPPERY_ENTER,
-    };
-
-    // The input channel to be targeted.
-    sp<InputChannel> inputChannel;
-
-    // Flags for the input target.
-    int32_t flags;
-
-    // The x and y offset to add to a MotionEvent as it is delivered.
-    // (ignored for KeyEvents)
-    float xOffset, yOffset;
-
-    // Scaling factor to apply to MotionEvent as it is delivered.
-    // (ignored for KeyEvents)
-    float scaleFactor;
-
-    // The subset of pointer ids to include in motion events dispatched to this input target
-    // if FLAG_SPLIT is set.
-    BitSet32 pointerIds;
-};
-
-
-/*
- * Input dispatcher configuration.
- *
- * Specifies various options that modify the behavior of the input dispatcher.
- * The values provided here are merely defaults. The actual values will come from ViewConfiguration
- * and are passed into the dispatcher during initialization.
- */
-struct InputDispatcherConfiguration {
-    // The key repeat initial timeout.
-    nsecs_t keyRepeatTimeout;
-
-    // The key repeat inter-key delay.
-    nsecs_t keyRepeatDelay;
-
-    InputDispatcherConfiguration() :
-            keyRepeatTimeout(500 * 1000000LL),
-            keyRepeatDelay(50 * 1000000LL) { }
-};
-
-
-/*
- * Input dispatcher policy interface.
- *
- * The input reader policy is used by the input reader to interact with the Window Manager
- * and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI.  This interface is also mocked in the unit tests.
- */
-class InputDispatcherPolicyInterface : public virtual RefBase {
-protected:
-    InputDispatcherPolicyInterface() { }
-    virtual ~InputDispatcherPolicyInterface() { }
-
-public:
-    /* Notifies the system that a configuration change has occurred. */
-    virtual void notifyConfigurationChanged(nsecs_t when) = 0;
-
-    /* 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,
-            const String8& reason) = 0;
-
-    /* Notifies the system that an input channel is unrecoverably broken. */
-    virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) = 0;
-
-    /* Gets the input dispatcher configuration. */
-    virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) = 0;
-
-    /* Returns true if automatic key repeating is enabled. */
-    virtual bool isKeyRepeatEnabled() = 0;
-
-    /* Filters an input event.
-     * Return true to dispatch the event unmodified, false to consume the event.
-     * A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED
-     * to injectInputEvent.
-     */
-    virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) = 0;
-
-    /* Intercepts a key event immediately before queueing it.
-     * The policy can use this method as an opportunity to perform power management functions
-     * and early event preprocessing such as updating policy flags.
-     *
-     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
-     * should be dispatched to applications.
-     */
-    virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) = 0;
-
-    /* Intercepts a touch, trackball or other motion event before queueing it.
-     * The policy can use this method as an opportunity to perform power management functions
-     * and early event preprocessing such as updating policy flags.
-     *
-     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
-     * should be dispatched to applications.
-     */
-    virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
-
-    /* Allows the policy a chance to intercept a key before dispatching. */
-    virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
-            const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
-
-    /* Allows the policy a chance to perform default processing for an unhandled key.
-     * Returns an alternate keycode to redispatch as a fallback, or 0 to give up. */
-    virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
-            const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) = 0;
-
-    /* Notifies the policy about switch events.
-     */
-    virtual void notifySwitch(nsecs_t when,
-            uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) = 0;
-
-    /* Poke user activity for an event dispatched to a window. */
-    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;
-
-    /* Checks whether a given application pid/uid has permission to inject input events
-     * into other applications.
-     *
-     * This method is special in that its implementation promises to be non-reentrant and
-     * is safe to call while holding other locks.  (Most other methods make no such guarantees!)
-     */
-    virtual bool checkInjectEventsPermissionNonReentrant(
-            int32_t injectorPid, int32_t injectorUid) = 0;
-};
-
-
-/* Notifies the system about input events generated by the input reader.
- * The dispatcher is expected to be mostly asynchronous. */
-class InputDispatcherInterface : public virtual RefBase, public InputListenerInterface {
-protected:
-    InputDispatcherInterface() { }
-    virtual ~InputDispatcherInterface() { }
-
-public:
-    /* Dumps the state of the input dispatcher.
-     *
-     * This method may be called on any thread (usually by the input manager). */
-    virtual void dump(String8& dump) = 0;
-
-    /* Called by the heatbeat to ensures that the dispatcher has not deadlocked. */
-    virtual void monitor() = 0;
-
-    /* Runs a single iteration of the dispatch loop.
-     * Nominally processes one queued event, a timeout, or a response from an input consumer.
-     *
-     * This method should only be called on the input dispatcher thread.
-     */
-    virtual void dispatchOnce() = 0;
-
-    /* Injects an input event and optionally waits for sync.
-     * The synchronization mode determines whether the method blocks while waiting for
-     * input injection to proceed.
-     * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId,
-            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
-            uint32_t policyFlags) = 0;
-
-    /* Sets the list of input windows.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) = 0;
-
-    /* Sets the focused application.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void setFocusedApplication(
-            const sp<InputApplicationHandle>& inputApplicationHandle) = 0;
-
-    /* Sets the input dispatching mode.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void setInputDispatchMode(bool enabled, bool frozen) = 0;
-
-    /* Sets whether input event filtering is enabled.
-     * When enabled, incoming input events are sent to the policy's filterInputEvent
-     * method instead of being dispatched.  The filter is expected to use
-     * injectInputEvent to inject the events it would like to have dispatched.
-     * It should include POLICY_FLAG_FILTERED in the policy flags during injection.
-     */
-    virtual void setInputFilterEnabled(bool enabled) = 0;
-
-    /* Transfers touch focus from the window associated with one channel to the
-     * window associated with the other channel.
-     *
-     * Returns true on success.  False if the window did not actually have touch focus.
-     */
-    virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
-            const sp<InputChannel>& toChannel) = 0;
-
-    /* Registers or unregister input channels that may be used as targets for input events.
-     * If monitor is true, the channel will receive a copy of all input events.
-     *
-     * These methods may be called on any thread (usually by the input manager).
-     */
-    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
-            const sp<InputWindowHandle>& inputWindowHandle, bool monitor) = 0;
-    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
-};
-
-/* Dispatches events to input targets.  Some functions of the input dispatcher, such as
- * identifying input targets, are controlled by a separate policy object.
- *
- * IMPORTANT INVARIANT:
- *     Because the policy can potentially block or cause re-entrance into the input dispatcher,
- *     the input dispatcher never calls into the policy while holding its internal locks.
- *     The implementation is also carefully designed to recover from scenarios such as an
- *     input channel becoming unregistered while identifying input targets or processing timeouts.
- *
- *     Methods marked 'Locked' must be called with the lock acquired.
- *
- *     Methods marked 'LockedInterruptible' must be called with the lock acquired but
- *     may during the course of their execution release the lock, call into the policy, and
- *     then reacquire the lock.  The caller is responsible for recovering gracefully.
- *
- *     A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
- */
-class InputDispatcher : public InputDispatcherInterface {
-protected:
-    virtual ~InputDispatcher();
-
-public:
-    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
-
-    virtual void dump(String8& dump);
-    virtual void monitor();
-
-    virtual void dispatchOnce();
-
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
-    virtual void notifyKey(const NotifyKeyArgs* args);
-    virtual void notifyMotion(const NotifyMotionArgs* args);
-    virtual void notifySwitch(const NotifySwitchArgs* args);
-    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
-
-    virtual int32_t injectInputEvent(const InputEvent* event, int32_t displayId,
-            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
-            uint32_t policyFlags);
-
-    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
-    virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
-    virtual void setInputDispatchMode(bool enabled, bool frozen);
-    virtual void setInputFilterEnabled(bool enabled);
-
-    virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
-            const sp<InputChannel>& toChannel);
-
-    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel,
-            const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
-    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
-
-private:
-    template <typename T>
-    struct Link {
-        T* next;
-        T* prev;
-
-    protected:
-        inline Link() : next(NULL), prev(NULL) { }
-    };
-
-    struct InjectionState {
-        mutable int32_t refCount;
-
-        int32_t injectorPid;
-        int32_t injectorUid;
-        int32_t injectionResult;  // initially INPUT_EVENT_INJECTION_PENDING
-        bool injectionIsAsync; // set to true if injection is not waiting for the result
-        int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
-
-        InjectionState(int32_t injectorPid, int32_t injectorUid);
-        void release();
-
-    private:
-        ~InjectionState();
-    };
-
-    struct EventEntry : Link<EventEntry> {
-        enum {
-            TYPE_CONFIGURATION_CHANGED,
-            TYPE_DEVICE_RESET,
-            TYPE_KEY,
-            TYPE_MOTION
-        };
-
-        mutable int32_t refCount;
-        int32_t type;
-        nsecs_t eventTime;
-        uint32_t policyFlags;
-        InjectionState* injectionState;
-
-        bool dispatchInProgress; // initially false, set to true while dispatching
-
-        inline bool isInjected() const { return injectionState != NULL; }
-
-        void release();
-
-        virtual void appendDescription(String8& msg) const = 0;
-
-    protected:
-        EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
-        virtual ~EventEntry();
-        void releaseInjectionState();
-    };
-
-    struct ConfigurationChangedEntry : EventEntry {
-        ConfigurationChangedEntry(nsecs_t eventTime);
-        virtual void appendDescription(String8& msg) const;
-
-    protected:
-        virtual ~ConfigurationChangedEntry();
-    };
-
-    struct DeviceResetEntry : EventEntry {
-        int32_t deviceId;
-
-        DeviceResetEntry(nsecs_t eventTime, int32_t deviceId);
-        virtual void appendDescription(String8& msg) const;
-
-    protected:
-        virtual ~DeviceResetEntry();
-    };
-
-    struct KeyEntry : EventEntry {
-        int32_t deviceId;
-        uint32_t source;
-        int32_t action;
-        int32_t flags;
-        int32_t keyCode;
-        int32_t scanCode;
-        int32_t metaState;
-        int32_t repeatCount;
-        nsecs_t downTime;
-
-        bool syntheticRepeat; // set to true for synthetic key repeats
-
-        enum InterceptKeyResult {
-            INTERCEPT_KEY_RESULT_UNKNOWN,
-            INTERCEPT_KEY_RESULT_SKIP,
-            INTERCEPT_KEY_RESULT_CONTINUE,
-            INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER,
-        };
-        InterceptKeyResult interceptKeyResult; // set based on the interception result
-        nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
-
-        KeyEntry(nsecs_t eventTime,
-                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
-                int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
-                int32_t repeatCount, nsecs_t downTime);
-        virtual void appendDescription(String8& msg) const;
-        void recycle();
-
-    protected:
-        virtual ~KeyEntry();
-    };
-
-    struct MotionEntry : EventEntry {
-        nsecs_t eventTime;
-        int32_t deviceId;
-        uint32_t source;
-        int32_t action;
-        int32_t flags;
-        int32_t metaState;
-        int32_t buttonState;
-        int32_t edgeFlags;
-        float xPrecision;
-        float yPrecision;
-        nsecs_t downTime;
-        int32_t displayId;
-        uint32_t pointerCount;
-        PointerProperties pointerProperties[MAX_POINTERS];
-        PointerCoords pointerCoords[MAX_POINTERS];
-
-        MotionEntry(nsecs_t eventTime,
-                int32_t deviceId, uint32_t source, uint32_t policyFlags,
-                int32_t action, int32_t flags,
-                int32_t metaState, int32_t buttonState, int32_t edgeFlags,
-                float xPrecision, float yPrecision,
-                nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
-                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
-                float xOffset, float yOffset);
-        virtual void appendDescription(String8& msg) const;
-
-    protected:
-        virtual ~MotionEntry();
-    };
-
-    // Tracks the progress of dispatching a particular event to a particular connection.
-    struct DispatchEntry : Link<DispatchEntry> {
-        const uint32_t seq; // unique sequence number, never 0
-
-        EventEntry* eventEntry; // the event to dispatch
-        int32_t targetFlags;
-        float xOffset;
-        float yOffset;
-        float scaleFactor;
-        nsecs_t deliveryTime; // time when the event was actually delivered
-
-        // Set to the resolved action and flags when the event is enqueued.
-        int32_t resolvedAction;
-        int32_t resolvedFlags;
-
-        DispatchEntry(EventEntry* eventEntry,
-                int32_t targetFlags, float xOffset, float yOffset, float scaleFactor);
-        ~DispatchEntry();
-
-        inline bool hasForegroundTarget() const {
-            return targetFlags & InputTarget::FLAG_FOREGROUND;
-        }
-
-        inline bool isSplit() const {
-            return targetFlags & InputTarget::FLAG_SPLIT;
-        }
-
-    private:
-        static volatile int32_t sNextSeqAtomic;
-
-        static uint32_t nextSeq();
-    };
-
-    // A command entry captures state and behavior for an action to be performed in the
-    // dispatch loop after the initial processing has taken place.  It is essentially
-    // a kind of continuation used to postpone sensitive policy interactions to a point
-    // in the dispatch loop where it is safe to release the lock (generally after finishing
-    // the critical parts of the dispatch cycle).
-    //
-    // The special thing about commands is that they can voluntarily release and reacquire
-    // the dispatcher lock at will.  Initially when the command starts running, the
-    // dispatcher lock is held.  However, if the command needs to call into the policy to
-    // do some work, it can release the lock, do the work, then reacquire the lock again
-    // before returning.
-    //
-    // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
-    // never calls into the policy while holding its lock.
-    //
-    // Commands are implicitly 'LockedInterruptible'.
-    struct CommandEntry;
-    typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
-
-    class Connection;
-    struct CommandEntry : Link<CommandEntry> {
-        CommandEntry(Command command);
-        ~CommandEntry();
-
-        Command command;
-
-        // parameters for the command (usage varies by command)
-        sp<Connection> connection;
-        nsecs_t eventTime;
-        KeyEntry* keyEntry;
-        sp<InputApplicationHandle> inputApplicationHandle;
-        sp<InputWindowHandle> inputWindowHandle;
-        String8 reason;
-        int32_t userActivityEventType;
-        uint32_t seq;
-        bool handled;
-    };
-
-    // Generic queue implementation.
-    template <typename T>
-    struct Queue {
-        T* head;
-        T* tail;
-
-        inline Queue() : head(NULL), tail(NULL) {
-        }
-
-        inline bool isEmpty() const {
-            return !head;
-        }
-
-        inline void enqueueAtTail(T* entry) {
-            entry->prev = tail;
-            if (tail) {
-                tail->next = entry;
-            } else {
-                head = entry;
-            }
-            entry->next = NULL;
-            tail = entry;
-        }
-
-        inline void enqueueAtHead(T* entry) {
-            entry->next = head;
-            if (head) {
-                head->prev = entry;
-            } else {
-                tail = entry;
-            }
-            entry->prev = NULL;
-            head = entry;
-        }
-
-        inline void dequeue(T* entry) {
-            if (entry->prev) {
-                entry->prev->next = entry->next;
-            } else {
-                head = entry->next;
-            }
-            if (entry->next) {
-                entry->next->prev = entry->prev;
-            } else {
-                tail = entry->prev;
-            }
-        }
-
-        inline T* dequeueAtHead() {
-            T* entry = head;
-            head = entry->next;
-            if (head) {
-                head->prev = NULL;
-            } else {
-                tail = NULL;
-            }
-            return entry;
-        }
-
-        uint32_t count() const;
-    };
-
-    /* Specifies which events are to be canceled and why. */
-    struct CancelationOptions {
-        enum Mode {
-            CANCEL_ALL_EVENTS = 0,
-            CANCEL_POINTER_EVENTS = 1,
-            CANCEL_NON_POINTER_EVENTS = 2,
-            CANCEL_FALLBACK_EVENTS = 3,
-        };
-
-        // The criterion to use to determine which events should be canceled.
-        Mode mode;
-
-        // Descriptive reason for the cancelation.
-        const char* reason;
-
-        // The specific keycode of the key event to cancel, or -1 to cancel any key event.
-        int32_t keyCode;
-
-        // The specific device id of events to cancel, or -1 to cancel events from any device.
-        int32_t deviceId;
-
-        CancelationOptions(Mode mode, const char* reason) :
-                mode(mode), reason(reason), keyCode(-1), deviceId(-1) { }
-    };
-
-    /* Tracks dispatched key and motion event state so that cancelation events can be
-     * synthesized when events are dropped. */
-    class InputState {
-    public:
-        InputState();
-        ~InputState();
-
-        // Returns true if there is no state to be canceled.
-        bool isNeutral() const;
-
-        // Returns true if the specified source is known to have received a hover enter
-        // motion event.
-        bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;
-
-        // Records tracking information for a key event that has just been published.
-        // Returns true if the event should be delivered, false if it is inconsistent
-        // and should be skipped.
-        bool trackKey(const KeyEntry* entry, int32_t action, int32_t flags);
-
-        // Records tracking information for a motion event that has just been published.
-        // Returns true if the event should be delivered, false if it is inconsistent
-        // and should be skipped.
-        bool trackMotion(const MotionEntry* entry, int32_t action, int32_t flags);
-
-        // Synthesizes cancelation events for the current state and resets the tracked state.
-        void synthesizeCancelationEvents(nsecs_t currentTime,
-                Vector<EventEntry*>& outEvents, const CancelationOptions& options);
-
-        // Clears the current state.
-        void clear();
-
-        // Copies pointer-related parts of the input state to another instance.
-        void copyPointerStateTo(InputState& other) const;
-
-        // Gets the fallback key associated with a keycode.
-        // Returns -1 if none.
-        // Returns AKEYCODE_UNKNOWN if we are only dispatching the unhandled key to the policy.
-        int32_t getFallbackKey(int32_t originalKeyCode);
-
-        // Sets the fallback key for a particular keycode.
-        void setFallbackKey(int32_t originalKeyCode, int32_t fallbackKeyCode);
-
-        // Removes the fallback key for a particular keycode.
-        void removeFallbackKey(int32_t originalKeyCode);
-
-        inline const KeyedVector<int32_t, int32_t>& getFallbackKeys() const {
-            return mFallbackKeys;
-        }
-
-    private:
-        struct KeyMemento {
-            int32_t deviceId;
-            uint32_t source;
-            int32_t keyCode;
-            int32_t scanCode;
-            int32_t metaState;
-            int32_t flags;
-            nsecs_t downTime;
-            uint32_t policyFlags;
-        };
-
-        struct MotionMemento {
-            int32_t deviceId;
-            uint32_t source;
-            int32_t flags;
-            float xPrecision;
-            float yPrecision;
-            nsecs_t downTime;
-            int32_t displayId;
-            uint32_t pointerCount;
-            PointerProperties pointerProperties[MAX_POINTERS];
-            PointerCoords pointerCoords[MAX_POINTERS];
-            bool hovering;
-            uint32_t policyFlags;
-
-            void setPointers(const MotionEntry* entry);
-        };
-
-        Vector<KeyMemento> mKeyMementos;
-        Vector<MotionMemento> mMotionMementos;
-        KeyedVector<int32_t, int32_t> mFallbackKeys;
-
-        ssize_t findKeyMemento(const KeyEntry* entry) const;
-        ssize_t findMotionMemento(const MotionEntry* entry, bool hovering) const;
-
-        void addKeyMemento(const KeyEntry* entry, int32_t flags);
-        void addMotionMemento(const MotionEntry* entry, int32_t flags, bool hovering);
-
-        static bool shouldCancelKey(const KeyMemento& memento,
-                const CancelationOptions& options);
-        static bool shouldCancelMotion(const MotionMemento& memento,
-                const CancelationOptions& options);
-    };
-
-    /* Manages the dispatch state associated with a single input channel. */
-    class Connection : public RefBase {
-    protected:
-        virtual ~Connection();
-
-    public:
-        enum Status {
-            // Everything is peachy.
-            STATUS_NORMAL,
-            // An unrecoverable communication error has occurred.
-            STATUS_BROKEN,
-            // The input channel has been unregistered.
-            STATUS_ZOMBIE
-        };
-
-        Status status;
-        sp<InputChannel> inputChannel; // never null
-        sp<InputWindowHandle> inputWindowHandle; // may be null
-        bool monitor;
-        InputPublisher inputPublisher;
-        InputState inputState;
-
-        // True if the socket is full and no further events can be published until
-        // the application consumes some of the input.
-        bool inputPublisherBlocked;
-
-        // Queue of events that need to be published to the connection.
-        Queue<DispatchEntry> outboundQueue;
-
-        // Queue of events that have been published to the connection but that have not
-        // yet received a "finished" response from the application.
-        Queue<DispatchEntry> waitQueue;
-
-        explicit Connection(const sp<InputChannel>& inputChannel,
-                const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
-
-        inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
-
-        const char* getWindowName() const;
-        const char* getStatusLabel() const;
-
-        DispatchEntry* findWaitQueueEntry(uint32_t seq);
-    };
-
-    enum DropReason {
-        DROP_REASON_NOT_DROPPED = 0,
-        DROP_REASON_POLICY = 1,
-        DROP_REASON_APP_SWITCH = 2,
-        DROP_REASON_DISABLED = 3,
-        DROP_REASON_BLOCKED = 4,
-        DROP_REASON_STALE = 5,
-    };
-
-    sp<InputDispatcherPolicyInterface> mPolicy;
-    InputDispatcherConfiguration mConfig;
-
-    Mutex mLock;
-
-    Condition mDispatcherIsAliveCondition;
-
-    sp<Looper> mLooper;
-
-    EventEntry* mPendingEvent;
-    Queue<EventEntry> mInboundQueue;
-    Queue<EventEntry> mRecentQueue;
-    Queue<CommandEntry> mCommandQueue;
-
-    void dispatchOnceInnerLocked(nsecs_t* nextWakeupTime);
-
-    // Enqueues an inbound event.  Returns true if mLooper->wake() should be called.
-    bool enqueueInboundEventLocked(EventEntry* entry);
-
-    // 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;
-
-    static bool isAppSwitchKeyCode(int32_t keyCode);
-    bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry);
-    bool isAppSwitchPendingLocked();
-    void resetPendingAppSwitchLocked(bool handled);
-
-    // Stale event latency optimization.
-    static bool isStaleEventLocked(nsecs_t currentTime, EventEntry* entry);
-
-    // Blocked event latency optimization.  Drops old events when the user intends
-    // to transfer focus to a new application.
-    EventEntry* mNextUnblockedEvent;
-
-    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y);
-
-    // All registered connections mapped by channel file descriptor.
-    KeyedVector<int, sp<Connection> > mConnectionsByFd;
-
-    ssize_t getConnectionIndexLocked(const sp<InputChannel>& inputChannel);
-
-    // Input channels that will receive a copy of all input events.
-    Vector<sp<InputChannel> > mMonitoringChannels;
-
-    // Event injection and synchronization.
-    Condition mInjectionResultAvailableCondition;
-    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
-    void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
-
-    Condition mInjectionSyncFinishedCondition;
-    void incrementPendingForegroundDispatchesLocked(EventEntry* entry);
-    void decrementPendingForegroundDispatchesLocked(EventEntry* entry);
-
-    // Key repeat tracking.
-    struct KeyRepeatState {
-        KeyEntry* lastKeyEntry; // or null if no repeat
-        nsecs_t nextRepeatTime;
-    } mKeyRepeatState;
-
-    void resetKeyRepeatLocked();
-    KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime);
-
-    // Deferred command processing.
-    bool haveCommandsLocked() const;
-    bool runCommandsLockedInterruptible();
-    CommandEntry* postCommandLocked(Command command);
-
-    // Input filter processing.
-    bool shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args);
-    bool shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args);
-
-    // Inbound event processing.
-    void drainInboundQueueLocked();
-    void releasePendingEventLocked();
-    void releaseInboundEventLocked(EventEntry* entry);
-
-    // Dispatch state.
-    bool mDispatchEnabled;
-    bool mDispatchFrozen;
-    bool mInputFilterEnabled;
-
-    Vector<sp<InputWindowHandle> > mWindowHandles;
-
-    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
-    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
-
-    // Focus tracking for keys, trackball, etc.
-    sp<InputWindowHandle> mFocusedWindowHandle;
-
-    // Focus tracking for touch.
-    struct TouchedWindow {
-        sp<InputWindowHandle> windowHandle;
-        int32_t targetFlags;
-        BitSet32 pointerIds;        // zero unless target flag FLAG_SPLIT is set
-    };
-    struct TouchState {
-        bool down;
-        bool split;
-        int32_t deviceId; // id of the device that is currently down, others are rejected
-        uint32_t source;  // source of the device that is current down, others are rejected
-        int32_t displayId; // id to the display that currently has a touch, others are rejected
-        Vector<TouchedWindow> windows;
-
-        TouchState();
-        ~TouchState();
-        void reset();
-        void copyFrom(const TouchState& other);
-        void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
-                int32_t targetFlags, BitSet32 pointerIds);
-        void removeWindow(const sp<InputWindowHandle>& windowHandle);
-        void filterNonAsIsTouchWindows();
-        sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
-        bool isSlippery() const;
-    };
-
-    KeyedVector<int32_t, TouchState> mTouchStatesByDisplay;
-    TouchState mTempTouchState;
-
-    // Focused application.
-    sp<InputApplicationHandle> mFocusedApplicationHandle;
-
-    // Dispatcher state at time of last ANR.
-    String8 mLastANRState;
-
-    // Dispatch inbound events.
-    bool dispatchConfigurationChangedLocked(
-            nsecs_t currentTime, ConfigurationChangedEntry* entry);
-    bool dispatchDeviceResetLocked(
-            nsecs_t currentTime, DeviceResetEntry* entry);
-    bool dispatchKeyLocked(
-            nsecs_t currentTime, KeyEntry* entry,
-            DropReason* dropReason, nsecs_t* nextWakeupTime);
-    bool dispatchMotionLocked(
-            nsecs_t currentTime, MotionEntry* entry,
-            DropReason* dropReason, nsecs_t* nextWakeupTime);
-    void dispatchEventLocked(nsecs_t currentTime, EventEntry* entry,
-            const Vector<InputTarget>& inputTargets);
-
-    void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
-    void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
-
-    // Keeping track of ANR timeouts.
-    enum InputTargetWaitCause {
-        INPUT_TARGET_WAIT_CAUSE_NONE,
-        INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
-        INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY,
-    };
-
-    InputTargetWaitCause mInputTargetWaitCause;
-    nsecs_t mInputTargetWaitStartTime;
-    nsecs_t mInputTargetWaitTimeoutTime;
-    bool mInputTargetWaitTimeoutExpired;
-    sp<InputApplicationHandle> mInputTargetWaitApplicationHandle;
-
-    // Contains the last window which received a hover event.
-    sp<InputWindowHandle> mLastHoverWindowHandle;
-
-    // Finding targets for input events.
-    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
-            const sp<InputApplicationHandle>& applicationHandle,
-            const sp<InputWindowHandle>& windowHandle,
-            nsecs_t* nextWakeupTime, const char* reason);
-    void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
-            const sp<InputChannel>& inputChannel);
-    nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
-    void resetANRTimeoutsLocked();
-
-    int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
-            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime);
-    int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
-            Vector<InputTarget>& inputTargets, nsecs_t* nextWakeupTime,
-            bool* outConflictingPointerActions);
-
-    void addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
-            int32_t targetFlags, BitSet32 pointerIds, Vector<InputTarget>& inputTargets);
-    void addMonitoringTargetsLocked(Vector<InputTarget>& inputTargets);
-
-    void pokeUserActivityLocked(const EventEntry* eventEntry);
-    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
-            const InjectionState* injectionState);
-    bool isWindowObscuredAtPointLocked(const sp<InputWindowHandle>& windowHandle,
-            int32_t x, int32_t y) const;
-    bool isWindowReadyForMoreInputLocked(nsecs_t currentTime,
-            const sp<InputWindowHandle>& windowHandle, const EventEntry* eventEntry);
-    String8 getApplicationWindowLabelLocked(const sp<InputApplicationHandle>& applicationHandle,
-            const sp<InputWindowHandle>& windowHandle);
-
-    // Manage the dispatch cycle for a single connection.
-    // These methods are deliberately not Interruptible because doing all of the work
-    // with the mutex held makes it easier to ensure that connection invariants are maintained.
-    // If needed, the methods post commands to run later once the critical bits are done.
-    void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
-            EventEntry* eventEntry, const InputTarget* inputTarget);
-    void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
-            EventEntry* eventEntry, const InputTarget* inputTarget);
-    void enqueueDispatchEntryLocked(const sp<Connection>& connection,
-            EventEntry* eventEntry, const InputTarget* inputTarget, int32_t dispatchMode);
-    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
-    void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
-            uint32_t seq, bool handled);
-    void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
-            bool notify);
-    void drainDispatchQueueLocked(Queue<DispatchEntry>* queue);
-    void releaseDispatchEntryLocked(DispatchEntry* dispatchEntry);
-    static int handleReceiveCallback(int fd, int events, void* data);
-
-    void synthesizeCancelationEventsForAllConnectionsLocked(
-            const CancelationOptions& options);
-    void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
-            const CancelationOptions& options);
-    void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
-            const CancelationOptions& options);
-
-    // Splitting motion events across windows.
-    MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
-
-    // Reset and drop everything the dispatcher is doing.
-    void resetAndDropEverythingLocked(const char* reason);
-
-    // Dump state.
-    void dumpDispatchStateLocked(String8& dump);
-    void logDispatchStateLocked();
-
-    // Registration.
-    void removeMonitorChannelLocked(const sp<InputChannel>& inputChannel);
-    status_t unregisterInputChannelLocked(const sp<InputChannel>& inputChannel, bool notify);
-
-    // Add or remove a connection to the mActiveConnections vector.
-    void activateConnectionLocked(Connection* connection);
-    void deactivateConnectionLocked(Connection* connection);
-
-    // Interesting events that we might like to log or tell the framework about.
-    void onDispatchCycleFinishedLocked(
-            nsecs_t currentTime, const sp<Connection>& connection, uint32_t seq, bool handled);
-    void onDispatchCycleBrokenLocked(
-            nsecs_t currentTime, const sp<Connection>& connection);
-    void onANRLocked(
-            nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
-            const sp<InputWindowHandle>& windowHandle,
-            nsecs_t eventTime, nsecs_t waitStartTime, const char* reason);
-
-    // Outbound policy interactions.
-    void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
-    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
-    void doNotifyANRLockedInterruptible(CommandEntry* commandEntry);
-    void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry);
-    void doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry);
-    bool afterKeyEventLockedInterruptible(const sp<Connection>& connection,
-            DispatchEntry* dispatchEntry, KeyEntry* keyEntry, bool handled);
-    bool afterMotionEventLockedInterruptible(const sp<Connection>& connection,
-            DispatchEntry* dispatchEntry, MotionEntry* motionEntry, bool handled);
-    void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry);
-    void initializeKeyEvent(KeyEvent* event, const KeyEntry* entry);
-
-    // Statistics gathering.
-    void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
-            int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
-    void traceInboundQueueLengthLocked();
-    void traceOutboundQueueLengthLocked(const sp<Connection>& connection);
-    void traceWaitQueueLengthLocked(const sp<Connection>& connection);
-};
-
-/* Enqueues and dispatches input events, endlessly. */
-class InputDispatcherThread : public Thread {
-public:
-    explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
-    ~InputDispatcherThread();
-
-private:
-    virtual bool threadLoop();
-
-    sp<InputDispatcherInterface> mDispatcher;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_DISPATCHER_H
diff --git a/libs/input/InputListener.cpp b/libs/input/InputListener.cpp
deleted file mode 100644
index 85bb0ed..0000000
--- a/libs/input/InputListener.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputListener"
-
-//#define LOG_NDEBUG 0
-
-#include "InputListener.h"
-
-#include <cutils/log.h>
-
-namespace android {
-
-// --- NotifyConfigurationChangedArgs ---
-
-NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(nsecs_t eventTime) :
-        eventTime(eventTime) {
-}
-
-NotifyConfigurationChangedArgs::NotifyConfigurationChangedArgs(
-        const NotifyConfigurationChangedArgs& other) :
-        eventTime(other.eventTime) {
-}
-
-void NotifyConfigurationChangedArgs::notify(const sp<InputListenerInterface>& listener) const {
-    listener->notifyConfigurationChanged(this);
-}
-
-
-// --- NotifyKeyArgs ---
-
-NotifyKeyArgs::NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
-        uint32_t policyFlags,
-        int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
-        int32_t metaState, nsecs_t downTime) :
-        eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
-        action(action), flags(flags), keyCode(keyCode), scanCode(scanCode),
-        metaState(metaState), downTime(downTime) {
-}
-
-NotifyKeyArgs::NotifyKeyArgs(const NotifyKeyArgs& other) :
-        eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
-        policyFlags(other.policyFlags),
-        action(other.action), flags(other.flags),
-        keyCode(other.keyCode), scanCode(other.scanCode),
-        metaState(other.metaState), downTime(other.downTime) {
-}
-
-void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
-    listener->notifyKey(this);
-}
-
-
-// --- NotifyMotionArgs ---
-
-NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
-        uint32_t policyFlags,
-        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
-        int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
-        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
-        float xPrecision, float yPrecision, nsecs_t downTime) :
-        eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
-        action(action), flags(flags), metaState(metaState), buttonState(buttonState),
-        edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
-        xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        this->pointerProperties[i].copyFrom(pointerProperties[i]);
-        this->pointerCoords[i].copyFrom(pointerCoords[i]);
-    }
-}
-
-NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
-        eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
-        policyFlags(other.policyFlags),
-        action(other.action), flags(other.flags),
-        metaState(other.metaState), buttonState(other.buttonState),
-        edgeFlags(other.edgeFlags), displayId(other.displayId),
-        pointerCount(other.pointerCount),
-        xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].copyFrom(other.pointerProperties[i]);
-        pointerCoords[i].copyFrom(other.pointerCoords[i]);
-    }
-}
-
-void NotifyMotionArgs::notify(const sp<InputListenerInterface>& listener) const {
-    listener->notifyMotion(this);
-}
-
-
-// --- NotifySwitchArgs ---
-
-NotifySwitchArgs::NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
-        uint32_t switchValues, uint32_t switchMask) :
-        eventTime(eventTime), policyFlags(policyFlags),
-        switchValues(switchValues), switchMask(switchMask) {
-}
-
-NotifySwitchArgs::NotifySwitchArgs(const NotifySwitchArgs& other) :
-        eventTime(other.eventTime), policyFlags(other.policyFlags),
-        switchValues(other.switchValues), switchMask(other.switchMask) {
-}
-
-void NotifySwitchArgs::notify(const sp<InputListenerInterface>& listener) const {
-    listener->notifySwitch(this);
-}
-
-
-// --- NotifyDeviceResetArgs ---
-
-NotifyDeviceResetArgs::NotifyDeviceResetArgs(nsecs_t eventTime, int32_t deviceId) :
-        eventTime(eventTime), deviceId(deviceId) {
-}
-
-NotifyDeviceResetArgs::NotifyDeviceResetArgs(const NotifyDeviceResetArgs& other) :
-        eventTime(other.eventTime), deviceId(other.deviceId) {
-}
-
-void NotifyDeviceResetArgs::notify(const sp<InputListenerInterface>& listener) const {
-    listener->notifyDeviceReset(this);
-}
-
-
-// --- QueuedInputListener ---
-
-QueuedInputListener::QueuedInputListener(const sp<InputListenerInterface>& innerListener) :
-        mInnerListener(innerListener) {
-}
-
-QueuedInputListener::~QueuedInputListener() {
-    size_t count = mArgsQueue.size();
-    for (size_t i = 0; i < count; i++) {
-        delete mArgsQueue[i];
-    }
-}
-
-void QueuedInputListener::notifyConfigurationChanged(
-        const NotifyConfigurationChangedArgs* args) {
-    mArgsQueue.push(new NotifyConfigurationChangedArgs(*args));
-}
-
-void QueuedInputListener::notifyKey(const NotifyKeyArgs* args) {
-    mArgsQueue.push(new NotifyKeyArgs(*args));
-}
-
-void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
-    mArgsQueue.push(new NotifyMotionArgs(*args));
-}
-
-void QueuedInputListener::notifySwitch(const NotifySwitchArgs* args) {
-    mArgsQueue.push(new NotifySwitchArgs(*args));
-}
-
-void QueuedInputListener::notifyDeviceReset(const NotifyDeviceResetArgs* args) {
-    mArgsQueue.push(new NotifyDeviceResetArgs(*args));
-}
-
-void QueuedInputListener::flush() {
-    size_t count = mArgsQueue.size();
-    for (size_t i = 0; i < count; i++) {
-        NotifyArgs* args = mArgsQueue[i];
-        args->notify(mInnerListener);
-        delete args;
-    }
-    mArgsQueue.clear();
-}
-
-
-} // namespace android
diff --git a/libs/input/InputListener.h b/libs/input/InputListener.h
deleted file mode 100644
index 78ae10f..0000000
--- a/libs/input/InputListener.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_LISTENER_H
-#define _UI_INPUT_LISTENER_H
-
-#include <input/Input.h>
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-class InputListenerInterface;
-
-
-/* Superclass of all input event argument objects */
-struct NotifyArgs {
-    virtual ~NotifyArgs() { }
-
-    virtual void notify(const sp<InputListenerInterface>& listener) const = 0;
-};
-
-
-/* Describes a configuration change event. */
-struct NotifyConfigurationChangedArgs : public NotifyArgs {
-    nsecs_t eventTime;
-
-    inline NotifyConfigurationChangedArgs() { }
-
-    NotifyConfigurationChangedArgs(nsecs_t eventTime);
-
-    NotifyConfigurationChangedArgs(const NotifyConfigurationChangedArgs& other);
-
-    virtual ~NotifyConfigurationChangedArgs() { }
-
-    virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a key event. */
-struct NotifyKeyArgs : public NotifyArgs {
-    nsecs_t eventTime;
-    int32_t deviceId;
-    uint32_t source;
-    uint32_t policyFlags;
-    int32_t action;
-    int32_t flags;
-    int32_t keyCode;
-    int32_t scanCode;
-    int32_t metaState;
-    nsecs_t downTime;
-
-    inline NotifyKeyArgs() { }
-
-    NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
-            int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
-            int32_t metaState, nsecs_t downTime);
-
-    NotifyKeyArgs(const NotifyKeyArgs& other);
-
-    virtual ~NotifyKeyArgs() { }
-
-    virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a motion event. */
-struct NotifyMotionArgs : public NotifyArgs {
-    nsecs_t eventTime;
-    int32_t deviceId;
-    uint32_t source;
-    uint32_t policyFlags;
-    int32_t action;
-    int32_t flags;
-    int32_t metaState;
-    int32_t buttonState;
-    int32_t edgeFlags;
-    int32_t displayId;
-    uint32_t pointerCount;
-    PointerProperties pointerProperties[MAX_POINTERS];
-    PointerCoords pointerCoords[MAX_POINTERS];
-    float xPrecision;
-    float yPrecision;
-    nsecs_t downTime;
-
-    inline NotifyMotionArgs() { }
-
-    NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
-            int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
-            int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
-            const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
-            float xPrecision, float yPrecision, nsecs_t downTime);
-
-    NotifyMotionArgs(const NotifyMotionArgs& other);
-
-    virtual ~NotifyMotionArgs() { }
-
-    virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a switch event. */
-struct NotifySwitchArgs : public NotifyArgs {
-    nsecs_t eventTime;
-    uint32_t policyFlags;
-    uint32_t switchValues;
-    uint32_t switchMask;
-
-    inline NotifySwitchArgs() { }
-
-    NotifySwitchArgs(nsecs_t eventTime, uint32_t policyFlags,
-            uint32_t switchValues, uint32_t switchMask);
-
-    NotifySwitchArgs(const NotifySwitchArgs& other);
-
-    virtual ~NotifySwitchArgs() { }
-
-    virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/* Describes a device reset event, such as when a device is added,
- * reconfigured, or removed. */
-struct NotifyDeviceResetArgs : public NotifyArgs {
-    nsecs_t eventTime;
-    int32_t deviceId;
-
-    inline NotifyDeviceResetArgs() { }
-
-    NotifyDeviceResetArgs(nsecs_t eventTime, int32_t deviceId);
-
-    NotifyDeviceResetArgs(const NotifyDeviceResetArgs& other);
-
-    virtual ~NotifyDeviceResetArgs() { }
-
-    virtual void notify(const sp<InputListenerInterface>& listener) const;
-};
-
-
-/*
- * The interface used by the InputReader to notify the InputListener about input events.
- */
-class InputListenerInterface : public virtual RefBase {
-protected:
-    InputListenerInterface() { }
-    virtual ~InputListenerInterface() { }
-
-public:
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) = 0;
-    virtual void notifyKey(const NotifyKeyArgs* args) = 0;
-    virtual void notifyMotion(const NotifyMotionArgs* args) = 0;
-    virtual void notifySwitch(const NotifySwitchArgs* args) = 0;
-    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) = 0;
-};
-
-
-/*
- * An implementation of the listener interface that queues up and defers dispatch
- * of decoded events until flushed.
- */
-class QueuedInputListener : public InputListenerInterface {
-protected:
-    virtual ~QueuedInputListener();
-
-public:
-    QueuedInputListener(const sp<InputListenerInterface>& innerListener);
-
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args);
-    virtual void notifyKey(const NotifyKeyArgs* args);
-    virtual void notifyMotion(const NotifyMotionArgs* args);
-    virtual void notifySwitch(const NotifySwitchArgs* args);
-    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args);
-
-    void flush();
-
-private:
-    sp<InputListenerInterface> mInnerListener;
-    Vector<NotifyArgs*> mArgsQueue;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_LISTENER_H
diff --git a/libs/input/InputManager.cpp b/libs/input/InputManager.cpp
deleted file mode 100644
index 6a6547b..0000000
--- a/libs/input/InputManager.cpp
+++ /dev/null
@@ -1,93 +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 "InputManager"
-
-//#define LOG_NDEBUG 0
-
-#include "InputManager.h"
-
-#include <cutils/log.h>
-
-namespace android {
-
-InputManager::InputManager(
-        const sp<EventHubInterface>& eventHub,
-        const sp<InputReaderPolicyInterface>& readerPolicy,
-        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
-    mDispatcher = new InputDispatcher(dispatcherPolicy);
-    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
-    initialize();
-}
-
-InputManager::InputManager(
-        const sp<InputReaderInterface>& reader,
-        const sp<InputDispatcherInterface>& dispatcher) :
-        mReader(reader),
-        mDispatcher(dispatcher) {
-    initialize();
-}
-
-InputManager::~InputManager() {
-    stop();
-}
-
-void InputManager::initialize() {
-    mReaderThread = new InputReaderThread(mReader);
-    mDispatcherThread = new InputDispatcherThread(mDispatcher);
-}
-
-status_t InputManager::start() {
-    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
-    if (result) {
-        ALOGE("Could not start InputDispatcher thread due to error %d.", result);
-        return result;
-    }
-
-    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
-    if (result) {
-        ALOGE("Could not start InputReader thread due to error %d.", result);
-
-        mDispatcherThread->requestExit();
-        return result;
-    }
-
-    return OK;
-}
-
-status_t InputManager::stop() {
-    status_t result = mReaderThread->requestExitAndWait();
-    if (result) {
-        ALOGW("Could not stop InputReader thread due to error %d.", result);
-    }
-
-    result = mDispatcherThread->requestExitAndWait();
-    if (result) {
-        ALOGW("Could not stop InputDispatcher thread due to error %d.", result);
-    }
-
-    return OK;
-}
-
-sp<InputReaderInterface> InputManager::getReader() {
-    return mReader;
-}
-
-sp<InputDispatcherInterface> InputManager::getDispatcher() {
-    return mDispatcher;
-}
-
-} // namespace android
diff --git a/libs/input/InputManager.h b/libs/input/InputManager.h
deleted file mode 100644
index a213b2d..0000000
--- a/libs/input/InputManager.h
+++ /dev/null
@@ -1,109 +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 _UI_INPUT_MANAGER_H
-#define _UI_INPUT_MANAGER_H
-
-/**
- * Native input manager.
- */
-
-#include "EventHub.h"
-#include "InputReader.h"
-#include "InputDispatcher.h"
-
-#include <input/Input.h>
-#include <input/InputTransport.h>
-#include <utils/Errors.h>
-#include <utils/Vector.h>
-#include <utils/Timers.h>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-namespace android {
-
-/*
- * The input manager is the core of the system event processing.
- *
- * The input manager uses two threads.
- *
- * 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
- *    applies policy, and posts messages to a queue managed by the DispatcherThread.
- * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
- *    queue and asynchronously dispatches them to applications.
- *
- * By design, the InputReaderThread class and InputDispatcherThread class do not share any
- * internal state.  Moreover, all communication is done one way from the InputReaderThread
- * into the InputDispatcherThread and never the reverse.  Both classes may interact with the
- * InputDispatchPolicy, however.
- *
- * The InputManager class never makes any calls into Java itself.  Instead, the
- * InputDispatchPolicy is responsible for performing all external interactions with the
- * system, including calling DVM services.
- */
-class InputManagerInterface : public virtual RefBase {
-protected:
-    InputManagerInterface() { }
-    virtual ~InputManagerInterface() { }
-
-public:
-    /* Starts the input manager threads. */
-    virtual status_t start() = 0;
-
-    /* Stops the input manager threads and waits for them to exit. */
-    virtual status_t stop() = 0;
-
-    /* Gets the input reader. */
-    virtual sp<InputReaderInterface> getReader() = 0;
-
-    /* Gets the input dispatcher. */
-    virtual sp<InputDispatcherInterface> getDispatcher() = 0;
-};
-
-class InputManager : public InputManagerInterface {
-protected:
-    virtual ~InputManager();
-
-public:
-    InputManager(
-            const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& readerPolicy,
-            const sp<InputDispatcherPolicyInterface>& dispatcherPolicy);
-
-    // (used for testing purposes)
-    InputManager(
-            const sp<InputReaderInterface>& reader,
-            const sp<InputDispatcherInterface>& dispatcher);
-
-    virtual status_t start();
-    virtual status_t stop();
-
-    virtual sp<InputReaderInterface> getReader();
-    virtual sp<InputDispatcherInterface> getDispatcher();
-
-private:
-    sp<InputReaderInterface> mReader;
-    sp<InputReaderThread> mReaderThread;
-
-    sp<InputDispatcherInterface> mDispatcher;
-    sp<InputDispatcherThread> mDispatcherThread;
-
-    void initialize();
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_MANAGER_H
diff --git a/libs/input/InputReader.cpp b/libs/input/InputReader.cpp
deleted file mode 100644
index 48c5223..0000000
--- a/libs/input/InputReader.cpp
+++ /dev/null
@@ -1,6543 +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 "InputReader"
-
-//#define LOG_NDEBUG 0
-
-// Log debug messages for each raw event received from the EventHub.
-#define DEBUG_RAW_EVENTS 0
-
-// Log debug messages about touch screen filtering hacks.
-#define DEBUG_HACKS 0
-
-// Log debug messages about virtual key processing.
-#define DEBUG_VIRTUAL_KEYS 0
-
-// Log debug messages about pointers.
-#define DEBUG_POINTERS 0
-
-// Log debug messages about pointer assignment calculations.
-#define DEBUG_POINTER_ASSIGNMENT 0
-
-// Log debug messages about gesture detection.
-#define DEBUG_GESTURES 0
-
-// Log debug messages about the vibrator.
-#define DEBUG_VIBRATOR 0
-
-#include "InputReader.h"
-
-#include <cutils/log.h>
-#include <input/Keyboard.h>
-#include <input/VirtualKeyMap.h>
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <limits.h>
-#include <math.h>
-
-#define INDENT "  "
-#define INDENT2 "    "
-#define INDENT3 "      "
-#define INDENT4 "        "
-#define INDENT5 "          "
-
-namespace android {
-
-// --- Constants ---
-
-// Maximum number of slots supported when using the slot-based Multitouch Protocol B.
-static const size_t MAX_SLOTS = 32;
-
-// --- Static Functions ---
-
-template<typename T>
-inline static T abs(const T& value) {
-    return value < 0 ? - value : value;
-}
-
-template<typename T>
-inline static T min(const T& a, const T& b) {
-    return a < b ? a : b;
-}
-
-template<typename T>
-inline static void swap(T& a, T& b) {
-    T temp = a;
-    a = b;
-    b = temp;
-}
-
-inline static float avg(float x, float y) {
-    return (x + y) / 2;
-}
-
-inline static float distance(float x1, float y1, float x2, float y2) {
-    return hypotf(x1 - x2, y1 - y2);
-}
-
-inline static int32_t signExtendNybble(int32_t value) {
-    return value >= 8 ? value - 16 : value;
-}
-
-static inline const char* toString(bool value) {
-    return value ? "true" : "false";
-}
-
-static int32_t rotateValueUsingRotationMap(int32_t value, int32_t orientation,
-        const int32_t map[][4], size_t mapSize) {
-    if (orientation != DISPLAY_ORIENTATION_0) {
-        for (size_t i = 0; i < mapSize; i++) {
-            if (value == map[i][0]) {
-                return map[i][orientation];
-            }
-        }
-    }
-    return value;
-}
-
-static const int32_t keyCodeRotationMap[][4] = {
-        // key codes enumerated counter-clockwise with the original (unrotated) key first
-        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
-        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
-        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
-        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
-        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
-};
-static const size_t keyCodeRotationMapSize =
-        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
-
-static int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
-    return rotateValueUsingRotationMap(keyCode, orientation,
-            keyCodeRotationMap, keyCodeRotationMapSize);
-}
-
-static void rotateDelta(int32_t orientation, float* deltaX, float* deltaY) {
-    float temp;
-    switch (orientation) {
-    case DISPLAY_ORIENTATION_90:
-        temp = *deltaX;
-        *deltaX = *deltaY;
-        *deltaY = -temp;
-        break;
-
-    case DISPLAY_ORIENTATION_180:
-        *deltaX = -*deltaX;
-        *deltaY = -*deltaY;
-        break;
-
-    case DISPLAY_ORIENTATION_270:
-        temp = *deltaX;
-        *deltaX = -*deltaY;
-        *deltaY = temp;
-        break;
-    }
-}
-
-static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
-    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
-}
-
-// Returns true if the pointer should be reported as being down given the specified
-// button states.  This determines whether the event is reported as a touch event.
-static bool isPointerDown(int32_t buttonState) {
-    return buttonState &
-            (AMOTION_EVENT_BUTTON_PRIMARY | AMOTION_EVENT_BUTTON_SECONDARY
-                    | AMOTION_EVENT_BUTTON_TERTIARY);
-}
-
-static float calculateCommonVector(float a, float b) {
-    if (a > 0 && b > 0) {
-        return a < b ? a : b;
-    } else if (a < 0 && b < 0) {
-        return a > b ? a : b;
-    } else {
-        return 0;
-    }
-}
-
-static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
-        nsecs_t when, int32_t deviceId, uint32_t source,
-        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
-        int32_t buttonState, int32_t keyCode) {
-    if (
-            (action == AKEY_EVENT_ACTION_DOWN
-                    && !(lastButtonState & buttonState)
-                    && (currentButtonState & buttonState))
-            || (action == AKEY_EVENT_ACTION_UP
-                    && (lastButtonState & buttonState)
-                    && !(currentButtonState & buttonState))) {
-        NotifyKeyArgs args(when, deviceId, source, policyFlags,
-                action, 0, keyCode, 0, context->getGlobalMetaState(), when);
-        context->getListener()->notifyKey(&args);
-    }
-}
-
-static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
-        nsecs_t when, int32_t deviceId, uint32_t source,
-        uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
-    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
-            lastButtonState, currentButtonState,
-            AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
-    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
-            lastButtonState, currentButtonState,
-            AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
-}
-
-
-// --- InputReaderConfiguration ---
-
-bool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
-    const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
-    if (viewport.displayId >= 0) {
-        *outViewport = viewport;
-        return true;
-    }
-    return false;
-}
-
-void InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
-    DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
-    v = viewport;
-}
-
-
-// --- InputReader ---
-
-InputReader::InputReader(const sp<EventHubInterface>& eventHub,
-        const sp<InputReaderPolicyInterface>& policy,
-        const sp<InputListenerInterface>& listener) :
-        mContext(this), mEventHub(eventHub), mPolicy(policy),
-        mGlobalMetaState(0), mGeneration(1),
-        mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
-        mConfigurationChangesToRefresh(0) {
-    mQueuedListener = new QueuedInputListener(listener);
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        refreshConfigurationLocked(0);
-        updateGlobalMetaStateLocked();
-    } // release lock
-}
-
-InputReader::~InputReader() {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        delete mDevices.valueAt(i);
-    }
-}
-
-void InputReader::loopOnce() {
-    int32_t oldGeneration;
-    int32_t timeoutMillis;
-    bool inputDevicesChanged = false;
-    Vector<InputDeviceInfo> inputDevices;
-    { // acquire lock
-        AutoMutex _l(mLock);
-
-        oldGeneration = mGeneration;
-        timeoutMillis = -1;
-
-        uint32_t changes = mConfigurationChangesToRefresh;
-        if (changes) {
-            mConfigurationChangesToRefresh = 0;
-            timeoutMillis = 0;
-            refreshConfigurationLocked(changes);
-        } else if (mNextTimeout != LLONG_MAX) {
-            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-            timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
-        }
-    } // release lock
-
-    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
-
-    { // acquire lock
-        AutoMutex _l(mLock);
-        mReaderIsAliveCondition.broadcast();
-
-        if (count) {
-            processEventsLocked(mEventBuffer, count);
-        }
-
-        if (mNextTimeout != LLONG_MAX) {
-            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-            if (now >= mNextTimeout) {
-#if DEBUG_RAW_EVENTS
-                ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
-#endif
-                mNextTimeout = LLONG_MAX;
-                timeoutExpiredLocked(now);
-            }
-        }
-
-        if (oldGeneration != mGeneration) {
-            inputDevicesChanged = true;
-            getInputDevicesLocked(inputDevices);
-        }
-    } // release lock
-
-    // Send out a message that the describes the changed input devices.
-    if (inputDevicesChanged) {
-        mPolicy->notifyInputDevicesChanged(inputDevices);
-    }
-
-    // Flush queued events out to the listener.
-    // This must happen outside of the lock because the listener could potentially call
-    // back into the InputReader's methods, such as getScanCodeState, or become blocked
-    // on another thread similarly waiting to acquire the InputReader lock thereby
-    // resulting in a deadlock.  This situation is actually quite plausible because the
-    // listener is actually the input dispatcher, which calls into the window manager,
-    // which occasionally calls into the input reader.
-    mQueuedListener->flush();
-}
-
-void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
-    for (const RawEvent* rawEvent = rawEvents; count;) {
-        int32_t type = rawEvent->type;
-        size_t batchSize = 1;
-        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
-            int32_t deviceId = rawEvent->deviceId;
-            while (batchSize < count) {
-                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT
-                        || rawEvent[batchSize].deviceId != deviceId) {
-                    break;
-                }
-                batchSize += 1;
-            }
-#if DEBUG_RAW_EVENTS
-            ALOGD("BatchSize: %d Count: %d", batchSize, count);
-#endif
-            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
-        } else {
-            switch (rawEvent->type) {
-            case EventHubInterface::DEVICE_ADDED:
-                addDeviceLocked(rawEvent->when, rawEvent->deviceId);
-                break;
-            case EventHubInterface::DEVICE_REMOVED:
-                removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
-                break;
-            case EventHubInterface::FINISHED_DEVICE_SCAN:
-                handleConfigurationChangedLocked(rawEvent->when);
-                break;
-            default:
-                ALOG_ASSERT(false); // can't happen
-                break;
-            }
-        }
-        count -= batchSize;
-        rawEvent += batchSize;
-    }
-}
-
-void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) {
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex >= 0) {
-        ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
-        return;
-    }
-
-    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId);
-    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
-    int32_t controllerNumber = mEventHub->getDeviceControllerNumber(deviceId);
-
-    InputDevice* device = createDeviceLocked(deviceId, controllerNumber, identifier, classes);
-    device->configure(when, &mConfig, 0);
-    device->reset(when);
-
-    if (device->isIgnored()) {
-        ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId,
-                identifier.name.string());
-    } else {
-        ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId,
-                identifier.name.string(), device->getSources());
-    }
-
-    mDevices.add(deviceId, device);
-    bumpGenerationLocked();
-}
-
-void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) {
-    InputDevice* device = NULL;
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex < 0) {
-        ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
-        return;
-    }
-
-    device = mDevices.valueAt(deviceIndex);
-    mDevices.removeItemsAt(deviceIndex, 1);
-    bumpGenerationLocked();
-
-    if (device->isIgnored()) {
-        ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)",
-                device->getId(), device->getName().string());
-    } else {
-        ALOGI("Device removed: id=%d, name='%s', sources=0x%08x",
-                device->getId(), device->getName().string(), device->getSources());
-    }
-
-    device->reset(when);
-    delete device;
-}
-
-InputDevice* InputReader::createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
-        const InputDeviceIdentifier& identifier, uint32_t classes) {
-    InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(),
-            controllerNumber, identifier, classes);
-
-    // External devices.
-    if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
-        device->setExternal(true);
-    }
-
-    // Switch-like devices.
-    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
-        device->addMapper(new SwitchInputMapper(device));
-    }
-
-    // Vibrator-like devices.
-    if (classes & INPUT_DEVICE_CLASS_VIBRATOR) {
-        device->addMapper(new VibratorInputMapper(device));
-    }
-
-    // Keyboard-like devices.
-    uint32_t keyboardSource = 0;
-    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
-    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
-        keyboardSource |= AINPUT_SOURCE_KEYBOARD;
-    }
-    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
-        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
-    }
-    if (classes & INPUT_DEVICE_CLASS_DPAD) {
-        keyboardSource |= AINPUT_SOURCE_DPAD;
-    }
-    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
-        keyboardSource |= AINPUT_SOURCE_GAMEPAD;
-    }
-
-    if (keyboardSource != 0) {
-        device->addMapper(new KeyboardInputMapper(device, keyboardSource, keyboardType));
-    }
-
-    // Cursor-like devices.
-    if (classes & INPUT_DEVICE_CLASS_CURSOR) {
-        device->addMapper(new CursorInputMapper(device));
-    }
-
-    // Touchscreens and touchpad devices.
-    if (classes & INPUT_DEVICE_CLASS_TOUCH_MT) {
-        device->addMapper(new MultiTouchInputMapper(device));
-    } else if (classes & INPUT_DEVICE_CLASS_TOUCH) {
-        device->addMapper(new SingleTouchInputMapper(device));
-    }
-
-    // Joystick-like devices.
-    if (classes & INPUT_DEVICE_CLASS_JOYSTICK) {
-        device->addMapper(new JoystickInputMapper(device));
-    }
-
-    return device;
-}
-
-void InputReader::processEventsForDeviceLocked(int32_t deviceId,
-        const RawEvent* rawEvents, size_t count) {
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex < 0) {
-        ALOGW("Discarding event for unknown deviceId %d.", deviceId);
-        return;
-    }
-
-    InputDevice* device = mDevices.valueAt(deviceIndex);
-    if (device->isIgnored()) {
-        //ALOGD("Discarding event for ignored deviceId %d.", deviceId);
-        return;
-    }
-
-    device->process(rawEvents, count);
-}
-
-void InputReader::timeoutExpiredLocked(nsecs_t when) {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
-        if (!device->isIgnored()) {
-            device->timeoutExpired(when);
-        }
-    }
-}
-
-void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
-    // Reset global meta state because it depends on the list of all configured devices.
-    updateGlobalMetaStateLocked();
-
-    // Enqueue configuration changed.
-    NotifyConfigurationChangedArgs args(when);
-    mQueuedListener->notifyConfigurationChanged(&args);
-}
-
-void InputReader::refreshConfigurationLocked(uint32_t changes) {
-    mPolicy->getReaderConfiguration(&mConfig);
-    mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
-
-    if (changes) {
-        ALOGI("Reconfiguring input devices.  changes=0x%08x", changes);
-        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-
-        if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
-            mEventHub->requestReopenDevices();
-        } else {
-            for (size_t i = 0; i < mDevices.size(); i++) {
-                InputDevice* device = mDevices.valueAt(i);
-                device->configure(now, &mConfig, changes);
-            }
-        }
-    }
-}
-
-void InputReader::updateGlobalMetaStateLocked() {
-    mGlobalMetaState = 0;
-
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
-        mGlobalMetaState |= device->getMetaState();
-    }
-}
-
-int32_t InputReader::getGlobalMetaStateLocked() {
-    return mGlobalMetaState;
-}
-
-void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
-    mDisableVirtualKeysTimeout = time;
-}
-
-bool InputReader::shouldDropVirtualKeyLocked(nsecs_t now,
-        InputDevice* device, int32_t keyCode, int32_t scanCode) {
-    if (now < mDisableVirtualKeysTimeout) {
-        ALOGI("Dropping virtual key from device %s because virtual keys are "
-                "temporarily disabled for the next %0.3fms.  keyCode=%d, scanCode=%d",
-                device->getName().string(),
-                (mDisableVirtualKeysTimeout - now) * 0.000001,
-                keyCode, scanCode);
-        return true;
-    } else {
-        return false;
-    }
-}
-
-void InputReader::fadePointerLocked() {
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        InputDevice* device = mDevices.valueAt(i);
-        device->fadePointer();
-    }
-}
-
-void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
-    if (when < mNextTimeout) {
-        mNextTimeout = when;
-        mEventHub->wake();
-    }
-}
-
-int32_t InputReader::bumpGenerationLocked() {
-    return ++mGeneration;
-}
-
-void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) {
-    AutoMutex _l(mLock);
-    getInputDevicesLocked(outInputDevices);
-}
-
-void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) {
-    outInputDevices.clear();
-
-    size_t numDevices = mDevices.size();
-    for (size_t i = 0; i < numDevices; i++) {
-        InputDevice* device = mDevices.valueAt(i);
-        if (!device->isIgnored()) {
-            outInputDevices.push();
-            device->getDeviceInfo(&outInputDevices.editTop());
-        }
-    }
-}
-
-int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
-        int32_t keyCode) {
-    AutoMutex _l(mLock);
-
-    return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
-}
-
-int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
-        int32_t scanCode) {
-    AutoMutex _l(mLock);
-
-    return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
-}
-
-int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
-    AutoMutex _l(mLock);
-
-    return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
-}
-
-int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
-        GetStateFunc getStateFunc) {
-    int32_t result = AKEY_STATE_UNKNOWN;
-    if (deviceId >= 0) {
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex >= 0) {
-            InputDevice* device = mDevices.valueAt(deviceIndex);
-            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                result = (device->*getStateFunc)(sourceMask, code);
-            }
-        }
-    } else {
-        size_t numDevices = mDevices.size();
-        for (size_t i = 0; i < numDevices; i++) {
-            InputDevice* device = mDevices.valueAt(i);
-            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                // If any device reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
-                // value.  Otherwise, return AKEY_STATE_UP as long as one device reports it.
-                int32_t currentResult = (device->*getStateFunc)(sourceMask, code);
-                if (currentResult >= AKEY_STATE_DOWN) {
-                    return currentResult;
-                } else if (currentResult == AKEY_STATE_UP) {
-                    result = currentResult;
-                }
-            }
-        }
-    }
-    return result;
-}
-
-bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
-        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
-    AutoMutex _l(mLock);
-
-    memset(outFlags, 0, numCodes);
-    return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
-}
-
-bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
-        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
-    bool result = false;
-    if (deviceId >= 0) {
-        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-        if (deviceIndex >= 0) {
-            InputDevice* device = mDevices.valueAt(deviceIndex);
-            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                result = device->markSupportedKeyCodes(sourceMask,
-                        numCodes, keyCodes, outFlags);
-            }
-        }
-    } else {
-        size_t numDevices = mDevices.size();
-        for (size_t i = 0; i < numDevices; i++) {
-            InputDevice* device = mDevices.valueAt(i);
-            if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
-                result |= device->markSupportedKeyCodes(sourceMask,
-                        numCodes, keyCodes, outFlags);
-            }
-        }
-    }
-    return result;
-}
-
-void InputReader::requestRefreshConfiguration(uint32_t changes) {
-    AutoMutex _l(mLock);
-
-    if (changes) {
-        bool needWake = !mConfigurationChangesToRefresh;
-        mConfigurationChangesToRefresh |= changes;
-
-        if (needWake) {
-            mEventHub->wake();
-        }
-    }
-}
-
-void InputReader::vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
-        ssize_t repeat, int32_t token) {
-    AutoMutex _l(mLock);
-
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex >= 0) {
-        InputDevice* device = mDevices.valueAt(deviceIndex);
-        device->vibrate(pattern, patternSize, repeat, token);
-    }
-}
-
-void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {
-    AutoMutex _l(mLock);
-
-    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
-    if (deviceIndex >= 0) {
-        InputDevice* device = mDevices.valueAt(deviceIndex);
-        device->cancelVibrate(token);
-    }
-}
-
-void InputReader::dump(String8& dump) {
-    AutoMutex _l(mLock);
-
-    mEventHub->dump(dump);
-    dump.append("\n");
-
-    dump.append("Input Reader State:\n");
-
-    for (size_t i = 0; i < mDevices.size(); i++) {
-        mDevices.valueAt(i)->dump(dump);
-    }
-
-    dump.append(INDENT "Configuration:\n");
-    dump.append(INDENT2 "ExcludedDeviceNames: [");
-    for (size_t i = 0; i < mConfig.excludedDeviceNames.size(); i++) {
-        if (i != 0) {
-            dump.append(", ");
-        }
-        dump.append(mConfig.excludedDeviceNames.itemAt(i).string());
-    }
-    dump.append("]\n");
-    dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
-            mConfig.virtualKeyQuietTime * 0.000001f);
-
-    dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
-            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
-            mConfig.pointerVelocityControlParameters.scale,
-            mConfig.pointerVelocityControlParameters.lowThreshold,
-            mConfig.pointerVelocityControlParameters.highThreshold,
-            mConfig.pointerVelocityControlParameters.acceleration);
-
-    dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
-            "scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
-            mConfig.wheelVelocityControlParameters.scale,
-            mConfig.wheelVelocityControlParameters.lowThreshold,
-            mConfig.wheelVelocityControlParameters.highThreshold,
-            mConfig.wheelVelocityControlParameters.acceleration);
-
-    dump.appendFormat(INDENT2 "PointerGesture:\n");
-    dump.appendFormat(INDENT3 "Enabled: %s\n",
-            toString(mConfig.pointerGesturesEnabled));
-    dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
-            mConfig.pointerGestureQuietInterval * 0.000001f);
-    dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
-            mConfig.pointerGestureDragMinSwitchSpeed);
-    dump.appendFormat(INDENT3 "TapInterval: %0.1fms\n",
-            mConfig.pointerGestureTapInterval * 0.000001f);
-    dump.appendFormat(INDENT3 "TapDragInterval: %0.1fms\n",
-            mConfig.pointerGestureTapDragInterval * 0.000001f);
-    dump.appendFormat(INDENT3 "TapSlop: %0.1fpx\n",
-            mConfig.pointerGestureTapSlop);
-    dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n",
-            mConfig.pointerGestureMultitouchSettleInterval * 0.000001f);
-    dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n",
-            mConfig.pointerGestureMultitouchMinDistance);
-    dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n",
-            mConfig.pointerGestureSwipeTransitionAngleCosine);
-    dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n",
-            mConfig.pointerGestureSwipeMaxWidthRatio);
-    dump.appendFormat(INDENT3 "MovementSpeedRatio: %0.1f\n",
-            mConfig.pointerGestureMovementSpeedRatio);
-    dump.appendFormat(INDENT3 "ZoomSpeedRatio: %0.1f\n",
-            mConfig.pointerGestureZoomSpeedRatio);
-}
-
-void InputReader::monitor() {
-    // Acquire and release the lock to ensure that the reader has not deadlocked.
-    mLock.lock();
-    mEventHub->wake();
-    mReaderIsAliveCondition.wait(mLock);
-    mLock.unlock();
-
-    // Check the EventHub
-    mEventHub->monitor();
-}
-
-
-// --- InputReader::ContextImpl ---
-
-InputReader::ContextImpl::ContextImpl(InputReader* reader) :
-        mReader(reader) {
-}
-
-void InputReader::ContextImpl::updateGlobalMetaState() {
-    // lock is already held by the input loop
-    mReader->updateGlobalMetaStateLocked();
-}
-
-int32_t InputReader::ContextImpl::getGlobalMetaState() {
-    // lock is already held by the input loop
-    return mReader->getGlobalMetaStateLocked();
-}
-
-void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
-    // lock is already held by the input loop
-    mReader->disableVirtualKeysUntilLocked(time);
-}
-
-bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
-        InputDevice* device, int32_t keyCode, int32_t scanCode) {
-    // lock is already held by the input loop
-    return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
-}
-
-void InputReader::ContextImpl::fadePointer() {
-    // lock is already held by the input loop
-    mReader->fadePointerLocked();
-}
-
-void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
-    // lock is already held by the input loop
-    mReader->requestTimeoutAtTimeLocked(when);
-}
-
-int32_t InputReader::ContextImpl::bumpGeneration() {
-    // lock is already held by the input loop
-    return mReader->bumpGenerationLocked();
-}
-
-InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
-    return mReader->mPolicy.get();
-}
-
-InputListenerInterface* InputReader::ContextImpl::getListener() {
-    return mReader->mQueuedListener.get();
-}
-
-EventHubInterface* InputReader::ContextImpl::getEventHub() {
-    return mReader->mEventHub.get();
-}
-
-
-// --- InputReaderThread ---
-
-InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
-        Thread(/*canCallJava*/ true), mReader(reader) {
-}
-
-InputReaderThread::~InputReaderThread() {
-}
-
-bool InputReaderThread::threadLoop() {
-    mReader->loopOnce();
-    return true;
-}
-
-
-// --- InputDevice ---
-
-InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t 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) {
-}
-
-InputDevice::~InputDevice() {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        delete mMappers[i];
-    }
-    mMappers.clear();
-}
-
-void InputDevice::dump(String8& dump) {
-    InputDeviceInfo deviceInfo;
-    getDeviceInfo(& deviceInfo);
-
-    dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(),
-            deviceInfo.getDisplayName().string());
-    dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration);
-    dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal));
-    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
-    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
-
-    const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
-    if (!ranges.isEmpty()) {
-        dump.append(INDENT2 "Motion Ranges:\n");
-        for (size_t i = 0; i < ranges.size(); i++) {
-            const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
-            const char* label = getAxisLabel(range.axis);
-            char name[32];
-            if (label) {
-                strncpy(name, label, sizeof(name));
-                name[sizeof(name) - 1] = '\0';
-            } else {
-                snprintf(name, sizeof(name), "%d", range.axis);
-            }
-            dump.appendFormat(INDENT3 "%s: source=0x%08x, "
-                    "min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f, resolution=%0.3f\n",
-                    name, range.source, range.min, range.max, range.flat, range.fuzz,
-                    range.resolution);
-        }
-    }
-
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->dump(dump);
-    }
-}
-
-void InputDevice::addMapper(InputMapper* mapper) {
-    mMappers.add(mapper);
-}
-
-void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) {
-    mSources = 0;
-
-    if (!isIgnored()) {
-        if (!changes) { // first time only
-            mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
-        }
-
-        if (!changes || (changes & InputReaderConfiguration::CHANGE_KEYBOARD_LAYOUTS)) {
-            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
-                sp<KeyCharacterMap> keyboardLayout =
-                        mContext->getPolicy()->getKeyboardLayoutOverlay(mIdentifier);
-                if (mContext->getEventHub()->setKeyboardLayoutOverlay(mId, keyboardLayout)) {
-                    bumpGeneration();
-                }
-            }
-        }
-
-        if (!changes || (changes & InputReaderConfiguration::CHANGE_DEVICE_ALIAS)) {
-            if (!(mClasses & INPUT_DEVICE_CLASS_VIRTUAL)) {
-                String8 alias = mContext->getPolicy()->getDeviceAlias(mIdentifier);
-                if (mAlias != alias) {
-                    mAlias = alias;
-                    bumpGeneration();
-                }
-            }
-        }
-
-        size_t numMappers = mMappers.size();
-        for (size_t i = 0; i < numMappers; i++) {
-            InputMapper* mapper = mMappers[i];
-            mapper->configure(when, config, changes);
-            mSources |= mapper->getSources();
-        }
-    }
-}
-
-void InputDevice::reset(nsecs_t when) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->reset(when);
-    }
-
-    mContext->updateGlobalMetaState();
-
-    notifyReset(when);
-}
-
-void InputDevice::process(const RawEvent* rawEvents, size_t count) {
-    // Process all of the events in order for each mapper.
-    // We cannot simply ask each mapper to process them in bulk because mappers may
-    // have side-effects that must be interleaved.  For example, joystick movement events and
-    // gamepad button presses are handled by different mappers but they should be dispatched
-    // in the order received.
-    size_t numMappers = mMappers.size();
-    for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) {
-#if DEBUG_RAW_EVENTS
-        ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%lld",
-                rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value,
-                rawEvent->when);
-#endif
-
-        if (mDropUntilNextSync) {
-            if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
-                mDropUntilNextSync = false;
-#if DEBUG_RAW_EVENTS
-                ALOGD("Recovered from input event buffer overrun.");
-#endif
-            } else {
-#if DEBUG_RAW_EVENTS
-                ALOGD("Dropped input event while waiting for next input sync.");
-#endif
-            }
-        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
-            ALOGI("Detected input event buffer overrun for device %s.", getName().string());
-            mDropUntilNextSync = true;
-            reset(rawEvent->when);
-        } else {
-            for (size_t i = 0; i < numMappers; i++) {
-                InputMapper* mapper = mMappers[i];
-                mapper->process(rawEvent);
-            }
-        }
-    }
-}
-
-void InputDevice::timeoutExpired(nsecs_t when) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->timeoutExpired(when);
-    }
-}
-
-void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
-    outDeviceInfo->initialize(mId, mGeneration, mControllerNumber, mIdentifier, mAlias,
-            mIsExternal);
-
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->populateDeviceInfo(outDeviceInfo);
-    }
-}
-
-int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
-}
-
-int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
-}
-
-int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
-}
-
-int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
-    int32_t result = AKEY_STATE_UNKNOWN;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
-            // If any mapper reports AKEY_STATE_DOWN or AKEY_STATE_VIRTUAL, return that
-            // value.  Otherwise, return AKEY_STATE_UP as long as one mapper reports it.
-            int32_t currentResult = (mapper->*getStateFunc)(sourceMask, code);
-            if (currentResult >= AKEY_STATE_DOWN) {
-                return currentResult;
-            } else if (currentResult == AKEY_STATE_UP) {
-                result = currentResult;
-            }
-        }
-    }
-    return result;
-}
-
-bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    bool result = false;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
-            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
-        }
-    }
-    return result;
-}
-
-void InputDevice::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
-        int32_t token) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->vibrate(pattern, patternSize, repeat, token);
-    }
-}
-
-void InputDevice::cancelVibrate(int32_t token) {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->cancelVibrate(token);
-    }
-}
-
-int32_t InputDevice::getMetaState() {
-    int32_t result = 0;
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        result |= mapper->getMetaState();
-    }
-    return result;
-}
-
-void InputDevice::fadePointer() {
-    size_t numMappers = mMappers.size();
-    for (size_t i = 0; i < numMappers; i++) {
-        InputMapper* mapper = mMappers[i];
-        mapper->fadePointer();
-    }
-}
-
-void InputDevice::bumpGeneration() {
-    mGeneration = mContext->bumpGeneration();
-}
-
-void InputDevice::notifyReset(nsecs_t when) {
-    NotifyDeviceResetArgs args(when, mId);
-    mContext->getListener()->notifyDeviceReset(&args);
-}
-
-
-// --- CursorButtonAccumulator ---
-
-CursorButtonAccumulator::CursorButtonAccumulator() {
-    clearButtons();
-}
-
-void CursorButtonAccumulator::reset(InputDevice* device) {
-    mBtnLeft = device->isKeyPressed(BTN_LEFT);
-    mBtnRight = device->isKeyPressed(BTN_RIGHT);
-    mBtnMiddle = device->isKeyPressed(BTN_MIDDLE);
-    mBtnBack = device->isKeyPressed(BTN_BACK);
-    mBtnSide = device->isKeyPressed(BTN_SIDE);
-    mBtnForward = device->isKeyPressed(BTN_FORWARD);
-    mBtnExtra = device->isKeyPressed(BTN_EXTRA);
-    mBtnTask = device->isKeyPressed(BTN_TASK);
-}
-
-void CursorButtonAccumulator::clearButtons() {
-    mBtnLeft = 0;
-    mBtnRight = 0;
-    mBtnMiddle = 0;
-    mBtnBack = 0;
-    mBtnSide = 0;
-    mBtnForward = 0;
-    mBtnExtra = 0;
-    mBtnTask = 0;
-}
-
-void CursorButtonAccumulator::process(const RawEvent* rawEvent) {
-    if (rawEvent->type == EV_KEY) {
-        switch (rawEvent->code) {
-        case BTN_LEFT:
-            mBtnLeft = rawEvent->value;
-            break;
-        case BTN_RIGHT:
-            mBtnRight = rawEvent->value;
-            break;
-        case BTN_MIDDLE:
-            mBtnMiddle = rawEvent->value;
-            break;
-        case BTN_BACK:
-            mBtnBack = rawEvent->value;
-            break;
-        case BTN_SIDE:
-            mBtnSide = rawEvent->value;
-            break;
-        case BTN_FORWARD:
-            mBtnForward = rawEvent->value;
-            break;
-        case BTN_EXTRA:
-            mBtnExtra = rawEvent->value;
-            break;
-        case BTN_TASK:
-            mBtnTask = rawEvent->value;
-            break;
-        }
-    }
-}
-
-uint32_t CursorButtonAccumulator::getButtonState() const {
-    uint32_t result = 0;
-    if (mBtnLeft) {
-        result |= AMOTION_EVENT_BUTTON_PRIMARY;
-    }
-    if (mBtnRight) {
-        result |= AMOTION_EVENT_BUTTON_SECONDARY;
-    }
-    if (mBtnMiddle) {
-        result |= AMOTION_EVENT_BUTTON_TERTIARY;
-    }
-    if (mBtnBack || mBtnSide) {
-        result |= AMOTION_EVENT_BUTTON_BACK;
-    }
-    if (mBtnForward || mBtnExtra) {
-        result |= AMOTION_EVENT_BUTTON_FORWARD;
-    }
-    return result;
-}
-
-
-// --- CursorMotionAccumulator ---
-
-CursorMotionAccumulator::CursorMotionAccumulator() {
-    clearRelativeAxes();
-}
-
-void CursorMotionAccumulator::reset(InputDevice* device) {
-    clearRelativeAxes();
-}
-
-void CursorMotionAccumulator::clearRelativeAxes() {
-    mRelX = 0;
-    mRelY = 0;
-}
-
-void CursorMotionAccumulator::process(const RawEvent* rawEvent) {
-    if (rawEvent->type == EV_REL) {
-        switch (rawEvent->code) {
-        case REL_X:
-            mRelX = rawEvent->value;
-            break;
-        case REL_Y:
-            mRelY = rawEvent->value;
-            break;
-        }
-    }
-}
-
-void CursorMotionAccumulator::finishSync() {
-    clearRelativeAxes();
-}
-
-
-// --- CursorScrollAccumulator ---
-
-CursorScrollAccumulator::CursorScrollAccumulator() :
-        mHaveRelWheel(false), mHaveRelHWheel(false) {
-    clearRelativeAxes();
-}
-
-void CursorScrollAccumulator::configure(InputDevice* device) {
-    mHaveRelWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_WHEEL);
-    mHaveRelHWheel = device->getEventHub()->hasRelativeAxis(device->getId(), REL_HWHEEL);
-}
-
-void CursorScrollAccumulator::reset(InputDevice* device) {
-    clearRelativeAxes();
-}
-
-void CursorScrollAccumulator::clearRelativeAxes() {
-    mRelWheel = 0;
-    mRelHWheel = 0;
-}
-
-void CursorScrollAccumulator::process(const RawEvent* rawEvent) {
-    if (rawEvent->type == EV_REL) {
-        switch (rawEvent->code) {
-        case REL_WHEEL:
-            mRelWheel = rawEvent->value;
-            break;
-        case REL_HWHEEL:
-            mRelHWheel = rawEvent->value;
-            break;
-        }
-    }
-}
-
-void CursorScrollAccumulator::finishSync() {
-    clearRelativeAxes();
-}
-
-
-// --- TouchButtonAccumulator ---
-
-TouchButtonAccumulator::TouchButtonAccumulator() :
-        mHaveBtnTouch(false), mHaveStylus(false) {
-    clearButtons();
-}
-
-void TouchButtonAccumulator::configure(InputDevice* device) {
-    mHaveBtnTouch = device->hasKey(BTN_TOUCH);
-    mHaveStylus = device->hasKey(BTN_TOOL_PEN)
-            || device->hasKey(BTN_TOOL_RUBBER)
-            || device->hasKey(BTN_TOOL_BRUSH)
-            || device->hasKey(BTN_TOOL_PENCIL)
-            || device->hasKey(BTN_TOOL_AIRBRUSH);
-}
-
-void TouchButtonAccumulator::reset(InputDevice* device) {
-    mBtnTouch = device->isKeyPressed(BTN_TOUCH);
-    mBtnStylus = device->isKeyPressed(BTN_STYLUS);
-    mBtnStylus2 = device->isKeyPressed(BTN_STYLUS);
-    mBtnToolFinger = device->isKeyPressed(BTN_TOOL_FINGER);
-    mBtnToolPen = device->isKeyPressed(BTN_TOOL_PEN);
-    mBtnToolRubber = device->isKeyPressed(BTN_TOOL_RUBBER);
-    mBtnToolBrush = device->isKeyPressed(BTN_TOOL_BRUSH);
-    mBtnToolPencil = device->isKeyPressed(BTN_TOOL_PENCIL);
-    mBtnToolAirbrush = device->isKeyPressed(BTN_TOOL_AIRBRUSH);
-    mBtnToolMouse = device->isKeyPressed(BTN_TOOL_MOUSE);
-    mBtnToolLens = device->isKeyPressed(BTN_TOOL_LENS);
-    mBtnToolDoubleTap = device->isKeyPressed(BTN_TOOL_DOUBLETAP);
-    mBtnToolTripleTap = device->isKeyPressed(BTN_TOOL_TRIPLETAP);
-    mBtnToolQuadTap = device->isKeyPressed(BTN_TOOL_QUADTAP);
-}
-
-void TouchButtonAccumulator::clearButtons() {
-    mBtnTouch = 0;
-    mBtnStylus = 0;
-    mBtnStylus2 = 0;
-    mBtnToolFinger = 0;
-    mBtnToolPen = 0;
-    mBtnToolRubber = 0;
-    mBtnToolBrush = 0;
-    mBtnToolPencil = 0;
-    mBtnToolAirbrush = 0;
-    mBtnToolMouse = 0;
-    mBtnToolLens = 0;
-    mBtnToolDoubleTap = 0;
-    mBtnToolTripleTap = 0;
-    mBtnToolQuadTap = 0;
-}
-
-void TouchButtonAccumulator::process(const RawEvent* rawEvent) {
-    if (rawEvent->type == EV_KEY) {
-        switch (rawEvent->code) {
-        case BTN_TOUCH:
-            mBtnTouch = rawEvent->value;
-            break;
-        case BTN_STYLUS:
-            mBtnStylus = rawEvent->value;
-            break;
-        case BTN_STYLUS2:
-            mBtnStylus2 = rawEvent->value;
-            break;
-        case BTN_TOOL_FINGER:
-            mBtnToolFinger = rawEvent->value;
-            break;
-        case BTN_TOOL_PEN:
-            mBtnToolPen = rawEvent->value;
-            break;
-        case BTN_TOOL_RUBBER:
-            mBtnToolRubber = rawEvent->value;
-            break;
-        case BTN_TOOL_BRUSH:
-            mBtnToolBrush = rawEvent->value;
-            break;
-        case BTN_TOOL_PENCIL:
-            mBtnToolPencil = rawEvent->value;
-            break;
-        case BTN_TOOL_AIRBRUSH:
-            mBtnToolAirbrush = rawEvent->value;
-            break;
-        case BTN_TOOL_MOUSE:
-            mBtnToolMouse = rawEvent->value;
-            break;
-        case BTN_TOOL_LENS:
-            mBtnToolLens = rawEvent->value;
-            break;
-        case BTN_TOOL_DOUBLETAP:
-            mBtnToolDoubleTap = rawEvent->value;
-            break;
-        case BTN_TOOL_TRIPLETAP:
-            mBtnToolTripleTap = rawEvent->value;
-            break;
-        case BTN_TOOL_QUADTAP:
-            mBtnToolQuadTap = rawEvent->value;
-            break;
-        }
-    }
-}
-
-uint32_t TouchButtonAccumulator::getButtonState() const {
-    uint32_t result = 0;
-    if (mBtnStylus) {
-        result |= AMOTION_EVENT_BUTTON_SECONDARY;
-    }
-    if (mBtnStylus2) {
-        result |= AMOTION_EVENT_BUTTON_TERTIARY;
-    }
-    return result;
-}
-
-int32_t TouchButtonAccumulator::getToolType() const {
-    if (mBtnToolMouse || mBtnToolLens) {
-        return AMOTION_EVENT_TOOL_TYPE_MOUSE;
-    }
-    if (mBtnToolRubber) {
-        return AMOTION_EVENT_TOOL_TYPE_ERASER;
-    }
-    if (mBtnToolPen || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush) {
-        return AMOTION_EVENT_TOOL_TYPE_STYLUS;
-    }
-    if (mBtnToolFinger || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap) {
-        return AMOTION_EVENT_TOOL_TYPE_FINGER;
-    }
-    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
-bool TouchButtonAccumulator::isToolActive() const {
-    return mBtnTouch || mBtnToolFinger || mBtnToolPen || mBtnToolRubber
-            || mBtnToolBrush || mBtnToolPencil || mBtnToolAirbrush
-            || mBtnToolMouse || mBtnToolLens
-            || mBtnToolDoubleTap || mBtnToolTripleTap || mBtnToolQuadTap;
-}
-
-bool TouchButtonAccumulator::isHovering() const {
-    return mHaveBtnTouch && !mBtnTouch;
-}
-
-bool TouchButtonAccumulator::hasStylus() const {
-    return mHaveStylus;
-}
-
-
-// --- RawPointerAxes ---
-
-RawPointerAxes::RawPointerAxes() {
-    clear();
-}
-
-void RawPointerAxes::clear() {
-    x.clear();
-    y.clear();
-    pressure.clear();
-    touchMajor.clear();
-    touchMinor.clear();
-    toolMajor.clear();
-    toolMinor.clear();
-    orientation.clear();
-    distance.clear();
-    tiltX.clear();
-    tiltY.clear();
-    trackingId.clear();
-    slot.clear();
-}
-
-
-// --- RawPointerData ---
-
-RawPointerData::RawPointerData() {
-    clear();
-}
-
-void RawPointerData::clear() {
-    pointerCount = 0;
-    clearIdBits();
-}
-
-void RawPointerData::copyFrom(const RawPointerData& other) {
-    pointerCount = other.pointerCount;
-    hoveringIdBits = other.hoveringIdBits;
-    touchingIdBits = other.touchingIdBits;
-
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        pointers[i] = other.pointers[i];
-
-        int id = pointers[i].id;
-        idToIndex[id] = other.idToIndex[id];
-    }
-}
-
-void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
-    float x = 0, y = 0;
-    uint32_t count = touchingIdBits.count();
-    if (count) {
-        for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
-            uint32_t id = idBits.clearFirstMarkedBit();
-            const Pointer& pointer = pointerForId(id);
-            x += pointer.x;
-            y += pointer.y;
-        }
-        x /= count;
-        y /= count;
-    }
-    *outX = x;
-    *outY = y;
-}
-
-
-// --- CookedPointerData ---
-
-CookedPointerData::CookedPointerData() {
-    clear();
-}
-
-void CookedPointerData::clear() {
-    pointerCount = 0;
-    hoveringIdBits.clear();
-    touchingIdBits.clear();
-}
-
-void CookedPointerData::copyFrom(const CookedPointerData& other) {
-    pointerCount = other.pointerCount;
-    hoveringIdBits = other.hoveringIdBits;
-    touchingIdBits = other.touchingIdBits;
-
-    for (uint32_t i = 0; i < pointerCount; i++) {
-        pointerProperties[i].copyFrom(other.pointerProperties[i]);
-        pointerCoords[i].copyFrom(other.pointerCoords[i]);
-
-        int id = pointerProperties[i].id;
-        idToIndex[id] = other.idToIndex[id];
-    }
-}
-
-
-// --- SingleTouchMotionAccumulator ---
-
-SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
-    clearAbsoluteAxes();
-}
-
-void SingleTouchMotionAccumulator::reset(InputDevice* device) {
-    mAbsX = device->getAbsoluteAxisValue(ABS_X);
-    mAbsY = device->getAbsoluteAxisValue(ABS_Y);
-    mAbsPressure = device->getAbsoluteAxisValue(ABS_PRESSURE);
-    mAbsToolWidth = device->getAbsoluteAxisValue(ABS_TOOL_WIDTH);
-    mAbsDistance = device->getAbsoluteAxisValue(ABS_DISTANCE);
-    mAbsTiltX = device->getAbsoluteAxisValue(ABS_TILT_X);
-    mAbsTiltY = device->getAbsoluteAxisValue(ABS_TILT_Y);
-}
-
-void SingleTouchMotionAccumulator::clearAbsoluteAxes() {
-    mAbsX = 0;
-    mAbsY = 0;
-    mAbsPressure = 0;
-    mAbsToolWidth = 0;
-    mAbsDistance = 0;
-    mAbsTiltX = 0;
-    mAbsTiltY = 0;
-}
-
-void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) {
-    if (rawEvent->type == EV_ABS) {
-        switch (rawEvent->code) {
-        case ABS_X:
-            mAbsX = rawEvent->value;
-            break;
-        case ABS_Y:
-            mAbsY = rawEvent->value;
-            break;
-        case ABS_PRESSURE:
-            mAbsPressure = rawEvent->value;
-            break;
-        case ABS_TOOL_WIDTH:
-            mAbsToolWidth = rawEvent->value;
-            break;
-        case ABS_DISTANCE:
-            mAbsDistance = rawEvent->value;
-            break;
-        case ABS_TILT_X:
-            mAbsTiltX = rawEvent->value;
-            break;
-        case ABS_TILT_Y:
-            mAbsTiltY = rawEvent->value;
-            break;
-        }
-    }
-}
-
-
-// --- MultiTouchMotionAccumulator ---
-
-MultiTouchMotionAccumulator::MultiTouchMotionAccumulator() :
-        mCurrentSlot(-1), mSlots(NULL), mSlotCount(0), mUsingSlotsProtocol(false),
-        mHaveStylus(false) {
-}
-
-MultiTouchMotionAccumulator::~MultiTouchMotionAccumulator() {
-    delete[] mSlots;
-}
-
-void MultiTouchMotionAccumulator::configure(InputDevice* device,
-        size_t slotCount, bool usingSlotsProtocol) {
-    mSlotCount = slotCount;
-    mUsingSlotsProtocol = usingSlotsProtocol;
-    mHaveStylus = device->hasAbsoluteAxis(ABS_MT_TOOL_TYPE);
-
-    delete[] mSlots;
-    mSlots = new Slot[slotCount];
-}
-
-void MultiTouchMotionAccumulator::reset(InputDevice* device) {
-    // Unfortunately there is no way to read the initial contents of the slots.
-    // So when we reset the accumulator, we must assume they are all zeroes.
-    if (mUsingSlotsProtocol) {
-        // Query the driver for the current slot index and use it as the initial slot
-        // before we start reading events from the device.  It is possible that the
-        // current slot index will not be the same as it was when the first event was
-        // written into the evdev buffer, which means the input mapper could start
-        // out of sync with the initial state of the events in the evdev buffer.
-        // In the extremely unlikely case that this happens, the data from
-        // two slots will be confused until the next ABS_MT_SLOT event is received.
-        // This can cause the touch point to "jump", but at least there will be
-        // no stuck touches.
-        int32_t initialSlot;
-        status_t status = device->getEventHub()->getAbsoluteAxisValue(device->getId(),
-                ABS_MT_SLOT, &initialSlot);
-        if (status) {
-            ALOGD("Could not retrieve current multitouch slot index.  status=%d", status);
-            initialSlot = -1;
-        }
-        clearSlots(initialSlot);
-    } else {
-        clearSlots(-1);
-    }
-}
-
-void MultiTouchMotionAccumulator::clearSlots(int32_t initialSlot) {
-    if (mSlots) {
-        for (size_t i = 0; i < mSlotCount; i++) {
-            mSlots[i].clear();
-        }
-    }
-    mCurrentSlot = initialSlot;
-}
-
-void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
-    if (rawEvent->type == EV_ABS) {
-        bool newSlot = false;
-        if (mUsingSlotsProtocol) {
-            if (rawEvent->code == ABS_MT_SLOT) {
-                mCurrentSlot = rawEvent->value;
-                newSlot = true;
-            }
-        } else if (mCurrentSlot < 0) {
-            mCurrentSlot = 0;
-        }
-
-        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
-#if DEBUG_POINTERS
-            if (newSlot) {
-                ALOGW("MultiTouch device emitted invalid slot index %d but it "
-                        "should be between 0 and %d; ignoring this slot.",
-                        mCurrentSlot, mSlotCount - 1);
-            }
-#endif
-        } else {
-            Slot* slot = &mSlots[mCurrentSlot];
-
-            switch (rawEvent->code) {
-            case ABS_MT_POSITION_X:
-                slot->mInUse = true;
-                slot->mAbsMTPositionX = rawEvent->value;
-                break;
-            case ABS_MT_POSITION_Y:
-                slot->mInUse = true;
-                slot->mAbsMTPositionY = rawEvent->value;
-                break;
-            case ABS_MT_TOUCH_MAJOR:
-                slot->mInUse = true;
-                slot->mAbsMTTouchMajor = rawEvent->value;
-                break;
-            case ABS_MT_TOUCH_MINOR:
-                slot->mInUse = true;
-                slot->mAbsMTTouchMinor = rawEvent->value;
-                slot->mHaveAbsMTTouchMinor = true;
-                break;
-            case ABS_MT_WIDTH_MAJOR:
-                slot->mInUse = true;
-                slot->mAbsMTWidthMajor = rawEvent->value;
-                break;
-            case ABS_MT_WIDTH_MINOR:
-                slot->mInUse = true;
-                slot->mAbsMTWidthMinor = rawEvent->value;
-                slot->mHaveAbsMTWidthMinor = true;
-                break;
-            case ABS_MT_ORIENTATION:
-                slot->mInUse = true;
-                slot->mAbsMTOrientation = rawEvent->value;
-                break;
-            case ABS_MT_TRACKING_ID:
-                if (mUsingSlotsProtocol && rawEvent->value < 0) {
-                    // The slot is no longer in use but it retains its previous contents,
-                    // which may be reused for subsequent touches.
-                    slot->mInUse = false;
-                } else {
-                    slot->mInUse = true;
-                    slot->mAbsMTTrackingId = rawEvent->value;
-                }
-                break;
-            case ABS_MT_PRESSURE:
-                slot->mInUse = true;
-                slot->mAbsMTPressure = rawEvent->value;
-                break;
-            case ABS_MT_DISTANCE:
-                slot->mInUse = true;
-                slot->mAbsMTDistance = rawEvent->value;
-                break;
-            case ABS_MT_TOOL_TYPE:
-                slot->mInUse = true;
-                slot->mAbsMTToolType = rawEvent->value;
-                slot->mHaveAbsMTToolType = true;
-                break;
-            }
-        }
-    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
-        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
-        mCurrentSlot += 1;
-    }
-}
-
-void MultiTouchMotionAccumulator::finishSync() {
-    if (!mUsingSlotsProtocol) {
-        clearSlots(-1);
-    }
-}
-
-bool MultiTouchMotionAccumulator::hasStylus() const {
-    return mHaveStylus;
-}
-
-
-// --- MultiTouchMotionAccumulator::Slot ---
-
-MultiTouchMotionAccumulator::Slot::Slot() {
-    clear();
-}
-
-void MultiTouchMotionAccumulator::Slot::clear() {
-    mInUse = false;
-    mHaveAbsMTTouchMinor = false;
-    mHaveAbsMTWidthMinor = false;
-    mHaveAbsMTToolType = false;
-    mAbsMTPositionX = 0;
-    mAbsMTPositionY = 0;
-    mAbsMTTouchMajor = 0;
-    mAbsMTTouchMinor = 0;
-    mAbsMTWidthMajor = 0;
-    mAbsMTWidthMinor = 0;
-    mAbsMTOrientation = 0;
-    mAbsMTTrackingId = -1;
-    mAbsMTPressure = 0;
-    mAbsMTDistance = 0;
-    mAbsMTToolType = 0;
-}
-
-int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
-    if (mHaveAbsMTToolType) {
-        switch (mAbsMTToolType) {
-        case MT_TOOL_FINGER:
-            return AMOTION_EVENT_TOOL_TYPE_FINGER;
-        case MT_TOOL_PEN:
-            return AMOTION_EVENT_TOOL_TYPE_STYLUS;
-        }
-    }
-    return AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-}
-
-
-// --- InputMapper ---
-
-InputMapper::InputMapper(InputDevice* device) :
-        mDevice(device), mContext(device->getContext()) {
-}
-
-InputMapper::~InputMapper() {
-}
-
-void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    info->addSource(getSources());
-}
-
-void InputMapper::dump(String8& dump) {
-}
-
-void InputMapper::configure(nsecs_t when,
-        const InputReaderConfiguration* config, uint32_t changes) {
-}
-
-void InputMapper::reset(nsecs_t when) {
-}
-
-void InputMapper::timeoutExpired(nsecs_t when) {
-}
-
-int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-    return AKEY_STATE_UNKNOWN;
-}
-
-bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    return false;
-}
-
-void InputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
-        int32_t token) {
-}
-
-void InputMapper::cancelVibrate(int32_t token) {
-}
-
-int32_t InputMapper::getMetaState() {
-    return 0;
-}
-
-void InputMapper::fadePointer() {
-}
-
-status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
-    return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
-}
-
-void InputMapper::bumpGeneration() {
-    mDevice->bumpGeneration();
-}
-
-void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
-        const RawAbsoluteAxisInfo& axis, const char* name) {
-    if (axis.valid) {
-        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d, resolution=%d\n",
-                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz, axis.resolution);
-    } else {
-        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
-    }
-}
-
-
-// --- SwitchInputMapper ---
-
-SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
-        InputMapper(device), mUpdatedSwitchValues(0), mUpdatedSwitchMask(0) {
-}
-
-SwitchInputMapper::~SwitchInputMapper() {
-}
-
-uint32_t SwitchInputMapper::getSources() {
-    return AINPUT_SOURCE_SWITCH;
-}
-
-void SwitchInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_SW:
-        processSwitch(rawEvent->code, rawEvent->value);
-        break;
-
-    case EV_SYN:
-        if (rawEvent->code == SYN_REPORT) {
-            sync(rawEvent->when);
-        }
-    }
-}
-
-void SwitchInputMapper::processSwitch(int32_t switchCode, int32_t switchValue) {
-    if (switchCode >= 0 && switchCode < 32) {
-        if (switchValue) {
-            mUpdatedSwitchValues |= 1 << switchCode;
-        }
-        mUpdatedSwitchMask |= 1 << switchCode;
-    }
-}
-
-void SwitchInputMapper::sync(nsecs_t when) {
-    if (mUpdatedSwitchMask) {
-        NotifySwitchArgs args(when, 0, mUpdatedSwitchValues, mUpdatedSwitchMask);
-        getListener()->notifySwitch(&args);
-
-        mUpdatedSwitchValues = 0;
-        mUpdatedSwitchMask = 0;
-    }
-}
-
-int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
-}
-
-
-// --- VibratorInputMapper ---
-
-VibratorInputMapper::VibratorInputMapper(InputDevice* device) :
-        InputMapper(device), mVibrating(false) {
-}
-
-VibratorInputMapper::~VibratorInputMapper() {
-}
-
-uint32_t VibratorInputMapper::getSources() {
-    return 0;
-}
-
-void VibratorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    info->setVibrator(true);
-}
-
-void VibratorInputMapper::process(const RawEvent* rawEvent) {
-    // TODO: Handle FF_STATUS, although it does not seem to be widely supported.
-}
-
-void VibratorInputMapper::vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
-        int32_t token) {
-#if DEBUG_VIBRATOR
-    String8 patternStr;
-    for (size_t i = 0; i < patternSize; i++) {
-        if (i != 0) {
-            patternStr.append(", ");
-        }
-        patternStr.appendFormat("%lld", pattern[i]);
-    }
-    ALOGD("vibrate: deviceId=%d, pattern=[%s], repeat=%ld, token=%d",
-            getDeviceId(), patternStr.string(), repeat, token);
-#endif
-
-    mVibrating = true;
-    memcpy(mPattern, pattern, patternSize * sizeof(nsecs_t));
-    mPatternSize = patternSize;
-    mRepeat = repeat;
-    mToken = token;
-    mIndex = -1;
-
-    nextStep();
-}
-
-void VibratorInputMapper::cancelVibrate(int32_t token) {
-#if DEBUG_VIBRATOR
-    ALOGD("cancelVibrate: deviceId=%d, token=%d", getDeviceId(), token);
-#endif
-
-    if (mVibrating && mToken == token) {
-        stopVibrating();
-    }
-}
-
-void VibratorInputMapper::timeoutExpired(nsecs_t when) {
-    if (mVibrating) {
-        if (when >= mNextStepTime) {
-            nextStep();
-        } else {
-            getContext()->requestTimeoutAtTime(mNextStepTime);
-        }
-    }
-}
-
-void VibratorInputMapper::nextStep() {
-    mIndex += 1;
-    if (size_t(mIndex) >= mPatternSize) {
-        if (mRepeat < 0) {
-            // We are done.
-            stopVibrating();
-            return;
-        }
-        mIndex = mRepeat;
-    }
-
-    bool vibratorOn = mIndex & 1;
-    nsecs_t duration = mPattern[mIndex];
-    if (vibratorOn) {
-#if DEBUG_VIBRATOR
-        ALOGD("nextStep: sending vibrate deviceId=%d, duration=%lld",
-                getDeviceId(), duration);
-#endif
-        getEventHub()->vibrate(getDeviceId(), duration);
-    } else {
-#if DEBUG_VIBRATOR
-        ALOGD("nextStep: sending cancel vibrate deviceId=%d", getDeviceId());
-#endif
-        getEventHub()->cancelVibrate(getDeviceId());
-    }
-    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
-    mNextStepTime = now + duration;
-    getContext()->requestTimeoutAtTime(mNextStepTime);
-#if DEBUG_VIBRATOR
-    ALOGD("nextStep: scheduled timeout in %0.3fms", duration * 0.000001f);
-#endif
-}
-
-void VibratorInputMapper::stopVibrating() {
-    mVibrating = false;
-#if DEBUG_VIBRATOR
-    ALOGD("stopVibrating: sending cancel vibrate deviceId=%d", getDeviceId());
-#endif
-    getEventHub()->cancelVibrate(getDeviceId());
-}
-
-void VibratorInputMapper::dump(String8& dump) {
-    dump.append(INDENT2 "Vibrator Input Mapper:\n");
-    dump.appendFormat(INDENT3 "Vibrating: %s\n", toString(mVibrating));
-}
-
-
-// --- KeyboardInputMapper ---
-
-KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
-        uint32_t source, int32_t keyboardType) :
-        InputMapper(device), mSource(source),
-        mKeyboardType(keyboardType) {
-}
-
-KeyboardInputMapper::~KeyboardInputMapper() {
-}
-
-uint32_t KeyboardInputMapper::getSources() {
-    return mSource;
-}
-
-void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    info->setKeyboardType(mKeyboardType);
-    info->setKeyCharacterMap(getEventHub()->getKeyCharacterMap(getDeviceId()));
-}
-
-void KeyboardInputMapper::dump(String8& dump) {
-    dump.append(INDENT2 "Keyboard Input Mapper:\n");
-    dumpParameters(dump);
-    dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
-    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
-    dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
-    dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
-    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
-}
-
-
-void KeyboardInputMapper::configure(nsecs_t when,
-        const InputReaderConfiguration* config, uint32_t changes) {
-    InputMapper::configure(when, config, changes);
-
-    if (!changes) { // first time only
-        // Configure basic parameters.
-        configureParameters();
-    }
-
-    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
-        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
-            DisplayViewport v;
-            if (config->getDisplayInfo(false /*external*/, &v)) {
-                mOrientation = v.orientation;
-            } else {
-                mOrientation = DISPLAY_ORIENTATION_0;
-            }
-        } else {
-            mOrientation = DISPLAY_ORIENTATION_0;
-        }
-    }
-}
-
-void KeyboardInputMapper::configureParameters() {
-    mParameters.orientationAware = false;
-    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
-            mParameters.orientationAware);
-
-    mParameters.hasAssociatedDisplay = false;
-    if (mParameters.orientationAware) {
-        mParameters.hasAssociatedDisplay = true;
-    }
-
-    mParameters.handlesKeyRepeat = false;
-    getDevice()->getConfiguration().tryGetProperty(String8("keyboard.handlesKeyRepeat"),
-            mParameters.handlesKeyRepeat);
-}
-
-void KeyboardInputMapper::dumpParameters(String8& dump) {
-    dump.append(INDENT3 "Parameters:\n");
-    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
-            toString(mParameters.hasAssociatedDisplay));
-    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
-            toString(mParameters.orientationAware));
-    dump.appendFormat(INDENT4 "HandlesKeyRepeat: %s\n",
-            toString(mParameters.handlesKeyRepeat));
-}
-
-void KeyboardInputMapper::reset(nsecs_t when) {
-    mMetaState = AMETA_NONE;
-    mDownTime = 0;
-    mKeyDowns.clear();
-    mCurrentHidUsage = 0;
-
-    resetLedState();
-
-    InputMapper::reset(when);
-}
-
-void KeyboardInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_KEY: {
-        int32_t scanCode = rawEvent->code;
-        int32_t usageCode = mCurrentHidUsage;
-        mCurrentHidUsage = 0;
-
-        if (isKeyboardOrGamepadKey(scanCode)) {
-            int32_t keyCode;
-            uint32_t flags;
-            if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) {
-                keyCode = AKEYCODE_UNKNOWN;
-                flags = 0;
-            }
-            processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags);
-        }
-        break;
-    }
-    case EV_MSC: {
-        if (rawEvent->code == MSC_SCAN) {
-            mCurrentHidUsage = rawEvent->value;
-        }
-        break;
-    }
-    case EV_SYN: {
-        if (rawEvent->code == SYN_REPORT) {
-            mCurrentHidUsage = 0;
-        }
-    }
-    }
-}
-
-bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
-    return scanCode < BTN_MOUSE
-        || scanCode >= KEY_OK
-        || (scanCode >= BTN_MISC && scanCode < BTN_MOUSE)
-        || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI);
-}
-
-void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
-        int32_t scanCode, uint32_t policyFlags) {
-
-    if (down) {
-        // Rotate key codes according to orientation if needed.
-        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
-            keyCode = rotateKeyCode(keyCode, mOrientation);
-        }
-
-        // Add key down.
-        ssize_t keyDownIndex = findKeyDown(scanCode);
-        if (keyDownIndex >= 0) {
-            // key repeat, be sure to use same keycode as before in case of rotation
-            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
-        } else {
-            // key down
-            if ((policyFlags & POLICY_FLAG_VIRTUAL)
-                    && mContext->shouldDropVirtualKey(when,
-                            getDevice(), keyCode, scanCode)) {
-                return;
-            }
-
-            mKeyDowns.push();
-            KeyDown& keyDown = mKeyDowns.editTop();
-            keyDown.keyCode = keyCode;
-            keyDown.scanCode = scanCode;
-        }
-
-        mDownTime = when;
-    } else {
-        // Remove key down.
-        ssize_t keyDownIndex = findKeyDown(scanCode);
-        if (keyDownIndex >= 0) {
-            // key up, be sure to use same keycode as before in case of rotation
-            keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
-            mKeyDowns.removeAt(size_t(keyDownIndex));
-        } else {
-            // key was not actually down
-            ALOGI("Dropping key up from device %s because the key was not down.  "
-                    "keyCode=%d, scanCode=%d",
-                    getDeviceName().string(), keyCode, scanCode);
-            return;
-        }
-    }
-
-    int32_t oldMetaState = mMetaState;
-    int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
-    bool metaStateChanged = oldMetaState != newMetaState;
-    if (metaStateChanged) {
-        mMetaState = newMetaState;
-        updateLedState(false);
-    }
-
-    nsecs_t downTime = mDownTime;
-
-    // Key down on external an keyboard should wake the device.
-    // We don't do this for internal keyboards to prevent them from waking up in your pocket.
-    // For internal keyboards, the key layout file should specify the policy flags for
-    // each wake key individually.
-    // TODO: Use the input device configuration to control this behavior more finely.
-    if (down && getDevice()->isExternal()
-            && !(policyFlags & (POLICY_FLAG_WAKE | POLICY_FLAG_WAKE_DROPPED))) {
-        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
-    }
-
-    if (mParameters.handlesKeyRepeat) {
-        policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
-    }
-
-    if (metaStateChanged) {
-        getContext()->updateGlobalMetaState();
-    }
-
-    if (down && !isMetaKey(keyCode)) {
-        getContext()->fadePointer();
-    }
-
-    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
-            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
-            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
-    getListener()->notifyKey(&args);
-}
-
-ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
-    size_t n = mKeyDowns.size();
-    for (size_t i = 0; i < n; i++) {
-        if (mKeyDowns[i].scanCode == scanCode) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
-}
-
-int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
-}
-
-bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
-}
-
-int32_t KeyboardInputMapper::getMetaState() {
-    return mMetaState;
-}
-
-void KeyboardInputMapper::resetLedState() {
-    initializeLedState(mCapsLockLedState, ALED_CAPS_LOCK);
-    initializeLedState(mNumLockLedState, ALED_NUM_LOCK);
-    initializeLedState(mScrollLockLedState, ALED_SCROLL_LOCK);
-
-    updateLedState(true);
-}
-
-void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
-    ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
-    ledState.on = false;
-}
-
-void KeyboardInputMapper::updateLedState(bool reset) {
-    updateLedStateForModifier(mCapsLockLedState, ALED_CAPS_LOCK,
-            AMETA_CAPS_LOCK_ON, reset);
-    updateLedStateForModifier(mNumLockLedState, ALED_NUM_LOCK,
-            AMETA_NUM_LOCK_ON, reset);
-    updateLedStateForModifier(mScrollLockLedState, ALED_SCROLL_LOCK,
-            AMETA_SCROLL_LOCK_ON, reset);
-}
-
-void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
-        int32_t led, int32_t modifier, bool reset) {
-    if (ledState.avail) {
-        bool desiredState = (mMetaState & modifier) != 0;
-        if (reset || ledState.on != desiredState) {
-            getEventHub()->setLedState(getDeviceId(), led, desiredState);
-            ledState.on = desiredState;
-        }
-    }
-}
-
-
-// --- CursorInputMapper ---
-
-CursorInputMapper::CursorInputMapper(InputDevice* device) :
-        InputMapper(device) {
-}
-
-CursorInputMapper::~CursorInputMapper() {
-}
-
-uint32_t CursorInputMapper::getSources() {
-    return mSource;
-}
-
-void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    if (mParameters.mode == Parameters::MODE_POINTER) {
-        float minX, minY, maxX, maxY;
-        if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
-            info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, minX, maxX, 0.0f, 0.0f, 0.0f);
-            info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, minY, maxY, 0.0f, 0.0f, 0.0f);
-        }
-    } else {
-        info->addMotionRange(AMOTION_EVENT_AXIS_X, mSource, -1.0f, 1.0f, 0.0f, mXScale, 0.0f);
-        info->addMotionRange(AMOTION_EVENT_AXIS_Y, mSource, -1.0f, 1.0f, 0.0f, mYScale, 0.0f);
-    }
-    info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mSource, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
-
-    if (mCursorScrollAccumulator.haveRelativeVWheel()) {
-        info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
-    }
-    if (mCursorScrollAccumulator.haveRelativeHWheel()) {
-        info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
-    }
-}
-
-void CursorInputMapper::dump(String8& dump) {
-    dump.append(INDENT2 "Cursor Input Mapper:\n");
-    dumpParameters(dump);
-    dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
-    dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
-    dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
-    dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
-    dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
-            toString(mCursorScrollAccumulator.haveRelativeVWheel()));
-    dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
-            toString(mCursorScrollAccumulator.haveRelativeHWheel()));
-    dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
-    dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
-    dump.appendFormat(INDENT3 "Orientation: %d\n", mOrientation);
-    dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
-    dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
-    dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
-}
-
-void CursorInputMapper::configure(nsecs_t when,
-        const InputReaderConfiguration* config, uint32_t changes) {
-    InputMapper::configure(when, config, changes);
-
-    if (!changes) { // first time only
-        mCursorScrollAccumulator.configure(getDevice());
-
-        // Configure basic parameters.
-        configureParameters();
-
-        // Configure device mode.
-        switch (mParameters.mode) {
-        case Parameters::MODE_POINTER:
-            mSource = AINPUT_SOURCE_MOUSE;
-            mXPrecision = 1.0f;
-            mYPrecision = 1.0f;
-            mXScale = 1.0f;
-            mYScale = 1.0f;
-            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
-            break;
-        case Parameters::MODE_NAVIGATION:
-            mSource = AINPUT_SOURCE_TRACKBALL;
-            mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
-            mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
-            mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
-            mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
-            break;
-        }
-
-        mVWheelScale = 1.0f;
-        mHWheelScale = 1.0f;
-    }
-
-    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
-        mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
-        mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
-        mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
-    }
-
-    if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
-        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
-            DisplayViewport v;
-            if (config->getDisplayInfo(false /*external*/, &v)) {
-                mOrientation = v.orientation;
-            } else {
-                mOrientation = DISPLAY_ORIENTATION_0;
-            }
-        } else {
-            mOrientation = DISPLAY_ORIENTATION_0;
-        }
-        bumpGeneration();
-    }
-}
-
-void CursorInputMapper::configureParameters() {
-    mParameters.mode = Parameters::MODE_POINTER;
-    String8 cursorModeString;
-    if (getDevice()->getConfiguration().tryGetProperty(String8("cursor.mode"), cursorModeString)) {
-        if (cursorModeString == "navigation") {
-            mParameters.mode = Parameters::MODE_NAVIGATION;
-        } else if (cursorModeString != "pointer" && cursorModeString != "default") {
-            ALOGW("Invalid value for cursor.mode: '%s'", cursorModeString.string());
-        }
-    }
-
-    mParameters.orientationAware = false;
-    getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
-            mParameters.orientationAware);
-
-    mParameters.hasAssociatedDisplay = false;
-    if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
-        mParameters.hasAssociatedDisplay = true;
-    }
-}
-
-void CursorInputMapper::dumpParameters(String8& dump) {
-    dump.append(INDENT3 "Parameters:\n");
-    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
-            toString(mParameters.hasAssociatedDisplay));
-
-    switch (mParameters.mode) {
-    case Parameters::MODE_POINTER:
-        dump.append(INDENT4 "Mode: pointer\n");
-        break;
-    case Parameters::MODE_NAVIGATION:
-        dump.append(INDENT4 "Mode: navigation\n");
-        break;
-    default:
-        ALOG_ASSERT(false);
-    }
-
-    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
-            toString(mParameters.orientationAware));
-}
-
-void CursorInputMapper::reset(nsecs_t when) {
-    mButtonState = 0;
-    mDownTime = 0;
-
-    mPointerVelocityControl.reset();
-    mWheelXVelocityControl.reset();
-    mWheelYVelocityControl.reset();
-
-    mCursorButtonAccumulator.reset(getDevice());
-    mCursorMotionAccumulator.reset(getDevice());
-    mCursorScrollAccumulator.reset(getDevice());
-
-    InputMapper::reset(when);
-}
-
-void CursorInputMapper::process(const RawEvent* rawEvent) {
-    mCursorButtonAccumulator.process(rawEvent);
-    mCursorMotionAccumulator.process(rawEvent);
-    mCursorScrollAccumulator.process(rawEvent);
-
-    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
-        sync(rawEvent->when);
-    }
-}
-
-void CursorInputMapper::sync(nsecs_t when) {
-    int32_t lastButtonState = mButtonState;
-    int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
-    mButtonState = currentButtonState;
-
-    bool wasDown = isPointerDown(lastButtonState);
-    bool down = isPointerDown(currentButtonState);
-    bool downChanged;
-    if (!wasDown && down) {
-        mDownTime = when;
-        downChanged = true;
-    } else if (wasDown && !down) {
-        downChanged = true;
-    } else {
-        downChanged = false;
-    }
-    nsecs_t downTime = mDownTime;
-    bool buttonsChanged = currentButtonState != lastButtonState;
-    bool buttonsPressed = currentButtonState & ~lastButtonState;
-
-    float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
-    float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
-    bool moved = deltaX != 0 || deltaY != 0;
-
-    // Rotate delta according to orientation if needed.
-    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
-            && (deltaX != 0.0f || deltaY != 0.0f)) {
-        rotateDelta(mOrientation, &deltaX, &deltaY);
-    }
-
-    // Move the pointer.
-    PointerProperties pointerProperties;
-    pointerProperties.clear();
-    pointerProperties.id = 0;
-    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
-
-    PointerCoords pointerCoords;
-    pointerCoords.clear();
-
-    float vscroll = mCursorScrollAccumulator.getRelativeVWheel();
-    float hscroll = mCursorScrollAccumulator.getRelativeHWheel();
-    bool scrolled = vscroll != 0 || hscroll != 0;
-
-    mWheelYVelocityControl.move(when, NULL, &vscroll);
-    mWheelXVelocityControl.move(when, &hscroll, NULL);
-
-    mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
-    int32_t displayId;
-    if (mPointerController != NULL) {
-        if (moved || scrolled || buttonsChanged) {
-            mPointerController->setPresentation(
-                    PointerControllerInterface::PRESENTATION_POINTER);
-
-            if (moved) {
-                mPointerController->move(deltaX, deltaY);
-            }
-
-            if (buttonsChanged) {
-                mPointerController->setButtonState(currentButtonState);
-            }
-
-            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
-        }
-
-        float x, y;
-        mPointerController->getPosition(&x, &y);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-        displayId = ADISPLAY_ID_DEFAULT;
-    } else {
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
-        displayId = ADISPLAY_ID_NONE;
-    }
-
-    pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
-
-    // Moving an external trackball or mouse should wake the device.
-    // We don't do this for internal cursor devices to prevent them from waking up
-    // the device in your pocket.
-    // TODO: Use the input device configuration to control this behavior more finely.
-    uint32_t policyFlags = 0;
-    if ((buttonsPressed || moved || scrolled) && getDevice()->isExternal()) {
-        policyFlags |= POLICY_FLAG_WAKE_DROPPED;
-    }
-
-    // Synthesize key down from buttons if needed.
-    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
-            policyFlags, lastButtonState, currentButtonState);
-
-    // Send motion event.
-    if (downChanged || moved || scrolled || buttonsChanged) {
-        int32_t metaState = mContext->getGlobalMetaState();
-        int32_t motionEventAction;
-        if (downChanged) {
-            motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
-        } else if (down || mPointerController == NULL) {
-            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
-        } else {
-            motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
-        }
-
-        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                motionEventAction, 0, metaState, currentButtonState, 0,
-                displayId, 1, &pointerProperties, &pointerCoords,
-                mXPrecision, mYPrecision, downTime);
-        getListener()->notifyMotion(&args);
-
-        // Send hover move after UP to tell the application that the mouse is hovering now.
-        if (motionEventAction == AMOTION_EVENT_ACTION_UP
-                && mPointerController != NULL) {
-            NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
-                    AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
-                    metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-                    displayId, 1, &pointerProperties, &pointerCoords,
-                    mXPrecision, mYPrecision, downTime);
-            getListener()->notifyMotion(&hoverArgs);
-        }
-
-        // Send scroll events.
-        if (scrolled) {
-            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
-            pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
-
-            NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
-                    AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
-                    AMOTION_EVENT_EDGE_FLAG_NONE,
-                    displayId, 1, &pointerProperties, &pointerCoords,
-                    mXPrecision, mYPrecision, downTime);
-            getListener()->notifyMotion(&scrollArgs);
-        }
-    }
-
-    // Synthesize key up from buttons if needed.
-    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
-            policyFlags, lastButtonState, currentButtonState);
-
-    mCursorMotionAccumulator.finishSync();
-    mCursorScrollAccumulator.finishSync();
-}
-
-int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
-        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
-    } else {
-        return AKEY_STATE_UNKNOWN;
-    }
-}
-
-void CursorInputMapper::fadePointer() {
-    if (mPointerController != NULL) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-    }
-}
-
-
-// --- TouchInputMapper ---
-
-TouchInputMapper::TouchInputMapper(InputDevice* device) :
-        InputMapper(device),
-        mSource(0), mDeviceMode(DEVICE_MODE_DISABLED),
-        mSurfaceWidth(-1), mSurfaceHeight(-1), mSurfaceLeft(0), mSurfaceTop(0),
-        mSurfaceOrientation(DISPLAY_ORIENTATION_0) {
-}
-
-TouchInputMapper::~TouchInputMapper() {
-}
-
-uint32_t TouchInputMapper::getSources() {
-    return mSource;
-}
-
-void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    if (mDeviceMode != DEVICE_MODE_DISABLED) {
-        info->addMotionRange(mOrientedRanges.x);
-        info->addMotionRange(mOrientedRanges.y);
-        info->addMotionRange(mOrientedRanges.pressure);
-
-        if (mOrientedRanges.haveSize) {
-            info->addMotionRange(mOrientedRanges.size);
-        }
-
-        if (mOrientedRanges.haveTouchSize) {
-            info->addMotionRange(mOrientedRanges.touchMajor);
-            info->addMotionRange(mOrientedRanges.touchMinor);
-        }
-
-        if (mOrientedRanges.haveToolSize) {
-            info->addMotionRange(mOrientedRanges.toolMajor);
-            info->addMotionRange(mOrientedRanges.toolMinor);
-        }
-
-        if (mOrientedRanges.haveOrientation) {
-            info->addMotionRange(mOrientedRanges.orientation);
-        }
-
-        if (mOrientedRanges.haveDistance) {
-            info->addMotionRange(mOrientedRanges.distance);
-        }
-
-        if (mOrientedRanges.haveTilt) {
-            info->addMotionRange(mOrientedRanges.tilt);
-        }
-
-        if (mCursorScrollAccumulator.haveRelativeVWheel()) {
-            info->addMotionRange(AMOTION_EVENT_AXIS_VSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
-                    0.0f);
-        }
-        if (mCursorScrollAccumulator.haveRelativeHWheel()) {
-            info->addMotionRange(AMOTION_EVENT_AXIS_HSCROLL, mSource, -1.0f, 1.0f, 0.0f, 0.0f,
-                    0.0f);
-        }
-        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
-            const InputDeviceInfo::MotionRange& x = mOrientedRanges.x;
-            const InputDeviceInfo::MotionRange& y = mOrientedRanges.y;
-            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_1, mSource, x.min, x.max, x.flat,
-                    x.fuzz, x.resolution);
-            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_2, mSource, y.min, y.max, y.flat,
-                    y.fuzz, y.resolution);
-            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_3, mSource, x.min, x.max, x.flat,
-                    x.fuzz, x.resolution);
-            info->addMotionRange(AMOTION_EVENT_AXIS_GENERIC_4, mSource, y.min, y.max, y.flat,
-                    y.fuzz, y.resolution);
-        }
-        info->setButtonUnderPad(mParameters.hasButtonUnderPad);
-    }
-}
-
-void TouchInputMapper::dump(String8& dump) {
-    dump.append(INDENT2 "Touch Input Mapper:\n");
-    dumpParameters(dump);
-    dumpVirtualKeys(dump);
-    dumpRawPointerAxes(dump);
-    dumpCalibration(dump);
-    dumpSurface(dump);
-
-    dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
-    dump.appendFormat(INDENT4 "XTranslate: %0.3f\n", mXTranslate);
-    dump.appendFormat(INDENT4 "YTranslate: %0.3f\n", mYTranslate);
-    dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
-    dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
-    dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
-    dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
-    dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
-    dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
-    dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
-    dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
-    dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
-    dump.appendFormat(INDENT4 "HaveTilt: %s\n", toString(mHaveTilt));
-    dump.appendFormat(INDENT4 "TiltXCenter: %0.3f\n", mTiltXCenter);
-    dump.appendFormat(INDENT4 "TiltXScale: %0.3f\n", mTiltXScale);
-    dump.appendFormat(INDENT4 "TiltYCenter: %0.3f\n", mTiltYCenter);
-    dump.appendFormat(INDENT4 "TiltYScale: %0.3f\n", mTiltYScale);
-
-    dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
-
-    dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
-            mLastRawPointerData.pointerCount);
-    for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
-        const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
-        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
-                "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
-                "orientation=%d, tiltX=%d, tiltY=%d, distance=%d, "
-                "toolType=%d, isHovering=%s\n", i,
-                pointer.id, pointer.x, pointer.y, pointer.pressure,
-                pointer.touchMajor, pointer.touchMinor,
-                pointer.toolMajor, pointer.toolMinor,
-                pointer.orientation, pointer.tiltX, pointer.tiltY, pointer.distance,
-                pointer.toolType, toString(pointer.isHovering));
-    }
-
-    dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
-            mLastCookedPointerData.pointerCount);
-    for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
-        const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
-        const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
-        dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
-                "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
-                "orientation=%0.3f, tilt=%0.3f, distance=%0.3f, "
-                "toolType=%d, isHovering=%s\n", i,
-                pointerProperties.id,
-                pointerCoords.getX(),
-                pointerCoords.getY(),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TILT),
-                pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
-                pointerProperties.toolType,
-                toString(mLastCookedPointerData.isHovering(i)));
-    }
-
-    if (mDeviceMode == DEVICE_MODE_POINTER) {
-        dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
-        dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
-                mPointerXMovementScale);
-        dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
-                mPointerYMovementScale);
-        dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
-                mPointerXZoomScale);
-        dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
-                mPointerYZoomScale);
-        dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
-                mPointerGestureMaxSwipeWidth);
-    }
-}
-
-void TouchInputMapper::configure(nsecs_t when,
-        const InputReaderConfiguration* config, uint32_t changes) {
-    InputMapper::configure(when, config, changes);
-
-    mConfig = *config;
-
-    if (!changes) { // first time only
-        // Configure basic parameters.
-        configureParameters();
-
-        // Configure common accumulators.
-        mCursorScrollAccumulator.configure(getDevice());
-        mTouchButtonAccumulator.configure(getDevice());
-
-        // Configure absolute axis information.
-        configureRawPointerAxes();
-
-        // Prepare input device calibration.
-        parseCalibration();
-        resolveCalibration();
-    }
-
-    if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
-        // Update pointer speed.
-        mPointerVelocityControl.setParameters(mConfig.pointerVelocityControlParameters);
-        mWheelXVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
-        mWheelYVelocityControl.setParameters(mConfig.wheelVelocityControlParameters);
-    }
-
-    bool resetNeeded = false;
-    if (!changes || (changes & (InputReaderConfiguration::CHANGE_DISPLAY_INFO
-            | InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT
-            | InputReaderConfiguration::CHANGE_SHOW_TOUCHES))) {
-        // Configure device sources, surface dimensions, orientation and
-        // scaling factors.
-        configureSurface(when, &resetNeeded);
-    }
-
-    if (changes && resetNeeded) {
-        // Send reset, unless this is the first time the device has been configured,
-        // in which case the reader will call reset itself after all mappers are ready.
-        getDevice()->notifyReset(when);
-    }
-}
-
-void TouchInputMapper::configureParameters() {
-    // Use the pointer presentation mode for devices that do not support distinct
-    // multitouch.  The spot-based presentation relies on being able to accurately
-    // locate two or more fingers on the touch pad.
-    mParameters.gestureMode = getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_SEMI_MT)
-            ? Parameters::GESTURE_MODE_POINTER : Parameters::GESTURE_MODE_SPOTS;
-
-    String8 gestureModeString;
-    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"),
-            gestureModeString)) {
-        if (gestureModeString == "pointer") {
-            mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER;
-        } else if (gestureModeString == "spots") {
-            mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS;
-        } else if (gestureModeString != "default") {
-            ALOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string());
-        }
-    }
-
-    if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_DIRECT)) {
-        // The device is a touch screen.
-        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
-    } else if (getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_POINTER)) {
-        // The device is a pointing device like a track pad.
-        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
-    } else if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X)
-            || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) {
-        // The device is a cursor device with a touch pad attached.
-        // By default don't use the touch pad to move the pointer.
-        mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
-    } else {
-        // The device is a touch pad of unknown purpose.
-        mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
-    }
-
-    mParameters.hasButtonUnderPad=
-            getEventHub()->hasInputProperty(getDeviceId(), INPUT_PROP_BUTTONPAD);
-
-    String8 deviceTypeString;
-    if (getDevice()->getConfiguration().tryGetProperty(String8("touch.deviceType"),
-            deviceTypeString)) {
-        if (deviceTypeString == "touchScreen") {
-            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
-        } else if (deviceTypeString == "touchPad") {
-            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD;
-        } else if (deviceTypeString == "touchNavigation") {
-            mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_NAVIGATION;
-        } else if (deviceTypeString == "pointer") {
-            mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER;
-        } else if (deviceTypeString != "default") {
-            ALOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string());
-        }
-    }
-
-    mParameters.orientationAware = mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN;
-    getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
-            mParameters.orientationAware);
-
-    mParameters.hasAssociatedDisplay = false;
-    mParameters.associatedDisplayIsExternal = false;
-    if (mParameters.orientationAware
-            || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
-            || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
-        mParameters.hasAssociatedDisplay = true;
-        mParameters.associatedDisplayIsExternal =
-                mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
-                        && getDevice()->isExternal();
-    }
-
-    // Initial downs on external touch devices should wake the device.
-    // Normally we don't do this for internal touch screens to prevent them from waking
-    // up in your pocket but you can enable it using the input device configuration.
-    mParameters.wake = getDevice()->isExternal();
-    getDevice()->getConfiguration().tryGetProperty(String8("touch.wake"),
-            mParameters.wake);
-}
-
-void TouchInputMapper::dumpParameters(String8& dump) {
-    dump.append(INDENT3 "Parameters:\n");
-
-    switch (mParameters.gestureMode) {
-    case Parameters::GESTURE_MODE_POINTER:
-        dump.append(INDENT4 "GestureMode: pointer\n");
-        break;
-    case Parameters::GESTURE_MODE_SPOTS:
-        dump.append(INDENT4 "GestureMode: spots\n");
-        break;
-    default:
-        assert(false);
-    }
-
-    switch (mParameters.deviceType) {
-    case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
-        dump.append(INDENT4 "DeviceType: touchScreen\n");
-        break;
-    case Parameters::DEVICE_TYPE_TOUCH_PAD:
-        dump.append(INDENT4 "DeviceType: touchPad\n");
-        break;
-    case Parameters::DEVICE_TYPE_TOUCH_NAVIGATION:
-        dump.append(INDENT4 "DeviceType: touchNavigation\n");
-        break;
-    case Parameters::DEVICE_TYPE_POINTER:
-        dump.append(INDENT4 "DeviceType: pointer\n");
-        break;
-    default:
-        ALOG_ASSERT(false);
-    }
-
-    dump.appendFormat(INDENT4 "AssociatedDisplay: hasAssociatedDisplay=%s, isExternal=%s\n",
-            toString(mParameters.hasAssociatedDisplay),
-            toString(mParameters.associatedDisplayIsExternal));
-    dump.appendFormat(INDENT4 "OrientationAware: %s\n",
-            toString(mParameters.orientationAware));
-}
-
-void TouchInputMapper::configureRawPointerAxes() {
-    mRawPointerAxes.clear();
-}
-
-void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
-    dump.append(INDENT3 "Raw Touch Axes:\n");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltX, "TiltX");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.tiltY, "TiltY");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
-    dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
-}
-
-void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) {
-    int32_t oldDeviceMode = mDeviceMode;
-
-    // Determine device mode.
-    if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER
-            && mConfig.pointerGesturesEnabled) {
-        mSource = AINPUT_SOURCE_MOUSE;
-        mDeviceMode = DEVICE_MODE_POINTER;
-        if (hasStylus()) {
-            mSource |= AINPUT_SOURCE_STYLUS;
-        }
-    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
-            && mParameters.hasAssociatedDisplay) {
-        mSource = AINPUT_SOURCE_TOUCHSCREEN;
-        mDeviceMode = DEVICE_MODE_DIRECT;
-        if (hasStylus()) {
-            mSource |= AINPUT_SOURCE_STYLUS;
-        }
-    } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_NAVIGATION) {
-        mSource = AINPUT_SOURCE_TOUCH_NAVIGATION;
-        mDeviceMode = DEVICE_MODE_NAVIGATION;
-    } else {
-        mSource = AINPUT_SOURCE_TOUCHPAD;
-        mDeviceMode = DEVICE_MODE_UNSCALED;
-    }
-
-    // Ensure we have valid X and Y axes.
-    if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
-        ALOGW(INDENT "Touch device '%s' did not report support for X or Y axis!  "
-                "The device will be inoperable.", getDeviceName().string());
-        mDeviceMode = DEVICE_MODE_DISABLED;
-        return;
-    }
-
-    // Raw width and height in the natural orientation.
-    int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
-    int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
-
-    // Get associated display dimensions.
-    DisplayViewport newViewport;
-    if (mParameters.hasAssociatedDisplay) {
-        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal, &newViewport)) {
-            ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
-                    "display.  The device will be inoperable until the display size "
-                    "becomes available.",
-                    getDeviceName().string());
-            mDeviceMode = DEVICE_MODE_DISABLED;
-            return;
-        }
-    } else {
-        newViewport.setNonDisplayViewport(rawWidth, rawHeight);
-    }
-    bool viewportChanged = mViewport != newViewport;
-    if (viewportChanged) {
-        mViewport = newViewport;
-
-        if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
-            // Convert rotated viewport to natural surface coordinates.
-            int32_t naturalLogicalWidth, naturalLogicalHeight;
-            int32_t naturalPhysicalWidth, naturalPhysicalHeight;
-            int32_t naturalPhysicalLeft, naturalPhysicalTop;
-            int32_t naturalDeviceWidth, naturalDeviceHeight;
-            switch (mViewport.orientation) {
-            case DISPLAY_ORIENTATION_90:
-                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
-                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
-                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
-                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
-                naturalPhysicalLeft = mViewport.deviceHeight - mViewport.physicalBottom;
-                naturalPhysicalTop = mViewport.physicalLeft;
-                naturalDeviceWidth = mViewport.deviceHeight;
-                naturalDeviceHeight = mViewport.deviceWidth;
-                break;
-            case DISPLAY_ORIENTATION_180:
-                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
-                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
-                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
-                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
-                naturalPhysicalLeft = mViewport.deviceWidth - mViewport.physicalRight;
-                naturalPhysicalTop = mViewport.deviceHeight - mViewport.physicalBottom;
-                naturalDeviceWidth = mViewport.deviceWidth;
-                naturalDeviceHeight = mViewport.deviceHeight;
-                break;
-            case DISPLAY_ORIENTATION_270:
-                naturalLogicalWidth = mViewport.logicalBottom - mViewport.logicalTop;
-                naturalLogicalHeight = mViewport.logicalRight - mViewport.logicalLeft;
-                naturalPhysicalWidth = mViewport.physicalBottom - mViewport.physicalTop;
-                naturalPhysicalHeight = mViewport.physicalRight - mViewport.physicalLeft;
-                naturalPhysicalLeft = mViewport.physicalTop;
-                naturalPhysicalTop = mViewport.deviceWidth - mViewport.physicalRight;
-                naturalDeviceWidth = mViewport.deviceHeight;
-                naturalDeviceHeight = mViewport.deviceWidth;
-                break;
-            case DISPLAY_ORIENTATION_0:
-            default:
-                naturalLogicalWidth = mViewport.logicalRight - mViewport.logicalLeft;
-                naturalLogicalHeight = mViewport.logicalBottom - mViewport.logicalTop;
-                naturalPhysicalWidth = mViewport.physicalRight - mViewport.physicalLeft;
-                naturalPhysicalHeight = mViewport.physicalBottom - mViewport.physicalTop;
-                naturalPhysicalLeft = mViewport.physicalLeft;
-                naturalPhysicalTop = mViewport.physicalTop;
-                naturalDeviceWidth = mViewport.deviceWidth;
-                naturalDeviceHeight = mViewport.deviceHeight;
-                break;
-            }
-
-            mSurfaceWidth = naturalLogicalWidth * naturalDeviceWidth / naturalPhysicalWidth;
-            mSurfaceHeight = naturalLogicalHeight * naturalDeviceHeight / naturalPhysicalHeight;
-            mSurfaceLeft = naturalPhysicalLeft * naturalLogicalWidth / naturalPhysicalWidth;
-            mSurfaceTop = naturalPhysicalTop * naturalLogicalHeight / naturalPhysicalHeight;
-
-            mSurfaceOrientation = mParameters.orientationAware ?
-                    mViewport.orientation : DISPLAY_ORIENTATION_0;
-        } else {
-            mSurfaceWidth = rawWidth;
-            mSurfaceHeight = rawHeight;
-            mSurfaceLeft = 0;
-            mSurfaceTop = 0;
-            mSurfaceOrientation = DISPLAY_ORIENTATION_0;
-        }
-    }
-
-    // If moving between pointer modes, need to reset some state.
-    bool deviceModeChanged = mDeviceMode != oldDeviceMode;
-    if (deviceModeChanged) {
-        mOrientedRanges.clear();
-    }
-
-    // Create pointer controller if needed.
-    if (mDeviceMode == DEVICE_MODE_POINTER ||
-            (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
-        if (mPointerController == NULL) {
-            mPointerController = getPolicy()->obtainPointerController(getDeviceId());
-        }
-    } else {
-        mPointerController.clear();
-    }
-
-    if (viewportChanged || deviceModeChanged) {
-        ALOGI("Device reconfigured: id=%d, name='%s', size %dx%d, orientation %d, mode %d, "
-                "display id %d",
-                getDeviceId(), getDeviceName().string(), mSurfaceWidth, mSurfaceHeight,
-                mSurfaceOrientation, mDeviceMode, mViewport.displayId);
-
-        // Configure X and Y factors.
-        mXScale = float(mSurfaceWidth) / rawWidth;
-        mYScale = float(mSurfaceHeight) / rawHeight;
-        mXTranslate = -mSurfaceLeft;
-        mYTranslate = -mSurfaceTop;
-        mXPrecision = 1.0f / mXScale;
-        mYPrecision = 1.0f / mYScale;
-
-        mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
-        mOrientedRanges.x.source = mSource;
-        mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
-        mOrientedRanges.y.source = mSource;
-
-        configureVirtualKeys();
-
-        // Scale factor for terms that are not oriented in a particular axis.
-        // If the pixels are square then xScale == yScale otherwise we fake it
-        // by choosing an average.
-        mGeometricScale = avg(mXScale, mYScale);
-
-        // Size of diagonal axis.
-        float diagonalSize = hypotf(mSurfaceWidth, mSurfaceHeight);
-
-        // Size factors.
-        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
-            if (mRawPointerAxes.touchMajor.valid
-                    && mRawPointerAxes.touchMajor.maxValue != 0) {
-                mSizeScale = 1.0f / mRawPointerAxes.touchMajor.maxValue;
-            } else if (mRawPointerAxes.toolMajor.valid
-                    && mRawPointerAxes.toolMajor.maxValue != 0) {
-                mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
-            } else {
-                mSizeScale = 0.0f;
-            }
-
-            mOrientedRanges.haveTouchSize = true;
-            mOrientedRanges.haveToolSize = true;
-            mOrientedRanges.haveSize = true;
-
-            mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
-            mOrientedRanges.touchMajor.source = mSource;
-            mOrientedRanges.touchMajor.min = 0;
-            mOrientedRanges.touchMajor.max = diagonalSize;
-            mOrientedRanges.touchMajor.flat = 0;
-            mOrientedRanges.touchMajor.fuzz = 0;
-            mOrientedRanges.touchMajor.resolution = 0;
-
-            mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
-            mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
-
-            mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
-            mOrientedRanges.toolMajor.source = mSource;
-            mOrientedRanges.toolMajor.min = 0;
-            mOrientedRanges.toolMajor.max = diagonalSize;
-            mOrientedRanges.toolMajor.flat = 0;
-            mOrientedRanges.toolMajor.fuzz = 0;
-            mOrientedRanges.toolMajor.resolution = 0;
-
-            mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
-            mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
-
-            mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
-            mOrientedRanges.size.source = mSource;
-            mOrientedRanges.size.min = 0;
-            mOrientedRanges.size.max = 1.0;
-            mOrientedRanges.size.flat = 0;
-            mOrientedRanges.size.fuzz = 0;
-            mOrientedRanges.size.resolution = 0;
-        } else {
-            mSizeScale = 0.0f;
-        }
-
-        // Pressure factors.
-        mPressureScale = 0;
-        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
-                || mCalibration.pressureCalibration
-                        == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
-            if (mCalibration.havePressureScale) {
-                mPressureScale = mCalibration.pressureScale;
-            } else if (mRawPointerAxes.pressure.valid
-                    && mRawPointerAxes.pressure.maxValue != 0) {
-                mPressureScale = 1.0f / mRawPointerAxes.pressure.maxValue;
-            }
-        }
-
-        mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
-        mOrientedRanges.pressure.source = mSource;
-        mOrientedRanges.pressure.min = 0;
-        mOrientedRanges.pressure.max = 1.0;
-        mOrientedRanges.pressure.flat = 0;
-        mOrientedRanges.pressure.fuzz = 0;
-        mOrientedRanges.pressure.resolution = 0;
-
-        // Tilt
-        mTiltXCenter = 0;
-        mTiltXScale = 0;
-        mTiltYCenter = 0;
-        mTiltYScale = 0;
-        mHaveTilt = mRawPointerAxes.tiltX.valid && mRawPointerAxes.tiltY.valid;
-        if (mHaveTilt) {
-            mTiltXCenter = avg(mRawPointerAxes.tiltX.minValue,
-                    mRawPointerAxes.tiltX.maxValue);
-            mTiltYCenter = avg(mRawPointerAxes.tiltY.minValue,
-                    mRawPointerAxes.tiltY.maxValue);
-            mTiltXScale = M_PI / 180;
-            mTiltYScale = M_PI / 180;
-
-            mOrientedRanges.haveTilt = true;
-
-            mOrientedRanges.tilt.axis = AMOTION_EVENT_AXIS_TILT;
-            mOrientedRanges.tilt.source = mSource;
-            mOrientedRanges.tilt.min = 0;
-            mOrientedRanges.tilt.max = M_PI_2;
-            mOrientedRanges.tilt.flat = 0;
-            mOrientedRanges.tilt.fuzz = 0;
-            mOrientedRanges.tilt.resolution = 0;
-        }
-
-        // Orientation
-        mOrientationScale = 0;
-        if (mHaveTilt) {
-            mOrientedRanges.haveOrientation = true;
-
-            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
-            mOrientedRanges.orientation.source = mSource;
-            mOrientedRanges.orientation.min = -M_PI;
-            mOrientedRanges.orientation.max = M_PI;
-            mOrientedRanges.orientation.flat = 0;
-            mOrientedRanges.orientation.fuzz = 0;
-            mOrientedRanges.orientation.resolution = 0;
-        } else if (mCalibration.orientationCalibration !=
-                Calibration::ORIENTATION_CALIBRATION_NONE) {
-            if (mCalibration.orientationCalibration
-                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
-                if (mRawPointerAxes.orientation.valid) {
-                    if (mRawPointerAxes.orientation.maxValue > 0) {
-                        mOrientationScale = M_PI_2 / mRawPointerAxes.orientation.maxValue;
-                    } else if (mRawPointerAxes.orientation.minValue < 0) {
-                        mOrientationScale = -M_PI_2 / mRawPointerAxes.orientation.minValue;
-                    } else {
-                        mOrientationScale = 0;
-                    }
-                }
-            }
-
-            mOrientedRanges.haveOrientation = true;
-
-            mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
-            mOrientedRanges.orientation.source = mSource;
-            mOrientedRanges.orientation.min = -M_PI_2;
-            mOrientedRanges.orientation.max = M_PI_2;
-            mOrientedRanges.orientation.flat = 0;
-            mOrientedRanges.orientation.fuzz = 0;
-            mOrientedRanges.orientation.resolution = 0;
-        }
-
-        // Distance
-        mDistanceScale = 0;
-        if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
-            if (mCalibration.distanceCalibration
-                    == Calibration::DISTANCE_CALIBRATION_SCALED) {
-                if (mCalibration.haveDistanceScale) {
-                    mDistanceScale = mCalibration.distanceScale;
-                } else {
-                    mDistanceScale = 1.0f;
-                }
-            }
-
-            mOrientedRanges.haveDistance = true;
-
-            mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
-            mOrientedRanges.distance.source = mSource;
-            mOrientedRanges.distance.min =
-                    mRawPointerAxes.distance.minValue * mDistanceScale;
-            mOrientedRanges.distance.max =
-                    mRawPointerAxes.distance.maxValue * mDistanceScale;
-            mOrientedRanges.distance.flat = 0;
-            mOrientedRanges.distance.fuzz =
-                    mRawPointerAxes.distance.fuzz * mDistanceScale;
-            mOrientedRanges.distance.resolution = 0;
-        }
-
-        // Compute oriented precision, scales and ranges.
-        // Note that the maximum value reported is an inclusive maximum value so it is one
-        // unit less than the total width or height of surface.
-        switch (mSurfaceOrientation) {
-        case DISPLAY_ORIENTATION_90:
-        case DISPLAY_ORIENTATION_270:
-            mOrientedXPrecision = mYPrecision;
-            mOrientedYPrecision = mXPrecision;
-
-            mOrientedRanges.x.min = mYTranslate;
-            mOrientedRanges.x.max = mSurfaceHeight + mYTranslate - 1;
-            mOrientedRanges.x.flat = 0;
-            mOrientedRanges.x.fuzz = 0;
-            mOrientedRanges.x.resolution = mRawPointerAxes.y.resolution * mYScale;
-
-            mOrientedRanges.y.min = mXTranslate;
-            mOrientedRanges.y.max = mSurfaceWidth + mXTranslate - 1;
-            mOrientedRanges.y.flat = 0;
-            mOrientedRanges.y.fuzz = 0;
-            mOrientedRanges.y.resolution = mRawPointerAxes.x.resolution * mXScale;
-            break;
-
-        default:
-            mOrientedXPrecision = mXPrecision;
-            mOrientedYPrecision = mYPrecision;
-
-            mOrientedRanges.x.min = mXTranslate;
-            mOrientedRanges.x.max = mSurfaceWidth + mXTranslate - 1;
-            mOrientedRanges.x.flat = 0;
-            mOrientedRanges.x.fuzz = 0;
-            mOrientedRanges.x.resolution = mRawPointerAxes.x.resolution * mXScale;
-
-            mOrientedRanges.y.min = mYTranslate;
-            mOrientedRanges.y.max = mSurfaceHeight + mYTranslate - 1;
-            mOrientedRanges.y.flat = 0;
-            mOrientedRanges.y.fuzz = 0;
-            mOrientedRanges.y.resolution = mRawPointerAxes.y.resolution * mYScale;
-            break;
-        }
-
-        if (mDeviceMode == DEVICE_MODE_POINTER) {
-            // Compute pointer gesture detection parameters.
-            float rawDiagonal = hypotf(rawWidth, rawHeight);
-            float displayDiagonal = hypotf(mSurfaceWidth, mSurfaceHeight);
-
-            // Scale movements such that one whole swipe of the touch pad covers a
-            // given area relative to the diagonal size of the display when no acceleration
-            // is applied.
-            // Assume that the touch pad has a square aspect ratio such that movements in
-            // X and Y of the same number of raw units cover the same physical distance.
-            mPointerXMovementScale = mConfig.pointerGestureMovementSpeedRatio
-                    * displayDiagonal / rawDiagonal;
-            mPointerYMovementScale = mPointerXMovementScale;
-
-            // Scale zooms to cover a smaller range of the display than movements do.
-            // This value determines the area around the pointer that is affected by freeform
-            // pointer gestures.
-            mPointerXZoomScale = mConfig.pointerGestureZoomSpeedRatio
-                    * displayDiagonal / rawDiagonal;
-            mPointerYZoomScale = mPointerXZoomScale;
-
-            // Max width between pointers to detect a swipe gesture is more than some fraction
-            // of the diagonal axis of the touch pad.  Touches that are wider than this are
-            // translated into freeform gestures.
-            mPointerGestureMaxSwipeWidth =
-                    mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
-
-            // Abort current pointer usages because the state has changed.
-            abortPointerUsage(when, 0 /*policyFlags*/);
-        }
-
-        // Inform the dispatcher about the changes.
-        *outResetNeeded = true;
-        bumpGeneration();
-    }
-}
-
-void TouchInputMapper::dumpSurface(String8& dump) {
-    dump.appendFormat(INDENT3 "Viewport: displayId=%d, orientation=%d, "
-            "logicalFrame=[%d, %d, %d, %d], "
-            "physicalFrame=[%d, %d, %d, %d], "
-            "deviceSize=[%d, %d]\n",
-            mViewport.displayId, mViewport.orientation,
-            mViewport.logicalLeft, mViewport.logicalTop,
-            mViewport.logicalRight, mViewport.logicalBottom,
-            mViewport.physicalLeft, mViewport.physicalTop,
-            mViewport.physicalRight, mViewport.physicalBottom,
-            mViewport.deviceWidth, mViewport.deviceHeight);
-
-    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
-    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
-    dump.appendFormat(INDENT3 "SurfaceLeft: %d\n", mSurfaceLeft);
-    dump.appendFormat(INDENT3 "SurfaceTop: %d\n", mSurfaceTop);
-    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
-}
-
-void TouchInputMapper::configureVirtualKeys() {
-    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
-    getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
-
-    mVirtualKeys.clear();
-
-    if (virtualKeyDefinitions.size() == 0) {
-        return;
-    }
-
-    mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
-
-    int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
-    int32_t touchScreenTop = mRawPointerAxes.y.minValue;
-    int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
-    int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
-
-    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
-        const VirtualKeyDefinition& virtualKeyDefinition =
-                virtualKeyDefinitions[i];
-
-        mVirtualKeys.add();
-        VirtualKey& virtualKey = mVirtualKeys.editTop();
-
-        virtualKey.scanCode = virtualKeyDefinition.scanCode;
-        int32_t keyCode;
-        uint32_t flags;
-        if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) {
-            ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
-                    virtualKey.scanCode);
-            mVirtualKeys.pop(); // drop the key
-            continue;
-        }
-
-        virtualKey.keyCode = keyCode;
-        virtualKey.flags = flags;
-
-        // convert the key definition's display coordinates into touch coordinates for a hit box
-        int32_t halfWidth = virtualKeyDefinition.width / 2;
-        int32_t halfHeight = virtualKeyDefinition.height / 2;
-
-        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
-                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
-        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
-                * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
-        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
-                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
-        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
-                * touchScreenHeight / mSurfaceHeight + touchScreenTop;
-    }
-}
-
-void TouchInputMapper::dumpVirtualKeys(String8& dump) {
-    if (!mVirtualKeys.isEmpty()) {
-        dump.append(INDENT3 "Virtual Keys:\n");
-
-        for (size_t i = 0; i < mVirtualKeys.size(); i++) {
-            const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
-            dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
-                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
-                    i, virtualKey.scanCode, virtualKey.keyCode,
-                    virtualKey.hitLeft, virtualKey.hitRight,
-                    virtualKey.hitTop, virtualKey.hitBottom);
-        }
-    }
-}
-
-void TouchInputMapper::parseCalibration() {
-    const PropertyMap& in = getDevice()->getConfiguration();
-    Calibration& out = mCalibration;
-
-    // Size
-    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
-    String8 sizeCalibrationString;
-    if (in.tryGetProperty(String8("touch.size.calibration"), sizeCalibrationString)) {
-        if (sizeCalibrationString == "none") {
-            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
-        } else if (sizeCalibrationString == "geometric") {
-            out.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
-        } else if (sizeCalibrationString == "diameter") {
-            out.sizeCalibration = Calibration::SIZE_CALIBRATION_DIAMETER;
-        } else if (sizeCalibrationString == "box") {
-            out.sizeCalibration = Calibration::SIZE_CALIBRATION_BOX;
-        } else if (sizeCalibrationString == "area") {
-            out.sizeCalibration = Calibration::SIZE_CALIBRATION_AREA;
-        } else if (sizeCalibrationString != "default") {
-            ALOGW("Invalid value for touch.size.calibration: '%s'",
-                    sizeCalibrationString.string());
-        }
-    }
-
-    out.haveSizeScale = in.tryGetProperty(String8("touch.size.scale"),
-            out.sizeScale);
-    out.haveSizeBias = in.tryGetProperty(String8("touch.size.bias"),
-            out.sizeBias);
-    out.haveSizeIsSummed = in.tryGetProperty(String8("touch.size.isSummed"),
-            out.sizeIsSummed);
-
-    // Pressure
-    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
-    String8 pressureCalibrationString;
-    if (in.tryGetProperty(String8("touch.pressure.calibration"), pressureCalibrationString)) {
-        if (pressureCalibrationString == "none") {
-            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
-        } else if (pressureCalibrationString == "physical") {
-            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
-        } else if (pressureCalibrationString == "amplitude") {
-            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
-        } else if (pressureCalibrationString != "default") {
-            ALOGW("Invalid value for touch.pressure.calibration: '%s'",
-                    pressureCalibrationString.string());
-        }
-    }
-
-    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
-            out.pressureScale);
-
-    // Orientation
-    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
-    String8 orientationCalibrationString;
-    if (in.tryGetProperty(String8("touch.orientation.calibration"), orientationCalibrationString)) {
-        if (orientationCalibrationString == "none") {
-            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
-        } else if (orientationCalibrationString == "interpolated") {
-            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
-        } else if (orientationCalibrationString == "vector") {
-            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_VECTOR;
-        } else if (orientationCalibrationString != "default") {
-            ALOGW("Invalid value for touch.orientation.calibration: '%s'",
-                    orientationCalibrationString.string());
-        }
-    }
-
-    // Distance
-    out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_DEFAULT;
-    String8 distanceCalibrationString;
-    if (in.tryGetProperty(String8("touch.distance.calibration"), distanceCalibrationString)) {
-        if (distanceCalibrationString == "none") {
-            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
-        } else if (distanceCalibrationString == "scaled") {
-            out.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
-        } else if (distanceCalibrationString != "default") {
-            ALOGW("Invalid value for touch.distance.calibration: '%s'",
-                    distanceCalibrationString.string());
-        }
-    }
-
-    out.haveDistanceScale = in.tryGetProperty(String8("touch.distance.scale"),
-            out.distanceScale);
-
-    out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_DEFAULT;
-    String8 coverageCalibrationString;
-    if (in.tryGetProperty(String8("touch.coverage.calibration"), coverageCalibrationString)) {
-        if (coverageCalibrationString == "none") {
-            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
-        } else if (coverageCalibrationString == "box") {
-            out.coverageCalibration = Calibration::COVERAGE_CALIBRATION_BOX;
-        } else if (coverageCalibrationString != "default") {
-            ALOGW("Invalid value for touch.coverage.calibration: '%s'",
-                    coverageCalibrationString.string());
-        }
-    }
-}
-
-void TouchInputMapper::resolveCalibration() {
-    // Size
-    if (mRawPointerAxes.touchMajor.valid || mRawPointerAxes.toolMajor.valid) {
-        if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DEFAULT) {
-            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_GEOMETRIC;
-        }
-    } else {
-        mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
-    }
-
-    // Pressure
-    if (mRawPointerAxes.pressure.valid) {
-        if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_DEFAULT) {
-            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
-        }
-    } else {
-        mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
-    }
-
-    // Orientation
-    if (mRawPointerAxes.orientation.valid) {
-        if (mCalibration.orientationCalibration == Calibration::ORIENTATION_CALIBRATION_DEFAULT) {
-            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
-        }
-    } else {
-        mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
-    }
-
-    // Distance
-    if (mRawPointerAxes.distance.valid) {
-        if (mCalibration.distanceCalibration == Calibration::DISTANCE_CALIBRATION_DEFAULT) {
-            mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
-        }
-    } else {
-        mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
-    }
-
-    // Coverage
-    if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_DEFAULT) {
-        mCalibration.coverageCalibration = Calibration::COVERAGE_CALIBRATION_NONE;
-    }
-}
-
-void TouchInputMapper::dumpCalibration(String8& dump) {
-    dump.append(INDENT3 "Calibration:\n");
-
-    // Size
-    switch (mCalibration.sizeCalibration) {
-    case Calibration::SIZE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.size.calibration: none\n");
-        break;
-    case Calibration::SIZE_CALIBRATION_GEOMETRIC:
-        dump.append(INDENT4 "touch.size.calibration: geometric\n");
-        break;
-    case Calibration::SIZE_CALIBRATION_DIAMETER:
-        dump.append(INDENT4 "touch.size.calibration: diameter\n");
-        break;
-    case Calibration::SIZE_CALIBRATION_BOX:
-        dump.append(INDENT4 "touch.size.calibration: box\n");
-        break;
-    case Calibration::SIZE_CALIBRATION_AREA:
-        dump.append(INDENT4 "touch.size.calibration: area\n");
-        break;
-    default:
-        ALOG_ASSERT(false);
-    }
-
-    if (mCalibration.haveSizeScale) {
-        dump.appendFormat(INDENT4 "touch.size.scale: %0.3f\n",
-                mCalibration.sizeScale);
-    }
-
-    if (mCalibration.haveSizeBias) {
-        dump.appendFormat(INDENT4 "touch.size.bias: %0.3f\n",
-                mCalibration.sizeBias);
-    }
-
-    if (mCalibration.haveSizeIsSummed) {
-        dump.appendFormat(INDENT4 "touch.size.isSummed: %s\n",
-                toString(mCalibration.sizeIsSummed));
-    }
-
-    // Pressure
-    switch (mCalibration.pressureCalibration) {
-    case Calibration::PRESSURE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.pressure.calibration: none\n");
-        break;
-    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
-        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
-        break;
-    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
-        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
-        break;
-    default:
-        ALOG_ASSERT(false);
-    }
-
-    if (mCalibration.havePressureScale) {
-        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
-                mCalibration.pressureScale);
-    }
-
-    // Orientation
-    switch (mCalibration.orientationCalibration) {
-    case Calibration::ORIENTATION_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.orientation.calibration: none\n");
-        break;
-    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
-        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
-        break;
-    case Calibration::ORIENTATION_CALIBRATION_VECTOR:
-        dump.append(INDENT4 "touch.orientation.calibration: vector\n");
-        break;
-    default:
-        ALOG_ASSERT(false);
-    }
-
-    // Distance
-    switch (mCalibration.distanceCalibration) {
-    case Calibration::DISTANCE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.distance.calibration: none\n");
-        break;
-    case Calibration::DISTANCE_CALIBRATION_SCALED:
-        dump.append(INDENT4 "touch.distance.calibration: scaled\n");
-        break;
-    default:
-        ALOG_ASSERT(false);
-    }
-
-    if (mCalibration.haveDistanceScale) {
-        dump.appendFormat(INDENT4 "touch.distance.scale: %0.3f\n",
-                mCalibration.distanceScale);
-    }
-
-    switch (mCalibration.coverageCalibration) {
-    case Calibration::COVERAGE_CALIBRATION_NONE:
-        dump.append(INDENT4 "touch.coverage.calibration: none\n");
-        break;
-    case Calibration::COVERAGE_CALIBRATION_BOX:
-        dump.append(INDENT4 "touch.coverage.calibration: box\n");
-        break;
-    default:
-        ALOG_ASSERT(false);
-    }
-}
-
-void TouchInputMapper::reset(nsecs_t when) {
-    mCursorButtonAccumulator.reset(getDevice());
-    mCursorScrollAccumulator.reset(getDevice());
-    mTouchButtonAccumulator.reset(getDevice());
-
-    mPointerVelocityControl.reset();
-    mWheelXVelocityControl.reset();
-    mWheelYVelocityControl.reset();
-
-    mCurrentRawPointerData.clear();
-    mLastRawPointerData.clear();
-    mCurrentCookedPointerData.clear();
-    mLastCookedPointerData.clear();
-    mCurrentButtonState = 0;
-    mLastButtonState = 0;
-    mCurrentRawVScroll = 0;
-    mCurrentRawHScroll = 0;
-    mCurrentFingerIdBits.clear();
-    mLastFingerIdBits.clear();
-    mCurrentStylusIdBits.clear();
-    mLastStylusIdBits.clear();
-    mCurrentMouseIdBits.clear();
-    mLastMouseIdBits.clear();
-    mPointerUsage = POINTER_USAGE_NONE;
-    mSentHoverEnter = false;
-    mDownTime = 0;
-
-    mCurrentVirtualKey.down = false;
-
-    mPointerGesture.reset();
-    mPointerSimple.reset();
-
-    if (mPointerController != NULL) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-        mPointerController->clearSpots();
-    }
-
-    InputMapper::reset(when);
-}
-
-void TouchInputMapper::process(const RawEvent* rawEvent) {
-    mCursorButtonAccumulator.process(rawEvent);
-    mCursorScrollAccumulator.process(rawEvent);
-    mTouchButtonAccumulator.process(rawEvent);
-
-    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
-        sync(rawEvent->when);
-    }
-}
-
-void TouchInputMapper::sync(nsecs_t when) {
-    // Sync button state.
-    mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
-            | mCursorButtonAccumulator.getButtonState();
-
-    // Sync scroll state.
-    mCurrentRawVScroll = mCursorScrollAccumulator.getRelativeVWheel();
-    mCurrentRawHScroll = mCursorScrollAccumulator.getRelativeHWheel();
-    mCursorScrollAccumulator.finishSync();
-
-    // Sync touch state.
-    bool havePointerIds = true;
-    mCurrentRawPointerData.clear();
-    syncTouch(when, &havePointerIds);
-
-#if DEBUG_RAW_EVENTS
-    if (!havePointerIds) {
-        ALOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
-                mLastRawPointerData.pointerCount,
-                mCurrentRawPointerData.pointerCount);
-    } else {
-        ALOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
-                "hovering ids 0x%08x -> 0x%08x",
-                mLastRawPointerData.pointerCount,
-                mCurrentRawPointerData.pointerCount,
-                mLastRawPointerData.touchingIdBits.value,
-                mCurrentRawPointerData.touchingIdBits.value,
-                mLastRawPointerData.hoveringIdBits.value,
-                mCurrentRawPointerData.hoveringIdBits.value);
-    }
-#endif
-
-    // Reset state that we will compute below.
-    mCurrentFingerIdBits.clear();
-    mCurrentStylusIdBits.clear();
-    mCurrentMouseIdBits.clear();
-    mCurrentCookedPointerData.clear();
-
-    if (mDeviceMode == DEVICE_MODE_DISABLED) {
-        // Drop all input if the device is disabled.
-        mCurrentRawPointerData.clear();
-        mCurrentButtonState = 0;
-    } else {
-        // Preprocess pointer data.
-        if (!havePointerIds) {
-            assignPointerIds();
-        }
-
-        // Handle policy on initial down or hover events.
-        uint32_t policyFlags = 0;
-        bool initialDown = mLastRawPointerData.pointerCount == 0
-                && mCurrentRawPointerData.pointerCount != 0;
-        bool buttonsPressed = mCurrentButtonState & ~mLastButtonState;
-        if (initialDown || buttonsPressed) {
-            // If this is a touch screen, hide the pointer on an initial down.
-            if (mDeviceMode == DEVICE_MODE_DIRECT) {
-                getContext()->fadePointer();
-            }
-
-            if (mParameters.wake) {
-                policyFlags |= POLICY_FLAG_WAKE_DROPPED;
-            }
-        }
-
-        // Synthesize key down from raw buttons if needed.
-        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
-                policyFlags, mLastButtonState, mCurrentButtonState);
-
-        // Consume raw off-screen touches before cooking pointer data.
-        // If touches are consumed, subsequent code will not receive any pointer data.
-        if (consumeRawTouches(when, policyFlags)) {
-            mCurrentRawPointerData.clear();
-        }
-
-        // Cook pointer data.  This call populates the mCurrentCookedPointerData structure
-        // with cooked pointer data that has the same ids and indices as the raw data.
-        // The following code can use either the raw or cooked data, as needed.
-        cookPointerData();
-
-        // Dispatch the touches either directly or by translation through a pointer on screen.
-        if (mDeviceMode == DEVICE_MODE_POINTER) {
-            for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
-                uint32_t id = idBits.clearFirstMarkedBit();
-                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
-                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
-                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
-                    mCurrentStylusIdBits.markBit(id);
-                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_FINGER
-                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
-                    mCurrentFingerIdBits.markBit(id);
-                } else if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_MOUSE) {
-                    mCurrentMouseIdBits.markBit(id);
-                }
-            }
-            for (BitSet32 idBits(mCurrentRawPointerData.hoveringIdBits); !idBits.isEmpty(); ) {
-                uint32_t id = idBits.clearFirstMarkedBit();
-                const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
-                if (pointer.toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS
-                        || pointer.toolType == AMOTION_EVENT_TOOL_TYPE_ERASER) {
-                    mCurrentStylusIdBits.markBit(id);
-                }
-            }
-
-            // Stylus takes precedence over all tools, then mouse, then finger.
-            PointerUsage pointerUsage = mPointerUsage;
-            if (!mCurrentStylusIdBits.isEmpty()) {
-                mCurrentMouseIdBits.clear();
-                mCurrentFingerIdBits.clear();
-                pointerUsage = POINTER_USAGE_STYLUS;
-            } else if (!mCurrentMouseIdBits.isEmpty()) {
-                mCurrentFingerIdBits.clear();
-                pointerUsage = POINTER_USAGE_MOUSE;
-            } else if (!mCurrentFingerIdBits.isEmpty() || isPointerDown(mCurrentButtonState)) {
-                pointerUsage = POINTER_USAGE_GESTURES;
-            }
-
-            dispatchPointerUsage(when, policyFlags, pointerUsage);
-        } else {
-            if (mDeviceMode == DEVICE_MODE_DIRECT
-                    && mConfig.showTouches && mPointerController != NULL) {
-                mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
-                mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-
-                mPointerController->setButtonState(mCurrentButtonState);
-                mPointerController->setSpots(mCurrentCookedPointerData.pointerCoords,
-                        mCurrentCookedPointerData.idToIndex,
-                        mCurrentCookedPointerData.touchingIdBits);
-            }
-
-            dispatchHoverExit(when, policyFlags);
-            dispatchTouches(when, policyFlags);
-            dispatchHoverEnterAndMove(when, policyFlags);
-        }
-
-        // Synthesize key up from raw buttons if needed.
-        synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
-                policyFlags, mLastButtonState, mCurrentButtonState);
-    }
-
-    // Copy current touch to last touch in preparation for the next cycle.
-    mLastRawPointerData.copyFrom(mCurrentRawPointerData);
-    mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
-    mLastButtonState = mCurrentButtonState;
-    mLastFingerIdBits = mCurrentFingerIdBits;
-    mLastStylusIdBits = mCurrentStylusIdBits;
-    mLastMouseIdBits = mCurrentMouseIdBits;
-
-    // Clear some transient state.
-    mCurrentRawVScroll = 0;
-    mCurrentRawHScroll = 0;
-}
-
-void TouchInputMapper::timeoutExpired(nsecs_t when) {
-    if (mDeviceMode == DEVICE_MODE_POINTER) {
-        if (mPointerUsage == POINTER_USAGE_GESTURES) {
-            dispatchPointerGestures(when, 0 /*policyFlags*/, true /*isTimeout*/);
-        }
-    }
-}
-
-bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
-    // Check for release of a virtual key.
-    if (mCurrentVirtualKey.down) {
-        if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
-            // Pointer went up while virtual key was down.
-            mCurrentVirtualKey.down = false;
-            if (!mCurrentVirtualKey.ignored) {
-#if DEBUG_VIRTUAL_KEYS
-                ALOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
-                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
-#endif
-                dispatchVirtualKey(when, policyFlags,
-                        AKEY_EVENT_ACTION_UP,
-                        AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
-            }
-            return true;
-        }
-
-        if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
-            uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
-            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
-            const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
-            if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
-                // Pointer is still within the space of the virtual key.
-                return true;
-            }
-        }
-
-        // Pointer left virtual key area or another pointer also went down.
-        // Send key cancellation but do not consume the touch yet.
-        // This is useful when the user swipes through from the virtual key area
-        // into the main display surface.
-        mCurrentVirtualKey.down = false;
-        if (!mCurrentVirtualKey.ignored) {
-#if DEBUG_VIRTUAL_KEYS
-            ALOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
-                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
-#endif
-            dispatchVirtualKey(when, policyFlags,
-                    AKEY_EVENT_ACTION_UP,
-                    AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
-                            | AKEY_EVENT_FLAG_CANCELED);
-        }
-    }
-
-    if (mLastRawPointerData.touchingIdBits.isEmpty()
-            && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
-        // Pointer just went down.  Check for virtual key press or off-screen touches.
-        uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
-        const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
-        if (!isPointInsideSurface(pointer.x, pointer.y)) {
-            // If exactly one pointer went down, check for virtual key hit.
-            // Otherwise we will drop the entire stroke.
-            if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
-                const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
-                if (virtualKey) {
-                    mCurrentVirtualKey.down = true;
-                    mCurrentVirtualKey.downTime = when;
-                    mCurrentVirtualKey.keyCode = virtualKey->keyCode;
-                    mCurrentVirtualKey.scanCode = virtualKey->scanCode;
-                    mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
-                            when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
-
-                    if (!mCurrentVirtualKey.ignored) {
-#if DEBUG_VIRTUAL_KEYS
-                        ALOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
-                                mCurrentVirtualKey.keyCode,
-                                mCurrentVirtualKey.scanCode);
-#endif
-                        dispatchVirtualKey(when, policyFlags,
-                                AKEY_EVENT_ACTION_DOWN,
-                                AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-    // Disable all virtual key touches that happen within a short time interval of the
-    // most recent touch within the screen area.  The idea is to filter out stray
-    // virtual key presses when interacting with the touch screen.
-    //
-    // Problems we're trying to solve:
-    //
-    // 1. While scrolling a list or dragging the window shade, the user swipes down into a
-    //    virtual key area that is implemented by a separate touch panel and accidentally
-    //    triggers a virtual key.
-    //
-    // 2. While typing in the on screen keyboard, the user taps slightly outside the screen
-    //    area and accidentally triggers a virtual key.  This often happens when virtual keys
-    //    are layed out below the screen near to where the on screen keyboard's space bar
-    //    is displayed.
-    if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
-        mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
-    }
-    return false;
-}
-
-void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
-        int32_t keyEventAction, int32_t keyEventFlags) {
-    int32_t keyCode = mCurrentVirtualKey.keyCode;
-    int32_t scanCode = mCurrentVirtualKey.scanCode;
-    nsecs_t downTime = mCurrentVirtualKey.downTime;
-    int32_t metaState = mContext->getGlobalMetaState();
-    policyFlags |= POLICY_FLAG_VIRTUAL;
-
-    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
-            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
-    getListener()->notifyKey(&args);
-}
-
-void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
-    BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
-    BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
-    int32_t metaState = getContext()->getGlobalMetaState();
-    int32_t buttonState = mCurrentButtonState;
-
-    if (currentIdBits == lastIdBits) {
-        if (!currentIdBits.isEmpty()) {
-            // No pointer id changes so this is a move event.
-            // The listener takes care of batching moves so we don't have to deal with that here.
-            dispatchMotion(when, policyFlags, mSource,
-                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
-                    AMOTION_EVENT_EDGE_FLAG_NONE,
-                    mCurrentCookedPointerData.pointerProperties,
-                    mCurrentCookedPointerData.pointerCoords,
-                    mCurrentCookedPointerData.idToIndex,
-                    currentIdBits, -1,
-                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
-        }
-    } else {
-        // There may be pointers going up and pointers going down and pointers moving
-        // all at the same time.
-        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
-        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
-        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
-        BitSet32 dispatchedIdBits(lastIdBits.value);
-
-        // Update last coordinates of pointers that have moved so that we observe the new
-        // pointer positions at the same time as other pointers that have just gone up.
-        bool moveNeeded = updateMovedPointers(
-                mCurrentCookedPointerData.pointerProperties,
-                mCurrentCookedPointerData.pointerCoords,
-                mCurrentCookedPointerData.idToIndex,
-                mLastCookedPointerData.pointerProperties,
-                mLastCookedPointerData.pointerCoords,
-                mLastCookedPointerData.idToIndex,
-                moveIdBits);
-        if (buttonState != mLastButtonState) {
-            moveNeeded = true;
-        }
-
-        // Dispatch pointer up events.
-        while (!upIdBits.isEmpty()) {
-            uint32_t upId = upIdBits.clearFirstMarkedBit();
-
-            dispatchMotion(when, policyFlags, mSource,
-                    AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
-                    mLastCookedPointerData.pointerProperties,
-                    mLastCookedPointerData.pointerCoords,
-                    mLastCookedPointerData.idToIndex,
-                    dispatchedIdBits, upId,
-                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
-            dispatchedIdBits.clearBit(upId);
-        }
-
-        // Dispatch move events if any of the remaining pointers moved from their old locations.
-        // Although applications receive new locations as part of individual pointer up
-        // events, they do not generally handle them except when presented in a move event.
-        if (moveNeeded) {
-            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
-            dispatchMotion(when, policyFlags, mSource,
-                    AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
-                    mCurrentCookedPointerData.pointerProperties,
-                    mCurrentCookedPointerData.pointerCoords,
-                    mCurrentCookedPointerData.idToIndex,
-                    dispatchedIdBits, -1,
-                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
-        }
-
-        // Dispatch pointer down events using the new pointer locations.
-        while (!downIdBits.isEmpty()) {
-            uint32_t downId = downIdBits.clearFirstMarkedBit();
-            dispatchedIdBits.markBit(downId);
-
-            if (dispatchedIdBits.count() == 1) {
-                // First pointer is going down.  Set down time.
-                mDownTime = when;
-            }
-
-            dispatchMotion(when, policyFlags, mSource,
-                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
-                    mCurrentCookedPointerData.pointerProperties,
-                    mCurrentCookedPointerData.pointerCoords,
-                    mCurrentCookedPointerData.idToIndex,
-                    dispatchedIdBits, downId,
-                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
-        }
-    }
-}
-
-void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
-    if (mSentHoverEnter &&
-            (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
-                    || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
-        int32_t metaState = getContext()->getGlobalMetaState();
-        dispatchMotion(when, policyFlags, mSource,
-                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
-                mLastCookedPointerData.pointerProperties,
-                mLastCookedPointerData.pointerCoords,
-                mLastCookedPointerData.idToIndex,
-                mLastCookedPointerData.hoveringIdBits, -1,
-                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
-        mSentHoverEnter = false;
-    }
-}
-
-void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
-    if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
-            && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
-        int32_t metaState = getContext()->getGlobalMetaState();
-        if (!mSentHoverEnter) {
-            dispatchMotion(when, policyFlags, mSource,
-                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
-                    mCurrentCookedPointerData.pointerProperties,
-                    mCurrentCookedPointerData.pointerCoords,
-                    mCurrentCookedPointerData.idToIndex,
-                    mCurrentCookedPointerData.hoveringIdBits, -1,
-                    mOrientedXPrecision, mOrientedYPrecision, mDownTime);
-            mSentHoverEnter = true;
-        }
-
-        dispatchMotion(when, policyFlags, mSource,
-                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
-                mCurrentCookedPointerData.pointerProperties,
-                mCurrentCookedPointerData.pointerCoords,
-                mCurrentCookedPointerData.idToIndex,
-                mCurrentCookedPointerData.hoveringIdBits, -1,
-                mOrientedXPrecision, mOrientedYPrecision, mDownTime);
-    }
-}
-
-void TouchInputMapper::cookPointerData() {
-    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
-
-    mCurrentCookedPointerData.clear();
-    mCurrentCookedPointerData.pointerCount = currentPointerCount;
-    mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
-    mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
-
-    // Walk through the the active pointers and map device coordinates onto
-    // surface coordinates and adjust for display orientation.
-    for (uint32_t i = 0; i < currentPointerCount; i++) {
-        const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
-
-        // Size
-        float touchMajor, touchMinor, toolMajor, toolMinor, size;
-        switch (mCalibration.sizeCalibration) {
-        case Calibration::SIZE_CALIBRATION_GEOMETRIC:
-        case Calibration::SIZE_CALIBRATION_DIAMETER:
-        case Calibration::SIZE_CALIBRATION_BOX:
-        case Calibration::SIZE_CALIBRATION_AREA:
-            if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
-                touchMajor = in.touchMajor;
-                touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
-                toolMajor = in.toolMajor;
-                toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
-                size = mRawPointerAxes.touchMinor.valid
-                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
-            } else if (mRawPointerAxes.touchMajor.valid) {
-                toolMajor = touchMajor = in.touchMajor;
-                toolMinor = touchMinor = mRawPointerAxes.touchMinor.valid
-                        ? in.touchMinor : in.touchMajor;
-                size = mRawPointerAxes.touchMinor.valid
-                        ? avg(in.touchMajor, in.touchMinor) : in.touchMajor;
-            } else if (mRawPointerAxes.toolMajor.valid) {
-                touchMajor = toolMajor = in.toolMajor;
-                touchMinor = toolMinor = mRawPointerAxes.toolMinor.valid
-                        ? in.toolMinor : in.toolMajor;
-                size = mRawPointerAxes.toolMinor.valid
-                        ? avg(in.toolMajor, in.toolMinor) : in.toolMajor;
-            } else {
-                ALOG_ASSERT(false, "No touch or tool axes.  "
-                        "Size calibration should have been resolved to NONE.");
-                touchMajor = 0;
-                touchMinor = 0;
-                toolMajor = 0;
-                toolMinor = 0;
-                size = 0;
-            }
-
-            if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
-                uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
-                if (touchingCount > 1) {
-                    touchMajor /= touchingCount;
-                    touchMinor /= touchingCount;
-                    toolMajor /= touchingCount;
-                    toolMinor /= touchingCount;
-                    size /= touchingCount;
-                }
-            }
-
-            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_GEOMETRIC) {
-                touchMajor *= mGeometricScale;
-                touchMinor *= mGeometricScale;
-                toolMajor *= mGeometricScale;
-                toolMinor *= mGeometricScale;
-            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_AREA) {
-                touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
-                touchMinor = touchMajor;
-                toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
-                toolMinor = toolMajor;
-            } else if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_DIAMETER) {
-                touchMinor = touchMajor;
-                toolMinor = toolMajor;
-            }
-
-            mCalibration.applySizeScaleAndBias(&touchMajor);
-            mCalibration.applySizeScaleAndBias(&touchMinor);
-            mCalibration.applySizeScaleAndBias(&toolMajor);
-            mCalibration.applySizeScaleAndBias(&toolMinor);
-            size *= mSizeScale;
-            break;
-        default:
-            touchMajor = 0;
-            touchMinor = 0;
-            toolMajor = 0;
-            toolMinor = 0;
-            size = 0;
-            break;
-        }
-
-        // Pressure
-        float pressure;
-        switch (mCalibration.pressureCalibration) {
-        case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
-        case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
-            pressure = in.pressure * mPressureScale;
-            break;
-        default:
-            pressure = in.isHovering ? 0 : 1;
-            break;
-        }
-
-        // Tilt and Orientation
-        float tilt;
-        float orientation;
-        if (mHaveTilt) {
-            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
-            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
-            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
-            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
-        } else {
-            tilt = 0;
-
-            switch (mCalibration.orientationCalibration) {
-            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
-                orientation = in.orientation * mOrientationScale;
-                break;
-            case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
-                int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
-                int32_t c2 = signExtendNybble(in.orientation & 0x0f);
-                if (c1 != 0 || c2 != 0) {
-                    orientation = atan2f(c1, c2) * 0.5f;
-                    float confidence = hypotf(c1, c2);
-                    float scale = 1.0f + confidence / 16.0f;
-                    touchMajor *= scale;
-                    touchMinor /= scale;
-                    toolMajor *= scale;
-                    toolMinor /= scale;
-                } else {
-                    orientation = 0;
-                }
-                break;
-            }
-            default:
-                orientation = 0;
-            }
-        }
-
-        // Distance
-        float distance;
-        switch (mCalibration.distanceCalibration) {
-        case Calibration::DISTANCE_CALIBRATION_SCALED:
-            distance = in.distance * mDistanceScale;
-            break;
-        default:
-            distance = 0;
-        }
-
-        // Coverage
-        int32_t rawLeft, rawTop, rawRight, rawBottom;
-        switch (mCalibration.coverageCalibration) {
-        case Calibration::COVERAGE_CALIBRATION_BOX:
-            rawLeft = (in.toolMinor & 0xffff0000) >> 16;
-            rawRight = in.toolMinor & 0x0000ffff;
-            rawBottom = in.toolMajor & 0x0000ffff;
-            rawTop = (in.toolMajor & 0xffff0000) >> 16;
-            break;
-        default:
-            rawLeft = rawTop = rawRight = rawBottom = 0;
-            break;
-        }
-
-        // X, Y, and the bounding box for coverage information
-        // Adjust coords for surface orientation.
-        float x, y, left, top, right, bottom;
-        switch (mSurfaceOrientation) {
-        case DISPLAY_ORIENTATION_90:
-            x = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
-            y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
-            left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
-            right = float(rawBottom- mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
-            bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
-            top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
-            orientation -= M_PI_2;
-            if (orientation < mOrientedRanges.orientation.min) {
-                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
-            }
-            break;
-        case DISPLAY_ORIENTATION_180:
-            x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale + mXTranslate;
-            y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
-            left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale + mXTranslate;
-            right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale + mXTranslate;
-            bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
-            top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
-            orientation -= M_PI;
-            if (orientation < mOrientedRanges.orientation.min) {
-                orientation += (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
-            }
-            break;
-        case DISPLAY_ORIENTATION_270:
-            x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale + mYTranslate;
-            y = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
-            left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale + mYTranslate;
-            right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale + mYTranslate;
-            bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
-            top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
-            orientation += M_PI_2;
-            if (orientation > mOrientedRanges.orientation.max) {
-                orientation -= (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
-            }
-            break;
-        default:
-            x = float(in.x - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
-            y = float(in.y - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
-            left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
-            right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale + mXTranslate;
-            bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
-            top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale + mYTranslate;
-            break;
-        }
-
-        // Write output coords.
-        PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
-        out.clear();
-        out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
-        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
-        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
-        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
-        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
-        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
-        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
-        if (mCalibration.coverageCalibration == Calibration::COVERAGE_CALIBRATION_BOX) {
-            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
-            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
-            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
-            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
-        } else {
-            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
-            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
-        }
-
-        // Write output properties.
-        PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
-        uint32_t id = in.id;
-        properties.clear();
-        properties.id = id;
-        properties.toolType = in.toolType;
-
-        // Write id index.
-        mCurrentCookedPointerData.idToIndex[id] = i;
-    }
-}
-
-void TouchInputMapper::dispatchPointerUsage(nsecs_t when, uint32_t policyFlags,
-        PointerUsage pointerUsage) {
-    if (pointerUsage != mPointerUsage) {
-        abortPointerUsage(when, policyFlags);
-        mPointerUsage = pointerUsage;
-    }
-
-    switch (mPointerUsage) {
-    case POINTER_USAGE_GESTURES:
-        dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
-        break;
-    case POINTER_USAGE_STYLUS:
-        dispatchPointerStylus(when, policyFlags);
-        break;
-    case POINTER_USAGE_MOUSE:
-        dispatchPointerMouse(when, policyFlags);
-        break;
-    default:
-        break;
-    }
-}
-
-void TouchInputMapper::abortPointerUsage(nsecs_t when, uint32_t policyFlags) {
-    switch (mPointerUsage) {
-    case POINTER_USAGE_GESTURES:
-        abortPointerGestures(when, policyFlags);
-        break;
-    case POINTER_USAGE_STYLUS:
-        abortPointerStylus(when, policyFlags);
-        break;
-    case POINTER_USAGE_MOUSE:
-        abortPointerMouse(when, policyFlags);
-        break;
-    default:
-        break;
-    }
-
-    mPointerUsage = POINTER_USAGE_NONE;
-}
-
-void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
-        bool isTimeout) {
-    // Update current gesture coordinates.
-    bool cancelPreviousGesture, finishPreviousGesture;
-    bool sendEvents = preparePointerGestures(when,
-            &cancelPreviousGesture, &finishPreviousGesture, isTimeout);
-    if (!sendEvents) {
-        return;
-    }
-    if (finishPreviousGesture) {
-        cancelPreviousGesture = false;
-    }
-
-    // Update the pointer presentation and spots.
-    if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
-        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT);
-        if (finishPreviousGesture || cancelPreviousGesture) {
-            mPointerController->clearSpots();
-        }
-        mPointerController->setSpots(mPointerGesture.currentGestureCoords,
-                mPointerGesture.currentGestureIdToIndex,
-                mPointerGesture.currentGestureIdBits);
-    } else {
-        mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
-    }
-
-    // Show or hide the pointer if needed.
-    switch (mPointerGesture.currentGestureMode) {
-    case PointerGesture::NEUTRAL:
-    case PointerGesture::QUIET:
-        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
-                && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE
-                        || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) {
-            // Remind the user of where the pointer is after finishing a gesture with spots.
-            mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL);
-        }
-        break;
-    case PointerGesture::TAP:
-    case PointerGesture::TAP_DRAG:
-    case PointerGesture::BUTTON_CLICK_OR_DRAG:
-    case PointerGesture::HOVER:
-    case PointerGesture::PRESS:
-        // Unfade the pointer when the current gesture manipulates the
-        // area directly under the pointer.
-        mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
-        break;
-    case PointerGesture::SWIPE:
-    case PointerGesture::FREEFORM:
-        // Fade the pointer when the current gesture manipulates a different
-        // area and there are spots to guide the user experience.
-        if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
-            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-        } else {
-            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
-        }
-        break;
-    }
-
-    // Send events!
-    int32_t metaState = getContext()->getGlobalMetaState();
-    int32_t buttonState = mCurrentButtonState;
-
-    // Update last coordinates of pointers that have moved so that we observe the new
-    // pointer positions at the same time as other pointers that have just gone up.
-    bool down = mPointerGesture.currentGestureMode == PointerGesture::TAP
-            || mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG
-            || mPointerGesture.currentGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
-            || mPointerGesture.currentGestureMode == PointerGesture::PRESS
-            || mPointerGesture.currentGestureMode == PointerGesture::SWIPE
-            || mPointerGesture.currentGestureMode == PointerGesture::FREEFORM;
-    bool moveNeeded = false;
-    if (down && !cancelPreviousGesture && !finishPreviousGesture
-            && !mPointerGesture.lastGestureIdBits.isEmpty()
-            && !mPointerGesture.currentGestureIdBits.isEmpty()) {
-        BitSet32 movedGestureIdBits(mPointerGesture.currentGestureIdBits.value
-                & mPointerGesture.lastGestureIdBits.value);
-        moveNeeded = updateMovedPointers(mPointerGesture.currentGestureProperties,
-                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
-                mPointerGesture.lastGestureProperties,
-                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
-                movedGestureIdBits);
-        if (buttonState != mLastButtonState) {
-            moveNeeded = true;
-        }
-    }
-
-    // Send motion events for all pointers that went up or were canceled.
-    BitSet32 dispatchedGestureIdBits(mPointerGesture.lastGestureIdBits);
-    if (!dispatchedGestureIdBits.isEmpty()) {
-        if (cancelPreviousGesture) {
-            dispatchMotion(when, policyFlags, mSource,
-                    AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
-                    AMOTION_EVENT_EDGE_FLAG_NONE,
-                    mPointerGesture.lastGestureProperties,
-                    mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
-                    dispatchedGestureIdBits, -1,
-                    0, 0, mPointerGesture.downTime);
-
-            dispatchedGestureIdBits.clear();
-        } else {
-            BitSet32 upGestureIdBits;
-            if (finishPreviousGesture) {
-                upGestureIdBits = dispatchedGestureIdBits;
-            } else {
-                upGestureIdBits.value = dispatchedGestureIdBits.value
-                        & ~mPointerGesture.currentGestureIdBits.value;
-            }
-            while (!upGestureIdBits.isEmpty()) {
-                uint32_t id = upGestureIdBits.clearFirstMarkedBit();
-
-                dispatchMotion(when, policyFlags, mSource,
-                        AMOTION_EVENT_ACTION_POINTER_UP, 0,
-                        metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-                        mPointerGesture.lastGestureProperties,
-                        mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
-                        dispatchedGestureIdBits, id,
-                        0, 0, mPointerGesture.downTime);
-
-                dispatchedGestureIdBits.clearBit(id);
-            }
-        }
-    }
-
-    // Send motion events for all pointers that moved.
-    if (moveNeeded) {
-        dispatchMotion(when, policyFlags, mSource,
-                AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-                mPointerGesture.currentGestureProperties,
-                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
-                dispatchedGestureIdBits, -1,
-                0, 0, mPointerGesture.downTime);
-    }
-
-    // Send motion events for all pointers that went down.
-    if (down) {
-        BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
-                & ~dispatchedGestureIdBits.value);
-        while (!downGestureIdBits.isEmpty()) {
-            uint32_t id = downGestureIdBits.clearFirstMarkedBit();
-            dispatchedGestureIdBits.markBit(id);
-
-            if (dispatchedGestureIdBits.count() == 1) {
-                mPointerGesture.downTime = when;
-            }
-
-            dispatchMotion(when, policyFlags, mSource,
-                    AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
-                    mPointerGesture.currentGestureProperties,
-                    mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
-                    dispatchedGestureIdBits, id,
-                    0, 0, mPointerGesture.downTime);
-        }
-    }
-
-    // Send motion events for hover.
-    if (mPointerGesture.currentGestureMode == PointerGesture::HOVER) {
-        dispatchMotion(when, policyFlags, mSource,
-                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
-                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-                mPointerGesture.currentGestureProperties,
-                mPointerGesture.currentGestureCoords, mPointerGesture.currentGestureIdToIndex,
-                mPointerGesture.currentGestureIdBits, -1,
-                0, 0, mPointerGesture.downTime);
-    } else if (dispatchedGestureIdBits.isEmpty()
-            && !mPointerGesture.lastGestureIdBits.isEmpty()) {
-        // Synthesize a hover move event after all pointers go up to indicate that
-        // the pointer is hovering again even if the user is not currently touching
-        // the touch pad.  This ensures that a view will receive a fresh hover enter
-        // event after a tap.
-        float x, y;
-        mPointerController->getPosition(&x, &y);
-
-        PointerProperties pointerProperties;
-        pointerProperties.clear();
-        pointerProperties.id = 0;
-        pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-
-        PointerCoords pointerCoords;
-        pointerCoords.clear();
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-
-        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
-                metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-                mViewport.displayId, 1, &pointerProperties, &pointerCoords,
-                0, 0, mPointerGesture.downTime);
-        getListener()->notifyMotion(&args);
-    }
-
-    // Update state.
-    mPointerGesture.lastGestureMode = mPointerGesture.currentGestureMode;
-    if (!down) {
-        mPointerGesture.lastGestureIdBits.clear();
-    } else {
-        mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
-        for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
-            uint32_t id = idBits.clearFirstMarkedBit();
-            uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
-            mPointerGesture.lastGestureProperties[index].copyFrom(
-                    mPointerGesture.currentGestureProperties[index]);
-            mPointerGesture.lastGestureCoords[index].copyFrom(
-                    mPointerGesture.currentGestureCoords[index]);
-            mPointerGesture.lastGestureIdToIndex[id] = index;
-        }
-    }
-}
-
-void TouchInputMapper::abortPointerGestures(nsecs_t when, uint32_t policyFlags) {
-    // Cancel previously dispatches pointers.
-    if (!mPointerGesture.lastGestureIdBits.isEmpty()) {
-        int32_t metaState = getContext()->getGlobalMetaState();
-        int32_t buttonState = mCurrentButtonState;
-        dispatchMotion(when, policyFlags, mSource,
-                AMOTION_EVENT_ACTION_CANCEL, 0, metaState, buttonState,
-                AMOTION_EVENT_EDGE_FLAG_NONE,
-                mPointerGesture.lastGestureProperties,
-                mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
-                mPointerGesture.lastGestureIdBits, -1,
-                0, 0, mPointerGesture.downTime);
-    }
-
-    // Reset the current pointer gesture.
-    mPointerGesture.reset();
-    mPointerVelocityControl.reset();
-
-    // Remove any current spots.
-    if (mPointerController != NULL) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-        mPointerController->clearSpots();
-    }
-}
-
-bool TouchInputMapper::preparePointerGestures(nsecs_t when,
-        bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout) {
-    *outCancelPreviousGesture = false;
-    *outFinishPreviousGesture = false;
-
-    // Handle TAP timeout.
-    if (isTimeout) {
-#if DEBUG_GESTURES
-        ALOGD("Gestures: Processing timeout");
-#endif
-
-        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
-            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
-                // The tap/drag timeout has not yet expired.
-                getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
-                        + mConfig.pointerGestureTapDragInterval);
-            } else {
-                // The tap is finished.
-#if DEBUG_GESTURES
-                ALOGD("Gestures: TAP finished");
-#endif
-                *outFinishPreviousGesture = true;
-
-                mPointerGesture.activeGestureId = -1;
-                mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
-                mPointerGesture.currentGestureIdBits.clear();
-
-                mPointerVelocityControl.reset();
-                return true;
-            }
-        }
-
-        // We did not handle this timeout.
-        return false;
-    }
-
-    const uint32_t currentFingerCount = mCurrentFingerIdBits.count();
-    const uint32_t lastFingerCount = mLastFingerIdBits.count();
-
-    // Update the velocity tracker.
-    {
-        VelocityTracker::Position positions[MAX_POINTERS];
-        uint32_t count = 0;
-        for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); count++) {
-            uint32_t id = idBits.clearFirstMarkedBit();
-            const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
-            positions[count].x = pointer.x * mPointerXMovementScale;
-            positions[count].y = pointer.y * mPointerYMovementScale;
-        }
-        mPointerGesture.velocityTracker.addMovement(when,
-                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.
-    // This guarantees we always have an active touch id when there is at least one pointer.
-    // We keep the same active touch id for as long as possible.
-    bool activeTouchChanged = false;
-    int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
-    int32_t activeTouchId = lastActiveTouchId;
-    if (activeTouchId < 0) {
-        if (!mCurrentFingerIdBits.isEmpty()) {
-            activeTouchChanged = true;
-            activeTouchId = mPointerGesture.activeTouchId =
-                    mCurrentFingerIdBits.firstMarkedBit();
-            mPointerGesture.firstTouchTime = when;
-        }
-    } else if (!mCurrentFingerIdBits.hasBit(activeTouchId)) {
-        activeTouchChanged = true;
-        if (!mCurrentFingerIdBits.isEmpty()) {
-            activeTouchId = mPointerGesture.activeTouchId =
-                    mCurrentFingerIdBits.firstMarkedBit();
-        } else {
-            activeTouchId = mPointerGesture.activeTouchId = -1;
-        }
-    }
-
-    // Determine whether we are in quiet time.
-    bool isQuietTime = false;
-    if (activeTouchId < 0) {
-        mPointerGesture.resetQuietTime();
-    } else {
-        isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
-        if (!isQuietTime) {
-            if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
-                    || mPointerGesture.lastGestureMode == PointerGesture::SWIPE
-                    || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
-                    && currentFingerCount < 2) {
-                // Enter quiet time when exiting swipe or freeform state.
-                // This is to prevent accidentally entering the hover state and flinging the
-                // pointer when finishing a swipe and there is still one pointer left onscreen.
-                isQuietTime = true;
-            } else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
-                    && currentFingerCount >= 2
-                    && !isPointerDown(mCurrentButtonState)) {
-                // Enter quiet time when releasing the button and there are still two or more
-                // fingers down.  This may indicate that one finger was used to press the button
-                // but it has not gone up yet.
-                isQuietTime = true;
-            }
-            if (isQuietTime) {
-                mPointerGesture.quietTime = when;
-            }
-        }
-    }
-
-    // Switch states based on button and pointer state.
-    if (isQuietTime) {
-        // Case 1: Quiet time. (QUIET)
-#if DEBUG_GESTURES
-        ALOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
-                + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
-#endif
-        if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
-            *outFinishPreviousGesture = true;
-        }
-
-        mPointerGesture.activeGestureId = -1;
-        mPointerGesture.currentGestureMode = PointerGesture::QUIET;
-        mPointerGesture.currentGestureIdBits.clear();
-
-        mPointerVelocityControl.reset();
-    } else if (isPointerDown(mCurrentButtonState)) {
-        // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
-        // The pointer follows the active touch point.
-        // Emit DOWN, MOVE, UP events at the pointer location.
-        //
-        // Only the active touch matters; other fingers are ignored.  This policy helps
-        // to handle the case where the user places a second finger on the touch pad
-        // to apply the necessary force to depress an integrated button below the surface.
-        // We don't want the second finger to be delivered to applications.
-        //
-        // For this to work well, we need to make sure to track the pointer that is really
-        // active.  If the user first puts one finger down to click then adds another
-        // finger to drag then the active pointer should switch to the finger that is
-        // being dragged.
-#if DEBUG_GESTURES
-        ALOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
-                "currentFingerCount=%d", activeTouchId, currentFingerCount);
-#endif
-        // Reset state when just starting.
-        if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
-            *outFinishPreviousGesture = true;
-            mPointerGesture.activeGestureId = 0;
-        }
-
-        // Switch pointers if needed.
-        // Find the fastest pointer and follow it.
-        if (activeTouchId >= 0 && currentFingerCount > 1) {
-            int32_t bestId = -1;
-            float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
-            for (BitSet32 idBits(mCurrentFingerIdBits); !idBits.isEmpty(); ) {
-                uint32_t id = idBits.clearFirstMarkedBit();
-                float vx, vy;
-                if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
-                    float speed = hypotf(vx, vy);
-                    if (speed > bestSpeed) {
-                        bestId = id;
-                        bestSpeed = speed;
-                    }
-                }
-            }
-            if (bestId >= 0 && bestId != activeTouchId) {
-                mPointerGesture.activeTouchId = activeTouchId = bestId;
-                activeTouchChanged = true;
-#if DEBUG_GESTURES
-                ALOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
-                        "bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
-#endif
-            }
-        }
-
-        if (activeTouchId >= 0 && mLastFingerIdBits.hasBit(activeTouchId)) {
-            const RawPointerData::Pointer& currentPointer =
-                    mCurrentRawPointerData.pointerForId(activeTouchId);
-            const RawPointerData::Pointer& lastPointer =
-                    mLastRawPointerData.pointerForId(activeTouchId);
-            float deltaX = (currentPointer.x - lastPointer.x) * mPointerXMovementScale;
-            float deltaY = (currentPointer.y - lastPointer.y) * mPointerYMovementScale;
-
-            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
-            mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
-            // Move the pointer using a relative motion.
-            // When using spots, the click will occur at the position of the anchor
-            // spot and all other spots will move there.
-            mPointerController->move(deltaX, deltaY);
-        } else {
-            mPointerVelocityControl.reset();
-        }
-
-        float x, y;
-        mPointerController->getPosition(&x, &y);
-
-        mPointerGesture.currentGestureMode = PointerGesture::BUTTON_CLICK_OR_DRAG;
-        mPointerGesture.currentGestureIdBits.clear();
-        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
-        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
-        mPointerGesture.currentGestureProperties[0].clear();
-        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
-        mPointerGesture.currentGestureProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-        mPointerGesture.currentGestureCoords[0].clear();
-        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-    } else if (currentFingerCount == 0) {
-        // Case 3. No fingers down and button is not pressed. (NEUTRAL)
-        if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
-            *outFinishPreviousGesture = true;
-        }
-
-        // Watch for taps coming out of HOVER or TAP_DRAG mode.
-        // Checking for taps after TAP_DRAG allows us to detect double-taps.
-        bool tapped = false;
-        if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
-                || mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
-                && lastFingerCount == 1) {
-            if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
-                float x, y;
-                mPointerController->getPosition(&x, &y);
-                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
-                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
-#if DEBUG_GESTURES
-                    ALOGD("Gestures: TAP");
-#endif
-
-                    mPointerGesture.tapUpTime = when;
-                    getContext()->requestTimeoutAtTime(when
-                            + mConfig.pointerGestureTapDragInterval);
-
-                    mPointerGesture.activeGestureId = 0;
-                    mPointerGesture.currentGestureMode = PointerGesture::TAP;
-                    mPointerGesture.currentGestureIdBits.clear();
-                    mPointerGesture.currentGestureIdBits.markBit(
-                            mPointerGesture.activeGestureId);
-                    mPointerGesture.currentGestureIdToIndex[
-                            mPointerGesture.activeGestureId] = 0;
-                    mPointerGesture.currentGestureProperties[0].clear();
-                    mPointerGesture.currentGestureProperties[0].id =
-                            mPointerGesture.activeGestureId;
-                    mPointerGesture.currentGestureProperties[0].toolType =
-                            AMOTION_EVENT_TOOL_TYPE_FINGER;
-                    mPointerGesture.currentGestureCoords[0].clear();
-                    mPointerGesture.currentGestureCoords[0].setAxisValue(
-                            AMOTION_EVENT_AXIS_X, mPointerGesture.tapX);
-                    mPointerGesture.currentGestureCoords[0].setAxisValue(
-                            AMOTION_EVENT_AXIS_Y, mPointerGesture.tapY);
-                    mPointerGesture.currentGestureCoords[0].setAxisValue(
-                            AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-
-                    tapped = true;
-                } else {
-#if DEBUG_GESTURES
-                    ALOGD("Gestures: Not a TAP, deltaX=%f, deltaY=%f",
-                            x - mPointerGesture.tapX,
-                            y - mPointerGesture.tapY);
-#endif
-                }
-            } else {
-#if DEBUG_GESTURES
-                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
-            }
-        }
-
-        mPointerVelocityControl.reset();
-
-        if (!tapped) {
-#if DEBUG_GESTURES
-            ALOGD("Gestures: NEUTRAL");
-#endif
-            mPointerGesture.activeGestureId = -1;
-            mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
-            mPointerGesture.currentGestureIdBits.clear();
-        }
-    } else if (currentFingerCount == 1) {
-        // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
-        // The pointer follows the active touch point.
-        // When in HOVER, emit HOVER_MOVE events at the pointer location.
-        // When in TAP_DRAG, emit MOVE events at the pointer location.
-        ALOG_ASSERT(activeTouchId >= 0);
-
-        mPointerGesture.currentGestureMode = PointerGesture::HOVER;
-        if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
-            if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
-                float x, y;
-                mPointerController->getPosition(&x, &y);
-                if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
-                        && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
-                    mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
-                } else {
-#if DEBUG_GESTURES
-                    ALOGD("Gestures: Not a TAP_DRAG, deltaX=%f, deltaY=%f",
-                            x - mPointerGesture.tapX,
-                            y - mPointerGesture.tapY);
-#endif
-                }
-            } else {
-#if DEBUG_GESTURES
-                ALOGD("Gestures: Not a TAP_DRAG, %0.3fms time since up",
-                        (when - mPointerGesture.tapUpTime) * 0.000001f);
-#endif
-            }
-        } else if (mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG) {
-            mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
-        }
-
-        if (mLastFingerIdBits.hasBit(activeTouchId)) {
-            const RawPointerData::Pointer& currentPointer =
-                    mCurrentRawPointerData.pointerForId(activeTouchId);
-            const RawPointerData::Pointer& lastPointer =
-                    mLastRawPointerData.pointerForId(activeTouchId);
-            float deltaX = (currentPointer.x - lastPointer.x)
-                    * mPointerXMovementScale;
-            float deltaY = (currentPointer.y - lastPointer.y)
-                    * mPointerYMovementScale;
-
-            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
-            mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
-            // Move the pointer using a relative motion.
-            // When using spots, the hover or drag will occur at the position of the anchor spot.
-            mPointerController->move(deltaX, deltaY);
-        } else {
-            mPointerVelocityControl.reset();
-        }
-
-        bool down;
-        if (mPointerGesture.currentGestureMode == PointerGesture::TAP_DRAG) {
-#if DEBUG_GESTURES
-            ALOGD("Gestures: TAP_DRAG");
-#endif
-            down = true;
-        } else {
-#if DEBUG_GESTURES
-            ALOGD("Gestures: HOVER");
-#endif
-            if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) {
-                *outFinishPreviousGesture = true;
-            }
-            mPointerGesture.activeGestureId = 0;
-            down = false;
-        }
-
-        float x, y;
-        mPointerController->getPosition(&x, &y);
-
-        mPointerGesture.currentGestureIdBits.clear();
-        mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
-        mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
-        mPointerGesture.currentGestureProperties[0].clear();
-        mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
-        mPointerGesture.currentGestureProperties[0].toolType =
-                AMOTION_EVENT_TOOL_TYPE_FINGER;
-        mPointerGesture.currentGestureCoords[0].clear();
-        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-        mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
-                down ? 1.0f : 0.0f);
-
-        if (lastFingerCount == 0 && currentFingerCount != 0) {
-            mPointerGesture.resetTap();
-            mPointerGesture.tapDownTime = when;
-            mPointerGesture.tapX = x;
-            mPointerGesture.tapY = y;
-        }
-    } else {
-        // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM)
-        // We need to provide feedback for each finger that goes down so we cannot wait
-        // for the fingers to move before deciding what to do.
-        //
-        // The ambiguous case is deciding what to do when there are two fingers down but they
-        // have not moved enough to determine whether they are part of a drag or part of a
-        // freeform gesture, or just a press or long-press at the pointer location.
-        //
-        // When there are two fingers we start with the PRESS hypothesis and we generate a
-        // down at the pointer location.
-        //
-        // When the two fingers move enough or when additional fingers are added, we make
-        // a decision to transition into SWIPE or FREEFORM mode accordingly.
-        ALOG_ASSERT(activeTouchId >= 0);
-
-        bool settled = when >= mPointerGesture.firstTouchTime
-                + mConfig.pointerGestureMultitouchSettleInterval;
-        if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
-                && mPointerGesture.lastGestureMode != PointerGesture::SWIPE
-                && mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
-            *outFinishPreviousGesture = true;
-        } else if (!settled && currentFingerCount > lastFingerCount) {
-            // Additional pointers have gone down but not yet settled.
-            // Reset the gesture.
-#if DEBUG_GESTURES
-            ALOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
-                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
-                            + mConfig.pointerGestureMultitouchSettleInterval - when)
-                            * 0.000001f);
-#endif
-            *outCancelPreviousGesture = true;
-        } else {
-            // Continue previous gesture.
-            mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
-        }
-
-        if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
-            mPointerGesture.currentGestureMode = PointerGesture::PRESS;
-            mPointerGesture.activeGestureId = 0;
-            mPointerGesture.referenceIdBits.clear();
-            mPointerVelocityControl.reset();
-
-            // Use the centroid and pointer location as the reference points for the gesture.
-#if DEBUG_GESTURES
-            ALOGD("Gestures: Using centroid as reference for MULTITOUCH, "
-                    "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
-                            + mConfig.pointerGestureMultitouchSettleInterval - when)
-                            * 0.000001f);
-#endif
-            mCurrentRawPointerData.getCentroidOfTouchingPointers(
-                    &mPointerGesture.referenceTouchX,
-                    &mPointerGesture.referenceTouchY);
-            mPointerController->getPosition(&mPointerGesture.referenceGestureX,
-                    &mPointerGesture.referenceGestureY);
-        }
-
-        // Clear the reference deltas for fingers not yet included in the reference calculation.
-        for (BitSet32 idBits(mCurrentFingerIdBits.value
-                & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
-            uint32_t id = idBits.clearFirstMarkedBit();
-            mPointerGesture.referenceDeltas[id].dx = 0;
-            mPointerGesture.referenceDeltas[id].dy = 0;
-        }
-        mPointerGesture.referenceIdBits = mCurrentFingerIdBits;
-
-        // Add delta for all fingers and calculate a common movement delta.
-        float commonDeltaX = 0, commonDeltaY = 0;
-        BitSet32 commonIdBits(mLastFingerIdBits.value
-                & mCurrentFingerIdBits.value);
-        for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
-            bool first = (idBits == commonIdBits);
-            uint32_t id = idBits.clearFirstMarkedBit();
-            const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
-            const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
-            PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
-            delta.dx += cpd.x - lpd.x;
-            delta.dy += cpd.y - lpd.y;
-
-            if (first) {
-                commonDeltaX = delta.dx;
-                commonDeltaY = delta.dy;
-            } else {
-                commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx);
-                commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy);
-            }
-        }
-
-        // Consider transitions from PRESS to SWIPE or MULTITOUCH.
-        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
-            float dist[MAX_POINTER_ID + 1];
-            int32_t distOverThreshold = 0;
-            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
-                uint32_t id = idBits.clearFirstMarkedBit();
-                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
-                dist[id] = hypotf(delta.dx * mPointerXZoomScale,
-                        delta.dy * mPointerYZoomScale);
-                if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
-                    distOverThreshold += 1;
-                }
-            }
-
-            // Only transition when at least two pointers have moved further than
-            // the minimum distance threshold.
-            if (distOverThreshold >= 2) {
-                if (currentFingerCount > 2) {
-                    // There are more than two pointers, switch to FREEFORM.
-#if DEBUG_GESTURES
-                    ALOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
-                            currentFingerCount);
-#endif
-                    *outCancelPreviousGesture = true;
-                    mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
-                } else {
-                    // There are exactly two pointers.
-                    BitSet32 idBits(mCurrentFingerIdBits);
-                    uint32_t id1 = idBits.clearFirstMarkedBit();
-                    uint32_t id2 = idBits.firstMarkedBit();
-                    const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
-                    const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
-                    float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
-                    if (mutualDistance > mPointerGestureMaxSwipeWidth) {
-                        // There are two pointers but they are too far apart for a SWIPE,
-                        // switch to FREEFORM.
-#if DEBUG_GESTURES
-                        ALOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
-                                mutualDistance, mPointerGestureMaxSwipeWidth);
-#endif
-                        *outCancelPreviousGesture = true;
-                        mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
-                    } else {
-                        // There are two pointers.  Wait for both pointers to start moving
-                        // before deciding whether this is a SWIPE or FREEFORM gesture.
-                        float dist1 = dist[id1];
-                        float dist2 = dist[id2];
-                        if (dist1 >= mConfig.pointerGestureMultitouchMinDistance
-                                && dist2 >= mConfig.pointerGestureMultitouchMinDistance) {
-                            // Calculate the dot product of the displacement vectors.
-                            // When the vectors are oriented in approximately the same direction,
-                            // the angle betweeen them is near zero and the cosine of the angle
-                            // approches 1.0.  Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
-                            PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
-                            PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
-                            float dx1 = delta1.dx * mPointerXZoomScale;
-                            float dy1 = delta1.dy * mPointerYZoomScale;
-                            float dx2 = delta2.dx * mPointerXZoomScale;
-                            float dy2 = delta2.dy * mPointerYZoomScale;
-                            float dot = dx1 * dx2 + dy1 * dy2;
-                            float cosine = dot / (dist1 * dist2); // denominator always > 0
-                            if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
-                                // Pointers are moving in the same direction.  Switch to SWIPE.
-#if DEBUG_GESTURES
-                                ALOGD("Gestures: PRESS transitioned to SWIPE, "
-                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
-                                        "cosine %0.3f >= %0.3f",
-                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
-                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
-                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
-#endif
-                                mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
-                            } else {
-                                // Pointers are moving in different directions.  Switch to FREEFORM.
-#if DEBUG_GESTURES
-                                ALOGD("Gestures: PRESS transitioned to FREEFORM, "
-                                        "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, "
-                                        "cosine %0.3f < %0.3f",
-                                        dist1, mConfig.pointerGestureMultitouchMinDistance,
-                                        dist2, mConfig.pointerGestureMultitouchMinDistance,
-                                        cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
-#endif
-                                *outCancelPreviousGesture = true;
-                                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
-                            }
-                        }
-                    }
-                }
-            }
-        } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
-            // Switch from SWIPE to FREEFORM if additional pointers go down.
-            // Cancel previous gesture.
-            if (currentFingerCount > 2) {
-#if DEBUG_GESTURES
-                ALOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
-                        currentFingerCount);
-#endif
-                *outCancelPreviousGesture = true;
-                mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
-            }
-        }
-
-        // Move the reference points based on the overall group motion of the fingers
-        // except in PRESS mode while waiting for a transition to occur.
-        if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
-                && (commonDeltaX || commonDeltaY)) {
-            for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
-                uint32_t id = idBits.clearFirstMarkedBit();
-                PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
-                delta.dx = 0;
-                delta.dy = 0;
-            }
-
-            mPointerGesture.referenceTouchX += commonDeltaX;
-            mPointerGesture.referenceTouchY += commonDeltaY;
-
-            commonDeltaX *= mPointerXMovementScale;
-            commonDeltaY *= mPointerYMovementScale;
-
-            rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
-            mPointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
-
-            mPointerGesture.referenceGestureX += commonDeltaX;
-            mPointerGesture.referenceGestureY += commonDeltaY;
-        }
-
-        // Report gestures.
-        if (mPointerGesture.currentGestureMode == PointerGesture::PRESS
-                || mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
-            // PRESS or SWIPE mode.
-#if DEBUG_GESTURES
-            ALOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
-                    "activeGestureId=%d, currentTouchPointerCount=%d",
-                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
-#endif
-            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
-
-            mPointerGesture.currentGestureIdBits.clear();
-            mPointerGesture.currentGestureIdBits.markBit(mPointerGesture.activeGestureId);
-            mPointerGesture.currentGestureIdToIndex[mPointerGesture.activeGestureId] = 0;
-            mPointerGesture.currentGestureProperties[0].clear();
-            mPointerGesture.currentGestureProperties[0].id = mPointerGesture.activeGestureId;
-            mPointerGesture.currentGestureProperties[0].toolType =
-                    AMOTION_EVENT_TOOL_TYPE_FINGER;
-            mPointerGesture.currentGestureCoords[0].clear();
-            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X,
-                    mPointerGesture.referenceGestureX);
-            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y,
-                    mPointerGesture.referenceGestureY);
-            mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-        } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
-            // FREEFORM mode.
-#if DEBUG_GESTURES
-            ALOGD("Gestures: FREEFORM activeTouchId=%d,"
-                    "activeGestureId=%d, currentTouchPointerCount=%d",
-                    activeTouchId, mPointerGesture.activeGestureId, currentFingerCount);
-#endif
-            ALOG_ASSERT(mPointerGesture.activeGestureId >= 0);
-
-            mPointerGesture.currentGestureIdBits.clear();
-
-            BitSet32 mappedTouchIdBits;
-            BitSet32 usedGestureIdBits;
-            if (mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
-                // Initially, assign the active gesture id to the active touch point
-                // if there is one.  No other touch id bits are mapped yet.
-                if (!*outCancelPreviousGesture) {
-                    mappedTouchIdBits.markBit(activeTouchId);
-                    usedGestureIdBits.markBit(mPointerGesture.activeGestureId);
-                    mPointerGesture.freeformTouchToGestureIdMap[activeTouchId] =
-                            mPointerGesture.activeGestureId;
-                } else {
-                    mPointerGesture.activeGestureId = -1;
-                }
-            } else {
-                // Otherwise, assume we mapped all touches from the previous frame.
-                // Reuse all mappings that are still applicable.
-                mappedTouchIdBits.value = mLastFingerIdBits.value
-                        & mCurrentFingerIdBits.value;
-                usedGestureIdBits = mPointerGesture.lastGestureIdBits;
-
-                // Check whether we need to choose a new active gesture id because the
-                // current went went up.
-                for (BitSet32 upTouchIdBits(mLastFingerIdBits.value
-                        & ~mCurrentFingerIdBits.value);
-                        !upTouchIdBits.isEmpty(); ) {
-                    uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
-                    uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
-                    if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
-                        mPointerGesture.activeGestureId = -1;
-                        break;
-                    }
-                }
-            }
-
-#if DEBUG_GESTURES
-            ALOGD("Gestures: FREEFORM follow up "
-                    "mappedTouchIdBits=0x%08x, usedGestureIdBits=0x%08x, "
-                    "activeGestureId=%d",
-                    mappedTouchIdBits.value, usedGestureIdBits.value,
-                    mPointerGesture.activeGestureId);
-#endif
-
-            BitSet32 idBits(mCurrentFingerIdBits);
-            for (uint32_t i = 0; i < currentFingerCount; i++) {
-                uint32_t touchId = idBits.clearFirstMarkedBit();
-                uint32_t gestureId;
-                if (!mappedTouchIdBits.hasBit(touchId)) {
-                    gestureId = usedGestureIdBits.markFirstUnmarkedBit();
-                    mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
-#if DEBUG_GESTURES
-                    ALOGD("Gestures: FREEFORM "
-                            "new mapping for touch id %d -> gesture id %d",
-                            touchId, gestureId);
-#endif
-                } else {
-                    gestureId = mPointerGesture.freeformTouchToGestureIdMap[touchId];
-#if DEBUG_GESTURES
-                    ALOGD("Gestures: FREEFORM "
-                            "existing mapping for touch id %d -> gesture id %d",
-                            touchId, gestureId);
-#endif
-                }
-                mPointerGesture.currentGestureIdBits.markBit(gestureId);
-                mPointerGesture.currentGestureIdToIndex[gestureId] = i;
-
-                const RawPointerData::Pointer& pointer =
-                        mCurrentRawPointerData.pointerForId(touchId);
-                float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
-                        * mPointerXZoomScale;
-                float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
-                        * mPointerYZoomScale;
-                rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
-
-                mPointerGesture.currentGestureProperties[i].clear();
-                mPointerGesture.currentGestureProperties[i].id = gestureId;
-                mPointerGesture.currentGestureProperties[i].toolType =
-                        AMOTION_EVENT_TOOL_TYPE_FINGER;
-                mPointerGesture.currentGestureCoords[i].clear();
-                mPointerGesture.currentGestureCoords[i].setAxisValue(
-                        AMOTION_EVENT_AXIS_X, mPointerGesture.referenceGestureX + deltaX);
-                mPointerGesture.currentGestureCoords[i].setAxisValue(
-                        AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY + deltaY);
-                mPointerGesture.currentGestureCoords[i].setAxisValue(
-                        AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
-            }
-
-            if (mPointerGesture.activeGestureId < 0) {
-                mPointerGesture.activeGestureId =
-                        mPointerGesture.currentGestureIdBits.firstMarkedBit();
-#if DEBUG_GESTURES
-                ALOGD("Gestures: FREEFORM new "
-                        "activeGestureId=%d", mPointerGesture.activeGestureId);
-#endif
-            }
-        }
-    }
-
-    mPointerController->setButtonState(mCurrentButtonState);
-
-#if DEBUG_GESTURES
-    ALOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
-            "currentGestureMode=%d, currentGestureIdBits=0x%08x, "
-            "lastGestureMode=%d, lastGestureIdBits=0x%08x",
-            toString(*outFinishPreviousGesture), toString(*outCancelPreviousGesture),
-            mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
-            mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
-    for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
-        uint32_t id = idBits.clearFirstMarkedBit();
-        uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
-        const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
-        const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
-        ALOGD("  currentGesture[%d]: index=%d, toolType=%d, "
-                "x=%0.3f, y=%0.3f, pressure=%0.3f",
-                id, index, properties.toolType,
-                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
-                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
-                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
-    }
-    for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
-        uint32_t id = idBits.clearFirstMarkedBit();
-        uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
-        const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
-        const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
-        ALOGD("  lastGesture[%d]: index=%d, toolType=%d, "
-                "x=%0.3f, y=%0.3f, pressure=%0.3f",
-                id, index, properties.toolType,
-                coords.getAxisValue(AMOTION_EVENT_AXIS_X),
-                coords.getAxisValue(AMOTION_EVENT_AXIS_Y),
-                coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
-    }
-#endif
-    return true;
-}
-
-void TouchInputMapper::dispatchPointerStylus(nsecs_t when, uint32_t policyFlags) {
-    mPointerSimple.currentCoords.clear();
-    mPointerSimple.currentProperties.clear();
-
-    bool down, hovering;
-    if (!mCurrentStylusIdBits.isEmpty()) {
-        uint32_t id = mCurrentStylusIdBits.firstMarkedBit();
-        uint32_t index = mCurrentCookedPointerData.idToIndex[id];
-        float x = mCurrentCookedPointerData.pointerCoords[index].getX();
-        float y = mCurrentCookedPointerData.pointerCoords[index].getY();
-        mPointerController->setPosition(x, y);
-
-        hovering = mCurrentCookedPointerData.hoveringIdBits.hasBit(id);
-        down = !hovering;
-
-        mPointerController->getPosition(&x, &y);
-        mPointerSimple.currentCoords.copyFrom(mCurrentCookedPointerData.pointerCoords[index]);
-        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-        mPointerSimple.currentProperties.id = 0;
-        mPointerSimple.currentProperties.toolType =
-                mCurrentCookedPointerData.pointerProperties[index].toolType;
-    } else {
-        down = false;
-        hovering = false;
-    }
-
-    dispatchPointerSimple(when, policyFlags, down, hovering);
-}
-
-void TouchInputMapper::abortPointerStylus(nsecs_t when, uint32_t policyFlags) {
-    abortPointerSimple(when, policyFlags);
-}
-
-void TouchInputMapper::dispatchPointerMouse(nsecs_t when, uint32_t policyFlags) {
-    mPointerSimple.currentCoords.clear();
-    mPointerSimple.currentProperties.clear();
-
-    bool down, hovering;
-    if (!mCurrentMouseIdBits.isEmpty()) {
-        uint32_t id = mCurrentMouseIdBits.firstMarkedBit();
-        uint32_t currentIndex = mCurrentRawPointerData.idToIndex[id];
-        if (mLastMouseIdBits.hasBit(id)) {
-            uint32_t lastIndex = mCurrentRawPointerData.idToIndex[id];
-            float deltaX = (mCurrentRawPointerData.pointers[currentIndex].x
-                    - mLastRawPointerData.pointers[lastIndex].x)
-                    * mPointerXMovementScale;
-            float deltaY = (mCurrentRawPointerData.pointers[currentIndex].y
-                    - mLastRawPointerData.pointers[lastIndex].y)
-                    * mPointerYMovementScale;
-
-            rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
-            mPointerVelocityControl.move(when, &deltaX, &deltaY);
-
-            mPointerController->move(deltaX, deltaY);
-        } else {
-            mPointerVelocityControl.reset();
-        }
-
-        down = isPointerDown(mCurrentButtonState);
-        hovering = !down;
-
-        float x, y;
-        mPointerController->getPosition(&x, &y);
-        mPointerSimple.currentCoords.copyFrom(
-                mCurrentCookedPointerData.pointerCoords[currentIndex]);
-        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
-        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
-        mPointerSimple.currentCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
-                hovering ? 0.0f : 1.0f);
-        mPointerSimple.currentProperties.id = 0;
-        mPointerSimple.currentProperties.toolType =
-                mCurrentCookedPointerData.pointerProperties[currentIndex].toolType;
-    } else {
-        mPointerVelocityControl.reset();
-
-        down = false;
-        hovering = false;
-    }
-
-    dispatchPointerSimple(when, policyFlags, down, hovering);
-}
-
-void TouchInputMapper::abortPointerMouse(nsecs_t when, uint32_t policyFlags) {
-    abortPointerSimple(when, policyFlags);
-
-    mPointerVelocityControl.reset();
-}
-
-void TouchInputMapper::dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
-        bool down, bool hovering) {
-    int32_t metaState = getContext()->getGlobalMetaState();
-
-    if (mPointerController != NULL) {
-        if (down || hovering) {
-            mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
-            mPointerController->clearSpots();
-            mPointerController->setButtonState(mCurrentButtonState);
-            mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
-        } else if (!down && !hovering && (mPointerSimple.down || mPointerSimple.hovering)) {
-            mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-        }
-    }
-
-    if (mPointerSimple.down && !down) {
-        mPointerSimple.down = false;
-
-        // Send up.
-        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                 AMOTION_EVENT_ACTION_UP, 0, metaState, mLastButtonState, 0,
-                 mViewport.displayId,
-                 1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
-                 mOrientedXPrecision, mOrientedYPrecision,
-                 mPointerSimple.downTime);
-        getListener()->notifyMotion(&args);
-    }
-
-    if (mPointerSimple.hovering && !hovering) {
-        mPointerSimple.hovering = false;
-
-        // Send hover exit.
-        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
-                mViewport.displayId,
-                1, &mPointerSimple.lastProperties, &mPointerSimple.lastCoords,
-                mOrientedXPrecision, mOrientedYPrecision,
-                mPointerSimple.downTime);
-        getListener()->notifyMotion(&args);
-    }
-
-    if (down) {
-        if (!mPointerSimple.down) {
-            mPointerSimple.down = true;
-            mPointerSimple.downTime = when;
-
-            // Send down.
-            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                    AMOTION_EVENT_ACTION_DOWN, 0, metaState, mCurrentButtonState, 0,
-                    mViewport.displayId,
-                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
-                    mOrientedXPrecision, mOrientedYPrecision,
-                    mPointerSimple.downTime);
-            getListener()->notifyMotion(&args);
-        }
-
-        // Send move.
-        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                AMOTION_EVENT_ACTION_MOVE, 0, metaState, mCurrentButtonState, 0,
-                mViewport.displayId,
-                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
-                mOrientedXPrecision, mOrientedYPrecision,
-                mPointerSimple.downTime);
-        getListener()->notifyMotion(&args);
-    }
-
-    if (hovering) {
-        if (!mPointerSimple.hovering) {
-            mPointerSimple.hovering = true;
-
-            // Send hover enter.
-            NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                    AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
-                    mViewport.displayId,
-                    1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
-                    mOrientedXPrecision, mOrientedYPrecision,
-                    mPointerSimple.downTime);
-            getListener()->notifyMotion(&args);
-        }
-
-        // Send hover move.
-        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
-                mViewport.displayId,
-                1, &mPointerSimple.currentProperties, &mPointerSimple.currentCoords,
-                mOrientedXPrecision, mOrientedYPrecision,
-                mPointerSimple.downTime);
-        getListener()->notifyMotion(&args);
-    }
-
-    if (mCurrentRawVScroll || mCurrentRawHScroll) {
-        float vscroll = mCurrentRawVScroll;
-        float hscroll = mCurrentRawHScroll;
-        mWheelYVelocityControl.move(when, NULL, &vscroll);
-        mWheelXVelocityControl.move(when, &hscroll, NULL);
-
-        // Send scroll.
-        PointerCoords pointerCoords;
-        pointerCoords.copyFrom(mPointerSimple.currentCoords);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
-        pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
-
-        NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
-                AMOTION_EVENT_ACTION_SCROLL, 0, metaState, mCurrentButtonState, 0,
-                mViewport.displayId,
-                1, &mPointerSimple.currentProperties, &pointerCoords,
-                mOrientedXPrecision, mOrientedYPrecision,
-                mPointerSimple.downTime);
-        getListener()->notifyMotion(&args);
-    }
-
-    // Save state.
-    if (down || hovering) {
-        mPointerSimple.lastCoords.copyFrom(mPointerSimple.currentCoords);
-        mPointerSimple.lastProperties.copyFrom(mPointerSimple.currentProperties);
-    } else {
-        mPointerSimple.reset();
-    }
-}
-
-void TouchInputMapper::abortPointerSimple(nsecs_t when, uint32_t policyFlags) {
-    mPointerSimple.currentCoords.clear();
-    mPointerSimple.currentProperties.clear();
-
-    dispatchPointerSimple(when, policyFlags, false, false);
-}
-
-void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
-        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
-        const PointerProperties* properties, const PointerCoords* coords,
-        const uint32_t* idToIndex, BitSet32 idBits,
-        int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime) {
-    PointerCoords pointerCoords[MAX_POINTERS];
-    PointerProperties pointerProperties[MAX_POINTERS];
-    uint32_t pointerCount = 0;
-    while (!idBits.isEmpty()) {
-        uint32_t id = idBits.clearFirstMarkedBit();
-        uint32_t index = idToIndex[id];
-        pointerProperties[pointerCount].copyFrom(properties[index]);
-        pointerCoords[pointerCount].copyFrom(coords[index]);
-
-        if (changedId >= 0 && id == uint32_t(changedId)) {
-            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-        }
-
-        pointerCount += 1;
-    }
-
-    ALOG_ASSERT(pointerCount != 0);
-
-    if (changedId >= 0 && pointerCount == 1) {
-        // Replace initial down and final up action.
-        // We can compare the action without masking off the changed pointer index
-        // because we know the index is 0.
-        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
-            action = AMOTION_EVENT_ACTION_DOWN;
-        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
-            action = AMOTION_EVENT_ACTION_UP;
-        } else {
-            // Can't happen.
-            ALOG_ASSERT(false);
-        }
-    }
-
-    NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
-            action, flags, metaState, buttonState, edgeFlags,
-            mViewport.displayId, pointerCount, pointerProperties, pointerCoords,
-            xPrecision, yPrecision, downTime);
-    getListener()->notifyMotion(&args);
-}
-
-bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
-        const PointerCoords* inCoords, const uint32_t* inIdToIndex,
-        PointerProperties* outProperties, PointerCoords* outCoords, const uint32_t* outIdToIndex,
-        BitSet32 idBits) const {
-    bool changed = false;
-    while (!idBits.isEmpty()) {
-        uint32_t id = idBits.clearFirstMarkedBit();
-        uint32_t inIndex = inIdToIndex[id];
-        uint32_t outIndex = outIdToIndex[id];
-
-        const PointerProperties& curInProperties = inProperties[inIndex];
-        const PointerCoords& curInCoords = inCoords[inIndex];
-        PointerProperties& curOutProperties = outProperties[outIndex];
-        PointerCoords& curOutCoords = outCoords[outIndex];
-
-        if (curInProperties != curOutProperties) {
-            curOutProperties.copyFrom(curInProperties);
-            changed = true;
-        }
-
-        if (curInCoords != curOutCoords) {
-            curOutCoords.copyFrom(curInCoords);
-            changed = true;
-        }
-    }
-    return changed;
-}
-
-void TouchInputMapper::fadePointer() {
-    if (mPointerController != NULL) {
-        mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
-    }
-}
-
-bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
-    return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
-            && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
-}
-
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
-        int32_t x, int32_t y) {
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
-
-#if DEBUG_VIRTUAL_KEYS
-        ALOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
-                "left=%d, top=%d, right=%d, bottom=%d",
-                x, y,
-                virtualKey.keyCode, virtualKey.scanCode,
-                virtualKey.hitLeft, virtualKey.hitTop,
-                virtualKey.hitRight, virtualKey.hitBottom);
-#endif
-
-        if (virtualKey.isHit(x, y)) {
-            return & virtualKey;
-        }
-    }
-
-    return NULL;
-}
-
-void TouchInputMapper::assignPointerIds() {
-    uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
-    uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
-
-    mCurrentRawPointerData.clearIdBits();
-
-    if (currentPointerCount == 0) {
-        // No pointers to assign.
-        return;
-    }
-
-    if (lastPointerCount == 0) {
-        // All pointers are new.
-        for (uint32_t i = 0; i < currentPointerCount; i++) {
-            uint32_t id = i;
-            mCurrentRawPointerData.pointers[i].id = id;
-            mCurrentRawPointerData.idToIndex[id] = i;
-            mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
-        }
-        return;
-    }
-
-    if (currentPointerCount == 1 && lastPointerCount == 1
-            && mCurrentRawPointerData.pointers[0].toolType
-                    == mLastRawPointerData.pointers[0].toolType) {
-        // Only one pointer and no change in count so it must have the same id as before.
-        uint32_t id = mLastRawPointerData.pointers[0].id;
-        mCurrentRawPointerData.pointers[0].id = id;
-        mCurrentRawPointerData.idToIndex[id] = 0;
-        mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
-        return;
-    }
-
-    // General case.
-    // We build a heap of squared euclidean distances between current and last pointers
-    // associated with the current and last pointer indices.  Then, we find the best
-    // match (by distance) for each current pointer.
-    // The pointers must have the same tool type but it is possible for them to
-    // transition from hovering to touching or vice-versa while retaining the same id.
-    PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
-
-    uint32_t heapSize = 0;
-    for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
-            currentPointerIndex++) {
-        for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
-                lastPointerIndex++) {
-            const RawPointerData::Pointer& currentPointer =
-                    mCurrentRawPointerData.pointers[currentPointerIndex];
-            const RawPointerData::Pointer& lastPointer =
-                    mLastRawPointerData.pointers[lastPointerIndex];
-            if (currentPointer.toolType == lastPointer.toolType) {
-                int64_t deltaX = currentPointer.x - lastPointer.x;
-                int64_t deltaY = currentPointer.y - lastPointer.y;
-
-                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
-
-                // Insert new element into the heap (sift up).
-                heap[heapSize].currentPointerIndex = currentPointerIndex;
-                heap[heapSize].lastPointerIndex = lastPointerIndex;
-                heap[heapSize].distance = distance;
-                heapSize += 1;
-            }
-        }
-    }
-
-    // Heapify
-    for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
-        startIndex -= 1;
-        for (uint32_t parentIndex = startIndex; ;) {
-            uint32_t childIndex = parentIndex * 2 + 1;
-            if (childIndex >= heapSize) {
-                break;
-            }
-
-            if (childIndex + 1 < heapSize
-                    && heap[childIndex + 1].distance < heap[childIndex].distance) {
-                childIndex += 1;
-            }
-
-            if (heap[parentIndex].distance <= heap[childIndex].distance) {
-                break;
-            }
-
-            swap(heap[parentIndex], heap[childIndex]);
-            parentIndex = childIndex;
-        }
-    }
-
-#if DEBUG_POINTER_ASSIGNMENT
-    ALOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
-    for (size_t i = 0; i < heapSize; i++) {
-        ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
-                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
-                heap[i].distance);
-    }
-#endif
-
-    // Pull matches out by increasing order of distance.
-    // To avoid reassigning pointers that have already been matched, the loop keeps track
-    // of which last and current pointers have been matched using the matchedXXXBits variables.
-    // It also tracks the used pointer id bits.
-    BitSet32 matchedLastBits(0);
-    BitSet32 matchedCurrentBits(0);
-    BitSet32 usedIdBits(0);
-    bool first = true;
-    for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
-        while (heapSize > 0) {
-            if (first) {
-                // The first time through the loop, we just consume the root element of
-                // the heap (the one with smallest distance).
-                first = false;
-            } else {
-                // Previous iterations consumed the root element of the heap.
-                // Pop root element off of the heap (sift down).
-                heap[0] = heap[heapSize];
-                for (uint32_t parentIndex = 0; ;) {
-                    uint32_t childIndex = parentIndex * 2 + 1;
-                    if (childIndex >= heapSize) {
-                        break;
-                    }
-
-                    if (childIndex + 1 < heapSize
-                            && heap[childIndex + 1].distance < heap[childIndex].distance) {
-                        childIndex += 1;
-                    }
-
-                    if (heap[parentIndex].distance <= heap[childIndex].distance) {
-                        break;
-                    }
-
-                    swap(heap[parentIndex], heap[childIndex]);
-                    parentIndex = childIndex;
-                }
-
-#if DEBUG_POINTER_ASSIGNMENT
-                ALOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
-                for (size_t i = 0; i < heapSize; i++) {
-                    ALOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
-                            i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
-                            heap[i].distance);
-                }
-#endif
-            }
-
-            heapSize -= 1;
-
-            uint32_t currentPointerIndex = heap[0].currentPointerIndex;
-            if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
-
-            uint32_t lastPointerIndex = heap[0].lastPointerIndex;
-            if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
-
-            matchedCurrentBits.markBit(currentPointerIndex);
-            matchedLastBits.markBit(lastPointerIndex);
-
-            uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
-            mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
-            mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
-            mCurrentRawPointerData.markIdBit(id,
-                    mCurrentRawPointerData.isHovering(currentPointerIndex));
-            usedIdBits.markBit(id);
-
-#if DEBUG_POINTER_ASSIGNMENT
-            ALOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
-                    lastPointerIndex, currentPointerIndex, id, heap[0].distance);
-#endif
-            break;
-        }
-    }
-
-    // Assign fresh ids to pointers that were not matched in the process.
-    for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
-        uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
-        uint32_t id = usedIdBits.markFirstUnmarkedBit();
-
-        mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
-        mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
-        mCurrentRawPointerData.markIdBit(id,
-                mCurrentRawPointerData.isHovering(currentPointerIndex));
-
-#if DEBUG_POINTER_ASSIGNMENT
-        ALOGD("assignPointerIds - assigned: cur=%d, id=%d",
-                currentPointerIndex, id);
-#endif
-    }
-}
-
-int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-    if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
-        return AKEY_STATE_VIRTUAL;
-    }
-
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
-        if (virtualKey.keyCode == keyCode) {
-            return AKEY_STATE_UP;
-        }
-    }
-
-    return AKEY_STATE_UNKNOWN;
-}
-
-int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-    if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
-        return AKEY_STATE_VIRTUAL;
-    }
-
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
-        if (virtualKey.scanCode == scanCode) {
-            return AKEY_STATE_UP;
-        }
-    }
-
-    return AKEY_STATE_UNKNOWN;
-}
-
-bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-        const int32_t* keyCodes, uint8_t* outFlags) {
-    size_t numVirtualKeys = mVirtualKeys.size();
-    for (size_t i = 0; i < numVirtualKeys; i++) {
-        const VirtualKey& virtualKey = mVirtualKeys[i];
-
-        for (size_t i = 0; i < numCodes; i++) {
-            if (virtualKey.keyCode == keyCodes[i]) {
-                outFlags[i] = 1;
-            }
-        }
-    }
-
-    return true;
-}
-
-
-// --- SingleTouchInputMapper ---
-
-SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device) :
-        TouchInputMapper(device) {
-}
-
-SingleTouchInputMapper::~SingleTouchInputMapper() {
-}
-
-void SingleTouchInputMapper::reset(nsecs_t when) {
-    mSingleTouchMotionAccumulator.reset(getDevice());
-
-    TouchInputMapper::reset(when);
-}
-
-void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
-    TouchInputMapper::process(rawEvent);
-
-    mSingleTouchMotionAccumulator.process(rawEvent);
-}
-
-void SingleTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
-    if (mTouchButtonAccumulator.isToolActive()) {
-        mCurrentRawPointerData.pointerCount = 1;
-        mCurrentRawPointerData.idToIndex[0] = 0;
-
-        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
-                && (mTouchButtonAccumulator.isHovering()
-                        || (mRawPointerAxes.pressure.valid
-                                && mSingleTouchMotionAccumulator.getAbsolutePressure() <= 0));
-        mCurrentRawPointerData.markIdBit(0, isHovering);
-
-        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
-        outPointer.id = 0;
-        outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
-        outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
-        outPointer.pressure = mSingleTouchMotionAccumulator.getAbsolutePressure();
-        outPointer.touchMajor = 0;
-        outPointer.touchMinor = 0;
-        outPointer.toolMajor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
-        outPointer.toolMinor = mSingleTouchMotionAccumulator.getAbsoluteToolWidth();
-        outPointer.orientation = 0;
-        outPointer.distance = mSingleTouchMotionAccumulator.getAbsoluteDistance();
-        outPointer.tiltX = mSingleTouchMotionAccumulator.getAbsoluteTiltX();
-        outPointer.tiltY = mSingleTouchMotionAccumulator.getAbsoluteTiltY();
-        outPointer.toolType = mTouchButtonAccumulator.getToolType();
-        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
-            outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-        }
-        outPointer.isHovering = isHovering;
-    }
-}
-
-void SingleTouchInputMapper::configureRawPointerAxes() {
-    TouchInputMapper::configureRawPointerAxes();
-
-    getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
-    getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
-    getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
-    getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
-    getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
-    getAbsoluteAxisInfo(ABS_TILT_X, &mRawPointerAxes.tiltX);
-    getAbsoluteAxisInfo(ABS_TILT_Y, &mRawPointerAxes.tiltY);
-}
-
-bool SingleTouchInputMapper::hasStylus() const {
-    return mTouchButtonAccumulator.hasStylus();
-}
-
-
-// --- MultiTouchInputMapper ---
-
-MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) :
-        TouchInputMapper(device) {
-}
-
-MultiTouchInputMapper::~MultiTouchInputMapper() {
-}
-
-void MultiTouchInputMapper::reset(nsecs_t when) {
-    mMultiTouchMotionAccumulator.reset(getDevice());
-
-    mPointerIdBits.clear();
-
-    TouchInputMapper::reset(when);
-}
-
-void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
-    TouchInputMapper::process(rawEvent);
-
-    mMultiTouchMotionAccumulator.process(rawEvent);
-}
-
-void MultiTouchInputMapper::syncTouch(nsecs_t when, bool* outHavePointerIds) {
-    size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
-    size_t outCount = 0;
-    BitSet32 newPointerIdBits;
-
-    for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
-        const MultiTouchMotionAccumulator::Slot* inSlot =
-                mMultiTouchMotionAccumulator.getSlot(inIndex);
-        if (!inSlot->isInUse()) {
-            continue;
-        }
-
-        if (outCount >= MAX_POINTERS) {
-#if DEBUG_POINTERS
-            ALOGD("MultiTouch device %s emitted more than maximum of %d pointers; "
-                    "ignoring the rest.",
-                    getDeviceName().string(), MAX_POINTERS);
-#endif
-            break; // too many fingers!
-        }
-
-        RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
-        outPointer.x = inSlot->getX();
-        outPointer.y = inSlot->getY();
-        outPointer.pressure = inSlot->getPressure();
-        outPointer.touchMajor = inSlot->getTouchMajor();
-        outPointer.touchMinor = inSlot->getTouchMinor();
-        outPointer.toolMajor = inSlot->getToolMajor();
-        outPointer.toolMinor = inSlot->getToolMinor();
-        outPointer.orientation = inSlot->getOrientation();
-        outPointer.distance = inSlot->getDistance();
-        outPointer.tiltX = 0;
-        outPointer.tiltY = 0;
-
-        outPointer.toolType = inSlot->getToolType();
-        if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
-            outPointer.toolType = mTouchButtonAccumulator.getToolType();
-            if (outPointer.toolType == AMOTION_EVENT_TOOL_TYPE_UNKNOWN) {
-                outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
-            }
-        }
-
-        bool isHovering = mTouchButtonAccumulator.getToolType() != AMOTION_EVENT_TOOL_TYPE_MOUSE
-                && (mTouchButtonAccumulator.isHovering()
-                        || (mRawPointerAxes.pressure.valid && inSlot->getPressure() <= 0));
-        outPointer.isHovering = isHovering;
-
-        // Assign pointer id using tracking id if available.
-        if (*outHavePointerIds) {
-            int32_t trackingId = inSlot->getTrackingId();
-            int32_t id = -1;
-            if (trackingId >= 0) {
-                for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
-                    uint32_t n = idBits.clearFirstMarkedBit();
-                    if (mPointerTrackingIdMap[n] == trackingId) {
-                        id = n;
-                    }
-                }
-
-                if (id < 0 && !mPointerIdBits.isFull()) {
-                    id = mPointerIdBits.markFirstUnmarkedBit();
-                    mPointerTrackingIdMap[id] = trackingId;
-                }
-            }
-            if (id < 0) {
-                *outHavePointerIds = false;
-                mCurrentRawPointerData.clearIdBits();
-                newPointerIdBits.clear();
-            } else {
-                outPointer.id = id;
-                mCurrentRawPointerData.idToIndex[id] = outCount;
-                mCurrentRawPointerData.markIdBit(id, isHovering);
-                newPointerIdBits.markBit(id);
-            }
-        }
-
-        outCount += 1;
-    }
-
-    mCurrentRawPointerData.pointerCount = outCount;
-    mPointerIdBits = newPointerIdBits;
-
-    mMultiTouchMotionAccumulator.finishSync();
-}
-
-void MultiTouchInputMapper::configureRawPointerAxes() {
-    TouchInputMapper::configureRawPointerAxes();
-
-    getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
-    getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
-    getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
-    getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
-    getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
-    getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
-    getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
-    getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
-    getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
-    getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
-    getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
-
-    if (mRawPointerAxes.trackingId.valid
-            && mRawPointerAxes.slot.valid
-            && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
-        size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
-        if (slotCount > MAX_SLOTS) {
-            ALOGW("MultiTouch Device %s reported %d slots but the framework "
-                    "only supports a maximum of %d slots at this time.",
-                    getDeviceName().string(), slotCount, MAX_SLOTS);
-            slotCount = MAX_SLOTS;
-        }
-        mMultiTouchMotionAccumulator.configure(getDevice(),
-                slotCount, true /*usingSlotsProtocol*/);
-    } else {
-        mMultiTouchMotionAccumulator.configure(getDevice(),
-                MAX_POINTERS, false /*usingSlotsProtocol*/);
-    }
-}
-
-bool MultiTouchInputMapper::hasStylus() const {
-    return mMultiTouchMotionAccumulator.hasStylus()
-            || mTouchButtonAccumulator.hasStylus();
-}
-
-
-// --- JoystickInputMapper ---
-
-JoystickInputMapper::JoystickInputMapper(InputDevice* device) :
-        InputMapper(device) {
-}
-
-JoystickInputMapper::~JoystickInputMapper() {
-}
-
-uint32_t JoystickInputMapper::getSources() {
-    return AINPUT_SOURCE_JOYSTICK;
-}
-
-void JoystickInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
-    InputMapper::populateDeviceInfo(info);
-
-    for (size_t i = 0; i < mAxes.size(); i++) {
-        const Axis& axis = mAxes.valueAt(i);
-        addMotionRange(axis.axisInfo.axis, axis, info);
-
-        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
-            addMotionRange(axis.axisInfo.highAxis, axis, info);
-
-        }
-    }
-}
-
-void JoystickInputMapper::addMotionRange(int32_t axisId, const Axis& axis,
-        InputDeviceInfo* info) {
-    info->addMotionRange(axisId, AINPUT_SOURCE_JOYSTICK,
-            axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
-    /* In order to ease the transition for developers from using the old axes
-     * to the newer, more semantically correct axes, we'll continue to register
-     * the old axes as duplicates of their corresponding new ones.  */
-    int32_t compatAxis = getCompatAxis(axisId);
-    if (compatAxis >= 0) {
-        info->addMotionRange(compatAxis, AINPUT_SOURCE_JOYSTICK,
-                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
-    }
-}
-
-/* A mapping from axes the joystick actually has to the axes that should be
- * artificially created for compatibility purposes.
- * Returns -1 if no compatibility axis is needed. */
-int32_t JoystickInputMapper::getCompatAxis(int32_t axis) {
-    switch(axis) {
-    case AMOTION_EVENT_AXIS_LTRIGGER:
-        return AMOTION_EVENT_AXIS_BRAKE;
-    case AMOTION_EVENT_AXIS_RTRIGGER:
-        return AMOTION_EVENT_AXIS_GAS;
-    }
-    return -1;
-}
-
-void JoystickInputMapper::dump(String8& dump) {
-    dump.append(INDENT2 "Joystick Input Mapper:\n");
-
-    dump.append(INDENT3 "Axes:\n");
-    size_t numAxes = mAxes.size();
-    for (size_t i = 0; i < numAxes; i++) {
-        const Axis& axis = mAxes.valueAt(i);
-        const char* label = getAxisLabel(axis.axisInfo.axis);
-        if (label) {
-            dump.appendFormat(INDENT4 "%s", label);
-        } else {
-            dump.appendFormat(INDENT4 "%d", axis.axisInfo.axis);
-        }
-        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
-            label = getAxisLabel(axis.axisInfo.highAxis);
-            if (label) {
-                dump.appendFormat(" / %s (split at %d)", label, axis.axisInfo.splitValue);
-            } else {
-                dump.appendFormat(" / %d (split at %d)", axis.axisInfo.highAxis,
-                        axis.axisInfo.splitValue);
-            }
-        } else if (axis.axisInfo.mode == AxisInfo::MODE_INVERT) {
-            dump.append(" (invert)");
-        }
-
-        dump.appendFormat(": min=%0.5f, max=%0.5f, flat=%0.5f, fuzz=%0.5f, resolution=%0.5f\n",
-                axis.min, axis.max, axis.flat, axis.fuzz, axis.resolution);
-        dump.appendFormat(INDENT4 "  scale=%0.5f, offset=%0.5f, "
-                "highScale=%0.5f, highOffset=%0.5f\n",
-                axis.scale, axis.offset, axis.highScale, axis.highOffset);
-        dump.appendFormat(INDENT4 "  rawAxis=%d, rawMin=%d, rawMax=%d, "
-                "rawFlat=%d, rawFuzz=%d, rawResolution=%d\n",
-                mAxes.keyAt(i), axis.rawAxisInfo.minValue, axis.rawAxisInfo.maxValue,
-                axis.rawAxisInfo.flat, axis.rawAxisInfo.fuzz, axis.rawAxisInfo.resolution);
-    }
-}
-
-void JoystickInputMapper::configure(nsecs_t when,
-        const InputReaderConfiguration* config, uint32_t changes) {
-    InputMapper::configure(when, config, changes);
-
-    if (!changes) { // first time only
-        // Collect all axes.
-        for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
-            if (!(getAbsAxisUsage(abs, getDevice()->getClasses())
-                    & INPUT_DEVICE_CLASS_JOYSTICK)) {
-                continue; // axis must be claimed by a different device
-            }
-
-            RawAbsoluteAxisInfo rawAxisInfo;
-            getAbsoluteAxisInfo(abs, &rawAxisInfo);
-            if (rawAxisInfo.valid) {
-                // Map axis.
-                AxisInfo axisInfo;
-                bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
-                if (!explicitlyMapped) {
-                    // Axis is not explicitly mapped, will choose a generic axis later.
-                    axisInfo.mode = AxisInfo::MODE_NORMAL;
-                    axisInfo.axis = -1;
-                }
-
-                // Apply flat override.
-                int32_t rawFlat = axisInfo.flatOverride < 0
-                        ? rawAxisInfo.flat : axisInfo.flatOverride;
-
-                // Calculate scaling factors and limits.
-                Axis axis;
-                if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
-                    float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
-                    float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
-                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
-                            scale, 0.0f, highScale, 0.0f,
-                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
-                            rawAxisInfo.resolution * scale);
-                } else if (isCenteredAxis(axisInfo.axis)) {
-                    float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
-                    float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
-                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
-                            scale, offset, scale, offset,
-                            -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
-                            rawAxisInfo.resolution * scale);
-                } else {
-                    float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
-                    axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
-                            scale, 0.0f, scale, 0.0f,
-                            0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale,
-                            rawAxisInfo.resolution * scale);
-                }
-
-                // To eliminate noise while the joystick is at rest, filter out small variations
-                // in axis values up front.
-                axis.filter = axis.flat * 0.25f;
-
-                mAxes.add(abs, axis);
-            }
-        }
-
-        // If there are too many axes, start dropping them.
-        // Prefer to keep explicitly mapped axes.
-        if (mAxes.size() > PointerCoords::MAX_AXES) {
-            ALOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
-                    getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
-            pruneAxes(true);
-            pruneAxes(false);
-        }
-
-        // Assign generic axis ids to remaining axes.
-        int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
-        size_t numAxes = mAxes.size();
-        for (size_t i = 0; i < numAxes; i++) {
-            Axis& axis = mAxes.editValueAt(i);
-            if (axis.axisInfo.axis < 0) {
-                while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
-                        && haveAxis(nextGenericAxisId)) {
-                    nextGenericAxisId += 1;
-                }
-
-                if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
-                    axis.axisInfo.axis = nextGenericAxisId;
-                    nextGenericAxisId += 1;
-                } else {
-                    ALOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
-                            "have already been assigned to other axes.",
-                            getDeviceName().string(), mAxes.keyAt(i));
-                    mAxes.removeItemsAt(i--);
-                    numAxes -= 1;
-                }
-            }
-        }
-    }
-}
-
-bool JoystickInputMapper::haveAxis(int32_t axisId) {
-    size_t numAxes = mAxes.size();
-    for (size_t i = 0; i < numAxes; i++) {
-        const Axis& axis = mAxes.valueAt(i);
-        if (axis.axisInfo.axis == axisId
-                || (axis.axisInfo.mode == AxisInfo::MODE_SPLIT
-                        && axis.axisInfo.highAxis == axisId)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-void JoystickInputMapper::pruneAxes(bool ignoreExplicitlyMappedAxes) {
-    size_t i = mAxes.size();
-    while (mAxes.size() > PointerCoords::MAX_AXES && i-- > 0) {
-        if (ignoreExplicitlyMappedAxes && mAxes.valueAt(i).explicitlyMapped) {
-            continue;
-        }
-        ALOGI("Discarding joystick '%s' axis %d because there are too many axes.",
-                getDeviceName().string(), mAxes.keyAt(i));
-        mAxes.removeItemsAt(i);
-    }
-}
-
-bool JoystickInputMapper::isCenteredAxis(int32_t axis) {
-    switch (axis) {
-    case AMOTION_EVENT_AXIS_X:
-    case AMOTION_EVENT_AXIS_Y:
-    case AMOTION_EVENT_AXIS_Z:
-    case AMOTION_EVENT_AXIS_RX:
-    case AMOTION_EVENT_AXIS_RY:
-    case AMOTION_EVENT_AXIS_RZ:
-    case AMOTION_EVENT_AXIS_HAT_X:
-    case AMOTION_EVENT_AXIS_HAT_Y:
-    case AMOTION_EVENT_AXIS_ORIENTATION:
-    case AMOTION_EVENT_AXIS_RUDDER:
-    case AMOTION_EVENT_AXIS_WHEEL:
-        return true;
-    default:
-        return false;
-    }
-}
-
-void JoystickInputMapper::reset(nsecs_t when) {
-    // Recenter all axes.
-    size_t numAxes = mAxes.size();
-    for (size_t i = 0; i < numAxes; i++) {
-        Axis& axis = mAxes.editValueAt(i);
-        axis.resetValue();
-    }
-
-    InputMapper::reset(when);
-}
-
-void JoystickInputMapper::process(const RawEvent* rawEvent) {
-    switch (rawEvent->type) {
-    case EV_ABS: {
-        ssize_t index = mAxes.indexOfKey(rawEvent->code);
-        if (index >= 0) {
-            Axis& axis = mAxes.editValueAt(index);
-            float newValue, highNewValue;
-            switch (axis.axisInfo.mode) {
-            case AxisInfo::MODE_INVERT:
-                newValue = (axis.rawAxisInfo.maxValue - rawEvent->value)
-                        * axis.scale + axis.offset;
-                highNewValue = 0.0f;
-                break;
-            case AxisInfo::MODE_SPLIT:
-                if (rawEvent->value < axis.axisInfo.splitValue) {
-                    newValue = (axis.axisInfo.splitValue - rawEvent->value)
-                            * axis.scale + axis.offset;
-                    highNewValue = 0.0f;
-                } else if (rawEvent->value > axis.axisInfo.splitValue) {
-                    newValue = 0.0f;
-                    highNewValue = (rawEvent->value - axis.axisInfo.splitValue)
-                            * axis.highScale + axis.highOffset;
-                } else {
-                    newValue = 0.0f;
-                    highNewValue = 0.0f;
-                }
-                break;
-            default:
-                newValue = rawEvent->value * axis.scale + axis.offset;
-                highNewValue = 0.0f;
-                break;
-            }
-            axis.newValue = newValue;
-            axis.highNewValue = highNewValue;
-        }
-        break;
-    }
-
-    case EV_SYN:
-        switch (rawEvent->code) {
-        case SYN_REPORT:
-            sync(rawEvent->when, false /*force*/);
-            break;
-        }
-        break;
-    }
-}
-
-void JoystickInputMapper::sync(nsecs_t when, bool force) {
-    if (!filterAxes(force)) {
-        return;
-    }
-
-    int32_t metaState = mContext->getGlobalMetaState();
-    int32_t buttonState = 0;
-
-    PointerProperties pointerProperties;
-    pointerProperties.clear();
-    pointerProperties.id = 0;
-    pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_UNKNOWN;
-
-    PointerCoords pointerCoords;
-    pointerCoords.clear();
-
-    size_t numAxes = mAxes.size();
-    for (size_t i = 0; i < numAxes; i++) {
-        const Axis& axis = mAxes.valueAt(i);
-        setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.axis, axis.currentValue);
-        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
-            setPointerCoordsAxisValue(&pointerCoords, axis.axisInfo.highAxis,
-                    axis.highCurrentValue);
-        }
-    }
-
-    // Moving a joystick axis should not wake the device because joysticks can
-    // be fairly noisy even when not in use.  On the other hand, pushing a gamepad
-    // button will likely wake the device.
-    // TODO: Use the input device configuration to control this behavior more finely.
-    uint32_t policyFlags = 0;
-
-    NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
-            AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
-            ADISPLAY_ID_NONE, 1, &pointerProperties, &pointerCoords, 0, 0, 0);
-    getListener()->notifyMotion(&args);
-}
-
-void JoystickInputMapper::setPointerCoordsAxisValue(PointerCoords* pointerCoords,
-        int32_t axis, float value) {
-    pointerCoords->setAxisValue(axis, value);
-    /* In order to ease the transition for developers from using the old axes
-     * to the newer, more semantically correct axes, we'll continue to produce
-     * values for the old axes as mirrors of the value of their corresponding
-     * new axes. */
-    int32_t compatAxis = getCompatAxis(axis);
-    if (compatAxis >= 0) {
-        pointerCoords->setAxisValue(compatAxis, value);
-    }
-}
-
-bool JoystickInputMapper::filterAxes(bool force) {
-    bool atLeastOneSignificantChange = force;
-    size_t numAxes = mAxes.size();
-    for (size_t i = 0; i < numAxes; i++) {
-        Axis& axis = mAxes.editValueAt(i);
-        if (force || hasValueChangedSignificantly(axis.filter,
-                axis.newValue, axis.currentValue, axis.min, axis.max)) {
-            axis.currentValue = axis.newValue;
-            atLeastOneSignificantChange = true;
-        }
-        if (axis.axisInfo.mode == AxisInfo::MODE_SPLIT) {
-            if (force || hasValueChangedSignificantly(axis.filter,
-                    axis.highNewValue, axis.highCurrentValue, axis.min, axis.max)) {
-                axis.highCurrentValue = axis.highNewValue;
-                atLeastOneSignificantChange = true;
-            }
-        }
-    }
-    return atLeastOneSignificantChange;
-}
-
-bool JoystickInputMapper::hasValueChangedSignificantly(
-        float filter, float newValue, float currentValue, float min, float max) {
-    if (newValue != currentValue) {
-        // Filter out small changes in value unless the value is converging on the axis
-        // bounds or center point.  This is intended to reduce the amount of information
-        // sent to applications by particularly noisy joysticks (such as PS3).
-        if (fabs(newValue - currentValue) > filter
-                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, min)
-                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, max)
-                || hasMovedNearerToValueWithinFilteredRange(filter, newValue, currentValue, 0)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool JoystickInputMapper::hasMovedNearerToValueWithinFilteredRange(
-        float filter, float newValue, float currentValue, float thresholdValue) {
-    float newDistance = fabs(newValue - thresholdValue);
-    if (newDistance < filter) {
-        float oldDistance = fabs(currentValue - thresholdValue);
-        if (newDistance < oldDistance) {
-            return true;
-        }
-    }
-    return false;
-}
-
-} // namespace android
diff --git a/libs/input/InputReader.h b/libs/input/InputReader.h
deleted file mode 100644
index c90d483..0000000
--- a/libs/input/InputReader.h
+++ /dev/null
@@ -1,1820 +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 _UI_INPUT_READER_H
-#define _UI_INPUT_READER_H
-
-#include "EventHub.h"
-#include "PointerController.h"
-#include "InputListener.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>
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-#include <utils/BitSet.h>
-
-#include <stddef.h>
-#include <unistd.h>
-
-// Maximum supported size of a vibration pattern.
-// Must be at least 2.
-#define MAX_VIBRATE_PATTERN_SIZE 100
-
-// Maximum allowable delay value in a vibration pattern before
-// which the delay will be truncated.
-#define MAX_VIBRATE_PATTERN_DELAY_NSECS (1000000 * 1000000000LL)
-
-namespace android {
-
-class InputDevice;
-class InputMapper;
-
-/*
- * Describes how coordinates are mapped on a physical display.
- * See com.android.server.display.DisplayViewport.
- */
-struct DisplayViewport {
-    int32_t displayId; // -1 if invalid
-    int32_t orientation;
-    int32_t logicalLeft;
-    int32_t logicalTop;
-    int32_t logicalRight;
-    int32_t logicalBottom;
-    int32_t physicalLeft;
-    int32_t physicalTop;
-    int32_t physicalRight;
-    int32_t physicalBottom;
-    int32_t deviceWidth;
-    int32_t deviceHeight;
-
-    DisplayViewport() :
-            displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0),
-            logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
-            physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0),
-            deviceWidth(0), deviceHeight(0) {
-    }
-
-    bool operator==(const DisplayViewport& other) const {
-        return displayId == other.displayId
-                && orientation == other.orientation
-                && logicalLeft == other.logicalLeft
-                && logicalTop == other.logicalTop
-                && logicalRight == other.logicalRight
-                && logicalBottom == other.logicalBottom
-                && physicalLeft == other.physicalLeft
-                && physicalTop == other.physicalTop
-                && physicalRight == other.physicalRight
-                && physicalBottom == other.physicalBottom
-                && deviceWidth == other.deviceWidth
-                && deviceHeight == other.deviceHeight;
-    }
-
-    bool operator!=(const DisplayViewport& other) const {
-        return !(*this == other);
-    }
-
-    inline bool isValid() const {
-        return displayId >= 0;
-    }
-
-    void setNonDisplayViewport(int32_t width, int32_t height) {
-        displayId = ADISPLAY_ID_NONE;
-        orientation = DISPLAY_ORIENTATION_0;
-        logicalLeft = 0;
-        logicalTop = 0;
-        logicalRight = width;
-        logicalBottom = height;
-        physicalLeft = 0;
-        physicalTop = 0;
-        physicalRight = width;
-        physicalBottom = height;
-        deviceWidth = width;
-        deviceHeight = height;
-    }
-};
-
-/*
- * Input reader configuration.
- *
- * Specifies various options that modify the behavior of the input reader.
- */
-struct InputReaderConfiguration {
-    // Describes changes that have occurred.
-    enum {
-        // The pointer speed changed.
-        CHANGE_POINTER_SPEED = 1 << 0,
-
-        // The pointer gesture control changed.
-        CHANGE_POINTER_GESTURE_ENABLEMENT = 1 << 1,
-
-        // The display size or orientation changed.
-        CHANGE_DISPLAY_INFO = 1 << 2,
-
-        // The visible touches option changed.
-        CHANGE_SHOW_TOUCHES = 1 << 3,
-
-        // The keyboard layouts must be reloaded.
-        CHANGE_KEYBOARD_LAYOUTS = 1 << 4,
-
-        // The device name alias supplied by the may have changed for some devices.
-        CHANGE_DEVICE_ALIAS = 1 << 5,
-
-        // All devices must be reopened.
-        CHANGE_MUST_REOPEN = 1 << 31,
-    };
-
-    // Gets the amount of time to disable virtual keys after the screen is touched
-    // in order to filter out accidental virtual key presses due to swiping gestures
-    // or taps near the edge of the display.  May be 0 to disable the feature.
-    nsecs_t virtualKeyQuietTime;
-
-    // The excluded device names for the platform.
-    // Devices with these names will be ignored.
-    Vector<String8> excludedDeviceNames;
-
-    // Velocity control parameters for mouse pointer movements.
-    VelocityControlParameters pointerVelocityControlParameters;
-
-    // Velocity control parameters for mouse wheel movements.
-    VelocityControlParameters wheelVelocityControlParameters;
-
-    // True if pointer gestures are enabled.
-    bool pointerGesturesEnabled;
-
-    // Quiet time between certain pointer gesture transitions.
-    // Time to allow for all fingers or buttons to settle into a stable state before
-    // starting a new gesture.
-    nsecs_t pointerGestureQuietInterval;
-
-    // The minimum speed that a pointer must travel for us to consider switching the active
-    // touch pointer to it during a drag.  This threshold is set to avoid switching due
-    // to noise from a finger resting on the touch pad (perhaps just pressing it down).
-    float pointerGestureDragMinSwitchSpeed; // in pixels per second
-
-    // Tap gesture delay time.
-    // The time between down and up must be less than this to be considered a tap.
-    nsecs_t pointerGestureTapInterval;
-
-    // Tap drag gesture delay time.
-    // The time between the previous tap's up and the next down must be less than
-    // this to be considered a drag.  Otherwise, the previous tap is finished and a
-    // new tap begins.
-    //
-    // Note that the previous tap will be held down for this entire duration so this
-    // interval must be shorter than the long press timeout.
-    nsecs_t pointerGestureTapDragInterval;
-
-    // The distance in pixels that the pointer is allowed to move from initial down
-    // to up and still be called a tap.
-    float pointerGestureTapSlop; // in pixels
-
-    // Time after the first touch points go down to settle on an initial centroid.
-    // This is intended to be enough time to handle cases where the user puts down two
-    // fingers at almost but not quite exactly the same time.
-    nsecs_t pointerGestureMultitouchSettleInterval;
-
-    // The transition from PRESS to SWIPE or FREEFORM gesture mode is made when
-    // at least two pointers have moved at least this far from their starting place.
-    float pointerGestureMultitouchMinDistance; // in pixels
-
-    // The transition from PRESS to SWIPE gesture mode can only occur when the
-    // cosine of the angle between the two vectors is greater than or equal to than this value
-    // which indicates that the vectors are oriented in the same direction.
-    // When the vectors are oriented in the exactly same direction, the cosine is 1.0.
-    // (In exactly opposite directions, the cosine is -1.0.)
-    float pointerGestureSwipeTransitionAngleCosine;
-
-    // The transition from PRESS to SWIPE gesture mode can only occur when the
-    // fingers are no more than this far apart relative to the diagonal size of
-    // the touch pad.  For example, a ratio of 0.5 means that the fingers must be
-    // no more than half the diagonal size of the touch pad apart.
-    float pointerGestureSwipeMaxWidthRatio;
-
-    // The gesture movement speed factor relative to the size of the display.
-    // Movement speed applies when the fingers are moving in the same direction.
-    // Without acceleration, a full swipe of the touch pad diagonal in movement mode
-    // will cover this portion of the display diagonal.
-    float pointerGestureMovementSpeedRatio;
-
-    // The gesture zoom speed factor relative to the size of the display.
-    // Zoom speed applies when the fingers are mostly moving relative to each other
-    // to execute a scale gesture or similar.
-    // Without acceleration, a full swipe of the touch pad diagonal in zoom mode
-    // will cover this portion of the display diagonal.
-    float pointerGestureZoomSpeedRatio;
-
-    // True to show the location of touches on the touch screen as spots.
-    bool showTouches;
-
-    InputReaderConfiguration() :
-            virtualKeyQuietTime(0),
-            pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
-            wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
-            pointerGesturesEnabled(true),
-            pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
-            pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second
-            pointerGestureTapInterval(150 * 1000000LL), // 150 ms
-            pointerGestureTapDragInterval(150 * 1000000LL), // 150 ms
-            pointerGestureTapSlop(10.0f), // 10 pixels
-            pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms
-            pointerGestureMultitouchMinDistance(15), // 15 pixels
-            pointerGestureSwipeTransitionAngleCosine(0.2588f), // cosine of 75 degrees
-            pointerGestureSwipeMaxWidthRatio(0.25f),
-            pointerGestureMovementSpeedRatio(0.8f),
-            pointerGestureZoomSpeedRatio(0.3f),
-            showTouches(false) { }
-
-    bool getDisplayInfo(bool external, DisplayViewport* outViewport) const;
-    void setDisplayInfo(bool external, const DisplayViewport& viewport);
-
-private:
-    DisplayViewport mInternalDisplay;
-    DisplayViewport mExternalDisplay;
-};
-
-
-/*
- * Input reader policy interface.
- *
- * The input reader policy is used by the input reader to interact with the Window Manager
- * and other system components.
- *
- * The actual implementation is partially supported by callbacks into the DVM
- * via JNI.  This interface is also mocked in the unit tests.
- *
- * These methods must NOT re-enter the input reader since they may be called while
- * holding the input reader lock.
- */
-class InputReaderPolicyInterface : public virtual RefBase {
-protected:
-    InputReaderPolicyInterface() { }
-    virtual ~InputReaderPolicyInterface() { }
-
-public:
-    /* Gets the input reader configuration. */
-    virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) = 0;
-
-    /* Gets a pointer controller associated with the specified cursor device (ie. a mouse). */
-    virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) = 0;
-
-    /* Notifies the input reader policy that some input devices have changed
-     * and provides information about all current input devices.
-     */
-    virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) = 0;
-
-    /* Gets the keyboard layout for a particular input device. */
-    virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(
-            const InputDeviceIdentifier& identifier) = 0;
-
-    /* Gets a user-supplied alias for a particular input device, or an empty string if none. */
-    virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) = 0;
-};
-
-
-/* Processes raw input events and sends cooked event data to an input listener. */
-class InputReaderInterface : public virtual RefBase {
-protected:
-    InputReaderInterface() { }
-    virtual ~InputReaderInterface() { }
-
-public:
-    /* Dumps the state of the input reader.
-     *
-     * This method may be called on any thread (usually by the input manager). */
-    virtual void dump(String8& dump) = 0;
-
-    /* Called by the heatbeat to ensures that the reader has not deadlocked. */
-    virtual void monitor() = 0;
-
-    /* Runs a single iteration of the processing loop.
-     * Nominally reads and processes one incoming message from the EventHub.
-     *
-     * This method should be called on the input reader thread.
-     */
-    virtual void loopOnce() = 0;
-
-    /* Gets information about all input devices.
-     *
-     * This method may be called on any thread (usually by the input manager).
-     */
-    virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices) = 0;
-
-    /* Query current input state. */
-    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t scanCode) = 0;
-    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t keyCode) = 0;
-    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
-            int32_t sw) = 0;
-
-    /* Determine whether physical keys exist for the given framework-domain key codes. */
-    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
-            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
-
-    /* Requests that a reconfiguration of all input devices.
-     * The changes flag is a bitfield that indicates what has changed and whether
-     * the input devices must all be reopened. */
-    virtual void requestRefreshConfiguration(uint32_t changes) = 0;
-
-    /* Controls the vibrator of a particular input device. */
-    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
-            ssize_t repeat, int32_t token) = 0;
-    virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0;
-};
-
-
-/* Internal interface used by individual input devices to access global input device state
- * and parameters maintained by the input reader.
- */
-class InputReaderContext {
-public:
-    InputReaderContext() { }
-    virtual ~InputReaderContext() { }
-
-    virtual void updateGlobalMetaState() = 0;
-    virtual int32_t getGlobalMetaState() = 0;
-
-    virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
-    virtual bool shouldDropVirtualKey(nsecs_t now,
-            InputDevice* device, int32_t keyCode, int32_t scanCode) = 0;
-
-    virtual void fadePointer() = 0;
-
-    virtual void requestTimeoutAtTime(nsecs_t when) = 0;
-    virtual int32_t bumpGeneration() = 0;
-
-    virtual InputReaderPolicyInterface* getPolicy() = 0;
-    virtual InputListenerInterface* getListener() = 0;
-    virtual EventHubInterface* getEventHub() = 0;
-};
-
-
-/* The input reader reads raw event data from the event hub and processes it into input events
- * that it sends to the input listener.  Some functions of the input reader, such as early
- * event filtering in low power states, are controlled by a separate policy object.
- *
- * The InputReader owns a collection of InputMappers.  Most of the work it does happens
- * on the input reader thread but the InputReader can receive queries from other system
- * components running on arbitrary threads.  To keep things manageable, the InputReader
- * uses a single Mutex to guard its state.  The Mutex may be held while calling into the
- * EventHub or the InputReaderPolicy but it is never held while calling into the
- * InputListener.
- */
-class InputReader : public InputReaderInterface {
-public:
-    InputReader(const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& policy,
-            const sp<InputListenerInterface>& listener);
-    virtual ~InputReader();
-
-    virtual void dump(String8& dump);
-    virtual void monitor();
-
-    virtual void loopOnce();
-
-    virtual void getInputDevices(Vector<InputDeviceInfo>& outInputDevices);
-
-    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t scanCode);
-    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
-            int32_t keyCode);
-    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
-            int32_t sw);
-
-    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
-            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
-
-    virtual void requestRefreshConfiguration(uint32_t changes);
-
-    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
-            ssize_t repeat, int32_t token);
-    virtual void cancelVibrate(int32_t deviceId, int32_t token);
-
-protected:
-    // These members are protected so they can be instrumented by test cases.
-    virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
-            const InputDeviceIdentifier& identifier, uint32_t classes);
-
-    class ContextImpl : public InputReaderContext {
-        InputReader* mReader;
-
-    public:
-        ContextImpl(InputReader* reader);
-
-        virtual void updateGlobalMetaState();
-        virtual int32_t getGlobalMetaState();
-        virtual void disableVirtualKeysUntil(nsecs_t time);
-        virtual bool shouldDropVirtualKey(nsecs_t now,
-                InputDevice* device, int32_t keyCode, int32_t scanCode);
-        virtual void fadePointer();
-        virtual void requestTimeoutAtTime(nsecs_t when);
-        virtual int32_t bumpGeneration();
-        virtual InputReaderPolicyInterface* getPolicy();
-        virtual InputListenerInterface* getListener();
-        virtual EventHubInterface* getEventHub();
-    } mContext;
-
-    friend class ContextImpl;
-
-private:
-    Mutex mLock;
-
-    Condition mReaderIsAliveCondition;
-
-    sp<EventHubInterface> mEventHub;
-    sp<InputReaderPolicyInterface> mPolicy;
-    sp<QueuedInputListener> mQueuedListener;
-
-    InputReaderConfiguration mConfig;
-
-    // The event queue.
-    static const int EVENT_BUFFER_SIZE = 256;
-    RawEvent mEventBuffer[EVENT_BUFFER_SIZE];
-
-    KeyedVector<int32_t, InputDevice*> mDevices;
-
-    // low-level input event decoding and device management
-    void processEventsLocked(const RawEvent* rawEvents, size_t count);
-
-    void addDeviceLocked(nsecs_t when, int32_t deviceId);
-    void removeDeviceLocked(nsecs_t when, int32_t deviceId);
-    void processEventsForDeviceLocked(int32_t deviceId, const RawEvent* rawEvents, size_t count);
-    void timeoutExpiredLocked(nsecs_t when);
-
-    void handleConfigurationChangedLocked(nsecs_t when);
-
-    int32_t mGlobalMetaState;
-    void updateGlobalMetaStateLocked();
-    int32_t getGlobalMetaStateLocked();
-
-    void fadePointerLocked();
-
-    int32_t mGeneration;
-    int32_t bumpGenerationLocked();
-
-    void getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices);
-
-    nsecs_t mDisableVirtualKeysTimeout;
-    void disableVirtualKeysUntilLocked(nsecs_t time);
-    bool shouldDropVirtualKeyLocked(nsecs_t now,
-            InputDevice* device, int32_t keyCode, int32_t scanCode);
-
-    nsecs_t mNextTimeout;
-    void requestTimeoutAtTimeLocked(nsecs_t when);
-
-    uint32_t mConfigurationChangesToRefresh;
-    void refreshConfigurationLocked(uint32_t changes);
-
-    // state queries
-    typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
-    int32_t getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
-            GetStateFunc getStateFunc);
-    bool markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-};
-
-
-/* Reads raw events from the event hub and processes them, endlessly. */
-class InputReaderThread : public Thread {
-public:
-    InputReaderThread(const sp<InputReaderInterface>& reader);
-    virtual ~InputReaderThread();
-
-private:
-    sp<InputReaderInterface> mReader;
-
-    virtual bool threadLoop();
-};
-
-
-/* Represents the state of a single input device. */
-class InputDevice {
-public:
-    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() 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; }
-
-    inline bool isIgnored() { return mMappers.isEmpty(); }
-
-    void dump(String8& dump);
-    void addMapper(InputMapper* mapper);
-    void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
-    void reset(nsecs_t when);
-    void process(const RawEvent* rawEvents, size_t count);
-    void timeoutExpired(nsecs_t when);
-
-    void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
-    int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
-    bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-    void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat, int32_t token);
-    void cancelVibrate(int32_t token);
-
-    int32_t getMetaState();
-
-    void fadePointer();
-
-    void bumpGeneration();
-
-    void notifyReset(nsecs_t when);
-
-    inline const PropertyMap& getConfiguration() { return mConfiguration; }
-    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
-
-    bool hasKey(int32_t code) {
-        return getEventHub()->hasScanCode(mId, code);
-    }
-
-    bool hasAbsoluteAxis(int32_t code) {
-        RawAbsoluteAxisInfo info;
-        getEventHub()->getAbsoluteAxisInfo(mId, code, &info);
-        return info.valid;
-    }
-
-    bool isKeyPressed(int32_t code) {
-        return getEventHub()->getScanCodeState(mId, code) == AKEY_STATE_DOWN;
-    }
-
-    int32_t getAbsoluteAxisValue(int32_t code) {
-        int32_t value;
-        getEventHub()->getAbsoluteAxisValue(mId, code, &value);
-        return value;
-    }
-
-private:
-    InputReaderContext* mContext;
-    int32_t mId;
-    int32_t mControllerNumber;
-    int32_t mGeneration;
-    InputDeviceIdentifier mIdentifier;
-    String8 mAlias;
-    uint32_t mClasses;
-
-    Vector<InputMapper*> mMappers;
-
-    uint32_t mSources;
-    bool mIsExternal;
-    bool mDropUntilNextSync;
-
-    typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
-    int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
-
-    PropertyMap mConfiguration;
-};
-
-
-/* Keeps track of the state of mouse or touch pad buttons. */
-class CursorButtonAccumulator {
-public:
-    CursorButtonAccumulator();
-    void reset(InputDevice* device);
-
-    void process(const RawEvent* rawEvent);
-
-    uint32_t getButtonState() const;
-
-private:
-    bool mBtnLeft;
-    bool mBtnRight;
-    bool mBtnMiddle;
-    bool mBtnBack;
-    bool mBtnSide;
-    bool mBtnForward;
-    bool mBtnExtra;
-    bool mBtnTask;
-
-    void clearButtons();
-};
-
-
-/* Keeps track of cursor movements. */
-
-class CursorMotionAccumulator {
-public:
-    CursorMotionAccumulator();
-    void reset(InputDevice* device);
-
-    void process(const RawEvent* rawEvent);
-    void finishSync();
-
-    inline int32_t getRelativeX() const { return mRelX; }
-    inline int32_t getRelativeY() const { return mRelY; }
-
-private:
-    int32_t mRelX;
-    int32_t mRelY;
-
-    void clearRelativeAxes();
-};
-
-
-/* Keeps track of cursor scrolling motions. */
-
-class CursorScrollAccumulator {
-public:
-    CursorScrollAccumulator();
-    void configure(InputDevice* device);
-    void reset(InputDevice* device);
-
-    void process(const RawEvent* rawEvent);
-    void finishSync();
-
-    inline bool haveRelativeVWheel() const { return mHaveRelWheel; }
-    inline bool haveRelativeHWheel() const { return mHaveRelHWheel; }
-
-    inline int32_t getRelativeX() const { return mRelX; }
-    inline int32_t getRelativeY() const { return mRelY; }
-    inline int32_t getRelativeVWheel() const { return mRelWheel; }
-    inline int32_t getRelativeHWheel() const { return mRelHWheel; }
-
-private:
-    bool mHaveRelWheel;
-    bool mHaveRelHWheel;
-
-    int32_t mRelX;
-    int32_t mRelY;
-    int32_t mRelWheel;
-    int32_t mRelHWheel;
-
-    void clearRelativeAxes();
-};
-
-
-/* Keeps track of the state of touch, stylus and tool buttons. */
-class TouchButtonAccumulator {
-public:
-    TouchButtonAccumulator();
-    void configure(InputDevice* device);
-    void reset(InputDevice* device);
-
-    void process(const RawEvent* rawEvent);
-
-    uint32_t getButtonState() const;
-    int32_t getToolType() const;
-    bool isToolActive() const;
-    bool isHovering() const;
-    bool hasStylus() const;
-
-private:
-    bool mHaveBtnTouch;
-    bool mHaveStylus;
-
-    bool mBtnTouch;
-    bool mBtnStylus;
-    bool mBtnStylus2;
-    bool mBtnToolFinger;
-    bool mBtnToolPen;
-    bool mBtnToolRubber;
-    bool mBtnToolBrush;
-    bool mBtnToolPencil;
-    bool mBtnToolAirbrush;
-    bool mBtnToolMouse;
-    bool mBtnToolLens;
-    bool mBtnToolDoubleTap;
-    bool mBtnToolTripleTap;
-    bool mBtnToolQuadTap;
-
-    void clearButtons();
-};
-
-
-/* Raw axis information from the driver. */
-struct RawPointerAxes {
-    RawAbsoluteAxisInfo x;
-    RawAbsoluteAxisInfo y;
-    RawAbsoluteAxisInfo pressure;
-    RawAbsoluteAxisInfo touchMajor;
-    RawAbsoluteAxisInfo touchMinor;
-    RawAbsoluteAxisInfo toolMajor;
-    RawAbsoluteAxisInfo toolMinor;
-    RawAbsoluteAxisInfo orientation;
-    RawAbsoluteAxisInfo distance;
-    RawAbsoluteAxisInfo tiltX;
-    RawAbsoluteAxisInfo tiltY;
-    RawAbsoluteAxisInfo trackingId;
-    RawAbsoluteAxisInfo slot;
-
-    RawPointerAxes();
-    void clear();
-};
-
-
-/* Raw data for a collection of pointers including a pointer id mapping table. */
-struct RawPointerData {
-    struct Pointer {
-        uint32_t id;
-        int32_t x;
-        int32_t y;
-        int32_t pressure;
-        int32_t touchMajor;
-        int32_t touchMinor;
-        int32_t toolMajor;
-        int32_t toolMinor;
-        int32_t orientation;
-        int32_t distance;
-        int32_t tiltX;
-        int32_t tiltY;
-        int32_t toolType; // a fully decoded AMOTION_EVENT_TOOL_TYPE constant
-        bool isHovering;
-    };
-
-    uint32_t pointerCount;
-    Pointer pointers[MAX_POINTERS];
-    BitSet32 hoveringIdBits, touchingIdBits;
-    uint32_t idToIndex[MAX_POINTER_ID + 1];
-
-    RawPointerData();
-    void clear();
-    void copyFrom(const RawPointerData& other);
-    void getCentroidOfTouchingPointers(float* outX, float* outY) const;
-
-    inline void markIdBit(uint32_t id, bool isHovering) {
-        if (isHovering) {
-            hoveringIdBits.markBit(id);
-        } else {
-            touchingIdBits.markBit(id);
-        }
-    }
-
-    inline void clearIdBits() {
-        hoveringIdBits.clear();
-        touchingIdBits.clear();
-    }
-
-    inline const Pointer& pointerForId(uint32_t id) const {
-        return pointers[idToIndex[id]];
-    }
-
-    inline bool isHovering(uint32_t pointerIndex) {
-        return pointers[pointerIndex].isHovering;
-    }
-};
-
-
-/* Cooked data for a collection of pointers including a pointer id mapping table. */
-struct CookedPointerData {
-    uint32_t pointerCount;
-    PointerProperties pointerProperties[MAX_POINTERS];
-    PointerCoords pointerCoords[MAX_POINTERS];
-    BitSet32 hoveringIdBits, touchingIdBits;
-    uint32_t idToIndex[MAX_POINTER_ID + 1];
-
-    CookedPointerData();
-    void clear();
-    void copyFrom(const CookedPointerData& other);
-
-    inline const PointerCoords& pointerCoordsForId(uint32_t id) const {
-        return pointerCoords[idToIndex[id]];
-    }
-
-    inline bool isHovering(uint32_t pointerIndex) {
-        return hoveringIdBits.hasBit(pointerProperties[pointerIndex].id);
-    }
-};
-
-
-/* Keeps track of the state of single-touch protocol. */
-class SingleTouchMotionAccumulator {
-public:
-    SingleTouchMotionAccumulator();
-
-    void process(const RawEvent* rawEvent);
-    void reset(InputDevice* device);
-
-    inline int32_t getAbsoluteX() const { return mAbsX; }
-    inline int32_t getAbsoluteY() const { return mAbsY; }
-    inline int32_t getAbsolutePressure() const { return mAbsPressure; }
-    inline int32_t getAbsoluteToolWidth() const { return mAbsToolWidth; }
-    inline int32_t getAbsoluteDistance() const { return mAbsDistance; }
-    inline int32_t getAbsoluteTiltX() const { return mAbsTiltX; }
-    inline int32_t getAbsoluteTiltY() const { return mAbsTiltY; }
-
-private:
-    int32_t mAbsX;
-    int32_t mAbsY;
-    int32_t mAbsPressure;
-    int32_t mAbsToolWidth;
-    int32_t mAbsDistance;
-    int32_t mAbsTiltX;
-    int32_t mAbsTiltY;
-
-    void clearAbsoluteAxes();
-};
-
-
-/* Keeps track of the state of multi-touch protocol. */
-class MultiTouchMotionAccumulator {
-public:
-    class Slot {
-    public:
-        inline bool isInUse() const { return mInUse; }
-        inline int32_t getX() const { return mAbsMTPositionX; }
-        inline int32_t getY() const { return mAbsMTPositionY; }
-        inline int32_t getTouchMajor() const { return mAbsMTTouchMajor; }
-        inline int32_t getTouchMinor() const {
-            return mHaveAbsMTTouchMinor ? mAbsMTTouchMinor : mAbsMTTouchMajor; }
-        inline int32_t getToolMajor() const { return mAbsMTWidthMajor; }
-        inline int32_t getToolMinor() const {
-            return mHaveAbsMTWidthMinor ? mAbsMTWidthMinor : mAbsMTWidthMajor; }
-        inline int32_t getOrientation() const { return mAbsMTOrientation; }
-        inline int32_t getTrackingId() const { return mAbsMTTrackingId; }
-        inline int32_t getPressure() const { return mAbsMTPressure; }
-        inline int32_t getDistance() const { return mAbsMTDistance; }
-        inline int32_t getToolType() const;
-
-    private:
-        friend class MultiTouchMotionAccumulator;
-
-        bool mInUse;
-        bool mHaveAbsMTTouchMinor;
-        bool mHaveAbsMTWidthMinor;
-        bool mHaveAbsMTToolType;
-
-        int32_t mAbsMTPositionX;
-        int32_t mAbsMTPositionY;
-        int32_t mAbsMTTouchMajor;
-        int32_t mAbsMTTouchMinor;
-        int32_t mAbsMTWidthMajor;
-        int32_t mAbsMTWidthMinor;
-        int32_t mAbsMTOrientation;
-        int32_t mAbsMTTrackingId;
-        int32_t mAbsMTPressure;
-        int32_t mAbsMTDistance;
-        int32_t mAbsMTToolType;
-
-        Slot();
-        void clear();
-    };
-
-    MultiTouchMotionAccumulator();
-    ~MultiTouchMotionAccumulator();
-
-    void configure(InputDevice* device, size_t slotCount, bool usingSlotsProtocol);
-    void reset(InputDevice* device);
-    void process(const RawEvent* rawEvent);
-    void finishSync();
-    bool hasStylus() const;
-
-    inline size_t getSlotCount() const { return mSlotCount; }
-    inline const Slot* getSlot(size_t index) const { return &mSlots[index]; }
-
-private:
-    int32_t mCurrentSlot;
-    Slot* mSlots;
-    size_t mSlotCount;
-    bool mUsingSlotsProtocol;
-    bool mHaveStylus;
-
-    void clearSlots(int32_t initialSlot);
-};
-
-
-/* An input mapper transforms raw input events into cooked event data.
- * A single input device can have multiple associated input mappers in order to interpret
- * different classes of events.
- *
- * InputMapper lifecycle:
- * - create
- * - configure with 0 changes
- * - reset
- * - process, process, process (may occasionally reconfigure with non-zero changes or reset)
- * - reset
- * - destroy
- */
-class InputMapper {
-public:
-    InputMapper(InputDevice* device);
-    virtual ~InputMapper();
-
-    inline InputDevice* getDevice() { return mDevice; }
-    inline int32_t getDeviceId() { return mDevice->getId(); }
-    inline const String8 getDeviceName() { return mDevice->getName(); }
-    inline InputReaderContext* getContext() { return mContext; }
-    inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
-    inline InputListenerInterface* getListener() { return mContext->getListener(); }
-    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
-
-    virtual uint32_t getSources() = 0;
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
-    virtual void reset(nsecs_t when);
-    virtual void process(const RawEvent* rawEvent) = 0;
-    virtual void timeoutExpired(nsecs_t when);
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-    virtual void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
-            int32_t token);
-    virtual void cancelVibrate(int32_t token);
-
-    virtual int32_t getMetaState();
-
-    virtual void fadePointer();
-
-protected:
-    InputDevice* mDevice;
-    InputReaderContext* mContext;
-
-    status_t getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo);
-    void bumpGeneration();
-
-    static void dumpRawAbsoluteAxisInfo(String8& dump,
-            const RawAbsoluteAxisInfo& axis, const char* name);
-};
-
-
-class SwitchInputMapper : public InputMapper {
-public:
-    SwitchInputMapper(InputDevice* device);
-    virtual ~SwitchInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
-
-private:
-    uint32_t mUpdatedSwitchValues;
-    uint32_t mUpdatedSwitchMask;
-
-    void processSwitch(int32_t switchCode, int32_t switchValue);
-    void sync(nsecs_t when);
-};
-
-
-class VibratorInputMapper : public InputMapper {
-public:
-    VibratorInputMapper(InputDevice* device);
-    virtual ~VibratorInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual void vibrate(const nsecs_t* pattern, size_t patternSize, ssize_t repeat,
-            int32_t token);
-    virtual void cancelVibrate(int32_t token);
-    virtual void timeoutExpired(nsecs_t when);
-    virtual void dump(String8& dump);
-
-private:
-    bool mVibrating;
-    nsecs_t mPattern[MAX_VIBRATE_PATTERN_SIZE];
-    size_t mPatternSize;
-    ssize_t mRepeat;
-    int32_t mToken;
-    ssize_t mIndex;
-    nsecs_t mNextStepTime;
-
-    void nextStep();
-    void stopVibrating();
-};
-
-
-class KeyboardInputMapper : public InputMapper {
-public:
-    KeyboardInputMapper(InputDevice* device, uint32_t source, int32_t keyboardType);
-    virtual ~KeyboardInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
-    virtual void reset(nsecs_t when);
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-
-    virtual int32_t getMetaState();
-
-private:
-    struct KeyDown {
-        int32_t keyCode;
-        int32_t scanCode;
-    };
-
-    uint32_t mSource;
-    int32_t mKeyboardType;
-
-    int32_t mOrientation; // orientation for dpad keys
-
-    Vector<KeyDown> mKeyDowns; // keys that are down
-    int32_t mMetaState;
-    nsecs_t mDownTime; // time of most recent key down
-
-    int32_t mCurrentHidUsage; // most recent HID usage seen this packet, or 0 if none
-
-    struct LedState {
-        bool avail; // led is available
-        bool on;    // we think the led is currently on
-    };
-    LedState mCapsLockLedState;
-    LedState mNumLockLedState;
-    LedState mScrollLockLedState;
-
-    // Immutable configuration parameters.
-    struct Parameters {
-        bool hasAssociatedDisplay;
-        bool orientationAware;
-        bool handlesKeyRepeat;
-    } mParameters;
-
-    void configureParameters();
-    void dumpParameters(String8& dump);
-
-    bool isKeyboardOrGamepadKey(int32_t scanCode);
-
-    void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
-            uint32_t policyFlags);
-
-    ssize_t findKeyDown(int32_t scanCode);
-
-    void resetLedState();
-    void initializeLedState(LedState& ledState, int32_t led);
-    void updateLedState(bool reset);
-    void updateLedStateForModifier(LedState& ledState, int32_t led,
-            int32_t modifier, bool reset);
-};
-
-
-class CursorInputMapper : public InputMapper {
-public:
-    CursorInputMapper(InputDevice* device);
-    virtual ~CursorInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
-    virtual void reset(nsecs_t when);
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-
-    virtual void fadePointer();
-
-private:
-    // Amount that trackball needs to move in order to generate a key event.
-    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
-
-    // Immutable configuration parameters.
-    struct Parameters {
-        enum Mode {
-            MODE_POINTER,
-            MODE_NAVIGATION,
-        };
-
-        Mode mode;
-        bool hasAssociatedDisplay;
-        bool orientationAware;
-    } mParameters;
-
-    CursorButtonAccumulator mCursorButtonAccumulator;
-    CursorMotionAccumulator mCursorMotionAccumulator;
-    CursorScrollAccumulator mCursorScrollAccumulator;
-
-    int32_t mSource;
-    float mXScale;
-    float mYScale;
-    float mXPrecision;
-    float mYPrecision;
-
-    float mVWheelScale;
-    float mHWheelScale;
-
-    // Velocity controls for mouse pointer and wheel movements.
-    // The controls for X and Y wheel movements are separate to keep them decoupled.
-    VelocityControl mPointerVelocityControl;
-    VelocityControl mWheelXVelocityControl;
-    VelocityControl mWheelYVelocityControl;
-
-    int32_t mOrientation;
-
-    sp<PointerControllerInterface> mPointerController;
-
-    int32_t mButtonState;
-    nsecs_t mDownTime;
-
-    void configureParameters();
-    void dumpParameters(String8& dump);
-
-    void sync(nsecs_t when);
-};
-
-
-class TouchInputMapper : public InputMapper {
-public:
-    TouchInputMapper(InputDevice* device);
-    virtual ~TouchInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
-    virtual void reset(nsecs_t when);
-    virtual void process(const RawEvent* rawEvent);
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags);
-
-    virtual void fadePointer();
-    virtual void timeoutExpired(nsecs_t when);
-
-protected:
-    CursorButtonAccumulator mCursorButtonAccumulator;
-    CursorScrollAccumulator mCursorScrollAccumulator;
-    TouchButtonAccumulator mTouchButtonAccumulator;
-
-    struct VirtualKey {
-        int32_t keyCode;
-        int32_t scanCode;
-        uint32_t flags;
-
-        // computed hit box, specified in touch screen coords based on known display size
-        int32_t hitLeft;
-        int32_t hitTop;
-        int32_t hitRight;
-        int32_t hitBottom;
-
-        inline bool isHit(int32_t x, int32_t y) const {
-            return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
-        }
-    };
-
-    // Input sources and device mode.
-    uint32_t mSource;
-
-    enum DeviceMode {
-        DEVICE_MODE_DISABLED, // input is disabled
-        DEVICE_MODE_DIRECT, // direct mapping (touchscreen)
-        DEVICE_MODE_UNSCALED, // unscaled mapping (touchpad)
-        DEVICE_MODE_NAVIGATION, // unscaled mapping with assist gesture (touch navigation)
-        DEVICE_MODE_POINTER, // pointer mapping (pointer)
-    };
-    DeviceMode mDeviceMode;
-
-    // The reader's configuration.
-    InputReaderConfiguration mConfig;
-
-    // Immutable configuration parameters.
-    struct Parameters {
-        enum DeviceType {
-            DEVICE_TYPE_TOUCH_SCREEN,
-            DEVICE_TYPE_TOUCH_PAD,
-            DEVICE_TYPE_TOUCH_NAVIGATION,
-            DEVICE_TYPE_POINTER,
-        };
-
-        DeviceType deviceType;
-        bool hasAssociatedDisplay;
-        bool associatedDisplayIsExternal;
-        bool orientationAware;
-        bool hasButtonUnderPad;
-
-        enum GestureMode {
-            GESTURE_MODE_POINTER,
-            GESTURE_MODE_SPOTS,
-        };
-        GestureMode gestureMode;
-
-        bool wake;
-    } mParameters;
-
-    // Immutable calibration parameters in parsed form.
-    struct Calibration {
-        // Size
-        enum SizeCalibration {
-            SIZE_CALIBRATION_DEFAULT,
-            SIZE_CALIBRATION_NONE,
-            SIZE_CALIBRATION_GEOMETRIC,
-            SIZE_CALIBRATION_DIAMETER,
-            SIZE_CALIBRATION_BOX,
-            SIZE_CALIBRATION_AREA,
-        };
-
-        SizeCalibration sizeCalibration;
-
-        bool haveSizeScale;
-        float sizeScale;
-        bool haveSizeBias;
-        float sizeBias;
-        bool haveSizeIsSummed;
-        bool sizeIsSummed;
-
-        // Pressure
-        enum PressureCalibration {
-            PRESSURE_CALIBRATION_DEFAULT,
-            PRESSURE_CALIBRATION_NONE,
-            PRESSURE_CALIBRATION_PHYSICAL,
-            PRESSURE_CALIBRATION_AMPLITUDE,
-        };
-
-        PressureCalibration pressureCalibration;
-        bool havePressureScale;
-        float pressureScale;
-
-        // Orientation
-        enum OrientationCalibration {
-            ORIENTATION_CALIBRATION_DEFAULT,
-            ORIENTATION_CALIBRATION_NONE,
-            ORIENTATION_CALIBRATION_INTERPOLATED,
-            ORIENTATION_CALIBRATION_VECTOR,
-        };
-
-        OrientationCalibration orientationCalibration;
-
-        // Distance
-        enum DistanceCalibration {
-            DISTANCE_CALIBRATION_DEFAULT,
-            DISTANCE_CALIBRATION_NONE,
-            DISTANCE_CALIBRATION_SCALED,
-        };
-
-        DistanceCalibration distanceCalibration;
-        bool haveDistanceScale;
-        float distanceScale;
-
-        enum CoverageCalibration {
-            COVERAGE_CALIBRATION_DEFAULT,
-            COVERAGE_CALIBRATION_NONE,
-            COVERAGE_CALIBRATION_BOX,
-        };
-
-        CoverageCalibration coverageCalibration;
-
-        inline void applySizeScaleAndBias(float* outSize) const {
-            if (haveSizeScale) {
-                *outSize *= sizeScale;
-            }
-            if (haveSizeBias) {
-                *outSize += sizeBias;
-            }
-            if (*outSize < 0) {
-                *outSize = 0;
-            }
-        }
-    } mCalibration;
-
-    // Raw pointer axis information from the driver.
-    RawPointerAxes mRawPointerAxes;
-
-    // Raw pointer sample data.
-    RawPointerData mCurrentRawPointerData;
-    RawPointerData mLastRawPointerData;
-
-    // Cooked pointer sample data.
-    CookedPointerData mCurrentCookedPointerData;
-    CookedPointerData mLastCookedPointerData;
-
-    // Button state.
-    int32_t mCurrentButtonState;
-    int32_t mLastButtonState;
-
-    // Scroll state.
-    int32_t mCurrentRawVScroll;
-    int32_t mCurrentRawHScroll;
-
-    // Id bits used to differentiate fingers, stylus and mouse tools.
-    BitSet32 mCurrentFingerIdBits; // finger or unknown
-    BitSet32 mLastFingerIdBits;
-    BitSet32 mCurrentStylusIdBits; // stylus or eraser
-    BitSet32 mLastStylusIdBits;
-    BitSet32 mCurrentMouseIdBits; // mouse or lens
-    BitSet32 mLastMouseIdBits;
-
-    // True if we sent a HOVER_ENTER event.
-    bool mSentHoverEnter;
-
-    // The time the primary pointer last went down.
-    nsecs_t mDownTime;
-
-    // The pointer controller, or null if the device is not a pointer.
-    sp<PointerControllerInterface> mPointerController;
-
-    Vector<VirtualKey> mVirtualKeys;
-
-    virtual void configureParameters();
-    virtual void dumpParameters(String8& dump);
-    virtual void configureRawPointerAxes();
-    virtual void dumpRawPointerAxes(String8& dump);
-    virtual void configureSurface(nsecs_t when, bool* outResetNeeded);
-    virtual void dumpSurface(String8& dump);
-    virtual void configureVirtualKeys();
-    virtual void dumpVirtualKeys(String8& dump);
-    virtual void parseCalibration();
-    virtual void resolveCalibration();
-    virtual void dumpCalibration(String8& dump);
-    virtual bool hasStylus() const = 0;
-
-    virtual void syncTouch(nsecs_t when, bool* outHavePointerIds) = 0;
-
-private:
-    // The current viewport.
-    // The components of the viewport are specified in the display's rotated orientation.
-    DisplayViewport mViewport;
-
-    // The surface orientation, width and height set by configureSurface().
-    // The width and height are derived from the viewport but are specified
-    // in the natural orientation.
-    // The surface origin specifies how the surface coordinates should be translated
-    // to align with the logical display coordinate space.
-    // The orientation may be different from the viewport orientation as it specifies
-    // the rotation of the surface coordinates required to produce the viewport's
-    // requested orientation, so it will depend on whether the device is orientation aware.
-    int32_t mSurfaceWidth;
-    int32_t mSurfaceHeight;
-    int32_t mSurfaceLeft;
-    int32_t mSurfaceTop;
-    int32_t mSurfaceOrientation;
-
-    // Translation and scaling factors, orientation-independent.
-    float mXTranslate;
-    float mXScale;
-    float mXPrecision;
-
-    float mYTranslate;
-    float mYScale;
-    float mYPrecision;
-
-    float mGeometricScale;
-
-    float mPressureScale;
-
-    float mSizeScale;
-
-    float mOrientationScale;
-
-    float mDistanceScale;
-
-    bool mHaveTilt;
-    float mTiltXCenter;
-    float mTiltXScale;
-    float mTiltYCenter;
-    float mTiltYScale;
-
-    // Oriented motion ranges for input device info.
-    struct OrientedRanges {
-        InputDeviceInfo::MotionRange x;
-        InputDeviceInfo::MotionRange y;
-        InputDeviceInfo::MotionRange pressure;
-
-        bool haveSize;
-        InputDeviceInfo::MotionRange size;
-
-        bool haveTouchSize;
-        InputDeviceInfo::MotionRange touchMajor;
-        InputDeviceInfo::MotionRange touchMinor;
-
-        bool haveToolSize;
-        InputDeviceInfo::MotionRange toolMajor;
-        InputDeviceInfo::MotionRange toolMinor;
-
-        bool haveOrientation;
-        InputDeviceInfo::MotionRange orientation;
-
-        bool haveDistance;
-        InputDeviceInfo::MotionRange distance;
-
-        bool haveTilt;
-        InputDeviceInfo::MotionRange tilt;
-
-        OrientedRanges() {
-            clear();
-        }
-
-        void clear() {
-            haveSize = false;
-            haveTouchSize = false;
-            haveToolSize = false;
-            haveOrientation = false;
-            haveDistance = false;
-            haveTilt = false;
-        }
-    } mOrientedRanges;
-
-    // Oriented dimensions and precision.
-    float mOrientedXPrecision;
-    float mOrientedYPrecision;
-
-    struct CurrentVirtualKeyState {
-        bool down;
-        bool ignored;
-        nsecs_t downTime;
-        int32_t keyCode;
-        int32_t scanCode;
-    } mCurrentVirtualKey;
-
-    // Scale factor for gesture or mouse based pointer movements.
-    float mPointerXMovementScale;
-    float mPointerYMovementScale;
-
-    // Scale factor for gesture based zooming and other freeform motions.
-    float mPointerXZoomScale;
-    float mPointerYZoomScale;
-
-    // The maximum swipe width.
-    float mPointerGestureMaxSwipeWidth;
-
-    struct PointerDistanceHeapElement {
-        uint32_t currentPointerIndex : 8;
-        uint32_t lastPointerIndex : 8;
-        uint64_t distance : 48; // squared distance
-    };
-
-    enum PointerUsage {
-        POINTER_USAGE_NONE,
-        POINTER_USAGE_GESTURES,
-        POINTER_USAGE_STYLUS,
-        POINTER_USAGE_MOUSE,
-    };
-    PointerUsage mPointerUsage;
-
-    struct PointerGesture {
-        enum Mode {
-            // No fingers, button is not pressed.
-            // Nothing happening.
-            NEUTRAL,
-
-            // No fingers, button is not pressed.
-            // Tap detected.
-            // Emits DOWN and UP events at the pointer location.
-            TAP,
-
-            // Exactly one finger dragging following a tap.
-            // Pointer follows the active finger.
-            // Emits DOWN, MOVE and UP events at the pointer location.
-            //
-            // Detect double-taps when the finger goes up while in TAP_DRAG mode.
-            TAP_DRAG,
-
-            // Button is pressed.
-            // Pointer follows the active finger if there is one.  Other fingers are ignored.
-            // Emits DOWN, MOVE and UP events at the pointer location.
-            BUTTON_CLICK_OR_DRAG,
-
-            // Exactly one finger, button is not pressed.
-            // Pointer follows the active finger.
-            // Emits HOVER_MOVE events at the pointer location.
-            //
-            // Detect taps when the finger goes up while in HOVER mode.
-            HOVER,
-
-            // Exactly two fingers but neither have moved enough to clearly indicate
-            // whether a swipe or freeform gesture was intended.  We consider the
-            // pointer to be pressed so this enables clicking or long-pressing on buttons.
-            // Pointer does not move.
-            // Emits DOWN, MOVE and UP events with a single stationary pointer coordinate.
-            PRESS,
-
-            // Exactly two fingers moving in the same direction, button is not pressed.
-            // Pointer does not move.
-            // Emits DOWN, MOVE and UP events with a single pointer coordinate that
-            // follows the midpoint between both fingers.
-            SWIPE,
-
-            // Two or more fingers moving in arbitrary directions, button is not pressed.
-            // Pointer does not move.
-            // Emits DOWN, POINTER_DOWN, MOVE, POINTER_UP and UP events that follow
-            // each finger individually relative to the initial centroid of the finger.
-            FREEFORM,
-
-            // Waiting for quiet time to end before starting the next gesture.
-            QUIET,
-        };
-
-        // Time the first finger went down.
-        nsecs_t firstTouchTime;
-
-        // The active pointer id from the raw touch data.
-        int32_t activeTouchId; // -1 if none
-
-        // The active pointer id from the gesture last delivered to the application.
-        int32_t activeGestureId; // -1 if none
-
-        // Pointer coords and ids for the current and previous pointer gesture.
-        Mode currentGestureMode;
-        BitSet32 currentGestureIdBits;
-        uint32_t currentGestureIdToIndex[MAX_POINTER_ID + 1];
-        PointerProperties currentGestureProperties[MAX_POINTERS];
-        PointerCoords currentGestureCoords[MAX_POINTERS];
-
-        Mode lastGestureMode;
-        BitSet32 lastGestureIdBits;
-        uint32_t lastGestureIdToIndex[MAX_POINTER_ID + 1];
-        PointerProperties lastGestureProperties[MAX_POINTERS];
-        PointerCoords lastGestureCoords[MAX_POINTERS];
-
-        // Time the pointer gesture last went down.
-        nsecs_t downTime;
-
-        // Time when the pointer went down for a TAP.
-        nsecs_t tapDownTime;
-
-        // Time when the pointer went up for a TAP.
-        nsecs_t tapUpTime;
-
-        // Location of initial tap.
-        float tapX, tapY;
-
-        // Time we started waiting for quiescence.
-        nsecs_t quietTime;
-
-        // Reference points for multitouch gestures.
-        float referenceTouchX;    // reference touch X/Y coordinates in surface units
-        float referenceTouchY;
-        float referenceGestureX;  // reference gesture X/Y coordinates in pixels
-        float referenceGestureY;
-
-        // Distance that each pointer has traveled which has not yet been
-        // subsumed into the reference gesture position.
-        BitSet32 referenceIdBits;
-        struct Delta {
-            float dx, dy;
-        };
-        Delta referenceDeltas[MAX_POINTER_ID + 1];
-
-        // Describes how touch ids are mapped to gesture ids for freeform gestures.
-        uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1];
-
-        // A velocity tracker for determining whether to switch active pointers during drags.
-        VelocityTracker velocityTracker;
-
-        void reset() {
-            firstTouchTime = LLONG_MIN;
-            activeTouchId = -1;
-            activeGestureId = -1;
-            currentGestureMode = NEUTRAL;
-            currentGestureIdBits.clear();
-            lastGestureMode = NEUTRAL;
-            lastGestureIdBits.clear();
-            downTime = 0;
-            velocityTracker.clear();
-            resetTap();
-            resetQuietTime();
-        }
-
-        void resetTap() {
-            tapDownTime = LLONG_MIN;
-            tapUpTime = LLONG_MIN;
-        }
-
-        void resetQuietTime() {
-            quietTime = LLONG_MIN;
-        }
-    } mPointerGesture;
-
-    struct PointerSimple {
-        PointerCoords currentCoords;
-        PointerProperties currentProperties;
-        PointerCoords lastCoords;
-        PointerProperties lastProperties;
-
-        // True if the pointer is down.
-        bool down;
-
-        // True if the pointer is hovering.
-        bool hovering;
-
-        // Time the pointer last went down.
-        nsecs_t downTime;
-
-        void reset() {
-            currentCoords.clear();
-            currentProperties.clear();
-            lastCoords.clear();
-            lastProperties.clear();
-            down = false;
-            hovering = false;
-            downTime = 0;
-        }
-    } mPointerSimple;
-
-    // The pointer and scroll velocity controls.
-    VelocityControl mPointerVelocityControl;
-    VelocityControl mWheelXVelocityControl;
-    VelocityControl mWheelYVelocityControl;
-
-    void sync(nsecs_t when);
-
-    bool consumeRawTouches(nsecs_t when, uint32_t policyFlags);
-    void dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
-            int32_t keyEventAction, int32_t keyEventFlags);
-
-    void dispatchTouches(nsecs_t when, uint32_t policyFlags);
-    void dispatchHoverExit(nsecs_t when, uint32_t policyFlags);
-    void dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags);
-    void cookPointerData();
-
-    void dispatchPointerUsage(nsecs_t when, uint32_t policyFlags, PointerUsage pointerUsage);
-    void abortPointerUsage(nsecs_t when, uint32_t policyFlags);
-
-    void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout);
-    void abortPointerGestures(nsecs_t when, uint32_t policyFlags);
-    bool preparePointerGestures(nsecs_t when,
-            bool* outCancelPreviousGesture, bool* outFinishPreviousGesture,
-            bool isTimeout);
-
-    void dispatchPointerStylus(nsecs_t when, uint32_t policyFlags);
-    void abortPointerStylus(nsecs_t when, uint32_t policyFlags);
-
-    void dispatchPointerMouse(nsecs_t when, uint32_t policyFlags);
-    void abortPointerMouse(nsecs_t when, uint32_t policyFlags);
-
-    void dispatchPointerSimple(nsecs_t when, uint32_t policyFlags,
-            bool down, bool hovering);
-    void abortPointerSimple(nsecs_t when, uint32_t policyFlags);
-
-    // Dispatches a motion event.
-    // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the
-    // method will take care of setting the index and transmuting the action to DOWN or UP
-    // it is the first / last pointer to go down / up.
-    void dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source,
-            int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
-            int32_t edgeFlags,
-            const PointerProperties* properties, const PointerCoords* coords,
-            const uint32_t* idToIndex, BitSet32 idBits,
-            int32_t changedId, float xPrecision, float yPrecision, nsecs_t downTime);
-
-    // Updates pointer coords and properties for pointers with specified ids that have moved.
-    // Returns true if any of them changed.
-    bool updateMovedPointers(const PointerProperties* inProperties,
-            const PointerCoords* inCoords, const uint32_t* inIdToIndex,
-            PointerProperties* outProperties, PointerCoords* outCoords,
-            const uint32_t* outIdToIndex, BitSet32 idBits) const;
-
-    bool isPointInsideSurface(int32_t x, int32_t y);
-    const VirtualKey* findVirtualKeyHit(int32_t x, int32_t y);
-
-    void assignPointerIds();
-};
-
-
-class SingleTouchInputMapper : public TouchInputMapper {
-public:
-    SingleTouchInputMapper(InputDevice* device);
-    virtual ~SingleTouchInputMapper();
-
-    virtual void reset(nsecs_t when);
-    virtual void process(const RawEvent* rawEvent);
-
-protected:
-    virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
-    virtual void configureRawPointerAxes();
-    virtual bool hasStylus() const;
-
-private:
-    SingleTouchMotionAccumulator mSingleTouchMotionAccumulator;
-};
-
-
-class MultiTouchInputMapper : public TouchInputMapper {
-public:
-    MultiTouchInputMapper(InputDevice* device);
-    virtual ~MultiTouchInputMapper();
-
-    virtual void reset(nsecs_t when);
-    virtual void process(const RawEvent* rawEvent);
-
-protected:
-    virtual void syncTouch(nsecs_t when, bool* outHavePointerIds);
-    virtual void configureRawPointerAxes();
-    virtual bool hasStylus() const;
-
-private:
-    MultiTouchMotionAccumulator mMultiTouchMotionAccumulator;
-
-    // Specifies the pointer id bits that are in use, and their associated tracking id.
-    BitSet32 mPointerIdBits;
-    int32_t mPointerTrackingIdMap[MAX_POINTER_ID + 1];
-};
-
-
-class JoystickInputMapper : public InputMapper {
-public:
-    JoystickInputMapper(InputDevice* device);
-    virtual ~JoystickInputMapper();
-
-    virtual uint32_t getSources();
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
-    virtual void dump(String8& dump);
-    virtual void configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes);
-    virtual void reset(nsecs_t when);
-    virtual void process(const RawEvent* rawEvent);
-
-private:
-    struct Axis {
-        RawAbsoluteAxisInfo rawAxisInfo;
-        AxisInfo axisInfo;
-
-        bool explicitlyMapped; // true if the axis was explicitly assigned an axis id
-
-        float scale;   // scale factor from raw to normalized values
-        float offset;  // offset to add after scaling for normalization
-        float highScale;  // scale factor from raw to normalized values of high split
-        float highOffset; // offset to add after scaling for normalization of high split
-
-        float min;        // normalized inclusive minimum
-        float max;        // normalized inclusive maximum
-        float flat;       // normalized flat region size
-        float fuzz;       // normalized error tolerance
-        float resolution; // normalized resolution in units/mm
-
-        float filter;  // filter out small variations of this size
-        float currentValue; // current value
-        float newValue; // most recent value
-        float highCurrentValue; // current value of high split
-        float highNewValue; // most recent value of high split
-
-        void initialize(const RawAbsoluteAxisInfo& rawAxisInfo, const AxisInfo& axisInfo,
-                bool explicitlyMapped, float scale, float offset,
-                float highScale, float highOffset,
-                float min, float max, float flat, float fuzz, float resolution) {
-            this->rawAxisInfo = rawAxisInfo;
-            this->axisInfo = axisInfo;
-            this->explicitlyMapped = explicitlyMapped;
-            this->scale = scale;
-            this->offset = offset;
-            this->highScale = highScale;
-            this->highOffset = highOffset;
-            this->min = min;
-            this->max = max;
-            this->flat = flat;
-            this->fuzz = fuzz;
-            this->resolution = resolution;
-            this->filter = 0;
-            resetValue();
-        }
-
-        void resetValue() {
-            this->currentValue = 0;
-            this->newValue = 0;
-            this->highCurrentValue = 0;
-            this->highNewValue = 0;
-        }
-    };
-
-    // Axes indexed by raw ABS_* axis index.
-    KeyedVector<int32_t, Axis> mAxes;
-
-    void sync(nsecs_t when, bool force);
-
-    bool haveAxis(int32_t axisId);
-    void pruneAxes(bool ignoreExplicitlyMappedAxes);
-    bool filterAxes(bool force);
-
-    static bool hasValueChangedSignificantly(float filter,
-            float newValue, float currentValue, float min, float max);
-    static bool hasMovedNearerToValueWithinFilteredRange(float filter,
-            float newValue, float currentValue, float thresholdValue);
-
-    static bool isCenteredAxis(int32_t axis);
-    static int32_t getCompatAxis(int32_t axis);
-
-    static void addMotionRange(int32_t axisId, const Axis& axis, InputDeviceInfo* info);
-    static void setPointerCoordsAxisValue(PointerCoords* pointerCoords, int32_t axis,
-            float value);
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_READER_H
diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp
deleted file mode 100644
index fe61918..0000000
--- a/libs/input/InputWindow.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "InputWindow"
-
-#include "InputWindow.h"
-
-#include <cutils/log.h>
-
-namespace android {
-
-// --- InputWindowInfo ---
-
-bool InputWindowInfo::touchableRegionContainsPoint(int32_t x, int32_t y) const {
-    return touchableRegion.contains(x, y);
-}
-
-bool InputWindowInfo::frameContainsPoint(int32_t x, int32_t y) const {
-    return x >= frameLeft && x <= frameRight
-            && y >= frameTop && y <= frameBottom;
-}
-
-bool InputWindowInfo::isTrustedOverlay() const {
-    return layoutParamsType == TYPE_INPUT_METHOD
-            || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
-            || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
-}
-
-bool InputWindowInfo::supportsSplitTouch() const {
-    return layoutParamsFlags & FLAG_SPLIT_TOUCH;
-}
-
-
-// --- InputWindowHandle ---
-
-InputWindowHandle::InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle) :
-    inputApplicationHandle(inputApplicationHandle), mInfo(NULL) {
-}
-
-InputWindowHandle::~InputWindowHandle() {
-    delete mInfo;
-}
-
-void InputWindowHandle::releaseInfo() {
-    if (mInfo) {
-        delete mInfo;
-        mInfo = NULL;
-    }
-}
-
-} // namespace android
diff --git a/libs/input/InputWindow.h b/libs/input/InputWindow.h
deleted file mode 100644
index 28fa7ab..0000000
--- a/libs/input/InputWindow.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UI_INPUT_WINDOW_H
-#define _UI_INPUT_WINDOW_H
-
-#include <input/Input.h>
-#include <input/InputTransport.h>
-#include <utils/RefBase.h>
-#include <utils/Timers.h>
-#include <utils/String8.h>
-
-#include <SkRegion.h>
-
-#include "InputApplication.h"
-
-namespace android {
-
-/*
- * Describes the properties of a window that can receive input.
- */
-struct InputWindowInfo {
-    // Window flags from WindowManager.LayoutParams
-    enum {
-        FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001,
-        FLAG_DIM_BEHIND        = 0x00000002,
-        FLAG_BLUR_BEHIND        = 0x00000004,
-        FLAG_NOT_FOCUSABLE      = 0x00000008,
-        FLAG_NOT_TOUCHABLE      = 0x00000010,
-        FLAG_NOT_TOUCH_MODAL    = 0x00000020,
-        FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040,
-        FLAG_KEEP_SCREEN_ON     = 0x00000080,
-        FLAG_LAYOUT_IN_SCREEN   = 0x00000100,
-        FLAG_LAYOUT_NO_LIMITS   = 0x00000200,
-        FLAG_FULLSCREEN      = 0x00000400,
-        FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800,
-        FLAG_DITHER             = 0x00001000,
-        FLAG_SECURE             = 0x00002000,
-        FLAG_SCALED             = 0x00004000,
-        FLAG_IGNORE_CHEEK_PRESSES    = 0x00008000,
-        FLAG_LAYOUT_INSET_DECOR = 0x00010000,
-        FLAG_ALT_FOCUSABLE_IM = 0x00020000,
-        FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000,
-        FLAG_SHOW_WHEN_LOCKED = 0x00080000,
-        FLAG_SHOW_WALLPAPER = 0x00100000,
-        FLAG_TURN_SCREEN_ON = 0x00200000,
-        FLAG_DISMISS_KEYGUARD = 0x00400000,
-        FLAG_SPLIT_TOUCH = 0x00800000,
-        FLAG_SLIPPERY = 0x20000000,
-        FLAG_NEEDS_MENU_KEY = 0x40000000,
-    };
-
-    // Private Window flags from WindowManager.LayoutParams
-    enum {
-        PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100,
-    };
-
-    // Window types from WindowManager.LayoutParams
-    enum {
-        FIRST_APPLICATION_WINDOW = 1,
-        TYPE_BASE_APPLICATION   = 1,
-        TYPE_APPLICATION        = 2,
-        TYPE_APPLICATION_STARTING = 3,
-        LAST_APPLICATION_WINDOW = 99,
-        FIRST_SUB_WINDOW        = 1000,
-        TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW,
-        TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1,
-        TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2,
-        TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3,
-        TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW+4,
-        LAST_SUB_WINDOW         = 1999,
-        FIRST_SYSTEM_WINDOW     = 2000,
-        TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW,
-        TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1,
-        TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2,
-        TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3,
-        TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4,
-        TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5,
-        TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6,
-        TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7,
-        TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8,
-        TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9,
-        TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10,
-        TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11,
-        TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
-        TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13,
-        TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14,
-        TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15,
-        TYPE_DRAG               = FIRST_SYSTEM_WINDOW+16,
-        TYPE_STATUS_BAR_SUB_PANEL  = FIRST_SYSTEM_WINDOW+17,
-        TYPE_POINTER            = FIRST_SYSTEM_WINDOW+18,
-        TYPE_NAVIGATION_BAR     = FIRST_SYSTEM_WINDOW+19,
-        TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20,
-        TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21,
-        LAST_SYSTEM_WINDOW      = 2999,
-    };
-
-    enum {
-        INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
-        INPUT_FEATURE_NO_INPUT_CHANNEL = 0x00000002,
-        INPUT_FEATURE_DISABLE_USER_ACTIVITY = 0x00000004,
-    };
-
-    sp<InputChannel> inputChannel;
-    String8 name;
-    int32_t layoutParamsFlags;
-    int32_t layoutParamsPrivateFlags;
-    int32_t layoutParamsType;
-    nsecs_t dispatchingTimeout;
-    int32_t frameLeft;
-    int32_t frameTop;
-    int32_t frameRight;
-    int32_t frameBottom;
-    float scaleFactor;
-    SkRegion touchableRegion;
-    bool visible;
-    bool canReceiveKeys;
-    bool hasFocus;
-    bool hasWallpaper;
-    bool paused;
-    int32_t layer;
-    int32_t ownerPid;
-    int32_t ownerUid;
-    int32_t inputFeatures;
-    int32_t displayId;
-
-    bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
-    bool frameContainsPoint(int32_t x, int32_t y) const;
-
-    /* Returns true if the window is of a trusted type that is allowed to silently
-     * overlay other windows for the purpose of implementing the secure views feature.
-     * Trusted overlays, such as IME windows, can partly obscure other windows without causing
-     * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
-     */
-    bool isTrustedOverlay() const;
-
-    bool supportsSplitTouch() const;
-};
-
-
-/*
- * Handle for a window that can receive input.
- *
- * Used by the native input dispatcher to indirectly refer to the window manager objects
- * that describe a window.
- */
-class InputWindowHandle : public RefBase {
-public:
-    const sp<InputApplicationHandle> inputApplicationHandle;
-
-    inline const InputWindowInfo* getInfo() const {
-        return mInfo;
-    }
-
-    inline sp<InputChannel> getInputChannel() const {
-        return mInfo ? mInfo->inputChannel : NULL;
-    }
-
-    inline String8 getName() const {
-        return mInfo ? mInfo->name : String8("<invalid>");
-    }
-
-    inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
-        return mInfo ? mInfo->dispatchingTimeout : defaultValue;
-    }
-
-    /**
-     * Requests that the state of this object be updated to reflect
-     * the most current available information about the application.
-     *
-     * This method should only be called from within the input dispatcher's
-     * critical section.
-     *
-     * Returns true on success, or false if the handle is no longer valid.
-     */
-    virtual bool updateInfo() = 0;
-
-    /**
-     * Releases the storage used by the associated information when it is
-     * no longer needed.
-     */
-    void releaseInfo();
-
-protected:
-    InputWindowHandle(const sp<InputApplicationHandle>& inputApplicationHandle);
-    virtual ~InputWindowHandle();
-
-    InputWindowInfo* mInfo;
-};
-
-} // namespace android
-
-#endif // _UI_INPUT_WINDOW_H
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index 790c0bb..b9e4ce7 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -21,6 +21,7 @@
 
 #include <ui/DisplayInfo.h>
 #include <input/Input.h>
+#include <inputflinger/PointerControllerInterface.h>
 #include <utils/BitSet.h>
 #include <utils/RefBase.h>
 #include <utils/Looper.h>
@@ -30,84 +31,6 @@
 
 namespace android {
 
-/**
- * Interface for tracking a mouse / touch pad pointer and touch pad spots.
- *
- * The spots are sprites on screen that visually represent the positions of
- * fingers
- *
- * The pointer controller is responsible for providing synchronization and for tracking
- * display orientation changes if needed.
- */
-class PointerControllerInterface : public virtual RefBase {
-protected:
-    PointerControllerInterface() { }
-    virtual ~PointerControllerInterface() { }
-
-public:
-    /* Gets the bounds of the region that the pointer can traverse.
-     * Returns true if the bounds are available. */
-    virtual bool getBounds(float* outMinX, float* outMinY,
-            float* outMaxX, float* outMaxY) const = 0;
-
-    /* Move the pointer. */
-    virtual void move(float deltaX, float deltaY) = 0;
-
-    /* Sets a mask that indicates which buttons are pressed. */
-    virtual void setButtonState(int32_t buttonState) = 0;
-
-    /* Gets a mask that indicates which buttons are pressed. */
-    virtual int32_t getButtonState() const = 0;
-
-    /* Sets the absolute location of the pointer. */
-    virtual void setPosition(float x, float y) = 0;
-
-    /* Gets the absolute location of the pointer. */
-    virtual void getPosition(float* outX, float* outY) const = 0;
-
-    enum Transition {
-        // Fade/unfade immediately.
-        TRANSITION_IMMEDIATE,
-        // Fade/unfade gradually.
-        TRANSITION_GRADUAL,
-    };
-
-    /* Fades the pointer out now. */
-    virtual void fade(Transition transition) = 0;
-
-    /* Makes the pointer visible if it has faded out.
-     * The pointer never unfades itself automatically.  This method must be called
-     * by the client whenever the pointer is moved or a button is pressed and it
-     * wants to ensure that the pointer becomes visible again. */
-    virtual void unfade(Transition transition) = 0;
-
-    enum Presentation {
-        // Show the mouse pointer.
-        PRESENTATION_POINTER,
-        // Show spots and a spot anchor in place of the mouse pointer.
-        PRESENTATION_SPOT,
-    };
-
-    /* Sets the mode of the pointer controller. */
-    virtual void setPresentation(Presentation presentation) = 0;
-
-    /* Sets the spots for the current gesture.
-     * The spots are not subject to the inactivity timeout like the pointer
-     * itself it since they are expected to remain visible for so long as
-     * the fingers are on the touch pad.
-     *
-     * The values of the AMOTION_EVENT_AXIS_PRESSURE axis is significant.
-     * For spotCoords, pressure != 0 indicates that the spot's location is being
-     * pressed (not hovering).
-     */
-    virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
-            BitSet32 spotIdBits) = 0;
-
-    /* Removes all spots. */
-    virtual void clearSpots() = 0;
-};
-
-
 /*
  * Pointer resources.
  */
diff --git a/libs/input/SpriteController.cpp b/libs/input/SpriteController.cpp
index fd9c66b..2667a72 100644
--- a/libs/input/SpriteController.cpp
+++ b/libs/input/SpriteController.cpp
@@ -216,12 +216,12 @@
                 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
                 surfaceCanvas.drawBitmap(update.state.icon.bitmap, 0, 0, &paint);
 
-                if (outBuffer.width > uint32_t(update.state.icon.bitmap.width())) {
+                if (outBuffer.width > update.state.icon.bitmap.width()) {
                     paint.setColor(0); // transparent fill color
                     surfaceCanvas.drawRectCoords(update.state.icon.bitmap.width(), 0,
                             outBuffer.width, update.state.icon.bitmap.height(), paint);
                 }
-                if (outBuffer.height > uint32_t(update.state.icon.bitmap.height())) {
+                if (outBuffer.height > update.state.icon.bitmap.height()) {
                     paint.setColor(0); // transparent fill color
                     surfaceCanvas.drawRectCoords(0, update.state.icon.bitmap.height(),
                             outBuffer.width, outBuffer.height, paint);
diff --git a/libs/input/tests/Android.mk b/libs/input/tests/Android.mk
deleted file mode 100644
index 9278f41..0000000
--- a/libs/input/tests/Android.mk
+++ /dev/null
@@ -1,48 +0,0 @@
-# Build the unit tests.
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# Build the unit tests.
-test_src_files := \
-    InputReader_test.cpp \
-    InputDispatcher_test.cpp
-
-shared_libraries := \
-    libcutils \
-    liblog \
-    libandroidfw \
-    libutils \
-    libhardware \
-    libhardware_legacy \
-    libui \
-    libskia \
-    libstlport \
-    libinput \
-    libinputservice
-
-static_libraries := \
-    libgtest \
-    libgtest_main
-
-c_includes := \
-    bionic \
-    bionic/libstdc++/include \
-    external/gtest/include \
-    external/stlport/stlport \
-    external/skia/include/core
-
-module_tags := eng tests
-
-$(foreach file,$(test_src_files), \
-    $(eval include $(CLEAR_VARS)) \
-    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
-    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
-    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
-    $(eval LOCAL_SRC_FILES := $(file)) \
-    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
-    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
-    $(eval include $(BUILD_NATIVE_TEST)) \
-)
-
-# Build the manual test programs.
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/input/tests/InputDispatcher_test.cpp b/libs/input/tests/InputDispatcher_test.cpp
deleted file mode 100644
index fc89a9b..0000000
--- a/libs/input/tests/InputDispatcher_test.cpp
+++ /dev/null
@@ -1,262 +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 "../InputDispatcher.h"
-
-#include <gtest/gtest.h>
-#include <linux/input.h>
-
-namespace android {
-
-// An arbitrary time value.
-static const nsecs_t ARBITRARY_TIME = 1234;
-
-// An arbitrary device id.
-static const int32_t DEVICE_ID = 1;
-
-// An arbitrary display id.
-static const int32_t DISPLAY_ID = 0;
-
-// An arbitrary injector pid / uid pair that has permission to inject events.
-static const int32_t INJECTOR_PID = 999;
-static const int32_t INJECTOR_UID = 1001;
-
-
-// --- FakeInputDispatcherPolicy ---
-
-class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
-    InputDispatcherConfiguration mConfig;
-
-protected:
-    virtual ~FakeInputDispatcherPolicy() {
-    }
-
-public:
-    FakeInputDispatcherPolicy() {
-    }
-
-private:
-    virtual void notifyConfigurationChanged(nsecs_t when) {
-    }
-
-    virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
-            const sp<InputWindowHandle>& inputWindowHandle,
-            const String8& reason) {
-        return 0;
-    }
-
-    virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
-    }
-
-    virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
-        *outConfig = mConfig;
-    }
-
-    virtual bool isKeyRepeatEnabled() {
-        return true;
-    }
-
-    virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
-        return true;
-    }
-
-    virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags) {
-    }
-
-    virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
-    }
-
-    virtual nsecs_t interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
-            const KeyEvent* keyEvent, uint32_t policyFlags) {
-        return 0;
-    }
-
-    virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
-            const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
-        return false;
-    }
-
-    virtual void notifySwitch(nsecs_t when,
-            uint32_t switchValues, uint32_t switchMask, uint32_t policyFlags) {
-    }
-
-    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
-    }
-
-    virtual bool checkInjectEventsPermissionNonReentrant(
-            int32_t injectorPid, int32_t injectorUid) {
-        return false;
-    }
-};
-
-
-// --- InputDispatcherTest ---
-
-class InputDispatcherTest : public testing::Test {
-protected:
-    sp<FakeInputDispatcherPolicy> mFakePolicy;
-    sp<InputDispatcher> mDispatcher;
-
-    virtual void SetUp() {
-        mFakePolicy = new FakeInputDispatcherPolicy();
-        mDispatcher = new InputDispatcher(mFakePolicy);
-    }
-
-    virtual void TearDown() {
-        mFakePolicy.clear();
-        mDispatcher.clear();
-    }
-};
-
-
-TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
-    KeyEvent event;
-
-    // Rejects undefined key actions.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
-            /*action*/ -1, 0,
-            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject key events with undefined action.";
-
-    // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
-            AKEY_EVENT_ACTION_MULTIPLE, 0,
-            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject key events with ACTION_MULTIPLE.";
-}
-
-TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
-    MotionEvent event;
-    PointerProperties pointerProperties[MAX_POINTERS + 1];
-    PointerCoords pointerCoords[MAX_POINTERS + 1];
-    for (int i = 0; i <= MAX_POINTERS; i++) {
-        pointerProperties[i].clear();
-        pointerProperties[i].id = i;
-        pointerCoords[i].clear();
-    }
-
-    // Rejects undefined motion actions.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with undefined action.";
-
-    // Rejects pointer down with invalid index.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with pointer down index too large.";
-
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with pointer down index too small.";
-
-    // Rejects pointer up with invalid index.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with pointer up index too large.";
-
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with pointer up index too small.";
-
-    // Rejects motion events with invalid number of pointers.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 0, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with 0 pointers.";
-
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ MAX_POINTERS + 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with more than MAX_POINTERS pointers.";
-
-    // Rejects motion events with invalid pointer ids.
-    pointerProperties[0].id = -1;
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with pointer ids less than 0.";
-
-    pointerProperties[0].id = MAX_POINTER_ID + 1;
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 1, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
-
-    // Rejects motion events with duplicate pointer ids.
-    pointerProperties[0].id = 1;
-    pointerProperties[1].id = 1;
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
-            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0, 0,
-            ARBITRARY_TIME, ARBITRARY_TIME,
-            /*pointerCount*/ 2, pointerProperties, pointerCoords);
-    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
-            &event, DISPLAY_ID,
-            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0, 0))
-            << "Should reject motion events with duplicate pointer ids.";
-}
-
-} // namespace android
diff --git a/libs/input/tests/InputReader_test.cpp b/libs/input/tests/InputReader_test.cpp
deleted file mode 100644
index aaa973d..0000000
--- a/libs/input/tests/InputReader_test.cpp
+++ /dev/null
@@ -1,5099 +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 "../InputReader.h"
-
-#include <utils/List.h>
-#include <gtest/gtest.h>
-#include <math.h>
-
-namespace android {
-
-// An arbitrary time value.
-static const nsecs_t ARBITRARY_TIME = 1234;
-
-// Arbitrary display properties.
-static const int32_t DISPLAY_ID = 0;
-static const int32_t DISPLAY_WIDTH = 480;
-static const int32_t DISPLAY_HEIGHT = 800;
-
-// Error tolerance for floating point assertions.
-static const float EPSILON = 0.001f;
-
-template<typename T>
-static inline T min(T a, T b) {
-    return a < b ? a : b;
-}
-
-static inline float avg(float x, float y) {
-    return (x + y) / 2;
-}
-
-
-// --- FakePointerController ---
-
-class FakePointerController : public PointerControllerInterface {
-    bool mHaveBounds;
-    float mMinX, mMinY, mMaxX, mMaxY;
-    float mX, mY;
-    int32_t mButtonState;
-
-protected:
-    virtual ~FakePointerController() { }
-
-public:
-    FakePointerController() :
-        mHaveBounds(false), mMinX(0), mMinY(0), mMaxX(0), mMaxY(0), mX(0), mY(0),
-        mButtonState(0) {
-    }
-
-    void setBounds(float minX, float minY, float maxX, float maxY) {
-        mHaveBounds = true;
-        mMinX = minX;
-        mMinY = minY;
-        mMaxX = maxX;
-        mMaxY = maxY;
-    }
-
-    virtual void setPosition(float x, float y) {
-        mX = x;
-        mY = y;
-    }
-
-    virtual void setButtonState(int32_t buttonState) {
-        mButtonState = buttonState;
-    }
-
-    virtual int32_t getButtonState() const {
-        return mButtonState;
-    }
-
-    virtual void getPosition(float* outX, float* outY) const {
-        *outX = mX;
-        *outY = mY;
-    }
-
-private:
-    virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
-        *outMinX = mMinX;
-        *outMinY = mMinY;
-        *outMaxX = mMaxX;
-        *outMaxY = mMaxY;
-        return mHaveBounds;
-    }
-
-    virtual void move(float deltaX, float deltaY) {
-        mX += deltaX;
-        if (mX < mMinX) mX = mMinX;
-        if (mX > mMaxX) mX = mMaxX;
-        mY += deltaY;
-        if (mY < mMinY) mY = mMinY;
-        if (mY > mMaxY) mY = mMaxY;
-    }
-
-    virtual void fade(Transition transition) {
-    }
-
-    virtual void unfade(Transition transition) {
-    }
-
-    virtual void setPresentation(Presentation presentation) {
-    }
-
-    virtual void setSpots(const PointerCoords* spotCoords,
-            const uint32_t* spotIdToIndex, BitSet32 spotIdBits) {
-    }
-
-    virtual void clearSpots() {
-    }
-};
-
-
-// --- FakeInputReaderPolicy ---
-
-class FakeInputReaderPolicy : public InputReaderPolicyInterface {
-    InputReaderConfiguration mConfig;
-    KeyedVector<int32_t, sp<FakePointerController> > mPointerControllers;
-    Vector<InputDeviceInfo> mInputDevices;
-
-protected:
-    virtual ~FakeInputReaderPolicy() { }
-
-public:
-    FakeInputReaderPolicy() {
-    }
-
-    void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) {
-        // Set the size of both the internal and external display at the same time.
-        bool isRotated = (orientation == DISPLAY_ORIENTATION_90
-                || orientation == DISPLAY_ORIENTATION_270);
-        DisplayViewport v;
-        v.displayId = displayId;
-        v.orientation = orientation;
-        v.logicalLeft = 0;
-        v.logicalTop = 0;
-        v.logicalRight = isRotated ? height : width;
-        v.logicalBottom = isRotated ? width : height;
-        v.physicalLeft = 0;
-        v.physicalTop = 0;
-        v.physicalRight = isRotated ? height : width;
-        v.physicalBottom = isRotated ? width : height;
-        v.deviceWidth = isRotated ? height : width;
-        v.deviceHeight = isRotated ? width : height;
-        mConfig.setDisplayInfo(false /*external*/, v);
-        mConfig.setDisplayInfo(true /*external*/, v);
-    }
-
-    void addExcludedDeviceName(const String8& deviceName) {
-        mConfig.excludedDeviceNames.push(deviceName);
-    }
-
-    void setPointerController(int32_t deviceId, const sp<FakePointerController>& controller) {
-        mPointerControllers.add(deviceId, controller);
-    }
-
-    const InputReaderConfiguration* getReaderConfiguration() const {
-        return &mConfig;
-    }
-
-    const Vector<InputDeviceInfo>& getInputDevices() const {
-        return mInputDevices;
-    }
-
-private:
-    virtual void getReaderConfiguration(InputReaderConfiguration* outConfig) {
-        *outConfig = mConfig;
-    }
-
-    virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId) {
-        return mPointerControllers.valueFor(deviceId);
-    }
-
-    virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices) {
-        mInputDevices = inputDevices;
-    }
-
-    virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier) {
-        return NULL;
-    }
-
-    virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier) {
-        return String8::empty();
-    }
-};
-
-
-// --- FakeInputListener ---
-
-class FakeInputListener : public InputListenerInterface {
-private:
-    List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgsQueue;
-    List<NotifyDeviceResetArgs> mNotifyDeviceResetArgsQueue;
-    List<NotifyKeyArgs> mNotifyKeyArgsQueue;
-    List<NotifyMotionArgs> mNotifyMotionArgsQueue;
-    List<NotifySwitchArgs> mNotifySwitchArgsQueue;
-
-protected:
-    virtual ~FakeInputListener() { }
-
-public:
-    FakeInputListener() {
-    }
-
-    void assertNotifyConfigurationChangedWasCalled(
-            NotifyConfigurationChangedArgs* outEventArgs = NULL) {
-        ASSERT_FALSE(mNotifyConfigurationChangedArgsQueue.empty())
-                << "Expected notifyConfigurationChanged() to have been called.";
-        if (outEventArgs) {
-            *outEventArgs = *mNotifyConfigurationChangedArgsQueue.begin();
-        }
-        mNotifyConfigurationChangedArgsQueue.erase(mNotifyConfigurationChangedArgsQueue.begin());
-    }
-
-    void assertNotifyDeviceResetWasCalled(
-            NotifyDeviceResetArgs* outEventArgs = NULL) {
-        ASSERT_FALSE(mNotifyDeviceResetArgsQueue.empty())
-                << "Expected notifyDeviceReset() to have been called.";
-        if (outEventArgs) {
-            *outEventArgs = *mNotifyDeviceResetArgsQueue.begin();
-        }
-        mNotifyDeviceResetArgsQueue.erase(mNotifyDeviceResetArgsQueue.begin());
-    }
-
-    void assertNotifyKeyWasCalled(NotifyKeyArgs* outEventArgs = NULL) {
-        ASSERT_FALSE(mNotifyKeyArgsQueue.empty())
-                << "Expected notifyKey() to have been called.";
-        if (outEventArgs) {
-            *outEventArgs = *mNotifyKeyArgsQueue.begin();
-        }
-        mNotifyKeyArgsQueue.erase(mNotifyKeyArgsQueue.begin());
-    }
-
-    void assertNotifyKeyWasNotCalled() {
-        ASSERT_TRUE(mNotifyKeyArgsQueue.empty())
-                << "Expected notifyKey() to not have been called.";
-    }
-
-    void assertNotifyMotionWasCalled(NotifyMotionArgs* outEventArgs = NULL) {
-        ASSERT_FALSE(mNotifyMotionArgsQueue.empty())
-                << "Expected notifyMotion() to have been called.";
-        if (outEventArgs) {
-            *outEventArgs = *mNotifyMotionArgsQueue.begin();
-        }
-        mNotifyMotionArgsQueue.erase(mNotifyMotionArgsQueue.begin());
-    }
-
-    void assertNotifyMotionWasNotCalled() {
-        ASSERT_TRUE(mNotifyMotionArgsQueue.empty())
-                << "Expected notifyMotion() to not have been called.";
-    }
-
-    void assertNotifySwitchWasCalled(NotifySwitchArgs* outEventArgs = NULL) {
-        ASSERT_FALSE(mNotifySwitchArgsQueue.empty())
-                << "Expected notifySwitch() to have been called.";
-        if (outEventArgs) {
-            *outEventArgs = *mNotifySwitchArgsQueue.begin();
-        }
-        mNotifySwitchArgsQueue.erase(mNotifySwitchArgsQueue.begin());
-    }
-
-private:
-    virtual void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) {
-        mNotifyConfigurationChangedArgsQueue.push_back(*args);
-    }
-
-    virtual void notifyDeviceReset(const NotifyDeviceResetArgs* args) {
-        mNotifyDeviceResetArgsQueue.push_back(*args);
-    }
-
-    virtual void notifyKey(const NotifyKeyArgs* args) {
-        mNotifyKeyArgsQueue.push_back(*args);
-    }
-
-    virtual void notifyMotion(const NotifyMotionArgs* args) {
-        mNotifyMotionArgsQueue.push_back(*args);
-    }
-
-    virtual void notifySwitch(const NotifySwitchArgs* args) {
-        mNotifySwitchArgsQueue.push_back(*args);
-    }
-};
-
-
-// --- FakeEventHub ---
-
-class FakeEventHub : public EventHubInterface {
-    struct KeyInfo {
-        int32_t keyCode;
-        uint32_t flags;
-    };
-
-    struct Device {
-        InputDeviceIdentifier identifier;
-        uint32_t classes;
-        PropertyMap configuration;
-        KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes;
-        KeyedVector<int, bool> relativeAxes;
-        KeyedVector<int32_t, int32_t> keyCodeStates;
-        KeyedVector<int32_t, int32_t> scanCodeStates;
-        KeyedVector<int32_t, int32_t> switchStates;
-        KeyedVector<int32_t, int32_t> absoluteAxisValue;
-        KeyedVector<int32_t, KeyInfo> keysByScanCode;
-        KeyedVector<int32_t, KeyInfo> keysByUsageCode;
-        KeyedVector<int32_t, bool> leds;
-        Vector<VirtualKeyDefinition> virtualKeys;
-
-        Device(uint32_t classes) :
-                classes(classes) {
-        }
-    };
-
-    KeyedVector<int32_t, Device*> mDevices;
-    Vector<String8> mExcludedDevices;
-    List<RawEvent> mEvents;
-
-protected:
-    virtual ~FakeEventHub() {
-        for (size_t i = 0; i < mDevices.size(); i++) {
-            delete mDevices.valueAt(i);
-        }
-    }
-
-public:
-    FakeEventHub() { }
-
-    void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
-        Device* device = new Device(classes);
-        device->identifier.name = name;
-        mDevices.add(deviceId, device);
-
-        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0);
-    }
-
-    void removeDevice(int32_t deviceId) {
-        delete mDevices.valueFor(deviceId);
-        mDevices.removeItem(deviceId);
-
-        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0);
-    }
-
-    void finishDeviceScan() {
-        enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0);
-    }
-
-    void addConfigurationProperty(int32_t deviceId, const String8& key, const String8& value) {
-        Device* device = getDevice(deviceId);
-        device->configuration.addProperty(key, value);
-    }
-
-    void addConfigurationMap(int32_t deviceId, const PropertyMap* configuration) {
-        Device* device = getDevice(deviceId);
-        device->configuration.addAll(configuration);
-    }
-
-    void addAbsoluteAxis(int32_t deviceId, int axis,
-            int32_t minValue, int32_t maxValue, int flat, int fuzz, int resolution = 0) {
-        Device* device = getDevice(deviceId);
-
-        RawAbsoluteAxisInfo info;
-        info.valid = true;
-        info.minValue = minValue;
-        info.maxValue = maxValue;
-        info.flat = flat;
-        info.fuzz = fuzz;
-        info.resolution = resolution;
-        device->absoluteAxes.add(axis, info);
-    }
-
-    void addRelativeAxis(int32_t deviceId, int32_t axis) {
-        Device* device = getDevice(deviceId);
-        device->relativeAxes.add(axis, true);
-    }
-
-    void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
-        Device* device = getDevice(deviceId);
-        device->keyCodeStates.replaceValueFor(keyCode, state);
-    }
-
-    void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
-        Device* device = getDevice(deviceId);
-        device->scanCodeStates.replaceValueFor(scanCode, state);
-    }
-
-    void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
-        Device* device = getDevice(deviceId);
-        device->switchStates.replaceValueFor(switchCode, state);
-    }
-
-    void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) {
-        Device* device = getDevice(deviceId);
-        device->absoluteAxisValue.replaceValueFor(axis, value);
-    }
-
-    void addKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
-            int32_t keyCode, uint32_t flags) {
-        Device* device = getDevice(deviceId);
-        KeyInfo info;
-        info.keyCode = keyCode;
-        info.flags = flags;
-        if (scanCode) {
-            device->keysByScanCode.add(scanCode, info);
-        }
-        if (usageCode) {
-            device->keysByUsageCode.add(usageCode, info);
-        }
-    }
-
-    void addLed(int32_t deviceId, int32_t led, bool initialState) {
-        Device* device = getDevice(deviceId);
-        device->leds.add(led, initialState);
-    }
-
-    bool getLedState(int32_t deviceId, int32_t led) {
-        Device* device = getDevice(deviceId);
-        return device->leds.valueFor(led);
-    }
-
-    Vector<String8>& getExcludedDevices() {
-        return mExcludedDevices;
-    }
-
-    void addVirtualKeyDefinition(int32_t deviceId, const VirtualKeyDefinition& definition) {
-        Device* device = getDevice(deviceId);
-        device->virtualKeys.push(definition);
-    }
-
-    void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
-            int32_t code, int32_t value) {
-        RawEvent event;
-        event.when = when;
-        event.deviceId = deviceId;
-        event.type = type;
-        event.code = code;
-        event.value = value;
-        mEvents.push_back(event);
-
-        if (type == EV_ABS) {
-            setAbsoluteAxisValue(deviceId, code, value);
-        }
-    }
-
-    void assertQueueIsEmpty() {
-        ASSERT_EQ(size_t(0), mEvents.size())
-                << "Expected the event queue to be empty (fully consumed).";
-    }
-
-private:
-    Device* getDevice(int32_t deviceId) const {
-        ssize_t index = mDevices.indexOfKey(deviceId);
-        return index >= 0 ? mDevices.valueAt(index) : NULL;
-    }
-
-    virtual uint32_t getDeviceClasses(int32_t deviceId) const {
-        Device* device = getDevice(deviceId);
-        return device ? device->classes : 0;
-    }
-
-    virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const {
-        Device* device = getDevice(deviceId);
-        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) {
-            *outConfiguration = device->configuration;
-        }
-    }
-
-    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
-            RawAbsoluteAxisInfo* outAxisInfo) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->absoluteAxes.indexOfKey(axis);
-            if (index >= 0) {
-                *outAxisInfo = device->absoluteAxes.valueAt(index);
-                return OK;
-            }
-        }
-        outAxisInfo->clear();
-        return -1;
-    }
-
-    virtual bool hasRelativeAxis(int32_t deviceId, int axis) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            return device->relativeAxes.indexOfKey(axis) >= 0;
-        }
-        return false;
-    }
-
-    virtual bool hasInputProperty(int32_t deviceId, int property) const {
-        return false;
-    }
-
-    virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode,
-            int32_t* outKeycode, uint32_t* outFlags) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            const KeyInfo* key = getKey(device, scanCode, usageCode);
-            if (key) {
-                if (outKeycode) {
-                    *outKeycode = key->keyCode;
-                }
-                if (outFlags) {
-                    *outFlags = key->flags;
-                }
-                return OK;
-            }
-        }
-        return NAME_NOT_FOUND;
-    }
-
-    const KeyInfo* getKey(Device* device, int32_t scanCode, int32_t usageCode) const {
-        if (usageCode) {
-            ssize_t index = device->keysByUsageCode.indexOfKey(usageCode);
-            if (index >= 0) {
-                return &device->keysByUsageCode.valueAt(index);
-            }
-        }
-        if (scanCode) {
-            ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
-            if (index >= 0) {
-                return &device->keysByScanCode.valueAt(index);
-            }
-        }
-        return NULL;
-    }
-
-    virtual status_t mapAxis(int32_t deviceId, int32_t scanCode,
-            AxisInfo* outAxisInfo) const {
-        return NAME_NOT_FOUND;
-    }
-
-    virtual void setExcludedDevices(const Vector<String8>& devices) {
-        mExcludedDevices = devices;
-    }
-
-    virtual size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
-        if (mEvents.empty()) {
-            return 0;
-        }
-
-        *buffer = *mEvents.begin();
-        mEvents.erase(mEvents.begin());
-        return 1;
-    }
-
-    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
-            if (index >= 0) {
-                return device->scanCodeStates.valueAt(index);
-            }
-        }
-        return AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
-            if (index >= 0) {
-                return device->keyCodeStates.valueAt(index);
-            }
-        }
-        return AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->switchStates.indexOfKey(sw);
-            if (index >= 0) {
-                return device->switchStates.valueAt(index);
-            }
-        }
-        return AKEY_STATE_UNKNOWN;
-    }
-
-    virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
-            int32_t* outValue) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->absoluteAxisValue.indexOfKey(axis);
-            if (index >= 0) {
-                *outValue = device->absoluteAxisValue.valueAt(index);
-                return OK;
-            }
-        }
-        *outValue = 0;
-        return -1;
-    }
-
-    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
-            uint8_t* outFlags) const {
-        bool result = false;
-        Device* device = getDevice(deviceId);
-        if (device) {
-            for (size_t i = 0; i < numCodes; i++) {
-                for (size_t j = 0; j < device->keysByScanCode.size(); j++) {
-                    if (keyCodes[i] == device->keysByScanCode.valueAt(j).keyCode) {
-                        outFlags[i] = 1;
-                        result = true;
-                    }
-                }
-                for (size_t j = 0; j < device->keysByUsageCode.size(); j++) {
-                    if (keyCodes[i] == device->keysByUsageCode.valueAt(j).keyCode) {
-                        outFlags[i] = 1;
-                        result = true;
-                    }
-                }
-            }
-        }
-        return result;
-    }
-
-    virtual bool hasScanCode(int32_t deviceId, int32_t scanCode) const {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->keysByScanCode.indexOfKey(scanCode);
-            return index >= 0;
-        }
-        return false;
-    }
-
-    virtual bool hasLed(int32_t deviceId, int32_t led) const {
-        Device* device = getDevice(deviceId);
-        return device && device->leds.indexOfKey(led) >= 0;
-    }
-
-    virtual void setLedState(int32_t deviceId, int32_t led, bool on) {
-        Device* device = getDevice(deviceId);
-        if (device) {
-            ssize_t index = device->leds.indexOfKey(led);
-            if (index >= 0) {
-                device->leds.replaceValueAt(led, on);
-            } else {
-                ADD_FAILURE()
-                        << "Attempted to set the state of an LED that the EventHub declared "
-                        "was not present.  led=" << led;
-            }
-        }
-    }
-
-    virtual void getVirtualKeyDefinitions(int32_t deviceId,
-            Vector<VirtualKeyDefinition>& outVirtualKeys) const {
-        outVirtualKeys.clear();
-
-        Device* device = getDevice(deviceId);
-        if (device) {
-            outVirtualKeys.appendVector(device->virtualKeys);
-        }
-    }
-
-    virtual sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const {
-        return NULL;
-    }
-
-    virtual bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) {
-        return false;
-    }
-
-    virtual void vibrate(int32_t deviceId, nsecs_t duration) {
-    }
-
-    virtual void cancelVibrate(int32_t deviceId) {
-    }
-
-    virtual bool isExternal(int32_t deviceId) const {
-        return false;
-    }
-
-    virtual void dump(String8& dump) {
-    }
-
-    virtual void monitor() {
-    }
-
-    virtual void requestReopenDevices() {
-    }
-
-    virtual void wake() {
-    }
-};
-
-
-// --- FakeInputReaderContext ---
-
-class FakeInputReaderContext : public InputReaderContext {
-    sp<EventHubInterface> mEventHub;
-    sp<InputReaderPolicyInterface> mPolicy;
-    sp<InputListenerInterface> mListener;
-    int32_t mGlobalMetaState;
-    bool mUpdateGlobalMetaStateWasCalled;
-    int32_t mGeneration;
-
-public:
-    FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& policy,
-            const sp<InputListenerInterface>& listener) :
-            mEventHub(eventHub), mPolicy(policy), mListener(listener),
-            mGlobalMetaState(0) {
-    }
-
-    virtual ~FakeInputReaderContext() { }
-
-    void assertUpdateGlobalMetaStateWasCalled() {
-        ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
-                << "Expected updateGlobalMetaState() to have been called.";
-        mUpdateGlobalMetaStateWasCalled = false;
-    }
-
-    void setGlobalMetaState(int32_t state) {
-        mGlobalMetaState = state;
-    }
-
-private:
-    virtual void updateGlobalMetaState() {
-        mUpdateGlobalMetaStateWasCalled = true;
-    }
-
-    virtual int32_t getGlobalMetaState() {
-        return mGlobalMetaState;
-    }
-
-    virtual EventHubInterface* getEventHub() {
-        return mEventHub.get();
-    }
-
-    virtual InputReaderPolicyInterface* getPolicy() {
-        return mPolicy.get();
-    }
-
-    virtual InputListenerInterface* getListener() {
-        return mListener.get();
-    }
-
-    virtual void disableVirtualKeysUntil(nsecs_t time) {
-    }
-
-    virtual bool shouldDropVirtualKey(nsecs_t now,
-            InputDevice* device, int32_t keyCode, int32_t scanCode) {
-        return false;
-    }
-
-    virtual void fadePointer() {
-    }
-
-    virtual void requestTimeoutAtTime(nsecs_t when) {
-    }
-
-    virtual int32_t bumpGeneration() {
-        return ++mGeneration;
-    }
-};
-
-
-// --- FakeInputMapper ---
-
-class FakeInputMapper : public InputMapper {
-    uint32_t mSources;
-    int32_t mKeyboardType;
-    int32_t mMetaState;
-    KeyedVector<int32_t, int32_t> mKeyCodeStates;
-    KeyedVector<int32_t, int32_t> mScanCodeStates;
-    KeyedVector<int32_t, int32_t> mSwitchStates;
-    Vector<int32_t> mSupportedKeyCodes;
-    RawEvent mLastEvent;
-
-    bool mConfigureWasCalled;
-    bool mResetWasCalled;
-    bool mProcessWasCalled;
-
-public:
-    FakeInputMapper(InputDevice* device, uint32_t sources) :
-            InputMapper(device),
-            mSources(sources), mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
-            mMetaState(0),
-            mConfigureWasCalled(false), mResetWasCalled(false), mProcessWasCalled(false) {
-    }
-
-    virtual ~FakeInputMapper() { }
-
-    void setKeyboardType(int32_t keyboardType) {
-        mKeyboardType = keyboardType;
-    }
-
-    void setMetaState(int32_t metaState) {
-        mMetaState = metaState;
-    }
-
-    void assertConfigureWasCalled() {
-        ASSERT_TRUE(mConfigureWasCalled)
-                << "Expected configure() to have been called.";
-        mConfigureWasCalled = false;
-    }
-
-    void assertResetWasCalled() {
-        ASSERT_TRUE(mResetWasCalled)
-                << "Expected reset() to have been called.";
-        mResetWasCalled = false;
-    }
-
-    void assertProcessWasCalled(RawEvent* outLastEvent = NULL) {
-        ASSERT_TRUE(mProcessWasCalled)
-                << "Expected process() to have been called.";
-        if (outLastEvent) {
-            *outLastEvent = mLastEvent;
-        }
-        mProcessWasCalled = false;
-    }
-
-    void setKeyCodeState(int32_t keyCode, int32_t state) {
-        mKeyCodeStates.replaceValueFor(keyCode, state);
-    }
-
-    void setScanCodeState(int32_t scanCode, int32_t state) {
-        mScanCodeStates.replaceValueFor(scanCode, state);
-    }
-
-    void setSwitchState(int32_t switchCode, int32_t state) {
-        mSwitchStates.replaceValueFor(switchCode, state);
-    }
-
-    void addSupportedKeyCode(int32_t keyCode) {
-        mSupportedKeyCodes.add(keyCode);
-    }
-
-private:
-    virtual uint32_t getSources() {
-        return mSources;
-    }
-
-    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) {
-        InputMapper::populateDeviceInfo(deviceInfo);
-
-        if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
-            deviceInfo->setKeyboardType(mKeyboardType);
-        }
-    }
-
-    virtual void configure(nsecs_t when,
-            const InputReaderConfiguration* config, uint32_t changes) {
-        mConfigureWasCalled = true;
-    }
-
-    virtual void reset(nsecs_t when) {
-        mResetWasCalled = true;
-    }
-
-    virtual void process(const RawEvent* rawEvent) {
-        mLastEvent = *rawEvent;
-        mProcessWasCalled = true;
-    }
-
-    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
-        ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
-        return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
-        ssize_t index = mScanCodeStates.indexOfKey(scanCode);
-        return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
-    }
-
-    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode) {
-        ssize_t index = mSwitchStates.indexOfKey(switchCode);
-        return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
-    }
-
-    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
-            const int32_t* keyCodes, uint8_t* outFlags) {
-        bool result = false;
-        for (size_t i = 0; i < numCodes; i++) {
-            for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
-                if (keyCodes[i] == mSupportedKeyCodes[j]) {
-                    outFlags[i] = 1;
-                    result = true;
-                }
-            }
-        }
-        return result;
-    }
-
-    virtual int32_t getMetaState() {
-        return mMetaState;
-    }
-
-    virtual void fadePointer() {
-    }
-};
-
-
-// --- InstrumentedInputReader ---
-
-class InstrumentedInputReader : public InputReader {
-    InputDevice* mNextDevice;
-
-public:
-    InstrumentedInputReader(const sp<EventHubInterface>& eventHub,
-            const sp<InputReaderPolicyInterface>& policy,
-            const sp<InputListenerInterface>& listener) :
-            InputReader(eventHub, policy, listener),
-            mNextDevice(NULL) {
-    }
-
-    virtual ~InstrumentedInputReader() {
-        if (mNextDevice) {
-            delete mNextDevice;
-        }
-    }
-
-    void setNextDevice(InputDevice* device) {
-        mNextDevice = device;
-    }
-
-    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, controllerNumber, identifier,
-                classes);
-    }
-
-protected:
-    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, controllerNumber, identifier, classes);
-    }
-
-    friend class InputReaderTest;
-};
-
-
-// --- InputReaderTest ---
-
-class InputReaderTest : public testing::Test {
-protected:
-    sp<FakeInputListener> mFakeListener;
-    sp<FakeInputReaderPolicy> mFakePolicy;
-    sp<FakeEventHub> mFakeEventHub;
-    sp<InstrumentedInputReader> mReader;
-
-    virtual void SetUp() {
-        mFakeEventHub = new FakeEventHub();
-        mFakePolicy = new FakeInputReaderPolicy();
-        mFakeListener = new FakeInputListener();
-
-        mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeListener);
-    }
-
-    virtual void TearDown() {
-        mReader.clear();
-
-        mFakeListener.clear();
-        mFakePolicy.clear();
-        mFakeEventHub.clear();
-    }
-
-    void addDevice(int32_t deviceId, const String8& name, uint32_t classes,
-            const PropertyMap* configuration) {
-        mFakeEventHub->addDevice(deviceId, name, classes);
-
-        if (configuration) {
-            mFakeEventHub->addConfigurationMap(deviceId, configuration);
-        }
-        mFakeEventHub->finishDeviceScan();
-        mReader->loopOnce();
-        mReader->loopOnce();
-        mFakeEventHub->assertQueueIsEmpty();
-    }
-
-    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, controllerNumber, name, classes);
-        FakeInputMapper* mapper = new FakeInputMapper(device, sources);
-        device->addMapper(mapper);
-        mReader->setNextDevice(device);
-        addDevice(deviceId, name, classes, configuration);
-        return mapper;
-    }
-};
-
-TEST_F(InputReaderTest, GetInputDevices) {
-    ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
-            INPUT_DEVICE_CLASS_KEYBOARD, NULL));
-    ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("ignored"),
-            0, NULL)); // no classes so device will be ignored
-
-    Vector<InputDeviceInfo> inputDevices;
-    mReader->getInputDevices(inputDevices);
-
-    ASSERT_EQ(1U, inputDevices.size());
-    ASSERT_EQ(1, inputDevices[0].getId());
-    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
-    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
-    ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
-
-    // Should also have received a notification describing the new input devices.
-    inputDevices = mFakePolicy->getInputDevices();
-    ASSERT_EQ(1U, inputDevices.size());
-    ASSERT_EQ(1, inputDevices[0].getId());
-    ASSERT_STREQ("keyboard", inputDevices[0].getIdentifier().name.string());
-    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, inputDevices[0].getKeyboardType());
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, inputDevices[0].getSources());
-    ASSERT_EQ(size_t(0), inputDevices[0].getMotionRanges().size());
-}
-
-TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    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);
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
-            AINPUT_SOURCE_ANY, AKEYCODE_A))
-            << "Should return unknown when the device id is >= 0 but unknown.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(1,
-            AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
-            AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-}
-
-TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    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);
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
-            AINPUT_SOURCE_ANY, KEY_A))
-            << "Should return unknown when the device id is >= 0 but unknown.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(1,
-            AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
-            AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-}
-
-TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    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);
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
-            AINPUT_SOURCE_ANY, SW_LID))
-            << "Should return unknown when the device id is >= 0 but unknown.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(1,
-            AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
-            AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
-            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-}
-
-TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    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);
-
-    const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
-    uint8_t flags[4] = { 0, 0, 0, 1 };
-
-    ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, 4, keyCodes, flags))
-            << "Should return false when device id is >= 0 but unknown.";
-    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_FALSE(mReader->hasKeys(1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return false when device id is valid but the sources are not supported by the device.";
-    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_TRUE(mReader->hasKeys(1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
-    ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return false when the device id is < 0 but the sources are not supported by any device.";
-    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
-
-    flags[3] = 1;
-    ASSERT_TRUE(mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
-    ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
-}
-
-TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
-    addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD, NULL);
-
-    NotifyConfigurationChangedArgs args;
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyConfigurationChangedWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-}
-
-TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
-    FakeInputMapper* mapper = NULL;
-    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);
-    mReader->loopOnce();
-    ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
-
-    RawEvent event;
-    ASSERT_NO_FATAL_FAILURE(mapper->assertProcessWasCalled(&event));
-    ASSERT_EQ(0, event.when);
-    ASSERT_EQ(1, event.deviceId);
-    ASSERT_EQ(EV_KEY, event.type);
-    ASSERT_EQ(KEY_A, event.code);
-    ASSERT_EQ(1, event.value);
-}
-
-
-// --- InputDeviceTest ---
-
-class InputDeviceTest : public testing::Test {
-protected:
-    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;
-    sp<FakeInputReaderPolicy> mFakePolicy;
-    sp<FakeInputListener> mFakeListener;
-    FakeInputReaderContext* mFakeContext;
-
-    InputDevice* mDevice;
-
-    virtual void SetUp() {
-        mFakeEventHub = new FakeEventHub();
-        mFakePolicy = new FakeInputReaderPolicy();
-        mFakeListener = new FakeInputListener();
-        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
-
-        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
-        InputDeviceIdentifier identifier;
-        identifier.name = DEVICE_NAME;
-        mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
-                DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
-    }
-
-    virtual void TearDown() {
-        delete mDevice;
-
-        delete mFakeContext;
-        mFakeListener.clear();
-        mFakePolicy.clear();
-        mFakeEventHub.clear();
-    }
-};
-
-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;
-
-TEST_F(InputDeviceTest, ImmutableProperties) {
-    ASSERT_EQ(DEVICE_ID, mDevice->getId());
-    ASSERT_STREQ(DEVICE_NAME, mDevice->getName());
-    ASSERT_EQ(DEVICE_CLASSES, mDevice->getClasses());
-}
-
-TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
-    // Configuration.
-    InputReaderConfiguration config;
-    mDevice->configure(ARBITRARY_TIME, &config, 0);
-
-    // Reset.
-    mDevice->reset(ARBITRARY_TIME);
-
-    NotifyDeviceResetArgs resetArgs;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
-    ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
-
-    // Metadata.
-    ASSERT_TRUE(mDevice->isIgnored());
-    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
-
-    InputDeviceInfo info;
-    mDevice->getDeviceInfo(&info);
-    ASSERT_EQ(DEVICE_ID, info.getId());
-    ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string());
-    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
-    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
-
-    // State queries.
-    ASSERT_EQ(0, mDevice->getMetaState());
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
-            << "Ignored device should return unknown key code state.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
-            << "Ignored device should return unknown scan code state.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
-            << "Ignored device should return unknown switch state.";
-
-    const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
-    uint8_t flags[2] = { 0, 1 };
-    ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 2, keyCodes, flags))
-            << "Ignored device should never mark any key codes.";
-    ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
-    ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
-}
-
-TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
-    // Configuration.
-    mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8("key"), String8("value"));
-
-    FakeInputMapper* mapper1 = new FakeInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD);
-    mapper1->setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    mapper1->setMetaState(AMETA_ALT_ON);
-    mapper1->addSupportedKeyCode(AKEYCODE_A);
-    mapper1->addSupportedKeyCode(AKEYCODE_B);
-    mapper1->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
-    mapper1->setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
-    mapper1->setScanCodeState(2, AKEY_STATE_DOWN);
-    mapper1->setScanCodeState(3, AKEY_STATE_UP);
-    mapper1->setSwitchState(4, AKEY_STATE_DOWN);
-    mDevice->addMapper(mapper1);
-
-    FakeInputMapper* mapper2 = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN);
-    mapper2->setMetaState(AMETA_SHIFT_ON);
-    mDevice->addMapper(mapper2);
-
-    InputReaderConfiguration config;
-    mDevice->configure(ARBITRARY_TIME, &config, 0);
-
-    String8 propertyValue;
-    ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty(String8("key"), propertyValue))
-            << "Device should have read configuration during configuration phase.";
-    ASSERT_STREQ("value", propertyValue.string());
-
-    ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled());
-    ASSERT_NO_FATAL_FAILURE(mapper2->assertConfigureWasCalled());
-
-    // Reset
-    mDevice->reset(ARBITRARY_TIME);
-    ASSERT_NO_FATAL_FAILURE(mapper1->assertResetWasCalled());
-    ASSERT_NO_FATAL_FAILURE(mapper2->assertResetWasCalled());
-
-    NotifyDeviceResetArgs resetArgs;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyDeviceResetWasCalled(&resetArgs));
-    ASSERT_EQ(ARBITRARY_TIME, resetArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, resetArgs.deviceId);
-
-    // Metadata.
-    ASSERT_FALSE(mDevice->isIgnored());
-    ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
-
-    InputDeviceInfo info;
-    mDevice->getDeviceInfo(&info);
-    ASSERT_EQ(DEVICE_ID, info.getId());
-    ASSERT_STREQ(DEVICE_NAME, info.getIdentifier().name.string());
-    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
-    ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
-
-    // State queries.
-    ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
-            << "Should query mappers and combine meta states.";
-
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown key code state when source not supported.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown scan code state when source not supported.";
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
-            << "Should return unknown switch state when source not supported.";
-
-    ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
-            << "Should query mapper when source is supported.";
-    ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
-            << "Should query mapper when source is supported.";
-    ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
-            << "Should query mapper when source is supported.";
-
-    const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
-    uint8_t flags[4] = { 0, 0, 0, 1 };
-    ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
-            << "Should do nothing when source is unsupported.";
-    ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
-    ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
-    ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
-    ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
-
-    ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 4, keyCodes, flags))
-            << "Should query mapper when source is supported.";
-    ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
-    ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
-    ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
-    ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
-
-    // Event handling.
-    RawEvent event;
-    mDevice->process(&event, 1);
-
-    ASSERT_NO_FATAL_FAILURE(mapper1->assertProcessWasCalled());
-    ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled());
-}
-
-
-// --- InputMapperTest ---
-
-class InputMapperTest : public testing::Test {
-protected:
-    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;
-    sp<FakeInputReaderPolicy> mFakePolicy;
-    sp<FakeInputListener> mFakeListener;
-    FakeInputReaderContext* mFakeContext;
-    InputDevice* mDevice;
-
-    virtual void SetUp() {
-        mFakeEventHub = new FakeEventHub();
-        mFakePolicy = new FakeInputReaderPolicy();
-        mFakeListener = new FakeInputListener();
-        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener);
-        InputDeviceIdentifier identifier;
-        identifier.name = DEVICE_NAME;
-        mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION,
-                DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
-
-        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
-    }
-
-    virtual void TearDown() {
-        delete mDevice;
-        delete mFakeContext;
-        mFakeListener.clear();
-        mFakePolicy.clear();
-        mFakeEventHub.clear();
-    }
-
-    void addConfigurationProperty(const char* key, const char* value) {
-        mFakeEventHub->addConfigurationProperty(DEVICE_ID, String8(key), String8(value));
-    }
-
-    void addMapperAndConfigure(InputMapper* mapper) {
-        mDevice->addMapper(mapper);
-        mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0);
-        mDevice->reset(ARBITRARY_TIME);
-    }
-
-    void setDisplayInfoAndReconfigure(int32_t displayId, int32_t width, int32_t height,
-            int32_t orientation) {
-        mFakePolicy->setDisplayInfo(displayId, width, height, orientation);
-        mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
-                InputReaderConfiguration::CHANGE_DISPLAY_INFO);
-    }
-
-    static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type,
-            int32_t code, int32_t value) {
-        RawEvent event;
-        event.when = when;
-        event.deviceId = deviceId;
-        event.type = type;
-        event.code = code;
-        event.value = value;
-        mapper->process(&event);
-    }
-
-    static void assertMotionRange(const InputDeviceInfo& info,
-            int32_t axis, uint32_t source, float min, float max, float flat, float fuzz) {
-        const InputDeviceInfo::MotionRange* range = info.getMotionRange(axis, source);
-        ASSERT_TRUE(range != NULL) << "Axis: " << axis << " Source: " << source;
-        ASSERT_EQ(axis, range->axis) << "Axis: " << axis << " Source: " << source;
-        ASSERT_EQ(source, range->source) << "Axis: " << axis << " Source: " << source;
-        ASSERT_NEAR(min, range->min, EPSILON) << "Axis: " << axis << " Source: " << source;
-        ASSERT_NEAR(max, range->max, EPSILON) << "Axis: " << axis << " Source: " << source;
-        ASSERT_NEAR(flat, range->flat, EPSILON) << "Axis: " << axis << " Source: " << source;
-        ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Axis: " << axis << " Source: " << source;
-    }
-
-    static void assertPointerCoords(const PointerCoords& coords,
-            float x, float y, float pressure, float size,
-            float touchMajor, float touchMinor, float toolMajor, float toolMinor,
-            float orientation, float distance) {
-        ASSERT_NEAR(x, coords.getAxisValue(AMOTION_EVENT_AXIS_X), 1);
-        ASSERT_NEAR(y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
-        ASSERT_NEAR(pressure, coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE), EPSILON);
-        ASSERT_NEAR(size, coords.getAxisValue(AMOTION_EVENT_AXIS_SIZE), EPSILON);
-        ASSERT_NEAR(touchMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR), 1);
-        ASSERT_NEAR(touchMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR), 1);
-        ASSERT_NEAR(toolMajor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR), 1);
-        ASSERT_NEAR(toolMinor, coords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR), 1);
-        ASSERT_NEAR(orientation, coords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION), EPSILON);
-        ASSERT_NEAR(distance, coords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE), EPSILON);
-    }
-
-    static void assertPosition(const sp<FakePointerController>& controller, float x, float y) {
-        float actualX, actualY;
-        controller->getPosition(&actualX, &actualY);
-        ASSERT_NEAR(x, actualX, 1);
-        ASSERT_NEAR(y, actualY, 1);
-    }
-};
-
-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
-
-
-// --- SwitchInputMapperTest ---
-
-class SwitchInputMapperTest : public InputMapperTest {
-protected:
-};
-
-TEST_F(SwitchInputMapperTest, GetSources) {
-    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources());
-}
-
-TEST_F(SwitchInputMapperTest, GetSwitchState) {
-    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 1);
-    ASSERT_EQ(1, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-
-    mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 0);
-    ASSERT_EQ(0, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
-}
-
-TEST_F(SwitchInputMapperTest, Process) {
-    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
-    addMapperAndConfigure(mapper);
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_JACK_PHYSICAL_INSERT, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_HEADPHONE_INSERT, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-
-    NotifySwitchArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifySwitchWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ((1 << SW_LID) | (1 << SW_JACK_PHYSICAL_INSERT), args.switchValues);
-    ASSERT_EQ((1 << SW_LID) | (1 << SW_JACK_PHYSICAL_INSERT) | (1 << SW_HEADPHONE_INSERT),
-            args.switchMask);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-}
-
-
-// --- KeyboardInputMapperTest ---
-
-class KeyboardInputMapperTest : public InputMapperTest {
-protected:
-    void testDPadKeyRotation(KeyboardInputMapper* mapper,
-            int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode);
-};
-
-void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper,
-        int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) {
-    NotifyKeyArgs args;
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, 1);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(originalScanCode, args.scanCode);
-    ASSERT_EQ(rotatedKeyCode, args.keyCode);
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(originalScanCode, args.scanCode);
-    ASSERT_EQ(rotatedKeyCode, args.keyCode);
-}
-
-
-TEST_F(KeyboardInputMapperTest, GetSources) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper->getSources());
-}
-
-TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
-    const int32_t USAGE_A = 0x070004;
-    const int32_t USAGE_UNKNOWN = 0x07ffff;
-    mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
-    mFakeEventHub->addKey(DEVICE_ID, 0, USAGE_A, AKEYCODE_A, POLICY_FLAG_WAKE);
-
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    // Key down by scan code.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_HOME, 1);
-    NotifyKeyArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Key up by scan code.
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
-            EV_KEY, KEY_HOME, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Key down by usage code.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_MSC, MSC_SCAN, USAGE_A);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, 0, 1);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(AKEYCODE_A, args.keyCode);
-    ASSERT_EQ(0, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Key up by usage code.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_MSC, MSC_SCAN, USAGE_A);
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
-            EV_KEY, 0, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEYCODE_A, args.keyCode);
-    ASSERT_EQ(0, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Key down with unknown scan code or usage code.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_UNKNOWN, 1);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(0, args.keyCode);
-    ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(0U, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Key up with unknown scan code or usage code.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_MSC, MSC_SCAN, USAGE_UNKNOWN);
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
-            EV_KEY, KEY_UNKNOWN, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(0, args.keyCode);
-    ASSERT_EQ(KEY_UNKNOWN, args.scanCode);
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
-    ASSERT_EQ(0U, args.policyFlags);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-}
-
-TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
-    mFakeEventHub->addKey(DEVICE_ID, KEY_LEFTSHIFT, 0, AKEYCODE_SHIFT_LEFT, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0);
-
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    // Initial metastate.
-    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
-
-    // Metakey down.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_LEFTSHIFT, 1);
-    NotifyKeyArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
-    ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
-
-    // Key down.
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
-            EV_KEY, KEY_A, 1);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
-
-    // Key up.
-    process(mapper, ARBITRARY_TIME + 2, DEVICE_ID,
-            EV_KEY, KEY_A, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
-
-    // Metakey up.
-    process(mapper, ARBITRARY_TIME + 3, DEVICE_ID,
-            EV_KEY, KEY_LEFTSHIFT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AMETA_NONE, args.metaState);
-    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
-    ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
-}
-
-TEST_F(KeyboardInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateDPad) {
-    mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
-
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_90);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
-}
-
-TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) {
-    mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0);
-
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addConfigurationProperty("keyboard.orientationAware", "1");
-    addMapperAndConfigure(mapper);
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_0);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_90);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN));
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_180);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_LEFT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_UP));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT));
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_270);
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_DOWN));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT));
-    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
-            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_UP));
-
-    // Special case: if orientation changes while key is down, we still emit the same keycode
-    // in the key up as we did in the key down.
-    NotifyKeyArgs args;
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_270);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(KEY_UP, args.scanCode);
-    ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_180);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(KEY_UP, args.scanCode);
-    ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
-}
-
-TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 1);
-    ASSERT_EQ(1, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
-
-    mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 0);
-    ASSERT_EQ(0, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
-}
-
-TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 1);
-    ASSERT_EQ(1, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
-
-    mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 0);
-    ASSERT_EQ(0, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
-}
-
-TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    mFakeEventHub->addKey(DEVICE_ID, KEY_A, 0, AKEYCODE_A, 0);
-
-    const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
-    uint8_t flags[2] = { 0, 0 };
-    ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 1, keyCodes, flags));
-    ASSERT_TRUE(flags[0]);
-    ASSERT_FALSE(flags[1]);
-}
-
-TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) {
-    mFakeEventHub->addLed(DEVICE_ID, LED_CAPSL, true /*initially on*/);
-    mFakeEventHub->addLed(DEVICE_ID, LED_NUML, false /*initially off*/);
-    mFakeEventHub->addLed(DEVICE_ID, LED_SCROLLL, false /*initially off*/);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0);
-
-    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
-            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
-    addMapperAndConfigure(mapper);
-
-    // Initialization should have turned all of the lights off.
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
-
-    // Toggle caps lock on.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_CAPSLOCK, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_CAPSLOCK, 0);
-    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
-    ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper->getMetaState());
-
-    // Toggle num lock on.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_NUMLOCK, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_NUMLOCK, 0);
-    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
-    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
-    ASSERT_EQ(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON, mapper->getMetaState());
-
-    // Toggle caps lock off.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_CAPSLOCK, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_CAPSLOCK, 0);
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
-    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
-    ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper->getMetaState());
-
-    // Toggle scroll lock on.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_SCROLLLOCK, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_SCROLLLOCK, 0);
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
-    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
-    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
-    ASSERT_EQ(AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
-
-    // Toggle num lock off.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_NUMLOCK, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_NUMLOCK, 0);
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
-    ASSERT_TRUE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
-    ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper->getMetaState());
-
-    // Toggle scroll lock off.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_SCROLLLOCK, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID,
-            EV_KEY, KEY_SCROLLLOCK, 0);
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_CAPSL));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_NUML));
-    ASSERT_FALSE(mFakeEventHub->getLedState(DEVICE_ID, LED_SCROLLL));
-    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
-}
-
-
-// --- CursorInputMapperTest ---
-
-class CursorInputMapperTest : public InputMapperTest {
-protected:
-    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
-
-    sp<FakePointerController> mFakePointerController;
-
-    virtual void SetUp() {
-        InputMapperTest::SetUp();
-
-        mFakePointerController = new FakePointerController();
-        mFakePolicy->setPointerController(DEVICE_ID, mFakePointerController);
-    }
-
-    void testMotionRotation(CursorInputMapper* mapper,
-            int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY);
-};
-
-const int32_t CursorInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
-
-void CursorInputMapperTest::testMotionRotation(CursorInputMapper* mapper,
-        int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
-    NotifyMotionArgs args;
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, originalX);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, originalY);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
-            float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD,
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(CursorInputMapperTest, WhenModeIsPointer_GetSources_ReturnsMouse) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "pointer");
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
-}
-
-TEST_F(CursorInputMapperTest, WhenModeIsNavigation_GetSources_ReturnsTrackball) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources());
-}
-
-TEST_F(CursorInputMapperTest, WhenModeIsPointer_PopulateDeviceInfo_ReturnsRangeFromPointerController) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "pointer");
-    addMapperAndConfigure(mapper);
-
-    InputDeviceInfo info;
-    mapper->populateDeviceInfo(&info);
-
-    // Initially there may not be a valid motion range.
-    ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE));
-    ASSERT_EQ(NULL, info.getMotionRange(AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE));
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
-            AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE, 0.0f, 1.0f, 0.0f, 0.0f));
-
-    // When the bounds are set, then there should be a valid motion range.
-    mFakePointerController->setBounds(1, 2, 800 - 1, 480 - 1);
-
-    InputDeviceInfo info2;
-    mapper->populateDeviceInfo(&info2);
-
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
-            AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_MOUSE,
-            1, 800 - 1, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
-            AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_MOUSE,
-            2, 480 - 1, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info2,
-            AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_MOUSE,
-            0.0f, 1.0f, 0.0f, 0.0f));
-}
-
-TEST_F(CursorInputMapperTest, WhenModeIsNavigation_PopulateDeviceInfo_ReturnsScaledRange) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addMapperAndConfigure(mapper);
-
-    InputDeviceInfo info;
-    mapper->populateDeviceInfo(&info);
-
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
-            AINPUT_MOTION_RANGE_X, AINPUT_SOURCE_TRACKBALL,
-            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
-            AINPUT_MOTION_RANGE_Y, AINPUT_SOURCE_TRACKBALL,
-            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
-    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info,
-            AINPUT_MOTION_RANGE_PRESSURE, AINPUT_SOURCE_TRACKBALL,
-            0.0f, 1.0f, 0.0f, 0.0f));
-}
-
-TEST_F(CursorInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyMotionArgs args;
-
-    // Button press.
-    // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(0, args.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, args.buttonState);
-    ASSERT_EQ(0, args.edgeFlags);
-    ASSERT_EQ(uint32_t(1), args.pointerCount);
-    ASSERT_EQ(0, args.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Button release.  Should have same down time.
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
-    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
-    ASSERT_EQ(uint32_t(0), args.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(0, args.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(0, args.buttonState);
-    ASSERT_EQ(0, args.edgeFlags);
-    ASSERT_EQ(uint32_t(1), args.pointerCount);
-    ASSERT_EQ(0, args.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, args.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
-    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-}
-
-TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs args;
-
-    // Motion in X but not Y.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Motion in Y but not X.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(CursorInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs args;
-
-    // Button press.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Button release.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(CursorInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs args;
-
-    // Combined X, Y and Button.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, -2);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            1.0f / TRACKBALL_MOVEMENT_THRESHOLD, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
-            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Move X, Y a bit while pressed.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 2);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
-            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // Release Button.
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-}
-
-TEST_F(CursorInputMapperTest, Process_WhenNotOrientationAware_ShouldNotRotateMotions) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addMapperAndConfigure(mapper);
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT,
-            DISPLAY_ORIENTATION_90);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
-}
-
-TEST_F(CursorInputMapperTest, Process_WhenOrientationAware_ShouldRotateMotions) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "navigation");
-    addConfigurationProperty("cursor.orientationAware", "1");
-    addMapperAndConfigure(mapper);
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_90);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1,  1));
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_180);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1, -1));
-
-    setDisplayInfoAndReconfigure(DISPLAY_ID,
-            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_270);
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1, -1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1,  1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  1,  0));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0, -1));
-    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1, -1));
-}
-
-TEST_F(CursorInputMapperTest, Process_ShouldHandleAllButtons) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "pointer");
-    addMapperAndConfigure(mapper);
-
-    mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
-    mFakePointerController->setPosition(100, 200);
-    mFakePointerController->setButtonState(0);
-
-    NotifyMotionArgs motionArgs;
-    NotifyKeyArgs keyArgs;
-
-    // press BTN_LEFT, release BTN_LEFT
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, mFakePointerController->getButtonState());
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_LEFT, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
-            motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
-            mFakePointerController->getButtonState());
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_RIGHT, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MIDDLE, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    // press BTN_BACK, release BTN_BACK
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_BACK, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-
-    // press BTN_SIDE, release BTN_SIDE
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_SIDE, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-
-    // press BTN_FORWARD, release BTN_FORWARD
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_FORWARD, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-
-    // press BTN_EXTRA, release BTN_EXTRA
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_EXTRA, 0);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, mFakePointerController->getButtonState());
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            100.0f, 200.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-}
-
-TEST_F(CursorInputMapperTest, Process_WhenModeIsPointer_ShouldMoveThePointerAround) {
-    CursorInputMapper* mapper = new CursorInputMapper(mDevice);
-    addConfigurationProperty("cursor.mode", "pointer");
-    addMapperAndConfigure(mapper);
-
-    mFakePointerController->setBounds(0, 0, 800 - 1, 480 - 1);
-    mFakePointerController->setPosition(100, 200);
-    mFakePointerController->setButtonState(0);
-
-    NotifyMotionArgs args;
-
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 10);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 20);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, args.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            110.0f, 220.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
-    ASSERT_NO_FATAL_FAILURE(assertPosition(mFakePointerController, 110.0f, 220.0f));
-}
-
-
-// --- TouchInputMapperTest ---
-
-class TouchInputMapperTest : public InputMapperTest {
-protected:
-    static const int32_t RAW_X_MIN;
-    static const int32_t RAW_X_MAX;
-    static const int32_t RAW_Y_MIN;
-    static const int32_t RAW_Y_MAX;
-    static const int32_t RAW_TOUCH_MIN;
-    static const int32_t RAW_TOUCH_MAX;
-    static const int32_t RAW_TOOL_MIN;
-    static const int32_t RAW_TOOL_MAX;
-    static const int32_t RAW_PRESSURE_MIN;
-    static const int32_t RAW_PRESSURE_MAX;
-    static const int32_t RAW_ORIENTATION_MIN;
-    static const int32_t RAW_ORIENTATION_MAX;
-    static const int32_t RAW_DISTANCE_MIN;
-    static const int32_t RAW_DISTANCE_MAX;
-    static const int32_t RAW_TILT_MIN;
-    static const int32_t RAW_TILT_MAX;
-    static const int32_t RAW_ID_MIN;
-    static const int32_t RAW_ID_MAX;
-    static const int32_t RAW_SLOT_MIN;
-    static const int32_t RAW_SLOT_MAX;
-    static const float X_PRECISION;
-    static const float Y_PRECISION;
-
-    static const float GEOMETRIC_SCALE;
-
-    static const VirtualKeyDefinition VIRTUAL_KEYS[2];
-
-    enum Axes {
-        POSITION = 1 << 0,
-        TOUCH = 1 << 1,
-        TOOL = 1 << 2,
-        PRESSURE = 1 << 3,
-        ORIENTATION = 1 << 4,
-        MINOR = 1 << 5,
-        ID = 1 << 6,
-        DISTANCE = 1 << 7,
-        TILT = 1 << 8,
-        SLOT = 1 << 9,
-        TOOL_TYPE = 1 << 10,
-    };
-
-    void prepareDisplay(int32_t orientation);
-    void prepareVirtualKeys();
-    int32_t toRawX(float displayX);
-    int32_t toRawY(float displayY);
-    float toDisplayX(int32_t rawX);
-    float toDisplayY(int32_t rawY);
-};
-
-const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
-const int32_t TouchInputMapperTest::RAW_X_MAX = 1019;
-const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
-const int32_t TouchInputMapperTest::RAW_Y_MAX = 1009;
-const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
-const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
-const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = RAW_TOUCH_MIN;
-const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = RAW_TOUCH_MAX;
-const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
-const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
-const int32_t TouchInputMapperTest::RAW_DISTANCE_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_DISTANCE_MAX = 7;
-const int32_t TouchInputMapperTest::RAW_TILT_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_TILT_MAX = 150;
-const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
-const int32_t TouchInputMapperTest::RAW_SLOT_MIN = 0;
-const int32_t TouchInputMapperTest::RAW_SLOT_MAX = 9;
-const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH;
-const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT;
-
-const float TouchInputMapperTest::GEOMETRIC_SCALE =
-        avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN + 1),
-                float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN + 1));
-
-const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
-        { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
-        { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
-};
-
-void TouchInputMapperTest::prepareDisplay(int32_t orientation) {
-    setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation);
-}
-
-void TouchInputMapperTest::prepareVirtualKeys() {
-    mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[0]);
-    mFakeEventHub->addVirtualKeyDefinition(DEVICE_ID, VIRTUAL_KEYS[1]);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, 0, AKEYCODE_HOME, POLICY_FLAG_WAKE);
-    mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, 0, AKEYCODE_MENU, POLICY_FLAG_WAKE);
-}
-
-int32_t TouchInputMapperTest::toRawX(float displayX) {
-    return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN + 1) / DISPLAY_WIDTH + RAW_X_MIN);
-}
-
-int32_t TouchInputMapperTest::toRawY(float displayY) {
-    return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN + 1) / DISPLAY_HEIGHT + RAW_Y_MIN);
-}
-
-float TouchInputMapperTest::toDisplayX(int32_t rawX) {
-    return float(rawX - RAW_X_MIN) * DISPLAY_WIDTH / (RAW_X_MAX - RAW_X_MIN + 1);
-}
-
-float TouchInputMapperTest::toDisplayY(int32_t rawY) {
-    return float(rawY - RAW_Y_MIN) * DISPLAY_HEIGHT / (RAW_Y_MAX - RAW_Y_MIN + 1);
-}
-
-
-// --- SingleTouchInputMapperTest ---
-
-class SingleTouchInputMapperTest : public TouchInputMapperTest {
-protected:
-    void prepareButtons();
-    void prepareAxes(int axes);
-
-    void processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
-    void processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
-    void processUp(SingleTouchInputMapper* mappery);
-    void processPressure(SingleTouchInputMapper* mapper, int32_t pressure);
-    void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor);
-    void processDistance(SingleTouchInputMapper* mapper, int32_t distance);
-    void processTilt(SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY);
-    void processKey(SingleTouchInputMapper* mapper, int32_t code, int32_t value);
-    void processSync(SingleTouchInputMapper* mapper);
-};
-
-void SingleTouchInputMapperTest::prepareButtons() {
-    mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
-}
-
-void SingleTouchInputMapperTest::prepareAxes(int axes) {
-    if (axes & POSITION) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_X,
-                RAW_X_MIN, RAW_X_MAX, 0, 0);
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_Y,
-                RAW_Y_MIN, RAW_Y_MAX, 0, 0);
-    }
-    if (axes & PRESSURE) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_PRESSURE,
-                RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
-    }
-    if (axes & TOOL) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TOOL_WIDTH,
-                RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
-    }
-    if (axes & DISTANCE) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_DISTANCE,
-                RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
-    }
-    if (axes & TILT) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_X,
-                RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_TILT_Y,
-                RAW_TILT_MIN, RAW_TILT_MAX, 0, 0);
-    }
-}
-
-void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 1);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
-}
-
-void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, x);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, y);
-}
-
-void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0);
-}
-
-void SingleTouchInputMapperTest::processPressure(
-        SingleTouchInputMapper* mapper, int32_t pressure) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_PRESSURE, pressure);
-}
-
-void SingleTouchInputMapperTest::processToolMajor(
-        SingleTouchInputMapper* mapper, int32_t toolMajor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, toolMajor);
-}
-
-void SingleTouchInputMapperTest::processDistance(
-        SingleTouchInputMapper* mapper, int32_t distance) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_DISTANCE, distance);
-}
-
-void SingleTouchInputMapperTest::processTilt(
-        SingleTouchInputMapper* mapper, int32_t tiltX, int32_t tiltY) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_X, tiltX);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TILT_Y, tiltY);
-}
-
-void SingleTouchInputMapperTest::processKey(
-        SingleTouchInputMapper* mapper, int32_t code, int32_t value) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
-}
-
-void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-}
-
-
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndNotACursor_ReturnsPointer) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    prepareButtons();
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_MOUSE, mapper->getSources());
-}
-
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsNotSpecifiedAndIsACursor_ReturnsTouchPad) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_X);
-    mFakeEventHub->addRelativeAxis(DEVICE_ID, REL_Y);
-    prepareButtons();
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
-}
-
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchPad_ReturnsTouchPad) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    prepareButtons();
-    prepareAxes(POSITION);
-    addConfigurationProperty("touch.deviceType", "touchPad");
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
-}
-
-TEST_F(SingleTouchInputMapperTest, GetSources_WhenDeviceTypeIsTouchScreen_ReturnsTouchScreen) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    prepareButtons();
-    prepareAxes(POSITION);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    addMapperAndConfigure(mapper);
-
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources());
-}
-
-TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    // Unknown key.
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
-
-    // Virtual key is down.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
-
-    // Virtual key is up.
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
-}
-
-TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    // Unknown key.
-    ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
-
-    // Virtual key is down.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
-
-    // Virtual key is up.
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled());
-
-    ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
-}
-
-TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    const int32_t keys[2] = { AKEYCODE_HOME, AKEYCODE_A };
-    uint8_t flags[2] = { 0, 0 };
-    ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 2, keys, flags));
-    ASSERT_TRUE(flags[0]);
-    ASSERT_FALSE(flags[1]);
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyKeyArgs args;
-
-    // Press virtual key.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Release virtual key.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
-    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
-    ASSERT_EQ(DEVICE_ID, args.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
-    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
-    ASSERT_EQ(KEY_HOME, args.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
-
-    // Should not have sent any motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyKeyArgs keyArgs;
-
-    // Press virtual key.
-    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
-    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
-    ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
-    ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
-
-    // Move out of bounds.  This should generate a cancel and a pointer down since we moved
-    // into the display area.
-    y -= 100;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
-    ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
-            | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
-    ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
-    ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
-    ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
-
-    NotifyMotionArgs motionArgs;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Keep moving out of bounds.  Should generate a pointer move.
-    y -= 50;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Release out of bounds.  Should generate a pointer up.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyMotionArgs motionArgs;
-
-    // Initially go down out of bounds.
-    int32_t x = -10;
-    int32_t y = -10;
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-
-    // Move into the display area.  Should generate a pointer down.
-    x = 50;
-    y = 75;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Release.  Should generate a pointer up.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyMotionArgs motionArgs;
-
-    // Down.
-    int32_t x = 100;
-    int32_t y = 125;
-    processDown(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Move.
-    x += 50;
-    y += 75;
-    processMove(mapper, x, y);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Up.
-    processUp(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenNotOrientationAware_DoesNotRotateMotions) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareButtons();
-    prepareAxes(POSITION);
-    addConfigurationProperty("touch.orientationAware", "0");
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs args;
-
-    // Rotation 90.
-    prepareDisplay(DISPLAY_ORIENTATION_90);
-    processDown(mapper, toRawX(50), toRawY(75));
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
-    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenOrientationAware_RotatesMotions) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareButtons();
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs args;
-
-    // Rotation 0.
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    processDown(mapper, toRawX(50), toRawY(75));
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
-    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
-
-    // Rotation 90.
-    prepareDisplay(DISPLAY_ORIENTATION_90);
-    processDown(mapper, RAW_X_MAX - toRawX(75) + RAW_X_MIN, toRawY(50));
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
-    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
-
-    // Rotation 180.
-    prepareDisplay(DISPLAY_ORIENTATION_180);
-    processDown(mapper, RAW_X_MAX - toRawX(50) + RAW_X_MIN, RAW_Y_MAX - toRawY(75) + RAW_Y_MIN);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
-    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
-
-    // Rotation 270.
-    prepareDisplay(DISPLAY_ORIENTATION_270);
-    processDown(mapper, toRawX(75), RAW_Y_MAX - toRawY(50) + RAW_Y_MIN);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NEAR(50, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X), 1);
-    ASSERT_NEAR(75, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y), 1);
-
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled());
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION | PRESSURE | TOOL | DISTANCE | TILT);
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawPressure = 10;
-    int32_t rawToolMajor = 12;
-    int32_t rawDistance = 2;
-    int32_t rawTiltX = 30;
-    int32_t rawTiltY = 110;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
-    float size = float(rawToolMajor) / RAW_TOOL_MAX;
-    float tool = float(rawToolMajor) * GEOMETRIC_SCALE;
-    float distance = float(rawDistance);
-
-    float tiltCenter = (RAW_TILT_MAX + RAW_TILT_MIN) * 0.5f;
-    float tiltScale = M_PI / 180;
-    float tiltXAngle = (rawTiltX - tiltCenter) * tiltScale;
-    float tiltYAngle = (rawTiltY - tiltCenter) * tiltScale;
-    float orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
-    float tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
-
-    processDown(mapper, rawX, rawY);
-    processPressure(mapper, rawPressure);
-    processToolMajor(mapper, rawToolMajor);
-    processDistance(mapper, rawDistance);
-    processTilt(mapper, rawTiltX, rawTiltY);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, size, tool, tool, tool, tool, orientation, distance));
-    ASSERT_EQ(tilt, args.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_TILT));
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllButtons) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-    NotifyKeyArgs keyArgs;
-
-    processDown(mapper, 100, 200);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.buttonState);
-
-    // press BTN_LEFT, release BTN_LEFT
-    processKey(mapper, BTN_LEFT, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
-
-    processKey(mapper, BTN_LEFT, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
-    processKey(mapper, BTN_RIGHT, 1);
-    processKey(mapper, BTN_MIDDLE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
-            motionArgs.buttonState);
-
-    processKey(mapper, BTN_RIGHT, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_MIDDLE, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // press BTN_BACK, release BTN_BACK
-    processKey(mapper, BTN_BACK, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_BACK, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-
-    // press BTN_SIDE, release BTN_SIDE
-    processKey(mapper, BTN_SIDE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_SIDE, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-
-    // press BTN_FORWARD, release BTN_FORWARD
-    processKey(mapper, BTN_FORWARD, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_FORWARD, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-
-    // press BTN_EXTRA, release BTN_EXTRA
-    processKey(mapper, BTN_EXTRA, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_EXTRA, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-
-    // press BTN_STYLUS, release BTN_STYLUS
-    processKey(mapper, BTN_STYLUS, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
-
-    processKey(mapper, BTN_STYLUS, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // press BTN_STYLUS2, release BTN_STYLUS2
-    processKey(mapper, BTN_STYLUS2, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
-
-    processKey(mapper, BTN_STYLUS2, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // release touch
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.buttonState);
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-
-    // default tool type is finger
-    processDown(mapper, 100, 200);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // eraser
-    processKey(mapper, BTN_TOOL_RUBBER, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
-
-    // stylus
-    processKey(mapper, BTN_TOOL_RUBBER, 0);
-    processKey(mapper, BTN_TOOL_PEN, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // brush
-    processKey(mapper, BTN_TOOL_PEN, 0);
-    processKey(mapper, BTN_TOOL_BRUSH, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // pencil
-    processKey(mapper, BTN_TOOL_BRUSH, 0);
-    processKey(mapper, BTN_TOOL_PENCIL, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // airbrush
-    processKey(mapper, BTN_TOOL_PENCIL, 0);
-    processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // mouse
-    processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
-    processKey(mapper, BTN_TOOL_MOUSE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
-
-    // lens
-    processKey(mapper, BTN_TOOL_MOUSE, 0);
-    processKey(mapper, BTN_TOOL_LENS, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
-
-    // double-tap
-    processKey(mapper, BTN_TOOL_LENS, 0);
-    processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // triple-tap
-    processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
-    processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // quad-tap
-    processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
-    processKey(mapper, BTN_TOOL_QUADTAP, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // finger
-    processKey(mapper, BTN_TOOL_QUADTAP, 0);
-    processKey(mapper, BTN_TOOL_FINGER, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // stylus trumps finger
-    processKey(mapper, BTN_TOOL_PEN, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // eraser trumps stylus
-    processKey(mapper, BTN_TOOL_RUBBER, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
-
-    // mouse trumps eraser
-    processKey(mapper, BTN_TOOL_MOUSE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
-
-    // back to default tool type
-    processKey(mapper, BTN_TOOL_MOUSE, 0);
-    processKey(mapper, BTN_TOOL_RUBBER, 0);
-    processKey(mapper, BTN_TOOL_PEN, 0);
-    processKey(mapper, BTN_TOOL_FINGER, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION);
-    mFakeEventHub->addKey(DEVICE_ID, BTN_TOOL_FINGER, 0, AKEYCODE_UNKNOWN, 0);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-
-    // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
-    processKey(mapper, BTN_TOOL_FINGER, 1);
-    processMove(mapper, 100, 200);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // move a little
-    processMove(mapper, 150, 250);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // down when BTN_TOUCH is pressed, pressure defaults to 1
-    processKey(mapper, BTN_TOUCH, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // up when BTN_TOUCH is released, hover restored
-    processKey(mapper, BTN_TOUCH, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // exit hover when pointer goes away
-    processKey(mapper, BTN_TOOL_FINGER, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-}
-
-TEST_F(SingleTouchInputMapperTest, Process_WhenAbsPressureIsPresent_HoversIfItsValueIsZero) {
-    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareButtons();
-    prepareAxes(POSITION | PRESSURE);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-
-    // initially hovering because pressure is 0
-    processDown(mapper, 100, 200);
-    processPressure(mapper, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // move a little
-    processMove(mapper, 150, 250);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // down when pressure is non-zero
-    processPressure(mapper, RAW_PRESSURE_MAX);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // up when pressure becomes 0, hover restored
-    processPressure(mapper, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // exit hover when pointer goes away
-    processUp(mapper);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-}
-
-
-// --- MultiTouchInputMapperTest ---
-
-class MultiTouchInputMapperTest : public TouchInputMapperTest {
-protected:
-    void prepareAxes(int axes);
-
-    void processPosition(MultiTouchInputMapper* mapper, int32_t x, int32_t y);
-    void processTouchMajor(MultiTouchInputMapper* mapper, int32_t touchMajor);
-    void processTouchMinor(MultiTouchInputMapper* mapper, int32_t touchMinor);
-    void processToolMajor(MultiTouchInputMapper* mapper, int32_t toolMajor);
-    void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor);
-    void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation);
-    void processPressure(MultiTouchInputMapper* mapper, int32_t pressure);
-    void processDistance(MultiTouchInputMapper* mapper, int32_t distance);
-    void processId(MultiTouchInputMapper* mapper, int32_t id);
-    void processSlot(MultiTouchInputMapper* mapper, int32_t slot);
-    void processToolType(MultiTouchInputMapper* mapper, int32_t toolType);
-    void processKey(MultiTouchInputMapper* mapper, int32_t code, int32_t value);
-    void processMTSync(MultiTouchInputMapper* mapper);
-    void processSync(MultiTouchInputMapper* mapper);
-};
-
-void MultiTouchInputMapperTest::prepareAxes(int axes) {
-    if (axes & POSITION) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_X,
-                RAW_X_MIN, RAW_X_MAX, 0, 0);
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_POSITION_Y,
-                RAW_Y_MIN, RAW_Y_MAX, 0, 0);
-    }
-    if (axes & TOUCH) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR,
-                RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
-        if (axes & MINOR) {
-            mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
-                    RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
-        }
-    }
-    if (axes & TOOL) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR,
-                RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
-        if (axes & MINOR) {
-            mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
-                    RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
-        }
-    }
-    if (axes & ORIENTATION) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_ORIENTATION,
-                RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
-    }
-    if (axes & PRESSURE) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_PRESSURE,
-                RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
-    }
-    if (axes & DISTANCE) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_DISTANCE,
-                RAW_DISTANCE_MIN, RAW_DISTANCE_MAX, 0, 0);
-    }
-    if (axes & ID) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
-                RAW_ID_MIN, RAW_ID_MAX, 0, 0);
-    }
-    if (axes & SLOT) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_SLOT,
-                RAW_SLOT_MIN, RAW_SLOT_MAX, 0, 0);
-        mFakeEventHub->setAbsoluteAxisValue(DEVICE_ID, ABS_MT_SLOT, 0);
-    }
-    if (axes & TOOL_TYPE) {
-        mFakeEventHub->addAbsoluteAxis(DEVICE_ID, ABS_MT_TOOL_TYPE,
-                0, MT_TOOL_MAX, 0, 0);
-    }
-}
-
-void MultiTouchInputMapperTest::processPosition(
-        MultiTouchInputMapper* mapper, int32_t x, int32_t y) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_X, x);
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_Y, y);
-}
-
-void MultiTouchInputMapperTest::processTouchMajor(
-        MultiTouchInputMapper* mapper, int32_t touchMajor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MAJOR, touchMajor);
-}
-
-void MultiTouchInputMapperTest::processTouchMinor(
-        MultiTouchInputMapper* mapper, int32_t touchMinor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MINOR, touchMinor);
-}
-
-void MultiTouchInputMapperTest::processToolMajor(
-        MultiTouchInputMapper* mapper, int32_t toolMajor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MAJOR, toolMajor);
-}
-
-void MultiTouchInputMapperTest::processToolMinor(
-        MultiTouchInputMapper* mapper, int32_t toolMinor) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MINOR, toolMinor);
-}
-
-void MultiTouchInputMapperTest::processOrientation(
-        MultiTouchInputMapper* mapper, int32_t orientation) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_ORIENTATION, orientation);
-}
-
-void MultiTouchInputMapperTest::processPressure(
-        MultiTouchInputMapper* mapper, int32_t pressure) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, pressure);
-}
-
-void MultiTouchInputMapperTest::processDistance(
-        MultiTouchInputMapper* mapper, int32_t distance) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_DISTANCE, distance);
-}
-
-void MultiTouchInputMapperTest::processId(
-        MultiTouchInputMapper* mapper, int32_t id) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, id);
-}
-
-void MultiTouchInputMapperTest::processSlot(
-        MultiTouchInputMapper* mapper, int32_t slot) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_SLOT, slot);
-}
-
-void MultiTouchInputMapperTest::processToolType(
-        MultiTouchInputMapper* mapper, int32_t toolType) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOOL_TYPE, toolType);
-}
-
-void MultiTouchInputMapperTest::processKey(
-        MultiTouchInputMapper* mapper, int32_t code, int32_t value) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, code, value);
-}
-
-void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0);
-}
-
-void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) {
-    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0);
-}
-
-
-TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyMotionArgs motionArgs;
-
-    // Two fingers down at once.
-    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
-    processPosition(mapper, x1, y1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Move.
-    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
-    processPosition(mapper, x1, y1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // First finger up.
-    x2 += 15; y2 -= 20;
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Move.
-    x2 += 20; y2 -= 25;
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // New finger down.
-    int32_t x3 = 700, y3 = 300;
-    processPosition(mapper, x2, y2);
-    processMTSync(mapper);
-    processPosition(mapper, x3, y3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Second finger up.
-    x3 += 30; y3 -= 20;
-    processPosition(mapper, x3, y3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Last finger up.
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
-    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
-    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
-    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.flags);
-    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(0, motionArgs.edgeFlags);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
-    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
-    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | ID);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyMotionArgs motionArgs;
-
-    // Two fingers down at once.
-    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
-    processPosition(mapper, x1, y1);
-    processId(mapper, 1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Move.
-    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
-    processPosition(mapper, x1, y1);
-    processId(mapper, 1);
-    processMTSync(mapper);
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // First finger up.
-    x2 += 15; y2 -= 20;
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Move.
-    x2 += 20; y2 -= 25;
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // New finger down.
-    int32_t x3 = 700, y3 = 300;
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processMTSync(mapper);
-    processPosition(mapper, x3, y3);
-    processId(mapper, 3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Second finger up.
-    x3 += 30; y3 -= 20;
-    processPosition(mapper, x3, y3);
-    processId(mapper, 3);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Last finger up.
-    processMTSync(mapper);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithSlots) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | ID | SLOT);
-    prepareVirtualKeys();
-    addMapperAndConfigure(mapper);
-
-    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
-
-    NotifyMotionArgs motionArgs;
-
-    // Two fingers down at once.
-    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
-    processPosition(mapper, x1, y1);
-    processId(mapper, 1);
-    processSlot(mapper, 1);
-    processPosition(mapper, x2, y2);
-    processId(mapper, 2);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Move.
-    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
-    processSlot(mapper, 0);
-    processPosition(mapper, x1, y1);
-    processSlot(mapper, 1);
-    processPosition(mapper, x2, y2);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // First finger up.
-    x2 += 15; y2 -= 20;
-    processSlot(mapper, 0);
-    processId(mapper, -1);
-    processSlot(mapper, 1);
-    processPosition(mapper, x2, y2);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Move.
-    x2 += 20; y2 -= 25;
-    processPosition(mapper, x2, y2);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(1, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // New finger down.
-    int32_t x3 = 700, y3 = 300;
-    processPosition(mapper, x2, y2);
-    processSlot(mapper, 0);
-    processId(mapper, 3);
-    processPosition(mapper, x3, y3);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Second finger up.
-    x3 += 30; y3 -= 20;
-    processSlot(mapper, 1);
-    processId(mapper, -1);
-    processSlot(mapper, 0);
-    processPosition(mapper, x3, y3);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            motionArgs.action);
-    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_EQ(1, motionArgs.pointerProperties[1].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[1].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
-            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Last finger up.
-    processId(mapper, -1);
-    processSync(mapper);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
-    ASSERT_EQ(0, motionArgs.pointerProperties[0].id);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // Should not have sent any more keys or motions.
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasNotCalled());
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR | DISTANCE);
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawTouchMajor = 7;
-    int32_t rawTouchMinor = 6;
-    int32_t rawToolMajor = 9;
-    int32_t rawToolMinor = 8;
-    int32_t rawPressure = 11;
-    int32_t rawDistance = 0;
-    int32_t rawOrientation = 3;
-    int32_t id = 5;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
-    float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
-    float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
-    float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
-    float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
-    float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
-    float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
-    float distance = float(rawDistance);
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processTouchMinor(mapper, rawTouchMinor);
-    processToolMajor(mapper, rawToolMajor);
-    processToolMinor(mapper, rawToolMinor);
-    processPressure(mapper, rawPressure);
-    processOrientation(mapper, rawOrientation);
-    processDistance(mapper, rawDistance);
-    processId(mapper, id);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(0, args.pointerProperties[0].id);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor,
-            orientation, distance));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL | MINOR);
-    addConfigurationProperty("touch.size.calibration", "geometric");
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawTouchMajor = 140;
-    int32_t rawTouchMinor = 120;
-    int32_t rawToolMajor = 180;
-    int32_t rawToolMinor = 160;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float size = avg(rawTouchMajor, rawTouchMinor) / RAW_TOUCH_MAX;
-    float toolMajor = float(rawToolMajor) * GEOMETRIC_SCALE;
-    float toolMinor = float(rawToolMinor) * GEOMETRIC_SCALE;
-    float touchMajor = float(rawTouchMajor) * GEOMETRIC_SCALE;
-    float touchMinor = float(rawTouchMinor) * GEOMETRIC_SCALE;
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processTouchMinor(mapper, rawTouchMinor);
-    processToolMajor(mapper, rawToolMajor);
-    processToolMinor(mapper, rawToolMinor);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, 1.0f, size, touchMajor, touchMinor, toolMajor, toolMinor, 0, 0));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_SummedLinearCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL);
-    addConfigurationProperty("touch.size.calibration", "diameter");
-    addConfigurationProperty("touch.size.scale", "10");
-    addConfigurationProperty("touch.size.bias", "160");
-    addConfigurationProperty("touch.size.isSummed", "1");
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    // Note: We only provide a single common touch/tool value because the device is assumed
-    //       not to emit separate values for each pointer (isSummed = 1).
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawX2 = 150;
-    int32_t rawY2 = 250;
-    int32_t rawTouchMajor = 5;
-    int32_t rawToolMajor = 8;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float x2 = toDisplayX(rawX2);
-    float y2 = toDisplayY(rawY2);
-    float size = float(rawTouchMajor) / 2 / RAW_TOUCH_MAX;
-    float touch = float(rawTouchMajor) / 2 * 10.0f + 160.0f;
-    float tool = float(rawToolMajor) / 2 * 10.0f + 160.0f;
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processToolMajor(mapper, rawToolMajor);
-    processMTSync(mapper);
-    processPosition(mapper, rawX2, rawY2);
-    processTouchMajor(mapper, rawTouchMajor);
-    processToolMajor(mapper, rawToolMajor);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
-            args.action);
-    ASSERT_EQ(size_t(2), args.pointerCount);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
-            x2, y2, 1.0f, size, touch, touch, tool, tool, 0, 0));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_AreaCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | TOUCH | TOOL);
-    addConfigurationProperty("touch.size.calibration", "area");
-    addConfigurationProperty("touch.size.scale", "43");
-    addConfigurationProperty("touch.size.bias", "3");
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawTouchMajor = 5;
-    int32_t rawToolMajor = 8;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float size = float(rawTouchMajor) / RAW_TOUCH_MAX;
-    float touch = sqrtf(rawTouchMajor) * 43.0f + 3.0f;
-    float tool = sqrtf(rawToolMajor) * 43.0f + 3.0f;
-
-    processPosition(mapper, rawX, rawY);
-    processTouchMajor(mapper, rawTouchMajor);
-    processToolMajor(mapper, rawToolMajor);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, 1.0f, size, touch, touch, tool, tool, 0, 0));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_PressureAxis_AmplitudeCalibration) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | PRESSURE);
-    addConfigurationProperty("touch.pressure.calibration", "amplitude");
-    addConfigurationProperty("touch.pressure.scale", "0.01");
-    addMapperAndConfigure(mapper);
-
-    // These calculations are based on the input device calibration documentation.
-    int32_t rawX = 100;
-    int32_t rawY = 200;
-    int32_t rawPressure = 60;
-
-    float x = toDisplayX(rawX);
-    float y = toDisplayY(rawY);
-    float pressure = float(rawPressure) * 0.01f;
-
-    processPosition(mapper, rawX, rawY);
-    processPressure(mapper, rawPressure);
-    processMTSync(mapper);
-    processSync(mapper);
-
-    NotifyMotionArgs args;
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
-            x, y, pressure, 0, 0, 0, 0, 0, 0, 0));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllButtons) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | ID | SLOT);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-    NotifyKeyArgs keyArgs;
-
-    processId(mapper, 1);
-    processPosition(mapper, 100, 200);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.buttonState);
-
-    // press BTN_LEFT, release BTN_LEFT
-    processKey(mapper, BTN_LEFT, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_PRIMARY, motionArgs.buttonState);
-
-    processKey(mapper, BTN_LEFT, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // press BTN_RIGHT + BTN_MIDDLE, release BTN_RIGHT, release BTN_MIDDLE
-    processKey(mapper, BTN_RIGHT, 1);
-    processKey(mapper, BTN_MIDDLE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY | AMOTION_EVENT_BUTTON_TERTIARY,
-            motionArgs.buttonState);
-
-    processKey(mapper, BTN_RIGHT, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_MIDDLE, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // press BTN_BACK, release BTN_BACK
-    processKey(mapper, BTN_BACK, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_BACK, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-
-    // press BTN_SIDE, release BTN_SIDE
-    processKey(mapper, BTN_SIDE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_BACK, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_SIDE, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_BACK, keyArgs.keyCode);
-
-    // press BTN_FORWARD, release BTN_FORWARD
-    processKey(mapper, BTN_FORWARD, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_FORWARD, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-
-    // press BTN_EXTRA, release BTN_EXTRA
-    processKey(mapper, BTN_EXTRA, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_FORWARD, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    processKey(mapper, BTN_EXTRA, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&keyArgs));
-    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
-    ASSERT_EQ(AKEYCODE_FORWARD, keyArgs.keyCode);
-
-    // press BTN_STYLUS, release BTN_STYLUS
-    processKey(mapper, BTN_STYLUS, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_SECONDARY, motionArgs.buttonState);
-
-    processKey(mapper, BTN_STYLUS, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // press BTN_STYLUS2, release BTN_STYLUS2
-    processKey(mapper, BTN_STYLUS2, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_BUTTON_TERTIARY, motionArgs.buttonState);
-
-    processKey(mapper, BTN_STYLUS2, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(0, motionArgs.buttonState);
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-
-    // release touch
-    processId(mapper, -1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_EQ(0, motionArgs.buttonState);
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_ShouldHandleAllToolTypes) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-
-    // default tool type is finger
-    processId(mapper, 1);
-    processPosition(mapper, 100, 200);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // eraser
-    processKey(mapper, BTN_TOOL_RUBBER, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
-
-    // stylus
-    processKey(mapper, BTN_TOOL_RUBBER, 0);
-    processKey(mapper, BTN_TOOL_PEN, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // brush
-    processKey(mapper, BTN_TOOL_PEN, 0);
-    processKey(mapper, BTN_TOOL_BRUSH, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // pencil
-    processKey(mapper, BTN_TOOL_BRUSH, 0);
-    processKey(mapper, BTN_TOOL_PENCIL, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // airbrush
-    processKey(mapper, BTN_TOOL_PENCIL, 0);
-    processKey(mapper, BTN_TOOL_AIRBRUSH, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // mouse
-    processKey(mapper, BTN_TOOL_AIRBRUSH, 0);
-    processKey(mapper, BTN_TOOL_MOUSE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
-
-    // lens
-    processKey(mapper, BTN_TOOL_MOUSE, 0);
-    processKey(mapper, BTN_TOOL_LENS, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
-
-    // double-tap
-    processKey(mapper, BTN_TOOL_LENS, 0);
-    processKey(mapper, BTN_TOOL_DOUBLETAP, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // triple-tap
-    processKey(mapper, BTN_TOOL_DOUBLETAP, 0);
-    processKey(mapper, BTN_TOOL_TRIPLETAP, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // quad-tap
-    processKey(mapper, BTN_TOOL_TRIPLETAP, 0);
-    processKey(mapper, BTN_TOOL_QUADTAP, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // finger
-    processKey(mapper, BTN_TOOL_QUADTAP, 0);
-    processKey(mapper, BTN_TOOL_FINGER, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // stylus trumps finger
-    processKey(mapper, BTN_TOOL_PEN, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // eraser trumps stylus
-    processKey(mapper, BTN_TOOL_RUBBER, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_ERASER, motionArgs.pointerProperties[0].toolType);
-
-    // mouse trumps eraser
-    processKey(mapper, BTN_TOOL_MOUSE, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_MOUSE, motionArgs.pointerProperties[0].toolType);
-
-    // MT tool type trumps BTN tool types: MT_TOOL_FINGER
-    processToolType(mapper, MT_TOOL_FINGER); // this is the first time we send MT_TOOL_TYPE
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-
-    // MT tool type trumps BTN tool types: MT_TOOL_PEN
-    processToolType(mapper, MT_TOOL_PEN);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_STYLUS, motionArgs.pointerProperties[0].toolType);
-
-    // back to default tool type
-    processToolType(mapper, -1); // use a deliberately undefined tool type, for testing
-    processKey(mapper, BTN_TOOL_MOUSE, 0);
-    processKey(mapper, BTN_TOOL_RUBBER, 0);
-    processKey(mapper, BTN_TOOL_PEN, 0);
-    processKey(mapper, BTN_TOOL_FINGER, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
-    ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_WhenBtnTouchPresent_HoversIfItsValueIsZero) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | ID | SLOT);
-    mFakeEventHub->addKey(DEVICE_ID, BTN_TOUCH, 0, AKEYCODE_UNKNOWN, 0);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-
-    // initially hovering because BTN_TOUCH not sent yet, pressure defaults to 0
-    processId(mapper, 1);
-    processPosition(mapper, 100, 200);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // move a little
-    processPosition(mapper, 150, 250);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // down when BTN_TOUCH is pressed, pressure defaults to 1
-    processKey(mapper, BTN_TOUCH, 1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // up when BTN_TOUCH is released, hover restored
-    processKey(mapper, BTN_TOUCH, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // exit hover when pointer goes away
-    processId(mapper, -1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-}
-
-TEST_F(MultiTouchInputMapperTest, Process_WhenAbsMTPressureIsPresent_HoversIfItsValueIsZero) {
-    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
-    addConfigurationProperty("touch.deviceType", "touchScreen");
-    prepareDisplay(DISPLAY_ORIENTATION_0);
-    prepareAxes(POSITION | ID | SLOT | PRESSURE);
-    addMapperAndConfigure(mapper);
-
-    NotifyMotionArgs motionArgs;
-
-    // initially hovering because pressure is 0
-    processId(mapper, 1);
-    processPosition(mapper, 100, 200);
-    processPressure(mapper, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(100), toDisplayY(200), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // move a little
-    processPosition(mapper, 150, 250);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // down when pressure becomes non-zero
-    processPressure(mapper, RAW_PRESSURE_MAX);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    // up when pressure becomes 0, hover restored
-    processPressure(mapper, 0);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 1, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_ENTER, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_MOVE, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-
-    // exit hover when pointer goes away
-    processId(mapper, -1);
-    processSync(mapper);
-    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
-    ASSERT_EQ(AMOTION_EVENT_ACTION_HOVER_EXIT, motionArgs.action);
-    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
-            toDisplayX(150), toDisplayY(250), 0, 0, 0, 0, 0, 0, 0, 0));
-}
-
-
-} // namespace android
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
index 300224a..3e07155 100644
--- a/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/accessorychat/Android.mk
@@ -11,7 +11,6 @@
 
 LOCAL_MODULE := accessorychat
 
-LOCAL_C_INCLUDES += bionic/libc/kernel/common
 LOCAL_STATIC_LIBRARIES := libusbhost libcutils
 LOCAL_LDLIBS += -lpthread
 LOCAL_CFLAGS := -g -O0
diff --git a/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h b/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h
new file mode 100644
index 0000000..75e017c
--- /dev/null
+++ b/libs/usb/tests/AccessoryChat/accessorychat/linux/usb/f_accessory.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ ****************************************************************************
+ ***
+ ***   This header was automatically generated from a Linux kernel header
+ ***   of the same name, to make information necessary for userspace to
+ ***   call into the kernel available to libc.  It contains only constants,
+ ***   structures, and macros generated from the original header, and thus,
+ ***   contains no copyrightable information.
+ ***
+ ***   To edit the content of this header, modify the corresponding
+ ***   source file (e.g. under external/kernel-headers/original/) then
+ ***   run bionic/libc/kernel/tools/update_all.py
+ ***
+ ***   Any manual change here will be lost the next time this script will
+ ***   be run. You've been warned!
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_LINUX_USB_F_ACCESSORY_H
+#define _UAPI_LINUX_USB_F_ACCESSORY_H
+#define USB_ACCESSORY_VENDOR_ID 0x18D1
+#define USB_ACCESSORY_PRODUCT_ID 0x2D00
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define USB_ACCESSORY_ADB_PRODUCT_ID 0x2D01
+#define ACCESSORY_STRING_MANUFACTURER 0
+#define ACCESSORY_STRING_MODEL 1
+#define ACCESSORY_STRING_DESCRIPTION 2
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_STRING_VERSION 3
+#define ACCESSORY_STRING_URI 4
+#define ACCESSORY_STRING_SERIAL 5
+#define ACCESSORY_GET_PROTOCOL 51
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SEND_STRING 52
+#define ACCESSORY_START 53
+#define ACCESSORY_REGISTER_HID 54
+#define ACCESSORY_UNREGISTER_HID 55
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_SET_HID_REPORT_DESC 56
+#define ACCESSORY_SEND_HID_EVENT 57
+#define ACCESSORY_SET_AUDIO_MODE 58
+#define ACCESSORY_GET_STRING_MANUFACTURER _IOW('M', 1, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_MODEL _IOW('M', 2, char[256])
+#define ACCESSORY_GET_STRING_DESCRIPTION _IOW('M', 3, char[256])
+#define ACCESSORY_GET_STRING_VERSION _IOW('M', 4, char[256])
+#define ACCESSORY_GET_STRING_URI _IOW('M', 5, char[256])
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define ACCESSORY_GET_STRING_SERIAL _IOW('M', 6, char[256])
+#define ACCESSORY_IS_START_REQUESTED _IO('M', 7)
+#define ACCESSORY_GET_AUDIO_MODE _IO('M', 8)
+#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index ccb4304..36778aa 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 
 
+import java.lang.SecurityException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -1104,13 +1105,18 @@
      * unless they depend on provider-specific APIs such as
      * {@link #requestLocationUpdates(String, long, float, LocationListener)}.
      *
+     * <p>
+     * Before API version 20, this method would throw {@link SecurityException}
+     * if the location permissions were not sufficient to use the specified
+     * provider.
+     *
      * @param provider the name of the provider
      * @return true if the provider exists and is enabled
      *
      * @throws IllegalArgumentException if provider is null
-     * @throws SecurityException if no suitable permission is present
      */
     public boolean isProviderEnabled(String provider) {
+        // STOPSHIP: finalize API version number in javadoc
         checkProvider(provider);
 
         try {
@@ -1610,7 +1616,7 @@
      * @hide
      */
     public boolean sendNiResponse(int notifId, int userResponse) {
-    	try {
+        try {
             return mService.sendNiResponse(notifId, userResponse);
         } catch (RemoteException e) {
             Log.e(TAG, "RemoteException in sendNiResponse: ", e);
diff --git a/location/java/android/location/SettingInjectorService.java b/location/java/android/location/SettingInjectorService.java
index 9f321f3..98c7864 100644
--- a/location/java/android/location/SettingInjectorService.java
+++ b/location/java/android/location/SettingInjectorService.java
@@ -26,7 +26,7 @@
 import android.util.Log;
 
 /**
- * Dynamically specifies the summary (subtitle) and enabled status of a preference injected into
+ * Dynamically specifies the 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
@@ -71,13 +71,12 @@
  * </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.
+ * and {@link #onGetEnabled()} methods must all be fast. If either is slow,
+ * it can delay the display of settings values for other apps as well. Note further that these
+ * methods 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
+ * distinct value for the setting, then only {@code settingsActivity} should display the value for
  * each account.
  */
 public abstract class SettingInjectorService extends Service {
@@ -109,14 +108,6 @@
             "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
@@ -160,42 +151,31 @@
 
     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);
+            sendStatus(intent, true);
             throw e;
         }
 
-        sendStatus(intent, summary, enabled);
+        sendStatus(intent, enabled);
     }
 
     /**
-     * Send the summary and enabled values back to the caller via the messenger encoded in the
+     * Send the enabled values back to the caller via the messenger encoded in the
      * intent.
      */
-    private void sendStatus(Intent intent, String summary, boolean enabled) {
+    private void sendStatus(Intent intent, 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
+            Log.d(TAG, mName + ": received " + intent
                     + ", enabled=" + enabled + ", sending message: " + message);
         }
 
@@ -208,13 +188,18 @@
     }
 
     /**
-     * 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.
+     * This method is no longer called, because status values are no longer shown for any injected
+     * setting.
      *
-     * @return the {@link android.preference.Preference#getSummary()} value
+     * @return ignored
+     *
+     * @deprecated not called any more
      */
-    protected abstract String onGetSummary();
+    @Deprecated
+    protected String onGetSummary() {
+        // Do not delete until no callers have @Override annotations for this method
+        return null;
+    }
 
     /**
      * Returns the {@link android.preference.Preference#isEnabled()} value. Should not perform
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index 57e2786..b33ba00 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -25,7 +25,6 @@
 import android.content.Intent;
 import android.location.LocationManager;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 
diff --git a/location/lib/java/com/android/location/provider/GeofenceProvider.java b/location/lib/java/com/android/location/provider/GeofenceProvider.java
index 2618f34..fafaa84 100644
--- a/location/lib/java/com/android/location/provider/GeofenceProvider.java
+++ b/location/lib/java/com/android/location/provider/GeofenceProvider.java
@@ -21,9 +21,6 @@
 import android.os.IBinder;
 
 import android.location.IGeofenceProvider;
-import android.util.Log;
-
-import java.lang.Long;
 
 /**
  * Base class for geofence providers implemented as unbundled services.
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index 150c289..d717f40 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -24,7 +24,6 @@
 import android.location.ILocationManager;
 import android.location.Location;
 import android.location.LocationManager;
-import android.location.LocationRequest;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
diff --git a/media/java/android/media/AmrInputStream.java b/media/java/android/media/AmrInputStream.java
index e2115e4..f90f1e2 100644
--- a/media/java/android/media/AmrInputStream.java
+++ b/media/java/android/media/AmrInputStream.java
@@ -16,8 +16,6 @@
 
 package android.media;
 
-import android.util.Log;
-
 import java.io.InputStream;
 import java.io.IOException;
 
diff --git a/media/java/android/media/AsyncPlayer.java b/media/java/android/media/AsyncPlayer.java
index 804528e..14b199e 100644
--- a/media/java/android/media/AsyncPlayer.java
+++ b/media/java/android/media/AsyncPlayer.java
@@ -22,8 +22,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 
-import java.io.IOException;
-import java.lang.IllegalStateException;
 import java.util.LinkedList;
 
 /**
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 49f498e..26e9cc5 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -31,7 +31,8 @@
     public static final int ENCODING_INVALID = 0;
     /** Default audio data format */
     public static final int ENCODING_DEFAULT = 1;
-    // These two values must be kept in sync with JNI code for AudioTrack, AudioRecord
+
+    // These two values must be kept in sync with core/jni/android_media_AudioFormat.h
     /** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */
     public static final int ENCODING_PCM_16BIT = 2;
     /** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d652cae..8ae06e0 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -26,7 +26,6 @@
 import android.content.Intent;
 import android.media.RemoteController.OnClientUpdateListener;
 import android.os.Binder;
-import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 461b52f..a4891f8 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -179,13 +179,16 @@
     /**
      * Audio session ID
      */
-    private int mSessionId = 0;
+    private int mSessionId = AudioSystem.AUDIO_SESSION_ALLOCATE;
 
     //---------------------------------------------------------
     // Constructor, Finalize
     //--------------------
     /**
      * Class constructor.
+     * Though some invalid parameters will result in an {@link IllegalArgumentException} exception,
+     * other errors do not.  Thus you should call {@link #getState()} immediately after construction
+     * to confirm that the object is usable.
      * @param audioSource the recording source. See {@link MediaRecorder.AudioSource} for
      *    recording source definitions.
      * @param sampleRateInHz the sample rate expressed in Hertz. 44100Hz is currently the only
@@ -221,7 +224,7 @@
 
         // native initialization
         int[] session = new int[1];
-        session[0] = 0;
+        session[0] = AudioSystem.AUDIO_SESSION_ALLOCATE;
         //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),
@@ -239,7 +242,7 @@
 
 
     // Convenience method for the constructor's parameter checks.
-    // This is where constructor IllegalArgumentException-s are thrown
+    // This and audioBuffSizeCheck are where constructor IllegalArgumentException-s are thrown
     // postconditions:
     //    mRecordSource is valid
     //    mChannelCount is valid
@@ -247,7 +250,8 @@
     //    mAudioFormat is valid
     //    mSampleRate is valid
     private void audioParamCheck(int audioSource, int sampleRateInHz,
-                                 int channelConfig, int audioFormat) {
+                                 int channelConfig, int audioFormat)
+            throws IllegalArgumentException {
 
         //--------------
         // audio source
@@ -311,7 +315,7 @@
     //    mAudioFormat is AudioFormat.ENCODING_PCM_8BIT OR AudioFormat.ENCODING_PCM_16BIT
     // postcondition:
     //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
-    private void audioBuffSizeCheck(int audioBufferSize) {
+    private void audioBuffSizeCheck(int audioBufferSize) throws IllegalArgumentException {
         // NB: this section is only valid with PCM data.
         // To update when supporting compressed formats
         int frameSizeInBytes = mChannelCount
@@ -800,7 +804,7 @@
     //--------------------
 
     private native final int native_setup(Object audiorecord_this,
-            int recordSource, int sampleRate, int nbChannels, int audioFormat,
+            int recordSource, int sampleRate, int channelMask, int audioFormat,
             int buffSizeInBytes, int[] sessionId);
 
     private native final void native_finalize();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 92474df..fe510f6 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -21,20 +21,17 @@
 import static android.media.AudioManager.RINGER_MODE_SILENT;
 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.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothClass;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothHeadset;
 import android.bluetooth.BluetoothProfile;
-import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -48,12 +45,8 @@
 import android.database.ContentObserver;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
-import android.net.Uri;
-import android.net.http.CertificateChainValidator;
-import android.net.http.SslError;
 import android.os.Binder;
 import android.os.Build;
-import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
@@ -68,9 +61,6 @@
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.provider.Settings.System;
-import android.speech.RecognizerIntent;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -83,22 +73,18 @@
 
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.io.ByteArrayInputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.lang.reflect.Field;
-import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.Set;
-import java.util.Stack;
 
 /**
  * The implementation of the volume manager service.
@@ -120,8 +106,6 @@
     protected static final boolean DEBUG_RC = false;
     /** Debug volumes */
     protected static final boolean DEBUG_VOL = false;
-    /** Debug cert verification */
-    private static final boolean DEBUG_CERTS = false;
 
     /** How long to delay before persisting a change in volume/ringer mode. */
     private static final int PERSIST_DELAY = 500;
@@ -274,7 +258,7 @@
     private final boolean mUseFixedVolume;
 
     // stream names used by dumpStreamStates()
-    private final String[] STREAM_NAMES = new String[] {
+    private static final String[] STREAM_NAMES = new String[] {
             "STREAM_VOICE_CALL",
             "STREAM_SYSTEM",
             "STREAM_RING",
@@ -630,6 +614,12 @@
         pw.println(Integer.toHexString(mMuteAffectedStreams));
     }
 
+    /** @hide */
+    public static String streamToString(int stream) {
+        if (stream >= 0 && stream < STREAM_NAMES.length) return STREAM_NAMES[stream];
+        if (stream == AudioManager.USE_DEFAULT_STREAM_TYPE) return "USE_DEFAULT_STREAM_TYPE";
+        return "UNKNOWN_STREAM_" + stream;
+    }
 
     private void updateStreamVolumeAlias(boolean updateVolumes) {
         int dtmfStreamAlias;
@@ -4587,43 +4577,6 @@
         }
     }
 
-    public int verifyX509CertChain(int numcerts, byte [] chain, String domain, String authType) {
-
-        if (DEBUG_CERTS) {
-            Log.v(TAG, "java side verify for "
-                    + numcerts + " certificates (" + chain.length + " bytes"
-                            + ")for "+ domain + "/" + authType);
-        }
-
-        byte[][] certChain = new byte[numcerts][];
-
-        ByteBuffer buf = ByteBuffer.wrap(chain);
-        for (int i = 0; i < numcerts; i++) {
-            int certlen = buf.getInt();
-            if (DEBUG_CERTS) {
-                Log.i(TAG, "cert " + i +": " + certlen);
-            }
-            certChain[i] = new byte[certlen];
-            buf.get(certChain[i]);
-        }
-
-        try {
-            SslError err = CertificateChainValidator.verifyServerCertificates(certChain,
-                    domain, authType);
-            if (DEBUG_CERTS) {
-                Log.i(TAG, "verified: " + err);
-            }
-            if (err == null) {
-                return -1;
-            } else {
-                return err.getPrimaryError();
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "failed to verify chain: " + e);
-        }
-        return SslError.SSL_INVALID;
-    }
-
 
     //==========================================================================================
     // Camera shutter sound policy.
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 661b0fd..9c67bae 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -103,6 +103,9 @@
     /** @deprecated */
     @Deprecated public static final int ROUTE_ALL               = 0xFFFFFFFF;
 
+    // Keep in sync with system/core/include/system/audio.h
+    public static final int AUDIO_SESSION_ALLOCATE = 0;
+
     /*
      * Checks whether the specified stream type is active.
      *
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 01a6fc2..40c6797 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -16,13 +16,27 @@
 
 package android.media;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.NioUtils;
 
+import android.annotation.IntDef;
+import android.app.ActivityThread;
+import android.app.AppOpsManager;
+import android.content.Context;
 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.util.Log;
 
+import com.android.internal.app.IAppOpsService;
+
 
 /**
  * The AudioTrack class manages and plays a single audio resource for Java applications.
@@ -145,6 +159,28 @@
     private final static String TAG = "android.media.AudioTrack";
 
 
+    /** @hide */
+    @IntDef({
+        WRITE_BLOCKING,
+        WRITE_NON_BLOCKING
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteMode {}
+
+    /**
+     * @hide CANDIDATE FOR PUBLIC API
+     * The write mode indicating the write operation will block until all data has been written,
+     * to be used in {@link #write(ByteBuffer, int, int, int)}.
+     */
+    public final static int WRITE_BLOCKING = 0;
+    /**
+     * @hide CANDIDATE FOR PUBLIC API
+     * The write mode indicating the write operation will return immediately after
+     * queuing as much audio data for playback as possible without blocking, to be used in
+     * {@link #write(ByteBuffer, int, int, int)}.
+     */
+    public final static int WRITE_NON_BLOCKING = 1;
+
     //--------------------------------------------------------------------------
     // Member variables
     //--------------------
@@ -211,8 +247,11 @@
     /**
      * Audio session ID
      */
-    private int mSessionId = 0;
-
+    private int mSessionId = AudioSystem.AUDIO_SESSION_ALLOCATE;
+    /**
+     * Reference to the app-ops service.
+     */
+    private final IAppOpsService mAppOps;
 
     //--------------------------------
     // Used exclusively by native code
@@ -263,7 +302,7 @@
             int bufferSizeInBytes, int mode)
     throws IllegalArgumentException {
         this(streamType, sampleRateInHz, channelConfig, audioFormat,
-                bufferSizeInBytes, mode, 0 /*session*/);
+                bufferSizeInBytes, mode, AudioSystem.AUDIO_SESSION_ALLOCATE);
     }
 
     /**
@@ -316,6 +355,9 @@
 
         audioBuffSizeCheck(bufferSizeInBytes);
 
+        IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
+        mAppOps = IAppOpsService.Stub.asInterface(b);
+
         if (sessionId < 0) {
             throw new IllegalArgumentException("Invalid audio session ID: "+sessionId);
         }
@@ -814,6 +856,9 @@
      *    {@link #ERROR_INVALID_OPERATION}
      */
     public int setStereoVolume(float leftVolume, float rightVolume) {
+        if (isRestricted()) {
+            return SUCCESS;
+        }
         if (mState == STATE_UNINITIALIZED) {
             return ERROR_INVALID_OPERATION;
         }
@@ -839,8 +884,12 @@
 
 
     /**
-     * Similar, except set volume of all channels to same value.
-     * @hide
+     * Sets the specified output volume values on all channels of this track.  The value is clamped
+     * to the ({@link #getMinVolume()}, {@link #getMaxVolume()}) interval if outside this range.
+     * @param volume output attenuation for all channels. A value of 0.0f is silence,
+     *      a value of 1.0f is no attenuation.
+     * @return error code or success, see {@link #SUCCESS},
+     *    {@link #ERROR_INVALID_OPERATION}
      */
     public int setVolume(float volume) {
         return setStereoVolume(volume, volume);
@@ -983,13 +1032,25 @@
         if (mState != STATE_INITIALIZED) {
             throw new IllegalStateException("play() called on uninitialized AudioTrack.");
         }
-
+        if (isRestricted()) {
+            setVolume(0);
+        }
         synchronized(mPlayStateLock) {
             native_start();
             mPlayState = PLAYSTATE_PLAYING;
         }
     }
 
+    private boolean isRestricted() {
+        try {
+            final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, mStreamType,
+                    Process.myUid(), ActivityThread.currentPackageName());
+            return mode != AppOpsManager.MODE_ALLOWED;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
     /**
      * Stops playing the audio data.
      * When used on an instance created in {@link #MODE_STREAM} mode, audio will stop playing
@@ -1080,7 +1141,8 @@
             return ERROR_BAD_VALUE;
         }
 
-        int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat);
+        int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
+                true /*isBlocking*/);
 
         if ((mDataLoadMode == MODE_STATIC)
                 && (mState == STATE_NO_STATIC_DATA)
@@ -1137,6 +1199,73 @@
 
 
     /**
+     * @hide CANDIDATE FOR PUBLIC API
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * In static buffer mode, copies the data to the buffer starting at its 0 offset, and the write
+     * mode is ignored.
+     * In streaming mode, the blocking behavior will depend on the write mode.
+     * @param audioData the buffer that holds the data to play, starting at the position reported
+     *     by <code>audioData.position()</code>.
+     *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
+     *     have been advanced to reflect the amount of data that was successfully written to
+     *     the AudioTrack.
+     * @param sizeInBytes number of bytes to write.
+     *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
+     * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
+     *     effect in static mode.
+     *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
+     *         to the audio sink.
+     *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
+     *     queuing as much audio data for playback as possible without blocking.
+     * @return 0 or a positive number of bytes that were written, or
+     *     {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}
+     */
+    public int write(ByteBuffer audioData, int sizeInBytes,
+            @WriteMode int writeMode) {
+
+        if (mState == STATE_UNINITIALIZED) {
+            Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
+            Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) {
+            Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value");
+            return ERROR_BAD_VALUE;
+        }
+
+        int ret = 0;
+        if (audioData.isDirect()) {
+            ret = native_write_native_bytes(audioData,
+                    audioData.position(), sizeInBytes, mAudioFormat,
+                    writeMode == WRITE_BLOCKING);
+        } else {
+            ret = native_write_byte(NioUtils.unsafeArray(audioData),
+                    NioUtils.unsafeArrayOffset(audioData) + audioData.position(),
+                    sizeInBytes, mAudioFormat,
+                    writeMode == WRITE_BLOCKING);
+        }
+
+        if ((mDataLoadMode == MODE_STATIC)
+                && (mState == STATE_NO_STATIC_DATA)
+                && (ret > 0)) {
+            // benign race with respect to other APIs that read mState
+            mState = STATE_INITIALIZED;
+        }
+
+        if (ret > 0) {
+            audioData.position(audioData.position() + ret);
+        }
+
+        return ret;
+    }
+
+    /**
      * Notifies the native resource to reuse the audio data already loaded in the native
      * layer, that is to rewind to start of buffer.
      * The track's creation mode must be {@link #MODE_STATIC}.
@@ -1195,6 +1324,9 @@
      *    {@link #ERROR_INVALID_OPERATION}
      */
     public int setAuxEffectSendLevel(float level) {
+        if (isRestricted()) {
+            return SUCCESS;
+        }
         if (mState == STATE_UNINITIALIZED) {
             return ERROR_INVALID_OPERATION;
         }
@@ -1319,7 +1451,7 @@
     //--------------------
 
     private native final int native_setup(Object audiotrack_this,
-            int streamType, int sampleRate, int nbChannels, int audioFormat,
+            int streamType, int sampleRate, int channelMask, int audioFormat,
             int buffSizeInBytes, int mode, int[] sessionId);
 
     private native final void native_finalize();
@@ -1335,11 +1467,15 @@
     private native final void native_flush();
 
     private native final int native_write_byte(byte[] audioData,
-                                               int offsetInBytes, int sizeInBytes, int format);
+                                               int offsetInBytes, int sizeInBytes, int format,
+                                               boolean isBlocking);
 
     private native final int native_write_short(short[] audioData,
                                                 int offsetInShorts, int sizeInShorts, int format);
 
+    private native final int native_write_native_bytes(Object audioData,
+            int positionInBytes, int sizeInBytes, int format, boolean blocking);
+
     private native final int native_reload_static();
 
     private native final int native_get_native_frame_count();
diff --git a/media/java/android/media/EncoderCapabilities.java b/media/java/android/media/EncoderCapabilities.java
index 71cb1b3..332e360 100644
--- a/media/java/android/media/EncoderCapabilities.java
+++ b/media/java/android/media/EncoderCapabilities.java
@@ -18,7 +18,6 @@
 
 import java.util.List;
 import java.util.ArrayList;
-import android.util.Log;
 
 /**
  * The EncoderCapabilities class is used to retrieve the
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index b5c3631..2f08325 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -35,8 +35,6 @@
  */
 interface IAudioService {
 
-    int verifyX509CertChain(int chainsize, in byte[] chain, String host, String authtype);
-
     void adjustVolume(int direction, int flags, String callingPackage);
 
     boolean isLocalOrRemoteMusicActive();
@@ -238,5 +236,4 @@
     AudioRoutesInfo startWatchingRoutes(in IAudioRoutesObserver observer);
 
     boolean isCameraSoundForced();
-
 }
diff --git a/media/java/android/media/IMediaHTTPConnection.aidl b/media/java/android/media/IMediaHTTPConnection.aidl
new file mode 100644
index 0000000..55ffc2e
--- /dev/null
+++ b/media/java/android/media/IMediaHTTPConnection.aidl
@@ -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.media;
+
+import android.os.IBinder;
+
+/** MUST STAY IN SYNC WITH NATIVE CODE at libmedia/IMediaHTTPConnection.{cpp,h} */
+
+/** @hide */
+interface IMediaHTTPConnection
+{
+    IBinder connect(in String uri, in String headers);
+    void disconnect();
+
+    int readAt(long offset, int size);
+    long getSize();
+    String getMIMEType();
+    String getUri();
+}
+
diff --git a/media/java/android/media/IMediaHTTPService.aidl b/media/java/android/media/IMediaHTTPService.aidl
new file mode 100644
index 0000000..8aaf6b3
--- /dev/null
+++ b/media/java/android/media/IMediaHTTPService.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 android.media;
+
+import android.media.IMediaHTTPConnection;
+
+/** MUST STAY IN SYNC WITH NATIVE CODE at libmedia/IMediaHTTPService.{cpp,h} */
+
+/** @hide */
+interface IMediaHTTPService
+{
+    IMediaHTTPConnection makeHTTPConnection();
+}
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index 23abce7..a346e17 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -21,7 +21,8 @@
 
 /**
  * <p>A single complete image buffer to use with a media source such as a
- * {@link MediaCodec}.</p>
+ * {@link MediaCodec} or a
+ * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p>
  *
  * <p>This class allows for efficient direct application access to the pixel
  * data of the Image through one or more
@@ -82,6 +83,15 @@
      *     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 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 CameraDevice}.
+     *   </td>
+     * </tr>
      * </table>
      *
      * @see android.graphics.ImageFormat
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index d454c42..1bd32c4 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -32,7 +32,8 @@
  * 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}, and
+ * 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>
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index ddf88df..115786c 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -21,8 +21,12 @@
 import android.media.MediaCrypto;
 import android.media.MediaFormat;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.view.Surface;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.Map;
@@ -66,8 +70,8 @@
  *
  * Each codec maintains a number of input and output buffers that are
  * referred to by index in API calls.
- * The contents of these buffers is represented by the ByteBuffer[] arrays
- * accessible through getInputBuffers() and getOutputBuffers().
+ * The contents of these buffers are represented by the ByteBuffer[] arrays
+ * accessible through {@link #getInputBuffers} and {@link #getOutputBuffers}.
  *
  * After a successful call to {@link #start} the client "owns" neither
  * input nor output buffers, subsequent calls to {@link #dequeueInputBuffer}
@@ -117,7 +121,18 @@
  * own any buffers anymore.
  * Note that the format of the data submitted after a flush must not change,
  * flush does not support format discontinuities,
- * for this a full stop(), configure(), start() cycle is necessary.
+ * for this a full {@link #stop}, {@link #configure}, {@link #start}
+ * cycle is necessary.
+ *
+ * <p> The factory methods
+ * {@link #createByCodecName},
+ * {@link #createDecoderByType},
+ * and {@link #createEncoderByType}
+ * throw {@link java.io.IOException} on failure which
+ * the caller must catch or declare to pass up.
+ * Other methods will throw {@link java.lang.IllegalStateException}
+ * if the codec is in an Uninitialized, Invalid, or Error state (e.g. not
+ * initialized properly).  Exceptions are thrown elsewhere as noted. </p>
  *
  */
 final public class MediaCodec {
@@ -161,6 +176,34 @@
      */
     public static final int BUFFER_FLAG_END_OF_STREAM         = 4;
 
+    private EventHandler mEventHandler;
+    private volatile NotificationCallback mNotificationCallback;
+
+    static final int EVENT_NOTIFY = 1;
+
+    private class EventHandler extends Handler {
+        private MediaCodec mCodec;
+
+        public EventHandler(MediaCodec codec, Looper looper) {
+            super(looper);
+            mCodec = codec;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_NOTIFY:
+                {
+                    NotificationCallback cb = mNotificationCallback;
+                    if (cb != null) {
+                        cb.onCodecNotify(mCodec);
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
     /**
      * Instantiate a decoder supporting input data of the given mime type.
      *
@@ -181,16 +224,22 @@
      * </ul>
      *
      * @param type The mime type of the input data.
+     * @throws IOException if the codec cannot be created.
+     * @throws IllegalArgumentException if type is null.
      */
-    public static MediaCodec createDecoderByType(String type) {
+    public static MediaCodec createDecoderByType(String type)
+            throws IOException {
         return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
     }
 
     /**
      * Instantiate an encoder supporting output data of the given mime type.
      * @param type The desired mime type of the output data.
+     * @throws IOException if the codec cannot be created.
+     * @throws IllegalArgumentException if type is null.
      */
-    public static MediaCodec createEncoderByType(String type) {
+    public static MediaCodec createEncoderByType(String type)
+            throws IOException {
         return new MediaCodec(type, true /* nameIsType */, true /* encoder */);
     }
 
@@ -199,14 +248,26 @@
      * use this method to instantiate it. Use with caution.
      * Likely to be used with information obtained from {@link android.media.MediaCodecList}
      * @param name The name of the codec to be instantiated.
+     * @throws IOException if the codec cannot be created.
+     * @throws IllegalArgumentException if name is null.
      */
-    public static MediaCodec createByCodecName(String name) {
+    public static MediaCodec createByCodecName(String name)
+            throws IOException {
         return new MediaCodec(
                 name, false /* nameIsType */, false /* unused */);
     }
 
     private MediaCodec(
             String name, boolean nameIsType, boolean encoder) {
+        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;
+        }
+
         native_setup(name, nameIsType, encoder);
     }
 
@@ -272,6 +333,10 @@
      * <p>
      * The application is responsible for calling release() on the Surface when
      * done.
+     * <p>
+     * The Surface must be rendered with a hardware-accelerated API, such as OpenGL ES.
+     * {@link android.view.Surface#lockCanvas(android.graphics.Rect)} may fail or produce
+     * unexpected results.
      */
     public native final Surface createInputSurface();
 
@@ -287,7 +352,15 @@
      * To ensure that it is available to other client call {@link #release}
      * and don't just rely on garbage collection to eventually do this for you.
      */
-    public native final void stop();
+    public final void stop() {
+        native_stop();
+
+        if (mEventHandler != null) {
+            mEventHandler.removeMessages(EVENT_NOTIFY);
+        }
+    }
+
+    private native final void native_stop();
 
     /**
      * Flush both input and output ports of the component, all indices
@@ -618,6 +691,22 @@
         setParameters(keys, values);
     }
 
+    public void setNotificationCallback(NotificationCallback cb) {
+        mNotificationCallback = cb;
+    }
+
+    public interface NotificationCallback {
+        void onCodecNotify(MediaCodec codec);
+    }
+
+    private void postEventFromNative(
+            int what, int arg1, int arg2, Object obj) {
+        if (mEventHandler != null) {
+            Message msg = mEventHandler.obtainMessage(what, arg1, arg2, obj);
+            mEventHandler.sendMessage(msg);
+        }
+    }
+
     private native final void setParameters(String[] keys, Object[] values);
 
     /**
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index f5a703b..7170ffb 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.media.MediaDrmException;
 import java.lang.ref.WeakReference;
 import java.util.UUID;
 import java.util.HashMap;
@@ -24,7 +23,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Bundle;
 import android.os.Parcel;
 import android.util.Log;
 
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index c3e5035..f2753ee 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -21,7 +21,9 @@
 import android.content.res.AssetFileDescriptor;
 import android.media.MediaCodec;
 import android.media.MediaFormat;
+import android.media.MediaHTTPService;
 import android.net.Uri;
+import android.os.IBinder;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -137,11 +139,19 @@
                 ++i;
             }
         }
-        setDataSource(path, keys, values);
+
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                keys,
+                values);
     }
 
-    private native final void setDataSource(
-            String path, String[] keys, String[] values) throws IOException;
+    private native final void nativeSetDataSource(
+            IBinder httpServiceBinder,
+            String path,
+            String[] keys,
+            String[] values) throws IOException;
 
     /**
      * Sets the data source (file-path or http URL) to use.
@@ -156,7 +166,11 @@
      * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
      */
     public final void setDataSource(String path) throws IOException {
-        setDataSource(path, null, null);
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                null,
+                null);
     }
 
     /**
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 761ecca..526656a 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -16,17 +16,12 @@
 
 package android.media;
 
-import android.content.ContentValues;
-import android.provider.MediaStore.Audio;
-import android.provider.MediaStore.Images;
-import android.provider.MediaStore.Video;
 import android.media.DecoderCapabilities;
 import android.media.DecoderCapabilities.VideoDecoder;
 import android.media.DecoderCapabilities.AudioDecoder;
 import android.mtp.MtpConstants;
 
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 
diff --git a/media/java/android/media/MediaFocusControl.java b/media/java/android/media/MediaFocusControl.java
index 34008bb..b155cda 100644
--- a/media/java/android/media/MediaFocusControl.java
+++ b/media/java/android/media/MediaFocusControl.java
@@ -51,7 +51,6 @@
 import android.util.Slog;
 import android.view.KeyEvent;
 
-import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -263,7 +262,7 @@
                 final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
                 while (displayIterator.hasNext()) {
                     final DisplayInfoForServer di =
-                            (DisplayInfoForServer) displayIterator.next();
+                            displayIterator.next();
                     if (di.mClientNotifListComp != null) {
                         boolean wasEnabled = di.mEnabled;
                         di.mEnabled = isComponentInStringArray(di.mClientNotifListComp,
@@ -539,7 +538,7 @@
             //  evaluated it, traversal order doesn't matter here)
             Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
             while(stackIterator.hasNext()) {
-                FocusRequester fr = (FocusRequester)stackIterator.next();
+                FocusRequester fr = stackIterator.next();
                 if(fr.hasSameClient(clientToRemove)) {
                     Log.i(TAG, "AudioFocus  removeFocusStackEntry(): removing entry for "
                             + clientToRemove);
@@ -563,7 +562,7 @@
         //  evaluated it, traversal order doesn't matter here)
         Iterator<FocusRequester> stackIterator = mFocusStack.iterator();
         while(stackIterator.hasNext()) {
-            FocusRequester fr = (FocusRequester)stackIterator.next();
+            FocusRequester fr = stackIterator.next();
             if(fr.hasSameBinder(cb)) {
                 Log.i(TAG, "AudioFocus  removeFocusStackEntry(): removing entry for " + cb);
                 stackIterator.remove();
@@ -931,33 +930,11 @@
         }
     }
 
-    protected static boolean isMediaKeyCode(int keyCode) {
-        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:
-                return true;
-            default:
-                return false;
-        }
-    }
-
     private static boolean isValidMediaKeyEvent(KeyEvent keyEvent) {
         if (keyEvent == null) {
             return false;
         }
-        return MediaFocusControl.isMediaKeyCode(keyEvent.getKeyCode());
+        return KeyEvent.isMediaKey(keyEvent.getKeyCode());
     }
 
     /**
@@ -1384,7 +1361,7 @@
         synchronized(mRCStack) {
             final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext()) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                final DisplayInfoForServer di = displayIterator.next();
                 pw.println("  IRCD: " + di.mRcDisplay +
                         "  -- w:" + di.mArtworkExpectedWidth +
                         "  -- h:" + di.mArtworkExpectedHeight +
@@ -1411,7 +1388,7 @@
                 // (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();
+                    RemoteControlStackEntry rcse = 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();
@@ -2076,7 +2053,7 @@
                 // remove the display from the list
                 final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
                 while (displayIterator.hasNext()) {
-                    final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                    final DisplayInfoForServer di = displayIterator.next();
                     if (di.mRcDisplay == mRcDisplay) {
                         if (DEBUG_RC) Log.w(TAG, " RCD removed from list");
                         displayIterator.remove();
@@ -2100,7 +2077,7 @@
     private void plugRemoteControlDisplaysIntoClient_syncRcStack(IRemoteControlClient rcc) {
         final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
         while (displayIterator.hasNext()) {
-            final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+            final DisplayInfoForServer di = displayIterator.next();
             try {
                 rcc.plugRemoteControlDisplay(di.mRcDisplay, di.mArtworkExpectedWidth,
                         di.mArtworkExpectedHeight);
@@ -2138,7 +2115,7 @@
     private boolean rcDisplayIsPluggedIn_syncRcStack(IRemoteControlDisplay rcd) {
         final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
         while (displayIterator.hasNext()) {
-            final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+            final DisplayInfoForServer di = displayIterator.next();
             if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
                 return true;
             }
@@ -2217,7 +2194,7 @@
             boolean displayWasPluggedIn = false;
             final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext() && !displayWasPluggedIn) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                final DisplayInfoForServer di = displayIterator.next();
                 if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
                     displayWasPluggedIn = true;
                     di.release();
@@ -2259,7 +2236,7 @@
             final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
             boolean artworkSizeUpdate = false;
             while (displayIterator.hasNext() && !artworkSizeUpdate) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                final DisplayInfoForServer di = displayIterator.next();
                 if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
                     if ((di.mArtworkExpectedWidth != w) || (di.mArtworkExpectedHeight != h)) {
                         di.mArtworkExpectedWidth = w;
@@ -2306,7 +2283,7 @@
             // (display stack traversal order doesn't matter).
             final Iterator<DisplayInfoForServer> displayIterator = mRcDisplays.iterator();
             while (displayIterator.hasNext()) {
-                final DisplayInfoForServer di = (DisplayInfoForServer) displayIterator.next();
+                final DisplayInfoForServer di = displayIterator.next();
                 if (di.mRcDisplay.asBinder().equals(rcd.asBinder())) {
                     di.mWantsPositionSync = wantsSync;
                     rcdRegistered = true;
diff --git a/media/java/android/media/MediaHTTPConnection.java b/media/java/android/media/MediaHTTPConnection.java
new file mode 100644
index 0000000..eb91668
--- /dev/null
+++ b/media/java/android/media/MediaHTTPConnection.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.IBinder;
+import android.os.StrictMode;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.URL;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Map;
+
+/** @hide */
+public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
+    private static final String TAG = "MediaHTTPConnection";
+    private static final boolean VERBOSE = false;
+
+    private long mCurrentOffset = -1;
+    private URL mURL = null;
+    private Map<String, String> mHeaders = null;
+    private HttpURLConnection mConnection = null;
+    private long mTotalSize = -1;
+    private InputStream mInputStream = null;
+
+    public MediaHTTPConnection() {
+        if (CookieHandler.getDefault() == null) {
+            CookieHandler.setDefault(new CookieManager());
+        }
+
+        native_setup();
+    }
+
+    @Override
+    public IBinder connect(String uri, String headers) {
+        if (VERBOSE) {
+            Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers);
+        }
+
+        try {
+            disconnect();
+            mURL = new URL(uri);
+            mHeaders = convertHeaderStringToMap(headers);
+        } catch (MalformedURLException e) {
+            return null;
+        }
+
+        return native_getIMemory();
+    }
+
+    private Map<String, String> convertHeaderStringToMap(String headers) {
+        HashMap<String, String> map = new HashMap<String, String>();
+
+        String[] pairs = headers.split("\r\n");
+        for (String pair : pairs) {
+            int colonPos = pair.indexOf(":");
+            if (colonPos >= 0) {
+                String key = pair.substring(0, colonPos);
+                String val = pair.substring(colonPos + 1);
+
+                map.put(key, val);
+            }
+        }
+
+        return map;
+    }
+
+    @Override
+    public void disconnect() {
+        teardownConnection();
+        mHeaders = null;
+        mURL = null;
+    }
+
+    private void teardownConnection() {
+        if (mConnection != null) {
+            mInputStream = null;
+
+            mConnection.disconnect();
+            mConnection = null;
+
+            mCurrentOffset = -1;
+        }
+    }
+
+    private void seekTo(long offset) throws IOException {
+        teardownConnection();
+
+        try {
+            mConnection = (HttpURLConnection)mURL.openConnection();
+
+            if (mHeaders != null) {
+                for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
+                    mConnection.setRequestProperty(
+                            entry.getKey(), entry.getValue());
+                }
+            }
+
+            if (offset > 0) {
+                mConnection.setRequestProperty(
+                        "Range", "bytes=" + offset + "-");
+            }
+
+            int response = mConnection.getResponseCode();
+            // remember the current, possibly redirected URL
+            mURL = mConnection.getURL();
+
+            if (response == HttpURLConnection.HTTP_PARTIAL) {
+                // Partial content, we cannot just use getContentLength
+                // because what we want is not just the length of the range
+                // returned but the size of the full content if available.
+
+                String contentRange =
+                    mConnection.getHeaderField("Content-Range");
+
+                mTotalSize = -1;
+                if (contentRange != null) {
+                    // format is "bytes xxx-yyy/zzz
+                    // where "zzz" is the total number of bytes of the
+                    // content or '*' if unknown.
+
+                    int lastSlashPos = contentRange.lastIndexOf('/');
+                    if (lastSlashPos >= 0) {
+                        String total =
+                            contentRange.substring(lastSlashPos + 1);
+
+                        try {
+                            mTotalSize = Long.parseLong(total);
+                        } catch (NumberFormatException e) {
+                        }
+                    }
+                }
+            } else if (response != HttpURLConnection.HTTP_OK) {
+                throw new IOException();
+            } else {
+                mTotalSize = mConnection.getContentLength();
+            }
+
+            if (offset > 0 && response != HttpURLConnection.HTTP_PARTIAL) {
+                // Some servers simply ignore "Range" requests and serve
+                // data from the start of the content.
+                throw new IOException();
+            }
+
+            mInputStream =
+                new BufferedInputStream(mConnection.getInputStream());
+
+            mCurrentOffset = offset;
+        } catch (IOException e) {
+            mTotalSize = -1;
+            mInputStream = null;
+            mConnection = null;
+            mCurrentOffset = -1;
+
+            throw e;
+        }
+    }
+
+    @Override
+    public int readAt(long offset, int size) {
+        return native_readAt(offset, size);
+    }
+
+    private int readAt(long offset, byte[] data, int size) {
+        StrictMode.ThreadPolicy policy =
+            new StrictMode.ThreadPolicy.Builder().permitAll().build();
+
+        StrictMode.setThreadPolicy(policy);
+
+        try {
+            if (offset != mCurrentOffset) {
+                seekTo(offset);
+            }
+
+            int n = mInputStream.read(data, 0, size);
+
+            if (n == -1) {
+                // InputStream signals EOS using a -1 result, our semantics
+                // are to return a 0-length read.
+                n = 0;
+            }
+
+            mCurrentOffset += n;
+
+            if (VERBOSE) {
+                Log.d(TAG, "readAt " + offset + " / " + size + " => " + n);
+            }
+
+            return n;
+        } catch (IOException e) {
+            if (VERBOSE) {
+                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
+            }
+            return -1;
+        } catch (Exception e) {
+            if (VERBOSE) {
+                Log.d(TAG, "unknown exception " + e);
+                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
+            }
+            return -1;
+        }
+    }
+
+    @Override
+    public long getSize() {
+        if (mConnection == null) {
+            try {
+                seekTo(0);
+            } catch (IOException e) {
+                return -1;
+            }
+        }
+
+        return mTotalSize;
+    }
+
+    @Override
+    public String getMIMEType() {
+        if (mConnection == null) {
+            try {
+                seekTo(0);
+            } catch (IOException e) {
+                return "application/octet-stream";
+            }
+        }
+
+        return mConnection.getContentType();
+    }
+
+    @Override
+    public String getUri() {
+        return mURL.toString();
+    }
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    private static native final void native_init();
+    private native final void native_setup();
+    private native final void native_finalize();
+
+    private native final IBinder native_getIMemory();
+    private native final int native_readAt(long offset, int size);
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private long mNativeContext;
+
+}
diff --git a/media/java/android/media/MediaHTTPService.java b/media/java/android/media/MediaHTTPService.java
new file mode 100644
index 0000000..3b4703d
--- /dev/null
+++ b/media/java/android/media/MediaHTTPService.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;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+
+/** @hide */
+public class MediaHTTPService extends IMediaHTTPService.Stub {
+    private static final String TAG = "MediaHTTPService";
+
+    public MediaHTTPService() {
+    }
+
+    public IMediaHTTPConnection makeHTTPConnection() {
+        return new MediaHTTPConnection();
+    }
+
+    /* package private */static IBinder createHttpServiceBinderIfNecessary(
+            String path) {
+        if (path.startsWith("http://")
+                || path.startsWith("https://")
+                || path.startsWith("widevine://")) {
+            return (new MediaHTTPService()).asBinder();
+        }
+
+        return null;
+    }
+}
diff --git a/media/java/android/media/MediaMetadataEditor.java b/media/java/android/media/MediaMetadataEditor.java
index 373ba11..3bfdb5a 100644
--- a/media/java/android/media/MediaMetadataEditor.java
+++ b/media/java/android/media/MediaMetadataEditor.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Bitmap;
 import android.os.Bundle;
-import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
 import android.util.SparseIntArray;
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index db27d09..9a69c06 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -21,6 +21,7 @@
 import android.content.res.AssetFileDescriptor;
 import android.graphics.Bitmap;
 import android.net.Uri;
+import android.os.IBinder;
 
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -100,11 +101,16 @@
             values[i] = entry.getValue();
             ++i;
         }
-        _setDataSource(uri, keys, values);
+
+        _setDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(uri),
+                uri,
+                keys,
+                values);
     }
 
     private native void _setDataSource(
-        String uri, String[] keys, String[] values)
+        IBinder httpServiceBinder, String uri, String[] keys, String[] values)
         throws IllegalArgumentException;
 
     /**
diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java
index e5c97e7..f518ab2 100644
--- a/media/java/android/media/MediaMuxer.java
+++ b/media/java/android/media/MediaMuxer.java
@@ -17,13 +17,11 @@
 package android.media;
 
 import android.media.MediaCodec.BufferInfo;
-
 import dalvik.system.CloseGuard;
 
-import java.io.File;
 import java.io.FileDescriptor;
-import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.util.Map;
 
@@ -79,6 +77,7 @@
         private OutputFormat() {}
         /** MPEG4 media file format*/
         public static final int MUXER_OUTPUT_MPEG_4 = 0;
+        public static final int MUXER_OUTPUT_WEBM   = 1;
     };
 
     // All the native functions are listed here.
@@ -120,20 +119,22 @@
         if (path == null) {
             throw new IllegalArgumentException("path must not be null");
         }
-        if (format != OutputFormat.MUXER_OUTPUT_MPEG_4) {
+        if (format != OutputFormat.MUXER_OUTPUT_MPEG_4 &&
+                format != OutputFormat.MUXER_OUTPUT_WEBM) {
             throw new IllegalArgumentException("format is invalid");
         }
-        FileOutputStream fos = null;
+        // Use RandomAccessFile so we can open the file with RW access;
+        // RW access allows the native writer to memory map the output file.
+        RandomAccessFile file = null;
         try {
-            File file = new File(path);
-            fos = new FileOutputStream(file);
-            FileDescriptor fd = fos.getFD();
+            file = new RandomAccessFile(path, "rws");
+            FileDescriptor fd = file.getFD();
             mNativeObject = nativeSetup(fd, format);
             mState = MUXER_STATE_INITIALIZED;
             mCloseGuard.open("release");
         } finally {
-            if (fos != null) {
-                fos.close();
+            if (file != null) {
+                file.close();
             }
         }
     }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 41ba5d6..1b92410 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -16,36 +16,38 @@
 
 package android.media;
 
+import android.app.ActivityThread;
+import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.res.AssetFileDescriptor;
-import android.net.Proxy;
-import android.net.ProxyProperties;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.os.IBinder;
 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.os.RemoteException;
+import android.os.ServiceManager;
 import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceHolder;
-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 com.android.internal.app.IAppOpsService;
+
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -580,6 +582,8 @@
     private PowerManager.WakeLock mWakeLock = null;
     private boolean mScreenOnWhilePlaying;
     private boolean mStayAwake;
+    private final IAppOpsService mAppOps;
+    private int mStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
 
     /**
      * Default constructor. Consider using one of the create() methods for
@@ -603,6 +607,8 @@
         mOutOfBandSubtitleTracks = new Vector<SubtitleTrack>();
         mOpenSubtitleSources = new Vector<InputStream>();
         mInbandSubtitleTracks = new SubtitleTrack[0];
+        IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
+        mAppOps = IAppOpsService.Stub.asInterface(b);
 
         /* Native setup requires a weak reference to our object.
          * It's easier to create it here than in C++.
@@ -884,8 +890,6 @@
      */
     public void setDataSource(Context context, Uri uri, Map<String, String> headers)
         throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
-        disableProxyListener();
-
         String scheme = uri.getScheme();
         if(scheme == null || scheme.equals("file")) {
             setDataSource(uri.getPath());
@@ -919,11 +923,6 @@
         Log.d(TAG, "Couldn't open file on client side, trying server side");
 
         setDataSource(uri.toString(), headers);
-
-        if (scheme.equalsIgnoreCase("http")
-                || scheme.equalsIgnoreCase("https")) {
-            setupProxyListener(context);
-        }
     }
 
     /**
@@ -974,8 +973,6 @@
 
     private void setDataSource(String path, String[] keys, String[] values)
             throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
-        disableProxyListener();
-
         final Uri uri = Uri.parse(path);
         if ("file".equals(uri.getScheme())) {
             path = uri.getPath();
@@ -992,8 +989,18 @@
         }
     }
 
-    private native void _setDataSource(
+    private void _setDataSource(
         String path, String[] keys, String[] values)
+        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                keys,
+                values);
+    }
+
+    private native void nativeSetDataSource(
+        IBinder httpServiceBinder, String path, String[] keys, String[] values)
         throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
 
     /**
@@ -1021,7 +1028,6 @@
      */
     public void setDataSource(FileDescriptor fd, long offset, long length)
             throws IOException, IllegalArgumentException, IllegalStateException {
-        disableProxyListener();
         _setDataSource(fd, offset, length);
     }
 
@@ -1059,13 +1065,35 @@
      *
      * @throws IllegalStateException if it is called in an invalid state
      */
-    public  void start() throws IllegalStateException {
+    public void start() throws IllegalStateException {
+        if (isRestricted()) {
+            _setVolume(0, 0);
+        }
         stayAwake(true);
         _start();
     }
 
     private native void _start() throws IllegalStateException;
 
+    private boolean isRestricted() {
+        try {
+            final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO,
+                    getAudioStreamType(), Process.myUid(), ActivityThread.currentPackageName());
+            return mode != AppOpsManager.MODE_ALLOWED;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    private int getAudioStreamType() {
+        if (mStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
+            mStreamType = _getAudioStreamType();
+        }
+        return mStreamType;
+    }
+
+    private native int _getAudioStreamType() throws IllegalStateException;
+
     /**
      * Stops playback after playback has been stopped or paused.
      *
@@ -1393,8 +1421,6 @@
         if (mEventHandler != null) {
             mEventHandler.removeCallbacksAndMessages(null);
         }
-
-        disableProxyListener();
     }
 
     private native void _reset();
@@ -1408,7 +1434,12 @@
      * @param streamtype the audio stream type
      * @see android.media.AudioManager
      */
-    public native void setAudioStreamType(int streamtype);
+    public void setAudioStreamType(int streamtype) {
+        _setAudioStreamType(streamtype);
+        mStreamType = streamtype;
+    }
+
+    private native void _setAudioStreamType(int streamtype);
 
     /**
      * Sets the player to be looping or non-looping.
@@ -1441,7 +1472,14 @@
      * The single parameter form below is preferred if the channel volumes don't need
      * to be set independently.
      */
-    public native void setVolume(float leftVolume, float rightVolume);
+    public void setVolume(float leftVolume, float rightVolume) {
+        if (isRestricted()) {
+            return;
+        }
+        _setVolume(leftVolume, rightVolume);
+    }
+
+    private native void _setVolume(float leftVolume, float rightVolume);
 
     /**
      * Similar, excepts sets volume of all channels to same value.
@@ -1506,7 +1544,14 @@
      * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
      * @param level send level scalar
      */
-    public native void setAuxEffectSendLevel(float level);
+    public void setAuxEffectSendLevel(float level) {
+        if (isRestricted()) {
+            return;
+        }
+        _setAuxEffectSendLevel(level);
+    }
+
+    private native void _setAuxEffectSendLevel(float level);
 
     /*
      * @param request Parcel destinated to the media player. The
@@ -2742,59 +2787,6 @@
                 mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
     }
 
-    private Context mProxyContext = null;
-    private ProxyReceiver mProxyReceiver = null;
-
-    private void setupProxyListener(Context context) {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Proxy.PROXY_CHANGE_ACTION);
-        mProxyReceiver = new ProxyReceiver();
-        mProxyContext = context;
-
-        Intent currentProxy =
-            context.getApplicationContext().registerReceiver(mProxyReceiver, filter);
-
-        if (currentProxy != null) {
-            handleProxyBroadcast(currentProxy);
-        }
-    }
-
-    private void disableProxyListener() {
-        if (mProxyReceiver == null) {
-            return;
-        }
-
-        Context appContext = mProxyContext.getApplicationContext();
-        if (appContext != null) {
-            appContext.unregisterReceiver(mProxyReceiver);
-        }
-
-        mProxyReceiver = null;
-        mProxyContext = null;
-    }
-
-    private void handleProxyBroadcast(Intent intent) {
-        ProxyProperties props =
-            (ProxyProperties)intent.getExtra(Proxy.EXTRA_PROXY_INFO);
-
-        if (props == null || props.getHost() == null) {
-            updateProxyConfig(null);
-        } else {
-            updateProxyConfig(props);
-        }
-    }
-
-    private class ProxyReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
-                handleProxyBroadcast(intent);
-            }
-        }
-    }
-
-    private native void updateProxyConfig(ProxyProperties props);
-
     /** @hide */
     static class TimeProvider implements MediaPlayer.OnSeekCompleteListener,
             MediaTimeProvider {
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 5a9d577..21e2f4b 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -124,6 +124,18 @@
     public native void setCamera(Camera c);
 
     /**
+     * Gets the surface to record from when using SURFACE video source.
+     * <p>
+     * Should only be called after prepare(). Frames rendered before start()
+     * will be discarded.
+     * </p>
+     * @throws IllegalStateException if it is called before prepare(), after
+     * stop() or is called when VideoSource is not set to SURFACE.
+     * @see android.media.MediaRecorder.VideoSource
+     */
+    public native Surface getSurface();
+
+    /**
      * Sets a Surface to show a preview of recorded media (video). Calls this
      * before prepare() to make sure that the desirable preview display is
      * set. If {@link #setCamera(Camera)} is used and the surface has been
@@ -225,10 +237,23 @@
        */
         private VideoSource() {}
         public static final int DEFAULT = 0;
-        /** Camera video source */
+        /** Camera video source
+         * <p>
+         * Using android.hardware.Camera as video source.
+         * </p>
+         */
         public static final int CAMERA = 1;
-        /** @hide */
-        public static final int GRALLOC_BUFFER = 2;
+        /** Surface video source
+         * <p>
+         * Using a Surface as video source.
+         * </p><p>
+         * This flag must be used when recording from an
+         * android.hardware.camera2.CameraDevice source.
+         * </p><p>
+         * When using this video source type, use {@link MediaRecorder#getSurface()}
+         * to retrieve the surface created by MediaRecorder.
+         */
+        public static final int SURFACE = 2;
     }
 
     /**
@@ -392,8 +417,8 @@
         setParameter("time-lapse-enable=1");
 
         double timeBetweenFrameCapture = 1 / fps;
-        int timeBetweenFrameCaptureMs = (int) (1000 * timeBetweenFrameCapture);
-        setParameter("time-between-time-lapse-frame-capture=" + timeBetweenFrameCaptureMs);
+        long timeBetweenFrameCaptureUs = (long) (1000000 * timeBetweenFrameCapture);
+        setParameter("time-between-time-lapse-frame-capture=" + timeBetweenFrameCaptureUs);
     }
 
     /**
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 53835e2..72f3e1a 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -55,6 +55,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Locale;
@@ -1400,27 +1401,60 @@
         return false;
     }
 
-    public static boolean isNoMediaPath(String path) {
-        if (path == null) return false;
+    private static HashMap<String,String> mNoMediaPaths = new HashMap<String,String>();
+    private static HashMap<String,String> mMediaPaths = new HashMap<String,String>();
 
-        // return true if file or any parent directory has name starting with a dot
-        if (path.indexOf("/.") >= 0) return true;
-
-        // now check to see if any parent directories have a ".nomedia" file
-        // start from 1 so we don't bother checking in the root directory
-        int offset = 1;
-        while (offset >= 0) {
-            int slashIndex = path.indexOf('/', offset);
-            if (slashIndex > offset) {
-                slashIndex++; // move past slash
-                File file = new File(path.substring(0, slashIndex) + ".nomedia");
-                if (file.exists()) {
-                    // we have a .nomedia in one of the parent directories
-                    return true;
-                }
+    /* MediaProvider calls this when a .nomedia file is added or removed */
+    public static void clearMediaPathCache(boolean clearMediaPaths, boolean clearNoMediaPaths) {
+        synchronized (MediaScanner.class) {
+            if (clearMediaPaths) {
+                mMediaPaths.clear();
             }
-            offset = slashIndex;
+            if (clearNoMediaPaths) {
+                mNoMediaPaths.clear();
+            }
         }
+    }
+
+    public static boolean isNoMediaPath(String path) {
+        if (path == null) {
+            return false;
+        }
+        // return true if file or any parent directory has name starting with a dot
+        if (path.indexOf("/.") >= 0) {
+            return true;
+        }
+
+        int firstSlash = path.lastIndexOf('/');
+        if (firstSlash <= 0) {
+            return false;
+        }
+        String parent = path.substring(0,  firstSlash);
+
+        synchronized (MediaScanner.class) {
+            if (mNoMediaPaths.containsKey(parent)) {
+                return true;
+            } else if (!mMediaPaths.containsKey(parent)) {
+                // check to see if any parent directories have a ".nomedia" file
+                // start from 1 so we don't bother checking in the root directory
+                int offset = 1;
+                while (offset >= 0) {
+                    int slashIndex = path.indexOf('/', offset);
+                    if (slashIndex > offset) {
+                        slashIndex++; // move past slash
+                        File file = new File(path.substring(0, slashIndex) + ".nomedia");
+                        if (file.exists()) {
+                            // we have a .nomedia in one of the parent directories
+                            mNoMediaPaths.put(parent, "");
+                            return true;
+                        }
+                    }
+                    offset = slashIndex;
+                }
+                mMediaPaths.put(parent, "");
+            }
+        }
+
         return isNoMediaFile(path);
     }
 
diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java
index b566653..eb543b4 100644
--- a/media/java/android/media/Metadata.java
+++ b/media/java/android/media/Metadata.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.util.Log;
 
diff --git a/media/java/android/media/MiniThumbFile.java b/media/java/android/media/MiniThumbFile.java
index 63b149c..23c3652 100644
--- a/media/java/android/media/MiniThumbFile.java
+++ b/media/java/android/media/MiniThumbFile.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Environment;
 import android.util.Log;
diff --git a/media/java/android/media/Rating.java b/media/java/android/media/Rating.java
index 82c0392..f4fbe2c 100644
--- a/media/java/android/media/Rating.java
+++ b/media/java/android/media/Rating.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.Log;
@@ -30,8 +29,13 @@
  * through one of the factory methods.
  */
 public final class Rating implements Parcelable {
-
     private final static String TAG = "Rating";
+    /**
+     * Indicates a rating style is not supported. A Rating will never have this
+     * type, but can be used by other classes to indicate they do not support
+     * Rating.
+     */
+    public final static int RATING_NONE = 0;
 
     /**
      * A rating style with a single degree of rating, "heart" vs "no heart". Can be used to
diff --git a/media/java/android/media/RemoteControlClient.java b/media/java/android/media/RemoteControlClient.java
index 0c00aba..c2c61d3 100644
--- a/media/java/android/media/RemoteControlClient.java
+++ b/media/java/android/media/RemoteControlClient.java
@@ -24,13 +24,11 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.RectF;
-import android.media.MediaMetadataRetriever;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
diff --git a/media/java/android/media/RemoteController.java b/media/java/android/media/RemoteController.java
index 910b24c..3711585 100644
--- a/media/java/android/media/RemoteController.java
+++ b/media/java/android/media/RemoteController.java
@@ -16,7 +16,6 @@
 
 package android.media;
 
-import android.Manifest;
 import android.app.ActivityManager;
 import android.app.PendingIntent;
 import android.app.PendingIntent.CanceledException;
@@ -29,8 +28,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -267,7 +264,7 @@
      * @throws IllegalArgumentException
      */
     public boolean sendMediaKeyEvent(KeyEvent keyEvent) throws IllegalArgumentException {
-        if (!MediaFocusControl.isMediaKeyCode(keyEvent.getKeyCode())) {
+        if (!KeyEvent.isMediaKey(keyEvent.getKeyCode())) {
             throw new IllegalArgumentException("not a media key event");
         }
         final PendingIntent pi;
diff --git a/media/java/android/media/ResampleInputStream.java b/media/java/android/media/ResampleInputStream.java
index b025e25..80919f7 100644
--- a/media/java/android/media/ResampleInputStream.java
+++ b/media/java/android/media/ResampleInputStream.java
@@ -16,8 +16,6 @@
 
 package android.media;
 
-import android.util.Log;
-
 import java.io.InputStream;
 import java.io.IOException;
 
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 8e4004b..e211b99 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -23,7 +23,6 @@
 import android.app.Activity;
 import android.content.ContentUris;
 import android.content.Context;
-import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Environment;
diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java
index fbfc574..14f0c69 100644
--- a/media/java/android/media/SoundPool.java
+++ b/media/java/android/media/SoundPool.java
@@ -18,19 +18,26 @@
 
 import java.io.File;
 import java.io.FileDescriptor;
-import java.io.IOException;
 import java.lang.ref.WeakReference;
 
+import android.app.ActivityThread;
+import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
 
+import com.android.internal.app.IAppOpsService;
+
 
 /**
  * The SoundPool class manages and plays audio resources for applications.
@@ -450,6 +457,8 @@
         private SoundPool mProxy;
 
         private final Object mLock;
+        private final int mStreamType;
+        private final IAppOpsService mAppOps;
 
         // SoundPool messages
         //
@@ -464,6 +473,9 @@
             }
             mLock = new Object();
             mProxy = proxy;
+            mStreamType = streamType;
+            IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
+            mAppOps = IAppOpsService.Stub.asInterface(b);
         }
 
         public int load(String path, int priority)
@@ -523,9 +535,27 @@
 
         public native final boolean unload(int soundID);
 
-        public native final int play(int soundID, float leftVolume, float rightVolume,
+        public final int play(int soundID, float leftVolume, float rightVolume,
+                int priority, int loop, float rate) {
+            if (isRestricted()) {
+                leftVolume = rightVolume = 0;
+            }
+            return _play(soundID, leftVolume, rightVolume, priority, loop, rate);
+        }
+
+        public native final int _play(int soundID, float leftVolume, float rightVolume,
                 int priority, int loop, float rate);
 
+        private boolean isRestricted() {
+            try {
+                final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO,
+                        mStreamType, Process.myUid(), ActivityThread.currentPackageName());
+                return mode != AppOpsManager.MODE_ALLOWED;
+            } catch (RemoteException e) {
+                return false;
+            }
+        }
+
         public native final void pause(int streamID);
 
         public native final void resume(int streamID);
@@ -536,8 +566,14 @@
 
         public native final void stop(int streamID);
 
-        public native final void setVolume(int streamID,
-                float leftVolume, float rightVolume);
+        public final void setVolume(int streamID, float leftVolume, float rightVolume) {
+            if (isRestricted()) {
+                return;
+            }
+            _setVolume(streamID, leftVolume, rightVolume);
+        }
+
+        private native final void _setVolume(int streamID, float leftVolume, float rightVolume);
 
         public void setVolume(int streamID, float volume) {
             setVolume(streamID, volume, volume);
diff --git a/media/java/android/media/SubtitleData.java b/media/java/android/media/SubtitleData.java
index f552e82..3e6f6f9 100644
--- a/media/java/android/media/SubtitleData.java
+++ b/media/java/android/media/SubtitleData.java
@@ -17,7 +17,6 @@
 package android.media;
 
 import android.os.Parcel;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 756638c..daa5fa5 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -17,9 +17,6 @@
 package android.media;
 
 import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
@@ -29,15 +26,12 @@
 import android.media.MediaFile.MediaFileType;
 import android.net.Uri;
 import android.os.ParcelFileDescriptor;
-import android.provider.BaseColumns;
 import android.provider.MediaStore.Images;
-import android.provider.MediaStore.Images.Thumbnails;
 import android.util.Log;
 
 import java.io.FileInputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.io.OutputStream;
 
 /**
  * Thumbnail generation routines for media provider.
diff --git a/media/java/android/media/WebVttRenderer.java b/media/java/android/media/WebVttRenderer.java
index 4dec081..58d3520 100644
--- a/media/java/android/media/WebVttRenderer.java
+++ b/media/java/android/media/WebVttRenderer.java
@@ -1136,11 +1136,15 @@
     }
 
     public WebVttRenderingWidget(Context context, AttributeSet attrs) {
-        this(context, null, 0);
+        this(context, attrs, 0);
     }
 
-    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
 
         // Cannot render text over video when layer type is hardware.
         setLayerType(View.LAYER_TYPE_SOFTWARE, null);
@@ -1521,6 +1525,8 @@
 
             if (DEBUG) {
                 setBackgroundColor(DEBUG_REGION_BACKGROUND);
+            } else {
+                setBackgroundColor(captionStyle.windowColor);
             }
         }
 
@@ -1533,6 +1539,8 @@
                 final CueLayout cueBox = mRegionCueBoxes.get(i);
                 cueBox.setCaptionStyle(captionStyle, fontSize);
             }
+
+            setBackgroundColor(captionStyle.windowColor);
         }
 
         /**
diff --git a/media/java/android/media/audiofx/AudioEffect.java b/media/java/android/media/audiofx/AudioEffect.java
index cc121a3..9b381cc 100644
--- a/media/java/android/media/audiofx/AudioEffect.java
+++ b/media/java/android/media/audiofx/AudioEffect.java
@@ -22,7 +22,6 @@
 import android.os.Looper;
 import android.os.Message;
 import android.util.Log;
-import java.io.IOException;
 import java.lang.ref.WeakReference;
 import java.nio.ByteOrder;
 import java.nio.ByteBuffer;
diff --git a/media/java/android/media/audiofx/BassBoost.java b/media/java/android/media/audiofx/BassBoost.java
index 91459ed..a46cc22 100644
--- a/media/java/android/media/audiofx/BassBoost.java
+++ b/media/java/android/media/audiofx/BassBoost.java
@@ -16,16 +16,9 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/EnvironmentalReverb.java b/media/java/android/media/audiofx/EnvironmentalReverb.java
index f1f582e..ef1c4c3 100644
--- a/media/java/android/media/audiofx/EnvironmentalReverb.java
+++ b/media/java/android/media/audiofx/EnvironmentalReverb.java
@@ -16,15 +16,7 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
 import java.util.StringTokenizer;
 
 /**
diff --git a/media/java/android/media/audiofx/Equalizer.java b/media/java/android/media/audiofx/Equalizer.java
index 7f38955..7abada0 100644
--- a/media/java/android/media/audiofx/Equalizer.java
+++ b/media/java/android/media/audiofx/Equalizer.java
@@ -16,16 +16,9 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/PresetReverb.java b/media/java/android/media/audiofx/PresetReverb.java
index 7a89ae7..ef91667 100644
--- a/media/java/android/media/audiofx/PresetReverb.java
+++ b/media/java/android/media/audiofx/PresetReverb.java
@@ -16,15 +16,7 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
-import android.util.Log;
-
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/Virtualizer.java b/media/java/android/media/audiofx/Virtualizer.java
index 68a7b88..6b20006 100644
--- a/media/java/android/media/audiofx/Virtualizer.java
+++ b/media/java/android/media/audiofx/Virtualizer.java
@@ -16,16 +16,9 @@
 
 package android.media.audiofx;
 
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
 import android.media.audiofx.AudioEffect;
-import android.os.Bundle;
 import android.util.Log;
 
-import java.nio.ByteOrder;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
 import java.util.StringTokenizer;
 
 
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index ff04201..24c74ac 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 import java.lang.ref.WeakReference;
-import java.io.IOException;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
diff --git a/media/java/android/media/session/IMediaController.aidl b/media/java/android/media/session/IMediaController.aidl
new file mode 100644
index 0000000..d34e973
--- /dev/null
+++ b/media/java/android/media/session/IMediaController.aidl
@@ -0,0 +1,51 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.content.Intent;
+import android.media.Rating;
+import android.media.session.IMediaControllerCallback;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.view.KeyEvent;
+
+/**
+ * Interface to a MediaSession in the system.
+ * @hide
+ */
+interface IMediaController {
+    void sendCommand(String command, in Bundle extras, in ResultReceiver cb);
+    void sendMediaButton(in KeyEvent mediaButton);
+    void registerCallbackListener(in IMediaControllerCallback cb);
+    void unregisterCallbackListener(in IMediaControllerCallback cb);
+    boolean isTransportControlEnabled();
+
+    // These commands are for the TransportController
+    void play();
+    void pause();
+    void stop();
+    void next();
+    void previous();
+    void fastForward();
+    void rewind();
+    void seekTo(long pos);
+    void rate(in Rating rating);
+    MediaMetadata getMetadata();
+    PlaybackState getPlaybackState();
+    int getRatingType();
+}
\ No newline at end of file
diff --git a/media/java/android/media/session/IMediaControllerCallback.aidl b/media/java/android/media/session/IMediaControllerCallback.aidl
new file mode 100644
index 0000000..3651f1b
--- /dev/null
+++ b/media/java/android/media/session/IMediaControllerCallback.aidl
@@ -0,0 +1,32 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+oneway interface IMediaControllerCallback {
+    void onEvent(String event, in Bundle extras);
+    void onRouteChanged(in Bundle route);
+
+    // These callbacks are for the TransportController
+    void onPlaybackStateChanged(in PlaybackState state);
+    void onMetadataChanged(in MediaMetadata metadata);
+}
\ No newline at end of file
diff --git a/media/java/android/media/session/IMediaSession.aidl b/media/java/android/media/session/IMediaSession.aidl
new file mode 100644
index 0000000..aed7641
--- /dev/null
+++ b/media/java/android/media/session/IMediaSession.aidl
@@ -0,0 +1,41 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.media.session.IMediaController;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+
+/**
+ * Interface to a MediaSession in the system.
+ * @hide
+ */
+interface IMediaSession {
+    void sendEvent(String event, in Bundle data);
+    IMediaController getMediaController();
+    void setTransportPerformerEnabled();
+    void setRouteState(in Bundle routeState);
+    void setRoute(in Bundle mediaRouteDescriptor);
+    List<String> getSupportedInterfaces();
+    void publish();
+    void destroy();
+
+    // These commands are for the TransportPerformer
+    void setMetadata(in MediaMetadata metadata);
+    void setPlaybackState(in PlaybackState state);
+    void setRatingType(int type);
+}
\ No newline at end of file
diff --git a/media/java/android/media/session/IMediaSessionCallback.aidl b/media/java/android/media/session/IMediaSessionCallback.aidl
new file mode 100644
index 0000000..7c183e0
--- /dev/null
+++ b/media/java/android/media/session/IMediaSessionCallback.aidl
@@ -0,0 +1,41 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.media.Rating;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+
+/**
+ * @hide
+ */
+oneway interface IMediaSessionCallback {
+    void onCommand(String command, in Bundle extras, in ResultReceiver cb);
+    void onMediaButton(in Intent mediaRequestIntent);
+    void onRequestRouteChange(in Bundle route);
+
+    // These callbacks are for the TransportPerformer
+    void onPlay();
+    void onPause();
+    void onStop();
+    void onNext();
+    void onPrevious();
+    void onFastForward();
+    void onRewind();
+    void onSeekTo(long pos);
+    void onRate(in Rating rating);
+}
\ No newline at end of file
diff --git a/media/java/android/media/session/IMediaSessionManager.aidl b/media/java/android/media/session/IMediaSessionManager.aidl
new file mode 100644
index 0000000..0b4328e
--- /dev/null
+++ b/media/java/android/media/session/IMediaSessionManager.aidl
@@ -0,0 +1,28 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
+import android.os.Bundle;
+
+/**
+ * Interface to the MediaSessionManagerService
+ * @hide
+ */
+interface IMediaSessionManager {
+    IMediaSession createSession(String packageName, in IMediaSessionCallback cb, String tag);
+}
\ No newline at end of file
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
new file mode 100644
index 0000000..afd8b11
--- /dev/null
+++ b/media/java/android/media/session/MediaController.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Allows an app to interact with an ongoing media session. Media buttons and
+ * other commands can be sent to the session. A callback may be registered to
+ * receive updates from the session, such as metadata and play state changes.
+ * <p>
+ * A MediaController can be created through {@link MediaSessionManager} if you
+ * hold the "android.permission.MEDIA_CONTENT_CONTROL" permission or directly if
+ * you have a {@link MediaSessionToken} from the session owner.
+ * <p>
+ * MediaController objects are thread-safe.
+ */
+public final class MediaController {
+    private static final String TAG = "MediaController";
+
+    private static final int MSG_EVENT = 1;
+    private static final int MESSAGE_PLAYBACK_STATE = 2;
+    private static final int MESSAGE_METADATA = 3;
+    private static final int MSG_ROUTE = 4;
+
+    private final IMediaController mSessionBinder;
+
+    private final CallbackStub mCbStub = new CallbackStub(this);
+    private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
+    private final Object mLock = new Object();
+
+    private boolean mCbRegistered = false;
+
+    private TransportController mTransportController;
+
+    private MediaController(IMediaController sessionBinder) {
+        mSessionBinder = sessionBinder;
+    }
+
+    /**
+     * @hide
+     */
+    public static MediaController fromBinder(IMediaController sessionBinder) {
+        MediaController controller = new MediaController(sessionBinder);
+        try {
+            controller.mSessionBinder.registerCallbackListener(controller.mCbStub);
+            if (controller.mSessionBinder.isTransportControlEnabled()) {
+                controller.mTransportController = new TransportController(sessionBinder);
+            }
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "MediaController created with expired token", e);
+            controller = null;
+        }
+        return controller;
+    }
+
+    /**
+     * Get a new MediaController for a MediaSessionToken. If successful the
+     * controller returned will be connected to the session that generated the
+     * token.
+     *
+     * @param token The session token to use
+     * @return A controller for the session or null
+     */
+    public static MediaController fromToken(MediaSessionToken token) {
+        return fromBinder(token.getBinder());
+    }
+
+    /**
+     * Get a TransportController if the session supports it. If it is not
+     * supported null will be returned.
+     *
+     * @return A TransportController or null
+     */
+    public TransportController getTransportController() {
+        return mTransportController;
+    }
+
+    /**
+     * Send the specified media button to the session. Only media keys can be
+     * sent using this method.
+     *
+     * @param keycode The media button keycode, such as
+     *            {@link KeyEvent#KEYCODE_MEDIA_PLAY}.
+     */
+    public void sendMediaButton(int keycode) {
+        if (!KeyEvent.isMediaKey(keycode)) {
+            throw new IllegalArgumentException("May only send media buttons through "
+                    + "sendMediaButton");
+        }
+        // TODO do something better than key down/up events
+        KeyEvent event = new KeyEvent(KeyEvent.ACTION_UP, keycode);
+        try {
+            mSessionBinder.sendMediaButton(event);
+        } catch (RemoteException e) {
+            Log.d(TAG, "Dead object in sendMediaButton", e);
+        }
+    }
+
+    /**
+     * Adds a callback to receive updates from the Session. Updates will be
+     * posted on the caller's thread.
+     *
+     * @param cb The callback object, must not be null
+     */
+    public void addCallback(Callback cb) {
+        addCallback(cb, null);
+    }
+
+    /**
+     * Adds a callback to receive updates from the session. Updates will be
+     * posted on the specified handler's thread.
+     *
+     * @param cb Cannot be null.
+     * @param handler The handler to post updates on. If null the callers thread
+     *            will be used
+     */
+    public void addCallback(Callback cb, Handler handler) {
+        if (handler == null) {
+            handler = new Handler();
+        }
+        synchronized (mLock) {
+            addCallbackLocked(cb, handler);
+        }
+    }
+
+    /**
+     * Stop receiving updates on the specified callback. If an update has
+     * already been posted you may still receive it after calling this method.
+     *
+     * @param cb The callback to remove
+     */
+    public void removeCallback(Callback cb) {
+        synchronized (mLock) {
+            removeCallbackLocked(cb);
+        }
+    }
+
+    /**
+     * Sends a generic command to the session. It is up to the session creator
+     * to decide what commands and parameters they will support. As such,
+     * commands should only be sent to sessions that the controller owns.
+     *
+     * @param command The command to send
+     * @param params Any parameters to include with the command
+     * @param cb The callback to receive the result on
+     */
+    public void sendCommand(String command, Bundle params, ResultReceiver cb) {
+        if (TextUtils.isEmpty(command)) {
+            throw new IllegalArgumentException("command cannot be null or empty");
+        }
+        try {
+            mSessionBinder.sendCommand(command, params, cb);
+        } catch (RemoteException e) {
+            Log.d(TAG, "Dead object in sendCommand.", e);
+        }
+    }
+
+    /*
+     * @hide
+     */
+    IMediaController getSessionBinder() {
+        return mSessionBinder;
+    }
+
+    private void addCallbackLocked(Callback cb, Handler handler) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException("Handler cannot be null");
+        }
+        if (getHandlerForCallbackLocked(cb) != null) {
+            Log.w(TAG, "Callback is already added, ignoring");
+            return;
+        }
+        MessageHandler holder = new MessageHandler(handler.getLooper(), cb);
+        mCallbacks.add(holder);
+
+        if (!mCbRegistered) {
+            try {
+                mSessionBinder.registerCallbackListener(mCbStub);
+                mCbRegistered = true;
+            } catch (RemoteException e) {
+                Log.d(TAG, "Dead object in registerCallback", e);
+            }
+        }
+    }
+
+    private boolean removeCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                mCallbacks.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private MessageHandler getHandlerForCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private void postEvent(String event, Bundle extras) {
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(MSG_EVENT, event, extras);
+            }
+        }
+    }
+
+    private void postRouteChanged(Bundle routeDescriptor) {
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(MSG_ROUTE, null, routeDescriptor);
+            }
+        }
+    }
+
+    /**
+     * Callback for receiving updates on from the session. A Callback can be
+     * registered using {@link #addCallback}
+     */
+    public static abstract class Callback {
+        /**
+         * Override to handle custom events sent by the session owner without a
+         * specified interface. Controllers should only handle these for
+         * sessions they own.
+         *
+         * @param event
+         */
+        public void onEvent(String event, Bundle extras) {
+        }
+
+        /**
+         * Override to handle route changes for this session.
+         *
+         * @param route
+         */
+        public void onRouteChanged(Bundle route) {
+        }
+    }
+
+    private final static class CallbackStub extends IMediaControllerCallback.Stub {
+        private final WeakReference<MediaController> mController;
+
+        public CallbackStub(MediaController controller) {
+            mController = new WeakReference<MediaController>(controller);
+        }
+
+        @Override
+        public void onEvent(String event, Bundle extras) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postEvent(event, extras);
+            }
+        }
+
+        @Override
+        public void onRouteChanged(Bundle mediaRouteDescriptor) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postRouteChanged(mediaRouteDescriptor);
+            }
+        }
+
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                TransportController tc = controller.getTransportController();
+                if (tc != null) {
+                    tc.postPlaybackStateChanged(state);
+                }
+            }
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                TransportController tc = controller.getTransportController();
+                if (tc != null) {
+                    tc.postMetadataChanged(metadata);
+                }
+            }
+        }
+
+    }
+
+    private final static class MessageHandler extends Handler {
+        private final MediaController.Callback mCallback;
+
+        public MessageHandler(Looper looper, MediaController.Callback cb) {
+            super(looper, null, true);
+            mCallback = cb;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_EVENT:
+                    mCallback.onEvent((String) msg.obj, msg.getData());
+                    break;
+                case MSG_ROUTE:
+                    mCallback.onRouteChanged(msg.getData());
+            }
+        }
+
+        public void post(int what, Object obj, Bundle data) {
+            obtainMessage(what, obj).sendToTarget();
+        }
+    }
+
+}
diff --git a/media/java/android/media/session/MediaMetadata.aidl b/media/java/android/media/session/MediaMetadata.aidl
new file mode 100644
index 0000000..4431d9d
--- /dev/null
+++ b/media/java/android/media/session/MediaMetadata.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media.session;
+
+parcelable MediaMetadata;
diff --git a/media/java/android/media/session/MediaMetadata.java b/media/java/android/media/session/MediaMetadata.java
new file mode 100644
index 0000000..e2330f7
--- /dev/null
+++ b/media/java/android/media/session/MediaMetadata.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.session;
+
+import android.graphics.Bitmap;
+import android.media.Rating;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+import android.util.Log;
+
+/**
+ * Contains metadata about an item, such as the title, artist, etc.
+ */
+public final class MediaMetadata implements Parcelable {
+    private static final String TAG = "MediaMetadata";
+
+    /**
+     * The title of the media.
+     */
+    public static final String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+
+    /**
+     * The artist of the media.
+     */
+    public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+
+    /**
+     * The duration of the media in ms. A duration of 0 is the default.
+     */
+    public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+
+    /**
+     * The album title for the media.
+     */
+    public static final String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+
+    /**
+     * The author of the media.
+     */
+    public static final String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+
+    /**
+     * The writer of the media.
+     */
+    public static final String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+
+    /**
+     * The composer of the media.
+     */
+    public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+
+    /**
+     * The date the media was created or published as TODO determine format.
+     */
+    public static final String METADATA_KEY_DATE = "android.media.metadata.DATE";
+
+    /**
+     * The year the media was created or published as a numeric String.
+     */
+    public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+
+    /**
+     * The genre of the media.
+     */
+    public static final String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+
+    /**
+     * The track number for the media.
+     */
+    public static final String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+
+    /**
+     * The number of tracks in the media's original source.
+     */
+    public static final String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+
+    /**
+     * The disc number for the media's original source.
+     */
+    public static final String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+
+    /**
+     * The artist for the album of the media's original source.
+     */
+    public static final String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+
+    /**
+     * The artwork for the media as a {@link Bitmap}.
+     */
+    public static final String METADATA_KEY_ART = "android.media.metadata.ART";
+
+    /**
+     * The artwork for the media as a Uri style String.
+     */
+    public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+
+    /**
+     * The artwork for the album of the media's original source as a
+     * {@link Bitmap}.
+     */
+    public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+
+    /**
+     * The artwork for the album of the media's original source as a Uri style
+     * String.
+     */
+    public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+
+    /**
+     * The user's rating for the media.
+     *
+     * @see Rating
+     */
+    public static final String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+
+    /**
+     * The overall rating for the media.
+     *
+     * @see Rating
+     */
+    public static final String METADATA_KEY_RATING = "android.media.metadata.RATING";
+
+    private static final int METADATA_TYPE_INVALID = -1;
+    private static final int METADATA_TYPE_LONG = 0;
+    private static final int METADATA_TYPE_STRING = 1;
+    private static final int METADATA_TYPE_BITMAP = 2;
+    private static final int METADATA_TYPE_RATING = 3;
+    private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
+
+    static {
+        METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
+        METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DURATION, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISC_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ART_URI, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART_URI, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING);
+    }
+    private final Bundle mBundle;
+
+    private MediaMetadata(Bundle bundle) {
+        mBundle = new Bundle(bundle);
+    }
+
+    private MediaMetadata(Parcel in) {
+        mBundle = in.readBundle();
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if no mapping of
+     * the desired type exists for the given key or a null value is explicitly
+     * associated with the key.
+     *
+     * @param key The key the value is stored under
+     * @return a String value, or null
+     */
+    public String getString(String key) {
+        return mBundle.getString(key);
+    }
+
+    /**
+     * Returns the value associated with the given key, or 0L if no long exists
+     * for the given key.
+     *
+     * @param key The key the value is stored under
+     * @return a long value
+     */
+    public long getLong(String key) {
+        return mBundle.getLong(key);
+    }
+
+    /**
+     * Return a {@link Rating} for the given key or null if no rating exists for
+     * the given key.
+     *
+     * @param key The key the value is stored under
+     * @return A {@link Rating} or null
+     */
+    public Rating getRating(String key) {
+        Rating rating = null;
+        try {
+            rating = mBundle.getParcelable(key);
+        } catch (Exception e) {
+            // ignore, value was not a bitmap
+            Log.d(TAG, "Failed to retrieve a key as Rating.", e);
+        }
+        return rating;
+    }
+
+    /**
+     * Return a {@link Bitmap} for the given key or null if no bitmap exists for
+     * the given key.
+     *
+     * @param key The key the value is stored under
+     * @return A {@link Bitmap} or null
+     */
+    public Bitmap getBitmap(String key) {
+        Bitmap bmp = null;
+        try {
+            bmp = mBundle.getParcelable(key);
+        } catch (Exception e) {
+            // ignore, value was not a bitmap
+            Log.d(TAG, "Failed to retrieve a key as Bitmap.", e);
+        }
+        return bmp;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBundle(mBundle);
+    }
+
+    public static final Parcelable.Creator<MediaMetadata> CREATOR
+            = new Parcelable.Creator<MediaMetadata>() {
+                @Override
+                public MediaMetadata createFromParcel(Parcel in) {
+                    return new MediaMetadata(in);
+                }
+
+                @Override
+                public MediaMetadata[] newArray(int size) {
+                    return new MediaMetadata[size];
+                }
+            };
+
+    /**
+     * Use to build MediaMetadata objects. The system defined metadata keys must
+     * use the appropriate data type.
+     */
+    public static final class Builder {
+        private final Bundle mBundle;
+
+        /**
+         * Create an empty Builder. Any field that should be included in the
+         * {@link MediaMetadata} must be added.
+         */
+        public Builder() {
+            mBundle = new Bundle();
+        }
+
+        /**
+         * Create a Builder using a {@link MediaMetadata} instance to set the
+         * initial values. All fields in the source metadata will be included in
+         * the new metadata. Fields can be overwritten by adding the same key.
+         *
+         * @param source
+         */
+        public Builder(MediaMetadata source) {
+            mBundle = new Bundle(source.mBundle);
+        }
+
+        /**
+         * Put a String value into the metadata. Custom keys may be used, but if
+         * the METADATA_KEYs defined in this class are used they may only be one
+         * of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ALBUM}</li>
+         * <li>{@link #METADATA_KEY_AUTHOR}</li>
+         * <li>{@link #METADATA_KEY_WRITER}</li>
+         * <li>{@link #METADATA_KEY_COMPOSER}</li>
+         * <li>{@link #METADATA_KEY_DATE}</li>
+         * <li>{@link #METADATA_KEY_YEAR}</li>
+         * <li>{@link #METADATA_KEY_GENRE}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>li>
+         * <li>{@link #METADATA_KEY_ART_URI}</li>li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The String value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putString(String key, String value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_STRING) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a String");
+                }
+            }
+            mBundle.putString(key, value);
+            return this;
+        }
+
+        /**
+         * Put a long value into the metadata. Custom keys may be used, but if
+         * the METADATA_KEYs defined in this class are used they may only be one
+         * of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_DURATION}</li>
+         * <li>{@link #METADATA_KEY_TRACK_NUMBER}</li>
+         * <li>{@link #METADATA_KEY_NUM_TRACKS}</li>
+         * <li>{@link #METADATA_KEY_DISC_NUMBER}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The String value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putLong(String key, long value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_LONG) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a long");
+                }
+            }
+            mBundle.putLong(key, value);
+            return this;
+        }
+
+        /**
+         * Put a {@link Rating} into the metadata. Custom keys may be used, but
+         * if the METADATA_KEYs defined in this class are used they may only be
+         * one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_RATING}</li>
+         * <li>{@link #METADATA_KEY_USER_RATING}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The String value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putRating(String key, Rating value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_RATING) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a Rating");
+                }
+            }
+            mBundle.putParcelable(key, value);
+            return this;
+        }
+
+        /**
+         * Put a {@link Bitmap} into the metadata. Custom keys may be used, but
+         * if the METADATA_KEYs defined in this class are used they may only be
+         * one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_ART}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The Bitmap to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putBitmap(String key, Bitmap value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a Bitmap");
+                }
+            }
+            mBundle.putParcelable(key, value);
+            return this;
+        }
+
+        /**
+         * Creates a {@link MediaMetadata} instance with the specified fields.
+         *
+         * @return The new MediaMetadata instance
+         */
+        public MediaMetadata build() {
+            return new MediaMetadata(mBundle);
+        }
+    }
+
+}
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
new file mode 100644
index 0000000..23c3035
--- /dev/null
+++ b/media/java/android/media/session/MediaSession.java
@@ -0,0 +1,537 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.content.Intent;
+import android.media.Rating;
+import android.media.session.IMediaController;
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Allows interaction with media controllers, media routes, volume keys, media
+ * buttons, and transport controls.
+ * <p>
+ * A MediaSession should be created when an app wants to publish media playback
+ * information or negotiate with a media route. In general an app only needs one
+ * session for all playback, though multiple sessions can be created for sending
+ * media to multiple routes or to provide finer grain controls of media.
+ * <p>
+ * A MediaSession is created by calling
+ * {@link MediaSessionManager#createSession(String)}. Once a session is created
+ * apps that have the MEDIA_CONTENT_CONTROL permission can interact with the
+ * session through {@link MediaSessionManager#getActiveSessions()}. The owner of
+ * the session may also use {@link #getSessionToken()} to allow apps without
+ * this permission to create a {@link MediaController} to interact with this
+ * session.
+ * <p>
+ * To receive commands, media keys, and other events a Callback must be set with
+ * {@link #addCallback(Callback)}.
+ * <p>
+ * When an app is finished performing playback it must call {@link #release()}
+ * to clean up the session and notify any controllers.
+ * <p>
+ * MediaSession objects are thread safe
+ */
+public final class MediaSession {
+    private static final String TAG = "MediaSession";
+
+    private static final int MSG_MEDIA_BUTTON = 1;
+    private static final int MSG_COMMAND = 2;
+    private static final int MSG_ROUTE_CHANGE = 3;
+
+    private static final String KEY_COMMAND = "command";
+    private static final String KEY_EXTRAS = "extras";
+    private static final String KEY_CALLBACK = "callback";
+
+    private final Object mLock = new Object();
+
+    private final MediaSessionToken mSessionToken;
+    private final IMediaSession mBinder;
+    private final CallbackStub mCbStub;
+
+    private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
+    // TODO route interfaces
+    private final ArrayMap<String, RouteInterface.Stub> mInterfaces
+            = new ArrayMap<String, RouteInterface.Stub>();
+
+    private TransportPerformer mPerformer;
+
+    private boolean mPublished = false;;
+
+    /**
+     * @hide
+     */
+    public MediaSession(IMediaSession binder, CallbackStub cbStub) {
+        mBinder = binder;
+        mCbStub = cbStub;
+        IMediaController controllerBinder = null;
+        try {
+            controllerBinder = mBinder.getMediaController();
+        } catch (RemoteException e) {
+            throw new RuntimeException("Dead object in MediaSessionController constructor: ", e);
+        }
+        mSessionToken = new MediaSessionToken(controllerBinder);
+    }
+
+    /**
+     * Set the callback to receive updates on.
+     *
+     * @param callback The callback object
+     */
+    public void addCallback(Callback callback) {
+        addCallback(callback, null);
+    }
+
+    public void addCallback(Callback callback, Handler handler) {
+        if (callback == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        synchronized (mLock) {
+            if (getHandlerForCallbackLocked(callback) != null) {
+                Log.w(TAG, "Callback is already added, ignoring");
+                return;
+            }
+            if (handler == null) {
+                handler = new Handler();
+            }
+            MessageHandler msgHandler = new MessageHandler(handler.getLooper(), callback);
+            mCallbacks.add(msgHandler);
+        }
+    }
+
+    public void removeCallback(Callback callback) {
+        synchronized (mLock) {
+            removeCallbackLocked(callback);
+        }
+    }
+
+    /**
+     * Start using a TransportPerformer with this media session. This must be
+     * called before calling publish and cannot be called more than once.
+     * Calling this will allow MediaControllers to retrieve a
+     * TransportController.
+     *
+     * @see TransportController
+     * @return The TransportPerformer created for this session
+     */
+    public TransportPerformer setTransportPerformerEnabled() {
+        if (mPerformer != null) {
+            throw new IllegalStateException("setTransportPerformer can only be called once.");
+        }
+        if (mPublished) {
+            throw new IllegalStateException("setTransportPerformer cannot be called after publish");
+        }
+
+        mPerformer = new TransportPerformer(mBinder);
+        try {
+            mBinder.setTransportPerformerEnabled();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setTransportPerformerEnabled.", e);
+        }
+        return mPerformer;
+    }
+
+    /**
+     * Retrieves the TransportPerformer used by this session. If called before
+     * {@link #setTransportPerformerEnabled} null will be returned.
+     *
+     * @return The TransportPerformer associated with this session or null
+     */
+    public TransportPerformer getTransportPerformer() {
+        return mPerformer;
+    }
+
+    /**
+     * Call after you have finished setting up the session. This will make it
+     * available to listeners and begin pushing updates to MediaControllers.
+     * This can only be called once.
+     */
+    public void publish() {
+        if (mPublished) {
+            throw new RuntimeException("publish() may only be called once.");
+        }
+        try {
+            mBinder.publish();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in publish.", e);
+        }
+        mPublished = true;
+    }
+
+    /**
+     * Add an interface that can be used by MediaSessions. TODO make this a
+     * route provider api
+     *
+     * @see RouteInterface
+     * @param iface The interface to add
+     * @hide
+     */
+    public void addInterface(RouteInterface.Stub iface) {
+        if (iface == null) {
+            throw new IllegalArgumentException("Stub cannot be null");
+        }
+        String name = iface.getName();
+        if (TextUtils.isEmpty(name)) {
+            throw new IllegalArgumentException("Stub must return a valid name");
+        }
+        if (mInterfaces.containsKey(iface)) {
+            throw new IllegalArgumentException("Interface is already added");
+        }
+        synchronized (mLock) {
+            mInterfaces.put(iface.getName(), iface);
+        }
+    }
+
+    /**
+     * Send a proprietary event to all MediaControllers listening to this
+     * Session. It's up to the Controller/Session owner to determine the meaning
+     * of any events.
+     *
+     * @param event The name of the event to send
+     * @param extras Any extras included with the event
+     */
+    public void sendEvent(String event, Bundle extras) {
+        if (TextUtils.isEmpty(event)) {
+            throw new IllegalArgumentException("event cannot be null or empty");
+        }
+        try {
+            mBinder.sendEvent(event, extras);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error sending event", e);
+        }
+    }
+
+    /**
+     * This must be called when an app has finished performing playback. If
+     * playback is expected to start again shortly the session can be left open,
+     * but it must be released if your activity or service is being destroyed.
+     */
+    public void release() {
+        try {
+            mBinder.destroy();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error releasing session: ", e);
+        }
+    }
+
+    /**
+     * Retrieve a token object that can be used by apps to create a
+     * {@link MediaController} for interacting with this session. The owner of
+     * the session is responsible for deciding how to distribute these tokens.
+     *
+     * @return A token that can be used to create a MediaController for this
+     *         session
+     */
+    public MediaSessionToken getSessionToken() {
+        return mSessionToken;
+    }
+
+    private MessageHandler getHandlerForCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private boolean removeCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                mCallbacks.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void postCommand(String command, Bundle extras, ResultReceiver resultCb) {
+        Command cmd = new Command(command, extras, resultCb);
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(MSG_COMMAND, cmd);
+            }
+        }
+    }
+
+    private void postMediaButton(Intent mediaButtonIntent) {
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(MSG_MEDIA_BUTTON, mediaButtonIntent);
+            }
+        }
+    }
+
+    private void postRequestRouteChange(Bundle mediaRouteDescriptor) {
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(MSG_ROUTE_CHANGE, mediaRouteDescriptor);
+            }
+        }
+    }
+
+    /**
+     * Receives commands or updates from controllers and routes. An app can
+     * specify what commands and buttons it supports by setting them on the
+     * MediaSession (TODO).
+     */
+    public abstract static class Callback {
+
+        public Callback() {
+        }
+
+        /**
+         * Called when a media button is pressed and this session has the
+         * highest priority or a controller sends a media button event to the
+         * session. TODO determine if using Intents identical to the ones
+         * RemoteControlClient receives is useful
+         * <p>
+         * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a
+         * KeyEvent in {@link Intent#EXTRA_KEY_EVENT}
+         *
+         * @param mediaButtonIntent an intent containing the KeyEvent as an
+         *            extra
+         */
+        public void onMediaButton(Intent mediaButtonIntent) {
+        }
+
+        /**
+         * Called when a controller has sent a custom command to this session.
+         * The owner of the session may handle custom commands but is not
+         * required to.
+         *
+         * @param command
+         * @param extras optional
+         */
+        public void onCommand(String command, Bundle extras, ResultReceiver cb) {
+        }
+
+        /**
+         * Called when the user has selected a different route to connect to.
+         * The app is responsible for connecting to the new route and migrating
+         * ongoing playback if necessary.
+         *
+         * @param descriptor
+         */
+        public void onRequestRouteChange(Bundle descriptor) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static class CallbackStub extends IMediaSessionCallback.Stub {
+        private WeakReference<MediaSession> mMediaSession;
+
+        public void setMediaSession(MediaSession session) {
+            mMediaSession = new WeakReference<MediaSession>(session);
+        }
+
+        @Override
+        public void onCommand(String command, Bundle extras, ResultReceiver cb)
+                throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.postCommand(command, extras, cb);
+            }
+        }
+
+        @Override
+        public void onMediaButton(Intent mediaButtonIntent) throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.postMediaButton(mediaButtonIntent);
+            }
+        }
+
+        @Override
+        public void onRequestRouteChange(Bundle mediaRouteDescriptor) throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.postRequestRouteChange(mediaRouteDescriptor);
+            }
+        }
+
+        @Override
+        public void onPlay() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onPlay();
+                }
+            }
+        }
+
+        @Override
+        public void onPause() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onPause();
+                }
+            }
+        }
+
+        @Override
+        public void onStop() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onStop();
+                }
+            }
+        }
+
+        @Override
+        public void onNext() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onNext();
+                }
+            }
+        }
+
+        @Override
+        public void onPrevious() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onPrevious();
+                }
+            }
+        }
+
+        @Override
+        public void onFastForward() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onFastForward();
+                }
+            }
+        }
+
+        @Override
+        public void onRewind() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onRewind();
+                }
+            }
+        }
+
+        @Override
+        public void onSeekTo(long pos) throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onSeekTo(pos);
+                }
+            }
+        }
+
+        @Override
+        public void onRate(Rating rating) throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onRate(rating);
+                }
+            }
+        }
+
+    }
+
+    private class MessageHandler extends Handler {
+        private MediaSession.Callback mCallback;
+
+        public MessageHandler(Looper looper, MediaSession.Callback callback) {
+            super(looper, null, true);
+            mCallback = callback;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            synchronized (mLock) {
+                if (mCallback == null) {
+                    return;
+                }
+                switch (msg.what) {
+                    case MSG_MEDIA_BUTTON:
+                        mCallback.onMediaButton((Intent) msg.obj);
+                        break;
+                    case MSG_COMMAND:
+                        Command cmd = (Command) msg.obj;
+                        mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
+                        break;
+                    case MSG_ROUTE_CHANGE:
+                        mCallback.onRequestRouteChange((Bundle) msg.obj);
+                        break;
+                }
+            }
+            msg.recycle();
+        }
+
+        public void post(int what, Object obj) {
+            obtainMessage(what, obj).sendToTarget();
+        }
+    }
+
+    private static final class Command {
+        public final String command;
+        public final Bundle extras;
+        public final ResultReceiver stub;
+
+        public Command(String command, Bundle extras, ResultReceiver stub) {
+            this.command = command;
+            this.extras = extras;
+            this.stub = stub;
+        }
+    }
+}
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
new file mode 100644
index 0000000..e3f2d9c
--- /dev/null
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.content.Context;
+import android.media.session.IMediaSessionManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * MediaSessionManager allows the creation and control of MediaSessions in the
+ * system. A MediaSession enables publishing information about ongoing media and
+ * interacting with MediaControllers and MediaRoutes.
+ * <p>
+ * Use <code>Context.getSystemService(Context.MEDIA_SESSION_SERVICE)</code> to
+ * get an instance of this class.
+ * <p>
+ *
+ * @see MediaSession
+ * @see MediaController
+ */
+public final class MediaSessionManager {
+    private static final String TAG = "MediaSessionManager";
+
+    private final IMediaSessionManager mService;
+
+    private Context mContext;
+
+    /**
+     * @hide
+     */
+    public MediaSessionManager(Context context) {
+        // Consider rewriting like DisplayManagerGlobal
+        // Decide if we need context
+        mContext = context;
+        IBinder b = ServiceManager.getService(Context.MEDIA_SESSION_SERVICE);
+        mService = IMediaSessionManager.Stub.asInterface(b);
+    }
+
+    /**
+     * Creates a new session.
+     *
+     * @param tag A short name for debugging purposes
+     * @return a {@link MediaSession} for the new session
+     */
+    public MediaSession createSession(String tag) {
+        try {
+            MediaSession.CallbackStub cbStub = new MediaSession.CallbackStub();
+            MediaSession session = new MediaSession(mService
+                    .createSession(mContext.getPackageName(), cbStub, tag), cbStub);
+            cbStub.setMediaSession(session);
+
+            return session;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to create session: ", e);
+            return null;
+        }
+    }
+
+    /**
+     * Get a list of controllers for all ongoing sessions. This requires the
+     * android.Manifest.permission.MEDIA_CONTENT_CONTROL permission be held by
+     * the calling app.
+     *
+     * @return a list of controllers for ongoing sessions
+     */
+    public List<MediaController> getActiveSessions() {
+        // TODO
+        return new ArrayList<MediaController>();
+    }
+}
diff --git a/media/java/android/media/session/MediaSessionToken.aidl b/media/java/android/media/session/MediaSessionToken.aidl
new file mode 100644
index 0000000..5812682
--- /dev/null
+++ b/media/java/android/media/session/MediaSessionToken.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media.session;
+
+parcelable MediaSessionToken;
diff --git a/media/java/android/media/session/MediaSessionToken.java b/media/java/android/media/session/MediaSessionToken.java
new file mode 100644
index 0000000..dbb4964
--- /dev/null
+++ b/media/java/android/media/session/MediaSessionToken.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.session;
+
+import android.media.session.IMediaController;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class MediaSessionToken implements Parcelable {
+    private IMediaController mBinder;
+
+    /**
+     * @hide
+     */
+    MediaSessionToken(IMediaController binder) {
+        mBinder = binder;
+    }
+
+    private MediaSessionToken(Parcel in) {
+        mBinder = IMediaController.Stub.asInterface(in.readStrongBinder());
+    }
+
+    /**
+     * @hide
+     */
+    IMediaController getBinder() {
+        return mBinder;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStrongBinder(mBinder.asBinder());
+    }
+
+    public static final Parcelable.Creator<MediaSessionToken> CREATOR
+            = new Parcelable.Creator<MediaSessionToken>() {
+        @Override
+        public MediaSessionToken createFromParcel(Parcel in) {
+            return new MediaSessionToken(in);
+        }
+
+        @Override
+        public MediaSessionToken[] newArray(int size) {
+            return new MediaSessionToken[size];
+        }
+    };
+}
diff --git a/media/java/android/media/session/PlaybackState.aidl b/media/java/android/media/session/PlaybackState.aidl
new file mode 100644
index 0000000..0876ebd
--- /dev/null
+++ b/media/java/android/media/session/PlaybackState.aidl
@@ -0,0 +1,18 @@
+/* Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.media.session;
+
+parcelable PlaybackState;
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
new file mode 100644
index 0000000..b3506b3
--- /dev/null
+++ b/media/java/android/media/session/PlaybackState.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.session;
+
+import android.media.RemoteControlClient;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Playback state for a {@link MediaSession}. This includes a state like
+ * {@link PlaybackState#PLAYSTATE_PLAYING}, the current playback position,
+ * and the current control capabilities.
+ */
+public final class PlaybackState implements Parcelable {
+    /**
+     * Indicates this performer supports the stop command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_STOP = 1 << 0;
+
+    /**
+     * Indicates this performer supports the pause command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_PAUSE = 1 << 1;
+
+    /**
+     * Indicates this performer supports the play command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_PLAY = 1 << 2;
+
+    /**
+     * Indicates this performer supports the rewind command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_REWIND = 1 << 3;
+
+    /**
+     * Indicates this performer supports the previous command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_PREVIOUS_ITEM = 1 << 4;
+
+    /**
+     * Indicates this performer supports the next command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_NEXT_ITEM = 1 << 5;
+
+    /**
+     * Indicates this performer supports the fast forward command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_FASTFORWARD = 1 << 6;
+
+    /**
+     * Indicates this performer supports the set rating command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_RATING = 1 << 7;
+
+    /**
+     * Indicates this performer supports the seek to command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_SEEK_TO = 1 << 8;
+
+    /**
+     * This is the default playback state and indicates that no media has been
+     * added yet, or the performer has been reset and has no content to play.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_NONE = 0;
+
+    /**
+     * State indicating this item is currently stopped.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_STOPPED = 1;
+
+    /**
+     * State indicating this item is currently paused.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_PAUSED = 2;
+
+    /**
+     * State indicating this item is currently playing.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_PLAYING = 3;
+
+    /**
+     * State indicating this item is currently fast forwarding.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_FAST_FORWARDING = 4;
+
+    /**
+     * State indicating this item is currently rewinding.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_REWINDING = 5;
+
+    /**
+     * State indicating this item is currently buffering and will begin playing
+     * when enough data has buffered.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_BUFFERING = 6;
+
+    /**
+     * State indicating this item is currently in an error state. The error
+     * message should also be set when entering this state.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_ERROR = 7;
+
+    private int mState;
+    private long mPosition;
+    private long mBufferPosition;
+    private float mSpeed;
+    private long mCapabilities;
+    private String mErrorMessage;
+
+    /**
+     * Create an empty PlaybackState. At minimum a state and actions should be
+     * set before publishing a PlaybackState.
+     */
+    public PlaybackState() {
+    }
+
+    /**
+     * Create a new PlaybackState from an existing PlaybackState. All fields
+     * will be copied to the new state.
+     *
+     * @param from The PlaybackState to duplicate
+     */
+    public PlaybackState(PlaybackState from) {
+        this.setState(from.getState());
+        this.setPosition(from.getPosition());
+        this.setBufferPosition(from.getBufferPosition());
+        this.setSpeed(from.getSpeed());
+        this.setActions(from.getActions());
+        this.setErrorMessage(from.getErrorMessage());
+    }
+
+    private PlaybackState(Parcel in) {
+        this.setState(in.readInt());
+        this.setPosition(in.readLong());
+        this.setBufferPosition(in.readLong());
+        this.setSpeed(in.readFloat());
+        this.setActions(in.readLong());
+        this.setErrorMessage(in.readString());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(getState());
+        dest.writeLong(getPosition());
+        dest.writeLong(getBufferPosition());
+        dest.writeFloat(getSpeed());
+        dest.writeLong(getActions());
+        dest.writeString(getErrorMessage());
+    }
+
+    /**
+     * Get the current state of playback. One of the following:
+     * <ul>
+     * <li> {@link PlaybackState#PLAYSTATE_NONE}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_STOPPED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PLAYING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PAUSED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_FAST_FORWARDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_REWINDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_BUFFERING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_ERROR}</li>
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Set the current state of playback. One of the following:
+     * <ul>
+     * <li> {@link PlaybackState#PLAYSTATE_NONE}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_STOPPED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PLAYING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PAUSED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_FAST_FORWARDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_REWINDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_BUFFERING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_ERROR}</li>
+     */
+    public void setState(int mState) {
+        this.mState = mState;
+    }
+
+    /**
+     * Get the current playback position in ms.
+     */
+    public long getPosition() {
+        return mPosition;
+    }
+
+    /**
+     * Set the current playback position in ms.
+     */
+    public void setPosition(long position) {
+        mPosition = position;
+    }
+
+    /**
+     * Get the current buffer position in ms. This is the farthest playback
+     * point that can be reached from the current position using only buffered
+     * content.
+     */
+    public long getBufferPosition() {
+        return mBufferPosition;
+    }
+
+    /**
+     * Set the current buffer position in ms. This is the farthest playback
+     * point that can be reached from the current position using only buffered
+     * content.
+     */
+    public void setBufferPosition(long bufferPosition) {
+        mBufferPosition = bufferPosition;
+    }
+
+    /**
+     * Get the current playback speed as a multiple of normal playback. This
+     * should be negative when rewinding. A value of 1 means normal playback and
+     * 0 means paused.
+     */
+    public float getSpeed() {
+        return mSpeed;
+    }
+
+    /**
+     * Set the current playback speed as a multiple of normal playback. This
+     * should be negative when rewinding. A value of 1 means normal playback and
+     * 0 means paused.
+     */
+    public void setSpeed(float speed) {
+        mSpeed = speed;
+    }
+
+    /**
+     * Get the current actions available on this session. This should use a
+     * bitmask of the available actions.
+     * <ul>
+     * <li> {@link PlaybackState#ACTION_PREVIOUS_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_REWIND}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY}</li>
+     * <li> {@link PlaybackState#ACTION_PAUSE}</li>
+     * <li> {@link PlaybackState#ACTION_STOP}</li>
+     * <li> {@link PlaybackState#ACTION_FASTFORWARD}</li>
+     * <li> {@link PlaybackState#ACTION_NEXT_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
+     * <li> {@link PlaybackState#ACTION_RATING}</li>
+     * </ul>
+     */
+    public long getActions() {
+        return mCapabilities;
+    }
+
+    /**
+     * Set the current capabilities available on this session. This should use a
+     * bitmask of the available capabilities.
+     * <ul>
+     * <li> {@link PlaybackState#ACTION_PREVIOUS_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_REWIND}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY}</li>
+     * <li> {@link PlaybackState#ACTION_PAUSE}</li>
+     * <li> {@link PlaybackState#ACTION_STOP}</li>
+     * <li> {@link PlaybackState#ACTION_FASTFORWARD}</li>
+     * <li> {@link PlaybackState#ACTION_NEXT_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
+     * <li> {@link PlaybackState#ACTION_RATING}</li>
+     * </ul>
+     */
+    public void setActions(long capabilities) {
+        mCapabilities = capabilities;
+    }
+
+    /**
+     * Get a user readable error message. This should be set when the state is
+     * {@link PlaybackState#PLAYSTATE_ERROR}.
+     */
+    public String getErrorMessage() {
+        return mErrorMessage;
+    }
+
+    /**
+     * Set a user readable error message. This should be set when the state is
+     * {@link PlaybackState#PLAYSTATE_ERROR}.
+     */
+    public void setErrorMessage(String errorMessage) {
+        mErrorMessage = errorMessage;
+    }
+
+    public static final Parcelable.Creator<PlaybackState> CREATOR
+            = new Parcelable.Creator<PlaybackState>() {
+        @Override
+        public PlaybackState createFromParcel(Parcel in) {
+            return new PlaybackState(in);
+        }
+
+        @Override
+        public PlaybackState[] newArray(int size) {
+            return new PlaybackState[size];
+        }
+    };
+}
diff --git a/media/java/android/media/session/RouteInterface.java b/media/java/android/media/session/RouteInterface.java
new file mode 100644
index 0000000..2391f27
--- /dev/null
+++ b/media/java/android/media/session/RouteInterface.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.session;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcelable;
+import android.os.ResultReceiver;
+
+/**
+ * Routes can support multiple interfaces for MediaSessions to interact with. To
+ * add a standard interface you should implement that interface's RouteInterface
+ * Stub and register it with the session. The set of supported commands is
+ * dependent on the specific interface's implementation.
+ * <p>
+ * A MediaInterface can be registered by calling TODO. Once added an interface
+ * will be used by Sessions to decide how they communicate with a session and
+ * cannot be removed, so all interfaces that you plan to support should be added
+ * when the route is created.
+ *
+ * @see RouteTransportControls
+ */
+public final class RouteInterface {
+    private static final String TAG = "MediaInterface";
+
+    private static final String KEY_RESULT = "result";
+
+    private final MediaController mController;
+    private final String mIface;
+
+    /**
+     * @hide
+     */
+    RouteInterface(MediaController controller, String iface) {
+        mController = controller;
+        mIface = iface;
+    }
+
+    public void sendCommand(String command, Bundle params, ResultReceiver cb) {
+        // TODO
+    }
+
+    public void addListener(EventListener listener) {
+        addListener(listener, null);
+    }
+
+    public void addListener(EventListener listener, Handler handler) {
+        // TODO See MediaController for add/remove pattern
+    }
+
+    public void removeListener(EventListener listener) {
+        // TODO
+    }
+
+    // TODO decide on list of supported types
+    private static Bundle writeResultToBundle(Object v) {
+        Bundle b = new Bundle();
+        if (v == null) {
+            // Don't send anything if null
+        } else if (v instanceof String) {
+            b.putString(KEY_RESULT, (String) v);
+        } else if (v instanceof Integer) {
+            b.putInt(KEY_RESULT, (Integer) v);
+        } else if (v instanceof Bundle) {
+            // Must be before Parcelable
+            b.putBundle(KEY_RESULT, (Bundle) v);
+        } else if (v instanceof Parcelable) {
+            b.putParcelable(KEY_RESULT, (Parcelable) v);
+        } else if (v instanceof Short) {
+            b.putShort(KEY_RESULT, (Short) v);
+        } else if (v instanceof Long) {
+            b.putLong(KEY_RESULT, (Long) v);
+        } else if (v instanceof Float) {
+            b.putFloat(KEY_RESULT, (Float) v);
+        } else if (v instanceof Double) {
+            b.putDouble(KEY_RESULT, (Double) v);
+        } else if (v instanceof Boolean) {
+            b.putBoolean(KEY_RESULT, (Boolean) v);
+        } else if (v instanceof CharSequence) {
+            // Must be after String
+            b.putCharSequence(KEY_RESULT, (CharSequence) v);
+        } else if (v instanceof boolean[]) {
+            b.putBooleanArray(KEY_RESULT, (boolean[]) v);
+        } else if (v instanceof byte[]) {
+            b.putByteArray(KEY_RESULT, (byte[]) v);
+        } else if (v instanceof String[]) {
+            b.putStringArray(KEY_RESULT, (String[]) v);
+        } else if (v instanceof CharSequence[]) {
+            // Must be after String[] and before Object[]
+            b.putCharSequenceArray(KEY_RESULT, (CharSequence[]) v);
+        } else if (v instanceof IBinder) {
+            b.putBinder(KEY_RESULT, (IBinder) v);
+        } else if (v instanceof Parcelable[]) {
+            b.putParcelableArray(KEY_RESULT, (Parcelable[]) v);
+        } else if (v instanceof int[]) {
+            b.putIntArray(KEY_RESULT, (int[]) v);
+        } else if (v instanceof long[]) {
+            b.putLongArray(KEY_RESULT, (long[]) v);
+        } else if (v instanceof Byte) {
+            b.putByte(KEY_RESULT, (Byte) v);
+        }
+        return b;
+    }
+
+    public abstract static class Stub {
+
+        /**
+         * The name of an interface should be a fully qualified name to prevent
+         * namespace collisions. Example: "com.myproject.MyPlaybackInterface"
+         *
+         * @return The name of this interface
+         */
+        public abstract String getName();
+
+        /**
+         * This is called when a command is received that matches the interface
+         * you registered. Commands can come from any app with a MediaController
+         * reference to the session.
+         *
+         * @see MediaController
+         * @see MediaSession
+         * @param command The command or method to invoke.
+         * @param args Any args that were included with the command. May be
+         *            null.
+         * @param cb The callback provided to send a response on. May be null.
+         */
+        public abstract void onCommand(String command, Bundle args, ResultReceiver cb);
+
+        public final void sendEvent(MediaSession session, String event, Bundle extras) {
+            // TODO
+        }
+    }
+
+    /**
+     * An EventListener can be registered by an app with TODO to handle events
+     * sent by the session on a specific interface.
+     */
+    public static abstract class EventListener {
+        /**
+         * This is called when an event is received from the interface. Events
+         * are sent by the session owner and will be delivered to all
+         * controllers that are listening to the interface.
+         *
+         * @param event The event that occurred.
+         * @param args Any extras that were included with the event. May be
+         *            null.
+         */
+        public abstract void onEvent(String event, Bundle args);
+    }
+
+    private static final class EventHandler extends Handler {
+
+        private final RouteInterface.EventListener mListener;
+
+        public EventHandler(Looper looper, RouteInterface.EventListener cb) {
+            super(looper, null, true);
+            mListener = cb;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            mListener.onEvent((String) msg.obj, msg.getData());
+        }
+
+        public void postEvent(String event, Bundle args) {
+            Message msg = obtainMessage(0, event);
+            msg.setData(args);
+            msg.sendToTarget();
+        }
+    }
+}
diff --git a/media/java/android/media/session/RouteTransportControls.java b/media/java/android/media/session/RouteTransportControls.java
new file mode 100644
index 0000000..665fd10
--- /dev/null
+++ b/media/java/android/media/session/RouteTransportControls.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.session;
+
+import android.media.RemoteControlClient;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.ResultReceiver;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * A standard media control interface for Routes. Routes can support multiple
+ * interfaces for MediaSessions to interact with. TODO rewrite for routes
+ */
+public final class RouteTransportControls {
+    private static final String TAG = "RouteTransportControls";
+    public static final String NAME = "android.media.session.RouteTransportControls";
+
+    private static final String KEY_VALUE1 = "value1";
+
+    private static final String METHOD_FAST_FORWARD = "fastForward";
+    private static final String METHOD_GET_CURRENT_POSITION = "getCurrentPosition";
+    private static final String METHOD_GET_CAPABILITIES = "getCapabilities";
+
+    private static final String EVENT_PLAYSTATE_CHANGE = "playstateChange";
+    private static final String EVENT_METADATA_CHANGE = "metadataChange";
+
+    private final MediaController mController;
+    private final RouteInterface mIface;
+
+    private RouteTransportControls(RouteInterface iface, MediaController controller) {
+        mIface = iface;
+        mController = controller;
+    }
+
+    public static RouteTransportControls from(MediaController controller) {
+//        MediaInterface iface = controller.getInterface(NAME);
+//        if (iface != null) {
+//            return new RouteTransportControls(iface, controller);
+//        }
+        return null;
+    }
+
+    /**
+     * Send a play command to the route. TODO rename resume() and use messaging
+     * protocol, not KeyEvent
+     */
+    public void play() {
+        // TODO
+    }
+
+    /**
+     * Send a pause command to the session.
+     */
+    public void pause() {
+        // TODO
+    }
+
+    /**
+     * Set the rate at which to fastforward. Valid values are in the range [0,1]
+     * with actual rates depending on the implementation.
+     *
+     * @param rate
+     */
+    public void fastForward(float rate) {
+        if (rate < 0 || rate > 1) {
+            throw new IllegalArgumentException("Rate must be between 0 and 1 inclusive");
+        }
+        Bundle b = new Bundle();
+        b.putFloat(KEY_VALUE1, rate);
+        mIface.sendCommand(METHOD_FAST_FORWARD, b, null);
+    }
+
+    public void getCurrentPosition(ResultReceiver cb) {
+        mIface.sendCommand(METHOD_GET_CURRENT_POSITION, null, cb);
+    }
+
+    public void getCapabilities(ResultReceiver cb) {
+        mIface.sendCommand(METHOD_GET_CAPABILITIES, null, cb);
+    }
+
+    public void addListener(Listener listener) {
+        mIface.addListener(listener.mListener);
+    }
+
+    public void addListener(Listener listener, Handler handler) {
+        mIface.addListener(listener.mListener, handler);
+    }
+
+    public void removeListener(Listener listener) {
+        mIface.removeListener(listener.mListener);
+    }
+
+    public static abstract class Stub extends RouteInterface.Stub {
+        private final MediaSession mSession;
+
+        public Stub(MediaSession session) {
+            mSession = session;
+        }
+
+        @Override
+        public String getName() {
+            return NAME;
+        }
+
+        @Override
+        public void onCommand(String method, Bundle extras, ResultReceiver cb) {
+            if (TextUtils.isEmpty(method)) {
+                return;
+            }
+            Bundle result;
+            if (METHOD_FAST_FORWARD.equals(method)) {
+                fastForward(extras.getFloat(KEY_VALUE1, -1));
+            } else if (METHOD_GET_CURRENT_POSITION.equals(method)) {
+                if (cb != null) {
+                    result = new Bundle();
+                    result.putLong(KEY_VALUE1, getCurrentPosition());
+                    cb.send(0, result);
+                }
+            } else if (METHOD_GET_CAPABILITIES.equals(method)) {
+                if (cb != null) {
+                    result = new Bundle();
+                    result.putLong(KEY_VALUE1, getCapabilities());
+                    cb.send(0, result);
+                }
+            }
+        }
+
+        /**
+         * Override to handle fast forwarding. Valid values are [0,1] inclusive.
+         * The interpretation of the rate is up to the implementation. If no
+         * rate was included with the command a rate of -1 will be used by
+         * default.
+         *
+         * @param rate The rate at which to fast forward as a multiplier
+         */
+        public void fastForward(float rate) {
+            Log.w(TAG, "fastForward is not supported.");
+        }
+
+        /**
+         * Override to handle getting the current position of playback in
+         * millis.
+         *
+         * @return The current position in millis or -1
+         */
+        public long getCurrentPosition() {
+            Log.w(TAG, "getCurrentPosition is not supported");
+            return -1;
+        }
+
+        /**
+         * Override to handle getting the set of capabilities currently
+         * available.
+         *
+         * @return A bit mask of the supported capabilities
+         */
+        public long getCapabilities() {
+            Log.w(TAG, "getCapabilities is not supported");
+            return 0;
+        }
+
+        /**
+         * Publish the current playback state to the system and any controllers.
+         * Valid values are defined in {@link RemoteControlClient}. TODO move
+         * play states somewhere else.
+         *
+         * @param state
+         */
+        public final void updatePlaybackState(int state) {
+            Bundle extras = new Bundle();
+            extras.putInt(KEY_VALUE1, state);
+            sendEvent(mSession, EVENT_PLAYSTATE_CHANGE, extras);
+        }
+    }
+
+    /**
+     * Register this event listener using TODO to receive
+     * TransportControlInterface events from a session.
+     *
+     * @see RouteInterface.EventListener
+     */
+    public static abstract class Listener {
+
+        private RouteInterface.EventListener mListener = new RouteInterface.EventListener() {
+            @Override
+            public final void onEvent(String event, Bundle args) {
+                if (EVENT_PLAYSTATE_CHANGE.equals(event)) {
+                    onPlaybackStateChange(args.getInt(KEY_VALUE1));
+                } else if (EVENT_METADATA_CHANGE.equals(event)) {
+                    onMetadataUpdate(args);
+                }
+            }
+        };
+
+        /**
+         * Override to handle updates to the playback state. Valid values are in
+         * {@link TransportPerformer}. TODO put playstate values somewhere more
+         * generic.
+         *
+         * @param state
+         */
+        public void onPlaybackStateChange(int state) {
+        }
+
+        /**
+         * Override to handle metadata changes for this session's media. The
+         * default supported fields are those in {@link MediaMetadata}.
+         *
+         * @param metadata
+         */
+        public void onMetadataUpdate(Bundle metadata) {
+        }
+    }
+
+}
diff --git a/media/java/android/media/session/TransportController.java b/media/java/android/media/session/TransportController.java
new file mode 100644
index 0000000..15b11f3
--- /dev/null
+++ b/media/java/android/media/session/TransportController.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.session;
+
+import android.media.Rating;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Interface for controlling media playback on a session. This allows an app to
+ * request changes in playback, retrieve the current playback state and
+ * metadata, and listen for changes to the playback state and metadata.
+ */
+public final class TransportController {
+    private static final String TAG = "TransportController";
+
+    private final Object mLock = new Object();
+    private final ArrayList<MessageHandler> mListeners = new ArrayList<MessageHandler>();
+    private final IMediaController mBinder;
+
+    /**
+     * @hide
+     */
+    public TransportController(IMediaController binder) {
+        mBinder = binder;
+    }
+
+    /**
+     * Start listening to changes in playback state.
+     */
+    public void addStateListener(TransportStateListener listener) {
+        addStateListener(listener, null);
+    }
+
+    public void addStateListener(TransportStateListener listener, Handler handler) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            if (getHandlerForListenerLocked(listener) != null) {
+                Log.w(TAG, "Listener is already added, ignoring");
+                return;
+            }
+            if (handler == null) {
+                handler = new Handler();
+            }
+
+            MessageHandler msgHandler = new MessageHandler(handler.getLooper(), listener);
+            mListeners.add(msgHandler);
+        }
+    }
+
+    /**
+     * Stop listening to changes in playback state.
+     */
+    public void removeStateListener(TransportStateListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            removeStateListenerLocked(listener);
+        }
+    }
+
+    /**
+     * Request that the player start its playback at its current position.
+     */
+    public void play() {
+        try {
+            mBinder.play();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling play.", e);
+        }
+    }
+
+    /**
+     * Request that the player pause its playback and stay at its current
+     * position.
+     */
+    public void pause() {
+        try {
+            mBinder.pause();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling pause.", e);
+        }
+    }
+
+    /**
+     * Request that the player stop its playback; it may clear its state in
+     * whatever way is appropriate.
+     */
+    public void stop() {
+        try {
+            mBinder.stop();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling stop.", e);
+        }
+    }
+
+    /**
+     * Move to a new location in the media stream.
+     *
+     * @param pos Position to move to, in milliseconds.
+     */
+    public void seekTo(long pos) {
+        try {
+            mBinder.seekTo(pos);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling seekTo.", e);
+        }
+    }
+
+    /**
+     * Start fast forwarding. If playback is already fast forwarding this may
+     * increase the rate.
+     */
+    public void fastForward() {
+        try {
+            mBinder.fastForward();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling fastForward.", e);
+        }
+    }
+
+    /**
+     * Skip to the next item.
+     */
+    public void next() {
+        try {
+            mBinder.next();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling next.", e);
+        }
+    }
+
+    /**
+     * Start rewinding. If playback is already rewinding this may increase the
+     * rate.
+     */
+    public void rewind() {
+        try {
+            mBinder.rewind();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling rewind.", e);
+        }
+    }
+
+    /**
+     * Skip to the previous item.
+     */
+    public void previous() {
+        try {
+            mBinder.previous();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling previous.", e);
+        }
+    }
+
+    /**
+     * Rate the current content. This will cause the rating to be set for the
+     * current user. The Rating type must match the type returned by
+     * {@link #getRatingType()}.
+     *
+     * @param rating The rating to set for the current content
+     */
+    public void rate(Rating rating) {
+        try {
+            mBinder.rate(rating);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling rate.", e);
+        }
+    }
+
+    /**
+     * Get the rating type supported by the session. One of:
+     * <ul>
+     * <li>{@link Rating#RATING_NONE}</li>
+     * <li>{@link Rating#RATING_HEART}</li>
+     * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li>
+     * <li>{@link Rating#RATING_3_STARS}</li>
+     * <li>{@link Rating#RATING_4_STARS}</li>
+     * <li>{@link Rating#RATING_5_STARS}</li>
+     * <li>{@link Rating#RATING_PERCENTAGE}</li>
+     * </ul>
+     *
+     * @return The supported rating type
+     */
+    public int getRatingType() {
+        try {
+            return mBinder.getRatingType();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getRatingType.", e);
+            return Rating.RATING_NONE;
+        }
+    }
+
+    /**
+     * Get the current playback state for this session.
+     *
+     * @return The current PlaybackState or null
+     */
+    public PlaybackState getPlaybackState() {
+        try {
+            return mBinder.getPlaybackState();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getPlaybackState.", e);
+            return null;
+        }
+    }
+
+    /**
+     * Get the current metadata for this session.
+     *
+     * @return The current MediaMetadata or null.
+     */
+    public MediaMetadata getMetadata() {
+        try {
+            return mBinder.getMetadata();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getMetadata.", e);
+            return null;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public final void postPlaybackStateChanged(PlaybackState state) {
+        synchronized (mLock) {
+            for (int i = mListeners.size() - 1; i >= 0; i--) {
+                mListeners.get(i).post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE, state);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public final void postMetadataChanged(MediaMetadata metadata) {
+        synchronized (mLock) {
+            for (int i = mListeners.size() - 1; i >= 0; i--) {
+                mListeners.get(i).post(MessageHandler.MSG_UPDATE_METADATA,
+                        metadata);
+            }
+        }
+    }
+
+    private MessageHandler getHandlerForListenerLocked(TransportStateListener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mListeners.get(i);
+            if (listener == handler.mListener) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private boolean removeStateListenerLocked(TransportStateListener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            if (listener == mListeners.get(i).mListener) {
+                mListeners.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Register using {@link #addStateListener} to receive updates when there
+     * are playback changes on the session.
+     */
+    public static abstract class TransportStateListener {
+        private MessageHandler mHandler;
+        /**
+         * Override to handle changes in playback state.
+         *
+         * @param state The new playback state of the session
+         */
+        public void onPlaybackStateChanged(PlaybackState state) {
+        }
+
+        /**
+         * Override to handle changes to the current metadata.
+         *
+         * @see MediaMetadata
+         * @param metadata The current metadata for the session or null
+         */
+        public void onMetadataChanged(MediaMetadata metadata) {
+        }
+
+        private void setHandler(Handler handler) {
+            mHandler = new MessageHandler(handler.getLooper(), this);
+        }
+    }
+
+    private static class MessageHandler extends Handler {
+        private static final int MSG_UPDATE_PLAYBACK_STATE = 1;
+        private static final int MSG_UPDATE_METADATA = 2;
+
+        private TransportStateListener mListener;
+
+        public MessageHandler(Looper looper, TransportStateListener cb) {
+            super(looper, null, true);
+            mListener = cb;
+        }
+
+        public void post(int msg, Object obj) {
+            obtainMessage(msg, obj).sendToTarget();
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_PLAYBACK_STATE:
+                    mListener.onPlaybackStateChanged((PlaybackState) msg.obj);
+                    break;
+                case MSG_UPDATE_METADATA:
+                    mListener.onMetadataChanged((MediaMetadata) msg.obj);
+                    break;
+            }
+        }
+    }
+
+}
diff --git a/media/java/android/media/session/TransportPerformer.java b/media/java/android/media/session/TransportPerformer.java
new file mode 100644
index 0000000..b96db20
--- /dev/null
+++ b/media/java/android/media/session/TransportPerformer.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.media.session;
+
+import android.media.AudioManager;
+import android.media.Rating;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Allows broadcasting of playback changes.
+ */
+public final class TransportPerformer {
+    private static final String TAG = "TransportPerformer";
+    private final Object mLock = new Object();
+    private final ArrayList<MessageHandler> mListeners = new ArrayList<MessageHandler>();
+
+    private IMediaSession mBinder;
+
+    /**
+     * @hide
+     */
+    public TransportPerformer(IMediaSession binder) {
+        mBinder = binder;
+    }
+
+    /**
+     * Add a listener to receive updates on.
+     *
+     * @param listener The callback object
+     */
+    public void addListener(Listener listener) {
+        addListener(listener, null);
+    }
+
+    /**
+     * Add a listener to receive updates on. The updates will be posted to the
+     * specified handler. If no handler is provided they will be posted to the
+     * caller's thread.
+     *
+     * @param listener The listener to receive updates on
+     * @param handler The handler to post the updates on
+     */
+    public void addListener(Listener listener, Handler handler) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            if (getHandlerForListenerLocked(listener) != null) {
+                Log.w(TAG, "Listener is already added, ignoring");
+            }
+            if (handler == null) {
+                handler = new Handler();
+            }
+            MessageHandler msgHandler = new MessageHandler(handler.getLooper(), listener);
+            mListeners.add(msgHandler);
+        }
+    }
+
+    /**
+     * Stop receiving updates on the specified handler. If an update has already
+     * been posted you may still receive it after this call returns.
+     *
+     * @param listener The listener to stop receiving updates on
+     */
+    public void removeListener(Listener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            removeListenerLocked(listener);
+        }
+    }
+
+    /**
+     * Update the current playback state.
+     *
+     * @param state The current state of playback
+     */
+    public final void setPlaybackState(PlaybackState state) {
+        try {
+            mBinder.setPlaybackState(state);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * Update the current metadata. New metadata can be created using
+     * {@link MediaMetadata.Builder}.
+     *
+     * @param metadata The new metadata
+     */
+    public final void setMetadata(MediaMetadata metadata) {
+        try {
+            mBinder.setMetadata(metadata);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public final void onPlay() {
+        post(MessageHandler.MESSAGE_PLAY);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onPause() {
+        post(MessageHandler.MESSAGE_PAUSE);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onStop() {
+        post(MessageHandler.MESSAGE_STOP);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onNext() {
+        post(MessageHandler.MESSAGE_NEXT);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onPrevious() {
+        post(MessageHandler.MESSAGE_PREVIOUS);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onFastForward() {
+        post(MessageHandler.MESSAGE_FAST_FORWARD);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onRewind() {
+        post(MessageHandler.MESSAGE_REWIND);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onSeekTo(long pos) {
+        post(MessageHandler.MESSAGE_SEEK_TO, pos);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onRate(Rating rating) {
+        post(MessageHandler.MESSAGE_RATE, rating);
+    }
+
+    private MessageHandler getHandlerForListenerLocked(Listener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mListeners.get(i);
+            if (listener == handler.mListener) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private boolean removeListenerLocked(Listener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            if (listener == mListeners.get(i).mListener) {
+                mListeners.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void post(int what, Object obj) {
+        synchronized (mLock) {
+            for (int i = mListeners.size() - 1; i >= 0; i--) {
+                mListeners.get(i).post(what, obj);
+            }
+        }
+    }
+
+    private void post(int what) {
+        post(what, null);
+    }
+
+    /**
+     * Extend Listener to handle transport controls. Listeners can be registered
+     * using {@link #addListener}.
+     */
+    public static abstract class Listener {
+
+        /**
+         * Override to handle requests to begin playback.
+         */
+        public void onPlay() {
+        }
+
+        /**
+         * Override to handle requests to pause playback.
+         */
+        public void onPause() {
+        }
+
+        /**
+         * Override to handle requests to skip to the next media item.
+         */
+        public void onNext() {
+        }
+
+        /**
+         * Override to handle requests to skip to the previous media item.
+         */
+        public void onPrevious() {
+        }
+
+        /**
+         * Override to handle requests to fast forward.
+         */
+        public void onFastForward() {
+        }
+
+        /**
+         * Override to handle requests to rewind.
+         */
+        public void onRewind() {
+        }
+
+        /**
+         * Override to handle requests to stop playback.
+         */
+        public void onStop() {
+        }
+
+        /**
+         * Override to handle requests to seek to a specific position in ms.
+         *
+         * @param pos New position to move to, in milliseconds.
+         */
+        public void onSeekTo(long pos) {
+        }
+
+        /**
+         * Override to handle the item being rated.
+         *
+         * @param rating
+         */
+        public void onRate(Rating rating) {
+        }
+
+        /**
+         * Report that audio focus has changed on the app. This only happens if
+         * you have indicated you have started playing with
+         * {@link #setPlaybackState}. TODO figure out route focus apis/handling.
+         *
+         * @param focusChange The type of focus change, TBD. The default
+         *            implementation will deliver a call to {@link #onPause}
+         *            when focus is lost.
+         */
+        public void onRouteFocusChange(int focusChange) {
+            switch (focusChange) {
+                case AudioManager.AUDIOFOCUS_LOSS:
+                    onPause();
+                    break;
+            }
+        }
+    }
+
+    private class MessageHandler extends Handler {
+        private static final int MESSAGE_PLAY = 1;
+        private static final int MESSAGE_PAUSE = 2;
+        private static final int MESSAGE_STOP = 3;
+        private static final int MESSAGE_NEXT = 4;
+        private static final int MESSAGE_PREVIOUS = 5;
+        private static final int MESSAGE_FAST_FORWARD = 6;
+        private static final int MESSAGE_REWIND = 7;
+        private static final int MESSAGE_SEEK_TO = 8;
+        private static final int MESSAGE_RATE = 9;
+
+        private Listener mListener;
+
+        public MessageHandler(Looper looper, Listener cb) {
+            super(looper);
+            mListener = cb;
+        }
+
+        public void post(int what, Object obj) {
+            obtainMessage(what, obj).sendToTarget();
+        }
+
+        public void post(int what) {
+            post(what, null);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_PLAY:
+                    mListener.onPlay();
+                    break;
+                case MESSAGE_PAUSE:
+                    mListener.onPause();
+                    break;
+                case MESSAGE_STOP:
+                    mListener.onStop();
+                    break;
+                case MESSAGE_NEXT:
+                    mListener.onNext();
+                    break;
+                case MESSAGE_PREVIOUS:
+                    mListener.onPrevious();
+                    break;
+                case MESSAGE_FAST_FORWARD:
+                    mListener.onFastForward();
+                    break;
+                case MESSAGE_REWIND:
+                    mListener.onRewind();
+                    break;
+                case MESSAGE_SEEK_TO:
+                    mListener.onSeekTo((Long) msg.obj);
+                    break;
+                case MESSAGE_RATE:
+                    mListener.onRate((Rating) msg.obj);
+                    break;
+            }
+        }
+    }
+}
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 2b0b3e2..2d3de85 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -28,7 +28,6 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Paint;
-import android.graphics.Rect;
 import android.graphics.Matrix;
 import android.media.videoeditor.VideoEditor.ExportProgressListener;
 import android.media.videoeditor.VideoEditor.PreviewProgressListener;
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 9ceefc3..15ae238 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -16,21 +16,23 @@
 
 package android.mtp;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.ContentValues;
 import android.content.IContentProvider;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.media.MediaScanner;
 import android.net.Uri;
-import android.os.Environment;
+import android.os.BatteryManager;
+import android.os.BatteryStats;
 import android.os.RemoteException;
 import android.provider.MediaStore;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Files;
-import android.provider.MediaStore.Images;
 import android.provider.MediaStore.MediaColumns;
 import android.util.Log;
 import android.view.Display;
@@ -115,11 +117,35 @@
                                             + Files.FileColumns.PARENT + "=?";
 
     private final MediaScanner mMediaScanner;
+    private MtpServer mServer;
+
+    // read from native code
+    private int mBatteryLevel;
+    private int mBatteryScale;
 
     static {
         System.loadLibrary("media_jni");
     }
 
+    private BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {
+          @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
+                mBatteryScale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
+                int newLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
+                if (newLevel != mBatteryLevel) {
+                    mBatteryLevel = newLevel;
+                    if (mServer != null) {
+                        // send device property changed event
+                        mServer.sendDevicePropertyChanged(
+                                MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL);
+                    }
+                }
+            }
+        }
+    };
+
     public MtpDatabase(Context context, String volumeName, String storagePath,
             String[] subDirectories) {
         native_setup();
@@ -173,6 +199,18 @@
         initDeviceProperties(context);
     }
 
+    public void setServer(MtpServer server) {
+        mServer = server;
+
+        // register for battery notifications when we are connected
+        if (server != null) {
+            mContext.registerReceiver(mBatteryReceiver,
+                    new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+        } else {
+            mContext.unregisterReceiver(mBatteryReceiver);
+        }
+    }
+
     @Override
     protected void finalize() throws Throwable {
         try {
@@ -558,6 +596,11 @@
             MtpConstants.PROPERTY_DURATION,
             MtpConstants.PROPERTY_GENRE,
             MtpConstants.PROPERTY_COMPOSER,
+            MtpConstants.PROPERTY_AUDIO_WAVE_CODEC,
+            MtpConstants.PROPERTY_BITRATE_TYPE,
+            MtpConstants.PROPERTY_AUDIO_BITRATE,
+            MtpConstants.PROPERTY_NUMBER_OF_CHANNELS,
+            MtpConstants.PROPERTY_SAMPLE_RATE,
     };
 
     static final int[] VIDEO_PROPERTIES = {
@@ -665,6 +708,7 @@
             MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,
             MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,
             MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE,
+            MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL,
         };
     }
 
@@ -821,6 +865,8 @@
                 outStringValue[imageSize.length()] = 0;
                 return MtpConstants.RESPONSE_OK;
 
+            // DEVICE_PROPERTY_BATTERY_LEVEL is implemented in the JNI code
+
             default:
                 return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
         }
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index 8310579..72dcaa8 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -18,8 +18,6 @@
 
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbDeviceConnection;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
 
 /**
  * This class represents an MTP or PTP device connected on the USB host bus. An application can
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index 48da40f..781988d 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -20,7 +20,6 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.RemoteException;
-import android.provider.MediaStore;
 import android.provider.MediaStore.Audio;
 import android.provider.MediaStore.Files;
 import android.provider.MediaStore.Images;
diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java
index 266f78e..3814630 100644
--- a/media/java/android/mtp/MtpServer.java
+++ b/media/java/android/mtp/MtpServer.java
@@ -30,6 +30,7 @@
 
     public MtpServer(MtpDatabase database, boolean usePtp) {
         native_setup(database, usePtp);
+        database.setServer(this);
     }
 
     public void start() {
@@ -51,6 +52,10 @@
         native_send_object_removed(handle);
     }
 
+    public void sendDevicePropertyChanged(int property) {
+        native_send_device_property_changed(property);
+    }
+
     public void addStorage(MtpStorage storage) {
         native_add_storage(storage);
     }
@@ -64,6 +69,7 @@
     private native final void native_cleanup();
     private native final void native_send_object_added(int handle);
     private native final void native_send_object_removed(int handle);
+    private native final void native_send_device_property_changed(int property);
     private native final void native_add_storage(MtpStorage storage);
     private native final void native_remove_storage(int storageId);
 }
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index dea971e..ed98b96 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -8,6 +8,7 @@
     android_media_MediaCodecList.cpp \
     android_media_MediaDrm.cpp \
     android_media_MediaExtractor.cpp \
+    android_media_MediaHTTPConnection.cpp \
     android_media_MediaMuxer.cpp \
     android_media_MediaPlayer.cpp \
     android_media_MediaRecorder.cpp \
@@ -37,6 +38,7 @@
     libcamera_client \
     libmtp \
     libusbhost \
+    libjhead \
     libexif \
     libstagefright_amrnb_common \
 
@@ -60,8 +62,7 @@
     $(call include-path-for, libhardware)/hardware \
     system/media/camera/include \
     $(PV_INCLUDES) \
-    $(JNI_H_INCLUDE) \
-    $(call include-path-for, corecg graphics)
+    $(JNI_H_INCLUDE)
 
 LOCAL_CFLAGS +=
 
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index d475eee..fcd425e 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -86,8 +86,8 @@
     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 setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; }
+    IGraphicBufferProducer* getProducer() { return mProducer.get(); }
 
     void setBufferFormat(int format) { mFormat = format; }
     int getBufferFormat() { return mFormat; }
@@ -104,7 +104,7 @@
 
     List<CpuConsumer::LockedBuffer*> mBuffers;
     sp<CpuConsumer> mConsumer;
-    sp<BufferQueue> mBufferQueue;
+    sp<IGraphicBufferProducer> mProducer;
     jobject mWeakThiz;
     jclass mClazz;
     int mFormat;
@@ -222,7 +222,7 @@
     return ctx->getCpuConsumer();
 }
 
-static BufferQueue* ImageReader_getBufferQueue(JNIEnv* env, jobject thiz)
+static IGraphicBufferProducer* ImageReader_getProducer(JNIEnv* env, jobject thiz)
 {
     ALOGV("%s:", __FUNCTION__);
     JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz);
@@ -230,7 +230,7 @@
         jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
         return NULL;
     }
-    return ctx->getBufferQueue();
+    return ctx->getProducer();
 }
 
 static void ImageReader_setNativeContext(JNIEnv* env,
@@ -613,8 +613,10 @@
 
     nativeFormat = Image_getPixelFormat(env, format);
 
-    sp<BufferQueue> bq = new BufferQueue();
-    sp<CpuConsumer> consumer = new CpuConsumer(bq, maxImages,
+    sp<IGraphicBufferProducer> gbProducer;
+    sp<IGraphicBufferConsumer> gbConsumer;
+    BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
+    sp<CpuConsumer> consumer = new CpuConsumer(gbConsumer, maxImages,
                                                /*controlledByApp*/true);
     // TODO: throw dvm exOutOfMemoryError?
     if (consumer == NULL) {
@@ -629,7 +631,7 @@
     }
     sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages));
     ctx->setCpuConsumer(consumer);
-    ctx->setBufferQueue(bq);
+    ctx->setProducer(gbProducer);
     consumer->setFrameAvailableListener(ctx);
     ImageReader_setNativeContext(env, thiz, ctx);
     ctx->setBufferFormat(nativeFormat);
@@ -794,14 +796,14 @@
 {
     ALOGV("%s: ", __FUNCTION__);
 
-    BufferQueue* bq = ImageReader_getBufferQueue(env, thiz);
-    if (bq == NULL) {
+    IGraphicBufferProducer* gbp = ImageReader_getProducer(env, thiz);
+    if (gbp == NULL) {
         jniThrowRuntimeException(env, "CpuConsumer is uninitialized");
         return NULL;
     }
 
     // Wrap the IGBP in a Java-language Surface.
-    return android_view_Surface_createFromIGraphicBufferProducer(env, bq);
+    return android_view_Surface_createFromIGraphicBufferProducer(env, gbp);
 }
 
 static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx)
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 221ea57..b2fb2df 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -51,6 +51,10 @@
     DEQUEUE_INFO_OUTPUT_BUFFERS_CHANGED     = -3,
 };
 
+enum {
+    EVENT_NOTIFY = 1,
+};
+
 struct CryptoErrorCodes {
     jint cryptoErrorNoKey;
     jint cryptoErrorKeyExpired;
@@ -59,6 +63,7 @@
 
 struct fields_t {
     jfieldID context;
+    jmethodID postEventFromNativeID;
     jfieldID cryptoInfoNumSubSamplesID;
     jfieldID cryptoInfoNumBytesOfClearDataID;
     jfieldID cryptoInfoNumBytesOfEncryptedDataID;
@@ -75,7 +80,9 @@
         JNIEnv *env, jobject thiz,
         const char *name, bool nameIsType, bool encoder)
     : mClass(NULL),
-      mObject(NULL) {
+      mObject(NULL),
+      mGeneration(1),
+      mRequestedActivityNotification(false) {
     jclass clazz = env->GetObjectClass(thiz);
     CHECK(clazz != NULL);
 
@@ -87,7 +94,7 @@
 
     mLooper->start(
             false,      // runOnCallingThread
-            false,       // canCallJava
+            true,       // canCallJava
             PRIORITY_FOREGROUND);
 
     if (nameIsType) {
@@ -101,12 +108,39 @@
     return mCodec != NULL ? OK : NO_INIT;
 }
 
-JMediaCodec::~JMediaCodec() {
+void JMediaCodec::registerSelf() {
+    mLooper->registerHandler(this);
+}
+
+void JMediaCodec::release() {
     if (mCodec != NULL) {
         mCodec->release();
         mCodec.clear();
     }
 
+    if (mLooper != NULL) {
+        mLooper->unregisterHandler(id());
+        mLooper->stop();
+        mLooper.clear();
+    }
+}
+
+JMediaCodec::~JMediaCodec() {
+    if (mCodec != NULL || mLooper != NULL) {
+        /* MediaCodec and looper should have been released explicitly already
+         * in setMediaCodec() (see comments in setMediaCodec()).
+         *
+         * Otherwise JMediaCodec::~JMediaCodec() might be called from within the
+         * message handler, doing release() there risks deadlock as MediaCodec::
+         * release() post synchronous message to the same looper.
+         *
+         * Print a warning and try to proceed with releasing.
+         */
+        ALOGW("try to release MediaCodec from JMediaCodec::~JMediaCodec()...");
+        release();
+        ALOGW("done releasing MediaCodec from JMediaCodec::~JMediaCodec().");
+    }
+
     JNIEnv *env = AndroidRuntime::getJNIEnv();
 
     env->DeleteWeakGlobalRef(mObject);
@@ -122,7 +156,8 @@
         int flags) {
     sp<Surface> client;
     if (bufferProducer != NULL) {
-        mSurfaceTextureClient = new Surface(bufferProducer, true /* controlledByApp */);
+        mSurfaceTextureClient =
+            new Surface(bufferProducer, true /* controlledByApp */);
     } else {
         mSurfaceTextureClient.clear();
     }
@@ -136,13 +171,32 @@
 }
 
 status_t JMediaCodec::start() {
-    return mCodec->start();
+    status_t err = mCodec->start();
+
+    if (err != OK) {
+        return err;
+    }
+
+    mActivityNotification = new AMessage(kWhatActivityNotify, id());
+    mActivityNotification->setInt32("generation", mGeneration);
+
+    requestActivityNotification();
+
+    return err;
 }
 
 status_t JMediaCodec::stop() {
     mSurfaceTextureClient.clear();
 
-    return mCodec->stop();
+    status_t err = mCodec->stop();
+
+    sp<AMessage> msg = new AMessage(kWhatStopActivityNotifications, id());
+    sp<AMessage> response;
+    msg->postAndAwaitResponse(&response);
+
+    mActivityNotification.clear();
+
+    return err;
 }
 
 status_t JMediaCodec::flush() {
@@ -174,7 +228,11 @@
 }
 
 status_t JMediaCodec::dequeueInputBuffer(size_t *index, int64_t timeoutUs) {
-    return mCodec->dequeueInputBuffer(index, timeoutUs);
+    status_t err = mCodec->dequeueInputBuffer(index, timeoutUs);
+
+    requestActivityNotification();
+
+    return err;
 }
 
 status_t JMediaCodec::dequeueOutputBuffer(
@@ -182,9 +240,12 @@
     size_t size, offset;
     int64_t timeUs;
     uint32_t flags;
-    status_t err;
-    if ((err = mCodec->dequeueOutputBuffer(
-                    index, &offset, &size, &timeUs, &flags, timeoutUs)) != OK) {
+    status_t err = mCodec->dequeueOutputBuffer(
+            index, &offset, &size, &timeUs, &flags, timeoutUs);
+
+    requestActivityNotification();
+
+    if (err != OK) {
         return err;
     }
 
@@ -320,6 +381,67 @@
     }
 }
 
+void JMediaCodec::onMessageReceived(const sp<AMessage> &msg) {
+    switch (msg->what()) {
+        case kWhatRequestActivityNotifications:
+        {
+            if (mRequestedActivityNotification) {
+                break;
+            }
+
+            mCodec->requestActivityNotification(mActivityNotification);
+            mRequestedActivityNotification = true;
+            break;
+        }
+
+        case kWhatActivityNotify:
+        {
+            {
+                int32_t generation;
+                CHECK(msg->findInt32("generation", &generation));
+
+                if (generation != mGeneration) {
+                    // stale
+                    break;
+                }
+
+                mRequestedActivityNotification = false;
+            }
+
+            JNIEnv *env = AndroidRuntime::getJNIEnv();
+            env->CallVoidMethod(
+                    mObject,
+                    gFields.postEventFromNativeID,
+                    EVENT_NOTIFY,
+                    0 /* arg1 */,
+                    0 /* arg2 */,
+                    NULL /* obj */);
+
+            break;
+        }
+
+        case kWhatStopActivityNotifications:
+        {
+            uint32_t replyID;
+            CHECK(msg->senderAwaitsResponse(&replyID));
+
+            ++mGeneration;
+            mRequestedActivityNotification = false;
+
+            sp<AMessage> response = new AMessage;
+            response->postReply(replyID);
+            break;
+        }
+
+        default:
+            TRESPASS();
+    }
+}
+
+void JMediaCodec::requestActivityNotification() {
+    (new AMessage(kWhatRequestActivityNotifications, id()))->post();
+}
+
 }  // namespace android
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -333,6 +455,12 @@
         codec->incStrong(thiz);
     }
     if (old != NULL) {
+        /* release MediaCodec and stop the looper now before decStrong.
+         * otherwise JMediaCodec::~JMediaCodec() could be called from within
+         * its message handler, doing release() from there will deadlock
+         * (as MediaCodec::release() post synchronous message to the same looper)
+         */
+        old->release();
         old->decStrong(thiz);
     }
     env->SetLongField(thiz, gFields.context, (jlong)codec.get());
@@ -888,6 +1016,12 @@
     gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
     CHECK(gFields.context != NULL);
 
+    gFields.postEventFromNativeID =
+        env->GetMethodID(
+                clazz.get(), "postEventFromNative", "(IIILjava/lang/Object;)V");
+
+    CHECK(gFields.postEventFromNativeID != NULL);
+
     clazz.reset(env->FindClass("android/media/MediaCodec$CryptoInfo"));
     CHECK(clazz.get() != NULL);
 
@@ -961,6 +1095,8 @@
         return;
     }
 
+    codec->registerSelf();
+
     setMediaCodec(env,thiz, codec);
 }
 
@@ -981,7 +1117,7 @@
       (void *)android_media_MediaCodec_createInputSurface },
 
     { "start", "()V", (void *)android_media_MediaCodec_start },
-    { "stop", "()V", (void *)android_media_MediaCodec_stop },
+    { "native_stop", "()V", (void *)android_media_MediaCodec_stop },
     { "flush", "()V", (void *)android_media_MediaCodec_flush },
 
     { "queueInputBuffer", "(IIIJI)V",
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 2fbbd72..2f2ea96 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -21,8 +21,8 @@
 
 #include <media/hardware/CryptoAPI.h>
 #include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/foundation/AHandler.h>
 #include <utils/Errors.h>
-#include <utils/RefBase.h>
 
 namespace android {
 
@@ -34,13 +34,16 @@
 struct MediaCodec;
 class Surface;
 
-struct JMediaCodec : public RefBase {
+struct JMediaCodec : public AHandler {
     JMediaCodec(
             JNIEnv *env, jobject thiz,
             const char *name, bool nameIsType, bool encoder);
 
     status_t initCheck() const;
 
+    void registerSelf();
+    void release();
+
     status_t configure(
             const sp<AMessage> &format,
             const sp<IGraphicBufferProducer> &bufferProducer,
@@ -94,7 +97,15 @@
 protected:
     virtual ~JMediaCodec();
 
+    virtual void onMessageReceived(const sp<AMessage> &msg);
+
 private:
+    enum {
+        kWhatActivityNotify,
+        kWhatRequestActivityNotifications,
+        kWhatStopActivityNotifications,
+    };
+
     jclass mClass;
     jweak mObject;
     sp<Surface> mSurfaceTextureClient;
@@ -102,6 +113,12 @@
     sp<ALooper> mLooper;
     sp<MediaCodec> mCodec;
 
+    sp<AMessage> mActivityNotification;
+    int32_t mGeneration;
+    bool mRequestedActivityNotification;
+
+    void requestActivityNotification();
+
     DISALLOW_EVIL_CONSTRUCTORS(JMediaCodec);
 };
 
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 543cb6c..a78f16d 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -26,6 +26,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 
+#include <media/IMediaHTTPService.h>
 #include <media/hardware/CryptoAPI.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -35,6 +36,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/NuMediaExtractor.h>
 
+#include "android_util_Binder.h"
+
 namespace android {
 
 struct fields_t {
@@ -135,8 +138,10 @@
 }
 
 status_t JMediaExtractor::setDataSource(
-        const char *path, const KeyedVector<String8, String8> *headers) {
-    return mImpl->setDataSource(path, headers);
+        const sp<IMediaHTTPService> &httpService,
+        const char *path,
+        const KeyedVector<String8, String8> *headers) {
+    return mImpl->setDataSource(httpService, path, headers);
 }
 
 status_t JMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {
@@ -661,7 +666,10 @@
 
 static void android_media_MediaExtractor_setDataSource(
         JNIEnv *env, jobject thiz,
-        jstring pathObj, jobjectArray keysArray, jobjectArray valuesArray) {
+        jobject httpServiceBinderObj,
+        jstring pathObj,
+        jobjectArray keysArray,
+        jobjectArray valuesArray) {
     sp<JMediaExtractor> extractor = getMediaExtractor(env, thiz);
 
     if (extractor == NULL) {
@@ -686,7 +694,13 @@
         return;
     }
 
-    status_t err = extractor->setDataSource(path, &headers);
+    sp<IMediaHTTPService> httpService;
+    if (httpServiceBinderObj != NULL) {
+        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
+        httpService = interface_cast<IMediaHTTPService>(binder);
+    }
+
+    status_t err = extractor->setDataSource(httpService, path, &headers);
 
     env->ReleaseStringUTFChars(pathObj, path);
     path = NULL;
@@ -839,8 +853,9 @@
     { "native_finalize", "()V",
       (void *)android_media_MediaExtractor_native_finalize },
 
-    { "setDataSource", "(Ljava/lang/String;[Ljava/lang/String;"
-                       "[Ljava/lang/String;)V",
+    { "nativeSetDataSource",
+        "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;"
+        "[Ljava/lang/String;)V",
       (void *)android_media_MediaExtractor_setDataSource },
 
     { "setDataSource", "(Ljava/io/FileDescriptor;JJ)V",
diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h
index ccbad8c..e5a0c16e 100644
--- a/media/jni/android_media_MediaExtractor.h
+++ b/media/jni/android_media_MediaExtractor.h
@@ -29,6 +29,7 @@
 
 namespace android {
 
+struct IMediaHTTPService;
 struct MetaData;
 struct NuMediaExtractor;
 
@@ -36,6 +37,7 @@
     JMediaExtractor(JNIEnv *env, jobject thiz);
 
     status_t setDataSource(
+            const sp<IMediaHTTPService> &httpService,
             const char *path,
             const KeyedVector<String8, String8> *headers);
 
diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp
new file mode 100644
index 0000000..0e7d83e
--- /dev/null
+++ b/media/jni/android_media_MediaHTTPConnection.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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 "MediaHTTPConnection-JNI"
+#include <utils/Log.h>
+
+#include <binder/MemoryDealer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <nativehelper/ScopedLocalRef.h>
+
+#include "android_media_MediaHTTPConnection.h"
+#include "android_util_Binder.h"
+
+#include "android_runtime/AndroidRuntime.h"
+#include "jni.h"
+#include "JNIHelp.h"
+
+namespace android {
+
+JMediaHTTPConnection::JMediaHTTPConnection(JNIEnv *env, jobject thiz)
+    : mClass(NULL),
+      mObject(NULL),
+      mByteArrayObj(NULL) {
+    jclass clazz = env->GetObjectClass(thiz);
+    CHECK(clazz != NULL);
+
+    mClass = (jclass)env->NewGlobalRef(clazz);
+    mObject = env->NewWeakGlobalRef(thiz);
+
+    mDealer = new MemoryDealer(kBufferSize, "MediaHTTPConnection");
+    mMemory = mDealer->allocate(kBufferSize);
+
+    ScopedLocalRef<jbyteArray> tmp(
+            env, env->NewByteArray(JMediaHTTPConnection::kBufferSize));
+
+    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
+}
+
+JMediaHTTPConnection::~JMediaHTTPConnection() {
+    JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+    env->DeleteGlobalRef(mByteArrayObj);
+    mByteArrayObj = NULL;
+    env->DeleteWeakGlobalRef(mObject);
+    mObject = NULL;
+    env->DeleteGlobalRef(mClass);
+    mClass = NULL;
+}
+
+sp<IMemory> JMediaHTTPConnection::getIMemory() {
+    return mMemory;
+}
+
+jbyteArray JMediaHTTPConnection::getByteArrayObj() {
+    return mByteArrayObj;
+}
+
+}  // namespace android
+
+using namespace android;
+
+struct fields_t {
+    jfieldID context;
+
+    jmethodID readAtMethodID;
+};
+
+static fields_t gFields;
+
+static sp<JMediaHTTPConnection> setObject(
+        JNIEnv *env, jobject thiz, const sp<JMediaHTTPConnection> &conn) {
+    sp<JMediaHTTPConnection> old =
+        (JMediaHTTPConnection *)env->GetLongField(thiz, gFields.context);
+
+    if (conn != NULL) {
+        conn->incStrong(thiz);
+    }
+    if (old != NULL) {
+        old->decStrong(thiz);
+    }
+    env->SetLongField(thiz, gFields.context, (jlong)conn.get());
+
+    return old;
+}
+
+static sp<JMediaHTTPConnection> getObject(JNIEnv *env, jobject thiz) {
+    return (JMediaHTTPConnection *)env->GetLongField(thiz, gFields.context);
+}
+
+static void android_media_MediaHTTPConnection_native_init(JNIEnv *env) {
+    ScopedLocalRef<jclass> clazz(
+            env, env->FindClass("android/media/MediaHTTPConnection"));
+    CHECK(clazz.get() != NULL);
+
+    gFields.context = env->GetFieldID(clazz.get(), "mNativeContext", "J");
+    CHECK(gFields.context != NULL);
+
+    gFields.readAtMethodID = env->GetMethodID(clazz.get(), "readAt", "(J[BI)I");
+}
+
+static void android_media_MediaHTTPConnection_native_setup(
+        JNIEnv *env, jobject thiz) {
+    sp<JMediaHTTPConnection> conn = new JMediaHTTPConnection(env, thiz);
+
+    setObject(env, thiz, conn);
+}
+
+static void android_media_MediaHTTPConnection_native_finalize(
+        JNIEnv *env, jobject thiz) {
+    setObject(env, thiz, NULL);
+}
+
+static jobject android_media_MediaHTTPConnection_native_getIMemory(
+        JNIEnv *env, jobject thiz) {
+    sp<JMediaHTTPConnection> conn = getObject(env, thiz);
+
+    return javaObjectForIBinder(env, conn->getIMemory()->asBinder());
+}
+
+static jint android_media_MediaHTTPConnection_native_readAt(
+        JNIEnv *env, jobject thiz, jlong offset, jint size) {
+    sp<JMediaHTTPConnection> conn = getObject(env, thiz);
+
+    if (size > JMediaHTTPConnection::kBufferSize) {
+        size = JMediaHTTPConnection::kBufferSize;
+    }
+
+    jbyteArray byteArrayObj = conn->getByteArrayObj();
+
+    jint n = env->CallIntMethod(
+            thiz, gFields.readAtMethodID, offset, byteArrayObj, size);
+
+    if (n > 0) {
+        env->GetByteArrayRegion(
+                byteArrayObj,
+                0,
+                n,
+                (jbyte *)conn->getIMemory()->pointer());
+    }
+
+    return n;
+}
+
+static JNINativeMethod gMethods[] = {
+    { "native_getIMemory", "()Landroid/os/IBinder;",
+      (void *)android_media_MediaHTTPConnection_native_getIMemory },
+
+    { "native_readAt", "(JI)I",
+      (void *)android_media_MediaHTTPConnection_native_readAt },
+
+    { "native_init", "()V",
+      (void *)android_media_MediaHTTPConnection_native_init },
+
+    { "native_setup", "()V",
+      (void *)android_media_MediaHTTPConnection_native_setup },
+
+    { "native_finalize", "()V",
+      (void *)android_media_MediaHTTPConnection_native_finalize },
+};
+
+int register_android_media_MediaHTTPConnection(JNIEnv *env) {
+    return AndroidRuntime::registerNativeMethods(env,
+                "android/media/MediaHTTPConnection", gMethods, NELEM(gMethods));
+}
+
diff --git a/media/jni/android_media_MediaHTTPConnection.h b/media/jni/android_media_MediaHTTPConnection.h
new file mode 100644
index 0000000..62ff678
--- /dev/null
+++ b/media/jni/android_media_MediaHTTPConnection.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef _ANDROID_MEDIA_MEDIAHTTPCONNECTION_H_
+#define _ANDROID_MEDIA_MEDIAHTTPCONNECTION_H_
+
+#include "jni.h"
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+struct IMemory;
+struct MemoryDealer;
+
+struct JMediaHTTPConnection : public RefBase {
+    enum {
+        kBufferSize = 32768,
+    };
+
+    JMediaHTTPConnection(JNIEnv *env, jobject thiz);
+
+    sp<IMemory> getIMemory();
+
+    jbyteArray getByteArrayObj();
+
+protected:
+    virtual ~JMediaHTTPConnection();
+
+private:
+    jclass mClass;
+    jweak mObject;
+    jbyteArray mByteArrayObj;
+
+    sp<MemoryDealer> mDealer;
+    sp<IMemory> mMemory;
+
+    DISALLOW_EVIL_CONSTRUCTORS(JMediaHTTPConnection);
+};
+
+}  // namespace android
+
+#endif  // _ANDROID_MEDIA_MEDIAHTTPCONNECTION_H_
diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp
index 6176f0f..4e42ae3 100644
--- a/media/jni/android_media_MediaMetadataRetriever.cpp
+++ b/media/jni/android_media_MediaMetadataRetriever.cpp
@@ -21,7 +21,8 @@
 #include <assert.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
-#include <core/SkBitmap.h>
+#include <SkBitmap.h>
+#include <media/IMediaHTTPService.h>
 #include <media/mediametadataretriever.h>
 #include <private/media/VideoFrame.h>
 
@@ -29,6 +30,7 @@
 #include "JNIHelp.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "android_media_Utils.h"
+#include "android_util_Binder.h"
 
 
 using namespace android;
@@ -80,7 +82,7 @@
 
 static void
 android_media_MediaMetadataRetriever_setDataSourceAndHeaders(
-        JNIEnv *env, jobject thiz, jstring path,
+        JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path,
         jobjectArray keys, jobjectArray values) {
 
     ALOGV("setDataSource");
@@ -122,10 +124,19 @@
             env, keys, values, &headersVector)) {
         return;
     }
+
+    sp<IMediaHTTPService> httpService;
+    if (httpServiceBinderObj != NULL) {
+        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
+        httpService = interface_cast<IMediaHTTPService>(binder);
+    }
+
     process_media_retriever_call(
             env,
             retriever->setDataSource(
-                pathStr.string(), headersVector.size() > 0 ? &headersVector : NULL),
+                httpService,
+                pathStr.string(),
+                headersVector.size() > 0 ? &headersVector : NULL),
 
             "java/lang/RuntimeException",
             "setDataSource failed");
@@ -442,7 +453,7 @@
 static JNINativeMethod nativeMethods[] = {
         {
             "_setDataSource",
-            "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
+            "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
             (void *)android_media_MediaMetadataRetriever_setDataSourceAndHeaders
         },
 
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index 3561b06..3fef446f 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -164,7 +164,7 @@
 }
 
 static void android_media_MediaMuxer_setLocation(
-        JNIEnv *env, jclass clazz, jint nativeObject, jint latitude, jint longitude) {
+        JNIEnv *env, jclass clazz, jlong nativeObject, jint latitude, jint longitude) {
     MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject);
 
     status_t res = muxer->setLocation(latitude, longitude);
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 9d0d5a6..abebd48 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -20,6 +20,7 @@
 #include "utils/Log.h"
 
 #include <media/mediaplayer.h>
+#include <media/IMediaHTTPService.h>
 #include <media/MediaPlayerInterface.h>
 #include <stdio.h>
 #include <assert.h>
@@ -45,6 +46,7 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
+#include "android_util_Binder.h"
 // ----------------------------------------------------------------------------
 
 using namespace android;
@@ -183,7 +185,7 @@
 
 static void
 android_media_MediaPlayer_setDataSourceAndHeaders(
-        JNIEnv *env, jobject thiz, jstring path,
+        JNIEnv *env, jobject thiz, jobject httpServiceBinderObj, jstring path,
         jobjectArray keys, jobjectArray values) {
 
     sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
@@ -214,8 +216,15 @@
         return;
     }
 
+    sp<IMediaHTTPService> httpService;
+    if (httpServiceBinderObj != NULL) {
+        sp<IBinder> binder = ibinderForJavaObject(env, httpServiceBinderObj);
+        httpService = interface_cast<IMediaHTTPService>(binder);
+    }
+
     status_t opStatus =
         mp->setDataSource(
+                httpService,
                 pathStr,
                 headersVector.size() > 0? &headersVector : NULL);
 
@@ -491,6 +500,20 @@
     process_media_player_call( env, thiz, mp->setAudioStreamType((audio_stream_type_t) streamtype) , NULL, NULL );
 }
 
+static jint
+android_media_MediaPlayer_getAudioStreamType(JNIEnv *env, jobject thiz)
+{
+    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+    if (mp == NULL ) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return 0;
+    }
+    audio_stream_type_t streamtype;
+    process_media_player_call( env, thiz, mp->getAudioStreamType(&streamtype), NULL, NULL );
+    ALOGV("getAudioStreamType: %d (streamtype)", streamtype);
+    return (jint) streamtype;
+}
+
 static void
 android_media_MediaPlayer_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
 {
@@ -726,7 +749,8 @@
 }
 
 static jint
-android_media_MediaPlayer_pullBatteryData(JNIEnv *env, jobject thiz, jobject java_reply)
+android_media_MediaPlayer_pullBatteryData(
+        JNIEnv *env, jobject /* thiz */, jobject java_reply)
 {
     sp<IBinder> binder = defaultServiceManager()->getService(String16("media.player"));
     sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
@@ -806,58 +830,13 @@
     ;
 }
 
-static void
-android_media_MediaPlayer_updateProxyConfig(
-        JNIEnv *env, jobject thiz, jobject proxyProps)
-{
-    ALOGV("updateProxyConfig");
-    sp<MediaPlayer> thisplayer = getMediaPlayer(env, thiz);
-    if (thisplayer == NULL) {
-        return;
-    }
-
-    if (proxyProps == NULL) {
-        thisplayer->updateProxyConfig(
-                NULL /* host */, 0 /* port */, NULL /* exclusionList */);
-    } else {
-        jstring hostObj = (jstring)env->CallObjectMethod(
-                proxyProps, fields.proxyConfigGetHost);
-
-        const char *host = env->GetStringUTFChars(hostObj, NULL);
-
-        int port = env->CallIntMethod(proxyProps, fields.proxyConfigGetPort);
-
-        jstring exclusionListObj = (jstring)env->CallObjectMethod(
-                proxyProps, fields.proxyConfigGetExclusionList);
-
-        if (host != NULL && exclusionListObj != NULL) {
-            const char *exclusionList = env->GetStringUTFChars(exclusionListObj, NULL);
-
-            if (exclusionList != NULL) {
-                thisplayer->updateProxyConfig(host, port, exclusionList);
-
-                env->ReleaseStringUTFChars(exclusionListObj, exclusionList);
-                exclusionList = NULL;
-            } else {
-                thisplayer->updateProxyConfig(host, port, "");
-            }
-        } else if (host != NULL) {
-            thisplayer->updateProxyConfig(host, port, "");
-        }
-
-        if (host != NULL) {
-            env->ReleaseStringUTFChars(hostObj, host);
-            host = NULL;
-        }
-    }
-}
-
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
     {
-        "_setDataSource",
-        "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V",
+        "nativeSetDataSource",
+        "(Landroid/os/IBinder;Ljava/lang/String;[Ljava/lang/String;"
+        "[Ljava/lang/String;)V",
         (void *)android_media_MediaPlayer_setDataSourceAndHeaders
     },
 
@@ -876,10 +855,11 @@
     {"getDuration",         "()I",                              (void *)android_media_MediaPlayer_getDuration},
     {"_release",            "()V",                              (void *)android_media_MediaPlayer_release},
     {"_reset",              "()V",                              (void *)android_media_MediaPlayer_reset},
-    {"setAudioStreamType",  "(I)V",                             (void *)android_media_MediaPlayer_setAudioStreamType},
+    {"_setAudioStreamType", "(I)V",                             (void *)android_media_MediaPlayer_setAudioStreamType},
+    {"_getAudioStreamType", "()I",                              (void *)android_media_MediaPlayer_getAudioStreamType},
     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer_setLooping},
     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer_isLooping},
-    {"setVolume",           "(FF)V",                            (void *)android_media_MediaPlayer_setVolume},
+    {"_setVolume",          "(FF)V",                            (void *)android_media_MediaPlayer_setVolume},
     {"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},
@@ -888,12 +868,11 @@
     {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
     {"getAudioSessionId",   "()I",                              (void *)android_media_MediaPlayer_get_audio_session_id},
     {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer_set_audio_session_id},
-    {"setAuxEffectSendLevel", "(F)V",                           (void *)android_media_MediaPlayer_setAuxEffectSendLevel},
+    {"_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},
     {"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},
 };
 
 static const char* const kClassPathName = "android/media/MediaPlayer";
@@ -911,6 +890,7 @@
 extern int register_android_media_MediaCodec(JNIEnv *env);
 extern int register_android_media_MediaExtractor(JNIEnv *env);
 extern int register_android_media_MediaCodecList(JNIEnv *env);
+extern int register_android_media_MediaHTTPConnection(JNIEnv *env);
 extern int register_android_media_MediaMetadataRetriever(JNIEnv *env);
 extern int register_android_media_MediaMuxer(JNIEnv *env);
 extern int register_android_media_MediaRecorder(JNIEnv *env);
@@ -922,7 +902,7 @@
 extern int register_android_mtp_MtpDevice(JNIEnv *env);
 extern int register_android_mtp_MtpServer(JNIEnv *env);
 
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
+jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
 {
     JNIEnv* env = NULL;
     jint result = -1;
@@ -1018,6 +998,11 @@
         goto bail;
     }
 
+    if (register_android_media_MediaHTTPConnection(env) < 0) {
+        ALOGE("ERROR: MediaHTTPConnection native registration failed");
+        goto bail;
+    }
+
     /* success -- return valid version number */
     result = JNI_VERSION_1_4;
 
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 0cfd2ff..fd69cad 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -344,6 +344,26 @@
     return (jint) result;
 }
 
+static jobject
+android_media_MediaRecorder_getSurface(JNIEnv *env, jobject thiz)
+{
+    ALOGV("getSurface");
+    sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+
+    sp<IGraphicBufferProducer> bufferProducer = mr->querySurfaceMediaSourceFromMediaServer();
+    if (bufferProducer == NULL) {
+        jniThrowException(
+                env,
+                "java/lang/IllegalStateException",
+                "failed to get surface");
+        return NULL;
+    }
+
+    // Wrap the IGBP in a Java-language Surface.
+    return android_view_Surface_createFromIGraphicBufferProducer(env,
+            bufferProducer);
+}
+
 static void
 android_media_MediaRecorder_start(JNIEnv *env, jobject thiz)
 {
@@ -470,6 +490,7 @@
     {"setMaxDuration",       "(I)V",                            (void *)android_media_MediaRecorder_setMaxDuration},
     {"setMaxFileSize",       "(J)V",                            (void *)android_media_MediaRecorder_setMaxFileSize},
     {"_prepare",             "()V",                             (void *)android_media_MediaRecorder_prepare},
+    {"getSurface",           "()Landroid/view/Surface;",        (void *)android_media_MediaRecorder_getSurface},
     {"getMaxAmplitude",      "()I",                             (void *)android_media_MediaRecorder_native_getMaxAmplitude},
     {"start",                "()V",                             (void *)android_media_MediaRecorder_start},
     {"stop",                 "()V",                             (void *)android_media_MediaRecorder_stop},
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 6b0bd0d..82c6a80 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -68,6 +68,8 @@
 static jmethodID method_sessionEnded;
 
 static jfieldID field_context;
+static jfieldID field_batteryLevel;
+static jfieldID field_batteryScale;
 
 // MtpPropertyList fields
 static jfieldID field_mCount;
@@ -527,68 +529,75 @@
 
 MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
                                             MtpDataPacket& packet) {
-    int         type;
-
-    if (!getDevicePropertyInfo(property, type))
-        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
-
     JNIEnv* env = AndroidRuntime::getJNIEnv();
-    jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
-                (jint)property, mLongBuffer, mStringBuffer);
-    if (result != MTP_RESPONSE_OK) {
+
+    if (property == MTP_DEVICE_PROPERTY_BATTERY_LEVEL) {
+        // special case - implemented here instead of Java
+        packet.putUInt8((uint8_t)env->GetIntField(mDatabase, field_batteryLevel));
+        return MTP_RESPONSE_OK;
+    } else {
+        int type;
+
+        if (!getDevicePropertyInfo(property, type))
+            return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
+
+        jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
+                    (jint)property, mLongBuffer, mStringBuffer);
+        if (result != MTP_RESPONSE_OK) {
+            checkAndClearExceptionFromCallback(env, __FUNCTION__);
+            return result;
+        }
+
+        jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
+        jlong longValue = longValues[0];
+        env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
+
+        switch (type) {
+            case MTP_TYPE_INT8:
+                packet.putInt8(longValue);
+                break;
+            case MTP_TYPE_UINT8:
+                packet.putUInt8(longValue);
+                break;
+            case MTP_TYPE_INT16:
+                packet.putInt16(longValue);
+                break;
+            case MTP_TYPE_UINT16:
+                packet.putUInt16(longValue);
+                break;
+            case MTP_TYPE_INT32:
+                packet.putInt32(longValue);
+                break;
+            case MTP_TYPE_UINT32:
+                packet.putUInt32(longValue);
+                break;
+            case MTP_TYPE_INT64:
+                packet.putInt64(longValue);
+                break;
+            case MTP_TYPE_UINT64:
+                packet.putUInt64(longValue);
+                break;
+            case MTP_TYPE_INT128:
+                packet.putInt128(longValue);
+                break;
+            case MTP_TYPE_UINT128:
+                packet.putInt128(longValue);
+                break;
+            case MTP_TYPE_STR:
+            {
+                jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
+                packet.putString(str);
+                env->ReleaseCharArrayElements(mStringBuffer, str, 0);
+                break;
+             }
+            default:
+                ALOGE("unsupported type in getDevicePropertyValue\n");
+                return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
+        }
+
         checkAndClearExceptionFromCallback(env, __FUNCTION__);
-        return result;
+        return MTP_RESPONSE_OK;
     }
-
-    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
-    jlong longValue = longValues[0];
-    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
-
-    switch (type) {
-        case MTP_TYPE_INT8:
-            packet.putInt8(longValue);
-            break;
-        case MTP_TYPE_UINT8:
-            packet.putUInt8(longValue);
-            break;
-        case MTP_TYPE_INT16:
-            packet.putInt16(longValue);
-            break;
-        case MTP_TYPE_UINT16:
-            packet.putUInt16(longValue);
-            break;
-        case MTP_TYPE_INT32:
-            packet.putInt32(longValue);
-            break;
-        case MTP_TYPE_UINT32:
-            packet.putUInt32(longValue);
-            break;
-        case MTP_TYPE_INT64:
-            packet.putInt64(longValue);
-            break;
-        case MTP_TYPE_UINT64:
-            packet.putUInt64(longValue);
-            break;
-        case MTP_TYPE_INT128:
-            packet.putInt128(longValue);
-            break;
-        case MTP_TYPE_UINT128:
-            packet.putInt128(longValue);
-            break;
-        case MTP_TYPE_STR:
-        {
-            jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
-            packet.putString(str);
-            env->ReleaseCharArrayElements(mStringBuffer, str, 0);
-            break;
-         }
-        default:
-            ALOGE("unsupported type in getDevicePropertyValue\n");
-            return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
-    }
-
-    checkAndClearExceptionFromCallback(env, __FUNCTION__);
-    return MTP_RESPONSE_OK;
 }
 
 MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
@@ -923,6 +932,7 @@
     {   MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER,    MTP_TYPE_STR },
     {   MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,       MTP_TYPE_STR },
     {   MTP_DEVICE_PROPERTY_IMAGE_SIZE,                 MTP_TYPE_STR },
+    {   MTP_DEVICE_PROPERTY_BATTERY_LEVEL,              MTP_TYPE_UINT8 },
 };
 
 bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
@@ -990,6 +1000,22 @@
 
 MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
                                             MtpObjectFormat format) {
+    static const int channelEnum[] = {
+                                        1,  // mono
+                                        2,  // stereo
+                                        3,  // 2.1
+                                        4,  // 3
+                                        5,  // 3.1
+                                        6,  // 4
+                                        7,  // 4.1
+                                        8,  // 5
+                                        9,  // 5.1
+                                    };
+    static const int bitrateEnum[] = {
+                                        1,  // fixed rate
+                                        2,  // variable rate
+                                     };
+
     MtpProperty* result = NULL;
     switch (property) {
         case MTP_PROPERTY_OBJECT_FORMAT:
@@ -1003,6 +1029,7 @@
         case MTP_PROPERTY_STORAGE_ID:
         case MTP_PROPERTY_PARENT_OBJECT:
         case MTP_PROPERTY_DURATION:
+        case MTP_PROPERTY_AUDIO_WAVE_CODEC:
             result = new MtpProperty(property, MTP_TYPE_UINT32);
             break;
         case MTP_PROPERTY_OBJECT_SIZE:
@@ -1031,6 +1058,22 @@
             // We allow renaming files and folders
             result = new MtpProperty(property, MTP_TYPE_STR, true);
             break;
+        case MTP_PROPERTY_BITRATE_TYPE:
+             result = new MtpProperty(property, MTP_TYPE_UINT16);
+            result->setFormEnum(bitrateEnum, sizeof(bitrateEnum)/sizeof(bitrateEnum[0]));
+            break;
+        case MTP_PROPERTY_AUDIO_BITRATE:
+            result = new MtpProperty(property, MTP_TYPE_UINT32);
+            result->setFormRange(1, 1536000, 1);
+            break;
+        case MTP_PROPERTY_NUMBER_OF_CHANNELS:
+            result = new MtpProperty(property, MTP_TYPE_UINT16);
+            result->setFormEnum(channelEnum, sizeof(channelEnum)/sizeof(channelEnum[0]));
+            break;
+        case MTP_PROPERTY_SAMPLE_RATE:
+            result = new MtpProperty(property, MTP_TYPE_UINT32);
+            result->setFormRange(8000, 48000, 1);
+            break;
     }
 
     return result;
@@ -1046,7 +1089,7 @@
         case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
             writable = true;
             // fall through
-        case MTP_DEVICE_PROPERTY_IMAGE_SIZE:
+        case MTP_DEVICE_PROPERTY_IMAGE_SIZE: {
             result = new MtpProperty(property, MTP_TYPE_STR, writable);
 
             // get current value
@@ -1063,6 +1106,12 @@
                 ALOGE("unable to read device property, response: %04X", ret);
             }
             break;
+        }
+        case MTP_DEVICE_PROPERTY_BATTERY_LEVEL:
+            result = new MtpProperty(property, MTP_TYPE_UINT8);
+            result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1);
+            result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel);
+            break;
     }
 
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
@@ -1234,6 +1283,16 @@
         ALOGE("Can't find MtpDatabase.mNativeContext");
         return -1;
     }
+    field_batteryLevel = env->GetFieldID(clazz, "mBatteryLevel", "I");
+    if (field_batteryLevel == NULL) {
+        ALOGE("Can't find MtpDatabase.mBatteryLevel");
+        return -1;
+    }
+    field_batteryScale = env->GetFieldID(clazz, "mBatteryScale", "I");
+    if (field_batteryScale == NULL) {
+        ALOGE("Can't find MtpDatabase.mBatteryScale");
+        return -1;
+    }
 
     // now set up fields for MtpPropertyList class
     clazz = env->FindClass("android/mtp/MtpPropertyList");
diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp
index 9d7f1c2..2f90dfe 100644
--- a/media/jni/android_mtp_MtpServer.cpp
+++ b/media/jni/android_mtp_MtpServer.cpp
@@ -118,6 +118,18 @@
 }
 
 static void
+android_mtp_MtpServer_send_device_property_changed(JNIEnv *env, jobject thiz, jint property)
+{
+    Mutex::Autolock autoLock(sMutex);
+
+    MtpServer* server = getMtpServer(env, thiz);
+    if (server)
+        server->sendDevicePropertyChanged(property);
+    else
+        ALOGE("server is null in send_object_removed");
+}
+
+static void
 android_mtp_MtpServer_add_storage(JNIEnv *env, jobject thiz, jobject jstorage)
 {
     Mutex::Autolock autoLock(sMutex);
@@ -174,6 +186,8 @@
     {"native_cleanup",              "()V",  (void *)android_mtp_MtpServer_cleanup},
     {"native_send_object_added",    "(I)V", (void *)android_mtp_MtpServer_send_object_added},
     {"native_send_object_removed",  "(I)V", (void *)android_mtp_MtpServer_send_object_removed},
+    {"native_send_device_property_changed",  "(I)V",
+                                    (void *)android_mtp_MtpServer_send_device_property_changed},
     {"native_add_storage",          "(Landroid/mtp/MtpStorage;)V",
                                             (void *)android_mtp_MtpServer_add_storage},
     {"native_remove_storage",       "(I)V", (void *)android_mtp_MtpServer_remove_storage},
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 5d2378d..312c366 100644
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -35,7 +35,6 @@
     $(TOP)/frameworks/base/media/libstagefright/include \
     $(TOP)/frameworks/base/media/libstagefright/rtsp \
     $(JNI_H_INCLUDE) \
-    $(call include-path-for, corecg graphics) \
     $(TOP)/frameworks/native/include/media/editor \
     $(TOP)/frameworks/base/core/jni/mediaeditor \
     $(TOP)/frameworks/av/libvideoeditor/vss/inc \
diff --git a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
index 9cc55ab..bda3b6b 100644
--- a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
+++ b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp
@@ -229,7 +229,7 @@
         "(I)Z",
         (void *)android_media_SoundPool_SoundPoolImpl_unload
     },
-    {   "play",
+    {   "_play",
         "(IFFIIF)I",
         (void *)android_media_SoundPool_SoundPoolImpl_play
     },
@@ -253,7 +253,7 @@
         "(I)V",
         (void *)android_media_SoundPool_SoundPoolImpl_stop
     },
-    {   "setVolume",
+    {   "_setVolume",
         "(IFF)V",
         (void *)android_media_SoundPool_SoundPoolImpl_setVolume
     },
diff --git a/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java b/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java
index 6cfc0e8..dc9dd79 100644
--- a/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java
+++ b/media/lib/java/com/android/media/remotedisplay/RemoteDisplay.java
@@ -16,7 +16,6 @@
 
 package com.android.media.remotedisplay;
 
-import android.media.MediaRouter;
 import android.media.RemoteDisplayState.RemoteDisplayInfo;
 import android.text.TextUtils;
 
diff --git a/media/mca/effect/java/android/media/effect/EffectContext.java b/media/mca/effect/java/android/media/effect/EffectContext.java
index ef03229..a11b9c4 100644
--- a/media/mca/effect/java/android/media/effect/EffectContext.java
+++ b/media/mca/effect/java/android/media/effect/EffectContext.java
@@ -19,10 +19,7 @@
 
 import android.filterfw.core.CachedFrameManager;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.FilterFactory;
 import android.filterfw.core.GLEnvironment;
-import android.filterfw.core.GLFrame;
-import android.filterfw.core.FrameManager;
 import android.opengl.GLES20;
 
 /**
diff --git a/media/mca/effect/java/android/media/effect/EffectFactory.java b/media/mca/effect/java/android/media/effect/EffectFactory.java
index 4330279..f6fcba7 100644
--- a/media/mca/effect/java/android/media/effect/EffectFactory.java
+++ b/media/mca/effect/java/android/media/effect/EffectFactory.java
@@ -18,7 +18,6 @@
 package android.media.effect;
 
 import java.lang.reflect.Constructor;
-import java.util.HashMap;
 
 /**
  * <p>The EffectFactory class defines the list of available Effects, and provides functionality to
diff --git a/media/mca/effect/java/android/media/effect/FilterEffect.java b/media/mca/effect/java/android/media/effect/FilterEffect.java
index d7c319e..34b3549 100644
--- a/media/mca/effect/java/android/media/effect/FilterEffect.java
+++ b/media/mca/effect/java/android/media/effect/FilterEffect.java
@@ -17,10 +17,7 @@
 
 package android.media.effect;
 
-import android.filterfw.core.CachedFrameManager;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.FilterFactory;
-import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
diff --git a/media/mca/effect/java/android/media/effect/FilterGraphEffect.java b/media/mca/effect/java/android/media/effect/FilterGraphEffect.java
index b18bea8..80c695b 100644
--- a/media/mca/effect/java/android/media/effect/FilterGraphEffect.java
+++ b/media/mca/effect/java/android/media/effect/FilterGraphEffect.java
@@ -19,17 +19,13 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterGraph;
 import android.filterfw.core.GraphRunner;
-import android.filterfw.core.SimpleScheduler;
 import android.filterfw.core.SyncRunner;
-import android.media.effect.Effect;
 import android.media.effect.FilterEffect;
 import android.media.effect.EffectContext;
 import android.filterfw.io.GraphIOException;
 import android.filterfw.io.GraphReader;
 import android.filterfw.io.TextGraphReader;
 
-import android.util.Log;
-
 /**
  * Effect subclass for effects based on a single Filter. Subclasses need only invoke the
  * constructor with the correct arguments to obtain an Effect implementation.
diff --git a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java
index 6f85861..47900df 100644
--- a/media/mca/effect/java/android/media/effect/SingleFilterEffect.java
+++ b/media/mca/effect/java/android/media/effect/SingleFilterEffect.java
@@ -21,11 +21,8 @@
 import android.filterfw.core.FilterFactory;
 import android.filterfw.core.FilterFunction;
 import android.filterfw.core.Frame;
-import android.media.effect.Effect;
 import android.media.effect.EffectContext;
 
-import android.util.Log;
-
 /**
  * Effect subclass for effects based on a single Filter. Subclasses need only invoke the
  * constructor with the correct arguments to obtain an Effect implementation.
diff --git a/media/mca/effect/java/android/media/effect/SizeChangeEffect.java b/media/mca/effect/java/android/media/effect/SizeChangeEffect.java
index 4d27bae..1bf7d40 100644
--- a/media/mca/effect/java/android/media/effect/SizeChangeEffect.java
+++ b/media/mca/effect/java/android/media/effect/SizeChangeEffect.java
@@ -16,15 +16,9 @@
 
 package android.media.effect;
 
-import android.filterfw.core.Filter;
-import android.filterfw.core.FilterFactory;
-import android.filterfw.core.FilterFunction;
 import android.filterfw.core.Frame;
-import android.media.effect.Effect;
 import android.media.effect.EffectContext;
 
-import android.util.Log;
-
 /**
  * Effect subclass for effects based on a single Filter with output size differnet
  * from input.  Subclasses need only invoke the constructor with the correct arguments
diff --git a/media/mca/effect/java/android/media/effect/effects/CropEffect.java b/media/mca/effect/java/android/media/effect/effects/CropEffect.java
index 3e8d78a..7e1c495 100644
--- a/media/mca/effect/java/android/media/effect/effects/CropEffect.java
+++ b/media/mca/effect/java/android/media/effect/effects/CropEffect.java
@@ -19,7 +19,6 @@
 
 import android.media.effect.EffectContext;
 import android.media.effect.SizeChangeEffect;
-import android.media.effect.SingleFilterEffect;
 import android.filterpacks.imageproc.CropRectFilter;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java b/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java
index 3f36d98..feaf6e8 100644
--- a/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java
+++ b/media/mca/filterfw/java/android/filterfw/FilterFunctionEnvironment.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterFactory;
 import android.filterfw.core.FilterFunction;
-import android.filterfw.core.Frame;
 import android.filterfw.core.FrameManager;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java b/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java
index 70cbad4..819774a 100644
--- a/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java
+++ b/media/mca/filterfw/java/android/filterfw/core/AsyncRunner.java
@@ -18,17 +18,9 @@
 package android.filterfw.core;
 
 import android.os.AsyncTask;
-import android.os.Handler;
 
 import android.util.Log;
 
-import java.lang.InterruptedException;
-import java.lang.Runnable;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.TimeUnit;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterfw/java/android/filterfw/core/Filter.java b/media/mca/filterfw/java/android/filterfw/core/Filter.java
index 73b009d..062b6ba 100644
--- a/media/mca/filterfw/java/android/filterfw/core/Filter.java
+++ b/media/mca/filterfw/java/android/filterfw/core/Filter.java
@@ -33,7 +33,6 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map.Entry;
-import java.util.LinkedList;
 import java.util.Set;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/Frame.java b/media/mca/filterfw/java/android/filterfw/core/Frame.java
index ef8c542..7dd0783 100644
--- a/media/mca/filterfw/java/android/filterfw/core/Frame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/Frame.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.FrameManager;
 import android.graphics.Bitmap;
-import android.util.Log;
 
 import java.nio.ByteBuffer;
 
diff --git a/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java b/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java
index bfd09ba..7d1553f 100644
--- a/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/NativeFrame.java
@@ -24,8 +24,6 @@
 import android.filterfw.core.NativeBuffer;
 import android.graphics.Bitmap;
 
-import android.util.Log;
-
 import java.nio.ByteBuffer;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java b/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java
index dbc8d16..83c475f 100644
--- a/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java
+++ b/media/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java
@@ -18,7 +18,6 @@
 package android.filterfw.core;
 
 import android.filterfw.core.Filter;
-import android.filterfw.core.Scheduler;
 import android.filterfw.core.RoundRobinScheduler;
 import android.util.Log;
 
diff --git a/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java b/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java
index f493fd2..35ba04f 100644
--- a/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/SerializedFrame.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.FrameManager;
-import android.filterfw.core.NativeBuffer;
 import android.filterfw.format.ObjectFormat;
 import android.graphics.Bitmap;
 
@@ -28,10 +27,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.io.OptionalDataException;
 import java.io.OutputStream;
-import java.io.StreamCorruptedException;
-import java.lang.reflect.Constructor;
 import java.nio.ByteBuffer;
 
 /**
diff --git a/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java b/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java
index 534a30d..7ddd1d4 100644
--- a/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java
+++ b/media/mca/filterfw/java/android/filterfw/core/SimpleFrame.java
@@ -20,11 +20,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.FrameManager;
-import android.filterfw.core.NativeBuffer;
 import android.filterfw.format.ObjectFormat;
 import android.graphics.Bitmap;
 
-import java.lang.reflect.Constructor;
 import java.nio.ByteBuffer;
 
 /**
diff --git a/media/mca/filterfw/native/core/gl_env.cpp b/media/mca/filterfw/native/core/gl_env.cpp
index 84dad8c..f092af8 100644
--- a/media/mca/filterfw/native/core/gl_env.cpp
+++ b/media/mca/filterfw/native/core/gl_env.cpp
@@ -162,9 +162,11 @@
   }
 
   // Create dummy surface using a GLConsumer
-  sp<BufferQueue> bq = new BufferQueue();
-  surfaceTexture_ = new GLConsumer(bq, 0);
-  window_ = new Surface(static_cast<sp<IGraphicBufferProducer> >(bq));
+  sp<IGraphicBufferProducer> producer;
+  sp<IGraphicBufferConsumer> consumer;
+  BufferQueue::createBufferQueue(&producer, &consumer);
+  surfaceTexture_ = new GLConsumer(consumer, 0);
+  window_ = new Surface(producer);
 
   surfaces_[0] = SurfaceWindowPair(eglCreateWindowSurface(display(), config, window_.get(), NULL), NULL);
   if (CheckEGLError("eglCreateWindowSurface")) return false;
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java b/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java
index 4185343..4a47fa4 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/CallbackFilter.java
@@ -20,13 +20,8 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.os.Handler;
 import android.os.Looper;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java b/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java
index 6b8cbc7..f909c3f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/FrameBranch.java
@@ -22,7 +22,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java b/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java
index 518b837..87d8f0b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/FrameFetch.java
@@ -24,8 +24,6 @@
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java b/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java
index 3aadaac..05ac50d 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/FrameStore.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java
index 1776820..af61d9a 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureSource.java
@@ -23,11 +23,8 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ImageFormat;
 
-import java.util.Set;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java
index b2285cd..91bb417 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/GLTextureTarget.java
@@ -23,11 +23,8 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ImageFormat;
 
-import java.util.Set;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java b/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java
index 6c22ee7..0ef9055 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/InputStreamSource.java
@@ -23,7 +23,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.PrimitiveFormat;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java b/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java
index f3e08e4..73434d4 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/NullFilter.java
@@ -19,8 +19,6 @@
 
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java b/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java
index d511e44..78e2b50 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/ObjectSource.java
@@ -17,15 +17,12 @@
 
 package android.filterpacks.base;
 
-import java.util.Set;
-
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ObjectFormat;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java b/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java
index 3d3d0f1..fd65a9d 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/OutputStreamTarget.java
@@ -20,7 +20,6 @@
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 
 import java.io.OutputStream;
diff --git a/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java b/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java
index 254167a..0e988820 100644
--- a/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/base/RetargetFilter.java
@@ -21,9 +21,7 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java
index 473369c..c3cc282 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/AlphaBlendFilter.java
@@ -17,18 +17,9 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
-import android.filterfw.format.ImageFormat;
-
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java
index c71c1c94..ac83db2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/AutoFixFilter.java
@@ -21,13 +21,10 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.NativeProgram;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 public class AutoFixFilter extends Filter {
 
     @GenerateFieldPort(name = "tile_size", hasDefault = true)
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
index e4bb6cf..92b177c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapOverlayFilter.java
@@ -21,17 +21,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.filterpacks.imageproc.ImageCombineFilter;
 import android.graphics.Bitmap;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java
index 978fc94..89e8723 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BitmapSource.java
@@ -17,17 +17,11 @@
 
 package android.filterpacks.imageproc;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
-import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.format.ImageFormat;
 import android.graphics.Bitmap;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
index 20b02d2..38221b4 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlackWhiteFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java
index 29bc8a3..aff5e9e 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BlendFilter.java
@@ -16,18 +16,9 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
-import android.filterfw.format.ImageFormat;
-
-import java.util.Set;
 
 /**
  * The filter linearly blends "left" and "right" frames. The blending weight is
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java
index 046e69d..bc62e19 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/BrightnessFilter.java
@@ -17,13 +17,8 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java
index 7488980..1d408be 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ColorTemperatureFilter.java
@@ -21,13 +21,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.util.Log;
 
 public class ColorTemperatureFilter extends Filter {
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java
index 70e987f..7043c72 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ContrastFilter.java
@@ -17,18 +17,11 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 
-import java.util.Set;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java
index 5222d9c..0ef323c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropFilter.java
@@ -22,19 +22,13 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
-import android.filterfw.geometry.Point;
 import android.filterfw.geometry.Quad;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.format.ObjectFormat;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java
index d423d06..010ee21 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/CropRectFilter.java
@@ -21,14 +21,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java
index e0514f8..d565e65 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/CrossProcessFilter.java
@@ -21,15 +21,10 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 public class CrossProcessFilter extends Filter {
 
     @GenerateFieldPort(name = "tile_size", hasDefault = true)
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
index f93a82c..72745c0 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DocumentaryFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java
index 3f1711e..d10a6ef 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawOverlayFilter.java
@@ -21,17 +21,11 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.GLFrame;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.geometry.Quad;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.format.ObjectFormat;
 
-import android.opengl.GLES20;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java
index 83c9348..b288e6e 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DrawRectFilter.java
@@ -23,9 +23,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.geometry.Quad;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java
index d8c88ee..ef82ee9 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/DuotoneFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java
index fc917a1..c7fb55d 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FillLightFilter.java
@@ -21,10 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.GenerateFinalPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java
index 5d7929f..2ff6588 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FisheyeFilter.java
@@ -22,17 +22,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 import java.lang.Math;
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java
index 3d319ea..340f308 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FixedRotationFilter.java
@@ -22,7 +22,6 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Point;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java
index f8b857b..68c760f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/FlipFilter.java
@@ -21,10 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
index 577243a..528eaa2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/GrainFilter.java
@@ -21,14 +21,9 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
-import android.filterfw.geometry.Quad;
-import android.filterfw.geometry.Point;
 
 import java.util.Date;
 import java.util.Random;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java
index 858489b..c9a6956 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageCombineFilter.java
@@ -21,16 +21,10 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import java.lang.reflect.Field;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java
index a5405cb..e8bf482 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageEncoder.java
@@ -17,21 +17,16 @@
 
 package android.filterpacks.imageproc;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.format.ImageFormat;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.CompressFormat;
 
-import android.util.Log;
-
 import java.io.OutputStream;
-import java.io.IOException;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java
index b996eb8..8bf80b2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageSlicer.java
@@ -20,9 +20,7 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java
index 20aba91..5e3d15b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ImageStitcher.java
@@ -20,16 +20,12 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 public class ImageStitcher extends Filter {
 
     @GenerateFieldPort(name = "xSlices")
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java
index 400fd5d..881e30f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/Invert.java
@@ -17,12 +17,8 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
-import android.filterfw.core.FrameFormat;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
index 726ffff..4e53f92 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/LomoishFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java
index 440d6a6..f66fc23 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/NegativeFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java
index bc2e553..864d7e2 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/PosterizeFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
index 8618804..48b2fdf 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/RedEyeFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
@@ -31,8 +28,6 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.PointF;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java
index 411e061..c79c11b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ResizeFilter.java
@@ -23,10 +23,7 @@
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java
index 3da7939..43d8d6c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/RotateFilter.java
@@ -22,16 +22,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Quad;
 import android.filterfw.geometry.Point;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java
index b83af39..757fac1 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SaturateFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java
index 7a83fdf..a9f4e2c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SepiaFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java
index 256b769..a290996 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SharpenFilter.java
@@ -21,15 +21,10 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import java.util.Set;
-
 public class SharpenFilter extends Filter {
 
     @GenerateFieldPort(name = "scale", hasDefault = true)
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java
index f4fc271e..afe92de 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/SimpleImageFilter.java
@@ -21,16 +21,10 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import java.lang.reflect.Field;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java
index c9f097d..9db296b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/StraightenFilter.java
@@ -22,16 +22,11 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Quad;
 import android.filterfw.geometry.Point;
-import android.util.Log;
 
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java
index 0da54a5..2b140ba 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/TintFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java
index 00e7bf4..760ce3a 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToGrayFilter.java
@@ -17,23 +17,14 @@
 
 package android.filterpacks.imageproc;
 
-import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
-import java.lang.reflect.Field;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java
index bc4a65e..3c121d0 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToPackedGrayFilter.java
@@ -27,8 +27,6 @@
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 import java.lang.Math;
 /**
  * @hide
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java
index ab4814f..f0084fa 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBAFilter.java
@@ -21,16 +21,11 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java
index 9258502..bbb0fc3 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/ToRGBFilter.java
@@ -21,16 +21,11 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
-import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.util.Log;
-
 /**
  * @hide
  */
diff --git a/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java b/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java
index 715fec6..249cc6f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/imageproc/VignetteFilter.java
@@ -21,9 +21,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
 import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
diff --git a/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java b/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java
index cc33b89..2fe519f 100644
--- a/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/text/StringSource.java
@@ -22,8 +22,6 @@
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.KeyValueMap;
-import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.format.ObjectFormat;
 
 /**
diff --git a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java
index a5c1ccb..ba88736 100644
--- a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceRenderFilter.java
@@ -26,19 +26,11 @@
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
-import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import android.graphics.Rect;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java
index 308d168..05cb81b 100644
--- a/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/ui/SurfaceTargetFilter.java
@@ -25,19 +25,11 @@
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import android.graphics.Rect;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java b/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
index 78f7f3e..a31ac2c 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videoproc/BackDropperFilter.java
@@ -24,7 +24,6 @@
 import android.filterfw.core.GLFrame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.opengl.GLES20;
@@ -32,7 +31,6 @@
 import android.os.SystemProperties;
 import android.util.Log;
 
-import java.lang.ArrayIndexOutOfBoundsException;
 import java.lang.Math;
 import java.util.Arrays;
 import java.nio.ByteBuffer;
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
index 8bb653b..d034051 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaEncoderFilter.java
@@ -17,32 +17,23 @@
 
 package android.filterpacks.videosink;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
-import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.filterfw.geometry.Point;
 import android.filterfw.geometry.Quad;
-import android.os.ConditionVariable;
 import android.media.MediaRecorder;
 import android.media.CamcorderProfile;
 import android.filterfw.core.GLEnvironment;
 
 import java.io.IOException;
 import java.io.FileDescriptor;
-import java.util.List;
-import java.util.Set;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java
index dbf9768..ce7a8c1 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosink/MediaRecorderStopException.java
@@ -18,7 +18,6 @@
 package android.filterpacks.videosink;
 
 import java.lang.RuntimeException;
-import android.util.Log;
 
 /** @hide **/
 public class MediaRecorderStopException extends RuntimeException {
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java
index 2c474ab..d260684 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/CameraSource.java
@@ -17,29 +17,22 @@
 
 package android.filterpacks.videosrc;
 
-import android.content.Context;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.hardware.Camera;
-import android.os.ConditionVariable;
 import android.opengl.Matrix;
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Set;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java
index 0be6c62..53a39a7 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/MediaSource.java
@@ -23,28 +23,20 @@
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.graphics.SurfaceTexture;
 import android.media.MediaPlayer;
 import android.net.Uri;
-import android.os.ConditionVariable;
 import android.opengl.Matrix;
 import android.view.Surface;
 
 import java.io.IOException;
-import java.io.FileDescriptor;
 import java.lang.IllegalArgumentException;
-import java.util.List;
-import java.util.Set;
 
 import android.util.Log;
 
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
index 37fa242..6595baa 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
@@ -16,31 +16,20 @@
 
 package android.filterpacks.videosrc;
 
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
-import android.filterfw.core.FrameManager;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 import android.graphics.SurfaceTexture;
-import android.media.MediaPlayer;
 import android.os.ConditionVariable;
 import android.opengl.Matrix;
 
-import java.io.IOException;
-import java.io.FileDescriptor;
-import java.lang.IllegalArgumentException;
-import java.util.List;
-import java.util.Set;
-
 import android.util.Log;
 
 /** <p>A filter that converts textures from a SurfaceTexture object into frames for
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
index b6d9f94..5d03627 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureTarget.java
@@ -19,29 +19,19 @@
 
 import android.filterfw.core.Filter;
 import android.filterfw.core.FilterContext;
-import android.filterfw.core.FilterSurfaceView;
 import android.filterfw.core.Frame;
 import android.filterfw.core.FrameFormat;
 import android.filterfw.core.GenerateFieldPort;
 import android.filterfw.core.GenerateFinalPort;
 import android.filterfw.core.GLEnvironment;
 import android.filterfw.core.GLFrame;
-import android.filterfw.core.KeyValueMap;
 import android.filterfw.core.MutableFrameFormat;
-import android.filterfw.core.NativeProgram;
-import android.filterfw.core.NativeFrame;
-import android.filterfw.core.Program;
 import android.filterfw.core.ShaderProgram;
 import android.filterfw.format.ImageFormat;
 
 import android.filterfw.geometry.Quad;
 import android.filterfw.geometry.Point;
 
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 
 import android.util.Log;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index ee867ff..d01f4ec 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -137,6 +137,8 @@
     public static final String INVALD_VIDEO_PATH =
             "/sdcard/media_api/filepathdoesnotexist" + "/filepathdoesnotexist/temp.3gp";
 
+    public static final String RECORDED_SURFACE_3GP = "/sdcard/surface.3gp";
+
     public static final long RECORDED_TIME = 5000;
     public static final long VALID_VIDEO_DURATION = 2000;
 
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
index abe8b8c..54c8add 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaProfileReader.java
@@ -88,7 +88,8 @@
         if (audioEncoder != MediaRecorder.AudioEncoder.AMR_NB &&
             audioEncoder != MediaRecorder.AudioEncoder.AMR_WB &&
             audioEncoder != MediaRecorder.AudioEncoder.AAC &&
-            audioEncoder != MediaRecorder.AudioEncoder.HE_AAC) {
+            audioEncoder != MediaRecorder.AudioEncoder.HE_AAC &&
+            audioEncoder != MediaRecorder.AudioEncoder.AAC_ELD) {
             throw new IllegalArgumentException("Unsupported audio encodeer " + audioEncoder);
         }
         return audioEncoderMap.get(audioEncoder);
@@ -128,5 +129,6 @@
         audioEncoderMap.put(MediaRecorder.AudioEncoder.AMR_WB, "amrwb");
         audioEncoderMap.put(MediaRecorder.AudioEncoder.AAC, "aac");
         audioEncoderMap.put(MediaRecorder.AudioEncoder.HE_AAC, "heaac");
+        audioEncoderMap.put(MediaRecorder.AudioEncoder.AAC_ELD, "aaceld");
     }
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
index 8e6d5cb..d7069cac 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/mediarecorder/MediaRecorderTest.java
@@ -22,6 +22,10 @@
 import java.io.*;
 
 import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Typeface;
 import android.hardware.Camera;
 import android.media.MediaPlayer;
 import android.media.MediaRecorder;
@@ -30,6 +34,7 @@
 import android.media.EncoderCapabilities.AudioEncoderCap;
 import android.test.ActivityInstrumentationTestCase2;
 import android.util.Log;
+import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import com.android.mediaframeworktest.MediaProfileReader;
@@ -41,27 +46,28 @@
 
 
 /**
- * Junit / Instrumentation test case for the media recorder api 
- */  
+ * Junit / Instrumentation test case for the media recorder api
+ */
 public class MediaRecorderTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
     private String TAG = "MediaRecorderTest";
     private int mOutputDuration =0;
     private int mOutputVideoWidth = 0;
     private int mOutputVideoHeight= 0 ;
-    
+
     private SurfaceHolder mSurfaceHolder = null;
     private MediaRecorder mRecorder;
 
     private int MIN_VIDEO_FPS = 5;
+    private int HIGH_SPEED_FPS = 120;
 
     private static final int CAMERA_ID = 0;
 
     Context mContext;
     Camera mCamera;
-  
+
     public MediaRecorderTest() {
-        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
-       
+        super(MediaFrameworkTest.class);
+
     }
 
     protected void setUp() throws Exception {
@@ -69,8 +75,8 @@
         mRecorder = new MediaRecorder();
         super.setUp();
     }
- 
-    private void recordVideo(int frameRate, int width, int height, 
+
+    private void recordVideo(int frameRate, int width, int height,
             int videoFormat, int outFormat, String outFile, boolean videoOnly) {
         Log.v(TAG,"startPreviewAndPrepareRecording");
         try {
@@ -80,7 +86,7 @@
             }
             mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
             mRecorder.setOutputFormat(outFormat);
-            Log.v(TAG, "output format " + outFormat);          
+            Log.v(TAG, "output format " + outFormat);
             mRecorder.setOutputFile(outFile);
             mRecorder.setVideoFrameRate(frameRate);
             mRecorder.setVideoSize(width, height);
@@ -105,7 +111,186 @@
             mRecorder.release();
         }
     }
-    
+
+    private boolean validateGetSurface(boolean useSurface) {
+        Log.v(TAG,"validateGetSurface, useSurface=" + useSurface);
+        MediaRecorder recorder = new MediaRecorder();
+        Surface surface;
+        boolean success = true;
+        try {
+            /* initialization */
+            if (!useSurface) {
+                mCamera = Camera.open(CAMERA_ID);
+                Camera.Parameters parameters = mCamera.getParameters();
+                parameters.setPreviewSize(352, 288);
+                parameters.set("orientation", "portrait");
+                mCamera.setParameters(parameters);
+                mCamera.unlock();
+                recorder.setCamera(mCamera);
+                mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+                recorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+            }
+
+            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+            int videoSource = useSurface ?
+                    MediaRecorder.VideoSource.SURFACE :
+                    MediaRecorder.VideoSource.CAMERA;
+            recorder.setVideoSource(videoSource);
+            recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+            recorder.setOutputFile(MediaNames.RECORDED_SURFACE_3GP);
+            recorder.setVideoFrameRate(30);
+            recorder.setVideoSize(352, 288);
+            recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
+            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+
+            /* Test: getSurface() before prepare()
+             * should throw IllegalStateException
+             */
+            try {
+                surface = recorder.getSurface();
+                throw new Exception("getSurface failed to throw IllegalStateException");
+            } catch (IllegalStateException e) {
+                // OK
+            }
+
+            recorder.prepare();
+
+            /* Test: getSurface() after prepare()
+             * should succeed for surface source
+             * should fail for camera source
+             */
+            try {
+                surface = recorder.getSurface();
+                if (!useSurface) {
+                    throw new Exception("getSurface failed to throw IllegalStateException");
+                }
+            } catch (IllegalStateException e) {
+                if (useSurface) {
+                    throw new Exception("getSurface failed to throw IllegalStateException");
+                }
+            }
+
+            recorder.start();
+
+            /* Test: getSurface() after start()
+             * should succeed for surface source
+             * should fail for camera source
+             */
+            try {
+                surface = recorder.getSurface();
+                if (!useSurface) {
+                    throw new Exception("getSurface failed to throw IllegalStateException");
+                }
+            } catch (IllegalStateException e) {
+                if (useSurface) {
+                    throw new Exception("getSurface failed to throw IllegalStateException");
+                }
+            }
+
+            try {
+                recorder.stop();
+            } catch (Exception e) {
+                // stop() could fail if the recording is empty, as we didn't render anything.
+                // ignore any failure in stop, we just want it stopped.
+            }
+
+            /* Test: getSurface() after stop()
+             * should throw IllegalStateException
+             */
+            try {
+                surface = recorder.getSurface();
+                throw new Exception("getSurface failed to throw IllegalStateException");
+            } catch (IllegalStateException e) {
+                // OK
+            }
+        } catch (Exception e) {
+            // fail
+            success = false;
+        }
+
+        try {
+            if (mCamera != null) {
+                mCamera.lock();
+                mCamera.release();
+                mCamera = null;
+            }
+            recorder.release();
+        } catch (Exception e) {
+            success = false;
+        }
+
+        return success;
+    }
+
+    private boolean recordVideoFromSurface(
+            int frameRate, int captureRate, int width, int height,
+            int videoFormat, int outFormat, String outFile, boolean videoOnly) {
+        Log.v(TAG,"recordVideoFromSurface");
+        MediaRecorder recorder = new MediaRecorder();
+        int sleepTime = 33; // normal capture at 33ms / frame
+        try {
+            if (!videoOnly) {
+                recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+            }
+            recorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
+            recorder.setOutputFormat(outFormat);
+            recorder.setOutputFile(outFile);
+            recorder.setVideoFrameRate(frameRate);
+            if (captureRate > 0) {
+                recorder.setCaptureRate(captureRate);
+                sleepTime = 1000 / captureRate;
+            }
+            recorder.setVideoSize(width, height);
+            recorder.setVideoEncoder(videoFormat);
+            if (!videoOnly) {
+                recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+            }
+            recorder.prepare();
+            Surface surface = recorder.getSurface();
+
+            Paint paint = new Paint();
+            paint.setTextSize(16);
+            paint.setColor(Color.RED);
+            int i;
+
+            /* Test: draw 10 frames at 30fps before start
+             * these should be dropped and not causing malformed stream.
+             */
+            for(i = 0; i < 10; i++) {
+                Canvas canvas = surface.lockCanvas(null);
+                int background = (i * 255 / 99);
+                canvas.drawARGB(255, background, background, background);
+                String text = "Frame #" + i;
+                canvas.drawText(text, 100, 100, paint);
+                surface.unlockCanvasAndPost(canvas);
+                Thread.sleep(sleepTime);
+            }
+
+            Log.v(TAG, "start");
+            recorder.start();
+
+            /* Test: draw another 90 frames at 30fps after start */
+            for(i = 10; i < 100; i++) {
+                Canvas canvas = surface.lockCanvas(null);
+                int background = (i * 255 / 99);
+                canvas.drawARGB(255, background, background, background);
+                String text = "Frame #" + i;
+                canvas.drawText(text, 100, 100, paint);
+                surface.unlockCanvasAndPost(canvas);
+                Thread.sleep(sleepTime);
+            }
+
+            Log.v(TAG, "stop");
+            recorder.stop();
+            recorder.release();
+        } catch (Exception e) {
+            Log.v("record video failed ", e.toString());
+            recorder.release();
+            return false;
+        }
+        return true;
+    }
+
     private boolean recordVideoWithPara(VideoEncoderCap videoCap, AudioEncoderCap audioCap, boolean highQuality){
         boolean recordSuccess = false;
         int videoEncoder = videoCap.mCodec;
@@ -171,7 +356,7 @@
         return recordSuccess;
     }
 
-    private boolean invalidRecordSetting(int frameRate, int width, int height, 
+    private boolean invalidRecordSetting(int frameRate, int width, int height,
             int videoFormat, int outFormat, String outFile, boolean videoOnly) {
         try {
             if (!videoOnly) {
@@ -180,7 +365,7 @@
             }
             mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
             mRecorder.setOutputFormat(outFormat);
-            Log.v(TAG, "output format " + outFormat);          
+            Log.v(TAG, "output format " + outFormat);
             mRecorder.setOutputFile(outFile);
             mRecorder.setVideoFrameRate(frameRate);
             mRecorder.setVideoSize(width, height);
@@ -208,7 +393,7 @@
         }
         return false;
     }
-    
+
     private void getOutputVideoProperty(String outputFilePath) {
         MediaPlayer mediaPlayer = new MediaPlayer();
         try {
@@ -223,13 +408,13 @@
             Thread.sleep(1000);
             mOutputVideoHeight = mediaPlayer.getVideoHeight();
             mOutputVideoWidth = mediaPlayer.getVideoWidth();
-            mediaPlayer.release();    
+            mediaPlayer.release();
         } catch (Exception e) {
             Log.v(TAG, e.toString());
             mediaPlayer.release();
-        }       
+        }
     }
-    
+
     private boolean validateVideo(String filePath, int width, int height) {
         boolean validVideo = false;
         getOutputVideoProperty(filePath);
@@ -260,7 +445,7 @@
             int codec = MediaRecorder.VideoEncoder.H263;
             int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
             recordVideo(frameRate, 352, 288, codec,
-                    MediaRecorder.OutputFormat.THREE_GPP, 
+                    MediaRecorder.OutputFormat.THREE_GPP,
                     MediaNames.RECORDED_PORTRAIT_H263, true);
             mCamera.lock();
             mCamera.release();
@@ -271,15 +456,15 @@
         }
         assertTrue("PortraitH263", videoRecordedResult);
     }
-    
+
     @LargeTest
-    public void testInvalidVideoPath() throws Exception {       
+    public void testInvalidVideoPath() throws Exception {
         boolean isTestInvalidVideoPathSuccessful = false;
-        isTestInvalidVideoPathSuccessful = invalidRecordSetting(15, 176, 144, MediaRecorder.VideoEncoder.H263, 
-               MediaRecorder.OutputFormat.THREE_GPP, MediaNames.INVALD_VIDEO_PATH, false);      
+        isTestInvalidVideoPathSuccessful = invalidRecordSetting(15, 176, 144, MediaRecorder.VideoEncoder.H263,
+               MediaRecorder.OutputFormat.THREE_GPP, MediaNames.INVALD_VIDEO_PATH, false);
         assertTrue("Invalid outputFile Path", isTestInvalidVideoPathSuccessful);
     }
-    
+
     @LargeTest
     //test cases for the new codec
     public void testDeviceSpecificCodec() throws Exception {
@@ -309,4 +494,83 @@
             assertTrue("testDeviceSpecificCodec", false);
         }
     }
+
+    // Test MediaRecorder.getSurface() api with surface or camera source
+    public void testGetSurfaceApi() {
+        boolean success = false;
+        int noOfFailure = 0;
+        try {
+            for (int k = 0; k < 2; k++) {
+                success = validateGetSurface(
+                        k == 0 ? true : false /* useSurface */);
+                if (!success) {
+                    noOfFailure++;
+                }
+            }
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+        }
+        assertTrue("testGetSurfaceApi", noOfFailure == 0);
+    }
+
+    // Test recording from surface source with/without audio
+    public void testSurfaceRecording() {
+        boolean success = false;
+        int noOfFailure = 0;
+        try {
+            int codec = MediaRecorder.VideoEncoder.H264;
+            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
+            for (int k = 0; k < 2; k++) {
+                String filename = "/sdcard/surface_" +
+                            (k==0?"video_only":"with_audio") + ".3gp";
+
+                success = recordVideoFromSurface(frameRate, 0, 352, 288, codec,
+                        MediaRecorder.OutputFormat.THREE_GPP, filename,
+                        k == 0 ? true : false /* videoOnly */);
+                if (success) {
+                    success = validateVideo(filename, 352, 288);
+                }
+                if (!success) {
+                    noOfFailure++;
+                }
+            }
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+        }
+        assertTrue("testSurfaceRecording", noOfFailure == 0);
+    }
+
+    // Test recording from surface source with/without audio
+    public void testSurfaceRecordingTimeLapse() {
+        boolean success = false;
+        int noOfFailure = 0;
+        try {
+            int codec = MediaRecorder.VideoEncoder.H264;
+            int frameRate = MediaProfileReader.getMaxFrameRateForCodec(codec);
+            for (int k = 0; k < 2; k++) {
+                // k==0: time lapse test, set capture rate to MIN_VIDEO_FPS
+                // k==1: slow motion test, set capture rate to HIGH_SPEED_FPS
+                String filename = "/sdcard/surface_" +
+                            (k==0 ? "time_lapse" : "slow_motion") + ".3gp";
+
+                // always set videoOnly=false, MediaRecorder should disable
+                // audio automatically with time lapse/slow motion
+                success = recordVideoFromSurface(frameRate,
+                        k==0 ? MIN_VIDEO_FPS : HIGH_SPEED_FPS,
+                        352, 288, codec,
+                        MediaRecorder.OutputFormat.THREE_GPP,
+                        filename, false /* videoOnly */);
+                if (success) {
+                    success = validateVideo(filename, 352, 288);
+                }
+                if (!success) {
+                    noOfFailure++;
+                }
+            }
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+        }
+        assertTrue("testSurfaceRecordingTimeLapse", noOfFailure == 0);
+    }
+
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
index 8c76421..eb1a589 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaInserterTest.java
@@ -85,8 +85,8 @@
         super.setUp();
         mMockProvider = EasyMock.createMock(IContentProvider.class);
         mMediaInserter = new MediaInserter(mMockProvider,
-		mPackageName, TEST_BUFFER_SIZE);
-	mPackageName = getInstrumentation().getContext().getPackageName();
+        mPackageName, TEST_BUFFER_SIZE);
+        mPackageName = getInstrumentation().getContext().getPackageName();
         mFilesCounter = 0;
         mAudioCounter = 0;
         mVideoCounter = 0;
@@ -224,19 +224,19 @@
     @SmallTest
     public void testInsertContentsWithDifferentSizePerContentType() throws Exception {
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sFilesUri),
+        MediaUriMatcher.expectMediaUri(sFilesUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(1);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sAudioUri),
+        MediaUriMatcher.expectMediaUri(sAudioUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(2);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sVideoUri),
+        MediaUriMatcher.expectMediaUri(sVideoUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(3);
         EasyMock.expect(mMockProvider.bulkInsert(mPackageName,
-		MediaUriMatcher.expectMediaUri(sImagesUri),
+        MediaUriMatcher.expectMediaUri(sImagesUri),
                 (ContentValues[]) EasyMock.anyObject())).andReturn(1);
         EasyMock.expectLastCall().times(4);
         EasyMock.replay(mMockProvider);
diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk
index ad874c8..95ae33b 100644
--- a/media/tests/omxjpegdecoder/Android.mk
+++ b/media/tests/omxjpegdecoder/Android.mk
@@ -34,11 +34,6 @@
 
 LOCAL_C_INCLUDES := \
     $(TOP)/external/jpeg \
-    $(TOP)/external/skia/include/config \
-    $(TOP)/external/skia/include/core \
-    $(TOP)/external/skia/include/images \
-    $(TOP)/external/skia/include/utils \
-    $(TOP)/external/skia/include/effects \
     $(TOP)/frameworks/base/media/libstagefright \
     $(TOP)/frameworks/base/include/ \
     $(TOP)/frameworks/base/ \
diff --git a/media/tests/omxjpegdecoder/StreamSource.h b/media/tests/omxjpegdecoder/StreamSource.h
index 6c34cbd..9807385 100644
--- a/media/tests/omxjpegdecoder/StreamSource.h
+++ b/media/tests/omxjpegdecoder/StreamSource.h
@@ -20,7 +20,7 @@
 
 #include <stdio.h>
 
-#include <core/SkStream.h>
+#include <SkStream.h>
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaErrors.h>
 #include <utils/threads.h>
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
index a94fedb..d1fed7bb 100644
--- a/media/tests/players/invoke_mock_media_player.cpp
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -27,6 +27,7 @@
 using android::INVALID_OPERATION;
 using android::Surface;
 using android::IGraphicBufferProducer;
+using android::IMediaHTTPService;
 using android::MediaPlayerBase;
 using android::OK;
 using android::Parcel;
@@ -57,6 +58,7 @@
     virtual bool        hardwareOutput() {return true;}
 
     virtual status_t    setDataSource(
+            const sp<IMediaHTTPService> &httpService,
             const char *url,
             const KeyedVector<String8, String8> *) {
         ALOGV("setDataSource %s", url);
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
index 8b333e7..3154030 100644
--- a/native/graphics/jni/Android.mk
+++ b/native/graphics/jni/Android.mk
@@ -23,7 +23,6 @@
     libskia
 
 LOCAL_C_INCLUDES += \
-	external/skia/include/core \
 	frameworks/base/native/include \
 	frameworks/base/core/jni/android/graphics
 
diff --git a/opengl/java/android/opengl/EGLObjectHandle.java b/opengl/java/android/opengl/EGLObjectHandle.java
index e6e3976..f961eb7 100644
--- a/opengl/java/android/opengl/EGLObjectHandle.java
+++ b/opengl/java/android/opengl/EGLObjectHandle.java
@@ -24,18 +24,28 @@
 public abstract class EGLObjectHandle {
     private final long mHandle;
 
-    // TODO Deprecate EGLObjectHandle(int) method
+    /**
+     * @deprecated Use {@link #EGLObjectHandle(long)} instead. Handles
+     *     on 64 bit platforms will be wider than java ints.
+     */
+    @Deprecated
     protected EGLObjectHandle(int handle) {
         mHandle = handle;
     }
-    // TODO Unhide the EGLObjectHandle(long) method
-    /**
-     * {@hide}
-     */
     protected EGLObjectHandle(long handle) {
         mHandle = handle;
     }
-    // TODO Deprecate getHandle() method in favor of getNativeHandle()
+    /**
+     * @deprecated Use {@link #getNativeHandle()} instead. Handles on
+     *     64 bit platforms will be wider than java ints.
+     */
+    @Deprecated
+    public int getHandle() {
+        if ((mHandle & 0xffffffffL) != mHandle) {
+            throw new UnsupportedOperationException();
+        }
+        return (int)mHandle;
+    }
     /**
      * Returns the native handle of the wrapped EGL object. This handle can be
      * cast to the corresponding native type on the native side.
@@ -44,17 +54,6 @@
      *
      * @return the native handle of the wrapped EGL object.
      */
-    public int getHandle() {
-        if ((mHandle & 0xffffffffL) != mHandle) {
-            throw new UnsupportedOperationException();
-        }
-        return (int)mHandle;
-    }
-
-    // TODO Unhide getNativeHandle() method
-    /**
-     * {@hide}
-     */
     public long getNativeHandle() {
         return mHandle;
     }
diff --git a/opengl/java/android/opengl/GLES10.java b/opengl/java/android/opengl/GLES10.java
index db52b82..fed84d5 100644
--- a/opengl/java/android/opengl/GLES10.java
+++ b/opengl/java/android/opengl/GLES10.java
@@ -262,7 +262,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
 
     private static Buffer _colorPointer;
diff --git a/opengl/java/android/opengl/GLES10Ext.java b/opengl/java/android/opengl/GLES10Ext.java
index 81fc59e..3dc26eb 100644
--- a/opengl/java/android/opengl/GLES10Ext.java
+++ b/opengl/java/android/opengl/GLES10Ext.java
@@ -22,7 +22,7 @@
 public class GLES10Ext {
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
     
     // C function GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent )
diff --git a/opengl/java/android/opengl/GLES11.java b/opengl/java/android/opengl/GLES11.java
index 1ca179b..bb69bba 100644
--- a/opengl/java/android/opengl/GLES11.java
+++ b/opengl/java/android/opengl/GLES11.java
@@ -147,7 +147,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
 
     private static Buffer _pointSizePointerOES;
diff --git a/opengl/java/android/opengl/GLES11Ext.java b/opengl/java/android/opengl/GLES11Ext.java
index 484439a..04d1b5d 100644
--- a/opengl/java/android/opengl/GLES11Ext.java
+++ b/opengl/java/android/opengl/GLES11Ext.java
@@ -132,7 +132,7 @@
 
     native private static void _nativeClassInit();
     static {
-	    _nativeClassInit();
+        _nativeClassInit();
     }
     
     private static final int GL_BYTE = GLES10.GL_BYTE;
diff --git a/opengl/java/android/opengl/GLES20.java b/opengl/java/android/opengl/GLES20.java
index 8261474..137f2f5 100644
--- a/opengl/java/android/opengl/GLES20.java
+++ b/opengl/java/android/opengl/GLES20.java
@@ -823,6 +823,7 @@
 
     // C function void glGetActiveAttrib ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name )
 
+    /** @hide Method is broken, but used to be public (b/6006380) */
     public static native void glGetActiveAttrib(
         int program,
         int index,
@@ -870,6 +871,7 @@
 
     // C function void glGetActiveUniform ( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, char *name )
 
+    /** @hide Method is broken, but used to be public (b/6006380) */
     public static native void glGetActiveUniform(
         int program,
         int index,
@@ -1107,6 +1109,7 @@
 
     // C function void glGetShaderSource ( GLuint shader, GLsizei bufsize, GLsizei *length, char *source )
 
+    /** @hide Method is broken, but used to be public (b/6006380) */
     public static native void glGetShaderSource(
         int shader,
         int bufsize,
diff --git a/opengl/java/android/opengl/GLES30.java b/opengl/java/android/opengl/GLES30.java
index 9164849..342ffa4 100644
--- a/opengl/java/android/opengl/GLES30.java
+++ b/opengl/java/android/opengl/GLES30.java
@@ -864,13 +864,13 @@
         int buffer
     );
 
-	// C function void glTransformFeedbackVaryings ( GLuint program, GLsizei count, const GLchar *varyings, GLenum bufferMode )
+    // C function void glTransformFeedbackVaryings ( GLuint program, GLsizei count, const GLchar *varyings, GLenum bufferMode )
 
-	public static native void glTransformFeedbackVaryings(
+    public static native void glTransformFeedbackVaryings(
         int program,
         String[] varyings,
         int bufferMode
-	);
+    );
 
     // C function void glGetTransformFeedbackVarying ( GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name )
 
@@ -1245,14 +1245,14 @@
         int size
     );
 
-	// C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
+    // C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
 
-	public static native void glGetUniformIndices(
+    public static native void glGetUniformIndices(
         int program,
         String[] uniformNames,
         int[] uniformIndices,
         int uniformIndicesOffset
-	);
+    );
 
     // C function void glGetUniformIndices ( GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices )
 
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 5a2e261..a9322b9 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -595,13 +595,9 @@
         mDetached = false;
     }
 
-    /**
-     * This method is used as part of the View class and is not normally
-     * called or subclassed by clients of GLSurfaceView.
-     * Must not be called before a renderer has been set.
-     */
+    /** @hide */
     @Override
-    protected void onDetachedFromWindow() {
+    protected void onDetachedFromWindowInternal() {
         if (LOG_ATTACH_DETACH) {
             Log.d(TAG, "onDetachedFromWindow");
         }
@@ -609,7 +605,7 @@
             mGLThread.requestExitAndWait();
         }
         mDetached = true;
-        super.onDetachedFromWindow();
+        super.onDetachedFromWindowInternal();
     }
 
     // ----------------------------------------------------------------------
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
index 6b23be9..d4c0c80 100644
--- a/opengl/java/com/google/android/gles_jni/GLImpl.java
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -39,7 +39,7 @@
 
     native private static void _nativeClassInit();
     static {
-	_nativeClassInit();
+        _nativeClassInit();
     }
 
     Buffer _colorPointer = null;
diff --git a/packages/BackupRestoreConfirmation/res/values-az-rAZ/strings.xml b/packages/BackupRestoreConfirmation/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..1f9e6aa
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-az-rAZ/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">"Tam yedəkləmə"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Tam bərpa"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Bütün datanın qoşulmuş masaüstü kompüterə rezerv olunması sorğusu göndərilib. Buna icazə vermək istəyirsiniz mi?\n\nƏgər bu sorğunu göndərməmisinizsə, bu prosesin davam etməsinə icazə verməyin."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Məlumatlarımı yedəklə"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Rezerv etməyin"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Qoşulmuş stolüstü kompüterdən tam bərpa tələb olunur. Buna icazə verilsin?\n\nBərpanı siz özünüz tələb etməmisinizsə, bu əməliyyatı davam etdirməyin. Bu cihazdakı istənilən məlumatı dəyişdirəcək."</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Məlumatlarımı bərpa et"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Bərpa etməyin"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Lütfən, aşağıda cari yedək parolunuzu daxil edin:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Lütfən, aşağıda cihaz şifrələmə parolunu daxil edin."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Lütfən, aşağıda cihaz şifrələmə parolunuzu daxil edin. Bu yedək arxivini şifrələmək üçün də istifadə olunacaq."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tam yedək data şifrələmədən istifadə üçün şifrə daxil edin. Əgər boş buraxılsa, cari yedək şifrə istifadə olunacaq:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Bütün yedək datanı şifrələmək istəyirsinizsə, aşağıda parol daxil edin:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Bərpa məlumatları şifrələnibsə, şifrəni aşağıda daxil edin:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Rezerv edilir ..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Yedəkləmə sona çatdı"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Bərpa başlayır..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Bərpa sona çatdı"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Əməliyyat vaxtı bitdi"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-az/strings.xml b/packages/BackupRestoreConfirmation/res/values-az/strings.xml
new file mode 100644
index 0000000..1f9e6aa
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-az/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">"Tam yedəkləmə"</string>
+    <string name="restore_confirm_title" msgid="5469365809567486602">"Tam bərpa"</string>
+    <string name="backup_confirm_text" msgid="1878021282758896593">"Bütün datanın qoşulmuş masaüstü kompüterə rezerv olunması sorğusu göndərilib. Buna icazə vermək istəyirsiniz mi?\n\nƏgər bu sorğunu göndərməmisinizsə, bu prosesin davam etməsinə icazə verməyin."</string>
+    <string name="allow_backup_button_label" msgid="4217228747769644068">"Məlumatlarımı yedəklə"</string>
+    <string name="deny_backup_button_label" msgid="6009119115581097708">"Rezerv etməyin"</string>
+    <string name="restore_confirm_text" msgid="7499866728030461776">"Qoşulmuş stolüstü kompüterdən tam bərpa tələb olunur. Buna icazə verilsin?\n\nBərpanı siz özünüz tələb etməmisinizsə, bu əməliyyatı davam etdirməyin. Bu cihazdakı istənilən məlumatı dəyişdirəcək."</string>
+    <string name="allow_restore_button_label" msgid="3081286752277127827">"Məlumatlarımı bərpa et"</string>
+    <string name="deny_restore_button_label" msgid="1724367334453104378">"Bərpa etməyin"</string>
+    <string name="current_password_text" msgid="8268189555578298067">"Lütfən, aşağıda cari yedək parolunuzu daxil edin:"</string>
+    <string name="device_encryption_restore_text" msgid="1570864916855208992">"Lütfən, aşağıda cihaz şifrələmə parolunu daxil edin."</string>
+    <string name="device_encryption_backup_text" msgid="5866590762672844664">"Lütfən, aşağıda cihaz şifrələmə parolunuzu daxil edin. Bu yedək arxivini şifrələmək üçün də istifadə olunacaq."</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tam yedək data şifrələmədən istifadə üçün şifrə daxil edin. Əgər boş buraxılsa, cari yedək şifrə istifadə olunacaq:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Bütün yedək datanı şifrələmək istəyirsinizsə, aşağıda parol daxil edin:"</string>
+    <string name="restore_enc_password_text" msgid="6140898525580710823">"Bərpa məlumatları şifrələnibsə, şifrəni aşağıda daxil edin:"</string>
+    <string name="toast_backup_started" msgid="550354281452756121">"Rezerv edilir ..."</string>
+    <string name="toast_backup_ended" msgid="3818080769548726424">"Yedəkləmə sona çatdı"</string>
+    <string name="toast_restore_started" msgid="7881679218971277385">"Bərpa başlayır..."</string>
+    <string name="toast_restore_ended" msgid="1764041639199696132">"Bərpa sona çatdı"</string>
+    <string name="toast_timeout" msgid="5276598587087626877">"Əməliyyat vaxtı bitdi"</string>
+</resources>
diff --git a/packages/BackupRestoreConfirmation/res/values-be/strings.xml b/packages/BackupRestoreConfirmation/res/values-be/strings.xml
deleted file mode 100644
index 188041a..0000000
--- a/packages/BackupRestoreConfirmation/res/values-be/strings.xml
+++ /dev/null
@@ -1,38 +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.
- -->
-
-<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Калі вы самі не запытвалі рэзервовае кап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="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">"Увядзіце нiжэй пароль для расшыфравання прылады."</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-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-et/strings.xml b/packages/BackupRestoreConfirmation/res/values-et-rEE/strings.xml
similarity index 100%
rename from packages/BackupRestoreConfirmation/res/values-et/strings.xml
rename to packages/BackupRestoreConfirmation/res/values-et-rEE/strings.xml
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-hi/strings.xml b/packages/BackupRestoreConfirmation/res/values-hi/strings.xml
index dd0c645..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="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-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-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-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-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/strings.xml b/packages/BackupRestoreConfirmation/res/values-ms-rMY/strings.xml
similarity index 100%
rename from packages/BackupRestoreConfirmation/res/values-ms/strings.xml
rename to packages/BackupRestoreConfirmation/res/values-ms-rMY/strings.xml
diff --git a/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml b/packages/BackupRestoreConfirmation/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..c56332f
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-ne-rNP/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">"ब्याकप डेटालाई encrypt गर्न पासवर्ड प्रविष्टि गर्नुहोस्, यदि यो खालि छोडिएको खण्डमा तपाईको पुरानै पासवर्ड प्रयोग हुने छ।"</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-ne/strings.xml b/packages/BackupRestoreConfirmation/res/values-ne/strings.xml
new file mode 100644
index 0000000..c56332f
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-ne/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">"ब्याकप डेटालाई encrypt गर्न पासवर्ड प्रविष्टि गर्नुहोस्, यदि यो खालि छोडिएको खण्डमा तपाईको पुरानै पासवर्ड प्रयोग हुने छ।"</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-si-rLK/strings.xml b/packages/BackupRestoreConfirmation/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..ed32e73
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-si-rLK/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ඔබ විසින් උපස්ථය කිරීමට ඉල්ලා නොතිබුණි නම්, මෙම මෙහෙයුම ඉදිරියට කරගෙන යාමට අවසර දෙන්න එපා. 1"</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-si/strings.xml b/packages/BackupRestoreConfirmation/res/values-si/strings.xml
new file mode 100644
index 0000000..ed32e73
--- /dev/null
+++ b/packages/BackupRestoreConfirmation/res/values-si/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ඔබ විසින් උපස්ථය කිරීමට ඉල්ලා නොතිබුණි නම්, මෙම මෙහෙයුම ඉදිරියට කරගෙන යාමට අවසර දෙන්න එපා. 1"</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-sw/strings.xml b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
index 619a6db..4e35b91 100644
--- a/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-sw/strings.xml
@@ -18,17 +18,17 @@
     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">"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="backup_confirm_text" msgid="1878021282758896593">"Ombi la kuhifadhi nakala rudufu kamili za data kwenye eneo kazi la kompyuta iliyounganishwa limewasilishwa. Ungependa shughuli hii ufanyike?\n\n Ikiwa sio wewe uliyewasilisha ombi hili, usikubali shughuli hii iendelee."</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="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>
+    <string name="current_password_text" msgid="8268189555578298067">"Tafadhali ingiza nenosiri unalotumia kuhifadhi nakala rudufu hapo chini:"</string>
     <string name="device_encryption_restore_text" msgid="1570864916855208992">"Tafadhali ingiza nenosiri la usimbaji fiche wa kifaa chako hapo chini."</string>
     <string name="device_encryption_backup_text" msgid="5866590762672844664">"Tafadhali ingiza nenosiri lako la msimbo fiche hapo chini. Pia litatumika kusimba fiche jalidi ya hifadhi."</string>
-    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tafadhali ingiza nenosiri la kutumia kwa usimbaji fiche wa chelezo ya data kamili. Ikiwa hii itawachwa wazi, nenosiri lako la sasa litatumika:"</string>
-    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ikiwa unataka kusimba fiche data nzima ya kucheleza, ingiza nenosiri la hapo chini:"</string>
+    <string name="backup_enc_password_text" msgid="4981585714795233099">"Tafadhali ingiza nenosiri la kutumia katika kusimba nakala rudufu kamili za data kwa njia fiche. Ikiwa hii itawachwa wazi, nenosiri lako la sasa litatumika:"</string>
+    <string name="backup_enc_password_optional" msgid="1350137345907579306">"Ikiwa unataka kusimba kwa njia fiche nakala rudufu za data, ingiza nenosiri lililo hapo chini:"</string>
     <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>
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-zu/strings.xml b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
index b62b7af..955b26f 100644
--- a/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values-zu/strings.xml
@@ -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/res/values-az-rAZ/strings.xml b/packages/DefaultContainerService/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..cae7d02
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-az-rAZ/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">"Paket Giriş Yardımçısı"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-az/strings.xml b/packages/DefaultContainerService/res/values-az/strings.xml
new file mode 100644
index 0000000..cae7d02
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-az/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">"Paket Giriş Yardımçısı"</string>
+</resources>
diff --git a/packages/DefaultContainerService/res/values-be/strings.xml b/packages/DefaultContainerService/res/values-be/strings.xml
deleted file mode 100644
index 68621b6..0000000
--- a/packages/DefaultContainerService/res/values-be/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
- -->
-
-<resources xmlns: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-et/strings.xml b/packages/DefaultContainerService/res/values-en-rIN/strings.xml
similarity index 100%
rename from packages/DefaultContainerService/res/values-et/strings.xml
rename to packages/DefaultContainerService/res/values-en-rIN/strings.xml
diff --git a/packages/DefaultContainerService/res/values-et/strings.xml b/packages/DefaultContainerService/res/values-et-rEE/strings.xml
similarity index 100%
copy from packages/DefaultContainerService/res/values-et/strings.xml
copy to packages/DefaultContainerService/res/values-et-rEE/strings.xml
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-et/strings.xml b/packages/DefaultContainerService/res/values-ka-rGE/strings.xml
similarity index 100%
copy from packages/DefaultContainerService/res/values-et/strings.xml
copy to packages/DefaultContainerService/res/values-ka-rGE/strings.xml
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-et/strings.xml b/packages/DefaultContainerService/res/values-lo-rLA/strings.xml
similarity index 100%
copy from packages/DefaultContainerService/res/values-et/strings.xml
copy to packages/DefaultContainerService/res/values-lo-rLA/strings.xml
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/strings.xml b/packages/DefaultContainerService/res/values-ms-rMY/strings.xml
similarity index 100%
rename from packages/DefaultContainerService/res/values-ms/strings.xml
rename to packages/DefaultContainerService/res/values-ms-rMY/strings.xml
diff --git a/packages/DefaultContainerService/res/values-ne-rNP/strings.xml b/packages/DefaultContainerService/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..5b70ce1
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-ne-rNP/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-ne/strings.xml b/packages/DefaultContainerService/res/values-ne/strings.xml
new file mode 100644
index 0000000..5b70ce1
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-ne/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-si-rLK/strings.xml b/packages/DefaultContainerService/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..522ec6c
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-si-rLK/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-si/strings.xml b/packages/DefaultContainerService/res/values-si/strings.xml
new file mode 100644
index 0000000..522ec6c
--- /dev/null
+++ b/packages/DefaultContainerService/res/values-si/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-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 6e34bbb..f68d1a9 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -39,10 +39,8 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StatFs;
-import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.app.IMediaContainerService;
diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml
new file mode 100644
index 0000000..41fd63a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-af/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Kon nie vouer skep nie"</string>
+    <string name="query_error" msgid="1222448261663503501">"Kon nie navraag doen oor dokumente 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Bergingdienste"</string>
+    <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..c77a8ee
--- /dev/null
+++ b/packages/DocumentsUI/res/values-am/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"አቃፊ መፍጠር አልተሳካም"</string>
+    <string name="query_error" msgid="1222448261663503501">"ለሰነዶች መጠይቅ መስራት አልተሳካም"</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-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml
new file mode 100644
index 0000000..c59c0ee
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ar/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"أخفق إنشاء المجلد"</string>
+    <string name="query_error" msgid="1222448261663503501">"أخفق إرسال طلب بحث عن المستندات"</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-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..c3242b2
--- /dev/null
+++ b/packages/DocumentsUI/res/values-bg/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Създаването на папката не бе успешно"</string>
+    <string name="query_error" msgid="1222448261663503501">"Заявката за документи не бе успешна"</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-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml
new file mode 100644
index 0000000..68c7b0e
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ca/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"No s\'ha pogut crear la carpeta"</string>
+    <string name="query_error" msgid="1222448261663503501">"No s\'han pogut consultar els documents"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Serveis d\'emmagatzematge"</string>
+    <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..f089c8b
--- /dev/null
+++ b/packages/DocumentsUI/res/values-cs/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Složku se nepodařilo vytvořit"</string>
+    <string name="query_error" msgid="1222448261663503501">"Seznam dokumentů se nepodařilo načíst"</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..816f9a7
--- /dev/null
+++ b/packages/DocumentsUI/res/values-da/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Mappen kunne ikke oprettes"</string>
+    <string name="query_error" msgid="1222448261663503501">"Dokumenterne kunne ikke forespørges."</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..e43a1e2
--- /dev/null
+++ b/packages/DocumentsUI/res/values-de/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Ordner konnte nicht erstellt werden."</string>
+    <string name="query_error" msgid="1222448261663503501">"Fehler bei der Anforderung von Dokumenten"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Speicherdienste"</string>
+    <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 Dokumente"</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..5a91484
--- /dev/null
+++ b/packages/DocumentsUI/res/values-el/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Αποτυχία δημιουργίας φακέλου"</string>
+    <string name="query_error" msgid="1222448261663503501">"Αποτυχία υποβολής  ερωτήματος για έγγραφα"</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..a95e7f1
--- /dev/null
+++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Failed to create folder"</string>
+    <string name="query_error" msgid="1222448261663503501">"Failed to query documents"</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..a95e7f1
--- /dev/null
+++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Failed to create folder"</string>
+    <string name="query_error" msgid="1222448261663503501">"Failed to query documents"</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..4a3ff33
--- /dev/null
+++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Error al crear la carpeta"</string>
+    <string name="query_error" msgid="1222448261663503501">"Error al consultar documentos"</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..1682542
--- /dev/null
+++ b/packages/DocumentsUI/res/values-es/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Error al crear la carpeta"</string>
+    <string name="query_error" msgid="1222448261663503501">"Error al consultar lista de documentos"</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..5412956
--- /dev/null
+++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Kausta loomine ebaõnnestus"</string>
+    <string name="query_error" msgid="1222448261663503501">"Dokumentide päring 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Mäluruumi teenused"</string>
+    <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..c922b37
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fa/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"ایجاد پوشه انجام نشد"</string>
+    <string name="query_error" msgid="1222448261663503501">"جستجوی اسناد ناموفق بود"</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-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml
new file mode 100644
index 0000000..5e40ecd
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fi/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Kansion luominen epäonnistui"</string>
+    <string name="query_error" msgid="1222448261663503501">"Dokumenttikysely 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Tallennuspalvelut"</string>
+    <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..a837379
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Échec de la création du dossier"</string>
+    <string name="query_error" msgid="1222448261663503501">"Échec de la demande de 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..ff9aeda
--- /dev/null
+++ b/packages/DocumentsUI/res/values-fr/strings.xml
@@ -0,0 +1,54 @@
+<?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 à partir de"</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="create_error" msgid="3735649141335444215">"Échec de la création du dossier."</string>
+    <string name="query_error" msgid="1222448261663503501">"Échec de la demande de documents."</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>
+    <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">"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..8d7fcba
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hi/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"फ़ोल्डर बनाने में विफल"</string>
+    <string name="query_error" msgid="1222448261663503501">"दस्तावेजों के लिए क्वेरी करने में विफल रहा"</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-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml
new file mode 100644
index 0000000..73c2f04
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hr/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Izrada mape nije uspjela"</string>
+    <string name="query_error" msgid="1222448261663503501">"Traženje dokumenata nije uspjelo"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Usluge pohrane"</string>
+    <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..db7854b
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hu/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Nem sikerült létrehozni a mappát"</string>
+    <string name="query_error" msgid="1222448261663503501">"A dokumentumok lekérése nem sikerült"</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..c683f3e
--- /dev/null
+++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Չհաջողվեց ստեղծել թղթապանակը"</string>
+    <string name="query_error" msgid="1222448261663503501">"Փաստաթղթերին հարցում կատարելիս սխալ տեղի ունեցավ"</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-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml
new file mode 100644
index 0000000..d9f4475
--- /dev/null
+++ b/packages/DocumentsUI/res/values-in/strings.xml
@@ -0,0 +1,54 @@
+<?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">"Urutkan 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="create_error" msgid="3735649141335444215">"Gagal membuat folder"</string>
+    <string name="query_error" msgid="1222448261663503501">"Gagal mengirim kueri untuk 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Layanan penyimpanan"</string>
+    <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..28323b6
--- /dev/null
+++ b/packages/DocumentsUI/res/values-it/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Impossibile creare la cartella"</string>
+    <string name="query_error" msgid="1222448261663503501">"Impossibile chiedere documenti"</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..712c060
--- /dev/null
+++ b/packages/DocumentsUI/res/values-iw/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"יצירת התיקיה נכשלה"</string>
+    <string name="query_error" msgid="1222448261663503501">"שאילתת המסמכים נכשלה"</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-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml
new file mode 100644
index 0000000..996496d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ja/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"フォルダを作成できませんでした"</string>
+    <string name="query_error" msgid="1222448261663503501">"ドキュメントのクエリに失敗しました"</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-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..f3e1274
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"საქაღალდის შექმნა ვერ მოხერხდა"</string>
+    <string name="query_error" msgid="1222448261663503501">"დოკუმენტებზე მოთხოვნა ვერ გაიგზავნა"</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-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..80f3698
--- /dev/null
+++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"បាន​បរាជ័យ​ក្នុង​ការ​បង្កើត​ថត"</string>
+    <string name="query_error" msgid="1222448261663503501">"បាន​បរាជ័យ​ក្នុង​ការ​​ច្រោះ​ឯកសារ"</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-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml
new file mode 100644
index 0000000..2cd0d44
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ko/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"폴더를 만들지 못함"</string>
+    <string name="query_error" msgid="1222448261663503501">"문서를 검색하지 못했습니다."</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-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..9a6f32f
--- /dev/null
+++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"ການ​ສ້າງ​ໂຟນ​ເດີລົ້ມເຫຼວ"</string>
+    <string name="query_error" msgid="1222448261663503501">"ການຊອກຫາເອກະສານລົ້ມເຫຼວ"</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-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml
new file mode 100644
index 0000000..f861b99
--- /dev/null
+++ b/packages/DocumentsUI/res/values-lt/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Nepavyko sukurti aplanko"</string>
+    <string name="query_error" msgid="1222448261663503501">"Nepavyko pateikti dokumentų užklausų"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Saugyklos paslaugos"</string>
+    <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..651a59fe0d
--- /dev/null
+++ b/packages/DocumentsUI/res/values-lv/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Neizdevās izveidot mapi."</string>
+    <string name="query_error" msgid="1222448261663503501">"Neizdevās atrast vaicājumā norādītos dokumentus."</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Glabāšanas pakalpojumi"</string>
+    <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..22c9fcd
--- /dev/null
+++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Фолдер үүсгэж чадсангүй"</string>
+    <string name="query_error" msgid="1222448261663503501">"Документын хүсэлт гаргаж чадсангүй"</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-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..7e09c57
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Gagal membuat folder"</string>
+    <string name="query_error" msgid="1222448261663503501">"Gagal menanyakan 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Perkhidmatan storan"</string>
+    <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..8831bd8
--- /dev/null
+++ b/packages/DocumentsUI/res/values-nb/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Kunne ikke opprette mappen"</string>
+    <string name="query_error" msgid="1222448261663503501">"Kunne ikke undersøke dokumenter"</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..08862e8
--- /dev/null
+++ b/packages/DocumentsUI/res/values-nl/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Kan map niet maken"</string>
+    <string name="query_error" msgid="1222448261663503501">"Kan geen query\'s voor documenten verzenden"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Opslagservices"</string>
+    <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..f4e5582
--- /dev/null
+++ b/packages/DocumentsUI/res/values-pl/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Nie udało się utworzyć folderu"</string>
+    <string name="query_error" msgid="1222448261663503501">"Nie udało się pobrać listy dokumentów"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Usługi pamięci masowej"</string>
+    <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..f1be722
--- /dev/null
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
+    <string name="query_error" msgid="1222448261663503501">"Falha ao consultar os documentos"</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">"Ver 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..78fcaf8
--- /dev/null
+++ b/packages/DocumentsUI/res/values-pt/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Falha ao criar a pasta"</string>
+    <string name="query_error" msgid="1222448261663503501">"Falha ao consultar documentos"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Serviços 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 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..5fd44c8
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ro/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Eroare la crearea dosarului"</string>
+    <string name="query_error" msgid="1222448261663503501">"Interogarea referitoare la documente 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Servicii de stocare"</string>
+    <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..85fd70e0
--- /dev/null
+++ b/packages/DocumentsUI/res/values-ru/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Не удалось создать папку"</string>
+    <string name="query_error" msgid="1222448261663503501">"Не удалось отправить запрос"</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-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..4b5ebcd
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sk/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Priečinok sa nepodarilo vytvoriť"</string>
+    <string name="query_error" msgid="1222448261663503501">"Zoznam dokumentov sa nepodarilo načítať"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Služby úložiska"</string>
+    <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ť pokročilé 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..f984a0a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sl/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Mape ni bilo mogoče ustvariti"</string>
+    <string name="query_error" msgid="1222448261663503501">"Poizvedba za dokumente ni uspela"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Storitve shrambe"</string>
+    <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..eb0b197
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sr/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Директоријум није направљен"</string>
+    <string name="query_error" msgid="1222448261663503501">"Слање упита за документе није успело"</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-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml
new file mode 100644
index 0000000..7aa5c50
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sv/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Det gick inte att skapa mappen"</string>
+    <string name="query_error" msgid="1222448261663503501">"Det gick inte att söka efter dokument"</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..299fda7
--- /dev/null
+++ b/packages/DocumentsUI/res/values-sw/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Ilishindwa kuunda folda"</string>
+    <string name="query_error" msgid="1222448261663503501">"Ilishindwa kuhoji 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Huduma za hifadhi"</string>
+    <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-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml
new file mode 100644
index 0000000..6ac8810
--- /dev/null
+++ b/packages/DocumentsUI/res/values-th/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"การสร้างโฟลเดอร์ล้มเหลว"</string>
+    <string name="query_error" msgid="1222448261663503501">"การค้นหาเอกสารล้มเหลว"</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-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml
new file mode 100644
index 0000000..e0fd8c8
--- /dev/null
+++ b/packages/DocumentsUI/res/values-tl/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Hindi nagawa ang folder"</string>
+    <string name="query_error" msgid="1222448261663503501">"Hindi na-query ang mga 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>
+    <string name="root_type_service" msgid="2178854894416775409">"Mga serbisyo ng storage"</string>
+    <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..699a5cd
--- /dev/null
+++ b/packages/DocumentsUI/res/values-tr/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Klasör oluşturulamadı"</string>
+    <string name="query_error" msgid="1222448261663503501">"Dokümanlar sorgulanamadı"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Depolama hizmetleri"</string>
+    <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..f87b6a2
--- /dev/null
+++ b/packages/DocumentsUI/res/values-uk/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Помилка створення папки"</string>
+    <string name="query_error" msgid="1222448261663503501">"Помилка надсилання запиту на документи"</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..41e29fa
--- /dev/null
+++ b/packages/DocumentsUI/res/values-vi/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"Không thể tạo thư mục"</string>
+    <string name="query_error" msgid="1222448261663503501">"Không truy vấn được tài liệu"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Dịch vụ lưu trữ"</string>
+    <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..742cda7
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"无法创建文件夹"</string>
+    <string name="query_error" msgid="1222448261663503501">"无法查询文档"</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-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..67ed587
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"無法建立資料夾"</string>
+    <string name="query_error" msgid="1222448261663503501">"無法查詢文件"</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-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..269583a
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml
@@ -0,0 +1,54 @@
+<?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="create_error" msgid="3735649141335444215">"無法建立資料夾"</string>
+    <string name="query_error" msgid="1222448261663503501">"無法查詢文件"</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-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml
new file mode 100644
index 0000000..bedd2cdf
--- /dev/null
+++ b/packages/DocumentsUI/res/values-zu/strings.xml
@@ -0,0 +1,54 @@
+<?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">"Ngedethi yokuguqula"</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="create_error" msgid="3735649141335444215">"Yehlulekile ukudala ifolda"</string>
+    <string name="query_error" msgid="1222448261663503501">"Ihlulekile ukubuza amadokhumenti"</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>
+    <string name="root_type_service" msgid="2178854894416775409">"Amasevisi wesitoreji"</string>
+    <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/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
index 1f7386c..71fd100 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
@@ -22,7 +22,6 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.provider.DocumentsContract.Document;
-import android.util.Log;
 
 import com.google.android.collect.Maps;
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index 05766f5..82c3048 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -54,8 +54,6 @@
 
 import libcore.io.IoUtils;
 
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
index 9d70c51..ce98db2 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SaveFragment.java
@@ -23,7 +23,6 @@
 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;
diff --git a/packages/ExternalStorageProvider/res/values-af/strings.xml b/packages/ExternalStorageProvider/res/values-af/strings.xml
new file mode 100644
index 0000000..1de881d
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-af/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">"Eksterne berging"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interne berging"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+</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..230fb06
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-am/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-ar/strings.xml b/packages/ExternalStorageProvider/res/values-ar/strings.xml
new file mode 100644
index 0000000..b20a056
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ar/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-az-rAZ/strings.xml b/packages/ExternalStorageProvider/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..a6a79ca8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-az-rAZ/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-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..f5dce31
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-bg/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-ca/strings.xml b/packages/ExternalStorageProvider/res/values-ca/strings.xml
new file mode 100644
index 0000000..15e9d46
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ca/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">"Emmagatzematge extern"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Emmagatzematge intern"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+</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..b68a928
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-cs/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">"Externí úložiště"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interní úložiště"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+</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..a9ecb69
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-da/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">"Ekstern lagring"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenter"</string>
+</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..318634a
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-de/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">"Externer Speicher"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interner Speicher"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumente"</string>
+</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..b3aa792
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-el/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-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..e7e38b5
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-es-rUS/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">"Almacenamiento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+</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..e7e38b5
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-es/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">"Almacenamiento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Almacenamiento interno"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+</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..6824e9d
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-et-rEE/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">"Väline talletusruum"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Sisemine salvestusruum"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumendid"</string>
+</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..8471fc7
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fa/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-fi/strings.xml b/packages/ExternalStorageProvider/res/values-fi/strings.xml
new file mode 100644
index 0000000..9d1fbaa
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fi/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">"Ulkoinen tallennustila"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Sisäinen tallennustila"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumentit"</string>
+</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..b3fdd48
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fr-rCA/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">"Stockage externe"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+</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..b3fdd48
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-fr/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">"Stockage externe"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Mémoire de stockage interne"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documents"</string>
+</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..1227bd4
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-hi/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-hr/strings.xml b/packages/ExternalStorageProvider/res/values-hr/strings.xml
new file mode 100644
index 0000000..a74f8e8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-hr/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">"Vanjska pohrana"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Unutarnja pohrana"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+</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..3f72b41
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-hu/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">"Külső tárhely"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Belső tárhely"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumentumok"</string>
+</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..42acde7
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-in/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">"Penyimpanan Eksternal"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Penyimpanan internal"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumen"</string>
+</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..957b5ff
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-it/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">"Archivio esterno"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Memoria interna"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documenti"</string>
+</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..775506a
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-iw/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-ja/strings.xml b/packages/ExternalStorageProvider/res/values-ja/strings.xml
new file mode 100644
index 0000000..188fca2
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ja/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-ka-rGE/strings.xml b/packages/ExternalStorageProvider/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..cc04860
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ka-rGE/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-km-rKH/strings.xml b/packages/ExternalStorageProvider/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..9cf76d4
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-km-rKH/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-ko/strings.xml b/packages/ExternalStorageProvider/res/values-ko/strings.xml
new file mode 100644
index 0000000..849d37e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ko/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-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..240ea89
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-lt/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">"Išorinė atmintinė"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Vidinė atmintinė"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumentai"</string>
+</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..d308fe8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-lv/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">"Ārējā krātuve"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Iekšējā atmiņa"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+</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..3d7b7f7
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-mn-rMN/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-ms-rMY/strings.xml b/packages/ExternalStorageProvider/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..cb4d736
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ms-rMY/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">"Storan Luaran"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Storan dalaman"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumen"</string>
+</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..a9ecb69
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-nb/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">"Ekstern lagring"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenter"</string>
+</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..bde6166
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-nl/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">"Externe opslag"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interne opslag"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documenten"</string>
+</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..6c5e7d7
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-pl/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">"Pamięć zewnętrzna"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Pamięć wewnętrzna"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+</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..77c89b8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-pt-rPT/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">"Armazenamento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+</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..77c89b8
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-pt/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">"Armazenamento externo"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Armazenamento interno"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documentos"</string>
+</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..abd0b98
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ro/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">"Stocare externă"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Stocare internă"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Documente"</string>
+</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..b6c10951
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-ru/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-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..9be7b79
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sk/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">"Externý ukladací priestor"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Interné úložisko"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenty"</string>
+</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..6ffa698
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sl/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">"Zunanja shramba"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Notranja shramba"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokumenti"</string>
+</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..54238a4
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sr/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-sv/strings.xml b/packages/ExternalStorageProvider/res/values-sv/strings.xml
new file mode 100644
index 0000000..6eac11e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sv/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">"Extern lagring"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Intern lagring"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokument"</string>
+</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..0d0e483
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-sw/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">"Hifadhi ya Nje"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Hifadhi ya ndani"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Hati"</string>
+</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..796635e
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-th/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-tl/strings.xml b/packages/ExternalStorageProvider/res/values-tl/strings.xml
new file mode 100644
index 0000000..529cdc2
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-tl/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">"Mga Dokumento"</string>
+</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..d6bd52a
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-tr/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">"Harici Depolama"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Dahili depolama"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Dokümanlar"</string>
+</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..b8206e0
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-uk/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-vi/strings.xml b/packages/ExternalStorageProvider/res/values-vi/strings.xml
new file mode 100644
index 0000000..b171c93
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-vi/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">"Bộ nhớ ngoài"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Bộ nhớ trong"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Tài liệu"</string>
+</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..7df77dd
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zh-rCN/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-zh-rHK/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..62d8afb
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zh-rHK/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-zh-rTW/strings.xml b/packages/ExternalStorageProvider/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..62d8afb
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zh-rTW/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-zu/strings.xml b/packages/ExternalStorageProvider/res/values-zu/strings.xml
new file mode 100644
index 0000000..4a0a845
--- /dev/null
+++ b/packages/ExternalStorageProvider/res/values-zu/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">"Isitoreji sangaphandle"</string>
+    <string name="root_internal_storage" msgid="827844243068584127">"Isitoreji sangaphakathi"</string>
+    <string name="root_documents" msgid="4051252304075469250">"Amadokhumenti"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-af/strings.xml b/packages/FusedLocation/res/values-af/strings.xml
new file mode 100644
index 0000000..a321abe
--- /dev/null
+++ b/packages/FusedLocation/res/values-af/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Saamgesmelte ligging"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-am/strings.xml b/packages/FusedLocation/res/values-am/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-am/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ar/strings.xml b/packages/FusedLocation/res/values-ar/strings.xml
new file mode 100644
index 0000000..dfbcf7a
--- /dev/null
+++ b/packages/FusedLocation/res/values-ar/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"الموقع المدمج"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-bg/strings.xml b/packages/FusedLocation/res/values-bg/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-bg/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ca/strings.xml b/packages/FusedLocation/res/values-ca/strings.xml
new file mode 100644
index 0000000..9dae512
--- /dev/null
+++ b/packages/FusedLocation/res/values-ca/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Ubicació combinada"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-cs/strings.xml b/packages/FusedLocation/res/values-cs/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-cs/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-da/strings.xml b/packages/FusedLocation/res/values-da/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-da/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-de/strings.xml b/packages/FusedLocation/res/values-de/strings.xml
new file mode 100644
index 0000000..d7e5faa
--- /dev/null
+++ b/packages/FusedLocation/res/values-de/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Kombinierte Standortbestimmung"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-el/strings.xml b/packages/FusedLocation/res/values-el/strings.xml
new file mode 100644
index 0000000..1243b21
--- /dev/null
+++ b/packages/FusedLocation/res/values-el/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Ενοποιημένη τοποθεσία"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-en-rGB/strings.xml b/packages/FusedLocation/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-en-rGB/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-en-rIN/strings.xml b/packages/FusedLocation/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-en-rIN/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-es-rUS/strings.xml b/packages/FusedLocation/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..ec95314
--- /dev/null
+++ b/packages/FusedLocation/res/values-es-rUS/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Ubicación combinada"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-es/strings.xml b/packages/FusedLocation/res/values-es/strings.xml
new file mode 100644
index 0000000..ec95314
--- /dev/null
+++ b/packages/FusedLocation/res/values-es/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Ubicación combinada"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-et-rEE/strings.xml b/packages/FusedLocation/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..fcf4ef7
--- /dev/null
+++ b/packages/FusedLocation/res/values-et-rEE/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Liidetud asukoht"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-fa/strings.xml b/packages/FusedLocation/res/values-fa/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-fa/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-fi/strings.xml b/packages/FusedLocation/res/values-fi/strings.xml
new file mode 100644
index 0000000..2d308b3
--- /dev/null
+++ b/packages/FusedLocation/res/values-fi/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Yhdistetty sijainti"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-fr-rCA/strings.xml b/packages/FusedLocation/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-fr-rCA/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-fr/strings.xml b/packages/FusedLocation/res/values-fr/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-fr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-hi/strings.xml b/packages/FusedLocation/res/values-hi/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-hi/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-hr/strings.xml b/packages/FusedLocation/res/values-hr/strings.xml
new file mode 100644
index 0000000..b2a2cc9
--- /dev/null
+++ b/packages/FusedLocation/res/values-hr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Lokacija iz kombiniranih izvora"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-hu/strings.xml b/packages/FusedLocation/res/values-hu/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-hu/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-hy-rAM/strings.xml b/packages/FusedLocation/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-hy-rAM/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-in/strings.xml b/packages/FusedLocation/res/values-in/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-in/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-it/strings.xml b/packages/FusedLocation/res/values-it/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-it/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-iw/strings.xml b/packages/FusedLocation/res/values-iw/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-iw/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ja/strings.xml b/packages/FusedLocation/res/values-ja/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-ja/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ka-rGE/strings.xml b/packages/FusedLocation/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-ka-rGE/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-km-rKH/strings.xml b/packages/FusedLocation/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..649e4f7
--- /dev/null
+++ b/packages/FusedLocation/res/values-km-rKH/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"ភ្ជាប់​ទីតាំង"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ko/strings.xml b/packages/FusedLocation/res/values-ko/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-ko/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-lo-rLA/strings.xml b/packages/FusedLocation/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-lo-rLA/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-lt/strings.xml b/packages/FusedLocation/res/values-lt/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-lt/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-lv/strings.xml b/packages/FusedLocation/res/values-lv/strings.xml
new file mode 100644
index 0000000..8c40cb2
--- /dev/null
+++ b/packages/FusedLocation/res/values-lv/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Apvienota atrašanās vieta"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-mn-rMN/strings.xml b/packages/FusedLocation/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..8055ca8
--- /dev/null
+++ b/packages/FusedLocation/res/values-mn-rMN/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Нэгдмэл байршил"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ms-rMY/strings.xml b/packages/FusedLocation/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..d345cb8
--- /dev/null
+++ b/packages/FusedLocation/res/values-ms-rMY/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Lokasi Terlakur"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-nb/strings.xml b/packages/FusedLocation/res/values-nb/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-nb/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-nl/strings.xml b/packages/FusedLocation/res/values-nl/strings.xml
new file mode 100644
index 0000000..b3003c8
--- /dev/null
+++ b/packages/FusedLocation/res/values-nl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Samengestelde locatie"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-pl/strings.xml b/packages/FusedLocation/res/values-pl/strings.xml
new file mode 100644
index 0000000..4637034
--- /dev/null
+++ b/packages/FusedLocation/res/values-pl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Uśredniona lokalizacja"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-pt-rPT/strings.xml b/packages/FusedLocation/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..2707fa9
--- /dev/null
+++ b/packages/FusedLocation/res/values-pt-rPT/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Localização Fundida"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-pt/strings.xml b/packages/FusedLocation/res/values-pt/strings.xml
new file mode 100644
index 0000000..4f8277a
--- /dev/null
+++ b/packages/FusedLocation/res/values-pt/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Localização combinada"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ro/strings.xml b/packages/FusedLocation/res/values-ro/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-ro/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-ru/strings.xml b/packages/FusedLocation/res/values-ru/strings.xml
new file mode 100644
index 0000000..40d9e6f
--- /dev/null
+++ b/packages/FusedLocation/res/values-ru/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Геоданные из нескольких источников"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-sk/strings.xml b/packages/FusedLocation/res/values-sk/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-sk/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-sl/strings.xml b/packages/FusedLocation/res/values-sl/strings.xml
new file mode 100644
index 0000000..928c50b
--- /dev/null
+++ b/packages/FusedLocation/res/values-sl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Kombinirana lokacija"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-sr/strings.xml b/packages/FusedLocation/res/values-sr/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-sr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-sv/strings.xml b/packages/FusedLocation/res/values-sv/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-sv/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-sw/strings.xml b/packages/FusedLocation/res/values-sw/strings.xml
new file mode 100644
index 0000000..60c235e
--- /dev/null
+++ b/packages/FusedLocation/res/values-sw/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Eneo Hakika"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-th/strings.xml b/packages/FusedLocation/res/values-th/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-th/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-tl/strings.xml b/packages/FusedLocation/res/values-tl/strings.xml
new file mode 100644
index 0000000..94a2507
--- /dev/null
+++ b/packages/FusedLocation/res/values-tl/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Naka-fuse na Lokasyon"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-tr/strings.xml b/packages/FusedLocation/res/values-tr/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-tr/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-uk/strings.xml b/packages/FusedLocation/res/values-uk/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-uk/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-vi/strings.xml b/packages/FusedLocation/res/values-vi/strings.xml
new file mode 100644
index 0000000..e0e83a8
--- /dev/null
+++ b/packages/FusedLocation/res/values-vi/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Vị trí được hợp nhất"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-zh-rCN/strings.xml b/packages/FusedLocation/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..e6d7bc1
--- /dev/null
+++ b/packages/FusedLocation/res/values-zh-rCN/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"一体化位置信息"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-zh-rHK/strings.xml b/packages/FusedLocation/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-zh-rHK/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-zh-rTW/strings.xml b/packages/FusedLocation/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..0d2cccc
--- /dev/null
+++ b/packages/FusedLocation/res/values-zh-rTW/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Fused Location"</string>
+</resources>
diff --git a/packages/FusedLocation/res/values-zu/strings.xml b/packages/FusedLocation/res/values-zu/strings.xml
new file mode 100644
index 0000000..62d4359
--- /dev/null
+++ b/packages/FusedLocation/res/values-zu/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="5379477904423203699">"Indawo ehlanganisiwe"</string>
+</resources>
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java
index 509c010..12966cf 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationService.java
@@ -16,9 +16,6 @@
 
 package com.android.location.fused;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
 import android.app.Service;
 import android.content.Intent;
 import android.os.IBinder;
diff --git a/packages/InputDevices/res/values-af/strings.xml b/packages/InputDevices/res/values-af/strings.xml
new file mode 100644
index 0000000..13fcbb4
--- /dev/null
+++ b/packages/InputDevices/res/values-af/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Invoertoestelle"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-sleutelbord"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engels (VK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Engels (VS)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Engels (VS), internasionale styl"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Engels (VS), Colemak-styl"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Engels (VS), Dvorak-styl"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Duits"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Frans"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Frans (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russies"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russies, Mac-styl"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spaans"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Switserse Frans"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Switserse Duits"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgies"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgaars"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiaans"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Deens"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Noors"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Sweeds"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Fins"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroaties"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tsjeggies"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estnies"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hongaars"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Yslands"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasiliaans"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugees"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slowaaks"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Sloweens"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turks"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Oekraïens"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-am/strings.xml b/packages/InputDevices/res/values-am/strings.xml
new file mode 100644
index 0000000..d475772
--- /dev/null
+++ b/packages/InputDevices/res/values-am/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"የግቤት መሣሪያዎች"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"የAndroid የቁልፍ ሰሌዳ"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"እንግሊዝኛ (ዩኬ)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"እንግሊዘኛ (ዩ.ኤስ.)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"እንግሊዘኛ (ዩ. ኤስ.)፣ አለም አቀፍ ቅጥ"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"እንግሊዘኛ (ዩ. ኤስ.)፣ የኮልማርክ ቅጥ"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"እንግሊዘኛ (ዩ. ኤስ.)፣ የድቮራክ ቅጥ"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"ጀርመን"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"ፈረንሳይኛ"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"ፈረንሳይኛ (ካናዳ)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ሩስያኛ"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ሩስያኛ፣ Mac ቅጥ"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"ስፓኒሽ"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"የስዊዝ ፈረንሳይኛ"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"የስዊዝ ጀርመን"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"ቤልጂየም"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"ቡልጋሪያ"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"ጣሊያንኛ"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"ዴኒሽ"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ኖርዌጂያ"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"ስዊድንኛ"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ፊኒሽ"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"ክሮሽያ"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"ቼክ"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ኤስቶኒያ"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ሀንጋሪ"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"አይስላንድ"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ብራዚል"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"ፖርቹጋል"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"ስሎቫክ"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"ስሎቫኒያ"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ቱርክኛ"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ዩክሬን"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ar/strings.xml b/packages/InputDevices/res/values-ar/strings.xml
new file mode 100644
index 0000000..903d978
--- /dev/null
+++ b/packages/InputDevices/res/values-ar/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"أجهزة إدخال بيانات"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"‏لوحة مفاتيح Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"الإنجليزية (المملكة المتحدة)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"الإنجليزية (الولايات المتحدة)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"الإنجليزية (الولايات المتحدة)، النمط الدولي"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"‏الإنجليزية (الولايات المتحدة)، نمط Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"‏الإنجليزية (الولايات المتحدة)، نمط Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"الألمانية"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"الفرنسية"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"الفرنسية (كندا)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"الروسية"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"‏الروسية، نمط Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"الإسبانية"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"الفرنسية السويسرية"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"الألمانية السويسرية"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"البلجيكية"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"البلغارية"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"الإيطالية"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"الدانماركية"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"النرويجية"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"السويدية"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"الفنلندية"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"الكرواتية"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"التشيكية"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"الإستونية"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"المجرية"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"الأيسلندية"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"البرازيلية"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"البرتغالية"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"السلوفاكية"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"السلوفينية"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"التركية"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"الأوكرانية"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-bg/strings.xml b/packages/InputDevices/res/values-bg/strings.xml
new file mode 100644
index 0000000..0c413a4
--- /dev/null
+++ b/packages/InputDevices/res/values-bg/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Входни устройства"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Клавиатура на Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"английски (Великобритания)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"английски (САЩ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"англ. (САЩ) – стил „Mеждународна“"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"английски (САЩ) – стил „Коулмак“"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"английски (САЩ) – стил „Дворак“"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"немски"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"френски"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"френски (Канада)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"руски"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"руски – стил „Mac“"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"испански"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"швейцарски френски"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"швейцарски немски"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"белгийски"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"български"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"италиански"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"датски"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"норвежки"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"шведски"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"финландски"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"хърватски"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"чешки"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"естонски"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"унгарски"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"исландски"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"португалски (Бразилия)"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"португалски"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"словашки"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словенски"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турски"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"украински"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ca/strings.xml b/packages/InputDevices/res/values-ca/strings.xml
new file mode 100644
index 0000000..2021b8f
--- /dev/null
+++ b/packages/InputDevices/res/values-ca/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Dispositius d’entrada"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Teclat Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Anglès (RU)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Anglès (EUA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Anglès (EUA), estil internacional"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Anglès (EUA), estil Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Anglès (EUA), estil Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Alemany"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francès"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francès (Canadà)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Rus"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Rus, estil Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Espanyol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francès suís"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Alemany suís"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belga"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Búlgar"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italià"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danès"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Noruec"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Suec"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finès"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croat"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Txec"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonià"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hongarès"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandès"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasiler"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguès"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Eslovac"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Eslovè"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turc"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraïnès"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-cs/strings.xml b/packages/InputDevices/res/values-cs/strings.xml
new file mode 100644
index 0000000..33b420e
--- /dev/null
+++ b/packages/InputDevices/res/values-cs/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Vstupní zařízení"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Klávesnice Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"anglické (Spojené království)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"anglické (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"anglické (USA), mezinárodní"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"anglické (USA), styl Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"anglické (USA), styl Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"německé"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"francouzské"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francouzské (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruské"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruské, styl Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španělské"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"švýcarské (francouzština)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"švýcarské (němčina)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgické"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bulharské"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"italské"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"dánské"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norské"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"švédské"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finské"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"chorvatské"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"české"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estonské"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"maďarské"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandské"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazilské"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalské"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovenské"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovinské"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turecké"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinské"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-da/strings.xml b/packages/InputDevices/res/values-da/strings.xml
new file mode 100644
index 0000000..fc07db2
--- /dev/null
+++ b/packages/InputDevices/res/values-da/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Inputenheder"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-tastatur"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engelsk (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Engelsk (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Engelsk (USA), international stil"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Engelsk (USA), Colemak-stil"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Engelsk (USA), Dvorak-stil"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Tysk"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Fransk"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Fransk (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russisk"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russisk, Mac-stil"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spansk"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Schweizisk fransk"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Schweizertysk"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgisk"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarsk"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiensk"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Dansk"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norsk"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Svensk"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finsk"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroatisk"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tjekkisk"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estisk"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ungarsk"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandsk"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasiliansk"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugisisk"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovakisk"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovensk"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Tyrkisk"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainsk"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-de/strings.xml b/packages/InputDevices/res/values-de/strings.xml
new file mode 100644
index 0000000..b5c3b50
--- /dev/null
+++ b/packages/InputDevices/res/values-de/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Eingabegeräte"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-Tastatur"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Englisch (Großbritannien)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Englisch (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Englisch (USA), international"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Englisch (USA), Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Englisch (USA), Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Deutsch"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Französisch"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Französisch (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russisch"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russisch, Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanisch"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Schweizer Französisch"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Schweizerdeutsch"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgisch"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarisch"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italienisch"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Dänisch"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegisch"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Schwedisch"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnisch"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroatisch"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tschechisch"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estnisch"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ungarisch"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Isländisch"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasilianisch"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugiesisch"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slowakisch"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slowenisch"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Türkisch"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainisch"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-el/strings.xml b/packages/InputDevices/res/values-el/strings.xml
new file mode 100644
index 0000000..f5d57a0
--- /dev/null
+++ b/packages/InputDevices/res/values-el/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Συσκευές εισόδου"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Πληκτρολόγιο Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Αγγλικά (ΗΒ)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Αγγλικά (ΗΠΑ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Αγγλικά (ΗΠΑ), τύπου International"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Αγγλικά (ΗΠΑ), τύπου Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Αγγλικά (ΗΠΑ), τύπου Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Γερμανικά"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Γαλλικά"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Γαλλικά (Καναδά)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Ρωσικά"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Ρωσικά, τύπου Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Ισπανικά"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Γαλλικά Ελβετίας"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Γερμανικά Ελβετίας"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Βελγικά"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Βουλγαρικά"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Ιταλικά"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Δανικά"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Νορβηγικά"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Σουηδικά"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Φινλανδικά"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Κροατικά"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Τσεχικά"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Εσθονικά"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ουγγρικά"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Ισλανδικά"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Βραζιλιάνικα"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Πορτογαλικά"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Σλοβακικά"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Σλοβενικά"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Τουρκικά"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ουκρανικά"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-en-rGB/strings.xml b/packages/InputDevices/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..2d794a6
--- /dev/null
+++ b/packages/InputDevices/res/values-en-rGB/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android keyboard"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"English (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"English (US)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), International style"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), Colemak style"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), Dvorak style"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russian"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russian, Mac style"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Swiss French"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Swiss German"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgian"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarian"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croatian"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonian"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazilian"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovak"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainian"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-en-rIN/strings.xml b/packages/InputDevices/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..2d794a6
--- /dev/null
+++ b/packages/InputDevices/res/values-en-rIN/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android keyboard"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"English (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"English (US)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"English (US), International style"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"English (US), Colemak style"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"English (US), Dvorak style"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russian"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russian, Mac style"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Swiss French"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Swiss German"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgian"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarian"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croatian"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonian"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazilian"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovak"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainian"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-es-rUS/strings.xml b/packages/InputDevices/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..2d61b80
--- /dev/null
+++ b/packages/InputDevices/res/values-es-rUS/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Dispositivos de entrada"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Teclado de Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglés (Reino Unido)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglés (EE. UU.)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglés (EE. UU.), internacional"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglés (EE. UU.), Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglés (EE. UU.), Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Alemán"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francés"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francés (Canadá)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Ruso"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Ruso, Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Español"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francés de Suiza"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Alemán de Suiza"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belga"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Búlgaro"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiano"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danés"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Noruego"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Sueco"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandés"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croata"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Checo"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonio"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Húngaro"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandés"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasileño"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugués"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Eslovaco"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Esloveno"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turco"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraniano"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-es/strings.xml b/packages/InputDevices/res/values-es/strings.xml
new file mode 100644
index 0000000..82ea4d6
--- /dev/null
+++ b/packages/InputDevices/res/values-es/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Dispositivos de entrada"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Teclado de Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglés (Reino Unido)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglés (EE.UU.)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglés (EE.UU.), estilo internacional"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglés (EE.UU.), estilo Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglés (EE.UU.), estilo Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Alemán"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francés"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francés (Canadá)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Ruso"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Ruso, estilo Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Español"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francés de Suiza"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Alemán suizo"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belga"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Búlgaro"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiano"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danés"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Noruego"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Sueco"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandés"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croata"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Checo"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonio"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Húngaro"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandés"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasileño"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugués"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Eslovaco"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Esloveno"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turco"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraniano"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-et-rEE/strings.xml b/packages/InputDevices/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..5b4fa3b
--- /dev/null
+++ b/packages/InputDevices/res/values-et-rEE/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Sisendseadmed"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Androidi klaviatuur"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglise (Ühendkuningriik)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglise (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglise (USA), rahvusvaheline stiil"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglise (USA), Colemaki stiil"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglise (USA), Dvoraki stiil"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Saksa"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Prantsuse"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Prantsuse (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Vene"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Vene, Maci stiil"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Hispaania"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Šveitsi prantsuse"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Šveitsisaksa"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgia"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgaaria"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Itaalia"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Taani"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norra"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Rootsi"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Soome"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Horvaatia"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tšehhi"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Eesti"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ungari"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandi"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasiilia"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugali"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovaki"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Sloveenia"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Türgi"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukraina"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-fa/strings.xml b/packages/InputDevices/res/values-fa/strings.xml
new file mode 100644
index 0000000..06c7f3a
--- /dev/null
+++ b/packages/InputDevices/res/values-fa/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"‏صفحه‌کلید Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"انگلیسی (بریتانیا)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"انگلیسی (امریکا)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"انگلیسی (ایالات متحده)، سبک بین‌المللی"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"‏انگلیسی (ایالات متحده)، سبک Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"‏انگلیسی (ایالات متحده)، سبک Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"آلمانی"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"فرانسوی"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"فرانسوی (کانادا)‏"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"روسی"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"‏روسی، سبک Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"اسپانیایی"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"فرانسوی سوئیس"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"آلمانی سوئیسی"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"بلژیکی"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"بلغاری"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"ایتالیایی"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"دانمارکی"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"نروژی"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"سوئدی"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"فنلاندی"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"کرواسی"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"چک"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"استونیایی"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"مجارستانی"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ایسلندی"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"برزیلی"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"پرتغالی"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"اسلوواکی"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"اسلوونیایی"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ترکی"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"اوکراینی"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-fi/strings.xml b/packages/InputDevices/res/values-fi/strings.xml
new file mode 100644
index 0000000..428eb30
--- /dev/null
+++ b/packages/InputDevices/res/values-fi/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Syöttölaitteet"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-näppäimistö"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"englanti (Iso-Britannia)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"englanti (Yhdysvallat)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"englanti (Yhdysvallat), kansainvälinen"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"englanti (Yhdysvallat), Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"englanti (Yhdysvallat), Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"saksa"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"ranska"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"ranska (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"venäjä"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"venäjä, Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"espanja"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"sveitsinranska"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"sveitsinsaksa"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgialainen"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bulgaria"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"italia"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"tanska"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norja"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"ruotsi"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"suomi"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"kroaatti"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"tšekki"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"viro"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"unkari"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islanti"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brasilialainen"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugali"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovakki"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"sloveeni"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turkki"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukraina"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-fr-rCA/strings.xml b/packages/InputDevices/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..c947634
--- /dev/null
+++ b/packages/InputDevices/res/values-fr-rCA/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Périphériques d\'entrée"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Clavier Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Anglais (britannique)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Anglais (États-Unis)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Anglais (États-Unis), international"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Anglais (États-Unis), type Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Anglais (États-Unis), type Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Allemand"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Français"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Français (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russe"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russe, type Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Espagnol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Français (Suisse)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Allemand (Suisse)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belge"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgare"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italien"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danois"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norvégien"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Suédois"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnois"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croate"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tchèque"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonien"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hongrois"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandais"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brésilien"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugais"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovaque"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovène"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turc"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainien"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-fr/strings.xml b/packages/InputDevices/res/values-fr/strings.xml
new file mode 100644
index 0000000..4ad4ffa
--- /dev/null
+++ b/packages/InputDevices/res/values-fr/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Clavier Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Anglais (Royaume-Uni)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Anglais (États-Unis)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Anglais (États-Unis), international"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Anglais (États-Unis), type Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Anglais (États-Unis), type Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Allemand"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Français"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Français (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russe"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russe, type Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Espagnol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Français (Suisse)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Allemand (Suisse)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belge"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgare"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italien"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danois"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norvégien"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Suédois"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnois"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croate"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tchèque"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonien"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hongrois"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandais"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brésilien"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugais"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovaque"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovène"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turc"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainien"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-hi/strings.xml b/packages/InputDevices/res/values-hi/strings.xml
new file mode 100644
index 0000000..8e1864e
--- /dev/null
+++ b/packages/InputDevices/res/values-hi/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"इनपुट उपकरण"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android कीबोर्ड"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"अंग्रेज़ी (यूके)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"अंग्रेज़ी (यूएस)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"अंग्रेज़ी (यूएस), अंतर्राष्ट्रीय शैली"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"अंग्रेज़ी (यूएस), कोलमैक शैली"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"अंग्रेज़ी (यूएस), ड्वोरक शैली"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"जर्मन"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"फ़्रांसीसी"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"फ़्रांसीसी (कनाडा)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"रूसी"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"रूसी, मैक शैली"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"स्पैनिश"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"स्विस फ़्रांसीसी"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"स्विस जर्मन"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"बेल्जियाई"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"बुल्‍गारियाई"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"इतालवी"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"डैनिश"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"नार्वेजियाई"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"स्वीडिश"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"फ़िनिश"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"क्रोएशियाई"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"चेक"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"एस्टोनियाई"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"हंगेरियाई"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"आइसलैंडिक"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ब्राज़ीलियाई"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"पुर्तगाली"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"स्लोवाक"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"स्लोवेनियाई"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"तुर्की"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"यूक्रेनियाई"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-hr/strings.xml b/packages/InputDevices/res/values-hr/strings.xml
new file mode 100644
index 0000000..6217bf0
--- /dev/null
+++ b/packages/InputDevices/res/values-hr/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Uređaji za unos"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android tipkovnica"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"engleska (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"engleska (SAD)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"engleska (SAD), međunarodna"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"engleska (SAD), Colemakov raspored"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"engleska (SAD), Dvorakov raspored"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"njemačka"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"francuska"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francuska (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruska"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruska, raspored Maca"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španjolska"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"švicarsko-francuska"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"švicarsko-njemačka"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgijska"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bugarska"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"talijanska"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"danska"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norveška"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"švedska"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finska"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"hrvatska"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"češka"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estonska"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"mađarska"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandska"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazilska"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalska"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovačka"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenska"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turska"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinska"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-hu/strings.xml b/packages/InputDevices/res/values-hu/strings.xml
new file mode 100644
index 0000000..0cdbfb2
--- /dev/null
+++ b/packages/InputDevices/res/values-hu/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Beviteli eszközök"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-billentyűzet"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"angol (Egyesült Királyság)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"angol (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"angol (USA), nemzetközi stílus"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"angol (USA), Colemak-stílus"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"angol (USA), Dvorak-stílus"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"német"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"francia"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francia (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"orosz"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"orosz, Mac-stílus"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"spanyol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"svájci francia"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"svájci német"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belga"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bolgár"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"olasz"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"dán"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norvég"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"svéd"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finn"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"horvát"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"cseh"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"észt"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"magyar"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"izlandi"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazil"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugál"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"szlovák"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"szlovén"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"török"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrán"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-hy-rAM/strings.xml b/packages/InputDevices/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..bc5bbfc
--- /dev/null
+++ b/packages/InputDevices/res/values-hy-rAM/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Մուտքագրման ​​սարքեր"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android ստեղնաշար"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Անգլերեն (ՄԲ)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Անգլերեն (ԱՄՆ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Անգլերեն (ԱՄՆ), միջազգային տեսակ"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Անգլերեն (ԱՄՆ), Colemak տեսակ"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Անգլերեն (ԱՄՆ), Dvorak տեսակ"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Գերմաներեն"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Ֆրանսերեն"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Ֆրանսերեն (Կանադա)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Ռուսերեն"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Ռուսերեն, Mac տեսակ"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Իսպաներեն"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Շվեյցարական ֆրանսերեն"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Շվեյցարական գերմաներեն"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Բելգիական"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Բուլղարերեն"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Իտալերեն"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Դանիերեն"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Նորվեգերեն"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Շվեդերեն"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Ֆիններեն"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Խորվաթերեն"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Չեխերեն"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Էստոներեն"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Հունգարերեն"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Իսլանդերեն"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Բրազիլերեն"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Պորտուգալերեն"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Սլովակերեն"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Սլովեներեն"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Թուրքերեն"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ուկրաիներեն"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-in/strings.xml b/packages/InputDevices/res/values-in/strings.xml
new file mode 100644
index 0000000..11e2dd0a
--- /dev/null
+++ b/packages/InputDevices/res/values-in/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Perangkat Masukan"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Keyboard Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inggris (Britania)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inggris (Amerika)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inggris (AS), gaya Internasional"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inggris (AS), gaya Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inggris (AS), gaya Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Jerman"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Prancis"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Prancis (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Rusia"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Rusia, gaya Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanyol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Prancis Swiss"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Jerman Swiss"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgia"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgaria"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italia"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Denmark"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegia"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedia"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandia"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroasia"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Cheska"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonia"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungaria"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandia"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasil"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugis"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slowakia"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenia"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turki"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukraina"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-it/strings.xml b/packages/InputDevices/res/values-it/strings.xml
new file mode 100644
index 0000000..334318e
--- /dev/null
+++ b/packages/InputDevices/res/values-it/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Dispositivi di immissione"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Tastiera Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglese (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglese (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglese (USA), stile internazionale"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglese (USA), stile Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglese (USA), stile Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Tedesco"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francese"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francese (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russo"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russo, stile Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spagnolo"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francese svizzero"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Tedesco svizzero"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belga"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgaro"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiano"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danese"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norvegese"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Svedese"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandese"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croato"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Ceco"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estone"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ungherese"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandese"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasiliano"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portoghese"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovacco"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Sloveno"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turco"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraino"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-iw/strings.xml b/packages/InputDevices/res/values-iw/strings.xml
new file mode 100644
index 0000000..a989391
--- /dev/null
+++ b/packages/InputDevices/res/values-iw/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"התקני קלט"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"‏מקלדת Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"אנגלית (בריטניה)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"אנגלית (ארה\"ב)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"אנגלית (ארה\"ב), סגנון בינ\"ל"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"‏אנגלית (ארה\"ב), סגנון Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"‏אנגלית (ארה\"ב), סגנון Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"גרמנית"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"צרפתית"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"צרפתית (קנדה)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"רוסית"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"‏רוסית, סגנון Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"ספרדית"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"צרפתית שוויצרית"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"גרמנית שוויצרית"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"בלגית"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"בולגרית"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"איטלקית"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"דנית"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"נורווגית"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"שוודית"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"פינית"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"קרואטית"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"צ\'כית"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"אסטונית"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"הונגרית"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"איסלנדית"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ברזילאית"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"פורטוגזית"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"סלובקית"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"סלובנית"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"טורקית"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"אוקראינית"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ja/strings.xml b/packages/InputDevices/res/values-ja/strings.xml
new file mode 100644
index 0000000..950b727
--- /dev/null
+++ b/packages/InputDevices/res/values-ja/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Androidキーボード"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"英語(イギリス)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"英語(アメリカ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"英語(アメリカ)、インターナショナル配列"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"英語(アメリカ)、Colemak配列"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"英語(アメリカ)、Dvorak配列"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"ドイツ語"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"フランス語"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"フランス語(カナダ)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ロシア語"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ロシア語(Mac配列)"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"スペイン語"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"フランス語(スイス)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"ドイツ語(スイス)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"ベルギー語"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"ブルガリア語"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"イタリア語"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"デンマーク語"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ノルウェー語"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"スウェーデン語"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"フィンランド語"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"クロアチア語"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"チェコ語"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"エストニア語"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ハンガリー語"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"アイスランド語"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ブラジル配列"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"ポルトガル語"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"スロバキア語"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"スロベニア語"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"トルコ語"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ウクライナ語"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ka-rGE/strings.xml b/packages/InputDevices/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..6e507aa
--- /dev/null
+++ b/packages/InputDevices/res/values-ka-rGE/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"შეყვანის მოწყობილობები"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-ის კლავიატურა"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ინგლისური (გართ. სამ.)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ინგლისური (აშშ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ინგლისური (აშშ), საერთაშორისო სტილი"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ინგლისური (აშშ), Colemak სტილი"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"ინგლისური (აშშ), Dvorak სტილი"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"გერმანული"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"ფრანგული"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"ფრანგული (კანადა)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"რუსული"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"რუსული, Mac სტილი"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"ესპანური"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"შვეიცარიული ფრანგული"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"შვეიცარიული გერმანული"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"ბელგიური"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"ბულგარული"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"იტალიური"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"დანიური"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ნორვეგიული"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"შვედური"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ფინური"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"ხორვატიული"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"ჩეხური"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ესტონური"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"უნგრული"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ისლანდიური"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ბრაზილიური"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"პორტუგალიური"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"სლოვაკური"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"სლოვენური"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"თურქული"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"უკრაინული"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-km-rKH/strings.xml b/packages/InputDevices/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..9a8c99b
--- /dev/null
+++ b/packages/InputDevices/res/values-km-rKH/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"ឧបករណ៍​បញ្ចូល"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"ក្ដារចុច​ Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"អង់គ្លេស (​ចក្រភព​អង់គ្លេស)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"អង់គ្លេស (​សហរដ្ឋ​អាមេរិក)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"អង់គ្លេស (សហរដ្ឋ​អាមេរិក​)​, ​​រចនាប័ទ្ម​​អន្តរជាតិ"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"អង់គ្លេស (សហរដ្ឋ​អាមេរិក​)​, ​​រចនាប័ទ្ម Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"អង់គ្លេស (សហរដ្ឋ​អាមេរិក​)​, ​​រចនាប័ទ្ម Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"អាល្លឺម៉ង់"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"បារាំង"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"បារាំង (កាណាដា​)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"រុស្សី"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"រុស្សី ​រចនាប័ទ្ម Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"អេស្ប៉ាញ"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"​​បារាំង​ ស្វីស"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"អាល្លឺម៉ង់ ស្វីស"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"បែលហ្ស៊ិក"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"ប៊ុលហ្ការី"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"អ៊ីតាលី"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"ដាណឺម៉ាក"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ន័រវែស"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"ស៊ុយអែដ"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ហ្វាំងឡង់"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"ក្រូអាត"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"ឆេក"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"អេស្តូនី"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ហុងគ្រី"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"អ៊ីស្លង់"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ប្រេស៊ីល"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"ព័រទុយហ្គាល់"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"ស្លូវ៉ាគី"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"ស្លូវ៉ានី"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ទួរគី"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"អ៊ុយក្រែន"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ko/strings.xml b/packages/InputDevices/res/values-ko/strings.xml
new file mode 100644
index 0000000..8071586
--- /dev/null
+++ b/packages/InputDevices/res/values-ko/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"입력 기기"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android 키보드"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"영어(영국)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"영어(미국)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"영어(미국), 글로벌 스타일"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"영어(미국), 콜맥 스타일"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"영어(미국), 드보락 스타일"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"독일어"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"프랑스어"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"프랑스어(캐나다)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"러시아어"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"러시아어, Mac 스타일"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"스페인어"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"프랑스어(스위스)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"독일어(스위스)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"벨기에어"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"불가리아어"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"이탈리아어"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"덴마크어"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"노르웨이어"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"스웨덴어"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"핀란드어"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"크로아티아어"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"체코어"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"에스토니아어"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"헝가리어"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"아이슬란드어"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"브라질어"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"포르투갈어"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"슬로바키아어"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"슬로베니아어"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"터키어"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"우크라이나어"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-lo-rLA/strings.xml b/packages/InputDevices/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..2c97e11
--- /dev/null
+++ b/packages/InputDevices/res/values-lo-rLA/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"ອຸປະກອນປ້ອນຂໍ້ມູນ"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"ແປ້ນພິມ Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"ອັງກິດ (ສະຫະລັດຊະອານາຈັກ)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"ອັງກິດ (ສະຫະລັດຯ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"ອັງກິດ (ສະຫະລັດຯ), ແບບສາກົນ"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"ອັງກິດ (ສະຫະລັດຯ), ແບບ Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"ອັງກິດ (ສະຫະລັດຯ), ແບບ Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"ເຢຍລະມັນ"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"ຝຣັ່ງ"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"ຝຣັ່ງ (ຄານາດາ)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ຣັດເຊຍ"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ຣັດຊຽຍ, ແບບ Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"ສະແປນນິດ"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"ສະວິສ ຝຣັ່ງ"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"ສະວິສ ເຢຍລະມັນ"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"ເບວຢ້ຽນ"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"ຮັງກາຣຽນ"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"ອິຕາລຽນ"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"ເດັນນິຊ"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"ນໍເວກຽນ"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"ສະວີດິຊ"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ຟິນນິຊ"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"ໂຄຣເອທຽນ"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"ເຊກ"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"ເອສໂຕນຽນ"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ຮັງກາຣຽນ"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ໄອສແລນດິກ"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"ບຣາຊິລຽນ"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"ປໍຕູກີສ"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"ສະໂລແວັກ"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"ສະໂລເວນຽນ"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ເຕີກິສ"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ຢູເຄຣນຽນ"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-lt/strings.xml b/packages/InputDevices/res/values-lt/strings.xml
new file mode 100644
index 0000000..c0ed159
--- /dev/null
+++ b/packages/InputDevices/res/values-lt/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"„Android“ klaviatūra"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Anglų k. (JK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Anglų k. (JAV)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Anglų k. (JAV), tarptautinis stilius"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Anglų k. (JAV), „Colemak“ stilius"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Anglų k. (JAV), „Dvorak“ stilius"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Vokiečių k."</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Prancūzų k."</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Prancūzų k. (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Rusų k."</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Rusų k., „Mac“ stilius"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Ispanų k."</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Šveicarijos prancūzų k."</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Šveicarijos vokiečių k."</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgų k."</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarų k."</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italų k."</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danų k."</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norvegų k."</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Švedų k."</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Suomių k."</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroatų k."</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Čekų k."</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estų k."</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Vengrų k."</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandų k."</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazilų k."</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugalų k."</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovakų k."</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovėnų k."</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkų k."</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainiečių k."</string>
+</resources>
diff --git a/packages/InputDevices/res/values-lv/strings.xml b/packages/InputDevices/res/values-lv/strings.xml
new file mode 100644
index 0000000..07a8654
--- /dev/null
+++ b/packages/InputDevices/res/values-lv/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Ievadierīces"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android tastatūra"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Angļu (Lielbritānija)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Angļu (ASV)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Angļu (ASV), starptautiska"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Angļu (ASV), Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Angļu (ASV), Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Vācu"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Franču"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Franču (Kanāda)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Krievu"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Krievu, Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spāņu"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Franču (Šveice)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Vācu (Šveice)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Beļģu"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgāru"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Itāļu"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Dāņu"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norvēģu"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Zviedru"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Somu"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Horvātu"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Čehu"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Igauņu"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ungāru"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Īslandiešu"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazīļu"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugāļu"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovāku"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovēņu"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turku"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukraiņu"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-mn-rMN/strings.xml b/packages/InputDevices/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..ec6cccb
--- /dev/null
+++ b/packages/InputDevices/res/values-mn-rMN/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Оруулах Төхөөрөмж"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Андройд гар"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Англи (ИБ)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Англи (АНУ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Англи (АНУ), Олон улсын стиль"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Англи (АНУ), Колемак стиль"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Англи (АНУ), Дворак стиль"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Герман"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Франц"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Франц (Канад)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Орос"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Орос, Maк стиль"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Испани"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Швейцарийн Франц"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Швейцарийн Герман"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Бельги"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Болгар"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Итали"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Дани"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Норвеги"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Швед"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Финлянд"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Хорват"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Чех"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Эстон"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Унгар"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Исланд"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Бразил"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Португал"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Словак"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Словени"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Турк"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Украйн"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ms-rMY/strings.xml b/packages/InputDevices/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..486f048
--- /dev/null
+++ b/packages/InputDevices/res/values-ms-rMY/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Peranti Input"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Papan kekunci Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Bahasa Inggeris (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Bahasa Inggeris (AS)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Bahasa Inggeris (AS), gaya A/bangsa"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Bahasa Inggeris (AS), gaya Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Bahasa Inggeris (AS), gaya Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Bahasa Jerman"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Bahasa Perancis"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Bahasa Perancis (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Bahasa Rusia"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Bahasa Rusia, gaya Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Bahasa Sepanyol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Perancis Switzerland"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Jerman Switzerland"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Bahasa Belgium"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bahasa Bulgaria"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Bahasa Itali"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Bahasa Denmark"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Bahasa Norway"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Bahasa Sweden"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Bahasa Finland"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Bahasa Croatia"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Bahasa Czech"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Bahasa Estonia"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Bahasa Hungary"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Bahasa Iceland"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Bahasa Brazil"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Bahasa Portugis"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Bahasa Slovakia"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Bahasa Slovenia"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Bahasa Turki"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Bahasa Ukraine"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-nb/strings.xml b/packages/InputDevices/res/values-nb/strings.xml
new file mode 100644
index 0000000..b646061
--- /dev/null
+++ b/packages/InputDevices/res/values-nb/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Inndataenheter"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-tastatur"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engelsk (Storbritannia)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Engelsk (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Engelsk (USA), internasjonal stil"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Engelsk (USA), Colemak-stil"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Engelsk (USA), Dvorak-stil"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Tysk"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Fransk"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Fransk (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russisk"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russisk, Mac-stil"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spansk"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Sveitsisk fransk"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Sveitsisk standardtysk"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgisk"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarsk"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiensk"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Dansk"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norsk"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Svensk"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finsk"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroatisk"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tsjekkisk"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estisk"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ungarsk"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandsk"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasiliansk"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugisisk"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovakisk"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovensk"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Tyrkisk"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainsk"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-nl/strings.xml b/packages/InputDevices/res/values-nl/strings.xml
new file mode 100644
index 0000000..56d84c9
--- /dev/null
+++ b/packages/InputDevices/res/values-nl/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Invoerapparaten"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android-toetsenbord"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engels (Verenigd Koninkrijk)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Engels (Verenigde Staten)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Engels (VS), internationaal"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Engels (VS), Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Engels (VS), Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Duits"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Frans"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Frans (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russisch"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russisch, Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spaans"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Zwitsers Frans"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Zwitsers Duits"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgisch"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgaars"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiaans"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Deens"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Noors"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Zweeds"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Fins"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroatisch"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tsjechisch"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estlands"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hongaars"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"IJslands"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Braziliaans"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugees"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slowaaks"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Sloveens"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turks"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Oekraïens"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-pl/strings.xml b/packages/InputDevices/res/values-pl/strings.xml
new file mode 100644
index 0000000..4522215
--- /dev/null
+++ b/packages/InputDevices/res/values-pl/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Urządzenia wejściowe"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Klawiatura Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Angielski (Wielka Brytania)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Angielski (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Angielski (USA), międzynarodowy"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Angielski (USA), Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Angielski (USA), Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Niemiecki"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francuski"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francuski (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Rosyjski"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Rosyjski, Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Hiszpański"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francuski (Szwajcaria)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Niemiecki (Szwajcaria)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgijski"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bułgarski"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Włoski"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Duński"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norweski"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Szwedzki"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Fiński"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Chorwacki"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czeski"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estoński"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Węgierski"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandzki"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazylijski"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugalski"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Słowacki"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Słoweński"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turecki"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukraiński"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-pt-rPT/strings.xml b/packages/InputDevices/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..9a639cd
--- /dev/null
+++ b/packages/InputDevices/res/values-pt-rPT/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Dispositivos de entrada"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Teclado do Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglês (RU)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglês (EUA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglês (EUA), est. Internacional"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglês (EUA), estilo Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglês (EUA), estilo Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Alemão"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francês"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francês (Canadá)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russo"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russo, estilo Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Espanhol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francês (Suíça)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Alemão (Suíça)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belga"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Búlgaro"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiano"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Dinamarquês"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norueguês"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Sueco"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandês"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croata"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Checo"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estónio"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Húngaro"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandês"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasileiro"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Português"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Eslovaco"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Esloveno"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turco"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraniano"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-pt/strings.xml b/packages/InputDevices/res/values-pt/strings.xml
new file mode 100644
index 0000000..05a0cd0
--- /dev/null
+++ b/packages/InputDevices/res/values-pt/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Dispositivos de entrada"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Teclado do Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Inglês (Reino Unido)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Inglês (EUA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Inglês (EUA), estilo internacional"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Inglês (EUA), estilo Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Inglês (EUA), estilo Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Alemão"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Francês"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Francês (Canadá)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russo"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russo, estilo Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Espanhol"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Francês suíço"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Alemão suíço"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belga"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Búlgaro"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiano"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Dinamarquês"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norueguês"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Sueco"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandês"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croata"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tcheco"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estoniano"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Húngaro"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandês"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brasileiro"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Português"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Eslovaco"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Esloveno"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turco"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraniano"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ro/strings.xml b/packages/InputDevices/res/values-ro/strings.xml
new file mode 100644
index 0000000..895d8f6
--- /dev/null
+++ b/packages/InputDevices/res/values-ro/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Dispozitive de introducere de date"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Tastatură Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engleză (Regatul Unit)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Engleză (SUA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Engleză (SUA), stil internațional"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Engleză (SUA), stil Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Engleză (SUA), stil Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Germană"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Franceză"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Franceză (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Rusă"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Rusă, stil Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spaniolă"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Franceză (Elveția)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Germană (Elveția)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgiană"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgară"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italiană"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Daneză"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norvegiană"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Suedeză"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finlandeză"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croată"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Cehă"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estoniană"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Maghiară"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Islandeză"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Braziliană"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugheză"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovacă"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenă"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turcă"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ucraineană"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-ru/strings.xml b/packages/InputDevices/res/values-ru/strings.xml
new file mode 100644
index 0000000..a4cbfd7
--- /dev/null
+++ b/packages/InputDevices/res/values-ru/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Устройства ввода"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Клавиатура Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"английский (Великобритания)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"английский (США)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"английский (США, международная)"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"английский (США, Colemak)"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"английский (США, Dvorak)"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"немецкий"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"французский"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"французский (Канада)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"русский"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"русский (Mac)"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"испанский"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"французский (Швейцария)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"немецкий (Швейцария)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"нидерландский (Бельгия)"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"болгарский"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"итальянский"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"датский"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"норвежский"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"шведский"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"финский"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"хорватский"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"чешский"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"эстонский"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"венгерский"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"исландский"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"португальский (Бразилия)"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"португальский"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"словацкий"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словенский"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турецкий"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"украинский"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-sk/strings.xml b/packages/InputDevices/res/values-sk/strings.xml
new file mode 100644
index 0000000..01ab042
--- /dev/null
+++ b/packages/InputDevices/res/values-sk/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Vstupné zariadenia"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Klávesnica Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"anglické (Spojené kráľovstvo)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"anglické (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"anglické (USA), medzinárodné"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"anglické (USA), štýl Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"anglické (USA), štýl Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"nemecké"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"francúzske"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francúzske (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruské"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruské, štýl Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španielske"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"švajčiarske (francúzština)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"švajčiarske (nemčina)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgické"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bulharské"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"talianske"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"dánske"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"nórske"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"švédske"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"fínske"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"chorvátske"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"české"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estónske"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"maďarské"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandské"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazílske"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalské"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovenské"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovinské"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turecké"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinské"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-sl/strings.xml b/packages/InputDevices/res/values-sl/strings.xml
new file mode 100644
index 0000000..30ff3c4
--- /dev/null
+++ b/packages/InputDevices/res/values-sl/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Vhodne naprave"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Tipkovnica Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"angleška (Združeno kraljestvo)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"angleška (ZDA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"angleška (ZDA), mednarodni slog"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"angleška (ZDA), slog Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"angleška (ZDA), slog Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"nemška"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"francoska"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"francoska (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"ruska"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"ruska, slog Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"španska"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"švicarska francoska"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"švicarska nemška"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"belgijska"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"bolgarska"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"italijanska"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"danska"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"norveška"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"švedska"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"finska"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"hrvaška"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"češka"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"estonska"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"madžarska"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"islandska"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"brazilska"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"portugalska"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"slovaška"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"slovenska"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"turška"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ukrajinska"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-sr/strings.xml b/packages/InputDevices/res/values-sr/strings.xml
new file mode 100644
index 0000000..d23ac00
--- /dev/null
+++ b/packages/InputDevices/res/values-sr/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Улазни уређаји"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android тастатура"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"енглеска (УК)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"енглеска (САД)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"енглеска (САД), међународни стил"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"енглеска (САД), Colemak стил"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"енглеска (САД), Dvorak стил"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"немачка"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"француска"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"француска (Канада)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"руска"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"руска, Mac стил"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"шпанска"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"швајцарско француска"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"швајцарско немачка"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"белгијска"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"бугарска"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"италијанска"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"данска"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"норвешка"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"шведска"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"финска"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"хрватска"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"чешка"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"естонска"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"мађарска"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"исландска"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"бразилска"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"португалска"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"словачка"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словеначка"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турска"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"украјинска"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-sv/strings.xml b/packages/InputDevices/res/values-sv/strings.xml
new file mode 100644
index 0000000..25a5ae8
--- /dev/null
+++ b/packages/InputDevices/res/values-sv/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Indataenheter"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Androids tangentbord"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Engelskt (Storbritannien)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Engelskt (USA)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Engelskt (USA), internationellt"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Engelskt (USA), colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Engelskt (USA), dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Tyskt"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Franskt"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Franskt (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Ryskt"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Ryskt, Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanskt"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Franskt (Schweiz)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Tyskt (Schweiz)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgiskt"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgariskt"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italienskt"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danskt"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norskt"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Svenskt"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finskt"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kroatiskt"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tjeckiskt"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estniskt"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Ungerskt"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Isländskt"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Portugisiskt (Brasilien)"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portugisiskt"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovakiskt"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenskt"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkiskt"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainskt"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-sw/strings.xml b/packages/InputDevices/res/values-sw/strings.xml
new file mode 100644
index 0000000..65ab96a1
--- /dev/null
+++ b/packages/InputDevices/res/values-sw/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Vifaa Ingizi"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Kibodi ya Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Kiingereza (Uingereza)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Kiingereza (Marekani)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Kiingereza (Marekani), Muundo wa Kimataifa"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Kiingereza (Marekani), Muundo wa Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Kiingereza (Marekani), Muundo wa Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Kijerumani"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Kifaransa"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Kifaransa (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Kirusi"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Kirusi, Muundo wa Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Kihispania"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Kifaransa cha Uswisi"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Kijerumani cha Uswisi"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Kibelgiji"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Kibulgaria"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Kiitaliano"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Kidenmarki"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Kinorwei"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Kiswidi"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Kifinlandi"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Kikroeshia"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Kicheki"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Kiestonia"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Kihungari"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Kiaislandi"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Kibrazili"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Kireno"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Kislovakia"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Kislovenia"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Kituruki"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Kiukrania"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-th/strings.xml b/packages/InputDevices/res/values-th/strings.xml
new file mode 100644
index 0000000..0cc7d47
--- /dev/null
+++ b/packages/InputDevices/res/values-th/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"อุปกรณ์อินพุต"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"แป้นพิมพ์แอนดรอยด์"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"อังกฤษ (สหราชอาณาจักร)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"อังกฤษ (อเมริกัน)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"อังกฤษ (อเมริกัน), รูปแบบนานาชาติ"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"อังกฤษ (อเมริกัน), รูปแบบ Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"อังกฤษ (อเมริกัน), รูปแบบ Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"เยอรมัน"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"ฝรั่งเศส"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"ฝรั่งเศส (แคนาดา)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"รัสเซีย"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"รัสเซีย, รูปแบบ Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"สเปน"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"ฝรั่งเศส (สวิส)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"เยอรมันสวิส"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"เบลเยียม"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"บัลแกเรีย"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"อิตาลี"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"เดนมาร์ก"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"นอร์เวย์"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"สวีเดน"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"ฟินแลนด์"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"โครเอเชีย"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"เช็ก"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"เอสโตเนีย"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"ฮังการี"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ไอซ์แลนดิก"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"บราซิล"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"โปรตุเกส"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"สโลวัก"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"สโลวีเนีย"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"ตุรกี"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"ยูเครน"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-tl/strings.xml b/packages/InputDevices/res/values-tl/strings.xml
new file mode 100644
index 0000000..08f34d2
--- /dev/null
+++ b/packages/InputDevices/res/values-tl/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Mga Input Device"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android keyboard"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Ingles (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Ingles (US)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Ingles (US), istilong International"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Ingles (US), istilong Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Ingles (US), istilong Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"German"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"French"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"French (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Russian"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Russian, istilong Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Spanish"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Swiss French"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Swiss German"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belgian"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarian"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Italian"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danish"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norwegian"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Swedish"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Finnish"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Croatian"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Czech"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonian"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Hungarian"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Icelandic"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brazilian"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portuguese"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovak"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovenian"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Turkish"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukrainian"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-tr/strings.xml b/packages/InputDevices/res/values-tr/strings.xml
new file mode 100644
index 0000000..f7c1262
--- /dev/null
+++ b/packages/InputDevices/res/values-tr/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Input Devices"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android klavyesi"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"İngilizce (İngiltere)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"İngilizce (ABD)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"İngilizce (ABD) Uluslararası stil"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"İngilizce (ABD) Colemak stili"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"İngilizce (ABD) Dvorak stili"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Almanca"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Fransızca"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Fransızca (Kanada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Rusça"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Rusça, Mac stili"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"İspanyolca"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"İsviçre Fransızcası"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"İsviçre Almancası"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Belçika dili"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Bulgarca"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"İtalyanca"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Danca"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Norveççe"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"İsveççe"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Fince"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Hırvatça"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Çekçe"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Estonca"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Macarca"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"İzlandaca"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Brezilya dili"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Portekizce"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Slovakça"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Slovence"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Türkçe"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Ukraynaca"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-uk/strings.xml b/packages/InputDevices/res/values-uk/strings.xml
new file mode 100644
index 0000000..ee6ffc7
--- /dev/null
+++ b/packages/InputDevices/res/values-uk/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Пристрої вводу"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Клавіатура Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"англійська (Великобританія)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"англійська (США)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"англійська (США), міжнародна"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"англійська (США), розкладка Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"англійська (США), розкладка Дворака"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"німецька"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"французька"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"французька (Канада)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"російська"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"російська, розкладка Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"іспанська"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"французька (Швейцарія)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"німецька (Швейцарія)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"бельгійська"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"болгарська"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"італійська"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"данська"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"норвезька"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"шведська"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"фінська"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"хорватська"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"чеська"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"естонська"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"угорська"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"ісландська"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"бразильська"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"португальська"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"словацька"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"словенська"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"турецька"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"українська"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-vi/strings.xml b/packages/InputDevices/res/values-vi/strings.xml
new file mode 100644
index 0000000..7a65e45
--- /dev/null
+++ b/packages/InputDevices/res/values-vi/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Thiết bị đầu vào"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Bàn phím Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"Tiếng Anh (Anh)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"Tiếng Anh (Mỹ)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"Tiếng Anh (Mỹ), kiểu Quốc tế"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"Tiếng Anh (Mỹ), kiểu Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"Tiếng Anh (Mỹ), kiểu Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Tiếng Đức"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Tiếng Pháp"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Tiếng Pháp (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Tiếng Nga"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Tiếng Nga, kiểu Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Tiếng Tây Ban Nha"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Tiếng Pháp ở Thụy Sĩ"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Tiếng Đức Thụy Sĩ"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Tiếng Bỉ"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Tiếng Bungary"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Tiếng Ý"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Tiếng Đan Mạch"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Tiếng Na Uy"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Tiếng Thụy Điển"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Tiếng Phần Lan"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Tiếng Croatia"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Tiếng Séc"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Tiếng Estonia"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Tiếng Hungary"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Tiếng Ai-xơ-len"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Tiếng Brazil"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Tiếng Bồ Đào Nha"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Tiếng Slovak"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Tiếng Sloven"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Tiếng Thổ Nhĩ Kỳ"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Tiếng Ukraina"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-zh-rCN/strings.xml b/packages/InputDevices/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..85b1c84
--- /dev/null
+++ b/packages/InputDevices/res/values-zh-rCN/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"输入设备"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android 键盘"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"英语(英国)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"英语(美国)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"英语(美国),国际风格"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"英语(美国),Colemak 风格"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"英语(美国),Dvorak 风格"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"德语"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"法语"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"法语(加拿大)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"俄语"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"俄语,Mac 风格"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"西班牙语"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"瑞士法语"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"瑞士德语"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"比利时语"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"保加利亚语"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"意大利语"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"丹麦语"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"挪威语"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"瑞典语"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"芬兰语"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"克罗地亚语"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"捷克语"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"爱沙尼亚语"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"匈牙利语"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"冰岛语"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"巴西语"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"葡萄牙语"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"斯洛伐克语"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"斯洛文尼亚语"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"土耳其语"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"乌克兰语"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-zh-rHK/strings.xml b/packages/InputDevices/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..839c546
--- /dev/null
+++ b/packages/InputDevices/res/values-zh-rHK/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"輸入裝置"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android 鍵盤"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"英文 (英國)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"英文 (美國)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"英文 (美國),國際樣式"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"英文 (美國),Colemak 樣式"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"英文 (美國),Dvorak 樣式"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"德文"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"法文"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"法文 (加拿大)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"俄文"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"俄文,Mac 樣式"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"西班牙文"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"法文 (瑞士)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"德文(瑞士)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"比利時文"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"保加利亞文"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"意大利文"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"丹麥文"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"挪威文"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"瑞典文"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"芬蘭文"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"克羅地亞文"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"捷克文"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"愛沙尼亞文"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"匈牙利文"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"冰島文"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"巴西文"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"葡萄牙文"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"斯洛伐克文"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"斯洛文尼亞文"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"土耳其文"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"烏克蘭文"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-zh-rTW/strings.xml b/packages/InputDevices/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..ba9f132
--- /dev/null
+++ b/packages/InputDevices/res/values-zh-rTW/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"輸入裝置"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Android 鍵盤"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"英文 (英國)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"英文 (美國)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"英文 (美國),國際樣式"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"英文 (美國),Colemak 樣式"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"英文 (美國),Dvorak 樣式"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"德文"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"法文"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"法文 (加拿大)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"俄文"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"俄文,Mac 樣式"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"西班牙文"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"法文 (瑞士)"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"德文 (瑞士)"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"比利時式"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"保加利亞文"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"義大利文"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"丹麥文"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"挪威文"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"瑞典文"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"芬蘭文"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"克羅埃西亞文"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"捷克文"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"愛沙尼亞文"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"匈牙利文"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"冰島文"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"巴西式"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"葡萄牙文"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"斯洛伐克文"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"斯洛維尼亞文"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"土耳其文"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"烏克蘭文"</string>
+</resources>
diff --git a/packages/InputDevices/res/values-zu/strings.xml b/packages/InputDevices/res/values-zu/strings.xml
new file mode 100644
index 0000000..fbf1074
--- /dev/null
+++ b/packages/InputDevices/res/values-zu/strings.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="8016145283189546017">"Amadivayisi wokufaka"</string>
+    <string name="keyboard_layouts_label" msgid="6688773268302087545">"Ikhibhodi ye-Android"</string>
+    <string name="keyboard_layout_english_uk_label" msgid="6664258463319999632">"I-English (UK)"</string>
+    <string name="keyboard_layout_english_us_label" msgid="8994890249649106291">"I-English (US)"</string>
+    <string name="keyboard_layout_english_us_intl" msgid="3705168594034233583">"I-English (US), isitayela sakwamanye amazwe"</string>
+    <string name="keyboard_layout_english_us_colemak_label" msgid="4194969610343455380">"I-English (US), isitayela se-Colemak"</string>
+    <string name="keyboard_layout_english_us_dvorak_label" msgid="793528923171145202">"I-English (US), isitayela se-Dvorak"</string>
+    <string name="keyboard_layout_german_label" msgid="8451565865467909999">"Isi-German"</string>
+    <string name="keyboard_layout_french_label" msgid="813450119589383723">"Isi-French"</string>
+    <string name="keyboard_layout_french_ca_label" msgid="365352601060604832">"Isi-French (Canada)"</string>
+    <string name="keyboard_layout_russian_label" msgid="8724879775815042968">"Isi-Russian"</string>
+    <string name="keyboard_layout_russian_mac_label" msgid="3795866869038264796">"Isi-Russian, isitayela se-Mac"</string>
+    <string name="keyboard_layout_spanish_label" msgid="7091555148131908240">"Isi-Spanish"</string>
+    <string name="keyboard_layout_swiss_french_label" msgid="4659191025396371684">"Isi-Swiss French"</string>
+    <string name="keyboard_layout_swiss_german_label" msgid="2305520941993314258">"Isi-Swiss German"</string>
+    <string name="keyboard_layout_belgian" msgid="2011984572838651558">"Isi-Belgian"</string>
+    <string name="keyboard_layout_bulgarian" msgid="8951224309972028398">"Isi-Bulgarian"</string>
+    <string name="keyboard_layout_italian" msgid="6497079660449781213">"Isi-Italian"</string>
+    <string name="keyboard_layout_danish" msgid="8036432066627127851">"Isi-Danish"</string>
+    <string name="keyboard_layout_norwegian" msgid="9090097917011040937">"Isi-Norwegian"</string>
+    <string name="keyboard_layout_swedish" msgid="732959109088479351">"Isi-Swedish"</string>
+    <string name="keyboard_layout_finnish" msgid="5585659438924315466">"Isi-Finnish"</string>
+    <string name="keyboard_layout_croatian" msgid="4172229471079281138">"Isi-Croatian"</string>
+    <string name="keyboard_layout_czech" msgid="1349256901452975343">"Isi-Czech"</string>
+    <string name="keyboard_layout_estonian" msgid="8775830985185665274">"Isi-Estonian"</string>
+    <string name="keyboard_layout_hungarian" msgid="4154963661406035109">"Isi-Hungarian"</string>
+    <string name="keyboard_layout_icelandic" msgid="5836645650912489642">"Isi-Icelandic"</string>
+    <string name="keyboard_layout_brazilian" msgid="5117896443147781939">"Isi-Brazilian"</string>
+    <string name="keyboard_layout_portuguese" msgid="2888198587329660305">"Isi-Portuguese"</string>
+    <string name="keyboard_layout_slovak" msgid="2469379934672837296">"Isi-Slovak"</string>
+    <string name="keyboard_layout_slovenian" msgid="1735933028924982368">"Isi-Slovenian"</string>
+    <string name="keyboard_layout_turkish" msgid="7736163250907964898">"Isi-Turkish"</string>
+    <string name="keyboard_layout_ukrainian" msgid="8176637744389480417">"Isi-Ukrainian"</string>
+</resources>
diff --git a/packages/Keyguard/Android.mk b/packages/Keyguard/Android.mk
index 1f2b5fb..5b08674 100644
--- a/packages/Keyguard/Android.mk
+++ b/packages/Keyguard/Android.mk
@@ -16,7 +16,8 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-subdir-Iaidl-files) \
+                   $(call all-proto-files-under,src)
 
 LOCAL_PACKAGE_NAME := Keyguard
 
@@ -26,6 +27,9 @@
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+LOCAL_PROTO_JAVA_OUTPUT_PARAMS := optional_field_style=accessors
+
 include $(BUILD_PACKAGE)
 
 #include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
new file mode 100644
index 0000000..ebd0a64
--- /dev/null
+++ b/packages/Keyguard/res/layout-land/keyguard_simple_host_view.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License")
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<!-- This is the host view that generally contains two sub views: the widget view
+    and the security view. -->
+<com.android.keyguard.KeyguardSimpleHostView
+    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">
+
+    <com.android.keyguard.KeyguardSecurityContainer
+        android:id="@+id/keyguard_security_container"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/keyguard_security_height"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:padding="0dp"
+        android:layout_gravity="center">
+        <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>
+
+</com.android.keyguard.KeyguardSimpleHostView>
+
diff --git a/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml b/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml
new file mode 100644
index 0000000..cba7667
--- /dev/null
+++ b/packages/Keyguard/res/layout-port/keyguard_simple_host_view.xml
@@ -0,0 +1,49 @@
+<?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.KeyguardSimpleHostView
+    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">
+
+    <com.android.keyguard.KeyguardSecurityContainer
+        android:id="@+id/keyguard_security_container"
+        android:layout_width="wrap_content"
+        android:layout_height="@dimen/keyguard_security_height"
+        android:clipChildren="false"
+        android:clipToPadding="false"
+        android:padding="0dp"
+        android:layout_gravity="center">
+        <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>
+
+</com.android.keyguard.KeyguardSimpleHostView>
+
diff --git a/packages/Keyguard/res/values-af/strings.xml b/packages/Keyguard/res/values-af/strings.xml
index 7e1f0bf..2667ed2 100644
--- a/packages/Keyguard/res/values-af/strings.xml
+++ b/packages/Keyguard/res/values-af/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Voer SIM PUK- en nuwe PIN-kode in"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK-kode"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nuwe SIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Laaik baie"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Laaik niks"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Hart"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Ontsluit om voort te gaan"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Begin gekanselleer"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Laat los <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> om uit te vee."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> sal nie uitgevee word nie."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Verkeerde SIM PIN-kode, jy sal nou jou diensverskaffer moet kontak om jou toestel te ontsluit."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Verkeerde SIM PIN-kode, jy het <xliff:g id="NUMBER">%d</xliff:g> oorblywende poging voordat jy jou diensverskaffer sal moet kontak om jou toestel te ontsluit."</item>
+    <item quantity="other" msgid="2215723361575359486">"Verkeerde SIM PIN-kode, jy het <xliff:g id="NUMBER">%d</xliff:g> oorblywende pogings."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM is onbruikbaar. Kontak jou diensverskaffer."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Verkeerde SIM PUK-kode, jy het <xliff:g id="NUMBER">%d</xliff:g> oorblywende poging voordat SIM permanent onbruikbaar word."</item>
+    <item quantity="other" msgid="5477305226026342036">"Verkeerde SIM PUK-kode, jy het <xliff:g id="NUMBER">%d</xliff:g> oorblywende pogings voordat SIM permanent onbruikbaar word."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN-bewerking het misluk!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK-bewerking het misluk!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kode is aanvaar!"</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>
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index 2f6dab0..933ef9c 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -21,13 +21,13 @@
 <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_enter_puk_code" msgid="3035856550289724338">"የሲም PUK እና አዲሱን ፒን ኮድ ይተይቡ"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"የሲም PUK ኮድ"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"አዲስ ሲም ፒን ኮድ"</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_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>
@@ -71,11 +71,18 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"አሪፍ"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"ደባሪ"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"ልብ"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"ለመቀጠል ይክፈቱ"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"ማስጀመር ተሰርዟል"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"ለመሰረዝ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>ን ጣል ያድርጉ።"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> አይሰርዝም።"</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_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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"ልክ ያልሆነ የሲም ኮድ። አሁን መሳሪያዎን ለማስከፈት ድምጸ ተያያዥ ሞደምዎን ማግኘት አለብዎ።"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"ልክ ያልሆነ የሲም ፒን ኮድ፣ መሳሪያዎን ለማስከፈት ድምጸ ተያያዥ ሞደምዎን ማግኘት ግዴታዎ ሊሆን <xliff:g id="NUMBER">%d</xliff:g> ሙከራ ይቀርዎታል።"</item>
+    <item quantity="other" msgid="2215723361575359486">"ልክ ያልሆነ የሲም ፒን ኮድ፣ <xliff:g id="NUMBER">%d</xliff:g> ሙከራዎች ይቀሩዎታል።"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"ሲሙ ጥቅም ላይ መዋል እይችልም። የእርስዎን ድምጸ ተያያዥ ሞደም ያግኙ።"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"ልክ ያልሆነ የሲም PUK ኮድ፣ ሲም ካርድዎ በቋሚነት ጥቅም ላይ መዋል የማይችል ሊሆን <xliff:g id="NUMBER">%d</xliff:g> ሙከራ ይቀርዎታል።"</item>
+    <item quantity="other" msgid="5477305226026342036">"ልክ ያልሆነ የሲም PUK ኮድ፣ ሲም ካርድዎ በቋሚነት ጥቅም ላይ መዋል የማይችል ሊሆን <xliff:g id="NUMBER">%d</xliff:g> ሙከራዎች ይቀሩዎታል።"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"የሲም ፒን ክወና አልተሳካም!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"የሲም PUK ክወና አልተሳካም!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"ኮዱ ተቀባይነት አግኝቷል!"</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>
diff --git a/packages/Keyguard/res/values-ar/strings.xml b/packages/Keyguard/res/values-ar/strings.xml
index bcfe7db..83d4b93 100644
--- a/packages/Keyguard/res/values-ar/strings.xml
+++ b/packages/Keyguard/res/values-ar/strings.xml
@@ -20,14 +20,14 @@
 
 <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_enter_pin_code" msgid="3037685796058495017">"‏اكتب رمز رمز PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"‏أدخل رمز PUK لبطاقة SIM ورمز \"رقم التعريف الشخصي\" الجديد"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"‏رمز PUK لبطاقة SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"‏رمز \"رقم تعريف شخصي\" جديد لبطاقة SIM"</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_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>
@@ -35,17 +35,17 @@
     <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_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>
@@ -62,7 +62,7 @@
     <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_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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"رائعة"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"معارضة"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"قلب"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"إلغاء القفل للمتابعة"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"تم إلغاء التشغيل"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"أسقط <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> للحذف."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"لن يتم حذف <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</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>
@@ -98,27 +105,26 @@
     <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_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">"إدخال رمز رقم التعريف الشخصي المراد"</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_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_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_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_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_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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"‏رمز \"رقم التعريف الشخصي\" لبطاقة SIM غير صحيح، ويلزمك الاتصال الآن بمشغّل شبكة الجوّال لإلغاء قفل الجهاز."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"‏رمز \"رقم التعريف الشخصي\" لبطاقة SIM غير صحيح، ويتبقى لديك محاولة واحدة (<xliff:g id="NUMBER">%d</xliff:g>) يتعين عليك بعدها الاتصال بمشغّل شبكة الجوّال لإلغاء قفل الجهاز."</item>
+    <item quantity="other" msgid="2215723361575359486">"‏رمز \"رقم التعريف الشخصي\" لبطاقة SIM غير صحيح، يتبقى لديك <xliff:g id="NUMBER">%d</xliff:g> من المحاولات."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"‏بطاقة SIM غير صالحة للاستخدام. يُرجى الاتصال بمشغّل شبكة الجوّال."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"‏رمز PUK لبطاقة SIM غير صالح، ويتبقى لديك محاولة واحدة (<xliff:g id="NUMBER">%d</xliff:g>)، تصبح بعدها بطاقة SIM غير صالحة للاستخدام بشكل دائم."</item>
+    <item quantity="other" msgid="5477305226026342036">"‏رمز PUK لبطاقة SIM غير صالح، ويتبقى لديك <xliff:g id="NUMBER">%d</xliff:g> من المحاولات، تصبح بعدها بطاقة SIM غير صالحة للاستخدام بشكل دائم."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"‏أخفقت عملية \"رقم التعريف الشخصي\" لبطاقة SIM!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"‏أخفقت عملية PUK لبطاقة SIM!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"تم قبول الرمز!"</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>
diff --git a/packages/Keyguard/res/values-az-rAZ/strings.xml b/packages/Keyguard/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..5c8f6ac
--- /dev/null
+++ b/packages/Keyguard/res/values-az-rAZ/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">"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="faceunlock_multiple_failures" msgid="754137583022792429">"Sifət kilidi cəhdləriniz bitdi"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Dolmuş"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Dolur, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Elektrikə qoşun."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmaq üçün Menyu düyməsinə baxın."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Şəbəkə kilidləndi"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SİM kart yoxdur"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Planşetdə SİM kart yoxdur.."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonda SİM kart yoxdu."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM kartı daxil edin."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SİM kart yoxdur və ya oxuna bilinmir. SİM kart daxil edin."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Yararsız SIM kart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"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="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kart kilidlənib."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SİM kart PUK ilə kilidlənib."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SİM kartın kilidi açılır..."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pauza düyməsi"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Oxutma düyməsi"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Dayandırma düymə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="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="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_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="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</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">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pauza düyməsi"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Oxutma düyməsi"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Dayandırma düyməsi"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Xidmət yoxdur."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-az/strings.xml b/packages/Keyguard/res/values-az/strings.xml
new file mode 100644
index 0000000..5c8f6ac
--- /dev/null
+++ b/packages/Keyguard/res/values-az/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">"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="faceunlock_multiple_failures" msgid="754137583022792429">"Sifət kilidi cəhdləriniz bitdi"</string>
+    <string name="keyguard_charged" msgid="3272223906073492454">"Dolmuş"</string>
+    <string name="keyguard_plugged_in" msgid="8117572000639998388">"Dolur, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
+    <string name="keyguard_low_battery" msgid="8143808018719173859">"Elektrikə qoşun."</string>
+    <string name="keyguard_instructions_when_pattern_disabled" msgid="1332288268600329841">"Kilidi açmaq üçün Menyu düyməsinə baxın."</string>
+    <string name="keyguard_network_locked_message" msgid="9169717779058037168">"Şəbəkə kilidləndi"</string>
+    <string name="keyguard_missing_sim_message_short" msgid="494980561304211931">"SİM kart yoxdur"</string>
+    <string name="keyguard_missing_sim_message" product="tablet" msgid="1445849005909260039">"Planşetdə SİM kart yoxdur.."</string>
+    <string name="keyguard_missing_sim_message" product="default" msgid="3481110395508637643">"Telefonda SİM kart yoxdu."</string>
+    <string name="keyguard_missing_sim_instructions" msgid="5210891509995942250">"SIM kartı daxil edin."</string>
+    <string name="keyguard_missing_sim_instructions_long" msgid="5968985489463870358">"SİM kart yoxdur və ya oxuna bilinmir. SİM kart daxil edin."</string>
+    <string name="keyguard_permanent_disabled_sim_message_short" msgid="8340813989586622356">"Yararsız SIM kart."</string>
+    <string name="keyguard_permanent_disabled_sim_instructions" msgid="5892940909699723544">"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="keyguard_sim_locked_message" msgid="6875773413306380902">"SIM kart kilidlənib."</string>
+    <string name="keyguard_sim_puk_locked_message" msgid="3747232467471801633">"SİM kart PUK ilə kilidlənib."</string>
+    <string name="keyguard_sim_unlock_progress_dialog_message" msgid="7975221805033614426">"SİM kartın kilidi açılır..."</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="keyguard_accessibility_transport_prev_description" msgid="1337286538318543555">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_next_description" msgid="7073928300444909320">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_accessibility_transport_pause_description" msgid="8455979545295224302">"Pauza düyməsi"</string>
+    <string name="keyguard_accessibility_transport_play_description" msgid="8146417789511154044">"Oxutma düyməsi"</string>
+    <string name="keyguard_accessibility_transport_stop_description" msgid="7656358482980912216">"Dayandırma düymə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="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="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_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="user_switched" msgid="3768006783166984410">"Cari istifadəçi <xliff:g id="NAME">%1$s</xliff:g>."</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">%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="keyguard_transport_prev_description" msgid="8229108430245669854">"Əvvəlki izləmə düyməsi"</string>
+    <string name="keyguard_transport_next_description" msgid="4299258300283778305">"Növbəti izləmə düyməsi"</string>
+    <string name="keyguard_transport_pause_description" msgid="5093073338238310224">"Pauza düyməsi"</string>
+    <string name="keyguard_transport_play_description" msgid="2924628863741150956">"Oxutma düyməsi"</string>
+    <string name="keyguard_transport_stop_description" msgid="3084179324810575787">"Dayandırma düyməsi"</string>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Xidmət yoxdur."</string>
+</resources>
diff --git a/packages/Keyguard/res/values-be/activitystrings.xml b/packages/Keyguard/res/values-be/activitystrings.xml
deleted file mode 100644
index ccefe40..0000000
--- a/packages/Keyguard/res/values-be/activitystrings.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the 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
deleted file mode 100644
index 81020a0..0000000
--- a/packages/Keyguard/res/values-be/strings.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under 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/strings.xml b/packages/Keyguard/res/values-bg/strings.xml
index 869ab7b..641adbd 100644
--- a/packages/Keyguard/res/values-bg/strings.xml
+++ b/packages/Keyguard/res/values-bg/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Въведете PUK за SIM картата и новия ПИН код"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK код за SIM картата"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Нов ПИН код за SIM картата"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Харесва ми"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Не ми харесва"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Сърце"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Отключете, за да продължите"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Стартирането е анулирано"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Пуснете <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>, за да изтриете."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> няма да се изтрие."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Неправилен ПИН код за SIM картата – сега трябва да се свържете с оператора си, за да отключите устройството."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Неправилен ПИН код за SIM картата – остава ви <xliff:g id="NUMBER">%d</xliff:g> опит, преди да трябва да се свържете с оператора си, за да отключите устройството."</item>
+    <item quantity="other" msgid="2215723361575359486">"Неправилен ПИН код за SIM картата – остават ви <xliff:g id="NUMBER">%d</xliff:g> опита."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM картата е неизползваема. Свържете се с оператора си."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Неправилен PUK код за SIM картата – остава ви <xliff:g id="NUMBER">%d</xliff:g> опит, преди SIM картата да стане неизползваема завинаги."</item>
+    <item quantity="other" msgid="5477305226026342036">"Неправилен PUK код за SIM картата – остават ви <xliff:g id="NUMBER">%d</xliff:g> опита, преди SIM картата да стане неизползваема завинаги."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Операцията с ПИН кода за SIM картата не бе успешна!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Операцията с PUK кода за SIM картата не бе успешна!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Кодът е приет!"</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>
diff --git a/packages/Keyguard/res/values-ca/strings.xml b/packages/Keyguard/res/values-ca/strings.xml
index 4f97c6b..8b81086 100644
--- a/packages/Keyguard/res/values-ca/strings.xml
+++ b/packages/Keyguard/res/values-ca/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Escriu el PUK de la SIM i el codi PIN nou."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Codi PUK de la SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Codi PIN de la SIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"M\'agrada"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"No m\'agrada"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Cor"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Desbloqueja per continuar"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"S\'ha cancel·lat l\'inici"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Deixa anar <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> per suprimir-lo."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"No se suprimirà <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"El codi PIN de la SIM no és correcte. Has de contactar amb l\'operador de telefonia mòbil per desbloquejar el dispositiu."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"El codi PIN de la SIM no és correcte. Et queda <xliff:g id="NUMBER">%d</xliff:g> intent; si no l\'encertes, contacta amb l\'operador de telefonia mòbil per desbloquejar el dispositiu."</item>
+    <item quantity="other" msgid="2215723361575359486">"El codi PIN de la SIM no és correcte. Et queden <xliff:g id="NUMBER">%d</xliff:g> intents."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"La SIM no es pot utilitzar. Contacta amb l\'operador de telefonia mòbil."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"El codi PUK de la SIM no és correcte. Et queda <xliff:g id="NUMBER">%d</xliff:g> intent; si no l\'encertes, la SIM no es podrà tornar a fer servir."</item>
+    <item quantity="other" msgid="5477305226026342036">"El codi PUK de la SIM no és correcte. Et queden <xliff:g id="NUMBER">%d</xliff:g> intents; si no l\'encertes, la SIM no es podrà tornar a fer servir."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Hi ha hagut un problema en l\'operació del PIN de la SIM."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Hi ha hagut un problema en l\'operació del PUK de la SIM."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"S\'ha acceptat el codi."</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>
diff --git a/packages/Keyguard/res/values-cs/strings.xml b/packages/Keyguard/res/values-cs/strings.xml
index ec2833c..e4ed02a 100644
--- a/packages/Keyguard/res/values-cs/strings.xml
+++ b/packages/Keyguard/res/values-cs/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Zadejte kód PUK SIM karty a nový kód PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Kód PUK SIM karty"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nový kód PIN SIM karty"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Líbí se mi"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Nelíbí se mi"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Srdíčko"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Pokračujte odemknutím"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Spuštění zrušeno"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Uvolněním dotyku widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> vymažete."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> nebude vymazá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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Zadali jste nesprávný kód PIN SIM karty. Nyní musíte za účelem odemknutí zařízení kontaktovat svého operátora."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Zadali jste nesprávný kód PIN SIM karty. Máte ještě <xliff:g id="NUMBER">%d</xliff:g> pokus, poté budete muset o odemknutí zařízení požádat svého operátora."</item>
+    <item quantity="other" msgid="2215723361575359486">"Zadali jste nesprávný kód PIN SIM karty. Počet zbývajících pokusů: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM kartu nelze použít. Kontaktujte operátora."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Nesprávný kód PUK SIM karty. Máte ještě <xliff:g id="NUMBER">%d</xliff:g> pokus, poté bude SIM karta natrvalo zablokována."</item>
+    <item quantity="other" msgid="5477305226026342036">"Zadali jste nesprávný kód PUK SIM karty. Počet zbývajících pokusů, po kterých bude SIM karta natrvalo zablokována: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Operace pomocí kódu PIN SIM karty se nezdařila!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Operace pomocí kódu PUK SIM karty se nezdařila!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kód byl přijat."</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>
diff --git a/packages/Keyguard/res/values-da/strings.xml b/packages/Keyguard/res/values-da/strings.xml
index cfc7464..f8f0a6f 100644
--- a/packages/Keyguard/res/values-da/strings.xml
+++ b/packages/Keyguard/res/values-da/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Indtast PUK-koden til SIM-kortet og den nye pinkode"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK-kode til SIM-kort"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Ny pinkode til SIM-kortet"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Synes om"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Synes ikke om"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Hjerte"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Lås op for at gå videre"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Starten blev annulleret"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Slip <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> for at slette."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> slettes ikke."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Forkert pinkode til SIM-kort. Du skal nu kontakte dit mobilselskab for at låse din enhed op."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Forkert pinkode til SIM-kort. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøg tilbage, før du skal kontakte dit mobilselskab for at låse din enhed op."</item>
+    <item quantity="other" msgid="2215723361575359486">"Forkert pinkode til SIM-kort. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøg tilbage."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM-kortet er ubrugeligt. Kontakt dit mobilselskab."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Forkert PUK-kode til SIM-kort. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøg tilbage, før SIM-kortet bliver permanent ubrugeligt."</item>
+    <item quantity="other" msgid="5477305226026342036">"Forkert PUK-kode til SIM-kort. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøg tilbage, før dit SIM-kort bliver permanent ubrugeligt."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Pinkoden til SIM-kortet blev afvist."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"PUK-koden til SIM-kortet blev afvist."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Koden blev accepteret."</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>
diff --git a/packages/Keyguard/res/values-de/strings.xml b/packages/Keyguard/res/values-de/strings.xml
index 85d1a4f9..edbbffd 100644
--- a/packages/Keyguard/res/values-de/strings.xml
+++ b/packages/Keyguard/res/values-de/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Geben Sie den PUK-Code der SIM-Karte und den neuen PIN-Code ein."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK-Code der SIM-Karte"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Neuer PIN-Code der SIM-Karte"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Mag ich"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Mag ich nicht"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Herz"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Zum Fortfahren entsperren"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Start abgebrochen"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Legen Sie <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> zum Löschen ab."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> wird nicht gelöscht."</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>
@@ -79,7 +86,7 @@
     <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_shift" msgid="2270748814315147690">"Shift"</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Falscher PIN-Code der SIM-Karte. Bitte wenden Sie sich an Ihren Mobilfunkanbieter, damit er Ihr Gerät entsperrt."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Falscher PIN-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER">%d</xliff:g> Versuch, bevor Sie das Gerät von Ihrem Mobilfunkanbieter entsperren lassen müssen."</item>
+    <item quantity="other" msgid="2215723361575359486">"Falscher PIN-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER">%d</xliff:g> Versuche."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Die SIM-Karte kann nicht verwendet werden. Bitte wenden Sie sich an Ihren Mobilfunkanbieter."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Falscher PUK-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER">%d</xliff:g> Versuch, bevor Ihre SIM-Karte endgültig gesperrt wird."</item>
+    <item quantity="other" msgid="5477305226026342036">"Falscher PUK-Code der SIM-Karte. Sie haben noch <xliff:g id="NUMBER">%d</xliff:g> Versuche, bevor Ihre SIM-Karte endgültig gesperrt wird."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Fehler beim Entsperren mit der PIN der SIM-Karte"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Fehler beim Entsperren mithilfe des PUK-Codes der SIM-Karte"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Code akzeptiert"</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>
diff --git a/packages/Keyguard/res/values-el/strings.xml b/packages/Keyguard/res/values-el/strings.xml
index e86f24d..be07dcd 100644
--- a/packages/Keyguard/res/values-el/strings.xml
+++ b/packages/Keyguard/res/values-el/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Πληκτρολογήστε τον κωδικό PUK της κάρτας SIM και τον νέο κωδικό PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Κωδικός PUK κάρτας SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Νέος κώδικας αριθμού PIN της κάρτας SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Επιδοκιμασία"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Αποδοκιμασία"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Καρδιά"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Ξεκλειδώστε για να συνεχίσετε"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Η εκκίνηση ακυρώθηκε"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Αποθέστε <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> για διαγραφή."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> δεν θα διαγραφεί."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Εσφαλμένος κωδικός PIN κάρτας SIM. Θα πρέπει να επικοινωνήσετε με τον πάροχο κινητής τηλεφωνίας σας για να ξεκλειδώσετε τη συσκευή σας."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Εσφαλμένος κωδικός PIN κάρτας SIM. Απομένει άλλη <xliff:g id="NUMBER">%d</xliff:g> προσπάθεια. Στη συνέχεια, θα πρέπει να επικοινωνήσετε με τον πάροχο κινητής τηλεφωνίας σας για να ξεκλειδώσετε τη συσκευή σας."</item>
+    <item quantity="other" msgid="2215723361575359486">"Εσφαλμένος κωδικός PIN κάρτας SIM. Απομένουν <xliff:g id="NUMBER">%d</xliff:g> προσπάθειες."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Η κάρτα SIM δεν μπορεί να χρησιμοποιηθεί. Επικοινωνήστε με τον πάροχο κινητής τηλεφωνίας σας."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Εσφαλμένος κωδικός PUK κάρτας SIM. Απομένει άλλη <xliff:g id="NUMBER">%d</xliff:g> προσπάθεια προτού δεν είναι πλέον δυνατή η χρήση της κάρτας SIM."</item>
+    <item quantity="other" msgid="5477305226026342036">"Εσφαλμένος κωδικός PUK κάρτας SIM. Απομένουν <xliff:g id="NUMBER">%d</xliff:g> προσπάθειες προτού δεν είναι πλέον δυνατή η χρήση της κάρτας SIM."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Αποτυχία λειτουργίας κωδικού PIN κάρτας SIM!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Αποτυχία λειτουργίας κωδικού PUK κάρτας SIM!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Αποδεκτός κωδικός!"</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>
diff --git a/packages/Keyguard/res/values-en-rGB/strings.xml b/packages/Keyguard/res/values-en-rGB/strings.xml
index 967c3fa..f0d81b8 100644
--- a/packages/Keyguard/res/values-en-rGB/strings.xml
+++ b/packages/Keyguard/res/values-en-rGB/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Type SIM PUK and new PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"New SIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Thumbs up"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Thumbs down"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Heart"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Unlock to continue"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Launch cancelled"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Drop <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> to delete."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> will not be deleted."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Incorrect SIM PIN code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before you must contact your carrier to unlock your device."</item>
+    <item quantity="other" msgid="2215723361575359486">"Incorrect SIM PIN code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM is unusable. Contact your operator."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Incorrect SIM PUK code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM becomes permanently unusable."</item>
+    <item quantity="other" msgid="5477305226026342036">"Incorrect SIM PUK code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM becomes permanently unusable."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN operation failed!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK operation failed!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Code accepted"</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>
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..f0d81b8
--- /dev/null
+++ b/packages/Keyguard/res/values-en-rIN/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"Type SIM PUK and new PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK code"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"New SIM 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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Thumbs up"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Thumbs down"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Heart"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Unlock to continue"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Launch cancelled"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Drop <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> to delete."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> will not be deleted."</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Incorrect SIM PIN code; you must now contact your operator to unlock your device."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Incorrect SIM PIN code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before you must contact your carrier to unlock your device."</item>
+    <item quantity="other" msgid="2215723361575359486">"Incorrect SIM PIN code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM is unusable. Contact your operator."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Incorrect SIM PUK code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM becomes permanently unusable."</item>
+    <item quantity="other" msgid="5477305226026342036">"Incorrect SIM PUK code; you have <xliff:g id="NUMBER">%d</xliff:g> remaining attempt/s before SIM becomes permanently unusable."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN operation failed!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK operation failed!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Code accepted"</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/strings.xml b/packages/Keyguard/res/values-es-rUS/strings.xml
index 787581a..38beca3 100644
--- a/packages/Keyguard/res/values-es-rUS/strings.xml
+++ b/packages/Keyguard/res/values-es-rUS/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Escribe el código PUK de la tarjeta SIM y un nuevo código PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Código PUK de la tarjeta SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nuevo código PIN de la tarjeta SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Votos a favor"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Votos en contra"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Corazón"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Desbloquea para continuar."</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Se canceló el inicio."</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Suelta <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> para eliminarlo."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"No se eliminará <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"El código PIN de la tarjeta SIM es incorrecto. Debes comunicarte con el proveedor para desbloquear el dispositivo."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"El código PIN de la tarjeta SIM es incorrecto. Te queda <xliff:g id="NUMBER">%d</xliff:g> intento antes de que debas comunicarte con el proveedor para desbloquear el dispositivo."</item>
+    <item quantity="other" msgid="2215723361575359486">"El código PIN de la tarjeta SIM es incorrecto. Te quedan <xliff:g id="NUMBER">%d</xliff:g> intentos."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"La tarjeta SIM no se puede utilizar. Comunícate con el proveedor."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"El código PUK de la tarjeta SIM es incorrecto. Te queda <xliff:g id="NUMBER">%d</xliff:g> intento antes de que la tarjeta SIM quede inutilizable permanentemente."</item>
+    <item quantity="other" msgid="5477305226026342036">"El código PUK de la tarjeta SIM es incorrecto. Te quedan <xliff:g id="NUMBER">%d</xliff:g> intentos antes de que la tarjeta SIM quede inutilizable permanentemente."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Error al desbloquear la tarjeta SIM con el PIN"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Error al desbloquear la tarjeta SIM con el PUK"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Código aceptado"</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>
diff --git a/packages/Keyguard/res/values-es/strings.xml b/packages/Keyguard/res/values-es/strings.xml
index d0c79eb..a93b10d 100644
--- a/packages/Keyguard/res/values-es/strings.xml
+++ b/packages/Keyguard/res/values-es/strings.xml
@@ -21,16 +21,16 @@
 <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_enter_puk_code" msgid="3035856550289724338">"Escribe el PUK de la tarjeta SIM y un nuevo código PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Código PUK de la tarjeta SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nuevo código PIN de tarjeta SIM"</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">"Cargado"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Me gusta"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"No me gusta"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Corazón"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Desbloquear para continuar"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Inicio cancelado"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Suelta <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> para eliminarlo."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> no se eliminará."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Código PIN de la tarjeta SIM incorrecto. Debes ponerte en contacto con tu operador para desbloquear el dispositivo."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Código PIN de la tarjeta SIM incorrecto. Queda <xliff:g id="NUMBER">%d</xliff:g> intento para tener que ponerte en contacto con tu operador para desbloquear el dispositivo."</item>
+    <item quantity="other" msgid="2215723361575359486">"Código PIN de la tarjeta SIM incorrecto. Quedan <xliff:g id="NUMBER">%d</xliff:g> intentos."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"La tarjeta SIM no se puede utilizar. Ponte en contacto con tu operador."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Código PUK de la tarjeta SIM incorrecto. Te queda <xliff:g id="NUMBER">%d</xliff:g> intento para que la tarjeta SIM no se pueda utilizar de forma permanente."</item>
+    <item quantity="other" msgid="5477305226026342036">"Código PUK de la tarjeta SIM incorrecto. Quedan <xliff:g id="NUMBER">%d</xliff:g> intentos para que la tarjeta SIM no se pueda utilizar de forma permanente."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Error al intentar desbloquear la tarjeta SIM con el código PIN"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Error al intentar desbloquear la tarjeta SIM con el código PUK"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Código aceptado"</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>
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..90bd829
--- /dev/null
+++ b/packages/Keyguard/res/values-et-rEE/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"Sisestage SIM-i PUK- ja uus PIN-kood"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM-i PUK-kood"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Uus SIM-i 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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Meeldib"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Ei meeldi"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Süda"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Jätkamiseks tühistage lukustus"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Käivitamine on tühistatud"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Kustutamiseks laske vidin <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> lahti."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Vidinat <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ei kustutata."</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Vale SIM-i PIN-kood, seadme avamiseks peate nüüd ühendust võtma oma operaatoriga."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Vale SIM-i PIN-kood, teil on jäänud veel <xliff:g id="NUMBER">%d</xliff:g> katse, enne kui peate seadme avamiseks operaatoriga ühendust võtma."</item>
+    <item quantity="other" msgid="2215723361575359486">"Vale SIM-i PIN-kood, teil on jäänud veel <xliff:g id="NUMBER">%d</xliff:g> katset."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM ei ole kasutatav. Võtke ühendust operaatoriga."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Vale SIM-i PUK-kood, teil on jäänud veel <xliff:g id="NUMBER">%d</xliff:g> katse, enne kui SIM püsivalt lukustatakse."</item>
+    <item quantity="other" msgid="5477305226026342036">"Vale SIM-i PUK-kood, teil on jäänud veel <xliff:g id="NUMBER">%d</xliff:g> katset, enne kui SIM püsivalt lukustatakse."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM-i PIN-koodi toiming ebaõnnestus."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM-i PUK-koodi toiming ebaõnnestus."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kood on õige."</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
deleted file mode 100644
index eb71afc..0000000
--- a/packages/Keyguard/res/values-et/activitystrings.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the 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
deleted file mode 100644
index 0a17a9c..0000000
--- a/packages/Keyguard/res/values-et/strings.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under 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/strings.xml b/packages/Keyguard/res/values-fa/strings.xml
index 83c5a34..b4a4c61 100644
--- a/packages/Keyguard/res/values-fa/strings.xml
+++ b/packages/Keyguard/res/values-fa/strings.xml
@@ -21,15 +21,15 @@
 <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_enter_puk_code" msgid="3035856550289724338">"‏PUK سیم کارت و کد پین جدید را تایپ کنید"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"‏کد PUK سیم کارت"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"کد پین جدید سیم کارت"</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="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>
@@ -41,11 +41,11 @@
     <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_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_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_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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"رأی موافق"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"رأی مخالف"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"قلب"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"برای ادامه قفل را باز کنید"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"راه‌اندازی لغو شد"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"جهت حذف، <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> را بکشید."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> پاک نخواهد شد."</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>
@@ -105,18 +112,17 @@
     <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_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_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>
@@ -125,10 +131,23 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"کد پین سیم کارت اشتباه است، اکنون برای گشودن قفل دستگاهتان باید با شرکت مخابراتی تماس بگیرید."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"کد پین سیم کارت اشتباه است، <xliff:g id="NUMBER">%d</xliff:g> بار دیگر می‌توانید تلاش کنید و پس از آن برای گشودن قفل دستگاهتان باید با شرکت مخابراتی تماس بگیرید."</item>
+    <item quantity="other" msgid="2215723361575359486">"کد پین سیم کارت اشتباه است، <xliff:g id="NUMBER">%d</xliff:g> بار دیگر می‌توانید تلاش کنید."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"سیم کارت غیر قابل استفاده است. با شرکت مخابراتی‌تان تماس بگیرید."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"‏کد PUK سیم کارت اشتباه است، <xliff:g id="NUMBER">%d</xliff:g> بار دیگر می‌توانید تلاش کنید و پس از آن سیم کارت به صورت دائم غیر قابل استفاده می‌شود."</item>
+    <item quantity="other" msgid="5477305226026342036">"‏کد PUK سیم کارت اشتباه است، <xliff:g id="NUMBER">%d</xliff:g> بار دیگر می‌توانید تلاش کنید و پس از آن سیم کارت به طور دائم غیر قابل استفاده می‌شود."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"عملیات پین سیم کارت ناموفق بود!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"‏عملیات PUK سیم کارت ناموفق بود!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"کد پذیرفته شد!"</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>
diff --git a/packages/Keyguard/res/values-fi/strings.xml b/packages/Keyguard/res/values-fi/strings.xml
index dbca50d..e079ffa 100644
--- a/packages/Keyguard/res/values-fi/strings.xml
+++ b/packages/Keyguard/res/values-fi/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Anna SIM-kortin PUK-koodi ja uusi PIN-koodi"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM-kortin PUK-koodi"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Uusi SIM-kortin 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Tykkään"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"En tykkää"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Sydän"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Jatka poistamalla lukitus"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Käynnistys peruutettu"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Poista <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> pudottamalla."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Kohdetta <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ei poisteta."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Virheellinen SIM-kortin PIN-koodi. Sinun on nyt otettava yhteys operaattoriin laitteen lukituksen avaamiseksi."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Virheellinen SIM-kortin PIN-koodi. Sinulla on <xliff:g id="NUMBER">%d</xliff:g> yritys jäljellä, ennen kuin sinun on otettava yhteys operaattoriin laitteen lukituksen avaamiseksi."</item>
+    <item quantity="other" msgid="2215723361575359486">"Virheellinen SIM-kortin PIN-koodi. Sinulla on <xliff:g id="NUMBER">%d</xliff:g> yritystä jäljellä."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM-kortti on käyttökelvoton. Ota yhteys operaattoriin."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Virheellinen SIM-kortin PUK-koodi. Sinulla on <xliff:g id="NUMBER">%d</xliff:g> yritys jäljellä, ennen kuin SIM-kortista tulee pysyvästi käyttökelvoton."</item>
+    <item quantity="other" msgid="5477305226026342036">"Virheellinen SIM-kortin PUK-koodi. Sinulla on <xliff:g id="NUMBER">%d</xliff:g> yritystä jäljellä, ennen kuin SIM-kortista tulee pysyvästi käyttökelvoton."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM-kortin PIN-toiminto epäonnistui!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM-kortin PUK-toiminto epäonnistui!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Koodi hyväksytty!"</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>
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..59f27aa
--- /dev/null
+++ b/packages/Keyguard/res/values-fr-rCA/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"Entrez le code PUK et le nouveau NIP de la carte SIM"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Code PUK de la carte SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nouveau NIP de la carte SIM"</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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"J\'aime"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Je n\'aime pas"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Cœur"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Déverrouiller pour continuer"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Lancement annulé"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Déposez <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> pour supprimer."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ne sera pas supprimé."</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"NIP de carte SIM incorrect. Vous devez maintenant communiquer avec votre fournisseur de services pour déverrouiller votre appareil."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"NIP de carte SIM incorrect. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative. Après cela, vous devrez communiquer avec votre fournisseur de services pour déverrouiller votre appareil."</item>
+    <item quantity="other" msgid="2215723361575359486">"NIP de carte SIM incorrect. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative(s)."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"La carte SIM est inutilisable. Communiquez avec votre fournisseur de services."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Code PUK de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative avant que votre carte SIM devienne définitivement inutilisable."</item>
+    <item quantity="other" msgid="5477305226026342036">"Code PUK de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative(s) avant que votre carte SIM devienne définitivement inutilisable."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Le déverrouillage par NIP de la carte SIM a échoué."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Le déverrouillage de la carte SIM par code PUK a échoué."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Code accepté"</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/strings.xml b/packages/Keyguard/res/values-fr/strings.xml
index 250a136..b910dd4 100644
--- a/packages/Keyguard/res/values-fr/strings.xml
+++ b/packages/Keyguard/res/values-fr/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Saisissez la clé PUK et le nouveau code PIN de la carte SIM."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Clé PUK de la carte SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nouveau code PIN de la carte SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"J\'aime"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Je n\'aime pas"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Cœur"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Déverrouillez l\'appareil pour continuer."</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Lancement annulé."</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Relâchez le widget \"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>\" pour le supprimer."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Le widget \"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>\" ne va pas être supprimé."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Code PIN de la carte SIM incorrect. Vous devez désormais contacter votre opérateur pour déverrouiller votre appareil."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Code PIN de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative. Après cela, vous devrez contacter votre opérateur pour déverrouiller votre appareil."</item>
+    <item quantity="other" msgid="2215723361575359486">"Code PIN de la carte SIM incorrect. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentatives."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"La carte SIM est inutilisable. Veuillez contacter votre opérateur."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Clé PUK de la carte SIM incorrecte. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentative avant que votre carte SIM ne devienne définitivement inutilisable."</item>
+    <item quantity="other" msgid="5477305226026342036">"Clé PUK de la carte SIM incorrecte. Il vous reste <xliff:g id="NUMBER">%d</xliff:g> tentatives avant que votre carte SIM ne devienne définitivement inutilisable."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Échec du déverrouillage à l\'aide du code PIN de la carte SIM."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Échec du déverrouillage à l\'aide de la clé PUK de la carte SIM."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Code accepté."</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>
diff --git a/packages/Keyguard/res/values-hi/strings.xml b/packages/Keyguard/res/values-hi/strings.xml
index 714d9fb..8c94eb3 100644
--- a/packages/Keyguard/res/values-hi/strings.xml
+++ b/packages/Keyguard/res/values-hi/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"सिम PUK और नया PIN कोड लिखें"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"सिम PUK कोड"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"नया सिम 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>
@@ -60,17 +60,24 @@
     <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="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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"पसंद"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"नापसंद"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"दिल"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"जारी रखने के लिए अनलॉक करें"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"लॉन्‍च रद्द कर दिया गया"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"हटाने के लिए <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> खींचें."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> को नहीं हटाया जाएगा."</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>
@@ -92,12 +99,12 @@
     <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_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_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>
@@ -105,30 +112,42 @@
     <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_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_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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"गलत सिम PIN कोड अपने उपकरण को अनलॉक करने के लिए अब आपको अपने वाहक से संपर्क करना होगा."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"गलत सिम PIN कोड, अपने उपकरण को अनलॉक करने के लिए अपने वाहक से संपर्क करने से पहले आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष है."</item>
+    <item quantity="other" msgid="2215723361575359486">"गलत सिम PIN कोड, आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष हैं."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"सिम अनुपयोगी है. अपने वाहक से संपर्क करें."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"गलत सिम PUK कोड, सिम के स्थायी रूप से अनुपयोगी हो जाने से पहले आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष है."</item>
+    <item quantity="other" msgid="5477305226026342036">"गलत सिम PUK कोड, सिम के स्थायी रूप से अनुपयोगी हो जाने से पहले आपके पास <xliff:g id="NUMBER">%d</xliff:g> प्रयास शेष हैं."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"सिम PIN की कार्यवाही विफल रही!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"सिम PUK की कार्यवाही विफल रही!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"कोड स्वीकार किया गया!"</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>
diff --git a/packages/Keyguard/res/values-hr/strings.xml b/packages/Keyguard/res/values-hr/strings.xml
index 70e6305..3843549 100644
--- a/packages/Keyguard/res/values-hr/strings.xml
+++ b/packages/Keyguard/res/values-hr/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Unesite PUK i novi PIN kôd SIM kartice"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK kôd SIM kartice"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Novi PIN kôd SIM kartice"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Palac gore"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Palac dolje"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Srce"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Otključajte za nastavak"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Pokretanje je otkazano"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Ispustite widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> da biste ga izbrisali."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Widget <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> neće se izbrisati."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Netočan PIN kôd SIM kartice; sada morate kontaktirati svog mobilnog operatera da bi otključao vaš uređaj."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Netočan PIN kôd SIM kartice; imate još <xliff:g id="NUMBER">%d</xliff:g> pokušaj prije nego što budete morali kontaktirati svog mobilnog operatera da bi otključao vaš uređaj."</item>
+    <item quantity="other" msgid="2215723361575359486">"Netočan PIN kôd SIM kartice; imate još ovoliko preostalih pokušaja: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM kartica nije upotrebljiva. Kontaktirajte svog mobilnog operatera."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Netočan PUK kôd SIM kartice; imate još <xliff:g id="NUMBER">%d</xliff:g> pokušaj prije nego što SIM kartica postane trajno neupotrebljiva."</item>
+    <item quantity="other" msgid="5477305226026342036">"Netočan PUK kôd SIM kartice; imate još nekoliko preostalih pokušaja (<xliff:g id="NUMBER">%d</xliff:g>) prije nego što SIM kartica postane trajno neupotrebljiva."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Operacija PIN-a SIM kartice nije uspjela!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Operacija PUK-a SIM kartice nije uspjela!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kôd je prihvaćen!"</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>
diff --git a/packages/Keyguard/res/values-hu/strings.xml b/packages/Keyguard/res/values-hu/strings.xml
index 611602e..bf6f528 100644
--- a/packages/Keyguard/res/values-hu/strings.xml
+++ b/packages/Keyguard/res/values-hu/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Írja be a SIM kártya PUK kódját, majd az új PIN kódot"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM kártya PUK kódja"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Új PIN kód a SIM kártyához"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Tetszik"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Nem tetszik"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Szív"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"A folytatáshoz oldja fel a billentyűzárat"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Indítás törölve"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Engedje el a(z) <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> törléséhez."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"A(z) <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> nem lesz törölve."</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>
@@ -105,13 +112,12 @@
     <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_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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Helytelen PIN kód a SIM kártyához; vegye fel a kapcsolatot szolgáltatójával az eszköz feloldásához."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Helytelen PIN kód a SIM kártyához; még <xliff:g id="NUMBER">%d</xliff:g> próbálkozása van, mielőtt fel kellene vennie a kapcsolatot szolgáltatójával az eszköz feloldásához."</item>
+    <item quantity="other" msgid="2215723361575359486">"Helytelen PIN kód a SIM kártyához; még <xliff:g id="NUMBER">%d</xliff:g> próbálkozása van."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"A SIM kártya használhatatlan. Vegye fel a kapcsolatot szolgáltatójával."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Helytelen PUK kód a SIM kártyához; még <xliff:g id="NUMBER">%d</xliff:g> próbálkozása van, mielőtt a SIM kártya végleg használhatatlan lesz."</item>
+    <item quantity="other" msgid="5477305226026342036">"Helytelen PUK kód a SIM kártyához; még <xliff:g id="NUMBER">%d</xliff:g> próbálkozása van, mielőtt a SIM kártya végleg használhatatlan lesz."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"A SIM kártya PIN-művelete sikertelen!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"A SIM kártya PUK-művelete sikertelen!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kód elfogadva."</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>
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..ff87920
--- /dev/null
+++ b/packages/Keyguard/res/values-hy-rAM/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"Մուտքագրեք SIM PUK-ը և նոր PIN կոդը"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK կոդը"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Նոր SIM 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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Լավն է"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Լավը չէ"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Սիրտ"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Շարունակելու համար ապակողպեք"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Գործարկումը չեղարկվեց"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> վիջեթը ջնջելու համար բաց թողեք այն այստեղ:"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> վիջեթը չի ջնջվի:"</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Սխալ SIM PIN կոդի պատճառով պետք է դիմեք ձեր օպերատորին՝ սարքն արգելաբացելու համար:"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"SIM PIN կոդը սխալ է: Մնաց <xliff:g id="NUMBER">%d</xliff:g> փորձ, որից հետո պետք է դիմեք ձեր օպերատորին՝ սարքն արգելաբացելու համար:"</item>
+    <item quantity="other" msgid="2215723361575359486">"SIM PIN կոդը սխալ է: Մնաց <xliff:g id="NUMBER">%d</xliff:g> փորձ:"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM-ը հնարավոր չէ օգտագործել: Դիմեք ձեր օպերատորին:"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"SIM PUK կոդը սխալ է: Մնաց <xliff:g id="NUMBER">%d</xliff:g> փորձ՝ մինչև SIM-ի ընդմիշտ արգելափակումը:"</item>
+    <item quantity="other" msgid="5477305226026342036">"SIM PUK կոդը սխալ է: Մնաց <xliff:g id="NUMBER">%d</xliff:g> փորձ՝ մինչև SIM-ի ընդմիշտ արգելափակումը:"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN գործողությունը ձախողվեց:"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK գործողությունը ձախողվեց:"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Կոդն ընդունվեց:"</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/strings.xml b/packages/Keyguard/res/values-in/strings.xml
index 9f731ab..9e19472 100644
--- a/packages/Keyguard/res/values-in/strings.xml
+++ b/packages/Keyguard/res/values-in/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Ketik kode PIN baru dan PUK SIM"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Kode PUK SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Kode PIN SIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Bagus"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Jelek"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Hati"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Buka kunci untuk melanjutkan"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Peluncuran dibatalkan"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Jatuhkan <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> untuk menghapus."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> tidak akan dihapus."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Kode PIN SIM salah. Hubungi operator untuk membuka kunci perangkat."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Kode PIN SIM salah, sisa <xliff:g id="NUMBER">%d</xliff:g> percobaan sebelum Anda harus menghubungi operator untuk membuka kunci perangkat."</item>
+    <item quantity="other" msgid="2215723361575359486">"Kode PIN SIM salah, sisa <xliff:g id="NUMBER">%d</xliff:g> percobaan."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM tidak dapat digunakan. Hubungi operator Anda."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Kode PUK SIM salah, sisa <xliff:g id="NUMBER">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan selamanya."</item>
+    <item quantity="other" msgid="5477305226026342036">"Kode PUK SIM salah, sisa <xliff:g id="NUMBER">%d</xliff:g> percobaan sebelum SIM tidak dapat digunakan selamanya."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Operasi PIN SIM gagal!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Operasi PUK SIM gagal!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kode Diterima!"</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>
diff --git a/packages/Keyguard/res/values-it/strings.xml b/packages/Keyguard/res/values-it/strings.xml
index 4eda348..7212e5e 100644
--- a/packages/Keyguard/res/values-it/strings.xml
+++ b/packages/Keyguard/res/values-it/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Digita il PUK della SIM e il nuovo codice PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Codice PUK della SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nuovo PIN della SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Mi piace"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Pollice giù"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Cuore"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Sblocca per continuare"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Avvio annullato"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Rilascia <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> per eliminarlo."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> non sarà eliminato."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Codice PIN della SIM errato. Devi contattare l\'operatore per sbloccare il dispositivo."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Codice PIN della SIM errato. Hai ancora <xliff:g id="NUMBER">%d</xliff:g> tentativo a disposizione, dopodiché dovrai contattare l\'operatore per sbloccare il dispositivo."</item>
+    <item quantity="other" msgid="2215723361575359486">"Codice PIN della SIM errato. Hai ancora <xliff:g id="NUMBER">%d</xliff:g> tentativi a disposizione."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM inutilizzabile. Contatta il tuo operatore."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Codice PUK della SIM errato. Hai ancora <xliff:g id="NUMBER">%d</xliff:g> tentativo a disposizione prima che la SIM diventi definitivamente inutilizzabile."</item>
+    <item quantity="other" msgid="5477305226026342036">"Codice PUK della SIM errato. Hai ancora <xliff:g id="NUMBER">%d</xliff:g> tentativi a disposizione prima che la SIM diventi definitivamente inutilizzabile."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Operazione con PIN della SIM non riuscita."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Operazione con PUK della SIM non riuscita."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Codice accettato."</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>
diff --git a/packages/Keyguard/res/values-iw/strings.xml b/packages/Keyguard/res/values-iw/strings.xml
index 8d36309..12b45e4 100644
--- a/packages/Keyguard/res/values-iw/strings.xml
+++ b/packages/Keyguard/res/values-iw/strings.xml
@@ -20,49 +20,49 @@
 
 <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_enter_pin_code" msgid="3037685796058495017">"‏הקלד קוד PIN"</string>
+    <string name="keyguard_password_enter_puk_code" msgid="3035856550289724338">"‏הקלד קוד PUK של כרטיס SIM וקוד PIN חדש"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"‏קוד PUK של כרטיס SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"‏מספר PIN חדש של כרטיס SIM"</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_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="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_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_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_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_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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"אהבתי"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"לא אהבתי"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"לב"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"בטל נעילה כדי להמשיך"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"ההפעלה בוטלה"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"שחרר את <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> למחיקה."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> לא יימחק."</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>
@@ -95,30 +102,29 @@
     <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_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_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_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_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_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_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_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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"‏מספר PIN שגוי של כרטיס ה-SIM. עליך ליצור כעת קשר עם הספק על מנת לבטל את נעילת המכשיר."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"‏מספר PIN שגוי של כרטיס ה-SIM. נותר לך ניסיון <xliff:g id="NUMBER">%d</xliff:g> נוסף לפני שיהיה עליך ליצור קשר עם הספק על מנת לבטל את נעילת המכשיר."</item>
+    <item quantity="other" msgid="2215723361575359486">"‏מספר PIN שגוי של כרטיס ה-SIM. נותרו לך <xliff:g id="NUMBER">%d</xliff:g> ניסיונות נוספים."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"‏לא ניתן להשתמש בכרטיס ה-SIM. צור קשר עם הספק."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"‏קוד PUK שגוי של כרטיס ה-SIM. נותר לך ניסיון <xliff:g id="NUMBER">%d</xliff:g> נוסף לפני שכרטיס ה-SIM ינעל לצמיתות."</item>
+    <item quantity="other" msgid="5477305226026342036">"‏קוד PUK שגוי של כרטיס ה-SIM. נותרו לך <xliff:g id="NUMBER">%d</xliff:g> ניסיונות נוספים לפני שכרטיס ה-SIM ינעל לצמיתות."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"‏פעולת מספר ה-PIN של כרטיס ה-SIM נכשלה!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"‏פעולת קוד ה-PUK של כרטיס ה-SIM נכשלה!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"הקוד התקבל!"</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>
diff --git a/packages/Keyguard/res/values-ja/strings.xml b/packages/Keyguard/res/values-ja/strings.xml
index 92e308b..5106271 100644
--- a/packages/Keyguard/res/values-ja/strings.xml
+++ b/packages/Keyguard/res/values-ja/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"PUKと新しいPINコードを入力"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUKコード"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"新しいSIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"グッド"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"イマイチ"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"ハート"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"続行するにはロックを解除してください"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"起動をキャンセルしました"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"削除するには<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>をドロップしてください。"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>は削除されません。"</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM PINコードが無効です。お使いの端末をロック解除するには携帯通信会社にお問い合わせいただく必要があります。"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"SIM PINコードが無効です。入力できるのはあと<xliff:g id="NUMBER">%d</xliff:g>回です。この回数を超えると、お使いの端末をロック解除するのに携帯通信会社にお問い合わせいただく必要があります。"</item>
+    <item quantity="other" msgid="2215723361575359486">"SIM PINコードが無効です。入力できるのはあと<xliff:g id="NUMBER">%d</xliff:g>回です。"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIMは使用できません。携帯通信会社にお問い合わせください。"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"SIM PUKコードが無効です。入力できるのはあと<xliff:g id="NUMBER">%d</xliff:g>回です。この回数を超えるとSIMは完全に使用できなくなります。"</item>
+    <item quantity="other" msgid="5477305226026342036">"SIM PUKコードが無効です。入力できるのはあと<xliff:g id="NUMBER">%d</xliff:g>回です。この回数を超えるとSIMは完全に使用できなくなります。"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN操作に失敗しました。"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK操作に失敗しました。"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"コードが承認されました。"</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>
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..3d7af75
--- /dev/null
+++ b/packages/Keyguard/res/values-ka-rGE/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"დაბეჭდეთ SIM-ის PUK კოდი და ახალი PIN კოდი"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK კოდი"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"SIM-ის ახალი 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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"ზევით აწეული ცერი"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"ქვევით დახრილი ცერი"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"გული"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"განბლოკეთ გასაგრძელებლად"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"გამოძახება გაუქმდა"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"ჩააგდეთ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> წასაშლელად."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> არ წაიშლება."</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM-ის არასწორი PIN კოდი. თქვენ ახლა მოგიწევთ მოწყობილობის განსაბლოკად მიმართოთ ოპერატორს."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"SIM-ის არასწორი PIN კოდი. თქვენ დაგრჩათ <xliff:g id="NUMBER">%d</xliff:g> მცდელობა, სანამ მოგიწევთ თქვენი მოწყობილობის განსაბლოკად ოპერატორთან დაკავშირება."</item>
+    <item quantity="other" msgid="2215723361575359486">"SIM-ის არასწორი PIN კოდი. თქვენ დაგრჩათ <xliff:g id="NUMBER">%d</xliff:g> მცდელობა."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM გამოუსადეგარია. დაუკავშირდით ოპერატორს."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"არასწორი SIM PUK კოდი. თქვენ დაგრჩათ <xliff:g id="NUMBER">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდებოდეს."</item>
+    <item quantity="other" msgid="5477305226026342036">"არასწორი SIM PUK კოდი. თქვენ დაგრჩათ <xliff:g id="NUMBER">%d</xliff:g> მცდელობა, სანამ SIM სამუდამოდ გამოუსადეგარი გახდებოდეს."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN ოპერაცია ჩაიშალა!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK ოპერაცია ჩაიშალა!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"კოდი მიღებულია!"</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..b09c749
--- /dev/null
+++ b/packages/Keyguard/res/values-km-rKH/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"បញ្ចូល​លេខ​កូដ PUK  និង​​ PIN ថ្មី​របស់​ស៊ីម"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"លេខ​កូដ PUK ស៊ីម"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"លេខ​កូដ 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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"មេដៃ​ឡើង"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"មេដៃ​ចុះ"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"បេះដូង"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"ដោះ​សោ ​ដើម្បី​បន្ត"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"បាន​បោះបង់​ការ​ចាប់ផ្ដើម"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"ទម្លាក់ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ដើម្បី​លុប។"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> នឹង​មិន​ត្រូវ​បាន​លុប​។"</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"លេខ​កូដ PIN ស៊ីម​មិន​ត្រឹមត្រូវ អ្នក​ត្រូវ​ទាក់ទង​ក្រុមហ៊ុន​បញ្ជូន​របស់​អ្នក​ឥឡូវ​នេះ ដើម្បី​ដោះ​សោ​ឧបករណ៍​របស់​អ្នក។"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"លេខ​កូដ PIN ស៊ីម​មិន​​ត្រឹមត្រូវ​, អ្នក​មាន <xliff:g id="NUMBER">%d</xliff:g> ការ​ព្យាយាម​ដែល​នៅសល់​មុន​ពេល​អ្នក​ត្រូវ​​ទាក់ទង​ក្រុម​ហ៊ុន​​​បញ្ជូន​របស់​អ្នក​​ ដើម្បី​​​ដោះ​សោ​ឧបករណ៍​របស់​អ្នក​។"</item>
+    <item quantity="other" msgid="2215723361575359486">"លេខ​កូដ​ PIN ស៊ីម​មិន​ត្រឹមត្រូវ​, អ្នក​មាន <xliff:g id="NUMBER">%d</xliff:g> ការ​ព្យាយាម​ដែល​នៅ​​សល់​។"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"ស៊ីម​មិន​អាច​ប្រើ​បាន។ ទាក់ទង​ក្រុមហ៊ុន​បញ្ជូន​របស់​អ្នក។"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"លេខ​កូដ PUK ស៊ីម​មិន​ត្រឹមត្រូវ, អ្នក​មាន <xliff:g id="NUMBER">%d</xliff:g> ការ​ព្យាយាម​ដែល​នៅ​សល់ មុន​ពេល​ស៊ីម​​ក្លាយ​ជា​មិន​អាច​ប្រើ​បាន​ជា​អចិន្ត្រៃយ៍​។"</item>
+    <item quantity="other" msgid="5477305226026342036">"លេខ​កូដ PUK ស៊ីម​មិន​ត្រឹមត្រូវ, អ្នក​មាន <xliff:g id="NUMBER">%d</xliff:g> ការ​ព្យាយាម​ដែល​នៅ​សល់ មុន​ពេល​ស៊ីម​​ក្លាយ​ជា​មិន​អាច​ប្រើ​បាន​ជា​អចិន្ត្រៃយ៍​។"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"បាន​បរាជ័យ​ក្នុង​ការ​ប្រតិបត្តិ​លេខ​កូដ PIN ស៊ីម!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"បាន​បរាជ័យ​ក្នុង​ការ​ប្រតិបត្តិ​​លេខ​កូដ PUK ស៊ីម!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"បាន​ទទួល​យក​លេខ​កូដ​!"</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/strings.xml b/packages/Keyguard/res/values-ko/strings.xml
index dfac106..2a7200c 100644
--- a/packages/Keyguard/res/values-ko/strings.xml
+++ b/packages/Keyguard/res/values-ko/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"SIM PUK 및 새 PIN 코드 입력"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK 코드"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"새 SIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"좋아요"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"싫어요"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"하트"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"계속하려면 잠금해제합니다."</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"실행 취소됨"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"삭제하려면 <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>을(를) 드롭합니다."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>은(는) 삭제되지 않습니다."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM PIN 코드가 잘못되었습니다. 이동통신사에 문의하여 기기를 잠금 해제해야 합니다."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"SIM PIN 코드가 잘못되었습니다. <xliff:g id="NUMBER">%d</xliff:g>회 이상 실패할 경우 이동통신사에 문의하여 기기를 잠금 해제해야 합니다."</item>
+    <item quantity="other" msgid="2215723361575359486">"SIM PIN 코드가 잘못되었습니다. <xliff:g id="NUMBER">%d</xliff:g>번의 기회가 남았습니다."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM을 사용할 수 없습니다. 이동통신사에 문의하세요."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"SIM PUK 코드가 잘못되었습니다. <xliff:g id="NUMBER">%d</xliff:g>회 이상 실패할 경우 SIM을 완전히 사용할 수 없습니다."</item>
+    <item quantity="other" msgid="5477305226026342036">"SIM PUK 코드가 잘못되었습니다. <xliff:g id="NUMBER">%d</xliff:g>회 이상 실패할 경우 SIM을 완전히 사용할 수 없습니다."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN 작업이 실패했습니다."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK 작업이 실패했습니다."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"코드 승인 완료"</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>
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..81c10181
--- /dev/null
+++ b/packages/Keyguard/res/values-lo-rLA/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"ປະເພດ PUK ຂອງ SIM ແລະລະຫັດ PIN ໃໝ່"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"ລະຫັດ PUK ຂອງ SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"ລະຫັດ PIN ໃໝ່ຂອງ SIM"</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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"ເລື່ອນນິ້ວໂປ້ຂຶ້ນ"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"ເລື່ອນນິ້ວໂປ້ລົງ"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"ຫົວໃຈ"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"ປົດລັອກເພື່ອດຳເນີນການຕໍ່"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"ການເປີດໃຊ້ຖືກຍົກເລີກ"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"ວາງ <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ເພື່ອລຶບ."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ຈະບໍ່ຖືກລຶບອອກ"</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"ລະຫັດ PIN ຂອງ SIM ບໍ່ຖືກຕ້ອງທ່ານຕ້ອງຕິດຕໍ່ຫາຜູ່ໃຫ້ບໍລິການ ເພື່ອປົດລັອກອຸປະກອນຂອງທ່ານ."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"ລະຫັດ PIN ຂອງ SIM ບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອກ່ອນທີ່ທ່ານຈະຕ້ອງຕິດຕໍ່ຫາຜູ່ໃຫ້ບໍລິການຂອງທ່ານ ເພື່ອປົດລັອກອຸປະກອນຂອງທ່ານ."</item>
+    <item quantity="other" msgid="2215723361575359486">"ລະຫັດ PIN ຂອງ SIM ບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອ."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM ໃຊ້ບໍ່ໄດ້ແລ້ວ. ກະລຸນາຕິດຕໍ່ຫາຜູ່ໃຫ້ບໍລິການຂອງທ່ານ."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"ລະຫັດ PUK ຂອງ SIM ບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຂອງທ່ານຈະໃຊ້ບໍ່ໄດ້ຢ່າງຖາວອນ."</item>
+    <item quantity="other" msgid="5477305226026342036">"ລະຫັດ PUK ຂອງ SIM ບໍ່ຖືກຕ້ອງ, ທ່ານສາມາດລອງໄດ້ອີກ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອກ່ອນທີ່ SIM ຂອງທ່ານຈະໃຊ້ບໍ່ໄດ້ຢ່າງຖາວອນ."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"PIN ຂອງ SIM ເຮັດວຽກລົ້ມເຫຼວ!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"PUK ຂອງ SIM ເຮັດວຽກລົ້ມເຫຼວ!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"ລະ​ຫັດ​ຖືກຕອບຮັບແລ້ວ!"</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/strings.xml b/packages/Keyguard/res/values-lt/strings.xml
index 29f62a7..ff3034a 100644
--- a/packages/Keyguard/res/values-lt/strings.xml
+++ b/packages/Keyguard/res/values-lt/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Įveskite SIM kortelės PUK kodą ir naują PIN kodą"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM kortelės PUK kodas"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Naujas SIM kortelės 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Patinka"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Nepatinka"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Širdis"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Jei norite tęsti, atrakinkite"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Paleidimas atšauktas"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Paleiskite „<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>“, kad jį ištrintumėte."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"„<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>“ nebus ištrintas."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Netinkamas SIM kortelės PIN kodas. Reikės susisiekti su operatoriumi, kad atrakintų įrenginį."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Netinkamas SIM kortelės PIN kodas. Jums liko <xliff:g id="NUMBER">%d</xliff:g> band. Paskui reikės susisiekti su operatoriumi, kad jis atrakintų įrenginį."</item>
+    <item quantity="other" msgid="2215723361575359486">"Netinkamas SIM kortelės PIN kodas, liko <xliff:g id="NUMBER">%d</xliff:g> band."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Nebegalima naudoti SIM kortelės. Susisiekite su operatoriumi."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Netinkamas SIM kortelės PUK kodas. Liko <xliff:g id="NUMBER">%d</xliff:g> band. Paskui visiškai nebegalėsite naudoti SIM kortelės."</item>
+    <item quantity="other" msgid="5477305226026342036">"Netinkamas SIM kortelės PUK kodas. Liko <xliff:g id="NUMBER">%d</xliff:g> band. Paskui visiškai nebegalėsite naudoti SIM kortelės."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Nepavyko atlikti SIM kortelės PIN kodo operacijos."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Nepavyko atlikti SIM kortelės PUK kodo operacijos."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kodas priimtas."</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>
diff --git a/packages/Keyguard/res/values-lv/strings.xml b/packages/Keyguard/res/values-lv/strings.xml
index aa13934..539f91d 100644
--- a/packages/Keyguard/res/values-lv/strings.xml
+++ b/packages/Keyguard/res/values-lv/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Ievadiet SIM kartes PUK kodu un jaunu PIN kodu."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM kartes PUK kods"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Jauns SIM kartes 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Patīk"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Nepatīk"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Sirds"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Atbloķējiet, lai turpinātu."</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Palaišana atcelta"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Velciet logrīku <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>, lai to izdzēstu."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Logrīks <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> netiks izdzēsts."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Nepareizs SIM kartes PIN kods. Lai atbloķētu ierīci, sazinieties ar mobilo sakaru operatoru."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Nepareizs SIM kartes PIN kods. Varat mēģināt vēl <xliff:g id="NUMBER">%d</xliff:g> reizi. Kļūdas gadījumā būs jāsazinās ar mobilo sakaru operatoru, lai tas atbloķētu jūsu ierīci."</item>
+    <item quantity="other" msgid="2215723361575359486">"Nepareizs SIM kartes PIN kods. Varat mēģināt vēl <xliff:g id="NUMBER">%d</xliff:g> reizi(-es)."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM karte nav izmantojama. Sazinieties ar mobilo sakaru operatoru."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Nepareizs SIM kartes PUK kods. Varat mēģināt vēl <xliff:g id="NUMBER">%d</xliff:g> reizi. Kļūdas gadījumā SIM karte kļūs neizmantojama."</item>
+    <item quantity="other" msgid="5477305226026342036">"Nepareizs SIM kartes PUK kods. Varat mēģināt vēl <xliff:g id="NUMBER">%d</xliff:g> reizi(-es). Kļūdas gadījumā SIM karte kļūs neizmantojama."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM kartes PIN koda ievadīšana neizdevās."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM kartes PUK koda ievadīšana neizdevās."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kods ir pieņemts!"</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>
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..e1b833e
--- /dev/null
+++ b/packages/Keyguard/res/values-mn-rMN/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"СИМ ПҮК-г бичээд шинэ ПИН код оруулна уу"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"СИМ ПҮК код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Шинэ СИМ ПИН код"</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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Сайн"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Онцгүй"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Зүрх"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Үргэлжлүүлэхийн тулд түгжээг тайлна уу"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Эхлүүлэхийг цуцалсан"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Устгахын тулд <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>-г тавина уу."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> устахгүй."</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"СИМ ПИН код буруу, та төхөөрөмжийн түгжээг тайлахын тулд оператор компанитай холбоо барих шаардлагатай."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"СИМ ПИН код буруу байна, танд мобайл оператор компанитай холбогдохгүйгээр төхөөрөмжийн түгжээг тайлахад <xliff:g id="NUMBER">%d</xliff:g> оролдлого хийх боломж үлдсэн байна."</item>
+    <item quantity="other" msgid="2215723361575359486">"СИМ ПИН код буруу байна, танд <xliff:g id="NUMBER">%d</xliff:g> оролдлого хийх боломж үлдлээ."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"СИМ ашиглах боломжгүй. Өөрийн оператор компанитай холбоо барина уу."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"СИМ ПҮК код буруу, таны СИМ бүрмөсөн ашиглалтгүй болохоос өмнө <xliff:g id="NUMBER">%d</xliff:g> оролдлого хийх боломж үлдлээ."</item>
+    <item quantity="other" msgid="5477305226026342036">"СИМ ПҮК код буруу, таны СИМ бүрмөсөн ашиглалтгүй болохоос өмнө <xliff:g id="NUMBER">%d</xliff:g> оролдлого хийх боломж үлдлээ."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"СИМ ПИН ажиллуулах амжилтгүй боллоо!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"СИМ ПҮК ажиллуулах амжилтгүй боллоо!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Код зөвшөөрөгдлөө!"</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..a6845bc
--- /dev/null
+++ b/packages/Keyguard/res/values-ms-rMY/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"Taip PUK SIM dan kod PIN baharu"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Kod PUK SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Kod PIN SIM 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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Menyukai"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Tidak diterima"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Jantung"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Buka kunci untuk meneruskan"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Pelancaran dibatalkan"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Jatuhkan <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> untuk memadam."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> tidak akan dipadamkan."</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Kod PIN SIM tidak betul, jadi anda harus menghubungi pembawa anda untuk membuka kunci peranti."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Kod PIN SIM tidak betul. Anda mempunyai <xliff:g id="NUMBER">%d</xliff:g> percubaan lagi sebelum anda harus menghubungi pembawa anda untuk membuka kunci peranti."</item>
+    <item quantity="other" msgid="2215723361575359486">"Kod PIN SIM tidak betul, anda mempunyai <xliff:g id="NUMBER">%d</xliff:g> percubaan lagi."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM tidak boleh digunakan. Hubungi pembawa anda."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Kod PUK SIM tidak betul, anda mempunyai <xliff:g id="NUMBER">%d</xliff:g> percubaan lagi sebelum SIM tidak boleh digunakan secara kekal."</item>
+    <item quantity="other" msgid="5477305226026342036">"Kod PUK SIM tidak betul, anda mempunyai <xliff:g id="NUMBER">%d</xliff:g> percubaan lagi sebelum SIM tidak boleh digunakan secara kekal."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Operasi PIN SIM gagal!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Operasi PUK SIM gagal!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kod Diterima!"</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
deleted file mode 100644
index 04e2184..0000000
--- a/packages/Keyguard/res/values-ms/activitystrings.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the 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
deleted file mode 100644
index 0aeeeb5..0000000
--- a/packages/Keyguard/res/values-ms/strings.xml
+++ /dev/null
@@ -1,138 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/* //device/apps/common/assets/res/any/strings.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under 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/strings.xml b/packages/Keyguard/res/values-nb/strings.xml
index 6a5bfa9..71138a5 100644
--- a/packages/Keyguard/res/values-nb/strings.xml
+++ b/packages/Keyguard/res/values-nb/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Skriv inn PUK-koden for SIM-kortet og en ny PIN-kode"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK-koden for SIM-kortet"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Ny PIN-kode for SIM-kortet"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Likt av meg"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Sanger du ikke liker"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Hjerte"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Lås opp for å fortsette"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Starten ble kansellert"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Slipp <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> for å slette den."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> blir ikke slettet."</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>
@@ -105,13 +112,12 @@
     <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_instructions" msgid="1100551261265506448">"Logg 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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Feil PIN-kode for SIM-kortet. Du må nå kontakte operatøren din for å låse opp enheten."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Feil PIN-kode for SIM-kortet. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøk igjen før du må kontakte operatøren din for å låse opp enheten."</item>
+    <item quantity="other" msgid="2215723361575359486">"Feil PIN-kode for SIM-kortet. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøk igjen."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM-kortet er ubrukelig. Kontakt operatøren din."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Feil PUK-kode for SIM-kortet. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig."</item>
+    <item quantity="other" msgid="5477305226026342036">"Feil PUK-kode for SIM-kortet. Du har <xliff:g id="NUMBER">%d</xliff:g> forsøk igjen før SIM-kortet blir permanent ubrukelig."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"PIN-koden for SIM-kortet ble avvist."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"PUK-koden for SIM-kortet ble avvist."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Koden er godkjent."</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>
diff --git a/packages/Keyguard/res/values-ne-rNP/strings.xml b/packages/Keyguard/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..0fa1182
--- /dev/null
+++ b/packages/Keyguard/res/values-ne-rNP/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">"अनलक गर्न मेनु थिच्नुहोस् र त्यसपछि ० थिच्नुहोस्।"</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">"?१२३"</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 टाइप गर्नुहोस्।"</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="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-ne/strings.xml b/packages/Keyguard/res/values-ne/strings.xml
new file mode 100644
index 0000000..0fa1182
--- /dev/null
+++ b/packages/Keyguard/res/values-ne/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">"अनलक गर्न मेनु थिच्नुहोस् र त्यसपछि ० थिच्नुहोस्।"</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">"?१२३"</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 टाइप गर्नुहोस्।"</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="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-nl/strings.xml b/packages/Keyguard/res/values-nl/strings.xml
index b94cb70..34149c9 100644
--- a/packages/Keyguard/res/values-nl/strings.xml
+++ b/packages/Keyguard/res/values-nl/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Typ de pukcode voor de simkaart en de nieuwe pincode"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Pukcode voor simkaart"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nieuwe pincode voor simkaart"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Leuk"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Niet leuk"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Hart"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Ontgrendel om door te gaan"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Start geannuleerd"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Zet <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> neer om te verwijderen."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> wordt niet verwijderd."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Onjuiste pincode voor simkaart. U moet nu contact opnemen met uw provider om uw apparaat te ontgrendelen."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Onjuiste pincode voor simkaart. U heeft nog <xliff:g id="NUMBER">%d</xliff:g> poging over voordat u contact met uw provider moet opnemen om uw apparaat te ontgrendelen."</item>
+    <item quantity="other" msgid="2215723361575359486">"Onjuiste pincode voor simkaart. U heeft nog <xliff:g id="NUMBER">%d</xliff:g> pogingen over."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Simkaart is onbruikbaar. Neem contact op met uw provider."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Onjuiste pukcode voor simkaart. U heeft nog <xliff:g id="NUMBER">%d</xliff:g> poging over voordat de simkaart definitief onbruikbaar wordt."</item>
+    <item quantity="other" msgid="5477305226026342036">"Onjuiste pukcode voor simkaart. U heeft nog <xliff:g id="NUMBER">%d</xliff:g> pogingen over voordat de simkaart definitief onbruikbaar wordt."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Bewerking met pincode voor simkaart mislukt."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Bewerking met pukcode voor simkaart is mislukt."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Code geaccepteerd."</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>
diff --git a/packages/Keyguard/res/values-pl/strings.xml b/packages/Keyguard/res/values-pl/strings.xml
index 15a4a7c..cfcbc46 100644
--- a/packages/Keyguard/res/values-pl/strings.xml
+++ b/packages/Keyguard/res/values-pl/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Wpisz PUK i nowy kod PIN karty SIM"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Kod PUK karty SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nowy kod PIN karty SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Podoba mi się"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Nie podoba mi się"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Serce"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Odblokuj, by kontynuować"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Uruchomienie anulowane"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Upuść <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>, by usunąć."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> nie zostanie usunięty."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Nieprawidłowy kod PIN karty SIM. Musisz teraz skontaktować się z operatorem, by odblokował Twoje urządzenie."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Nieprawidłowy kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER">%d</xliff:g> próbę, zanim będziesz musiał skontaktować się z operatorem, by odblokował Twoje urządzenie."</item>
+    <item quantity="other" msgid="2215723361575359486">"Nieprawidłowy kod PIN karty SIM. Masz jeszcze <xliff:g id="NUMBER">%d</xliff:g> prób(y)."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Karta SIM została trwale zablokowana. Skontaktuj się z operatorem."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Nieprawidłowy kod PUK karty SIM. Masz jeszcze <xliff:g id="NUMBER">%d</xliff:g> próbę, zanim karta SIM zostanie trwale zablokowana."</item>
+    <item quantity="other" msgid="5477305226026342036">"Nieprawidłowy kod PUK karty SIM. Masz jeszcze <xliff:g id="NUMBER">%d</xliff:g> prób(y), zanim karta SIM zostanie trwale zablokowana."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Operacja z kodem PIN karty SIM nie udała się."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Operacja z kodem PUK karty SIM nie udała się."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kod został zaakceptowany."</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>
diff --git a/packages/Keyguard/res/values-pt-rPT/strings.xml b/packages/Keyguard/res/values-pt-rPT/strings.xml
index 222051c..abd4fcd 100644
--- a/packages/Keyguard/res/values-pt-rPT/strings.xml
+++ b/packages/Keyguard/res/values-pt-rPT/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Introduzir PUK do cartão SIM e o novo código PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Código PUK do cartão SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Novo código PIN do cartão SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Gosto"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Não gosto"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Coração"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Desbloquear para continuar"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Lançamento cancelado"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Largue <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> para eliminar."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> não será eliminado."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Código PIN do cartão SIM incorreto. Tem de contactar o seu operador para desbloquear o dispositivo."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER">%d</xliff:g> tentativa antes de necessitar de contactar o seu operador para desbloquear o dispositivo."</item>
+    <item quantity="other" msgid="2215723361575359486">"Código PIN do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER">%d</xliff:g> tentativas."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Cartão SIM inutilizável. Contacte o seu operador."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Código PUK do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER">%d</xliff:g> tentativa antes de o cartão SIM ficar permanentemente inutilizável."</item>
+    <item quantity="other" msgid="5477305226026342036">"Código PUK do cartão SIM incorreto. Tem mais <xliff:g id="NUMBER">%d</xliff:g> tentativas antes de o cartão SIM ficar permanentemente inutilizável."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Falha ao introduzir o PIN do cartão SIM!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Falha ao introduzir o PUK do cartão SIM!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Código aceite!"</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>
diff --git a/packages/Keyguard/res/values-pt/strings.xml b/packages/Keyguard/res/values-pt/strings.xml
index a563372..24d78e5 100644
--- a/packages/Keyguard/res/values-pt/strings.xml
+++ b/packages/Keyguard/res/values-pt/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Digite o PUK do SIM e o novo código PIN."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Código PUK do SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Novo código PIN do SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Gostei"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Não gostei"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Coração"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Desbloqueie para continuar"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Inicialização cancelada"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Solte <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> para excluir."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> não será excluído."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Código PIN do SIM incorreto. Entre em contato com a operadora para desbloquear o dispositivo."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Código PIN do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER">%d</xliff:g>. Caso o código correto não seja digitado, será necessário entrar em contato com a operadora para desbloquear o dispositivo."</item>
+    <item quantity="other" msgid="2215723361575359486">"Código PIN do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"O SIM está inutilizável. Entre em contato com a operadora."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Código PUK do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER">%d</xliff:g> Caso o código correto não seja digitado, o SIM se tornará permanentemente inutilizável."</item>
+    <item quantity="other" msgid="5477305226026342036">"Código PUK do SIM incorreto. Tentativas restantes: <xliff:g id="NUMBER">%d</xliff:g>. Caso o código correto não seja digitado, o SIM se tornará permanentemente inutilizável."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Falha na operação de PIN do SIM."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Falha na operação de PUK do SIM."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Código aceito."</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>
diff --git a/packages/Keyguard/res/values-rm/strings.xml b/packages/Keyguard/res/values-rm/strings.xml
index 8dda055..ee26a3d 100644
--- a/packages/Keyguard/res/values-rm/strings.xml
+++ b/packages/Keyguard/res/values-rm/strings.xml
@@ -22,11 +22,11 @@
     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) -->
+    <!-- no translation found for keyguard_password_enter_puk_code (3035856550289724338) -->
     <skip />
-    <!-- no translation found for keyguard_password_enter_puk_prompt (1341112146710087048) -->
+    <!-- no translation found for keyguard_password_enter_puk_prompt (1801941051094974609) -->
     <skip />
-    <!-- no translation found for keyguard_password_enter_pin_prompt (8027680321614196258) -->
+    <!-- no translation found for keyguard_password_enter_pin_prompt (3201151840570492538) -->
     <skip />
     <!-- no translation found for keyguard_password_entry_touch_hint (7858547464982981384) -->
     <skip />
@@ -121,6 +121,20 @@
     <skip />
     <!-- no translation found for keyguard_accessibility_transport_stop_description (7656358482980912216) -->
     <skip />
+    <!-- no translation found for keyguard_accessibility_transport_thumbs_up_description (4535938129663903194) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_transport_thumbs_down_description (8101433677192177861) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_transport_heart_description (2336943232474689887) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_show_bouncer (5425837272418176176) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_hide_bouncer (7896992171878309358) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_delete_widget_start (4096550552634391451) -->
+    <skip />
+    <!-- no translation found for keyguard_accessibility_delete_widget_end (508833506780909393) -->
+    <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>
@@ -186,8 +200,6 @@
     <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) -->
@@ -234,6 +246,20 @@
     <skip />
     <!-- no translation found for kg_reordering_delete_drop_target_text (7899202978204438708) -->
     <skip />
+    <!-- no translation found for kg_password_wrong_pin_code_pukked (30531039455764924) -->
+    <skip />
+    <!-- no translation found for kg_password_wrong_pin_code:one (8134313997799638254) -->
+    <!-- no translation found for kg_password_wrong_pin_code:other (2215723361575359486) -->
+    <!-- no translation found for kg_password_wrong_puk_code_dead (7077536808291316208) -->
+    <skip />
+    <!-- no translation found for kg_password_wrong_puk_code:one (3256893607561060649) -->
+    <!-- no translation found for kg_password_wrong_puk_code:other (5477305226026342036) -->
+    <!-- no translation found for kg_password_pin_failed (6268288093558031564) -->
+    <skip />
+    <!-- no translation found for kg_password_puk_failed (2838824369502455984) -->
+    <skip />
+    <!-- no translation found for kg_pin_accepted (1448241673570020097) -->
+    <skip />
     <!-- no translation found for keyguard_transport_prev_description (8229108430245669854) -->
     <skip />
     <!-- no translation found for keyguard_transport_next_description (4299258300283778305) -->
diff --git a/packages/Keyguard/res/values-ro/strings.xml b/packages/Keyguard/res/values-ro/strings.xml
index 01d79f8..1c7e88f 100644
--- a/packages/Keyguard/res/values-ro/strings.xml
+++ b/packages/Keyguard/res/values-ro/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Introduceți codul PUK pentru cardul SIM și codul PIN nou"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Codul PUK pentru cardul SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Codul PIN nou pentru cardul SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Vot pozitiv"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Vot negativ"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Inimă"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Deblocați pentru a continua"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Lansare anulată"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Eliberați <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> pentru a șterge."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Widgetul <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> nu va fi șters."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Codul PIN pentru cardul SIM este incorect. Contactați operatorul pentru a vă debloca dispozitivul."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Codul PIN pentru cardul SIM este incorect. V-a mai rămas <xliff:g id="NUMBER">%d</xliff:g> încercare, după care va trebui să contactați operatorul pentru a vă debloca dispozitivul."</item>
+    <item quantity="other" msgid="2215723361575359486">"Codul PIN pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER">%d</xliff:g> încercări."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Cardul SIM nu poate fi utilizat. Contactați operatorul."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Codul PUK pentru cardul SIM este incorect. V-a mai rămas <xliff:g id="NUMBER">%d</xliff:g> încercare până când cardul SIM va deveni inutilizabil definitiv."</item>
+    <item quantity="other" msgid="5477305226026342036">"Codul PUK pentru cardul SIM este incorect. V-au mai rămas <xliff:g id="NUMBER">%d</xliff:g> încercări până când cardul SIM va deveni inutilizabil definitiv."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Deblocarea cu ajutorul codului PIN pentru cardul SIM nu a reușit!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Deblocarea cu ajutorul codului PUK pentru cardul SIM nu a reușit!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Cod acceptat!"</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>
diff --git a/packages/Keyguard/res/values-ru/strings.xml b/packages/Keyguard/res/values-ru/strings.xml
index 136982a..304f474 100644
--- a/packages/Keyguard/res/values-ru/strings.xml
+++ b/packages/Keyguard/res/values-ru/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Введите PUK-код и новый PIN-код"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK-код"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Новый 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>
@@ -42,7 +42,7 @@
     <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_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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Нравится"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Не нравится"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Рейтинг"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Разблокируйте экран, чтобы продолжить."</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Запуск отменен."</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Отпустите виджет \"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>\", чтобы удалить его."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Виджет \"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>\" не будет удален."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Неверный PIN-код. Обратитесь к оператору связи, чтобы разблокировать SIM-карту."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Неверный PIN-код. Осталось попыток: <xliff:g id="NUMBER">%d</xliff:g>. После этого SIM-карта будет заблокирована и вам придется обратиться к оператору связи."</item>
+    <item quantity="other" msgid="2215723361575359486">"Неверный PIN-код. Осталось попыток: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM-карта заблокирована навсегда. Обратитесь к оператору связи."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Неверный PUK-код. Осталось попыток: <xliff:g id="NUMBER">%d</xliff:g>. После этого SIM-карта будет заблокирована навсегда."</item>
+    <item quantity="other" msgid="5477305226026342036">"Неверный PUK-код. Осталось попыток: <xliff:g id="NUMBER">%d</xliff:g>. После этого SIM-карта будет заблокирована навсегда."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Не удалось разблокировать SIM-карту"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Не удалось разблокировать SIM-карту"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Код принят"</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>
diff --git a/packages/Keyguard/res/values-si-rLK/strings.xml b/packages/Keyguard/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..8904c7e
--- /dev/null
+++ b/packages/Keyguard/res/values-si-rLK/strings.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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.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="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">"අංක 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-si/strings.xml b/packages/Keyguard/res/values-si/strings.xml
new file mode 100644
index 0000000..8904c7e
--- /dev/null
+++ b/packages/Keyguard/res/values-si/strings.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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.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="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">"අංක 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-sk/strings.xml b/packages/Keyguard/res/values-sk/strings.xml
index 4b2e1e3..cdf8ca9 100644
--- a/packages/Keyguard/res/values-sk/strings.xml
+++ b/packages/Keyguard/res/values-sk/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Zadajte kód PUK karty SIM a nový kód PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Kód PUK karty SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nový kód PIN karty SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Páči sa mi"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Nepáči sa mi"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Srdce"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Odomknite zariadenie a pokračujte"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Spustenie bolo zrušené"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Uvoľnením dotyku miniaplikáciu <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> odstránite."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Miniaplikácia <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> nebude odstránená."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Nesprávny kód PIN karty SIM. Teraz musíte kontaktovať svojho operátora, aby vám odomkol zariadenie."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Nesprávny kód PIN karty SIM. Zostáva vám <xliff:g id="NUMBER">%d</xliff:g> pokus, inak budete musieť kontaktovať svojho operátora, aby vám odomkol zariadenie."</item>
+    <item quantity="other" msgid="2215723361575359486">"Nesprávny kód PIN karty SIM. Počet zostávajúcich pokusov: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Karta SIM je nepoužiteľná. Kontaktujte svojho operátora."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Nesprávny kód PUK karty SIM. Zostáva vám <xliff:g id="NUMBER">%d</xliff:g> pokus, inak sa vaša karta SIM natrvalo zablokuje."</item>
+    <item quantity="other" msgid="5477305226026342036">"Nesprávny kód PUK karty SIM. Počet zostávajúcich pokusov pred trvalým zablokovaním karty SIM: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Operácia kódu PIN karty SIM zlyhala!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Operácia kódu PUK karty SIM zlyhala!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kód bol prijatý!"</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>
diff --git a/packages/Keyguard/res/values-sl/strings.xml b/packages/Keyguard/res/values-sl/strings.xml
index b6cfc1c..b0ec84e 100644
--- a/packages/Keyguard/res/values-sl/strings.xml
+++ b/packages/Keyguard/res/values-sl/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Vnesite kodo PUK in novo kodo PIN kartice SIM"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Koda PUK kartice SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Nova koda PIN kartice SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Všeč mi je"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Ni mi všeč"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Srce"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Za nadaljevanje odklenite"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Zagon je preklican"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Izpustite pripomoček <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>, da ga izbrišete."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Pripomoček <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ne bo izbrisan."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Napačna koda PIN kartice SIM. Zdaj se boste morali za odklenitev naprave obrniti na operaterja."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Napačna koda PIN kartice SIM. Na voljo imate še <xliff:g id="NUMBER">%d</xliff:g> poskus. Potem se boste morali za odklenitev naprave obrniti na operaterja."</item>
+    <item quantity="other" msgid="2215723361575359486">"Napačna koda PIN kartice SIM. Poskusite lahko še <xliff:g id="NUMBER">%d</xliff:g>-krat."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Kartica SIM ni več uporabna. Obrnite se na operaterja."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Napačna koda PUK kartice SIM. Na voljo imate še <xliff:g id="NUMBER">%d</xliff:g> poskus. Potem bo kartica SIM postala trajno neuporabna."</item>
+    <item quantity="other" msgid="5477305226026342036">"Napačna koda PUK kartice SIM. Poskusite lahko še <xliff:g id="NUMBER">%d</xliff:g>-krat. Potem bo kartica SIM postala trajno neuporabna."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Postopek za odklepanje s kodo PIN kartice SIM ni uspel."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Postopek za odklepanje s kodo PUK kartice SIM ni uspel."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Koda je sprejeta."</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>
diff --git a/packages/Keyguard/res/values-sr/strings.xml b/packages/Keyguard/res/values-sr/strings.xml
index 664b85e..2bdd8f5 100644
--- a/packages/Keyguard/res/values-sr/strings.xml
+++ b/packages/Keyguard/res/values-sr/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Унесите SIM PUK кôд и нови PIN кôд"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK кôд"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Нови SIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Свиђа ми се"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Не свиђа ми се"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Срце"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Откључајте да бисте наставили"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Покретање је отказано"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Отпустите виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> да бисте га избрисали."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Виџет <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> неће бити избрисан."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,10 +135,23 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Нетачан SIM PIN кôд. Сада морате да контактирате мобилног оператера да бисте откључали уређај."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Нетачан SIM PIN кôд. Имате још <xliff:g id="NUMBER">%d</xliff:g> покушај, а онда морате да контактирате мобилног оператера да бисте откључали уређај."</item>
+    <item quantity="other" msgid="2215723361575359486">"Нетачан SIM PIN кôд. Имате још <xliff:g id="NUMBER">%d</xliff:g> покушаја."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM картица је неупотребљива. Контактирајте мобилног оператера."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Нетачан SIM PUK кôд. Имате још <xliff:g id="NUMBER">%d</xliff:g> покушај пре него што SIM картица постане трајно неупотребљива."</item>
+    <item quantity="other" msgid="5477305226026342036">"Нетачан SIM PUK кôд. Имате још <xliff:g id="NUMBER">%d</xliff:g> покушаја пре него што SIM картица постане трајно неупотребљива."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Радња са SIM PIN кодом није успела!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Радња са SIM PUK кодом није успела!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Кôд је прихваћен!"</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>
+    <string name="keyguard_carrier_default" msgid="8700650403054042153">"Офлајн сте."</string>
 </resources>
diff --git a/packages/Keyguard/res/values-sv/strings.xml b/packages/Keyguard/res/values-sv/strings.xml
index fb0f912..e446f61 100644
--- a/packages/Keyguard/res/values-sv/strings.xml
+++ b/packages/Keyguard/res/values-sv/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Ange PUK-koden och en ny pinkod för SIM-kortet"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK-kod för SIM-kortet"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Ny pinkod för SIM-kort"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Gillar"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Tummen ned"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Hjärta"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Lås upp om du vill fortsätta"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Lanseringen har avbrutits"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Ta bort genom att släppa <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> här."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> kommer inte att tas bort."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Du angav fel pinkod för SIM-kortet och måste nu kontakta operatören för att låsa upp enheten."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Du angav fel pinkod för SIM-kortet. <xliff:g id="NUMBER">%d</xliff:g> försök återstår innan du måste kontakta operatören för att låsa upp enheten."</item>
+    <item quantity="other" msgid="2215723361575359486">"Du angav fel pinkod för SIM-kortet. <xliff:g id="NUMBER">%d</xliff:g> försök återstår."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM-kortet är obrukbart. Kontakta operatören."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Du angav fel PUK-kod för SIM-kortet. <xliff:g id="NUMBER">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart."</item>
+    <item quantity="other" msgid="5477305226026342036">"Du angav fel PUK-kod för SIM-kortet. <xliff:g id="NUMBER">%d</xliff:g> försök återstår innan SIM-kortet blir obrukbart."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Det gick inte att låsa upp med pinkoden för SIM-kortet."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Det gick inte att låsa upp med PUK-koden för SIM-kortet."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Koden godkändes!"</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>
diff --git a/packages/Keyguard/res/values-sw/strings.xml b/packages/Keyguard/res/values-sw/strings.xml
index 27f1f30..1d60a13 100644
--- a/packages/Keyguard/res/values-sw/strings.xml
+++ b/packages/Keyguard/res/values-sw/strings.xml
@@ -21,16 +21,16 @@
 <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_enter_puk_code" msgid="3035856550289724338">"Chapa PUK ya SIM na msimbo mpya wa PIN"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Msimbo wa PUK ya SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Msimbo mpya wa PIN ya SIM"</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_charged" msgid="3272223906073492454">"Betri imejaa"</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>
@@ -45,8 +45,8 @@
     <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_changed" msgid="5678624624681400191">"%1$s. Wijeti %2$d ya %3$d."</string>
+    <string name="keyguard_accessibility_add_widget" msgid="8273277058724924654">"Ongeza wijeti."</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>
@@ -55,7 +55,7 @@
     <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_start" msgid="8736853615588828197">"Upangaji upya wa wijeti 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Bomba"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Si bomba"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Moyo"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Fungua ili uendelee"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Uzinduzi umeghairiwa"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Dondosha <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ili ufute."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> haitafutwa."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Msimbo wa PIN ya SIM usiosahihi sasa lazima uwasiliane na mtoa huduma wako ili ufungue kifaa chako."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Msimbo wa PIN ya SIM usio sahihi, umesalia na majaribio <xliff:g id="NUMBER">%d</xliff:g> kabla ulazimike kuwasiliana na mtoa huduma wako ili ufungue kifaa chako."</item>
+    <item quantity="other" msgid="2215723361575359486">"Msimbo wa PIN ya SIM usio sahihi, umesalia na majaribio <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM haiwezi kutumika. Wasiliana na mtoa huduma wako."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Msimbo wa PUK ya SIM usio sahihi, umesalia na majaribio <xliff:g id="NUMBER">%d</xliff:g> kabla ya SIM kuacha kutumika kabisa."</item>
+    <item quantity="other" msgid="5477305226026342036">"Msimbo wa PUK ya SIM usio sahihi, umesalia na majaribio <xliff:g id="NUMBER">%d</xliff:g> kabla ya SIM kuacha kutumika kabisa."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Utendakazi wa PIN ya SIM umeshindwa!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Utendakazi wa PUK ya SIM umeshindwa!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Msimbo Umekubaliwa!"</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>
diff --git a/packages/Keyguard/res/values-th/strings.xml b/packages/Keyguard/res/values-th/strings.xml
index d6308b6..a44f9fe 100644
--- a/packages/Keyguard/res/values-th/strings.xml
+++ b/packages/Keyguard/res/values-th/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"พิมพ์ PUK และรหัส PIN ใหม่"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"รหัส PUK ของซิม"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"รหัส 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"สุดยอด"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"ไม่ชอบ"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"หัวใจ"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"ปลดล็อกเพื่อดำเนินการต่อ"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"ยกเลิกการเปิดใช้งานแล้ว"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"ลาก <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> เพื่อลบ"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> จะไม่ถูกลบ"</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"รหัส PIN ของซิมไม่ถูกต้อง ตอนนี้คุณต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์ของคุณ"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"รหัส PIN ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER">%d</xliff:g> ครั้งก่อนที่จะต้องติดต่อผู้ให้บริการเพื่อปลดล็อกอุปกรณ์ของคุณ"</item>
+    <item quantity="other" msgid="2215723361575359486">"รหัส PIN ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER">%d</xliff:g> ครั้ง"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"ซิมไม่สามารถใช้งานได้ ติดต่อผู้ให้บริการของคุณ"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"รหัส PUK ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร"</item>
+    <item quantity="other" msgid="5477305226026342036">"รหัส PUK ของซิมไม่ถูกต้อง คุณพยายามได้อีก <xliff:g id="NUMBER">%d</xliff:g> ครั้งก่อนที่ซิมจะไม่สามารถใช้งานได้อย่างถาวร"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"การปลดล็อกด้วย PIN ของซิมล้มเหลว!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"การปลดล็อกด้วย PUK ของซิมล้มเหลว!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"รหัสได้รับการยอมรับ!"</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>
diff --git a/packages/Keyguard/res/values-tl/strings.xml b/packages/Keyguard/res/values-tl/strings.xml
index a41d268..6516766 100644
--- a/packages/Keyguard/res/values-tl/strings.xml
+++ b/packages/Keyguard/res/values-tl/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"I-type ang SIM PUK at bagong PIN code"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK code ng SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Bagong PIN code ng SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Thumbs up"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Thumbs down"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Heart"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"I-unlock upang magpatuloy"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Nakansela ang paglunsad"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"I-drop ang <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> upang tanggalin."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"Hindi tatanggalin ang <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Maling PIN code ng SIM, dapat ka nang makipag-ugnay sa iyong carrier upang i-unlock ang iyong device."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Maling PIN code ng SIM, mayroon kang <xliff:g id="NUMBER">%d</xliff:g> (na) natitirang pagsubok bago ka dapat makipag-ugnay sa iyong carrier upang i-unlock ang iyong device."</item>
+    <item quantity="other" msgid="2215723361575359486">"Maling PIN code ng SIM, mayroon kang <xliff:g id="NUMBER">%d</xliff:g> (na) natitirang pagsubok."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"Hindi magagamit ang SIM. Makipag-ugnay sa iyong carrier."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Maling PUK code ng SIM, mayroon kang <xliff:g id="NUMBER">%d</xliff:g> (na) natitirang pagsubok bago maging permanenteng hindi magagamit ang SIM."</item>
+    <item quantity="other" msgid="5477305226026342036">"Maling PUK code ng SIM, mayroon kang <xliff:g id="NUMBER">%d</xliff:g> (na) natitirang pagsubok bago maging permanenteng hindi magagamit ang SIM."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Nabigo ang operasyon ng SIM PIN!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Nabigo ang operasyon ng SIM PUK!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Tinanggap ang Code!"</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>
diff --git a/packages/Keyguard/res/values-tr/strings.xml b/packages/Keyguard/res/values-tr/strings.xml
index 0af7740..aed8a47 100644
--- a/packages/Keyguard/res/values-tr/strings.xml
+++ b/packages/Keyguard/res/values-tr/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"SIM PUK kodunu ve yeni bir PIN kodu yazın."</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK kodu"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Yeni SIM 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Beğen"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Beğenme"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Kalp"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Devam etmek için kilidini açın"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Başlatma iptal edildi"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Silmek için <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> widget\'ını bırakın."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> silinmeyecek."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Yanlış SIM PIN kodu. Cihazınızın kilidini açmak için artık operatörünüzle bağlantı kurmanız gerekiyor."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Yanlış SIM PIN kodu. Cihazının kilidini açmak için operatörünüzle bağlantı kurmak zorunda kalmadan önce <xliff:g id="NUMBER">%d</xliff:g> deneme hakkınız kaldı."</item>
+    <item quantity="other" msgid="2215723361575359486">"Yanlış SIM PIN kodu. <xliff:g id="NUMBER">%d</xliff:g> deneme hakkınız kaldı."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM kullanılamaz. Operatörünüzle bağlantı kurun."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Yanlış SIM PUK kodu. SIM kalıcı olarak kullanılmaz hale gelmeden önce <xliff:g id="NUMBER">%d</xliff:g> deneme hakkınız kaldı."</item>
+    <item quantity="other" msgid="5477305226026342036">"Yanlış SIM PUK kodu. SIM kalıcı olarak kullanılmaz hale gelmeden önce <xliff:g id="NUMBER">%d</xliff:g> deneme hakkınız kaldı."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN işlemi başarısız oldu!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK işlemi başarısız oldu!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Kod Kabul Edildi!"</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>
diff --git a/packages/Keyguard/res/values-uk/strings.xml b/packages/Keyguard/res/values-uk/strings.xml
index 2879e87..5e355e4 100644
--- a/packages/Keyguard/res/values-uk/strings.xml
+++ b/packages/Keyguard/res/values-uk/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Введіть PUK-код і новий PIN-код SIM-карти"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"PUK-код SIM-карти"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Новий PIN-код SIM-карти"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Подобається"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Не подобається"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Рейтинг"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Розблокуйте, щоб продовжити"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Запуск скасовано"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Відпустіть <xliff:g id="WIDGET_INDEX">%1$s</xliff:g>, щоб видалити."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> не буде видалено."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Неправильний PIN-код SIM-карти. Зв’яжіться зі своїм оператором, щоб розблокувати пристрій."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Неправильний PIN-код SIM-карти. У вас залишилась <xliff:g id="NUMBER">%d</xliff:g> спроба. Після цього потрібно буде зв’язатися з оператором, щоб розблокувати пристрій."</item>
+    <item quantity="other" msgid="2215723361575359486">"Неправильний PIN-код SIM-карти. У вас залишилося стільки спроб: <xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM-карту заблоковано. Зв’яжіться з оператором."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Неправильний PUK-код SIM-карти. У вас залишилась <xliff:g id="NUMBER">%d</xliff:g> спроба. Після цього SIM-карту буде назавжди заблоковано."</item>
+    <item quantity="other" msgid="5477305226026342036">"Неправильний PUK-код SIM-карти. У вас залишилося стільки спроб: <xliff:g id="NUMBER">%d</xliff:g>. Після цього SIM-карту буде назавжди заблоковано."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Помилка введення PIN-коду SIM-карти."</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Помилка введення PUK-коду SIM-карти."</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Код прийнято."</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>
diff --git a/packages/Keyguard/res/values-vi/strings.xml b/packages/Keyguard/res/values-vi/strings.xml
index 70d3c73..19eb4c5 100644
--- a/packages/Keyguard/res/values-vi/strings.xml
+++ b/packages/Keyguard/res/values-vi/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Nhập mã PIN mới và mã PUK của SIM"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Mã PUK của SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Mã PIN mới của SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Bài hát được đánh dấu thích"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Bài hát được đánh dấu không thích"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Trái tim"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Mở khóa để tiếp tục"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Quá trình khởi chạy bị hủy"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Thả <xliff:g id="WIDGET_INDEX">%1$s</xliff:g> để xóa."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> sẽ không bị xóa."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Mã PIN của SIM không chính xác, bây giờ bạn phải liên hệ với nhà cung cấp dịch vụ để mở khóa thiết bị của bạn."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Mã PIN của SIM không chính xác, bạn còn <xliff:g id="NUMBER">%d</xliff:g> lần thử trước khi bạn phải liên hệ với nhà cung cấp dịch vụ để mở khóa thiết bị của bạn."</item>
+    <item quantity="other" msgid="2215723361575359486">"Mã PIN của SIM không chính xác, bạn còn <xliff:g id="NUMBER">%d</xliff:g> lần thử."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM không thể sử dụng được. Liên hệ với nhà cung cấp dịch vụ của bạn."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Mã PUK của SIM không chính xác, bạn còn <xliff:g id="NUMBER">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không thể sử dụng được."</item>
+    <item quantity="other" msgid="5477305226026342036">"Mã PUK của SIM không chính xác, bạn còn <xliff:g id="NUMBER">%d</xliff:g> lần thử trước khi SIM vĩnh viễn không thể sử dụng được."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Thao tác mã PIN của SIM không thành công!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Thao tác mã PUK của SIM không thành công!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Mã được chấp nhận!"</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>
diff --git a/packages/Keyguard/res/values-zh-rCN/strings.xml b/packages/Keyguard/res/values-zh-rCN/strings.xml
index cdb1944e..18578e4 100644
--- a/packages/Keyguard/res/values-zh-rCN/strings.xml
+++ b/packages/Keyguard/res/values-zh-rCN/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"请输入 SIM 卡 PUK 码和新的 PIN 码"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM 卡 PUK 码"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"新 SIM 卡 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"我喜欢"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"不喜欢"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"爱心"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"解锁即可继续"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"启动已取消"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"放下<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>即可将其删除。"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>将不会被删除。"</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM 卡 PIN 码不正确,您现在必须联系运营商为您解锁设备。"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"SIM 卡 PIN 码不正确,您还有<xliff:g id="NUMBER">%d</xliff:g>次尝试机会。如果仍然失败,则必须联系运营商帮您解锁设备。"</item>
+    <item quantity="other" msgid="2215723361575359486">"SIM 卡 PIN 码不正确,您还有<xliff:g id="NUMBER">%d</xliff:g>次尝试机会。"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM 卡无法使用,请与您的运营商联系。"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"SIM 卡 PUK 码不正确,您还有<xliff:g id="NUMBER">%d</xliff:g>次尝试机会。如果仍然失败,SIM 卡将永远无法使用。"</item>
+    <item quantity="other" msgid="5477305226026342036">"SIM 卡 PUK 码不正确,您还有<xliff:g id="NUMBER">%d</xliff:g>次尝试机会。如果仍然失败,SIM 卡将永远无法使用。"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM 卡 PIN 码操作失败!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM 卡 PUK 码操作失败!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"代码正确!"</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>
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..010ad2f
--- /dev/null
+++ b/packages/Keyguard/res/values-zh-rHK/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under 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="3035856550289724338">"請輸入 SIM PUK 碼和新 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM PUK 碼"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"新 SIM 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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"喜歡"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"不喜歡"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"心形"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"請解鎖以繼續"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"已取消啟動"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"拖放「<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>」即可刪除。"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"「<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>」將不會被刪除。"</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_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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM PIN 碼不正確,您現在必須聯絡流動網絡供應商為您的裝置解鎖。"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"SIM PIN 碼不正確,您剩下 <xliff:g id="NUMBER">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,您必須聯絡流動網絡供應商為您的裝置解鎖。"</item>
+    <item quantity="other" msgid="2215723361575359486">"SIM PIN 碼不正確,您剩下 <xliff:g id="NUMBER">%d</xliff:g> 次機會輸入。"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM 無法使用,請聯絡您的流動網絡供應商。"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"SIM PUK 碼不正確,您剩下 <xliff:g id="NUMBER">%d</xliff:g> 次機會輸入。如果仍然輪入錯誤,SIM 將永久無法使用。"</item>
+    <item quantity="other" msgid="5477305226026342036">"SIM PUK 碼不正確,您剩下 <xliff:g id="NUMBER">%d</xliff:g> 次機會輸入。如果仍然輸入錯誤,SIM 將永久無法使用。"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM PIN 碼操作失敗!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM PUK 碼操作失敗!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"密碼正確!"</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/strings.xml b/packages/Keyguard/res/values-zh-rTW/strings.xml
index 72a1c0f..d81cc16 100644
--- a/packages/Keyguard/res/values-zh-rTW/strings.xml
+++ b/packages/Keyguard/res/values-zh-rTW/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"輸入 SIM 卡 PUK 碼和新 PIN 碼"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"SIM 卡 PUK 碼"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"新增 SIM 卡 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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"喜歡"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"不喜歡"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"愛心"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"先解鎖才能繼續操作"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"已取消啟動"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"拖放「<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>」即可將其刪除。"</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"「<xliff:g id="WIDGET_INDEX">%1$s</xliff:g>」將不會遭到刪除。"</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"SIM 卡的 PIN 碼輸入錯誤,您現在必須請行動通訊業者為裝置解鎖。"</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"SIM 卡的 PIN 碼輸入錯誤,您還可以再試 <xliff:g id="NUMBER">%d</xliff:g> 次。如果仍然失敗,就必須請行動通訊業者為裝置解鎖。"</item>
+    <item quantity="other" msgid="2215723361575359486">"SIM 卡的 PIN 碼輸入錯誤,您還可以再試 <xliff:g id="NUMBER">%d</xliff:g> 次。"</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"SIM 卡無法使用,請與您的行動通訊業者聯絡。"</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"SIM 卡的 PUK 碼輸入錯誤,您還可以再試 <xliff:g id="NUMBER">%d</xliff:g> 次。如果仍然失敗,SIM 卡將永久無法使用。"</item>
+    <item quantity="other" msgid="5477305226026342036">"SIM 卡的 PUK 碼輸入錯誤,您還可以再試 <xliff:g id="NUMBER">%d</xliff:g> 次。如果仍然失敗,SIM 卡將永久無法使用。"</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"SIM 卡 PIN 碼操作失敗!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"SIM 卡 PUK 碼操作失敗!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"密碼正確!"</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>
diff --git a/packages/Keyguard/res/values-zu/strings.xml b/packages/Keyguard/res/values-zu/strings.xml
index 185ea03..b205634 100644
--- a/packages/Keyguard/res/values-zu/strings.xml
+++ b/packages/Keyguard/res/values-zu/strings.xml
@@ -21,9 +21,9 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="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_enter_puk_code" msgid="3035856550289724338">"Thayipha i-PUK ye-SIM nekhodi yephinikhodi entsha"</string>
+    <string name="keyguard_password_enter_puk_prompt" msgid="1801941051094974609">"Ikhodi ye-PUK ye-SIM"</string>
+    <string name="keyguard_password_enter_pin_prompt" msgid="3201151840570492538">"Ikhodi entsha yephinikhodi ye-SIM"</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>
@@ -71,6 +71,13 @@
     <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="keyguard_accessibility_transport_thumbs_up_description" msgid="4535938129663903194">"Okushaphu"</string>
+    <string name="keyguard_accessibility_transport_thumbs_down_description" msgid="8101433677192177861">"Akulungile"</string>
+    <string name="keyguard_accessibility_transport_heart_description" msgid="2336943232474689887">"Inhliziyo"</string>
+    <string name="keyguard_accessibility_show_bouncer" msgid="5425837272418176176">"Vula ukuze uqhubeke"</string>
+    <string name="keyguard_accessibility_hide_bouncer" msgid="7896992171878309358">"Ukuqalisa kukhanseliwe"</string>
+    <string name="keyguard_accessibility_delete_widget_start" msgid="4096550552634391451">"Lahla i-<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ukuze uyisuse."</string>
+    <string name="keyguard_accessibility_delete_widget_end" msgid="508833506780909393">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ngeke isuswe."</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>
@@ -105,7 +112,6 @@
     <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>
@@ -129,6 +135,19 @@
     <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="kg_password_wrong_pin_code_pukked" msgid="30531039455764924">"Ikhodi yephinikhodi ye-SIM engalungile manje kumele uxhumane nenkampini yenethiwekhi yakho ukuvula idivayisi yakho."</string>
+  <plurals name="kg_password_wrong_pin_code">
+    <item quantity="one" msgid="8134313997799638254">"Ikhodi yephinikhodi ye-SIM engalungile, unemizamo engu-<xliff:g id="NUMBER">%d</xliff:g> esele ngaphambi kokuba uxhumane nenkampini yenethiwekhi."</item>
+    <item quantity="other" msgid="2215723361575359486">"Ikhodi yephinikhodi ye-SIM engalungile, unemizamo esele engu-<xliff:g id="NUMBER">%d</xliff:g>."</item>
+  </plurals>
+    <string name="kg_password_wrong_puk_code_dead" msgid="7077536808291316208">"I-SIM ayisebenziseki. Xhumana nemkampini yenethiwekhi yakho."</string>
+  <plurals name="kg_password_wrong_puk_code">
+    <item quantity="one" msgid="3256893607561060649">"Ikhodi ye-PUK ye-SIM engalungile, unemizamo engu-<xliff:g id="NUMBER">%d</xliff:g> esele ngaphambi kokuba i-SIM ibe engasebenziseki unaphakade."</item>
+    <item quantity="other" msgid="5477305226026342036">"Ikhodi ye-PUK ye-SIM engalungile, unemizamo engu-<xliff:g id="NUMBER">%d</xliff:g> esele ngaphambi kokuba i-SIM iba engasebenziseki unaphakade."</item>
+  </plurals>
+    <string name="kg_password_pin_failed" msgid="6268288093558031564">"Umsebenzi wephinikhodi ye-SIM wehlulekile!"</string>
+    <string name="kg_password_puk_failed" msgid="2838824369502455984">"Umsebenzi we-PUK ye-SIM wehlulekile!"</string>
+    <string name="kg_pin_accepted" msgid="1448241673570020097">"Ikhodi yamukelwe!"</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>
diff --git a/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java b/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java
index 689366b..de839c6 100644
--- a/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java
+++ b/packages/Keyguard/src/com/android/keyguard/FaceUnlock.java
@@ -304,7 +304,7 @@
         int currentUserId = mLockPatternUtils.getCurrentUser();
         if (authenticatedUserId == currentUserId) {
             if (DEBUG) Log.d(TAG, "Unlocking for user " + authenticatedUserId);
-            mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
+            mKeyguardScreenCallback.reportUnlockAttempt(true);
             mKeyguardScreenCallback.dismiss(true);
         } else {
             Log.d(TAG, "Ignoring unlock for authenticated user (" + authenticatedUserId +
@@ -335,7 +335,7 @@
         // next time the user visits keyguard.
         KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
 
-        mKeyguardScreenCallback.reportFailedUnlockAttempt();
+        mKeyguardScreenCallback.reportUnlockAttempt(false);
     }
 
     /**
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 461fd77..3950159 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -154,14 +154,14 @@
     protected void verifyPasswordAndUnlock() {
         String entry = mPasswordEntry.getText().toString();
         if (mLockPatternUtils.checkPassword(entry)) {
-            mCallback.reportSuccessfulUnlockAttempt();
+            mCallback.reportUnlockAttempt(true);
             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)) {
+            mCallback.reportUnlockAttempt(false);
+            int attempts = KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts();
+            if (0 == (attempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
                 long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
                 handleAttemptLockout(deadline);
             }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
index 6b8be69..f69fa5f 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
@@ -177,14 +177,14 @@
                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     mContext.startActivityAsUser(intent,
                             new UserHandle(mLockPatternUtils.getCurrentUser()));
-                    mCallback.reportSuccessfulUnlockAttempt();
+                    mCallback.reportUnlockAttempt(true);
 
                     // dismiss keyguard
                     mCallback.dismiss(true);
                 } else {
                     mSecurityMessageDisplay.setMessage(R.string.kg_login_invalid_input, true);
                     mPassword.setText("");
-                    mCallback.reportFailedUnlockAttempt();
+                    mCallback.reportUnlockAttempt(false);
                 }
             }
         });
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java
index 0a915ea..368a97a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardActivityLauncher.java
@@ -53,10 +53,12 @@
 
     abstract Context getContext();
 
-    abstract KeyguardSecurityCallback getCallback();
-
     abstract LockPatternUtils getLockPatternUtils();
 
+    abstract void setOnDismissAction(OnDismissAction action);
+
+    abstract void requestDismissKeyguard();
+
     public static class CameraWidgetInfo {
         public String contextPackage;
         public int layoutId;
@@ -190,8 +192,7 @@
         } else {
             // Create a runnable to start the activity and ask the user to enter their
             // credentials.
-            KeyguardSecurityCallback callback = getCallback();
-            callback.setOnDismissAction(new OnDismissAction() {
+            setOnDismissAction(new OnDismissAction() {
                 @Override
                 public boolean onDismiss() {
                     dismissKeyguardOnNextActivity();
@@ -199,7 +200,7 @@
                     return true;
                 }
             });
-            callback.dismiss(false);
+            requestDismissKeyguard();
         }
     }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
index 63b61ad..0e08cf4 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardCircleFramedDrawable.java
@@ -29,8 +29,6 @@
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 
-import android.util.Log;
-
 class KeyguardCircleFramedDrawable extends Drawable {
 
     private final Bitmap mBitmap;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 247089f..2e76f19 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -16,6 +16,8 @@
 
 package com.android.keyguard;
 
+import android.nfc.NfcUnlock;
+
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.keyguard.KeyguardUpdateMonitor.DisplayClientState;
@@ -23,7 +25,6 @@
 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;
@@ -37,9 +38,9 @@
 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;
@@ -49,11 +50,9 @@
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Slog;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.WindowManager;
 import android.widget.RemoteViews.OnClickHandler;
 
 import java.io.File;
@@ -62,6 +61,8 @@
 
 public class KeyguardHostView extends KeyguardViewBase {
     private static final String TAG = "KeyguardHostView";
+    public static boolean DEBUG = KeyguardViewMediator.DEBUG;
+    public static boolean DEBUGXPORT = true; // debug music transport control
 
     // Transport control states.
     static final int TRANSPORT_GONE = 0;
@@ -70,42 +71,24 @@
 
     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;
 
-    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
@@ -184,8 +167,6 @@
 
         mAppWidgetManager = AppWidgetManager.getInstance(userContext);
 
-        mSecurityModel = new KeyguardSecurityModel(context);
-
         mViewStateManager = new KeyguardViewStateManager(this);
 
         mUserSetupCompleted = Settings.Secure.getIntForUser(mContext.getContentResolver(),
@@ -205,13 +186,6 @@
         }
     }
 
-    public void announceCurrentSecurityMethod() {
-        View v = (View) getSecurityView(mCurrentSecuritySelection);
-        if (v != null) {
-            v.announceForAccessibility(v.getContentDescription());
-        }
-    }
-
     private void getInitialTransportState() {
         DisplayClientState dcs = KeyguardUpdateMonitor.getInstance(mContext)
                 .getCachedDisplayClientState();
@@ -296,6 +270,12 @@
                 }
             }
         }
+        @Override
+        public void onNfcUnlock() {
+            if (NfcUnlock.getPropertyEnabled()) {
+                dismiss(true);
+            }
+        }
     };
 
     private static final boolean isMusicPlaying(int playbackState) {
@@ -320,21 +300,13 @@
     public boolean onTouchEvent(MotionEvent ev) {
         boolean result = super.onTouchEvent(ev);
         mTempRect.set(0, 0, 0, 0);
-        offsetRectIntoDescendantCoords(mSecurityViewContainer, mTempRect);
+        offsetRectIntoDescendantCoords(getSecurityContainer(), mTempRect);
         ev.offsetLocation(mTempRect.left, mTempRect.top);
-        result = mSecurityViewContainer.dispatchTouchEvent(ev) || result;
+        result = getSecurityContainer().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();
@@ -352,6 +324,8 @@
 
     @Override
     protected void onFinishInflate() {
+        super.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);
@@ -376,11 +350,8 @@
         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);
+        mViewStateManager.setSecurityViewContainer(getSecurityContainer());
 
         if (KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
             updateAndAddWidgets();
@@ -395,8 +366,7 @@
             };
         }
 
-        showPrimarySecurityScreen(false);
-        updateSecurityViews();
+        getSecurityContainer().updateSecurityViews(mViewStateManager.isBouncing());
         enableUserSelectorIfNecessary();
     }
 
@@ -425,17 +395,37 @@
         }
     }
 
-    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;
     }
 
+    @Override
+    public boolean dismiss(boolean authenticated) {
+        boolean finished = super.dismiss(authenticated);
+        if (!finished) {
+            mViewStateManager.showBouncer(true);
+
+            // Enter full screen mode if we're in SIM or Account screen
+            SecurityMode securityMode = getSecurityContainer().getSecurityMode();
+            boolean isFullScreen = getResources().getBoolean(R.bool.kg_sim_puk_account_full_screen);
+            boolean isSimOrAccount = securityMode == SecurityMode.SimPin
+                    || securityMode == SecurityMode.SimPuk
+                    || securityMode == SecurityMode.Account;
+            mAppWidgetContainer.setVisibility(
+                    isSimOrAccount && isFullScreen ? View.GONE : View.VISIBLE);
+
+            // Don't show camera or search in navbar when SIM or Account screen is showing
+            setSystemUiVisibility(isSimOrAccount ?
+                    (getSystemUiVisibility() | View.STATUS_BAR_DISABLE_SEARCH)
+                    : (getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_SEARCH));
+
+            if (mSlidingChallengeLayout != null) {
+                mSlidingChallengeLayout.setChallengeInteractive(!isFullScreen);
+            }
+        }
+        return finished;
+    }
+
     private int getDisabledFeatures(DevicePolicyManager dpm) {
         int disabledFeatures = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
         if (dpm != null) {
@@ -458,32 +448,10 @@
                 || (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 setLockPatternUtils(LockPatternUtils utils) {
+        super.setLockPatternUtils(utils);
+        getSecurityContainer().updateSecurityViews(mViewStateManager.isBouncing());
     }
 
     @Override
@@ -542,7 +510,8 @@
         }
     };
 
-    public void initializeSwitchingUserState(boolean switching) {
+    @Override
+    public void onUserSwitching(boolean switching) {
         if (!switching && mKeyguardMultiUserSelectorView != null) {
             mKeyguardMultiUserSelectorView.finalizeActiveUserView(false);
         }
@@ -570,283 +539,23 @@
         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) {
-        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 static class MyOnClickHandler extends OnClickHandler {
 
         // weak reference to the hostView to avoid keeping a live reference
         // due to Binder GC linkages to AppWidgetHost. By the same token,
         // this click handler should not keep references to any large
         // objects.
-        WeakReference<KeyguardHostView> mThis;
+        WeakReference<KeyguardHostView> mKeyguardHostView;
 
         MyOnClickHandler(KeyguardHostView hostView) {
-            mThis = new WeakReference<KeyguardHostView>(hostView);
+            mKeyguardHostView = new WeakReference<KeyguardHostView>(hostView);
         }
 
         @Override
         public boolean onClickHandler(final View view,
                 final android.app.PendingIntent pendingIntent,
                 final Intent fillInIntent) {
-            KeyguardHostView hostView = mThis.get();
+            KeyguardHostView hostView = mKeyguardHostView.get();
             if (hostView == null) {
                 return false;
             }
@@ -876,7 +585,7 @@
                 if (hostView.mViewStateManager.isChallengeShowing()) {
                     hostView.mViewStateManager.showBouncer(true);
                 } else {
-                    hostView.mCallback.dismiss(false);
+                    hostView.dismiss();
                 }
                 return true;
             } else {
@@ -885,249 +594,33 @@
         };
     };
 
-    // 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);
-
-        // Don't show camera or search in navbar when SIM or Account screen is showing
-        setSystemUiVisibility(isSimOrAccount ?
-                (getSystemUiVisibility() | View.STATUS_BAR_DISABLE_SEARCH)
-                : (getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_SEARCH));
-
-        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();
-
-        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();
-
+        super.onScreenTurnedOn();
         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);
+        super.onScreenTurnedOff();
         // We use mAppWidgetToShow to show a particular widget after you add it-- once the screen
         // turns off we reset that behavior
         clearAppWidgetToShow();
         if (KeyguardUpdateMonitor.getInstance(mContext).hasBootCompleted()) {
             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) {
@@ -1175,23 +668,6 @@
             }
         };
 
-    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;
@@ -1213,7 +689,7 @@
                 @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);
+                    getActivityLauncher().launchWidgetPicker(AppWidgetManager.INVALID_APPWIDGET_ID);
                 }
             });
         }
@@ -1223,8 +699,8 @@
         // 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);
+            View cameraWidget = CameraWidgetFrame.create(mContext, mCameraWidgetCallbacks,
+                    getActivityLauncher());
             if (cameraWidget != null) {
                 mAppWidgetContainer.addWidget(cameraWidget);
             }
@@ -1575,9 +1051,6 @@
     }
 
     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();
@@ -1587,61 +1060,53 @@
         }
 
         // 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);
+        if (!um.isUserSwitcherEnabled()) {
             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);
+            if (DEBUG) Log.d(TAG, "can't find user_selector in layout.");
             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);
+        if (multiUserView instanceof KeyguardMultiUserSelectorView) {
+            mKeyguardMultiUserSelectorView = (KeyguardMultiUserSelectorView) multiUserView;
+            mKeyguardMultiUserSelectorView.setVisibility(View.VISIBLE);
+            mKeyguardMultiUserSelectorView.addUsers(um.getUsers(true));
+            UserSwitcherCallback callback = new UserSwitcherCallback() {
+                @Override
+                public void hideSecurityView(int duration) {
+                    getSecurityContainer().animate().alpha(0).setDuration(duration);
                 }
+
+                @Override
+                public void showSecurityView() {
+                    getSecurityContainer().setAlpha(1.0f);
+                }
+
+                @Override
+                public void showUnlockHint() {
+                    if (getSecurityContainer() != null) {
+                        getSecurityContainer().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);
             }
         }
     }
@@ -1655,23 +1120,7 @@
             KeyguardWidgetFrame frame = mAppWidgetContainer.getWidgetPageAt(i);
             frame.removeAllViews();
         }
-        mSecurityViewContainer.onPause(); // clean up any actions in progress
-    }
-
-    /**
-     * 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;
+        getSecurityContainer().onPause(); // clean up any actions in progress
     }
 
     public void goToWidget(int appWidgetId) {
@@ -1679,58 +1128,26 @@
         mSwitchPageRunnable.run();
     }
 
-    public boolean handleMenuKey() {
-        // The following enables the MENU key to work for testing automation
-        if (shouldEnableMenuKey()) {
-            showNextSecurityScreenOrFinish(false);
-            return true;
-        }
-        return false;
+    @Override
+    protected void showBouncer(boolean show) {
+        super.showBouncer(show);
+        mViewStateManager.showBouncer(show);
     }
 
-    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);
-    }
-
-    public void dispatch(MotionEvent event) {
+    @Override
+    public void onExternalMotionEvent(MotionEvent event) {
         mAppWidgetContainer.handleExternalCameraEvent(event);
     }
 
-    public void launchCamera() {
-        mActivityLauncher.launchCamera(getHandler(), null);
+    @Override
+    protected void onCreateOptions(Bundle options) {
+        if (options != null) {
+            int widgetToShow = options.getInt(LockPatternUtils.KEYGUARD_SHOW_APPWIDGET,
+                    AppWidgetManager.INVALID_APPWIDGET_ID);
+            if (widgetToShow != AppWidgetManager.INVALID_APPWIDGET_ID) {
+                goToWidget(widgetToShow);
+            }
+        }
     }
 
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index 751572c..2e4dbdf 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -23,16 +23,10 @@
 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;
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
index 7975d8e..06815e1 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMultiUserSelectorView.java
@@ -76,11 +76,13 @@
         Collections.sort(users, mOrderAddedComparator);
 
         for (UserInfo user: users) {
-            KeyguardMultiUserAvatar uv = createAndAddUser(user);
-            if (user.id == activeUser.id) {
-                mActiveUserAvatar = uv;
+            if (user.supportsSwitchTo()) {
+                KeyguardMultiUserAvatar uv = createAndAddUser(user);
+                if (user.id == activeUser.id) {
+                    mActiveUserAvatar = uv;
+                }
+                uv.setActive(false, false, null);
             }
-            uv.setActive(false, false, null);
         }
         mActiveUserAvatar.lockPressed(true);
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index 3d1c3f3..ca2d615 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -17,7 +17,6 @@
 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;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index 4e3568b..e733afc 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -16,13 +16,10 @@
 
 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;
@@ -31,9 +28,6 @@
 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
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 3b72f43..14de6dd 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -262,7 +262,7 @@
 
         public void onPatternDetected(List<LockPatternView.Cell> pattern) {
             if (mLockPatternUtils.checkPattern(pattern)) {
-                mCallback.reportSuccessfulUnlockAttempt();
+                mCallback.reportUnlockAttempt(true);
                 mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
                 mCallback.dismiss(true);
             } else {
@@ -273,7 +273,7 @@
                 boolean registeredAttempt =
                         pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL;
                 if (registeredAttempt) {
-                    mCallback.reportFailedUnlockAttempt();
+                    mCallback.reportUnlockAttempt(false);
                 }
                 int attempts = mKeyguardUpdateMonitor.getFailedUnlockAttempts();
                 if (registeredAttempt &&
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
index 4f139ad..975ad6c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityCallback.java
@@ -15,8 +15,6 @@
  */
 package com.android.keyguard;
 
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
-
 public interface KeyguardSecurityCallback {
 
     /**
@@ -39,30 +37,14 @@
     boolean isVerifyUnlockOnly();
 
     /**
-     * Call when user correctly enters their credentials
+     * Call to report an unlock attempt.
+     * @param success set to 'true' if user correctly entered security 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();
+    void reportUnlockAttempt(boolean success);
 
     /**
      * 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
index 9d03c6a..0f62100 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -1,11 +1,55 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 package com.android.keyguard;
 
+import android.app.Activity;
+import android.app.AlertDialog;
 import android.content.Context;
 import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.FrameLayout;
 
-public class KeyguardSecurityContainer extends FrameLayout {
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+
+public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSecurityView {
+    private static final boolean DEBUG = KeyguardViewMediator.DEBUG;
+    private static final String TAG = "KeyguardSecurityView";
+    private KeyguardSecurityModel mSecurityModel;
+    private boolean mEnableFallback; // TODO: This should get the value from KeyguardPatternView
+    private LockPatternUtils mLockPatternUtils;
+
+    private KeyguardSecurityViewFlipper mSecurityViewFlipper;
+    private boolean mIsVerifyUnlockOnly;
+    private SecurityMode mCurrentSecuritySelection = SecurityMode.Invalid;
+    private boolean mIsBouncing;
+    private SecurityCallback mSecurityCallback;
+
+    // Used to notify the container when something interesting happens.
+    public interface SecurityCallback {
+        public boolean dismiss(boolean authenticated);
+        public void userActivity(long timeout);
+        public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
+        public void finish();
+    }
+
     public KeyguardSecurityContainer(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
@@ -16,9 +60,331 @@
 
     public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        mSecurityModel = new KeyguardSecurityModel(context);
+        mLockPatternUtils = new LockPatternUtils(context);
     }
 
-    KeyguardSecurityViewFlipper getFlipper() {
+    public void setSecurityCallback(SecurityCallback callback) {
+        mSecurityCallback = callback;
+    }
+
+    @Override
+    public void onResume(int reason) {
+        getSecurityView(mCurrentSecuritySelection).onResume(reason);
+    }
+
+    @Override
+    public void onPause() {
+        getSecurityView(mCurrentSecuritySelection).onPause();
+    }
+
+    void updateSecurityViews(boolean isBouncing) {
+        int children = mSecurityViewFlipper.getChildCount();
+        for (int i = 0; i < children; i++) {
+            updateSecurityView(mSecurityViewFlipper.getChildAt(i), isBouncing);
+        }
+    }
+
+    public void announceCurrentSecurityMethod() {
+        View v = (View) getSecurityView(mCurrentSecuritySelection);
+        if (v != null) {
+            v.announceForAccessibility(v.getContentDescription());
+        }
+    }
+
+    private KeyguardSecurityView getSecurityView(SecurityMode securityMode) {
+        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
+        KeyguardSecurityView view = null;
+        final int children = mSecurityViewFlipper.getChildCount();
+        for (int child = 0; child < children; child++) {
+            if (mSecurityViewFlipper.getChildAt(child).getId() == securityViewIdForMode) {
+                view = ((KeyguardSecurityView)mSecurityViewFlipper.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, mSecurityViewFlipper, false);
+            mSecurityViewFlipper.addView(v);
+            updateSecurityView(v, mIsBouncing);
+            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;
+    }
+
+    private void updateSecurityView(View view, boolean isBouncing) {
+        mIsBouncing = isBouncing;
+        if (view instanceof KeyguardSecurityView) {
+            KeyguardSecurityView ksv = (KeyguardSecurityView) view;
+            ksv.setKeyguardCallback(mCallback);
+            ksv.setLockPatternUtils(mLockPatternUtils);
+            if (isBouncing) {
+                ksv.showBouncer(0);
+            } else {
+                ksv.hideBouncer(0);
+            }
+        } else {
+            Log.w(TAG, "View " + view + " is not a KeyguardSecurityView");
+        }
+    }
+
+    protected void onFinishInflate() {
+        mSecurityViewFlipper = (KeyguardSecurityViewFlipper) findViewById(R.id.view_flipper);
+        mSecurityViewFlipper.setLockPatternUtils(mLockPatternUtils);
+    }
+
+    public void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+        mSecurityModel.setLockPatternUtils(utils);
+        mSecurityViewFlipper.setLockPatternUtils(mLockPatternUtils);
+    }
+
+    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;
+            // These don't have timeout dialogs.
+            case Account:
+            case Biometric:
+            case Invalid:
+            case None:
+            case SimPin:
+            case SimPuk:
+                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) {
+        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);
+    }
+
+    /**
+     * Shows the next security screen if there is one.
+     * @param authenticated true if the user entered the correct authentication
+     * @param authenticated
+     * @return true if keyguard is done
+     */
+    boolean 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) {
+            mSecurityCallback.finish();
+        }
+        return finish;
+    }
+
+    /**
+     * 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);
+
+        // 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);
+
+        // Find and show this child.
+        final int childCount = mSecurityViewFlipper.getChildCount();
+
+        final int securityViewIdForMode = getSecurityViewIdForMode(securityMode);
+        for (int i = 0; i < childCount; i++) {
+            if (mSecurityViewFlipper.getChildAt(i).getId() == securityViewIdForMode) {
+                mSecurityViewFlipper.setDisplayedChild(i);
+                break;
+            }
+        }
+
+        mCurrentSecuritySelection = securityMode;
+        mSecurityCallback.onSecurityModeChanged(securityMode, newView.needsInput());
+    }
+
+    private KeyguardSecurityViewFlipper getFlipper() {
         for (int i = 0; i < getChildCount(); i++) {
             View child = getChildAt(i);
             if (child instanceof KeyguardSecurityViewFlipper) {
@@ -41,5 +407,129 @@
             flipper.hideBouncer(duration);
         }
     }
+
+    private KeyguardSecurityCallback mCallback = new KeyguardSecurityCallback() {
+
+        public void userActivity(long timeout) {
+            if (mSecurityCallback != null) {
+                mSecurityCallback.userActivity(timeout);
+            }
+        }
+
+        public void dismiss(boolean authenticated) {
+            mSecurityCallback.dismiss(authenticated);
+        }
+
+        public boolean isVerifyUnlockOnly() {
+            return mIsVerifyUnlockOnly;
+        }
+
+        public void reportUnlockAttempt(boolean success) {
+            KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
+            if (success) {
+                monitor.clearFailedUnlockAttempts();
+                mLockPatternUtils.reportSuccessfulPasswordAttempt();
+            } else {
+                if (mCurrentSecuritySelection == SecurityMode.Biometric) {
+                    monitor.reportFailedBiometricUnlockAttempt();
+                } else {
+                    KeyguardSecurityContainer.this.reportFailedUnlockAttempt();
+                }
+            }
+        }
+
+        @Override
+        public void showBackupSecurity() {
+            KeyguardSecurityContainer.this.showBackupSecurityScreen();
+        }
+
+    };
+
+    // The following is used to ignore callbacks from SecurityViews that are no longer current
+    // (e.g. face unlock). This avoids unwanted asynchronous events from messing with the
+    // state for the current security method.
+    private KeyguardSecurityCallback mNullCallback = new KeyguardSecurityCallback() {
+        @Override
+        public void userActivity(long timeout) { }
+        @Override
+        public void showBackupSecurity() { }
+        @Override
+        public void reportUnlockAttempt(boolean success) { }
+        @Override
+        public boolean isVerifyUnlockOnly() { return false; }
+        @Override
+        public void dismiss(boolean securityVerified) { }
+    };
+
+    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;
+        }
+    }
+
+    public SecurityMode getSecurityMode() {
+        return mSecurityModel.getSecurityMode();
+    }
+
+    public void verifyUnlock() {
+        mIsVerifyUnlockOnly = true;
+        showSecurityScreen(getSecurityMode());
+    }
+
+    public SecurityMode getCurrentSecuritySelection() {
+        return mCurrentSecuritySelection;
+    }
+
+    public void dismiss(boolean authenticated) {
+        mCallback.dismiss(authenticated);
+    }
+
+    public boolean needsInput() {
+        return mSecurityViewFlipper.needsInput();
+    }
+
+    @Override
+    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
+        mSecurityViewFlipper.setKeyguardCallback(callback);
+    }
+
+    @Override
+    public void reset() {
+        mSecurityViewFlipper.reset();
+    }
+
+    @Override
+    public KeyguardSecurityCallback getCallback() {
+        return mSecurityViewFlipper.getCallback();
+    }
+
+    @Override
+    public void showUsabilityHint() {
+        mSecurityViewFlipper.showUsabilityHint();
+    }
+
 }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index 4129e33..9f5768a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -105,7 +105,7 @@
                     break;
 
                 default:
-                    throw new IllegalStateException("Unknown unlock mode:" + mode);
+                    throw new IllegalStateException("Unknown security quality:" + security);
             }
         }
         return mode;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
index 63be102..97aec68 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -16,19 +16,14 @@
 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;
@@ -63,23 +58,6 @@
             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);
@@ -122,23 +100,6 @@
         }
     };
 
-    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);
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index 9accbb4..ae7ac97 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -20,16 +20,12 @@
 import com.android.internal.telephony.PhoneConstants;
 
 import android.content.Context;
-import android.content.DialogInterface;
-import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.AlertDialog.Builder;
 import android.app.Dialog;
 import android.app.ProgressDialog;
-import android.os.Message;
 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;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index d882eca..ca4f811 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -17,14 +17,12 @@
 package com.android.keyguard;
 
 import android.content.Context;
-import android.animation.AnimatorSet.Builder;
 import android.app.Activity;
 import android.app.AlertDialog;
 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;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
new file mode 100644
index 0000000..cf983cb
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+public class KeyguardSimpleHostView extends KeyguardViewBase {
+
+    public KeyguardSimpleHostView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void showBouncer(boolean show) {
+        super.showBouncer(show);
+        if (show) {
+            getSecurityContainer().showBouncer(250);
+        } else {
+            getSecurityContainer().hideBouncer(250);
+        }
+    }
+
+    @Override
+    public void verifyUnlock() {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void cleanUp() {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public long getUserActivityTimeout() {
+        return -1; // not used
+    }
+
+    @Override
+    protected void onUserSwitching(boolean switching) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    protected void onCreateOptions(Bundle options) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    protected void onExternalMotionEvent(MotionEvent event) {
+        // TODO Auto-generated method stub
+    }
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
index 349078f..a7cd909 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardTransportControlView.java
@@ -32,7 +32,6 @@
 import android.media.RemoteController;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.SystemClock;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.transition.ChangeBounds;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a849316..3b712e9 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -36,6 +36,7 @@
 import static android.os.BatteryManager.EXTRA_HEALTH;
 import android.media.AudioManager;
 import android.media.IRemoteControlDisplay;
+import android.nfc.NfcUnlock;
 import android.os.BatteryManager;
 import android.os.Bundle;
 import android.os.Handler;
@@ -94,6 +95,7 @@
     protected static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
     private static final int MSG_SCREEN_TURNED_ON = 319;
     private static final int MSG_SCREEN_TURNED_OFF = 320;
+    private static final int MSG_NFC_UNLOCK = 321;
 
     private static KeyguardUpdateMonitor sInstance;
 
@@ -194,6 +196,9 @@
                 case MSG_SCREEN_TURNED_ON:
                     handleScreenTurnedOn();
                     break;
+                case MSG_NFC_UNLOCK:
+                    handleNfcUnlock();
+                    break;
             }
         }
     };
@@ -311,6 +316,15 @@
         }
     };
 
+    private final BroadcastReceiver mNfcUnlockReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (NfcUnlock.ACTION_NFC_UNLOCK.equals(intent.getAction())) {
+                mHandler.sendEmptyMessage(MSG_NFC_UNLOCK);
+            }
+        }
+    }
+    ;
     /**
      * When we receive a
      * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
@@ -495,6 +509,15 @@
         }
     }
 
+    private void handleNfcUnlock() {
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onNfcUnlock();
+            }
+        }
+    }
+
     private KeyguardUpdateMonitor(Context context) {
         mContext = context;
 
@@ -524,6 +547,11 @@
         filter.addAction(Intent.ACTION_USER_REMOVED);
         context.registerReceiver(mBroadcastReceiver, filter);
 
+        final IntentFilter nfcUnlockIntentFilter = new IntentFilter();
+        nfcUnlockIntentFilter.addAction(NfcUnlock.ACTION_NFC_UNLOCK);
+        context.registerReceiver(mNfcUnlockReceiver, nfcUnlockIntentFilter,
+                NfcUnlock.NFC_UNLOCK_PERMISSION, null /* run on default scheduler */);
+
         final IntentFilter bootCompleteFilter = new IntentFilter();
         bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
         bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index c08880d..481d132 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -20,6 +20,7 @@
 import android.graphics.Bitmap;
 import android.media.AudioManager;
 import android.os.SystemClock;
+import android.util.Log;
 import android.view.WindowManagerPolicy;
 
 import com.android.internal.telephony.IccCardConstants;
@@ -172,4 +173,9 @@
      *   {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}.
      */
     public void onScreenTurnedOff(int why) { }
+
+    /**
+     * Called when the NFC Service has found a tag that is registered for NFC unlock.
+     */
+    public void onNfcUnlock() { }
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
index bff1f93..78f4506 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -17,18 +17,36 @@
 package com.android.keyguard;
 
 import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.app.SearchManager;
 import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Canvas;
 import android.media.AudioManager;
 import android.media.IAudioService;
+import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
 import android.telephony.TelephonyManager;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Slog;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
 import android.widget.FrameLayout;
 
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
+import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+
+import java.io.File;
+
 /**
  * Base class for keyguard view.  {@link #reset} is where you should
  * reset the state of your view.  Use the {@link KeyguardViewCallback} via
@@ -38,16 +56,22 @@
  * Handles intercepting of media keys that still work when the keyguard is
  * showing.
  */
-public abstract class KeyguardViewBase extends FrameLayout {
+public abstract class KeyguardViewBase extends FrameLayout implements SecurityCallback {
 
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager = null;
     protected KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
+    protected LockPatternUtils mLockPatternUtils;
+    private OnDismissAction mDismissAction;
 
     // 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;
+    private static final boolean DEBUG = false;
+    private static final String TAG = "KeyguardViewBase";
+
+    private KeyguardSecurityContainer mSecurityContainer;
 
     public KeyguardViewBase(Context context) {
         this(context, null);
@@ -57,20 +81,181 @@
         super(context, attrs);
     }
 
-    /**
-     * Called when the screen turned off.
-     */
-    abstract public void onScreenTurnedOff();
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.keyguardDoneDrawing();
+        }
+    }
 
     /**
-     * Called when the screen turned on.
+     * Sets an action to run when keyguard finishes.
+     *
+     * @param action
      */
-    abstract public void onScreenTurnedOn();
+    public void setOnDismissAction(OnDismissAction action) {
+        mDismissAction = action;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        mSecurityContainer =
+                (KeyguardSecurityContainer) findViewById(R.id.keyguard_security_container);
+        mLockPatternUtils = new LockPatternUtils(mContext);
+        mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
+        mSecurityContainer.setSecurityCallback(this);
+        mSecurityContainer.showPrimarySecurityScreen(false);
+        // mSecurityContainer.updateSecurityViews(false /* not bouncing */);
+        setBackButtonEnabled(false);
+    }
 
     /**
      * Called when the view needs to be shown.
      */
-    abstract public void show();
+    public void show() {
+        if (DEBUG) Log.d(TAG, "show()");
+        mSecurityContainer.showPrimarySecurityScreen(false);
+    }
+
+    /**
+     *  Dismisses the keyguard by going to the next screen or making it gone.
+     */
+    public void dismiss() {
+        dismiss(false);
+    }
+
+    private void setBackButtonEnabled(boolean enabled) {
+        setSystemUiVisibility(enabled ?
+                getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_BACK :
+                getSystemUiVisibility() | View.STATUS_BAR_DISABLE_BACK);
+    }
+
+    protected void showBouncer(boolean show) {
+        CharSequence what = getContext().getResources().getText(
+                show ? R.string.keyguard_accessibility_show_bouncer
+                        : R.string.keyguard_accessibility_hide_bouncer);
+        announceForAccessibility(what);
+        announceCurrentSecurityMethod();
+    }
+
+    public boolean handleBackKey() {
+        if (mSecurityContainer.getCurrentSecuritySelection() == SecurityMode.Account) {
+            // go back to primary screen and re-disable back
+            setBackButtonEnabled(false);
+            mSecurityContainer.showPrimarySecurityScreen(false /*turningOff*/);
+            return true;
+        }
+        if (mSecurityContainer.getCurrentSecuritySelection() != SecurityMode.None) {
+            mSecurityContainer.dismiss(false);
+            return true;
+        }
+        return false;
+    }
+
+    protected void announceCurrentSecurityMethod() {
+        mSecurityContainer.announceCurrentSecurityMethod();
+    }
+
+    protected KeyguardSecurityContainer getSecurityContainer() {
+        return mSecurityContainer;
+    }
+
+    /**
+     * Extend display timeout
+     * @param timeout duration to delay timeout, in ms.
+     */
+    @Override
+    public void userActivity(long timeout) {
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.userActivity(timeout);
+        }
+    }
+
+    @Override
+    public boolean dismiss(boolean authenticated) {
+        return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated);
+    }
+
+    /**
+     * Authentication has happened and it's time to dismiss keyguard. This function
+     * should clean up and inform KeyguardViewMediator.
+     */
+    @Override
+    public void 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);
+            }
+        }
+    }
+
+    @Override
+    public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
+        // Enable or disable the back button based on security mode
+        if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) {
+            // we're showing account as a backup, provide a way to get back to primary
+            setBackButtonEnabled(true);
+        }
+
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.setNeedsInput(needsInput);
+        }
+    }
+
+    public void userActivity() {
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.userActivity();
+        }
+    }
+
+    protected void onUserActivityTimeoutChanged() {
+        if (mViewMediatorCallback != null) {
+            mViewMediatorCallback.onUserActivityTimeoutChanged();
+        }
+    }
+
+    /**
+     * Called when the screen turned off.
+     */
+    protected 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);
+        mSecurityContainer.showPrimarySecurityScreen(true);
+        mSecurityContainer.onPause();
+        clearFocus();
+    }
+
+    /**
+     * Called when the screen turned on.
+     */
+    protected void onScreenTurnedOn() {
+        if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
+        mSecurityContainer.showPrimarySecurityScreen(false);
+        mSecurityContainer.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();
+        requestFocus();
+    }
 
     /**
      * Verify that the user can get past the keyguard securely.  This is called,
@@ -79,7 +264,24 @@
      *
      * The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
      */
-    abstract public void verifyUnlock();
+    public void verifyUnlock() {
+        SecurityMode securityMode = mSecurityContainer.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
+            mSecurityContainer.verifyUnlock();
+        }
+    }
 
     /**
      * Called before this view is being removed.
@@ -183,7 +385,7 @@
         return false;
     }
 
-    void handleMediaKeyEvent(KeyEvent keyEvent) {
+    private void handleMediaKeyEvent(KeyEvent keyEvent) {
         IAudioService audioService = IAudioService.Stub.asInterface(
                 ServiceManager.checkService(Context.AUDIO_SERVICE));
         if (audioService != null) {
@@ -206,8 +408,91 @@
         }
     }
 
+    /**
+     * 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 boolean handleMenuKey() {
+        // The following enables the MENU key to work for testing automation
+        if (shouldEnableMenuKey()) {
+            dismiss();
+            return true;
+        }
+        return false;
+    }
+
     public void setViewMediatorCallback(
             KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
         mViewMediatorCallback = viewMediatorCallback;
+        // Update ViewMediator with the current input method requirements
+        mViewMediatorCallback.setNeedsInput(mSecurityContainer.needsInput());
     }
+
+    protected KeyguardActivityLauncher getActivityLauncher() {
+        return mActivityLauncher;
+    }
+
+    private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
+        @Override
+        Context getContext() {
+            return mContext;
+        }
+
+        @Override
+        void setOnDismissAction(OnDismissAction action) {
+            KeyguardViewBase.this.setOnDismissAction(action);
+        }
+
+        @Override
+        LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+
+        @Override
+        void requestDismissKeyguard() {
+            KeyguardViewBase.this.dismiss(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);
+    }
+
+    public void launchCamera() {
+        mActivityLauncher.launchCamera(getHandler(), null);
+    }
+
+    protected void setLockPatternUtils(LockPatternUtils utils) {
+        mLockPatternUtils = utils;
+        mSecurityContainer.setLockPatternUtils(utils);
+    }
+
+    protected abstract void onUserSwitching(boolean switching);
+
+    protected abstract void onCreateOptions(Bundle options);
+
+    protected abstract void onExternalMotionEvent(MotionEvent event);
+
 }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 7d0059f..5b35ba88 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -16,15 +16,17 @@
 
 package com.android.keyguard;
 
-import android.app.PendingIntent;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
+
 import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.analytics.KeyguardAnalytics;
 
-import android.app.Activity;
+import org.xmlpull.v1.XmlPullParser;
+
 import android.app.ActivityManager;
-import android.appwidget.AppWidgetManager;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
@@ -40,6 +42,7 @@
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.SystemProperties;
+import android.provider.Settings;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -68,16 +71,18 @@
 
     // Timeout used for keypresses
     static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
+    private static final boolean ENABLE_SIMPLE_KEYGUARD = false;
 
     private final Context mContext;
     private final ViewManager mViewManager;
     private final KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback;
+    private final KeyguardAnalytics.Callback mAnalyticsCallback;
 
     private WindowManager.LayoutParams mWindowLayoutParams;
     private boolean mNeedsInput = false;
 
     private ViewManagerHost mKeyguardHost;
-    private KeyguardHostView mKeyguardView;
+    private KeyguardViewBase mKeyguardView;
 
     private boolean mScreenOn = false;
     private LockPatternUtils mLockPatternUtils;
@@ -103,11 +108,12 @@
      */
     public KeyguardViewManager(Context context, ViewManager viewManager,
             KeyguardViewMediator.ViewMediatorCallback callback,
-            LockPatternUtils lockPatternUtils) {
+            LockPatternUtils lockPatternUtils, KeyguardAnalytics.Callback analyticsCallback) {
         mContext = context;
         mViewManager = viewManager;
         mViewMediatorCallback = callback;
         mLockPatternUtils = lockPatternUtils;
+        mAnalyticsCallback = analyticsCallback;
     }
 
     /**
@@ -116,6 +122,9 @@
      */
     public synchronized void show(Bundle options) {
         if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
+        if (mAnalyticsCallback != null) {
+            mAnalyticsCallback.onShow();
+        }
 
         boolean enableScreenRotation = shouldEnableScreenRotation();
 
@@ -258,9 +267,19 @@
             }
             return super.dispatchKeyEvent(event);
         }
+
+        @Override
+        public boolean dispatchTouchEvent(MotionEvent ev) {
+            boolean result = false;
+            if (mAnalyticsCallback != null) {
+                result = mAnalyticsCallback.onTouchEvent(ev, getWidth(), getHeight()) || result;
+            }
+            return super.dispatchTouchEvent(ev) || result;
+        }
     }
 
     SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>();
+    private int mCurrentLayout;
 
     private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,
             Bundle options) {
@@ -308,7 +327,14 @@
         if (force || mKeyguardView == null) {
             mKeyguardHost.setCustomBackground(null);
             mKeyguardHost.removeAllViews();
-            inflateKeyguardView(options);
+            int layout = (allowNotificationsOnSecureKeyguard() && ENABLE_SIMPLE_KEYGUARD)
+                    ? R.layout.keyguard_simple_host_view
+                    : R.layout.keyguard_host_view;
+            if (mCurrentLayout != layout) {
+                mStateContainer.clear(); // don't restore to the wrong view hierarchy
+                mCurrentLayout = layout;
+            }
+            mKeyguardView = inflateKeyguardView(options, layout);
             mKeyguardView.requestFocus();
         }
         updateUserActivityTimeoutInWindowLayoutParams();
@@ -317,38 +343,24 @@
         mKeyguardHost.restoreHierarchyState(mStateContainer);
     }
 
-    private void inflateKeyguardView(Bundle options) {
+    private boolean allowNotificationsOnSecureKeyguard() {
+        ContentResolver cr = mContext.getContentResolver();
+        return Settings.Global.getInt(cr, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) == 1;
+    }
+
+    private KeyguardViewBase inflateKeyguardView(Bundle options, int layoutId) {
         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);
-            }
-        }
+        View view = inflater.inflate(layoutId, mKeyguardHost, true);
+        KeyguardViewBase keyguard = (KeyguardViewBase) view.findViewById(R.id.keyguard_host_view);
+        keyguard.setLockPatternUtils(mLockPatternUtils);
+        keyguard.setViewMediatorCallback(mViewMediatorCallback);
+        keyguard.onUserSwitching(options != null && options.getBoolean(IS_SWITCHING_USER));
+        keyguard.onCreateOptions(options);
+        return keyguard;
     }
 
     public void updateUserActivityTimeout() {
@@ -476,6 +488,9 @@
                 Slog.w(TAG, "Exception calling onShown():", e);
             }
         }
+        if (mAnalyticsCallback != null) {
+            mAnalyticsCallback.onScreenOn();
+        }
     }
 
     public synchronized void verifyUnlock() {
@@ -490,6 +505,10 @@
     public synchronized void hide() {
         if (DEBUG) Log.d(TAG, "hide()");
 
+        if (mAnalyticsCallback != null) {
+            mAnalyticsCallback.onHide();
+        }
+
         if (mKeyguardHost != null) {
             mKeyguardHost.setVisibility(View.GONE);
 
@@ -544,7 +563,7 @@
 
     public void dispatch(MotionEvent event) {
         if (mKeyguardView != null) {
-            mKeyguardView.dispatch(event);
+            mKeyguardView.onExternalMotionEvent(event);
         }
     }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
index 4086f84..3fc562c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewMediator.java
@@ -16,10 +16,10 @@
 
 package com.android.keyguard;
 
-import android.graphics.Bitmap;
 import com.android.internal.policy.IKeyguardExitCallback;
 import com.android.internal.policy.IKeyguardShowCallback;
 import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
+import static com.android.keyguard.analytics.KeyguardAnalytics.SessionTypeAdapter;
 
 import android.app.Activity;
 import android.app.ActivityManagerNative;
@@ -34,6 +34,7 @@
 import android.content.IntentFilter;
 import android.media.AudioManager;
 import android.media.SoundPool;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -49,13 +50,16 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
-import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
 
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.analytics.Session;
+import com.android.keyguard.analytics.KeyguardAnalytics;
+
+import java.io.File;
 
 
 /**
@@ -102,6 +106,7 @@
 public class KeyguardViewMediator {
     private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
     final static boolean DEBUG = false;
+    private static final boolean ENABLE_ANALYTICS = Build.IS_DEBUGGABLE;
     private final static boolean DBG_WAKE = false;
 
     private final static String TAG = "KeyguardViewMediator";
@@ -151,6 +156,23 @@
      */
     private static final boolean ENABLE_INSECURE_STATUS_BAR_EXPAND = true;
 
+    /**
+     * Allow the user to expand the status bar when a SECURE keyguard is engaged
+     * and {@link Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS} is set
+     * (private notifications will be masked).
+     */
+    private static final boolean ENABLE_SECURE_STATUS_BAR_EXPAND = true;
+
+    /**
+     * Default value of {@link Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
+     */
+    private static final boolean ALLOW_NOTIFICATIONS_DEFAULT = false;
+
+    /**
+     * Secure setting whether analytics are collected on the keyguard.
+     */
+    private static final String KEYGUARD_ANALYTICS_SETTING = "keyguard_analytics";
+
     /** The stream type that the lock sounds are tied to. */
     private int mMasterStreamType;
 
@@ -184,6 +206,8 @@
 
     private KeyguardViewManager mKeyguardViewManager;
 
+    private final KeyguardAnalytics mKeyguardAnalytics;
+
     // these are protected by synchronized (this)
 
     /**
@@ -248,6 +272,11 @@
     private int mLockSoundStreamId;
 
     /**
+     * Tracks value of {@link Settings.Global#LOCK_SCREEN_SHOW_NOTIFICATIONS}.
+     */
+    private boolean mAllowNotificationsWhenSecure;
+
+    /**
      * The volume applied to the lock/unlock sounds.
      */
     private final float mLockSoundVolume;
@@ -513,12 +542,25 @@
                 && !mLockPatternUtils.isLockScreenDisabled();
 
         WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-
-        mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
-                mLockPatternUtils);
-
         final ContentResolver cr = mContext.getContentResolver();
 
+        if (ENABLE_ANALYTICS && !LockPatternUtils.isSafeModeEnabled() &&
+                Settings.Secure.getInt(cr, KEYGUARD_ANALYTICS_SETTING, 0) == 1) {
+            mKeyguardAnalytics = new KeyguardAnalytics(context, new SessionTypeAdapter() {
+
+                @Override
+                public int getSessionType() {
+                    return mLockPatternUtils.isSecure() ? Session.TYPE_KEYGUARD_SECURE
+                            : Session.TYPE_KEYGUARD_INSECURE;
+                }
+            }, new File(mContext.getCacheDir(), "keyguard_analytics.bin"));
+        } else {
+            mKeyguardAnalytics = null;
+        }
+        mKeyguardViewManager = new KeyguardViewManager(context, wm, mViewMediatorCallback,
+                mLockPatternUtils,
+                mKeyguardAnalytics != null ? mKeyguardAnalytics.getCallback() : null);
+
         mScreenOn = mPM.isScreenOn();
 
         mLockSounds = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
@@ -616,6 +658,9 @@
             } else {
                 doKeyguardLocked(null);
             }
+            if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) {
+                mKeyguardAnalytics.getCallback().onScreenOff();
+            }
         }
         KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurndOff(why);
     }
@@ -689,7 +734,7 @@
 
     private void maybeSendUserPresentBroadcast() {
         if (mSystemReady && mLockPatternUtils.isLockScreenDisabled()
-                && mUserManager.getUsers(true).size() == 1) {
+                && !mUserManager.isUserSwitcherEnabled()) {
             // 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()
@@ -854,6 +899,9 @@
                 updateActivityLockScreenState();
                 adjustStatusBarLocked();
             }
+            if (ENABLE_ANALYTICS && mKeyguardAnalytics != null) {
+                mKeyguardAnalytics.getCallback().onSetHidden(isHidden);
+            }
         }
     }
 
@@ -896,6 +944,13 @@
             return;
         }
 
+        // note whether notification access should be allowed
+        mAllowNotificationsWhenSecure = ENABLE_SECURE_STATUS_BAR_EXPAND
+                && 0 != Settings.Global.getInt(
+                        mContext.getContentResolver(),
+                        Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                        ALLOW_NOTIFICATIONS_DEFAULT ? 1 : 0);
+
         // 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");
@@ -918,12 +973,19 @@
             return;
         }
 
-        if (mUserManager.getUsers(true).size() < 2
+        if (!mUserManager.isUserSwitcherEnabled()
                 && mLockPatternUtils.isLockScreenDisabled() && !lockedOrMissing) {
             if (DEBUG) Log.d(TAG, "doKeyguard: not showing because lockscreen is off");
             return;
         }
 
+        if (mLockPatternUtils.checkVoldPassword()) {
+            if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
+            // Without this, settings is not enabled until the lock screen first appears
+            hideLocked();
+            return;
+        }
+
         if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen");
         showLocked(options);
     }
@@ -1280,13 +1342,15 @@
                 // (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) {
+                if ((isSecure() && !mAllowNotificationsWhenSecure)
+                        || !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;
+                    // showing secure lockscreen; disable ticker and switch private notifications
+                    // to show their public versions, if available.
+                    flags |= StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS;
                 }
                 if (!isAssistantAvailable()) {
                     flags |= StatusBarManager.DISABLE_SEARCH;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
index 169899f..e47edf3 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewStateManager.java
@@ -20,7 +20,6 @@
 import android.animation.AnimatorListenerAdapter;
 import android.os.Handler;
 import android.os.Looper;
-import android.util.Log;
 import android.view.View;
 
 public class KeyguardViewStateManager implements
@@ -106,11 +105,6 @@
     }
 
     public void showBouncer(boolean show) {
-        CharSequence what = mKeyguardHostView.getContext().getResources().getText(
-                show ? R.string.keyguard_accessibility_show_bouncer
-                        : R.string.keyguard_accessibility_hide_bouncer);
-        mKeyguardHostView.announceForAccessibility(what);
-        mKeyguardHostView.announceCurrentSecurityMethod();
         mChallengeLayout.showBouncer();
     }
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
index 99f7757..6120127 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardWidgetPager.java
@@ -953,17 +953,13 @@
                     // to keep event dispatch happy.
                     mCameraEventInProgress = true;
                     userActivity();
-                    startPageWarp(cameraPage);
                     break;
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL:
                     mCameraEventInProgress = false;
-                    endWarp = isWarping();
                     break;
             }
             dispatchTouchEvent(event);
-            // This has to happen after the event has been handled by the real widget pager
-            if (endWarp) stopPageWarp();
         }
         endCameraEvent();
     }
diff --git a/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
index 4cfc9dc..340a4d5 100644
--- a/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
+++ b/packages/Keyguard/src/com/android/keyguard/MultiPaneChallengeLayout.java
@@ -28,7 +28,6 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.View.MeasureSpec;
 import android.widget.LinearLayout;
 
 public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
diff --git a/packages/Keyguard/src/com/android/keyguard/PagedView.java b/packages/Keyguard/src/com/android/keyguard/PagedView.java
index 53c17a5..d233ee9 100644
--- a/packages/Keyguard/src/com/android/keyguard/PagedView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PagedView.java
@@ -36,15 +36,7 @@
 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.ViewPropertyAnimator;
+import android.view.*;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -262,6 +254,7 @@
     // Page warping
     private int mPageSwapIndex = -1; // the page we swapped out if needed
     private int mPageWarpIndex = -1; // the page we intend to warp
+
     private boolean mWarpPageExposed;
     private ViewPropertyAnimator mWarpAnimation;
 
@@ -494,9 +487,6 @@
             mIsPageMoving = true;
             if (isWarping()) {
                 dispatchOnPageBeginWarp();
-                if (mPageSwapIndex != -1) {
-                    swapPages(mPageSwapIndex, mPageWarpIndex);
-                }
             }
             onPageBeginMoving();
         }
@@ -523,22 +513,13 @@
         if (mIsPageMoving) {
             mIsPageMoving = false;
             if (isWarping()) {
-                if (mPageSwapIndex != -1) {
-                    swapPages(mPageSwapIndex, mPageWarpIndex);
-                }
                 dispatchOnPageEndWarp();
-                resetPageWarp();
+                mWarpPageExposed = false;
             }
             onPageEndMoving();
         }
     }
 
-    private void resetPageWarp() {
-        // TODO: Verify pages have been reset correctly
-        mPageSwapIndex = -1;
-        mPageWarpIndex = -1;
-    }
-
     protected boolean isPageMoving() {
         return mIsPageMoving;
     }
@@ -794,11 +775,6 @@
             setHorizontalScrollBarEnabled(true);
             mFirstLayout = false;
         }
-        // If a page was swapped when we rebuilt the layout, swap it again now.
-        if (mPageSwapIndex  != -1) {
-            if (DEBUG_WARP) Log.v(TAG, "onLayout: swapping pages");
-            swapPages(mPageSwapIndex, mPageWarpIndex);
-        }
     }
 
     protected void screenScrolled(int screenCenter) {
@@ -1252,6 +1228,25 @@
         }
     }
 
+    private boolean isHorizontalCameraScroll(MotionEvent ev) {
+        // Disallow scrolling if we don't have a valid pointer index
+        final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+        if (pointerIndex == -1) return false;
+
+        // If we're only allowing edge swipes, we break out early if the down event wasn't
+        // at the edge.
+        if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return false;
+
+        final float x = ev.getX(pointerIndex);
+        final int xDiff = (int) Math.abs(x - mDownMotionX);
+
+        final int touchSlop = Math.round(TOUCH_SLOP_SCALE * mTouchSlop);
+        boolean xPaged = xDiff > mPagingTouchSlop;
+        boolean xMoved = xDiff > touchSlop;
+
+        return mIsCameraEvent && (mUsePagingTouchSlop ? xPaged : xMoved);
+    }
+
     /*
      * Determines if we should change the touch state to start scrolling after the
      * user moves their touch point too far.
@@ -1271,14 +1266,12 @@
         if (mOnlyAllowEdgeSwipes && !mDownEventOnEdge) return false;
 
         final int xDiff = (int) Math.abs(x - mLastMotionX);
-        final int yDiff = (int) Math.abs(y - mLastMotionY);
 
         final int touchSlop = Math.round(TOUCH_SLOP_SCALE * mTouchSlop);
         boolean xPaged = xDiff > mPagingTouchSlop;
         boolean xMoved = xDiff > touchSlop;
-        boolean yMoved = yDiff > touchSlop;
 
-        return (xMoved || xPaged || yMoved) && (mUsePagingTouchSlop ? xPaged : xMoved);
+        return mUsePagingTouchSlop ? xPaged : xMoved;
     }
 
     private void startScrolling(MotionEvent ev) {
@@ -1446,7 +1439,7 @@
                     mTouchX += deltaX;
                     mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
                     if (isWarping()) {
-                        KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
+                        KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(getPageWarpIndex());
                         v.setTranslationX(v.getTranslationX() - deltaX);
                     } else if (!mDeferScrollUpdate) {
                         scrollBy((int) deltaX, 0);
@@ -1565,8 +1558,13 @@
                     removeCallbacks(mSidePageHoverRunnable);
                     mSidePageHoverIndex = -1;
                 }
-            } else if (mIsCameraEvent || determineScrollingStart(ev)) {
+            } else if (determineScrollingStart(ev)) {
                 startScrolling(ev);
+            } else if (isHorizontalCameraScroll(ev)) {
+                startScrolling(ev);
+                // we need to cancel the camera animation
+                KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(getPageWarpIndex());
+                v.animate().cancel();
             }
             break;
 
@@ -1612,7 +1610,8 @@
                 } else if (((isSignificantMove && deltaX < 0 && !isFling) ||
                         (isFling && velocityX < 0)) &&
                         mCurrentPage < getChildCount() - 1) {
-                    finalPage = returnToOriginalPage ? mCurrentPage : mCurrentPage + 1;
+                    finalPage = returnToOriginalPage ? mCurrentPage :
+                            isWarping() ? getPageWarpIndex() : mCurrentPage + 1;
                     snapToPageWithVelocity(finalPage, velocityX);
                 } else {
                     snapToDestination();
@@ -1929,20 +1928,19 @@
     }
 
     protected void snapToPage(int whichPage, int delta, int duration, boolean immediate) {
-        if (mPageSwapIndex != -1 && whichPage == mPageSwapIndex) {
-            mNextPage = mPageWarpIndex; // jump to the warp page
+        if (isWarping() && whichPage == mCurrentPage+1) {
+            mNextPage = getPageWarpIndex(); // jump to the warp page
             if (DEBUG_WARP) Log.v(TAG, "snapToPage(" + whichPage + ") : reset mPageSwapIndex");
         } else {
             mNextPage = whichPage;
         }
 
-        if (isWarping()) {
+        if(mWarpPageExposed) {
             dispatchOnPageEndWarp();
-            notifyPageSwitching(whichPage);
-            resetPageWarp();
-        } else {
-            notifyPageSwitching(whichPage);
+            mWarpPageExposed = false;
         }
+        notifyPageSwitching(whichPage);
+
 
         View focusedChild = getFocusedChild();
         if (focusedChild != null && whichPage != mCurrentPage &&
@@ -1973,7 +1971,7 @@
     }
 
     protected boolean isWarping() {
-        return mPageWarpIndex != -1;
+        return mWarpPageExposed;
     }
 
     public void scrollLeft() {
@@ -2716,6 +2714,12 @@
                 animateWarpPageOffScreen("onScreen end", true);
             }
         }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            super.onAnimationCancel(animation);
+            mWarpAnimation = null;
+        }
     };
 
     AnimatorListenerAdapter mOffScreenAnimationListener = new AnimatorListenerAdapter() {
@@ -2723,6 +2727,14 @@
         public void onAnimationEnd(Animator animation) {
             mWarpAnimation = null;
             mWarpPageExposed = false;
+            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(getPageWarpIndex());
+            v.setTranslationX(0.0f);
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            super.onAnimationCancel(animation);
+            mWarpAnimation = null;
         }
     };
 
@@ -2731,7 +2743,7 @@
         if (abortAnimation) {
             // We're done with the animation and moving to a new page.  Let the scroller
             // take over the animation.
-            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
+            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(getPageWarpIndex());
             v.animate().cancel();
             // Make the scroll amount match the current warp position.
             scrollBy(Math.round(-v.getTranslationX()), 0);
@@ -2747,28 +2759,43 @@
 
     private void animateWarpPageOnScreen(String reason) {
         if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOnScreen(" + reason + ")");
-        if (isWarping() && !mWarpPageExposed) {
+        if (!mWarpPageExposed) {
             mWarpPageExposed = true;
             dispatchOnPageBeginWarp();
-            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
+            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(getPageWarpIndex());
             if (DEBUG_WARP) Log.v(TAG, "moving page on screen: Tx=" + v.getTranslationX());
             DecelerateInterpolator interp = new DecelerateInterpolator(1.5f);
+            int totalOffset = getCurrentWarpOffset();
+            v.setTranslationX(totalOffset);
             mWarpAnimation = v.animate();
-            mWarpAnimation.translationX(mWarpPeekAmount)
+            mWarpAnimation.translationX(mWarpPeekAmount+totalOffset)
                     .setInterpolator(interp)
                     .setDuration(WARP_PEEK_ANIMATION_DURATION)
                     .setListener(mOnScreenAnimationListener);
         }
     }
 
+    private int getCurrentWarpOffset() {
+        if (mCurrentPage == getPageWarpIndex()) {
+            return 0;
+        }
+        View viewRight = getPageAt(mCurrentPage + 1);
+        View warpView = getPageAt(getPageWarpIndex());
+        if (viewRight != warpView && viewRight != null && warpView != null) {
+            return viewRight.getLeft() - warpView.getLeft();
+        }
+        return 0;
+    }
+
     private void animateWarpPageOffScreen(String reason, boolean animate) {
         if (DEBUG_WARP) Log.v(TAG, "animateWarpPageOffScreen(" + reason + " anim:" + animate + ")");
-        if (isWarping()) {
+        if (mWarpPageExposed) {
             dispatchOnPageEndWarp();
-            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(mPageWarpIndex);
+            KeyguardWidgetFrame v = (KeyguardWidgetFrame) getPageAt(getPageWarpIndex());
             if (DEBUG_WARP) Log.v(TAG, "moving page off screen: Tx=" + v.getTranslationX());
             AccelerateInterpolator interp = new AccelerateInterpolator(1.5f);
-            v.animate().translationX(0.0f)
+            int totalOffset = getCurrentWarpOffset();
+            v.animate().translationX(totalOffset)
                     .setInterpolator(interp)
                     .setDuration(animate ? WARP_PEEK_ANIMATION_DURATION : 0)
                     .setListener(mOffScreenAnimationListener);
@@ -2799,7 +2826,7 @@
     }
 
     protected int getPageWarpIndex() {
-        return mPageWarpIndex;
+        return getPageCount() - 1;
     }
 
     public void stopPageWarp() {
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java b/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java
new file mode 100644
index 0000000..55750cc
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/KeyguardAnalytics.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard.analytics;
+
+import com.google.protobuf.nano.CodedOutputByteBufferNano;
+import com.google.protobuf.nano.MessageNano;
+
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.AsyncTask;
+import android.util.Log;
+import android.view.MotionEvent;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Tracks sessions, touch and sensor events in Keyguard.
+ *
+ * A session starts when the user is presented with the Keyguard and ends when the Keyguard is no
+ * longer visible to the user.
+ */
+public class KeyguardAnalytics implements SensorEventListener {
+
+    private static final boolean DEBUG = false;
+    private static final String TAG = "KeyguardAnalytics";
+    private static final long TIMEOUT_MILLIS = 11000; // 11 seconds.
+
+    private static final int[] SENSORS = new int[] {
+            Sensor.TYPE_ACCELEROMETER,
+            Sensor.TYPE_GYROSCOPE,
+            Sensor.TYPE_PROXIMITY,
+            Sensor.TYPE_LIGHT,
+            Sensor.TYPE_ROTATION_VECTOR,
+    };
+
+    private Session mCurrentSession = null;
+    // Err on the side of caution, so logging is not started after a crash even tough the screen
+    // is off.
+    private boolean mScreenOn = false;
+    private boolean mHidden = false;
+
+    private final SensorManager mSensorManager;
+    private final SessionTypeAdapter mSessionTypeAdapter;
+    private final File mAnalyticsFile;
+
+    public KeyguardAnalytics(Context context, SessionTypeAdapter sessionTypeAdapter,
+            File analyticsFile) {
+        mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+        mSessionTypeAdapter = sessionTypeAdapter;
+        mAnalyticsFile = analyticsFile;
+    }
+
+    public Callback getCallback() {
+        return mCallback;
+    }
+
+    public interface Callback {
+        public void onShow();
+        public void onHide();
+        public void onScreenOn();
+        public void onScreenOff();
+        public boolean onTouchEvent(MotionEvent ev, int width, int height);
+        public void onSetHidden(boolean hidden);
+    }
+
+    public interface SessionTypeAdapter {
+        public int getSessionType();
+    }
+
+    private void sessionEntrypoint() {
+        if (mCurrentSession == null && mScreenOn && !mHidden) {
+            onSessionStart();
+        }
+    }
+
+    private void sessionExitpoint(int result) {
+        if (mCurrentSession != null) {
+            onSessionEnd(result);
+        }
+    }
+
+    private void onSessionStart() {
+        int type = mSessionTypeAdapter.getSessionType();
+        mCurrentSession = new Session(System.currentTimeMillis(), System.nanoTime(), type);
+        if (type == Session.TYPE_KEYGUARD_SECURE) {
+            mCurrentSession.setRedactTouchEvents();
+        }
+        for (int sensorType : SENSORS) {
+            Sensor s = mSensorManager.getDefaultSensor(sensorType);
+            if (s != null) {
+                mSensorManager.registerListener(this, s, SensorManager.SENSOR_DELAY_GAME);
+            }
+        }
+        if (DEBUG) {
+            Log.d(TAG, "onSessionStart()");
+        }
+    }
+
+    private void onSessionEnd(int result) {
+        if (DEBUG) {
+            Log.d(TAG, String.format("onSessionEnd(success=%d)", result));
+        }
+        mSensorManager.unregisterListener(this);
+
+        Session session = mCurrentSession;
+        mCurrentSession = null;
+
+        session.end(System.currentTimeMillis(), result);
+        queueSession(session);
+    }
+
+    private void queueSession(final Session currentSession) {
+        if (DEBUG) {
+            Log.i(TAG, "Saving session.");
+        }
+        new AsyncTask<Void, Void, Void>() {
+            @Override
+            protected Void doInBackground(Void... params) {
+                try {
+                    byte[] b = writeDelimitedProto(currentSession.toProto());
+                    OutputStream os = new FileOutputStream(mAnalyticsFile, true /* append */);
+                    if (DEBUG) {
+                        Log.d(TAG, String.format("Serialized size: %d kB.", b.length / 1024));
+                    }
+                    try {
+                        os.write(b);
+                        os.flush();
+                    } finally {
+                        try {
+                            os.close();
+                        } catch (IOException e) {
+                            Log.e(TAG, "Exception while closing file", e);
+                        }
+                    }
+                } catch (IOException e) {
+                    Log.e(TAG, "Exception while writing file", e);
+                }
+                return null;
+            }
+
+            private byte[] writeDelimitedProto(MessageNano proto)
+                    throws IOException {
+                byte[] result = new byte[CodedOutputByteBufferNano.computeMessageSizeNoTag(proto)];
+                CodedOutputByteBufferNano ob = CodedOutputByteBufferNano.newInstance(result);
+                ob.writeMessageNoTag(proto);
+                ob.checkNoSpaceLeft();
+                return result;
+            }
+        }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
+    }
+
+    @Override
+    public synchronized void onSensorChanged(SensorEvent event) {
+        if (false) {
+            Log.v(TAG, String.format(
+                    "onSensorChanged(name=%s, values[0]=%f)",
+                    event.sensor.getName(), event.values[0]));
+        }
+        if (mCurrentSession != null) {
+            mCurrentSession.addSensorEvent(event, System.nanoTime());
+            enforceTimeout();
+        }
+    }
+
+    private void enforceTimeout() {
+        if (System.currentTimeMillis() - mCurrentSession.getStartTimestampMillis()
+                > TIMEOUT_MILLIS) {
+            onSessionEnd(Session.RESULT_UNKNOWN);
+            if (DEBUG) {
+                Log.i(TAG, "Analytics timed out.");
+            }
+        }
+    }
+
+    @Override
+    public void onAccuracyChanged(Sensor sensor, int accuracy) {
+    }
+
+    private final Callback mCallback = new Callback() {
+        @Override
+        public void onShow() {
+            if (DEBUG) {
+                Log.d(TAG, "onShow()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                sessionEntrypoint();
+            }
+        }
+
+        @Override
+        public void onHide() {
+            if (DEBUG) {
+                Log.d(TAG, "onHide()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                sessionExitpoint(Session.RESULT_SUCCESS);
+            }
+        }
+
+        @Override
+        public void onScreenOn() {
+            if (DEBUG) {
+                Log.d(TAG, "onScreenOn()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                mScreenOn = true;
+                sessionEntrypoint();
+            }
+        }
+
+        @Override
+        public void onScreenOff() {
+            if (DEBUG) {
+                Log.d(TAG, "onScreenOff()");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                mScreenOn = false;
+                sessionExitpoint(Session.RESULT_FAILURE);
+            }
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev, int width, int height) {
+            if (DEBUG) {
+                Log.v(TAG, "onTouchEvent(ev.action="
+                        + MotionEvent.actionToString(ev.getAction()) + ")");
+            }
+            synchronized (KeyguardAnalytics.this) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.addMotionEvent(ev);
+                    mCurrentSession.setTouchArea(width, height);
+                    enforceTimeout();
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public void onSetHidden(boolean hidden) {
+            synchronized (KeyguardAnalytics.this) {
+                if (hidden != mHidden) {
+                    if (DEBUG) {
+                        Log.d(TAG, "onSetHidden(" + hidden + ")");
+                    }
+                    mHidden = hidden;
+                    if (hidden) {
+                        // Could have gone to camera on purpose / by falsing or an app could have
+                        // launched on top of the lockscreen.
+                        sessionExitpoint(Session.RESULT_UNKNOWN);
+                    } else {
+                        sessionEntrypoint();
+                    }
+                }
+            }
+        }
+    };
+
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java b/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java
new file mode 100644
index 0000000..e68f751
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/PointerTracker.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard.analytics;
+
+import android.graphics.RectF;
+import android.util.FloatMath;
+import android.util.SparseArray;
+import android.view.MotionEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.TouchEvent.BoundingBox;
+
+/**
+ * Takes motion events and tracks the length and bounding box of each pointer gesture as well as
+ * the bounding box of the whole gesture.
+ */
+public class PointerTracker {
+    private SparseArray<Pointer> mPointerInfoMap = new SparseArray<Pointer>();
+    private RectF mTotalBoundingBox = new RectF();
+
+    public void addMotionEvent(MotionEvent ev) {
+        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            float x = ev.getX();
+            float y = ev.getY();
+            mTotalBoundingBox.set(x, y, x, y);
+        }
+        for (int i = 0; i < ev.getPointerCount(); i++) {
+            int id = ev.getPointerId(i);
+            Pointer pointer = getPointer(id);
+            float x = ev.getX(i);
+            float y = ev.getY(i);
+            boolean down = ev.getActionMasked() == MotionEvent.ACTION_DOWN
+                    || (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN
+                            && ev.getActionIndex() == i);
+            pointer.addPoint(x, y, down);
+            mTotalBoundingBox.union(x, y);
+        }
+    }
+
+    public float getPointerLength(int id) {
+        return getPointer(id).length;
+    }
+
+    public BoundingBox getBoundingBox() {
+        return boundingBoxFromRect(mTotalBoundingBox);
+    }
+
+    public BoundingBox getPointerBoundingBox(int id) {
+        return boundingBoxFromRect(getPointer(id).boundingBox);
+    }
+
+    private BoundingBox boundingBoxFromRect(RectF f) {
+        BoundingBox bb = new BoundingBox();
+        bb.setHeight(f.height());
+        bb.setWidth(f.width());
+        return bb;
+    }
+
+    private Pointer getPointer(int id) {
+        Pointer p = mPointerInfoMap.get(id);
+        if (p == null) {
+            p = new Pointer();
+            mPointerInfoMap.put(id, p);
+        }
+        return p;
+    }
+
+    private static class Pointer {
+        public float length;
+        public final RectF boundingBox = new RectF();
+
+        private float mLastX;
+        private float mLastY;
+
+        public void addPoint(float x, float y, boolean down) {
+            float deltaX;
+            float deltaY;
+            if (down) {
+                boundingBox.set(x, y, x, y);
+                length = 0f;
+                deltaX = 0;
+                deltaY = 0;
+            } else {
+                deltaX = x - mLastX;
+                deltaY = y - mLastY;
+            }
+            mLastX = x;
+            mLastY = y;
+            length += FloatMath.sqrt(deltaX * deltaX + deltaY * deltaY);
+            boundingBox.union(x, y);
+        }
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/Session.java b/packages/Keyguard/src/com/android/keyguard/analytics/Session.java
new file mode 100644
index 0000000..05f9165
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/Session.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.keyguard.analytics;
+
+import android.os.Build;
+import android.util.Slog;
+import android.view.MotionEvent;
+
+import java.util.ArrayList;
+
+import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.SensorEvent;
+import static com.android.keyguard.analytics.KeyguardAnalyticsProtos.Session.TouchEvent;
+
+/**
+ * Records data about one keyguard session.
+ *
+ * The recorded data contains start and end of the session, whether it unlocked the device
+ * successfully, sensor data and touch data.
+ *
+ * If the keyguard is secure, the recorded touch data will correlate or contain the user pattern or
+ * PIN. If this is not desired, the touch coordinates can be redacted before serialization.
+ */
+public class Session {
+
+    private static final String TAG = "KeyguardAnalytics";
+    private static final boolean DEBUG = false;
+
+    /**
+     * The user has failed to unlock the device in this session.
+     */
+    public static final int RESULT_FAILURE = KeyguardAnalyticsProtos.Session.FAILURE;
+    /**
+     * The user has succeeded in unlocking the device in this session.
+     */
+    public static final int RESULT_SUCCESS = KeyguardAnalyticsProtos.Session.SUCCESS;
+
+    /**
+     * It is unknown how the session with the keyguard ended.
+     */
+    public static final int RESULT_UNKNOWN = KeyguardAnalyticsProtos.Session.UNKNOWN;
+
+    /**
+     * This session took place on an insecure keyguard.
+     */
+    public static final int TYPE_KEYGUARD_INSECURE
+            = KeyguardAnalyticsProtos.Session.KEYGUARD_INSECURE;
+
+    /**
+     * This session took place on an secure keyguard.
+     */
+    public static final int TYPE_KEYGUARD_SECURE
+            = KeyguardAnalyticsProtos.Session.KEYGUARD_SECURE;
+
+    /**
+     * This session took place during a fake wake up of the device.
+     */
+    public static final int TYPE_RANDOM_WAKEUP = KeyguardAnalyticsProtos.Session.RANDOM_WAKEUP;
+
+
+    private final PointerTracker mPointerTracker = new PointerTracker();
+
+    private final long mStartTimestampMillis;
+    private final long mStartSystemTimeNanos;
+    private final int mType;
+
+    private boolean mRedactTouchEvents;
+    private ArrayList<TouchEvent> mMotionEvents = new ArrayList<TouchEvent>(200);
+    private ArrayList<SensorEvent> mSensorEvents = new ArrayList<SensorEvent>(600);
+    private int mTouchAreaHeight;
+    private int mTouchAreaWidth;
+
+    private long mEndTimestampMillis;
+    private int mResult;
+    private boolean mEnded;
+
+    public Session(long startTimestampMillis, long startSystemTimeNanos, int type) {
+        mStartTimestampMillis = startTimestampMillis;
+        mStartSystemTimeNanos = startSystemTimeNanos;
+        mType = type;
+    }
+
+    public void end(long endTimestampMillis, int result) {
+        mEnded = true;
+        mEndTimestampMillis = endTimestampMillis;
+        mResult = result;
+    }
+
+    public void addMotionEvent(MotionEvent motionEvent) {
+        if (mEnded) {
+            return;
+        }
+        mPointerTracker.addMotionEvent(motionEvent);
+        mMotionEvents.add(protoFromMotionEvent(motionEvent));
+    }
+
+    public void addSensorEvent(android.hardware.SensorEvent eventOrig, long systemTimeNanos) {
+        if (mEnded) {
+            return;
+        }
+        SensorEvent event = protoFromSensorEvent(eventOrig, systemTimeNanos);
+        mSensorEvents.add(event);
+        if (DEBUG) {
+            Slog.v(TAG, String.format("addSensorEvent(name=%s, values[0]=%f",
+                    event.getType(), event.values[0]));
+        }
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("Session{");
+        sb.append("mType=").append(mType);
+        sb.append(", mStartTimestampMillis=").append(mStartTimestampMillis);
+        sb.append(", mStartSystemTimeNanos=").append(mStartSystemTimeNanos);
+        sb.append(", mEndTimestampMillis=").append(mEndTimestampMillis);
+        sb.append(", mResult=").append(mResult);
+        sb.append(", mRedactTouchEvents=").append(mRedactTouchEvents);
+        sb.append(", mTouchAreaHeight=").append(mTouchAreaHeight);
+        sb.append(", mTouchAreaWidth=").append(mTouchAreaWidth);
+        sb.append(", mMotionEvents=[size=").append(mMotionEvents.size()).append("]");
+        sb.append(", mSensorEvents=[size=").append(mSensorEvents.size()).append("]");
+        sb.append('}');
+        return sb.toString();
+    }
+
+    public KeyguardAnalyticsProtos.Session toProto() {
+        KeyguardAnalyticsProtos.Session proto = new KeyguardAnalyticsProtos.Session();
+        proto.setStartTimestampMillis(mStartTimestampMillis);
+        proto.setDurationMillis(mEndTimestampMillis - mStartTimestampMillis);
+        proto.setBuild(Build.FINGERPRINT);
+        proto.setResult(mResult);
+        proto.sensorEvents = mSensorEvents.toArray(proto.sensorEvents);
+        proto.touchEvents = mMotionEvents.toArray(proto.touchEvents);
+        proto.setTouchAreaWidth(mTouchAreaWidth);
+        proto.setTouchAreaHeight(mTouchAreaHeight);
+        proto.setType(mType);
+        if (mRedactTouchEvents) {
+            redactTouchEvents(proto.touchEvents);
+        }
+        return proto;
+    }
+
+    private void redactTouchEvents(TouchEvent[] touchEvents) {
+        for (int i = 0; i < touchEvents.length; i++) {
+            TouchEvent t = touchEvents[i];
+            for (int j = 0; j < t.pointers.length; j++) {
+                TouchEvent.Pointer p = t.pointers[j];
+                p.clearX();
+                p.clearY();
+            }
+            t.setRedacted(true);
+        }
+    }
+
+    private SensorEvent protoFromSensorEvent(android.hardware.SensorEvent ev, long sysTimeNanos) {
+        SensorEvent proto = new SensorEvent();
+        proto.setType(ev.sensor.getType());
+        proto.setTimeOffsetNanos(sysTimeNanos - mStartSystemTimeNanos);
+        proto.setTimestamp(ev.timestamp);
+        proto.values = ev.values.clone();
+        return proto;
+    }
+
+    private TouchEvent protoFromMotionEvent(MotionEvent ev) {
+        int count = ev.getPointerCount();
+        TouchEvent proto = new TouchEvent();
+        proto.setTimeOffsetNanos(ev.getEventTimeNano() - mStartSystemTimeNanos);
+        proto.setAction(ev.getActionMasked());
+        proto.setActionIndex(ev.getActionIndex());
+        proto.pointers = new TouchEvent.Pointer[count];
+        for (int i = 0; i < count; i++) {
+            TouchEvent.Pointer p = new TouchEvent.Pointer();
+            p.setX(ev.getX(i));
+            p.setY(ev.getY(i));
+            p.setSize(ev.getSize(i));
+            p.setPressure(ev.getPressure(i));
+            p.setId(ev.getPointerId(i));
+            proto.pointers[i] = p;
+            if ((ev.getActionMasked() == MotionEvent.ACTION_POINTER_UP && ev.getActionIndex() == i)
+                    || ev.getActionMasked() == MotionEvent.ACTION_UP) {
+                p.boundingBox = mPointerTracker.getPointerBoundingBox(p.getId());
+                p.setLength(mPointerTracker.getPointerLength(p.getId()));
+            }
+        }
+        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
+            proto.boundingBox = mPointerTracker.getBoundingBox();
+        }
+        return proto;
+    }
+
+    /**
+     * Discards the x / y coordinates of the touch events on serialization. Retained are the
+     * size of the individual and overall bounding boxes and the length of each pointer's gesture.
+     */
+    public void setRedactTouchEvents() {
+        mRedactTouchEvents = true;
+    }
+
+    public void setTouchArea(int width, int height) {
+        mTouchAreaWidth = width;
+        mTouchAreaHeight = height;
+    }
+
+    public long getStartTimestampMillis() {
+        return mStartTimestampMillis;
+    }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto b/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto
new file mode 100644
index 0000000..68b1590
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/analytics/keyguard_analytics.proto
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+syntax = "proto2";
+
+package keyguard;
+
+option java_package = "com.android.keyguard.analytics";
+option java_outer_classname = "KeyguardAnalyticsProtos";
+
+message Session {
+    message TouchEvent {
+        message BoundingBox {
+            optional float width = 1;
+            optional float height = 2;
+        }
+
+        enum Action {
+            // Keep in sync with MotionEvent.
+            DOWN = 0;
+            UP = 1;
+            MOVE = 2;
+            CANCEL = 3;
+            OUTSIDE = 4;
+            POINTER_DOWN = 5;
+            POINTER_UP = 6;
+        }
+
+        message Pointer {
+            optional float x = 1;
+            optional float y = 2;
+            optional float size = 3;
+            optional float pressure = 4;
+            optional int32 id = 5;
+            optional float length = 6;
+            // Bounding box of the pointer. Only set on UP or POINTER_UP event of this pointer.
+            optional BoundingBox boundingBox = 7;
+        }
+
+        optional uint64 timeOffsetNanos = 1;
+        optional Action action = 2;
+        optional int32 actionIndex = 3;
+        repeated Pointer pointers = 4;
+        /* If true, the the x / y coordinates of the touch events were redacted. Retained are the
+           size of the individual and overall bounding boxes and the length of each pointer's
+           gesture. */
+        optional bool redacted = 5;
+        // Bounding box of the whole gesture. Only set on UP event.
+        optional BoundingBox boundingBox = 6;
+    }
+
+    message SensorEvent {
+        enum Type {
+            ACCELEROMETER = 1;
+            GYROSCOPE = 4;
+            LIGHT = 5;
+            PROXIMITY = 8;
+            ROTATION_VECTOR = 11;
+        }
+
+        optional Type type = 1;
+        optional uint64 timeOffsetNanos = 2;
+        repeated float values = 3;
+        optional uint64 timestamp = 4;
+    }
+
+    enum Result {
+        FAILURE = 0;
+        SUCCESS = 1;
+        UNKNOWN = 2;
+    }
+
+    enum Type {
+        KEYGUARD_INSECURE = 0;
+        KEYGUARD_SECURE = 1;
+        RANDOM_WAKEUP = 2;
+    }
+
+    optional uint64 startTimestampMillis = 1;
+    optional uint64 durationMillis = 2;
+    optional string build = 3;
+    optional Result result = 4;
+    repeated TouchEvent touchEvents = 5;
+    repeated SensorEvent sensorEvents = 6;
+
+    optional int32 touchAreaWidth = 9;
+    optional int32 touchAreaHeight = 10;
+    optional Type type = 11;
+}
diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml
new file mode 100644
index 0000000..a10a5a0
--- /dev/null
+++ b/packages/PrintSpooler/res/values-af/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Drukwaglys"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Drukkerinstellings"</string>
+    <string name="print_button" msgid="645164566271246268">"Druk"</string>
+    <string name="save_button" msgid="1921310454071758999">"Stoor"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Bestemming"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Afskrifte"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Papiergrootte"</string>
+    <string name="label_color" msgid="1108690305218188969">"Kleur"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Oriëntasie"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Bladsye (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"bv. 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Drukvoorskou"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Installeer PDF-bekyker vir voorskou"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Drukkerprogram het omgeval"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Bladsye"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Genereer uitdruktaak"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Stoor as PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Alle drukkers…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Drukdialoog"</string>
+    <string name="search" msgid="5421724265322228497">"Deursoek"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Alle drukkers"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Voeg diens by"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Soekkassie vertoon"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Soekkassie weggesteek"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Voeg drukker by"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Kies drukker"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Vergeet drukker"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> drukker gekry"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> drukkers gekry"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Kies drukdiens"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Soek tans vir drukkers"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Geen drukkers gekry nie"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Druk tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kanselleer tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Drukkerfout by <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Drukker het <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> geblokkeer"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-uitdruktaak"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-uitdruktake"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Kanselleer"</string>
+    <string name="restart" msgid="2472034227037808749">"Herbegin"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met drukker nie"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie beskikbaar nie"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Kon nie uitdruktaak genereer nie"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Swart en wit"</item>
+    <item msgid="2762241247228983754">"Kleur"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portret"</item>
+    <item msgid="3199660090246166812">"Landskap"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Alles"</item>
+    <item msgid="6812869625222503603">"Reikwydte"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
new file mode 100644
index 0000000..d86acb86cb
--- /dev/null
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"የህትመት አስተላላፊ"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"የአታሚ ቅንብሮች"</string>
+    <string name="print_button" msgid="645164566271246268">"አትም"</string>
+    <string name="save_button" msgid="1921310454071758999">"አስቀምጥ"</string>
+    <string name="label_destination" msgid="9132510997381599275">"መድረሻ"</string>
+    <string name="label_copies" msgid="3634531042822968308">"ቅጂዎች"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"የወረቀት መጠን"</string>
+    <string name="label_color" msgid="1108690305218188969">"ቀለም"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"አቀማመጠ ገፅ"</string>
+    <string name="label_pages" msgid="6300874667546617333">"ገጾች (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ለምሳሌ፦ 1–5,8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"የህትመት ቅድመ እይታ"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"ለቅድመ-እይታ የፒ ዲ ኤፍ መመልከቻ ይጫኑ"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"የአታሚ መተግበሪያ ተበላሽቷል"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"ገፆች"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"የህትመት ስራን በማመንጨት ላይ"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"እንደ ፒ ዲ ኤፍ አስቀምጥ"</string>
+    <string name="all_printers" msgid="5018829726861876202">"ሁሉም አታሚዎች…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"የህትመት መገናኛ"</string>
+    <string name="search" msgid="5421724265322228497">"ፍለጋ"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"ሁሉም አታሚዎች"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"አገልግሎት አክል"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"የፍለጋ ሳጥን ይታያል"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"የፍለጋ ሳጥን ተደብቋል"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"አታሚ አክል"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"አታሚ ምረጥ"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"አታሚ እርሳ"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> አታሚ ተገኝቷል"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> አታሚዎች ተገኝተዋል"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"የህትመት አገልግሎት ይምረጡ"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"አታሚዎችን በመፈለግ ላይ"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"ምንም አታሚዎች አልተገኙም"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በማተም ላይ"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በመተው ላይ"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"የአታሚ ስህተት <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"አታሚ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን አግዷል"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> የህትመት ስራ"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> የህትመት ስራዎች"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"ይቅር"</string>
+    <string name="restart" msgid="2472034227037808749">"እንደገና ጀምር"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"ከአታሚ ጋር ምንም ግንኙነት የለም"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"አይታወቅም"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – አይገኝም"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"የህትመት ስራን ማመንጨት አልተቻለም"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"ጥቁር እና ነጭ"</item>
+    <item msgid="2762241247228983754">"ቀለም"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"የቁም"</item>
+    <item msgid="3199660090246166812">"የወርድ"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"ሁሉም"</item>
+    <item msgid="6812869625222503603">"ምጥጥነ ገጽታ"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml
new file mode 100644
index 0000000..b883f93
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ar/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"إعدادات الطابعة"</string>
+    <string name="print_button" msgid="645164566271246268">"طباعة"</string>
+    <string name="save_button" msgid="1921310454071758999">"حفظ"</string>
+    <string name="label_destination" msgid="9132510997381599275">"الوجهة"</string>
+    <string name="label_copies" msgid="3634531042822968308">"عدد النسخ"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"حجم الورق"</string>
+    <string name="label_color" msgid="1108690305218188969">"ألوان"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"الاتجاه"</string>
+    <string name="label_pages" msgid="6300874667546617333">"الصفحات (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"على سبيل المثال، 1—5،8،11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"معاينة قبل الطباعة"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"‏تثبيت برنامج عرض PDF للمعاينة"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"تعطّل تطبيق الطباعة"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"الصفحات"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"جارٍ إنشاء مهمة الطباعة"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"‏حفظ بتنسيق PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"جميع الطابعات…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"مربع حوار الطباعة"</string>
+    <string name="search" msgid="5421724265322228497">"بحث"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"جميع الطابعات"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"إضافة خدمة"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"تم إظهار مربع البحث"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"تم إخفاء مربع البحث"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"إضافة طابعة"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"حدد الطابعة"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"تجاهل الطابعة"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"تم العثور على <xliff:g id="COUNT">%1$s</xliff:g> طابعة"</item>
+    <item quantity="other" msgid="6533817036607128241">"تم العثور على <xliff:g id="COUNT">%1$s</xliff:g> من الطابعات"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"اختر خدمة طباعة"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"البحث عن طابعات"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"لم يتم العثور على طابعات"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"جارٍ طباعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"جارٍ إلغاء <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"خطا في الطابعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"رفضت الطابعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> مهمة طباعة"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> من مهام الطباعة"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"إلغاء"</string>
+    <string name="restart" msgid="2472034227037808749">"إعادة تشغيل"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"لا يوجد اتصال بالطابعة"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"غير معروف"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – غير متاحة"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"تعذر إنشاء عملية الطباعة"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"أبيض وأسود"</item>
+    <item msgid="2762241247228983754">"ملونة"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"عمودي"</item>
+    <item msgid="3199660090246166812">"أفقي"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"الكل"</item>
+    <item msgid="6812869625222503603">"النطاق"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-be/arrays.xml b/packages/PrintSpooler/res/values-be/arrays.xml
deleted file mode 100644
index d40278c..0000000
--- a/packages/PrintSpooler/res/values-be/arrays.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>NA_LETTER</item>
-        <item>NA_GOVT_LETTER</item>
-        <item>NA_LEGAL</item>
-        <item>NA_JUNIOR_LEGAL</item>
-        <item>NA_LEDGER</item>
-        <item>NA_TABLOID</item>
-        <item>NA_INDEX_3X5</item>
-        <item>NA_INDEX_4X6</item>
-        <item>NA_INDEX_5X8</item>
-        <item>NA_MONARCH</item>
-        <item>NA_QUARTO</item>
-        <item>NA_FOOLSCAP</item>
-    </string-array>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-be/donottranslate.xml b/packages/PrintSpooler/res/values-be/donottranslate.xml
deleted file mode 100644
index 7537aa5..0000000
--- a/packages/PrintSpooler/res/values-be/donottranslate.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<resources>
-
-    <string name="mediasize_default">NA_LETTER</string>
-    <string name="mediasize_standard">@string/mediasize_standard_north_america</string>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml
new file mode 100644
index 0000000..4009aa2
--- /dev/null
+++ b/packages/PrintSpooler/res/values-bg/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Спулер за печат"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Настройки на принтера"</string>
+    <string name="print_button" msgid="645164566271246268">"Печат"</string>
+    <string name="save_button" msgid="1921310454071758999">"Запазване"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Местоназначение"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Копия"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Размер на хартията"</string>
+    <string name="label_color" msgid="1108690305218188969">"Цвят"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Ориентация"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Страници (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"напр. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Визуализация за печат"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Инсталиране на визуализатор на PDF"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Получи се срив в приложението за отпечатване"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Страници"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Заданието за печат се генерира"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Запазване като PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Всички принтери…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Диалогов прозорец за отпечатване"</string>
+    <string name="search" msgid="5421724265322228497">"Търсене"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Всички принтери"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Добавяне на услуга"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Полето за търсене е показано"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Полето за търсене е скрито"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Добавяне на принтер"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Избиране на принтер"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Забравяне на принтера"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Намерен е <xliff:g id="COUNT">%1$s</xliff:g> принтер"</item>
+    <item quantity="other" msgid="6533817036607128241">"Намерени са <xliff:g id="COUNT">%1$s</xliff:g> принтера"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Избиране на услуга за отпечатване"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Търсят се принтери"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Няма намерени принтери"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се отпечатва"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се анулира"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка в принтера при „<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Принтерът блокира при „<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Задание за отпечатване: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Задания за отпечатване: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Отказ"</string>
+    <string name="restart" msgid="2472034227037808749">"Рестартиране"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Няма връзка с принтера"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"няма данни"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – не е налице"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Заданието за отпечатване не можа да се генерира"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Черно-бяло"</item>
+    <item msgid="2762241247228983754">"Цветно"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Вертикално"</item>
+    <item msgid="3199660090246166812">"Хоризонтално"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Всички"</item>
+    <item msgid="6812869625222503603">"Поредица"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ca/arrays.xml b/packages/PrintSpooler/res/values-ca/arrays.xml
deleted file mode 100644
index d40278c..0000000
--- a/packages/PrintSpooler/res/values-ca/arrays.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>NA_LETTER</item>
-        <item>NA_GOVT_LETTER</item>
-        <item>NA_LEGAL</item>
-        <item>NA_JUNIOR_LEGAL</item>
-        <item>NA_LEDGER</item>
-        <item>NA_TABLOID</item>
-        <item>NA_INDEX_3X5</item>
-        <item>NA_INDEX_4X6</item>
-        <item>NA_INDEX_5X8</item>
-        <item>NA_MONARCH</item>
-        <item>NA_QUARTO</item>
-        <item>NA_FOOLSCAP</item>
-    </string-array>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml
new file mode 100644
index 0000000..a429dd5
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ca/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Gest. cues impr."</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Configuració impressora"</string>
+    <string name="print_button" msgid="645164566271246268">"Imprimeix"</string>
+    <string name="save_button" msgid="1921310454071758999">"Desa"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destinació"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Còpies"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Mida del paper"</string>
+    <string name="label_color" msgid="1108690305218188969">"Color"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientació"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pàgines (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Visualització prèvia impressió"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instal·la un lector de PDF per a visualitz. prèvia"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"L\'aplicació d\'impressió ha fallat"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pàgines"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generant tasca impressió"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Desa com a PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Totes les impressores…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Diàleg d\'impressió"</string>
+    <string name="search" msgid="5421724265322228497">"Cerca"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Totes les impressores"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Afegeix un servei"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Es mostra el quadre de cerca"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"S\'ha amagat el quadre de cerca"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Afegeix una impressora"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Selecciona una impressora"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Oblida la impressora"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"S\'ha trobat <xliff:g id="COUNT">%1$s</xliff:g> impressora"</item>
+    <item quantity="other" msgid="6533817036607128241">"S\'han trobat <xliff:g id="COUNT">%1$s</xliff:g> impressores"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Selecció del servei d\'impressió"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Cerca d\'impressores"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"No s\'ha trobat cap impressora"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"S\'està imprimint <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"S\'està cancel·lant <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Error d\'impressora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Impressora bloquejada <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Tasca d\'impressió per a <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Tasques d\'impressió per a <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancel·la"</string>
+    <string name="restart" msgid="2472034227037808749">"Reinicia"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"No hi ha connexió amb la impressora"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"desconegut"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"No s\'ha pogut generar la tasca d\'impressió"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Blanc i negre"</item>
+    <item msgid="2762241247228983754">"Color"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Vertical"</item>
+    <item msgid="3199660090246166812">"Horitzontal"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Tots"</item>
+    <item msgid="6812869625222503603">"Interval"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml
new file mode 100644
index 0000000..3ddc701
--- /dev/null
+++ b/packages/PrintSpooler/res/values-cs/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Nastavení tiskárny"</string>
+    <string name="print_button" msgid="645164566271246268">"Tisk"</string>
+    <string name="save_button" msgid="1921310454071758999">"Uložit"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Cíl"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopie"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Velikost papíru"</string>
+    <string name="label_color" msgid="1108690305218188969">"Barva"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientace"</string>
+    <string name="label_pages" msgid="6300874667546617333">"STRÁNKY (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"např. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Náhled tisku"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Nainstalovat prohlížeč PDF (umožní náhled)"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Aplikace tisku selhala"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Stránky"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generování úlohy tisku"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Uložit ve formátu PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Všechny tiskárny…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Dialog tisku"</string>
+    <string name="search" msgid="5421724265322228497">"Hledat"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Všechny tiskárny"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Přidat službu"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Vyhledávací pole se zobrazuje"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Vyhledávací pole je skryto"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Přidat tiskárnu"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Vybrat tiskárnu"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Odstranit tiskárnu"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Počet nalezených tiskáren: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+    <item quantity="other" msgid="6533817036607128241">"Počet nalezených tiskáren: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Zvolte službu tisku"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Vyhledávání tiskáren"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nebyly nalezeny žádné tiskárny"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Tisk úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Rušení úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Chyba tiskárny u úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Tiskárna blokuje úlohu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Počet tiskových úloh: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Počet tiskových úloh: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Zrušit"</string>
+    <string name="restart" msgid="2472034227037808749">"Restartovat"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nelze se připojit k tiskárně"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"neznámé"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – není k dispozici"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Tiskovou úlohu nelze vytvořit"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Černobíle"</item>
+    <item msgid="2762241247228983754">"Barevně"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Na výšku"</item>
+    <item msgid="3199660090246166812">"Na šířku"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Vše"</item>
+    <item msgid="6812869625222503603">"Rozsah"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml
new file mode 100644
index 0000000..74190b4
--- /dev/null
+++ b/packages/PrintSpooler/res/values-da/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Printerindstillinger"</string>
+    <string name="print_button" msgid="645164566271246268">"Udskriv"</string>
+    <string name="save_button" msgid="1921310454071758999">"Gem"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopier"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Papirstørrelse"</string>
+    <string name="label_color" msgid="1108690305218188969">"Farve"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Retning"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Sider (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"f.eks. 1-5,8,11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Vis udskrift"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Installer et PDF-visningsprog. for at se eksempel"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Udskrivningsapp gik ned"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Sider"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Udskriften generes"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Gem som PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Alle printere..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Udskriftsdialog"</string>
+    <string name="search" msgid="5421724265322228497">"Søg"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Alle printere"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Tilføj tjeneste"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Søgefeltet vises"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Søgefeltet er skjult"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Tilføj printer"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Vælg printer"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Glem printer"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Der blev fundet <xliff:g id="COUNT">%1$s</xliff:g> printer"</item>
+    <item quantity="other" msgid="6533817036607128241">"Der blev fundet <xliff:g id="COUNT">%1$s</xliff:g> printere"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Vælg udskriftstjeneste"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Søger efter printere"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Der blev ikke fundet nogen printere"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> udskrives"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annulleres"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Udskriften <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> mislykkedes"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printeren har blokeret <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-udskriftsjob"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>-udskriftsjobs"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Annuller"</string>
+    <string name="restart" msgid="2472034227037808749">"Genstart"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse til printer"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"ukendt"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ikke tilgængelig"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Der kunne ikke genereres et udskriftsjob"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Sort/hvid"</item>
+    <item msgid="2762241247228983754">"Farve"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portræt"</item>
+    <item msgid="3199660090246166812">"Landskab"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Alle"</item>
+    <item msgid="6812869625222503603">"Interval"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml
new file mode 100644
index 0000000..6b83ac3
--- /dev/null
+++ b/packages/PrintSpooler/res/values-de/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Druck-Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Druckereinstellungen"</string>
+    <string name="print_button" msgid="645164566271246268">"Drucken"</string>
+    <string name="save_button" msgid="1921310454071758999">"Speichern"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Ziel"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Exemplare"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Papiergröße"</string>
+    <string name="label_color" msgid="1108690305218188969">"Farbe"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Ausrichtung"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Seiten (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"z. B. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Vorschau drucken"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"PDF-Viewer für Vorschau installieren"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Druck-App abgestürzt"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Seiten"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Druckauftrag wird generiert..."</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Als PDF speichern"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Alle Drucker…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Druckdialogfeld"</string>
+    <string name="search" msgid="5421724265322228497">"Suchen"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Alle Drucker"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Dienst hinzufügen"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Suchfeld angezeigt"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Suchfeld ausgeblendet"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Drucker hinzufügen"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Drucker auswählen"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Drucker wieder vergessen"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> Drucker gefunden"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> Drucker gefunden"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Druckdienst auswählen"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Suche nach Druckern"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Keine Drucker gefunden"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird gedruckt..."</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird abgebrochen..."</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Druckerfehler <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Drucker hat <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> blockiert."</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Druckauftrag \"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>\""</item>
+    <item quantity="other" msgid="8746611264734222865">"Druckaufträge \"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>\""</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Abbrechen"</string>
+    <string name="restart" msgid="2472034227037808749">"Neu starten"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Keine Verbindung zum Drucker"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"unbekannt"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nicht verfügbar"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Druckauftrag konnte nicht generiert werden."</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Schwarz-weiß"</item>
+    <item msgid="2762241247228983754">"Farbe"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Hochformat"</item>
+    <item msgid="3199660090246166812">"Querformat"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Alle"</item>
+    <item msgid="6812869625222503603">"Bereich"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml
new file mode 100644
index 0000000..795e730
--- /dev/null
+++ b/packages/PrintSpooler/res/values-el/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Λογισμικό ουράς εκτύπωσης"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Ρυθμίσεις εκτυπωτή"</string>
+    <string name="print_button" msgid="645164566271246268">"Εκτύπωση"</string>
+    <string name="save_button" msgid="1921310454071758999">"Αποθήκευση"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Προορισμός"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Αντίγραφα"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Μέγεθος χαρτιού"</string>
+    <string name="label_color" msgid="1108690305218188969">"Χρώμα"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Προσανατολισμός"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Σελίδες (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"π.χ. 1-5,8,11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Προεπισκόπηση εκτύπωσης"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Εγκαταστήστε το PDF viewer για προεπισκόπηση"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Διακοπή λειτουργίας εφαρμογής εκτύπωσης"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Σελίδες"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Δημιουργία εργασίας εκτύπωσης"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Αποθήκευση ως PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Όλοι οι εκτυπωτές…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Πλαίσιο διαλόγου εκτύπωσης"</string>
+    <string name="search" msgid="5421724265322228497">"Αναζήτηση"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Όλοι οι εκτυπωτές"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Προσθήκη υπηρεσίας"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Εμφάνιση πλαισίου αναζήτησης"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Απόκρυψη πλαισίου αναζήτησης"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Προσθήκη εκτυπωτή"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Επιλογή εκτυπωτή"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Διαγραφή εκτυπωτή"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Βρέθηκε <xliff:g id="COUNT">%1$s</xliff:g> εκτυπωτής"</item>
+    <item quantity="other" msgid="6533817036607128241">"Βρέθηκαν <xliff:g id="COUNT">%1$s</xliff:g> εκτυπωτές"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Επιλέξτε υπηρεσία εκτύπωσης"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Αναζήτηση για εκτυπωτές"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Δεν βρέθηκαν εκτυπωτές"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Εκτύπωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ακύρωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Σφάλμα εκτυπωτή <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Ο εκτυπωτής απέκλεισε <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"εργασία εκτύπωσης <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"εργασίες εκτύπωσης <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Ακύρωση"</string>
+    <string name="restart" msgid="2472034227037808749">"Επανεκκίνηση"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Δεν υπάρχει σύνδεση με εκτυπωτή"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"άγνωστο"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – μη διαθέσιμο"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Δεν ήταν δυνατή η δημιουργία εργασίας εκτύπωσης"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Ασπρόμαυρο"</item>
+    <item msgid="2762241247228983754">"Χρώμα"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Πορτραίτο"</item>
+    <item msgid="3199660090246166812">"Οριζόντια"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Όλα"</item>
+    <item msgid="6812869625222503603">"Εύρος"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..27372f8
--- /dev/null
+++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Printer settings"</string>
+    <string name="print_button" msgid="645164566271246268">"Print"</string>
+    <string name="save_button" msgid="1921310454071758999">"Save"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copies"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Paper Size"</string>
+    <string name="label_color" msgid="1108690305218188969">"Colour"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pages (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"e.g. 1–5,8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Print preview"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Install PDF viewer for preview"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Printing app crashed"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pages"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generating print job"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Save as PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"All printers…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Print dialogue"</string>
+    <string name="search" msgid="5421724265322228497">"Search"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"All printers"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Add service"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Search box shown"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Search box hidden"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Add printer"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Select printer"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Forget printer"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> printer found"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> printers found"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer blocked <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> print job"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> print jobs"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancel"</string>
+    <string name="restart" msgid="2472034227037808749">"Restart"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Couldn\'t generate print job"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Black &amp; White"</item>
+    <item msgid="2762241247228983754">"Colour"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portrait"</item>
+    <item msgid="3199660090246166812">"Landscape"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"All"</item>
+    <item msgid="6812869625222503603">"Range"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..27372f8
--- /dev/null
+++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Printer settings"</string>
+    <string name="print_button" msgid="645164566271246268">"Print"</string>
+    <string name="save_button" msgid="1921310454071758999">"Save"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copies"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Paper Size"</string>
+    <string name="label_color" msgid="1108690305218188969">"Colour"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pages (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"e.g. 1–5,8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Print preview"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Install PDF viewer for preview"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Printing app crashed"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pages"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generating print job"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Save as PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"All printers…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Print dialogue"</string>
+    <string name="search" msgid="5421724265322228497">"Search"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"All printers"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Add service"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Search box shown"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Search box hidden"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Add printer"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Select printer"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Forget printer"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> printer found"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> printers found"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer blocked <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> print job"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> print jobs"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancel"</string>
+    <string name="restart" msgid="2472034227037808749">"Restart"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"No connection to printer"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"unknown"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – unavailable"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Couldn\'t generate print job"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Black &amp; White"</item>
+    <item msgid="2762241247228983754">"Colour"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portrait"</item>
+    <item msgid="3199660090246166812">"Landscape"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"All"</item>
+    <item msgid="6812869625222503603">"Range"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-es-rUS/arrays.xml b/packages/PrintSpooler/res/values-es-rUS/arrays.xml
deleted file mode 100644
index d40278c..0000000
--- a/packages/PrintSpooler/res/values-es-rUS/arrays.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>NA_LETTER</item>
-        <item>NA_GOVT_LETTER</item>
-        <item>NA_LEGAL</item>
-        <item>NA_JUNIOR_LEGAL</item>
-        <item>NA_LEDGER</item>
-        <item>NA_TABLOID</item>
-        <item>NA_INDEX_3X5</item>
-        <item>NA_INDEX_4X6</item>
-        <item>NA_INDEX_5X8</item>
-        <item>NA_MONARCH</item>
-        <item>NA_QUARTO</item>
-        <item>NA_FOOLSCAP</item>
-    </string-array>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..c7d12af
--- /dev/null
+++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Cola de impresión"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Config. de impresora"</string>
+    <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
+    <string name="save_button" msgid="1921310454071758999">"Guardar"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destino"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copias"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Tamaño del papel"</string>
+    <string name="label_color" msgid="1108690305218188969">"Color"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientación"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Páginas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"Ej.: 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Vista previa de impresión"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar visualizador de PDF para vista previa"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"La aplicación de impresión falló"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Páginas"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generando trabajo de impresión"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Guardar como PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Todas las impresoras…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Cuadro de diálogo de impresión"</string>
+    <string name="search" msgid="5421724265322228497">"Buscar"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Todas las impresoras"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Agregar servicio"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Cuadro de búsqueda visible"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Cuadro de búsqueda oculto"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Agregar impresora"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Seleccionar impresora"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"No recordar impresora"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Se encontró <xliff:g id="COUNT">%1$s</xliff:g> impresora."</item>
+    <item quantity="other" msgid="6533817036607128241">"Se encontraron <xliff:g id="COUNT">%1$s</xliff:g> impresoras."</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Elegir servicio de impresión"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Buscando impresoras"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"No se encontraron impresoras"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Error de impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"La impresora bloqueó <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>."</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Trabajo de impresión <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Trabajos de impresión <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancelar"</string>
+    <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora."</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>: no disponible"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Error al generar el trabajo de impresión"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Blanco y negro"</item>
+    <item msgid="2762241247228983754">"Color"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Vertical"</item>
+    <item msgid="3199660090246166812">"Horizontal"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Todas"</item>
+    <item msgid="6812869625222503603">"Intervalo"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml
new file mode 100644
index 0000000..0225cad
--- /dev/null
+++ b/packages/PrintSpooler/res/values-es/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Cola de impresión"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Ajustes de impresora"</string>
+    <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
+    <string name="save_button" msgid="1921310454071758999">"Guardar"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destino"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copias"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Tamaño del papel"</string>
+    <string name="label_color" msgid="1108690305218188969">"Color"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientación"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Páginas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"p. ej.: 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Vista previa de impresión"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar visor PDF para obtener vista previa"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Error de aplicación de impresión"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Páginas"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generando trabajo de impresión"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Guardar como PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Todas las impresoras…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Cuadro de diálogo de impresión"</string>
+    <string name="search" msgid="5421724265322228497">"Buscar"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Todas las impresoras"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Añadir servicio"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Cuadro de búsqueda visible"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Cuadro de búsqueda oculto"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Añadir impresora"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Seleccionar impresora"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Borrar impresora"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Se ha encontrado <xliff:g id="COUNT">%1$s</xliff:g> impresora"</item>
+    <item quantity="other" msgid="6533817036607128241">"Se han encontrado <xliff:g id="COUNT">%1$s</xliff:g> impresoras"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Seleccionar servicio de impresión"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Buscando impresoras"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"No se encontraron impresoras"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Error de impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"La impresora ha bloqueado <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Trabajo de impresión <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Trabajos de impresión <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancelar"</string>
+    <string name="restart" msgid="2472034227037808749">"Volver a empezar"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"No hay conexión con la impresora"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"desconocido"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – no disponible"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Error al generar el trabajo de impresión"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Blanco y negro"</item>
+    <item msgid="2762241247228983754">"Color"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Vertical"</item>
+    <item msgid="3199660090246166812">"Horizontal"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Todo"</item>
+    <item msgid="6812869625222503603">"Intervalo"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml
new file mode 100644
index 0000000..2b3b352
--- /dev/null
+++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Prindispuuler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Printeri seaded"</string>
+    <string name="print_button" msgid="645164566271246268">"Prindi"</string>
+    <string name="save_button" msgid="1921310454071758999">"Salvesta"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Sihtkoht"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Koopiaid"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Paberiformaat"</string>
+    <string name="label_color" msgid="1108690305218188969">"Värv"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Suund"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Lehti (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"nt 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Prindi eelvaade"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"PDF-vaaturi installimine eelvaate kuvamiseks"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Printimisrakendus jooksis kokku"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Lehed"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Prinditöö loomine"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Salvesta PDF-ina"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Kõik printerid …"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Printimisdialoog"</string>
+    <string name="search" msgid="5421724265322228497">"Otsing"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Kõik printerid"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Lisa teenus"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Otsingukast on kuvatud"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Otsingukast on peidetud"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Lisa printer"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Printeri valimine"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Printeri unustamine"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Leiti <xliff:g id="COUNT">%1$s</xliff:g> printer"</item>
+    <item quantity="other" msgid="6533817036607128241">"Leiti <xliff:g id="COUNT">%1$s</xliff:g> printerit"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Prinditeenuse valimine"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Printerite otsimine"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Printereid ei leitud"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> printimine"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> tühistamine"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Printeri viga: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer blokeeris töö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Prinditööd <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Tühista"</string>
+    <string name="restart" msgid="2472034227037808749">"Taaskäivita"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Printeriühendus puudub"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"teadmata"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – pole saadaval"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Prinditööd ei saanud luua"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Mustvalge"</item>
+    <item msgid="2762241247228983754">"Värv"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Vertikaalpaigutus"</item>
+    <item msgid="3199660090246166812">"Horisontaalpaigutus"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Kõik"</item>
+    <item msgid="6812869625222503603">"Vahemik"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml
new file mode 100644
index 0000000..49bae323
--- /dev/null
+++ b/packages/PrintSpooler/res/values-fa/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"هماهنگ‌کننده چاپ"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"تنظیمات چاپگر"</string>
+    <string name="print_button" msgid="645164566271246268">"چاپ"</string>
+    <string name="save_button" msgid="1921310454071758999">"ذخیره"</string>
+    <string name="label_destination" msgid="9132510997381599275">"مقصد"</string>
+    <string name="label_copies" msgid="3634531042822968308">"کپی‌ها"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"اندازه کاغذ"</string>
+    <string name="label_color" msgid="1108690305218188969">"رنگی"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"جهت"</string>
+    <string name="label_pages" msgid="6300874667546617333">"صفحات (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"‏‏‎مثلاً ۱—۵،‏۹،۷—۱۰"</string>
+    <string name="print_preview" msgid="8010217796057763343">"پیش‌نمایش چاپ"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"‏نصب نمایشگر PDF برای پیش‌نمایش"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"برنامه چاپ خراب شد"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"صفحات"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"در حال ایجاد کار چاپ"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"‏ذخیره به‌عنوان PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"همه چاپگرها..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"چاپ گفتگو"</string>
+    <string name="search" msgid="5421724265322228497">"جستجو"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"همه چاپگرها"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"افزودن سرویس"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"کادر جستجو نمایان شد"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"کادر جستجو پنهان شد"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"افزودن چاپگر"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"انتخاب چاپگر"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"فراموش کردن چاپگر"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> چاپگر یافت شد"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> چاپگر یافت شد"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"انتخاب سرویس چاپ"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"در حال جستجو برای چاپگرها"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"هیچ چاپگری یافت نشد"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"در حال چاپ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"در حال لغو <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"خطای چاپگر <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"چاپگر، کار <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> را مسدود کرد"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"کار چاپ <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"کارهای چاپ <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"لغو"</string>
+    <string name="restart" msgid="2472034227037808749">"راه‌اندازی مجدد"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"اتصال با چاپگر برقرار نیست"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"نامعلوم"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - در دسترس نیست"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"کار چاپ ایجاد نشد"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"سیاه و سفید"</item>
+    <item msgid="2762241247228983754">"رنگی"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"عمودی"</item>
+    <item msgid="3199660090246166812">"افقی"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"همه"</item>
+    <item msgid="6812869625222503603">"محدوده"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml
new file mode 100644
index 0000000..8658e04
--- /dev/null
+++ b/packages/PrintSpooler/res/values-fi/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Taustatulostus"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Tulostimen asetukset"</string>
+    <string name="print_button" msgid="645164566271246268">"Tulosta"</string>
+    <string name="save_button" msgid="1921310454071758999">"Tallenna"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Kohde"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopiot"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Paperikoko"</string>
+    <string name="label_color" msgid="1108690305218188969">"Väri"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Suunta"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Sivut (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"esim. 1–5,8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Tulostuksen esikatselu"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Asenna PDF-katseluohjelma esikatselua varten"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Tulostussovellus kaatui"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Sivut"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Luodaan tulostustyö"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Tallenna PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Kaikki tulostimet…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Tulostusikkuna"</string>
+    <string name="search" msgid="5421724265322228497">"Haku"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Kaikki tulostimet"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Lisää palvelu"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Hakukenttä näkyvissä"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Hakukenttä piilotettu"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Lisää tulostin"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Valitse tulostin"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Unohda tulostin"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Löytyi <xliff:g id="COUNT">%1$s</xliff:g> tulostin"</item>
+    <item quantity="other" msgid="6533817036607128241">"Löytyi <xliff:g id="COUNT">%1$s</xliff:g> tulostinta"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Valitse tulostuspalvelu"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Etsitään tulostimia"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Tulostimia ei löydy"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Tulostetaan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Peruutetaan työ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Tulostinvirhe työlle <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Tulostin esti työn <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Tulostustyö <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Tulostustyöt <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Peruuta"</string>
+    <string name="restart" msgid="2472034227037808749">"Käynnistä uudelleen"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Ei yhteyttä tulostimeen"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"tuntematon"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ei käytettävissä"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Tulostustyötä ei voitu luoda"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Mustavalkoinen"</item>
+    <item msgid="2762241247228983754">"Väri"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Pysty"</item>
+    <item msgid="3199660090246166812">"Vaaka"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Kaikki"</item>
+    <item msgid="6812869625222503603">"Väli"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..9a3352c
--- /dev/null
+++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"File d\'att. impr."</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Paramètres de l\'imprimante"</string>
+    <string name="print_button" msgid="645164566271246268">"Imprimer"</string>
+    <string name="save_button" msgid="1921310454071758999">"Enregistrer"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copies"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Format du papier"</string>
+    <string name="label_color" msgid="1108690305218188969">"Couleur"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pages (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Aperçu avant impression"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Installer un lecteur PDF pour voir l\'aperçu"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"L\'application à l\'origine de l\'impression a planté"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pages"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Génération tâche impression…"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Enregistrer en format PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Toutes les imprimantes…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Boîte de dialogue d\'impression"</string>
+    <string name="search" msgid="5421724265322228497">"Rechercher"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Toutes les imprimantes"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Ajouter le service"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Champ de recherche affiché"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Champ de recherche masqué"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Ajouter une imprimante"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Sélectionner une imprimante"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Supprimer l\'imprimante"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> imprimante trouvée"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> imprimantes trouvées"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Sélectionner le service d\'impression"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Recherche d\'imprimantes en cours..."</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Aucune imprimante trouvée"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> en cours…"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> »…"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Erreur impression : « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> »"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Impression de « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> » bloquée"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Tâche d\'impression <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Tâches d\'impression <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Annuler"</string>
+    <string name="restart" msgid="2472034227037808749">"Recommencer"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"inconnu"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — indisponible"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Impossible de générer la tâche d\'impression"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Noir et blanc"</item>
+    <item msgid="2762241247228983754">"Couleur"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portrait"</item>
+    <item msgid="3199660090246166812">"Paysage"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Tous"</item>
+    <item msgid="6812869625222503603">"Plage"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml
new file mode 100644
index 0000000..17fabdc
--- /dev/null
+++ b/packages/PrintSpooler/res/values-fr/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Spouler impress."</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Paramètres de l\'imprimante"</string>
+    <string name="print_button" msgid="645164566271246268">"Imprimer"</string>
+    <string name="save_button" msgid="1921310454071758999">"Enregistrer"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copies"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Format du papier"</string>
+    <string name="label_color" msgid="1108690305218188969">"Couleur"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientation"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pages (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ex. : 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Aperçu avant impression"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Installer un lecteur PDF pour afficher l\'aperçu"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"L\'application à l\'origine de l\'impression a planté"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pages"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Génération tâche impression…"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Enregistrer au format .PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Toutes les imprim."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Boîte de dialogue d\'impression"</string>
+    <string name="search" msgid="5421724265322228497">"Rechercher"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Toutes les imprimantes"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Ajouter un service"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Champ de recherche affiché."</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Champ de recherche masqué."</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Ajouter une imprimante"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Sélectionner une imprimante"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Supprimer l\'imprimante"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> imprimante trouvée."</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> imprimantes trouvées."</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Sélectionner le service d\'impression"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Recherche d\'imprimantes en cours"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Aucune imprimante trouvée"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Erreur impression pour \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" bloquée"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> tâche d\'impression"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> tâches d\'impression"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Annuler"</string>
+    <string name="restart" msgid="2472034227037808749">"Redémarrer"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Aucune connexion à l\'imprimante."</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"inconnue"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponible"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Impossible de générer la tâche d\'impression."</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Noir et blanc"</item>
+    <item msgid="2762241247228983754">"Couleur"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portrait"</item>
+    <item msgid="3199660090246166812">"Paysage"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Tout"</item>
+    <item msgid="6812869625222503603">"Plage"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
new file mode 100644
index 0000000..60406b7
--- /dev/null
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"प्रिंट स्पूलर"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"प्रिंटर सेटिंग"</string>
+    <string name="print_button" msgid="645164566271246268">"प्रिंट करें"</string>
+    <string name="save_button" msgid="1921310454071758999">"सहेजें"</string>
+    <string name="label_destination" msgid="9132510997381599275">"गंतव्य"</string>
+    <string name="label_copies" msgid="3634531042822968308">"प्रतियां"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"कागज़ का आकार"</string>
+    <string name="label_color" msgid="1108690305218188969">"रंग"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"अभिविन्‍यास"</string>
+    <string name="label_pages" msgid="6300874667546617333">"पृष्‍ठ (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"उदा. 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"प्रिंट पूर्वावलोकन"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"पूर्वावलोकन के लिए PDF व्यूअर इंस्टॉल करें"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"प्रिंटिंग एप्लिकेशन क्रैश हो गया"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"पृष्ठ"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"प्रिंट कार्य जनरेट हो रहा है"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF के रूप में सहेजें"</string>
+    <string name="all_printers" msgid="5018829726861876202">"सभी प्रिंटर..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"प्रिंट संवाद"</string>
+    <string name="search" msgid="5421724265322228497">"खोजें"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"सभी प्रिंटर"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"सेवा जोड़ें"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"खोज बॉक्स प्रदर्शित है"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"खोज बॉक्स छिपा हुआ है"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"प्रिंटर जोड़ें"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"प्रिंटर चुनें"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"प्रिंटर को भूल जाएं"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> प्रिंटर मिला"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> प्रिंटर मिले"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"प्रिंट सेवा चुनें"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर खोज रहा है"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"कोई प्रिंटर नहीं मिले"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> प्रिंट हो रहा है"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द हो रहा है"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर त्रुटि <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"प्रिंटर अवरोधित <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> प्रिंट कार्य"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> प्रिंट कार्य"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"रद्द करें"</string>
+    <string name="restart" msgid="2472034227037808749">"पुन: आरंभ करें"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"प्रिंटर के लिए कोई कनेक्शन नहीं"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"अज्ञात"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – अनुपलब्ध"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"प्रिंट कार्य जनरेट नहीं किया जा सका"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"श्याम और श्वेत"</item>
+    <item msgid="2762241247228983754">"रंग"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"पोर्ट्रेट"</item>
+    <item msgid="3199660090246166812">"लैंडस्केप"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"सभी"</item>
+    <item msgid="6812869625222503603">"सीमा"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml
new file mode 100644
index 0000000..7182cf6
--- /dev/null
+++ b/packages/PrintSpooler/res/values-hr/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Postavke pisača"</string>
+    <string name="print_button" msgid="645164566271246268">"Ispis"</string>
+    <string name="save_button" msgid="1921310454071758999">"Spremi"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Odredište"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopije"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Veličina papira"</string>
+    <string name="label_color" msgid="1108690305218188969">"U boji"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orijentacija"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Stranice (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"npr. 1 – 5,8,11 – 13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Pregled ispisa"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instaliraj PDF preglednik za pregled"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Srušila se aplikacija za ispis"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Stranice"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generiranje zadatka ispisa"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Spremi kao PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Svi pisači…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Dijaloški okvir za ispis"</string>
+    <string name="search" msgid="5421724265322228497">"Pretraživanje"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Svi pisači"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Dodaj uslugu"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Okvir za pretraživanje prikazan je"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Okvir za pretraživanje skriven je"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Dodaj pisač"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Odaberite pisač"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Zaboravite pisač"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Pronađen je <xliff:g id="COUNT">%1$s</xliff:g> pisač"</item>
+    <item quantity="other" msgid="6533817036607128241">"Pronađen je sljedeći broj pisača: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Odaberite uslugu ispisa"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje pisača"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nije pronađen nijedan pisač"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Ispisivanje <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazivanje zadatka <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Pogreška pisača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Pisač je blokirao <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Zadatak ispisa <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Broj zadataka ispisa: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Odustani"</string>
+    <string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema veze s pisačem"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"nepoznato"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – zadatak nije dostupan"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Zadatak ispisa nije generiran"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Crno-bijelo"</item>
+    <item msgid="2762241247228983754">"U boji"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portret"</item>
+    <item msgid="3199660090246166812">"Pejzaž"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Sve"</item>
+    <item msgid="6812869625222503603">"Raspon"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml
new file mode 100644
index 0000000..6a0741b
--- /dev/null
+++ b/packages/PrintSpooler/res/values-hu/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Nyomtatásisor-kezelő"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Nyomtatóbeállítások"</string>
+    <string name="print_button" msgid="645164566271246268">"Nyomtatás"</string>
+    <string name="save_button" msgid="1921310454071758999">"Mentés"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Cél"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Példányszám"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Papírméret"</string>
+    <string name="label_color" msgid="1108690305218188969">"Szín"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Tájolás"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Oldalszám (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"pl. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Előnézet nyomtatása"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Az előnézethez telepítse a PDF-megtekintőt."</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"A nyomtatási alkalmazás összeomlott."</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Oldalak"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Nyomtatási feladat létrehozása"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Mentés PDF-ként"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Az összes nyomtató…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Nyomtatási párbeszédablak"</string>
+    <string name="search" msgid="5421724265322228497">"Keresés"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Az összes nyomtató"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Szolgáltatás hozzáadása"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Keresőmező megjelenítve"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Keresőmező elrejtve"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Nyomtató hozzáadása"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Nyomtató kiválasztása"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Nyomtató elfelejtése"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> nyomtató észlelve"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> nyomtató észlelve"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Nyomtatási szolgáltatás kiválasztása"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Nyomtatók keresése"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nem található nyomtató"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> nyomtatása"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> törlése"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Nyomtatási hiba: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> letiltva."</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> – nyomtatási feladat"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> – nyomtatási feladatok"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Mégse"</string>
+    <string name="restart" msgid="2472034227037808749">"Újraindítás"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nincs kapcsolat a nyomtatóval"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"ismeretlen"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nem érhető el"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Nem sikerült létrehozni a nyomtatási feladatot."</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Fekete-fehér"</item>
+    <item msgid="2762241247228983754">"Szín"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Álló"</item>
+    <item msgid="3199660090246166812">"Fekvő"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Összes"</item>
+    <item msgid="6812869625222503603">"Tartomány"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
new file mode 100644
index 0000000..1423b82
--- /dev/null
+++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Տպման կարգավար"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Տպիչի կարգավորումներ"</string>
+    <string name="print_button" msgid="645164566271246268">"Տպել"</string>
+    <string name="save_button" msgid="1921310454071758999">"Պահել"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Նպատակակետ"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Պատճեններ"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Թղթի չափը"</string>
+    <string name="label_color" msgid="1108690305218188969">"Գույնը"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Դիրքավորում"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Էջեր (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"օր.՝ 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Տպելու նախադիտում"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Նախադիտման համար տեղադրեք PDF դիտարկիչ"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Տպելու ծրագիրը վթարի է ենթարկվել"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Էջեր"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Ձևավորվում է տպելու աշխատանքը"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Պահել որպես PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Բոլոր տպիչները..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Տպելու երկխոսության պատուհան"</string>
+    <string name="search" msgid="5421724265322228497">"Որոնել"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Բոլոր տպիչները"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Ավելացնել ծառայություն"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Որոնման վանդակը ցուցադրված է"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Որոնման վանդակը թաքցվել է"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Ավելացնել տպիչ"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Ընտրել տպիչ"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Մոռանալ տպիչը"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> տպիչ է գտնվել"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> տպիչ է գտնվել"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Ընտրեք տպելու ծառայությունը"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Տպիչների որոնում"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Տպիչներ չեն գտնվել"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Տպվում է՝ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ը չեղարկվում է"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Տպիչի սխալ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Տպիչն արգելափակել է <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ը"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> տպման աշխատանք"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> տպման աշխատանքներ"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Չեղարկել"</string>
+    <string name="restart" msgid="2472034227037808749">"Վերագործարկել"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Տպիչի հետ կապ չկա"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"անհայտ"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> տպիչն անհասանելի է"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Չկարողացանք մշակել տպման աշխատանքը"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Սև ու սպիտակ"</item>
+    <item msgid="2762241247228983754">"Գույնը"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Դիմանկար"</item>
+    <item msgid="3199660090246166812">"Լանդշաֆտ"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Բոլորը"</item>
+    <item msgid="6812869625222503603">"Միջակայք"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml
new file mode 100644
index 0000000..2b80d07
--- /dev/null
+++ b/packages/PrintSpooler/res/values-in/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Setelan printer"</string>
+    <string name="print_button" msgid="645164566271246268">"Cetak"</string>
+    <string name="save_button" msgid="1921310454071758999">"Simpan"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Tujuan"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Salinan"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Ukuran Kertas"</string>
+    <string name="label_color" msgid="1108690305218188969">"Warna"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientasi"</string>
+    <string name="label_pages" msgid="6300874667546617333">"(<xliff:g id="PAGE_COUNT">%1$s</xliff:g>) halaman"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"misalnya 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Pratinjau cetak"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Pasang penampil PDF untuk pratinjau"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Aplikasi pencetakan mogok"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Halaman"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Membuat tugas pencetakan"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Simpan sebagai PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Semua printer…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Cetak dialog"</string>
+    <string name="search" msgid="5421724265322228497">"Cari"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Semua printer"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Tambahkan layanan"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Kotak telusur ditampilkan"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Kotak telusur disembunyikan"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Tambahkan printer"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Pilih printer"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Lupakan printer"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> printer ditemukan"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> printer ditemukan"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Pilih layanan cetak"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Mencari printer"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Tidak ditemukan printer"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Ada kesalahan printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printer memblokir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Tugas cetak <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Tugas cetak <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Batal"</string>
+    <string name="restart" msgid="2472034227037808749">"Mulai Ulang"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Tidak ada sambungan ke printer"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"tak diketahui"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Tidak dapat membuat tugas cetak"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Hitam &amp; Putih"</item>
+    <item msgid="2762241247228983754">"Warna"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Potret"</item>
+    <item msgid="3199660090246166812">"Lanskap"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Semua"</item>
+    <item msgid="6812869625222503603">"Rentang"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml
new file mode 100644
index 0000000..96c3b48
--- /dev/null
+++ b/packages/PrintSpooler/res/values-it/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Impostazioni stampante"</string>
+    <string name="print_button" msgid="645164566271246268">"Stampa"</string>
+    <string name="save_button" msgid="1921310454071758999">"Salva"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destinazione"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copie"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Formato carta"</string>
+    <string name="label_color" msgid="1108690305218188969">"A colori"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientamento"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pagine (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"Es.: 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Anteprima di stampa"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Installa visualizzatore PDF per anteprima"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Arresto anomalo dell\'app di stampa"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pagine"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generazione processo di stampa"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Salva in PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Tutte le stampanti…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Finestra di dialogo Stampa"</string>
+    <string name="search" msgid="5421724265322228497">"Cerca"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Tutte le stampanti"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Aggiungi servizio"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Casella di ricerca visualizzata"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Casella di ricerca nascosta"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Aggiungi stampante"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Seleziona stampante"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Elimina stampante"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> stampante trovata"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> stampanti trovate"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Scegli servizio di stampa"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Ricerca di stampanti"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nessuna stampante trovata"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Stampa di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annullamento di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Errore della stampante: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"La stampante ha bloccato <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Processo di stampa <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Processi di stampa <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Annulla"</string>
+    <string name="restart" msgid="2472034227037808749">"Riavvia"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nessun collegamento alla stampante"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"sconosciuto"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - non disponibile"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Impossibile generare processo di stampa"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Bianco e nero"</item>
+    <item msgid="2762241247228983754">"A colori"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Verticale"</item>
+    <item msgid="3199660090246166812">"Orizzontale"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Tutte"</item>
+    <item msgid="6812869625222503603">"Intervallo"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml
new file mode 100644
index 0000000..3e0e732
--- /dev/null
+++ b/packages/PrintSpooler/res/values-iw/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"הגדרות מדפסת"</string>
+    <string name="print_button" msgid="645164566271246268">"הדפס"</string>
+    <string name="save_button" msgid="1921310454071758999">"שמור"</string>
+    <string name="label_destination" msgid="9132510997381599275">"יעד"</string>
+    <string name="label_copies" msgid="3634531042822968308">"עותקים"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"גודל נייר"</string>
+    <string name="label_color" msgid="1108690305218188969">"צבע"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"כיוון"</string>
+    <string name="label_pages" msgid="6300874667546617333">"עמודים (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"למשל 1–5‏,8,‏11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"תצוגה מקדימה של הדפסה"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"‏התקן מציג PDF ליצירת תצוגה מקדימה"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"אפליקציית ההדפסה קרסה"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"עמודים"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"יוצר עבודת הדפסה"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"‏שמור כ-PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"כל המדפסות…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"תיבת דו שיח של מדפסת"</string>
+    <string name="search" msgid="5421724265322228497">"חפש"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"כל המדפסות"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"הוסף שירות"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"תיבת החיפוש מוצגת"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"תיבת החיפוש מוסתרת"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"הוסף מדפסת"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"בחר מדפסת"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"שכח את המדפסת"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"נמצאה מדפסת <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+    <item quantity="other" msgid="6533817036607128241">"נמצאו <xliff:g id="COUNT">%1$s</xliff:g> מדפסות"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"בחר שירות הדפסה"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"מחפש מדפסות"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"לא נמצאו מדפסות"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"מדפיס את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"מבטל את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"שגיאת מדפסת ב-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"המדפסת חסמה את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"עבודת הדפסה <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> עבודות הדפסה"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"בטל"</string>
+    <string name="restart" msgid="2472034227037808749">"הפעל מחדש"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"אין חיבור למדפסת"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"לא ידוע"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – לא זמינה"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"לא ניתן היה ליצור את עבודת ההדפסה"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"שחור ולבן"</item>
+    <item msgid="2762241247228983754">"צבע"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"לאורך"</item>
+    <item msgid="3199660090246166812">"לרוחב"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"הכל"</item>
+    <item msgid="6812869625222503603">"טווח"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml
new file mode 100644
index 0000000..f8be5c7
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ja/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"印刷スプーラ"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"プリンタの設定"</string>
+    <string name="print_button" msgid="645164566271246268">"印刷"</string>
+    <string name="save_button" msgid="1921310454071758999">"保存"</string>
+    <string name="label_destination" msgid="9132510997381599275">"印刷先"</string>
+    <string name="label_copies" msgid="3634531042822968308">"部数"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"用紙サイズ"</string>
+    <string name="label_color" msgid="1108690305218188969">"カラー"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
+    <string name="label_pages" msgid="6300874667546617333">"ページ(<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"例: 1-5,8,11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"印刷プレビュー"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"プレビュー用PDFビューアをインストール"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"印刷アプリでの障害発生"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"ページ数"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"印刷ジョブを生成しています"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF形式で保存"</string>
+    <string name="all_printers" msgid="5018829726861876202">"すべてのプリンタ…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"印刷ダイアログ"</string>
+    <string name="search" msgid="5421724265322228497">"検索"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"すべてのプリンタ"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"サービスを追加"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"検索ボックスは表示されています"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"検索ボックスは表示されていません"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"プリンタを追加"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"プリンタを選択"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"プリンタを切断"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g>台のプリンタが見つかりました"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g>台のプリンタが見つかりました"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"印刷サービスの選択"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"プリンタの検索中"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"プリンタが見つかりません"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>を印刷しています"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>をキャンセルしています"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"プリンタエラー: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>をブロックしました"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>の印刷ジョブ"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>の印刷ジョブ"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"キャンセル"</string>
+    <string name="restart" msgid="2472034227037808749">"再試行"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"プリンタに接続されていません"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>–使用不可"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"印刷ジョブを生成できませんでした"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"モノクロ"</item>
+    <item msgid="2762241247228983754">"色"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"縦向き"</item>
+    <item msgid="3199660090246166812">"横向き"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"すべて"</item>
+    <item msgid="6812869625222503603">"範囲"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..d36b7c9
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"ბეჭდვის Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"პრინტერის პარამეტრები"</string>
+    <string name="print_button" msgid="645164566271246268">"ბეჭდვა"</string>
+    <string name="save_button" msgid="1921310454071758999">"შენახვა"</string>
+    <string name="label_destination" msgid="9132510997381599275">"დანიშნულება"</string>
+    <string name="label_copies" msgid="3634531042822968308">"ასლები"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"ფურცლის ზომა"</string>
+    <string name="label_color" msgid="1108690305218188969">"ფერი"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"ორიენტაცია"</string>
+    <string name="label_pages" msgid="6300874667546617333">"გვერდები (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"მაგ. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"ნახვა ამობეჭდვამდე"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"გადახედვისთვის დააყენეთ PDF მნახველი"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"ბეჭდვის აპი ავარიულად გაითიშა"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"გვერდები"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"მიმდინარეობის ბეჭდვის დავალების შექმნა"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF-ად შენახვა"</string>
+    <string name="all_printers" msgid="5018829726861876202">"ყველა პრინტერი…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"ბეჭდვის სარკმელი"</string>
+    <string name="search" msgid="5421724265322228497">"ძიება"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"ყველა პრინტერი"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"სერვისის დამატება"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"საძიებო ველი ნაჩვენებია"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"საძიებო ველი დამალულია"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"პრინტერის დამატება"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"პრინტერის არჩევა"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"პრინტერის დავიწყება"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"ნაპოვნია <xliff:g id="COUNT">%1$s</xliff:g> პრინტერი"</item>
+    <item quantity="other" msgid="6533817036607128241">"ნაპოვნია <xliff:g id="COUNT">%1$s</xliff:g> პრინტერი"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"აირჩიეთ ბეჭდვის სერვისი"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"მიმდინარეობს პრინტერების ძიება"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"პრინტერები ვერ მოიძებნა"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"იბეჭდება <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"მიმდინარეობს <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ის გაუქმება"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"ბეჭდვის შეცდომა <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"პრინტერმა დაბლოკა <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"ბეჭდვის <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> დავალება"</item>
+    <item quantity="other" msgid="8746611264734222865">"ბეჭდვის <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> დავალება"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"გაუქმება"</string>
+    <string name="restart" msgid="2472034227037808749">"გადატვირთვა"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"პრინტერთან კავშირი არ არის"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"უცნობი"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – მიუწვდომელია"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"ბეჭდვის დავალების გენერაცია ვერ ხერხდება"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"შავ-თეთრი"</item>
+    <item msgid="2762241247228983754">"ფერი"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"პორტრეტი"</item>
+    <item msgid="3199660090246166812">"პეიზაჟის რეჟიმი"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"ყველა"</item>
+    <item msgid="6812869625222503603">"დიაპაზონი"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..c89f9bf
--- /dev/null
+++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"បោះពុម្ព​ស្ពូល័រ"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"ការ​កំណត់​ម៉ាស៊ីន​បោះពុម្ព"</string>
+    <string name="print_button" msgid="645164566271246268">"បោះពុម្ព"</string>
+    <string name="save_button" msgid="1921310454071758999">"រក្សាទុក"</string>
+    <string name="label_destination" msgid="9132510997381599275">"ទិសដៅ"</string>
+    <string name="label_copies" msgid="3634531042822968308">"ច្បាប់​ចម្លង"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"ទំហំ​ក្រដាស"</string>
+    <string name="label_color" msgid="1108690305218188969">"ពណ៌"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"ទិស"</string>
+    <string name="label_pages" msgid="6300874667546617333">"ទំព័រ (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ឧ. 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"មើល​មុន​បោះពុម្ព"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"ដំឡើង​កម្មវិធី​មើល PDF សម្រាប់​ការ​មើល​ជា​មុន"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"កម្មវិធី​បោះពុម្ព​គាំង"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"ទំព័រ"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"​បង្កើត​ការ​ងារ​បោះពុម្ព"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"រក្សា​ទុក​ជា PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"ម៉ាស៊ីន​បោះពុម្ព​ទាំងអស់ ..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"ប្រអប់​បោះពុម្ព"</string>
+    <string name="search" msgid="5421724265322228497">"ស្វែងរក"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"ម៉ាស៊ីន​បោះពុម្ព​ទាំងអស់"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"បន្ថែម​សេវាកម្ម"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"បាន​បង្ហាញ​ប្រ​អប់​ស្វែងរក"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"បាន​លាក់​ប្រអប់​ស្វែងរក"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"បន្ថែម​ម៉ាស៊ីន​បោះពុម្ព"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"ជ្រើស​ម៉ាស៊ីន​បោះពុម្ព"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"ភ្លេច​​ម៉ាស៊ីន​បោះពុម្ព"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"រក​ឃើញ​ម៉ាស៊ីន​បោះពុម្ព <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+    <item quantity="other" msgid="6533817036607128241">"រក​ឃើញ​ម៉ាស៊ីន​បោះពុម្ព <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"ជ្រើស​សេវា​បោះពុម្ព"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"ស្វែងរក​ម៉ាស៊ីន​បោះពុម្ព"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"រក​មិន​ឃើញ​ម៉ាស៊ីន​បោះពុម្ព"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"កំពុង​​បោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ការ​បោះបង់ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"កំហុស​ម៉ាស៊ីន​បោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"ម៉ាស៊ីន​បោះពុម្ព​បាន​ទប់ស្កាត់ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"ការងារ​បោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"ការងារ​បោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"បោះបង់"</string>
+    <string name="restart" msgid="2472034227037808749">"ចាប់ផ្ដើម​ឡើងវិញ"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"គ្មាន​​​ការ​ភ្ជាប់​ទៅ​ម៉ាស៊ីន​បោះពុម្ព"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"មិន​ស្គាល់"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – មិន​អាច​ប្រើ​បាន"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"មិន​អាច​បង្កើត​ការ​ងារ​បោះពុម្ព"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"ស &amp; ខ្មៅ"</item>
+    <item msgid="2762241247228983754">"ពណ៌"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"បញ្ឈរ"</item>
+    <item msgid="3199660090246166812">"ផ្ដេក"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"ទាំង​អស់"</item>
+    <item msgid="6812869625222503603">"ជួរ"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml
new file mode 100644
index 0000000..3b2fef7
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ko/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"인쇄 스풀러"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"프린터 설정"</string>
+    <string name="print_button" msgid="645164566271246268">"인쇄"</string>
+    <string name="save_button" msgid="1921310454071758999">"저장"</string>
+    <string name="label_destination" msgid="9132510997381599275">"대상"</string>
+    <string name="label_copies" msgid="3634531042822968308">"매수"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"용지 크기"</string>
+    <string name="label_color" msgid="1108690305218188969">"색상"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"방향"</string>
+    <string name="label_pages" msgid="6300874667546617333">"페이지 수(<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"예: 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"인쇄 미리보기"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"미리보기용 PDF 뷰어 설치"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"인쇄 앱에 오류 발생"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"페이지"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"인쇄 작업 생성 중"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF로 저장"</string>
+    <string name="all_printers" msgid="5018829726861876202">"모든 프린터…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"인쇄 대화상자"</string>
+    <string name="search" msgid="5421724265322228497">"검색"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"모든 프린터"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"서비스 추가"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"검색창 표시됨"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"검색창 숨겨짐"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"프린터 추가"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"프린터 선택"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"프린터 삭제"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"프린터 <xliff:g id="COUNT">%1$s</xliff:g>대 검색됨"</item>
+    <item quantity="other" msgid="6533817036607128241">"프린터 <xliff:g id="COUNT">%1$s</xliff:g>대 검색됨"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"인쇄 서비스 선택"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"프린터 검색 중"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"프린터 없음"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 인쇄 중"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 취소 중"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"프린터 오류: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"차단된 프린터: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> 인쇄 작업"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> 인쇄 작업"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"취소"</string>
+    <string name="restart" msgid="2472034227037808749">"다시 시작"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"프린터와 연결되지 않음"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"알 수 없음"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 사용할 수 없음"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"인쇄 작업을 생성할 수 없습니다."</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"흑백"</item>
+    <item msgid="2762241247228983754">"컬러"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"세로"</item>
+    <item msgid="3199660090246166812">"가로"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"모두"</item>
+    <item msgid="6812869625222503603">"범위"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..f954606
--- /dev/null
+++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"ຕົວຈັດຄິວການພິມ"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"ການຕັ້ງຄ່າເຄື່ອງພິມ"</string>
+    <string name="print_button" msgid="645164566271246268">"ພິມ"</string>
+    <string name="save_button" msgid="1921310454071758999">"ບັນທຶກ"</string>
+    <string name="label_destination" msgid="9132510997381599275">"ປາຍທາງ"</string>
+    <string name="label_copies" msgid="3634531042822968308">"ສຳເນົາ"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"ຂະໜາດຂອງໜ້າເຈ້ຍ"</string>
+    <string name="label_color" msgid="1108690305218188969">"ສີ"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"ລວງ"</string>
+    <string name="label_pages" msgid="6300874667546617333">"(<xliff:g id="PAGE_COUNT">%1$s</xliff:g>) ໜ້າ"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ຕົວຢ່າງ: 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"ເບິ່ງກ່ອນພິມ"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"ຕິດຕັ້ງໂປຼແກຼມເບິ່ງ PDF ເພື່ອເບິ່ງຕົວຢ່າງ"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"ແອັບຯພິມລົ້ມເຫລວ"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"ໜ້າ"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"ກຳລັງສ້າງວຽກພິມ"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"ບັນທຶກເປັ​​ນ PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"ທຸກເຄື່ອງພິມ..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"ໜ້າຕ່າງການພິມ"</string>
+    <string name="search" msgid="5421724265322228497">"ຊອກຫາ"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"ທຸກເຄື່ອງພິມ"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"ເພີ່ມບໍລິການ"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"ກ່ອງຊອກຫາຖືກສະແດງ"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ກ່ອງຊອກຫາຖືກເຊື່ອງ"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"ເພີ່ມເຄື່ອງພິມ"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"ເລືອກເຄື່ອງພິມ"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"ລືມເຄື່ອງພິມ"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"ພົບ <xliff:g id="COUNT">%1$s</xliff:g> ເຄື່ອງພິມ"</item>
+    <item quantity="other" msgid="6533817036607128241">"ພົບ <xliff:g id="COUNT">%1$s</xliff:g> ເຄື່ອງພິມ"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"ເລືອກບໍລິການການພິມ"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"ກຳລັງຊອກຫາເຄື່ອງພິມ"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"ບໍ່ພົບເຄື່ອງພິມ"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"ກຳລັງພິມ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ກຳລັງຍົກເລີກ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"ເຄື່ອງພິມເກີດຂໍ້ຜິດພາດ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"ເຄື່ອງພິມຖືກບລອກ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"ງານພິມ <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"ງານພິມ <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"ຍົກເລີກ"</string>
+    <string name="restart" msgid="2472034227037808749">"ປິດເປີດໃໝ່"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"ບໍ່ມີການເຊື່ອມຕໍ່ຫາເຄື່ອງພິມ"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"ບໍ່ຮູ້ຈັກ"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - ບໍ່ມີຢູ່"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"ບໍ່​ສາ​ມາດ​ສ້າງວຽກພິມໄດ້"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"ຂາວດຳ"</item>
+    <item msgid="2762241247228983754">"ສີ"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"ລວງຕັ້ງ"</item>
+    <item msgid="3199660090246166812">"ລວງນອນ"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"ທັງໝົດ"</item>
+    <item msgid="6812869625222503603">"ໄລຍະ"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml
new file mode 100644
index 0000000..0c4e386
--- /dev/null
+++ b/packages/PrintSpooler/res/values-lt/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Spausdintuvo nustatymai"</string>
+    <string name="print_button" msgid="645164566271246268">"Spausdinti"</string>
+    <string name="save_button" msgid="1921310454071758999">"Išsaugoti"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Paskirties vieta"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopijos"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Popieriaus dydis"</string>
+    <string name="label_color" msgid="1108690305218188969">"Spalva"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientacija"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Puslapiai (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"pvz., 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Spaudinio peržiūra"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Įdiegti PDF peržiūros priemonę"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Spausdinimo programa užstrigo"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Puslapiai"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generuojama spausd. užduotis"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Išsaugoti kaip PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Visi spausdintuvai…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Spausdinimo dialogo langas"</string>
+    <string name="search" msgid="5421724265322228497">"Ieškoti"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Visi spausdintuvai"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Pridėti paslaugą"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Paieškos laukelis rodomas"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Paieškos laukelis paslėptas"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Pridėti spausdintuvą"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Pasirinkti spausdintuvą"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Pamiršti spausdintuvą"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Rasta spausdintuvų: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+    <item quantity="other" msgid="6533817036607128241">"Rasta spausdintuvų: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Pasirinkite spausdinimo paslaugą"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Ieškoma spausdintuvų"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nerasta spausdintuvų"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Spausdinama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Atšaukiama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Spausdintuvo klaida: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Spausdintuvas užblokavo: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Spausdinimo užduotis: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Spausdinimo užduotys: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Atšaukti"</string>
+    <string name="restart" msgid="2472034227037808749">"Paleisti iš naujo"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nėra ryšio su spausdintuvu"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"nežinoma"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ – nepasiekiama"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Nepavyko sukurti spausdinimo užduoties"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Nespalvotas"</item>
+    <item msgid="2762241247228983754">"Spalva"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Stačias"</item>
+    <item msgid="3199660090246166812">"Gulsčias"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Visi"</item>
+    <item msgid="6812869625222503603">"Diapazonas"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml
new file mode 100644
index 0000000..3fffdfe
--- /dev/null
+++ b/packages/PrintSpooler/res/values-lv/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Printera iestatījumi"</string>
+    <string name="print_button" msgid="645164566271246268">"Drukāt"</string>
+    <string name="save_button" msgid="1921310454071758999">"Saglabāt"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Galamērķis"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Eksemplāri"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Papīra izmērs"</string>
+    <string name="label_color" msgid="1108690305218188969">"Krāsa"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Virziens"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Lapas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"piem., 1–5,8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Drukas priekšskatījums"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalēt PDF skatītāju priekšskatīšanai"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Drukas lietotne avarēja"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Lapas"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Ģenerē drukas darbu…"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Saglabāt kā PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Visi printeri…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Drukāšanas dialoglodziņš"</string>
+    <string name="search" msgid="5421724265322228497">"Meklēt"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Visi printeri"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Pievienot pakalpojumu"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Meklēšanas lodziņš ir redzams."</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Meklēšanas lodziņš ir paslēpts."</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Pievienot printeri"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Atlasīt printeri"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Neatcerēties printeri"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Atrasts <xliff:g id="COUNT">%1$s</xliff:g> printeris"</item>
+    <item quantity="other" msgid="6533817036607128241">"Atrasti <xliff:g id="COUNT">%1$s</xliff:g> printeri"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Izvēlieties drukāšanas pakalpojumu"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Printeru meklēšana"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Netika atrasts neviens printeris."</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Notiek darba <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> drukāšana…"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Pārtrauc drukas darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Printera kļūda ar darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printeris bloķēja darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Drukas darbs <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Drukas darbi <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Atcelt"</string>
+    <string name="restart" msgid="2472034227037808749">"Restartēt"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nav savienojuma ar printeri"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"nezināms"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> — nav pieejams"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Nevarēja ģenerēt drukas darbu"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Melnbalts"</item>
+    <item msgid="2762241247228983754">"Krāsa"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portrets"</item>
+    <item msgid="3199660090246166812">"Ainava"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Visi"</item>
+    <item msgid="6812869625222503603">"Diapazons"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
new file mode 100644
index 0000000..e429387
--- /dev/null
+++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Хэвлэгчийн буфер"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Принтерийн тохиргоо"</string>
+    <string name="print_button" msgid="645164566271246268">"Хэвлэх"</string>
+    <string name="save_button" msgid="1921310454071758999">"Хадгалах"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Хүлээн авагч"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Хуулбарууд"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Цаасны хэмжээ"</string>
+    <string name="label_color" msgid="1108690305218188969">"Өнгө"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Чиглэл"</string>
+    <string name="label_pages" msgid="6300874667546617333">"(<xliff:g id="PAGE_COUNT">%1$s</xliff:g>) хуудас"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ж.нь. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Хэвлэхээр урьдчилан харах"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Урьдчилан харахын тулд PDF харагчийг суулгах"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Хэвлэгч апп гацсан"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Хуудас"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Хэвлэх ажил үүсгэж байна"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF болгож хадгалах"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Бүх принтерүүд…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Хэвлэх диалоги"</string>
+    <string name="search" msgid="5421724265322228497">"Хайх"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Бүх принтерүүд"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Үйлчилгээ нэмэх"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Хайлтын нүдийг гаргах"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Хайлтын нүдийг далдлах"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Принтер нэмэх"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Принтер сонгох"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Принтерийг мартах"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> принтер олдсон"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> принтер олдсон"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Хэвлэх үйлчилгээг сонгох"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтер хайж байна"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Принтер олдсонгүй"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Хэвлэж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Цуцлаж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Принтерийн алдаа <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Принтер хориглогдсон <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> хэвлэх ажил"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> хэвлэх ажлууд"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Цуцлах"</string>
+    <string name="restart" msgid="2472034227037808749">"Дахин эхлүүлэх"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Принтер холбогдоогүй байна"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"тодорхойгүй"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ашиглах боломжгүй"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Хэвлэх ажлыг үүсгэж чадсангүй"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Хар &amp; Цагаан"</item>
+    <item msgid="2762241247228983754">"Өнгө"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Босоо"</item>
+    <item msgid="3199660090246166812">"Хэвтээ"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Бүгд"</item>
+    <item msgid="6812869625222503603">"Хүрээ"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
new file mode 100644
index 0000000..cca5d2c
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Penspul Cetakan"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Tetapan pencetak"</string>
+    <string name="print_button" msgid="645164566271246268">"Cetak"</string>
+    <string name="save_button" msgid="1921310454071758999">"Simpan"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destinasi"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Salinan"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Saiz Kertas"</string>
+    <string name="label_color" msgid="1108690305218188969">"Warna"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientasi"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Halaman (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"cth. 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Pratonton cetak"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Pasang pemapar PDF untuk pratonton"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Apl percetakan ranap"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Halaman"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Menjana kerja cetak"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Simpan sebagai PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Semua pencetak..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Dialog cetakan"</string>
+    <string name="search" msgid="5421724265322228497">"Cari"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Semua pencetak"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Tambahkan perkhidmatan"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Kotak carian ditunjukkan"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Kotak carian tersembunyi"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Tambah pencetak"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Pilih pencetak"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Lupakan pencetak"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> pencetak ditemui"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> pencetak ditemui"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Pilih perkhidmatan cetak"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Mencari pencetak"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Tiada pencetak ditemui"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Ralat pencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Pencetak disekat <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Kerja cetakan <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Kerja cetakan <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Batal"</string>
+    <string name="restart" msgid="2472034227037808749">"Mulakan semula"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Tiada sambungan ke pencetak"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"tidak diketahui"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – tidak tersedia"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Tidak dapat menjana kerja cetakan"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Hitam &amp; Putih"</item>
+    <item msgid="2762241247228983754">"Warna"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Potret"</item>
+    <item msgid="3199660090246166812">"Landskap"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Semua"</item>
+    <item msgid="6812869625222503603">"Julat"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml
new file mode 100644
index 0000000..f6a60c6
--- /dev/null
+++ b/packages/PrintSpooler/res/values-nb/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Utskriftskø"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Skriverinnstillinger"</string>
+    <string name="print_button" msgid="645164566271246268">"Skriv ut"</string>
+    <string name="save_button" msgid="1921310454071758999">"Lagre"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destinasjon"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopier"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Papirstørrelse"</string>
+    <string name="label_color" msgid="1108690305218188969">"Farge"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Retning"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Sider (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"f.eks. 1–5, 8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Utskriftsforhåndsvisning"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Installer PDF-leser for forhåndsvisning"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Utskriftsappen krasjet"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Sider"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Genererer utskriftsjobb"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Lagre som PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Alle skrivere"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Skriv ut dialog"</string>
+    <string name="search" msgid="5421724265322228497">"Søk"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Alle skrivere"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Legg til tjeneste"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Søkefeltet vises"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Søkefeltet er skjult"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Legg til skriver"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Velg skriver"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Glem skriveren"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> skriver ble funnet"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> skrivere ble funnet"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Velg utskriftstjeneste"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Søker etter skrivere"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Fant ingen skrivere"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Skriverfeil <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Skriveren blokkerte <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Utskriftsjobb for <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Utskriftsjobber for <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Avbryt"</string>
+    <string name="restart" msgid="2472034227037808749">"Start på nytt"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen forbindelse med skriveren"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"ukjent"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – utilgjengelig"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Kunne ikke generere utskriftsjobben"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Svart og hvitt"</item>
+    <item msgid="2762241247228983754">"Farge"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Stående"</item>
+    <item msgid="3199660090246166812">"Liggende"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Alle"</item>
+    <item msgid="6812869625222503603">"Område"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml
new file mode 100644
index 0000000..dc12508
--- /dev/null
+++ b/packages/PrintSpooler/res/values-nl/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Afdrukspooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Printerinstellingen"</string>
+    <string name="print_button" msgid="645164566271246268">"Afdrukken"</string>
+    <string name="save_button" msgid="1921310454071758999">"Opslaan"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Bestemming"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Aantal exemplaren"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Papierformaat"</string>
+    <string name="label_color" msgid="1108690305218188969">"Kleur"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Stand"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pagina\'s (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"bijv. 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Afdrukvoorbeeld"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Pdf-viewer installeren voor voorbeeld"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Afdruk-app gecrasht"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pagina\'s"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Afdruktaak genereren"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Opslaan als pdf"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Alle printers…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Afdrukdialoogvenster"</string>
+    <string name="search" msgid="5421724265322228497">"Zoeken"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Alle printers"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Service toevoegen"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Zoekvak weergegeven"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Zoekvak verborgen"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Printer toevoegen"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Printer selecteren"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Printer vergeten"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> printer gevonden"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> printers gevonden"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Afdrukservice kiezen"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Printers zoeken"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Geen printers gevonden"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> afdrukken"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annuleren"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Printerfout <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> geblokkeerd door printer"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> afdruktaak"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> afdruktaken"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Annuleren"</string>
+    <string name="restart" msgid="2472034227037808749">"Opnieuw starten"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Geen verbinding met printer"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"onbekend"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niet beschikbaar"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Kan de afdruktaak niet genereren"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Zwart-wit"</item>
+    <item msgid="2762241247228983754">"Kleur"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portret"</item>
+    <item msgid="3199660090246166812">"Landschap"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Alle"</item>
+    <item msgid="6812869625222503603">"Bereik"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml
new file mode 100644
index 0000000..81acc76
--- /dev/null
+++ b/packages/PrintSpooler/res/values-pl/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Bufor wydruku"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Ustawienia drukarki"</string>
+    <string name="print_button" msgid="645164566271246268">"Drukuj"</string>
+    <string name="save_button" msgid="1921310454071758999">"Zapisz"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Miejsce docelowe"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopie"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Rozmiar papieru"</string>
+    <string name="label_color" msgid="1108690305218188969">"Kolor"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientacja"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Strony (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"np. 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Podgląd wydruku"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Zainstaluj przeglądarkę PDF, by zobaczyć podgląd"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Aplikacja drukująca uległa awarii"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Strony"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generowanie zadania wydruku"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Zapisz jako PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Wszystkie drukarki…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Okno drukowania"</string>
+    <string name="search" msgid="5421724265322228497">"Szukaj"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Wszystkie drukarki"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Dodaj usługę"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Pole wyszukiwania jest widoczne"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Pole wyszukiwania jest ukryte"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Dodaj drukarkę"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Wybierz drukarkę"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Nie zapamiętuj drukarki"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Znaleziono <xliff:g id="COUNT">%1$s</xliff:g> drukarkę"</item>
+    <item quantity="other" msgid="6533817036607128241">"Znalezione drukarki: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Wybierz usługę drukowania"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Szukanie drukarek"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nie znaleziono drukarek"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Drukowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Anulowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Błąd drukarki: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Drukarka zablokowała <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> zadanie drukowania"</item>
+    <item quantity="other" msgid="8746611264734222865">"Zadania drukowania: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Anuluj"</string>
+    <string name="restart" msgid="2472034227037808749">"Od nowa"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Brak połączenia z drukarką"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"brak informacji"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – niedostępne"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Nie udało się wygenerować zadania drukowania"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Czarno-białe"</item>
+    <item msgid="2762241247228983754">"Kolor"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Pionowa"</item>
+    <item msgid="3199660090246166812">"Pozioma"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Wszystkie"</item>
+    <item msgid="6812869625222503603">"Zakres"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..6bfc395
--- /dev/null
+++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Definições da impressora"</string>
+    <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
+    <string name="save_button" msgid="1921310454071758999">"Guardar"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destino"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Cópias"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Tamanho do papel"</string>
+    <string name="label_color" msgid="1108690305218188969">"Cor"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientação"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Páginas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"p. ex. 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Pré-visualização de impressão"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar o leitor de PDF para pré-visualização"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"A aplicação de impressão bloqueou"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Páginas"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"A gerar tarefa de impressão"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Guardar como PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Todas as impressoras..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Caixa de diálogo de impressão"</string>
+    <string name="search" msgid="5421724265322228497">"Pesquisar"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Todas as impressoras"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Adicionar serviço"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Caixa de pesquisa apresentada"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Caixa de pesquisa ocultada"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Adicionar impressora"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Selecionar impressora"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Esquecer impressora"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> impressora encontrada"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> impressoras encontradas"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Escolher o serviço de impressão"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"A procurar impressoras"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"A imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A cancelar <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro da impressora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"A impressora bloqueou <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Tarefa de impressão: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Tarefas de impressão: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancelar"</string>
+    <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem ligação à impressora"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – indisponível"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Não foi possível gerar a tarefa de impressão"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Preto e branco"</item>
+    <item msgid="2762241247228983754">"Cor"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Vertical"</item>
+    <item msgid="3199660090246166812">"Horizontal"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Todas"</item>
+    <item msgid="6812869625222503603">"Intervalo"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml
new file mode 100644
index 0000000..82c157d
--- /dev/null
+++ b/packages/PrintSpooler/res/values-pt/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Sp. de impressão"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Configur. da impressora"</string>
+    <string name="print_button" msgid="645164566271246268">"Imprimir"</string>
+    <string name="save_button" msgid="1921310454071758999">"Salvar"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destino"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Cópias"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Tamanho do papel"</string>
+    <string name="label_color" msgid="1108690305218188969">"Cor"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientação"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Páginas (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"Ex.: 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Visualização de impressão"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalar o visualizador de PDF"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"O aplicativo de impressão falhou"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Páginas"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Gerando trabalho de impressão"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Salvar como PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Todas as impressoras…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Diálogo de impressão"</string>
+    <string name="search" msgid="5421724265322228497">"Pesquisar"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Todas as impressoras"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Adicionar serviço"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Caixa de pesquisa exibida"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Caixa de pesquisa oculta"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Adicionar impressora"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Selecionar impressora"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Esquecer impressora"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> impressora encontrada"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> impressoras encontradas"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Selecione o serviço de impressão"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Procurando impressoras"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro ao imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"A impressora bloqueou <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Trabalho de impressão <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Trabalhos de impressão <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Cancelar"</string>
+    <string name="restart" msgid="2472034227037808749">"Reiniciar"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Sem conexão com a impressora"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"desconhecido"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – não disponível"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Não foi possível gerar o trabalho de impressão"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Preto e branco"</item>
+    <item msgid="2762241247228983754">"Cor"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Retrato"</item>
+    <item msgid="3199660090246166812">"Paisagem"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Todas"</item>
+    <item msgid="6812869625222503603">"Intervalo"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml
new file mode 100644
index 0000000..79c3bdc
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ro/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Derulator print."</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Setările imprimantei"</string>
+    <string name="print_button" msgid="645164566271246268">"Printați"</string>
+    <string name="save_button" msgid="1921310454071758999">"Salvați"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destinație"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Copii"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Formatul hârtiei"</string>
+    <string name="label_color" msgid="1108690305218188969">"Color"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientare"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Pagini (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"de ex. 1-5, 8, 11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Previzualizați printarea"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Instalați PDF viewer pentru previzualizare"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Aplicația de printare s-a blocat"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Pagini"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Se generează sarcină printare"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Salvați ca PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Toate imprimantele..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Caseta de dialog de printare"</string>
+    <string name="search" msgid="5421724265322228497">"Căutați"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Toate imprimantele"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Adăugați un serviciu"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Caseta de căutare este afișată"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Caseta de căutare este ascunsă"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Adăugați o imprimantă"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Selectați imprimanta"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Omiteți imprimanta"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> imprimantă găsită"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> (de) imprimante găsite"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Alegeți serviciul de printare"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Se caută imprimante"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nu au fost găsite imprimante"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Se printează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Se anulează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Eroare de printare: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printare blocată: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Sarcină de printare <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Sarcini de printare <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Anulați"</string>
+    <string name="restart" msgid="2472034227037808749">"Reporniți"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Nu există conexiune la o imprimantă"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"necunoscut"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - indisponibil"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Nu s-a putut genera sarcina de printare"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Alb-negru"</item>
+    <item msgid="2762241247228983754">"Color"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portret"</item>
+    <item msgid="3199660090246166812">"Peisaj"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Toate"</item>
+    <item msgid="6812869625222503603">"Interval"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml
new file mode 100644
index 0000000..a27f3c8
--- /dev/null
+++ b/packages/PrintSpooler/res/values-ru/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Спулер печати"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Настройки принтера"</string>
+    <string name="print_button" msgid="645164566271246268">"Печать"</string>
+    <string name="save_button" msgid="1921310454071758999">"Сохранить"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Принтер"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Копии"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Формат"</string>
+    <string name="label_color" msgid="1108690305218188969">"Печать"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Ориентация"</string>
+    <string name="label_pages" msgid="6300874667546617333">"СТРАНИЦЫ (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"напр., 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Предварительный просмотр"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Установить средство просмотра PDF"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Сбой приложения печати"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Количество страниц"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Создание задания печати…"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Сохранить как PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Все принтеры"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Диалоговое окно печати"</string>
+    <string name="search" msgid="5421724265322228497">"Поиск"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Все принтеры"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Добавить службу печати"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Окно поиска показано"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Окно поиска скрыто"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Добавить принтер"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Выбрать принтер"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Удалить принтер"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Найден <xliff:g id="COUNT">%1$s</xliff:g> принтер"</item>
+    <item quantity="other" msgid="6533817036607128241">"Найдено принтеров: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Выберите службу печати"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Поиск принтеров…"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Ничего не найдено"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Печать задания \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\"…"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отмена задания <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Ошибка задания \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Задание \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" заблокировано"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Задание печати: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Задания печати: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Отмена"</string>
+    <string name="restart" msgid="2472034227037808749">"Повторить"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Нет связи с принтером"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"неизвестно"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступен"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Не удалось отправить документ на печать."</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Черно-белая"</item>
+    <item msgid="2762241247228983754">"Цветная"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Книга"</item>
+    <item msgid="3199660090246166812">"Альбом"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Все"</item>
+    <item msgid="6812869625222503603">"Диапазон"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml
new file mode 100644
index 0000000..39a022d
--- /dev/null
+++ b/packages/PrintSpooler/res/values-sk/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Zaraďovač tlače"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Nastavenia tlačiarne"</string>
+    <string name="print_button" msgid="645164566271246268">"Tlačiť"</string>
+    <string name="save_button" msgid="1921310454071758999">"Uložiť"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Cieľ"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kópie"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Veľkosť papiera"</string>
+    <string name="label_color" msgid="1108690305218188969">"Farba"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientácia"</string>
+    <string name="label_pages" msgid="6300874667546617333">"STRÁNKY (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"napr. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Ukážka pred tlačou"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Inštalovať zobrazovač PDF na zobrazenie ukážky"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Aplikácia pre tlač zlyhala"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Strany"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Generuje sa tlačová úloha"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Uložiť ako PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Všetky tlačiarne..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Dialógové okno tlače"</string>
+    <string name="search" msgid="5421724265322228497">"VYHĽADÁVANIE"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Všetky tlačiarne"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Pridať službu"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Vyhľadávacie pole sa zobrazuje"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Vyhľadávacie pole je skryté"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Pridať tlačiareň"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Vybrať tlačiareň"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Odstrániť tlačiareň"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Našla sa <xliff:g id="COUNT">%1$s</xliff:g> tlačiareň"</item>
+    <item quantity="other" msgid="6533817036607128241">"Počet nájdených tlačiarní: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Výber tlačovej služby"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Vyhľadávanie tlačiarní"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Nenašli sa žiadne tlačiarne"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Prebieha tlač úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prebieha zrušenie úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Chyba tlačiarne – úloha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Tlačiareň zablok. úlohu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Počet tlačových úloh: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Počet tlačových úloh: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Zrušiť"</string>
+    <string name="restart" msgid="2472034227037808749">"Spustiť znova"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Žiadne pripojenie k tlačiarni"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"neznáme"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nie je k dispozícii"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Tlačovú úlohu nie je možné vytvoriť"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Čiernobiele"</item>
+    <item msgid="2762241247228983754">"Farba"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Na výšku"</item>
+    <item msgid="3199660090246166812">"Na šírku"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Všetky"</item>
+    <item msgid="6812869625222503603">"Rozsah"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml
new file mode 100644
index 0000000..5d4fe94
--- /dev/null
+++ b/packages/PrintSpooler/res/values-sl/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Tisk. v ozadju"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Nastavitve tiskalnika"</string>
+    <string name="print_button" msgid="645164566271246268">"Natisni"</string>
+    <string name="save_button" msgid="1921310454071758999">"Shrani"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Cilj"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Št. kopij"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Velikost papirja"</string>
+    <string name="label_color" msgid="1108690305218188969">"Barvno"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Postavitev"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Št. strani (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"npr. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Predogled tiskanja"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Za predogled namestite pregledovalnik za PDF-je"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Aplikacija za tiskanje se je zrušila"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Št. strani:"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Ustvarjanje zahteve za tisk"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Shrani kot PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Vsi tiskalniki …"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Pogovorno okno za tiskanje"</string>
+    <string name="search" msgid="5421724265322228497">"Iskanje"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Vsi tiskalniki"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Dodaj storitev"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Iskalno polje je prikazano"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Iskalno polje je skrito"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Dodajanje tiskalnika"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Izbira tiskalnika"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Odstranitev tiskalnika"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Najden <xliff:g id="COUNT">%1$s</xliff:g> tiskalnik"</item>
+    <item quantity="other" msgid="6533817036607128241">"Število najdenih tiskalnikov: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Izberite tiskalno storitev"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Iskanje tiskalnikov"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Tiskalnikov ni mogoče najti"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Tiskanje: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Preklic: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Napaka tiskalnika: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Tiskalnik je blokiral <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Tiskalno opravilo: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Tiskalna opravila: <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Prekliči"</string>
+    <string name="restart" msgid="2472034227037808749">"Začni znova"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Ni povezave s tiskalnikom"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"neznano"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ni na voljo"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Tiskalnega opravila ni bilo mogoče ustvariti"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Črno-belo"</item>
+    <item msgid="2762241247228983754">"Barvno"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Navpično"</item>
+    <item msgid="3199660090246166812">"Ležeče"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Vse"</item>
+    <item msgid="6812869625222503603">"Obseg"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml
new file mode 100644
index 0000000..cbab1a6
--- /dev/null
+++ b/packages/PrintSpooler/res/values-sr/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Штамп. из мемор."</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Подешавања штампача"</string>
+    <string name="print_button" msgid="645164566271246268">"Штампај"</string>
+    <string name="save_button" msgid="1921310454071758999">"Сачувај"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Одредиште"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Копије"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Величина папира"</string>
+    <string name="label_color" msgid="1108690305218188969">"Боја"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Положај"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Странице (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"нпр. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Преглед пре штампања"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Инсталирај PDF приказивач за преглед"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Апликација за штампање је отказала"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Странице"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Генерисање задатка за штампање"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Сачувај као PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Сви штампачи…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Дијалог за штампање"</string>
+    <string name="search" msgid="5421724265322228497">"Претражи"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Сви штампачи"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Додај услугу"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Оквир за претрагу је приказан"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Оквир за претрагу је сакривен"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Додај штампач"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Изабери штампач"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Заборави штампач"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Пронађен је <xliff:g id="COUNT">%1$s</xliff:g> штампач"</item>
+    <item quantity="other" msgid="6533817036607128241">"Пронађено је <xliff:g id="COUNT">%1$s</xliff:g> штампача"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Изаберите услугу штампања"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Претрага штампача"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Није пронађен ниједан штампач"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Штампа се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отказује се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка штампача <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Штампач је блокирао <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Задатак штампања <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Задаци штампања <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Откажи"</string>
+    <string name="restart" msgid="2472034227037808749">"Поново покрени"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Нема везе са штампачем"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"непознато"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – недоступан"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Није могуће генерисати задатак за штампање"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Црно-бело"</item>
+    <item msgid="2762241247228983754">"Боја"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Усправно"</item>
+    <item msgid="3199660090246166812">"Водоравно"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Све"</item>
+    <item msgid="6812869625222503603">"Опсег"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml
new file mode 100644
index 0000000..2286fce
--- /dev/null
+++ b/packages/PrintSpooler/res/values-sv/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Utskriftskö"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Skrivarinställningar"</string>
+    <string name="print_button" msgid="645164566271246268">"Skriv ut"</string>
+    <string name="save_button" msgid="1921310454071758999">"Spara"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Destination"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopior"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Pappersstorlek"</string>
+    <string name="label_color" msgid="1108690305218188969">"Färg"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Orientering"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Sidor (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"t.ex. 1–5,8,11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Förhandsgranskning"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Installera PDF-läsare för förhandsgranskning"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Utskriftsappen kraschade"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Sidor"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Genererar utskriftsjobb"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Spara som PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Alla skrivare ..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Dialogrutan Skriv ut"</string>
+    <string name="search" msgid="5421724265322228497">"Sök"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Alla skrivare"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Lägg till tjänst"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Sökrutan visas"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Sökrutan är dold"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Lägg till skrivare"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Välj en skrivare"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Ta bort en skrivare"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> skrivare hittades"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> skrivare hittades"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Välj utskriftstjänst"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Söker efter skrivare"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Det gick inte att hitta några skrivare"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Skrivarfel för <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Skrivaren har blockerat <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Utskriftsjobb – <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Utskriftsjobb – <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Avbryt"</string>
+    <string name="restart" msgid="2472034227037808749">"Starta om"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Ingen anslutning till skrivaren"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"okänt"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – inte tillgänglig"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Det gick inte att skapa utskriftsjobbet"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Svartvit"</item>
+    <item msgid="2762241247228983754">"Färg"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Stående"</item>
+    <item msgid="3199660090246166812">"Liggande"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Alla"</item>
+    <item msgid="6812869625222503603">"Intervall"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml
new file mode 100644
index 0000000..55c8687
--- /dev/null
+++ b/packages/PrintSpooler/res/values-sw/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Programu ya kuandaa Printa kwa ajili ya Kuchapisha"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Mipangilio ya printa"</string>
+    <string name="print_button" msgid="645164566271246268">"Chapisha"</string>
+    <string name="save_button" msgid="1921310454071758999">"Hifadhi"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Itakapofika"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Nakala"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Ukubwa wa Karatasi"</string>
+    <string name="label_color" msgid="1108690305218188969">"Rangi"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Mkao"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Kurasa (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"k.m. 1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Chungulia kwanza kabla ya kuchapisha"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Sakinisha kitazamaji cha PDF kwa onyesho la kuchungulia"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Programu ya kuchapisha imeacha kufanya kazi"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Kurasa"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Inazanzisha kazi ya kuchapisha"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Hifadhi kama PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Printa zote..."</string>
+    <string name="print_dialog" msgid="32628687461331979">"Chapisha mazungumzo"</string>
+    <string name="search" msgid="5421724265322228497">"Tafuta"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Printa zote"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Ongeza huduma"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Kisanduku cha kutafutia kimeonyeshwa"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Kisanduku cha kutafutia kimefichwa"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Ongeza printa"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Chagua printa"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Sahau printa"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Printa <xliff:g id="COUNT">%1$s</xliff:g> imepatikana"</item>
+    <item quantity="other" msgid="6533817036607128241">"Printa <xliff:g id="COUNT">%1$s</xliff:g> zimepatikana"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Chagua huduma ya printa"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Inatafuta printa"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Hakuna printa zilizopatikana"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Inachapisha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Inaghairi <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Hitilafu ya kuchapisha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Printa imefungwa <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Kazi ya kuchapisha ya <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Kazi za kuchapisha za <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Ghairi"</string>
+    <string name="restart" msgid="2472034227037808749">"Anzisha upya"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Hakuna muunganisho kwa printa"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"haijulikani"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - haipatikani"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Haikuweza kuunda kazi ya kuchapisha"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Nyeusi na Nyeupe"</item>
+    <item msgid="2762241247228983754">"Rangi"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Wima"</item>
+    <item msgid="3199660090246166812">"Mlalo"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Zote"</item>
+    <item msgid="6812869625222503603">"Masafa"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml
new file mode 100644
index 0000000..aa01d6f
--- /dev/null
+++ b/packages/PrintSpooler/res/values-th/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"การตั้งค่าเครื่องพิมพ์"</string>
+    <string name="print_button" msgid="645164566271246268">"พิมพ์"</string>
+    <string name="save_button" msgid="1921310454071758999">"บันทึก"</string>
+    <string name="label_destination" msgid="9132510997381599275">"ปลายทาง"</string>
+    <string name="label_copies" msgid="3634531042822968308">"สำเนา"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"ขนาดของกระดาษ"</string>
+    <string name="label_color" msgid="1108690305218188969">"สี"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"การวางแนว"</string>
+    <string name="label_pages" msgid="6300874667546617333">"หน้า (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"เช่น 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"ตัวอย่างก่อนพิมพ์"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"ติดตั้งโปรแกรมดู PDF เพื่อดูหน้าตัวอย่าง"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"แอปการพิมพ์ขัดข้อง"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"หน้า"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"กำลังสร้างงานพิมพ์"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"บันทึกเป็น PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"เครื่องพิมพ์ทั้งหมด…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"ช่องโต้ตอบการพิมพ์"</string>
+    <string name="search" msgid="5421724265322228497">"ค้นหา"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"เครื่องพิมพ์ทั้งหมด"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"เพิ่มบริการ"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"แสดงช่องค้นหาอยู่"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"ซ่อนช่องค้นหาอยู่"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"เพิ่มเครื่องพิมพ์"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"เลือกเครื่องพิมพ์"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"ไม่ต้องจำเครื่องพิมพ์"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"พบเครื่องพิมพ์ <xliff:g id="COUNT">%1$s</xliff:g> เครื่อง"</item>
+    <item quantity="other" msgid="6533817036607128241">"พบเครื่องพิมพ์ <xliff:g id="COUNT">%1$s</xliff:g> เครื่อง"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"เลือกบริการพิมพ์"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"กำลังค้นหาเครื่องพิมพ์"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"ไม่พบเครื่องพิมพ์"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"กำลังพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"กำลังยกเลิก <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"ข้อผิดพลาดเครื่องพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"เครื่องพิมพ์ได้บล็อก <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"งานพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"งานพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"ยกเลิก"</string>
+    <string name="restart" msgid="2472034227037808749">"เริ่มต้นใหม่"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"ไม่มีการเชื่อมต่อไปยังเครื่องพิมพ์"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"ไม่ทราบ"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ไม่พร้อมใช้งาน"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"ไม่สามารถสร้างงานพิมพ์"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"ขาวดำ"</item>
+    <item msgid="2762241247228983754">"สี"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"แนวตั้ง"</item>
+    <item msgid="3199660090246166812">"แนวนอน"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"ทั้งหมด"</item>
+    <item msgid="6812869625222503603">"ช่วง"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml
new file mode 100644
index 0000000..a72c937
--- /dev/null
+++ b/packages/PrintSpooler/res/values-tl/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Mga setting ng printer"</string>
+    <string name="print_button" msgid="645164566271246268">"I-print"</string>
+    <string name="save_button" msgid="1921310454071758999">"I-save"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Patutunguhan"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Mga Kopya"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Laki ng Papel"</string>
+    <string name="label_color" msgid="1108690305218188969">"Kulay"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Oryentasyon"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Mga Pahina (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"hal. 1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Preview sa pag-print"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Mag-install ng PDF viewer para sa pag-preview"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Nag-crash ang app sa pag-print"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Mga Pahina"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Gumagawa ng pag-print"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"I-save bilang PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Lahat ng printer…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Dialog ng pag-print"</string>
+    <string name="search" msgid="5421724265322228497">"Hanapin"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Lahat ng printer"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Magdagdag ng serbisyo"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Ipinapakita ang box para sa paghahanap"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Nakatago ang box para sa paghahanap"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Magdagdag ng printer"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Piliin ang printer"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Kalimutan ang printer"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> printer ang nakita"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> (na) printer ang nakita"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Pumili ng serbisyo ng pag-print"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Naghahanap ng mga printer"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Walang mga printer na nakita"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Pini-print ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kinakansela ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Error sa printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Naka-block ang Printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Pag-print ng <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Mga pag-print ng <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Kanselahin"</string>
+    <string name="restart" msgid="2472034227037808749">"I-restart"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Hindi nakakonekta sa printer"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"hindi alam"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – hindi available"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Hindi mabuo ang pag-print"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Black &amp; White"</item>
+    <item msgid="2762241247228983754">"Kulay"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Portrait"</item>
+    <item msgid="3199660090246166812">"Landscape"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Lahat"</item>
+    <item msgid="6812869625222503603">"Sakop"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml
new file mode 100644
index 0000000..c6e302d
--- /dev/null
+++ b/packages/PrintSpooler/res/values-tr/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Yazıcı ayarları"</string>
+    <string name="print_button" msgid="645164566271246268">"Yazdır"</string>
+    <string name="save_button" msgid="1921310454071758999">"Kaydet"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Hedef"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Kopya sayısı"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Kağıt Boyutu"</string>
+    <string name="label_color" msgid="1108690305218188969">"Renkli"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Sayfa yönü"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Sayfa (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"ör. 1-5,8,11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Yazdırmayı önizle"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Önizlemek için PDF görüntüleyici yükleyin"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Yazdırma uygulaması kilitlendi"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Sayfa"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Yazdırma işi oluşturuluyor"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"PDF olarak kaydet"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Tüm yazıcılar…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Yazdırma iletişim kutusu"</string>
+    <string name="search" msgid="5421724265322228497">"Ara"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Tüm yazıcılar"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Hizmet ekle"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Arama kutusu gösteriliyor"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Arama kutusu gizli"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Yazıcı ekle"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Yazıcı seç"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Yazıcıyı unut"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> yazıcı bulundu"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> yazıcı bulundu"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Yazdırma hizmetini seçin"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Yazıcılar aranıyor"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Yazıcı bulunamadı"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> yazdırılıyor"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> iptal ediliyor"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Yazıcı hatası: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Yazıcı <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> işini engelledi"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> yazdırma işi"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> yazdırma işleri"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"İptal"</string>
+    <string name="restart" msgid="2472034227037808749">"Yeniden başlat"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Yazıcı bağlantısı yok"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"bilinmiyor"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – kullanılamıyor"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Yazdırma işi oluşturulamadı"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Siyah Beyaz"</item>
+    <item msgid="2762241247228983754">"Renkli"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Dikey"</item>
+    <item msgid="3199660090246166812">"Yatay"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Tümü"</item>
+    <item msgid="6812869625222503603">"Aralık"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml
new file mode 100644
index 0000000..4f526d0
--- /dev/null
+++ b/packages/PrintSpooler/res/values-uk/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Налаштування принтера"</string>
+    <string name="print_button" msgid="645164566271246268">"Друк"</string>
+    <string name="save_button" msgid="1921310454071758999">"Зберегти"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Місце признач-ня"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Копії"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Розмір паперу"</string>
+    <string name="label_color" msgid="1108690305218188969">"Колір"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Орієнтація"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Сторінки (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"напр.,1–5, 8, 11–13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Версія для друку"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Установити засіб перегляду PDF"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Програма друку аварійно завершила роботу"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Сторінки"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Створюється завдання друку"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Зберегти як PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Усі принтери…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Діалогове вікно друку"</string>
+    <string name="search" msgid="5421724265322228497">"Пошук"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Усі принтери"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Додати службу"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Вікно пошуку показано"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Вікно пошуку сховано"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Додати принтер"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Вибрати принтер"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Ігнорувати принтер"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Знайдено принтерів: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+    <item quantity="other" msgid="6533817036607128241">"Знайдено принтерів: <xliff:g id="COUNT">%1$s</xliff:g>"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Вибрати службу друку"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Пошук принтерів"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Принтери не знайдено"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" друкується"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" скасовується"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Помилка завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" заблоковано"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Завдання друку <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Завдання друку <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Скасувати"</string>
+    <string name="restart" msgid="2472034227037808749">"Перезапустити"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Немає з’єднання з принтером"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"невідомо"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" не доступне"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Не вдалося створити завдання друку"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Чорно-білий"</item>
+    <item msgid="2762241247228983754">"Колір"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Книжкова"</item>
+    <item msgid="3199660090246166812">"Альбомна"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Усі"</item>
+    <item msgid="6812869625222503603">"Діапазон"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml
new file mode 100644
index 0000000..d21172c
--- /dev/null
+++ b/packages/PrintSpooler/res/values-vi/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Print Spooler"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Cài đặt máy in"</string>
+    <string name="print_button" msgid="645164566271246268">"In"</string>
+    <string name="save_button" msgid="1921310454071758999">"Lưu"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Đích"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Bản sao"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Kích thước trang"</string>
+    <string name="label_color" msgid="1108690305218188969">"Màu"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Hướng"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Trang (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"Ví dụ: 1—5, 8, 11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Xem trước bản in"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Cài đặt trình xem PDF để xem trước"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Ứng dụng in gặp lỗi"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Trang"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Đang tạo lệnh in"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Lưu dưới dạng PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Tất cả máy in…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Hộp thoại in"</string>
+    <string name="search" msgid="5421724265322228497">"Tìm kiếm"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Tất cả máy in"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Thêm dịch vụ"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Hiển thị hộp tìm kiếm"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Ẩn hộp tìm kiếm"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Thêm máy in"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Chọn máy in"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Bỏ qua máy in"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"Đã tìm thấy <xliff:g id="COUNT">%1$s</xliff:g> máy in"</item>
+    <item quantity="other" msgid="6533817036607128241">"Đã tìm thấy <xliff:g id="COUNT">%1$s</xliff:g> máy in"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Chọn dịch vụ in"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Đang tìm kiếm máy in"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Không tìm thấy máy in"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"In <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Hủy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Lỗi máy in <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Máy in đã chặn <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"Lệnh in <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+    <item quantity="other" msgid="8746611264734222865">"Lệnh in <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Hủy"</string>
+    <string name="restart" msgid="2472034227037808749">"Bắt đầu lại"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Không có kết nối nào với máy in"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"không xác định"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – không khả dụng"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Không thể tạo lệnh in"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Đen trắng"</item>
+    <item msgid="2762241247228983754">"Màu"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Dọc"</item>
+    <item msgid="3199660090246166812">"Ngang"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Tất cả"</item>
+    <item msgid="6812869625222503603">"Dãy"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/arrays.xml b/packages/PrintSpooler/res/values-zh-rCN/arrays.xml
deleted file mode 100644
index 4fc75db..0000000
--- a/packages/PrintSpooler/res/values-zh-rCN/arrays.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<resources>
-
-    <string-array name="pdf_printer_media_sizes" translatable="false">
-        <item>ROC_8K</item>
-        <item>ROC_16K</item>
-        <item>PRC_1</item>
-        <item>PRC_2</item>
-        <item>PRC_3</item>
-        <item>PRC_4</item>
-        <item>PRC_5</item>
-        <item>PRC_6</item>
-        <item>PRC_7</item>
-        <item>PRC_8</item>
-        <item>PRC_9</item>
-        <item>PRC_10</item>
-        <item>PRC_16K</item>
-        <item>OM_PA_KAI</item>
-        <item>OM_DAI_PA_KAI</item>
-        <item>OM_JUURO_KU_KAI</item>
-    </string-array>
-
-</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..e43ea60
--- /dev/null
+++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"打印处理服务"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"打印机设置"</string>
+    <string name="print_button" msgid="645164566271246268">"打印"</string>
+    <string name="save_button" msgid="1921310454071758999">"保存"</string>
+    <string name="label_destination" msgid="9132510997381599275">"目的地"</string>
+    <string name="label_copies" msgid="3634531042822968308">"份数"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"纸张尺寸"</string>
+    <string name="label_color" msgid="1108690305218188969">"颜色"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
+    <string name="label_pages" msgid="6300874667546617333">"页数 (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"例如:1-5、8、11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"打印预览"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"安装 PDF 查看器以便预览"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"打印应用崩溃了"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"页数"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"正在生成打印作业"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"保存为 PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"所有打印机…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"打印对话框"</string>
+    <string name="search" msgid="5421724265322228497">"搜索"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"所有打印机"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"添加服务"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"搜索框已显示"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"搜索框已隐藏"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"添加打印机"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"选择打印机"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"取消保存打印机"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"找到<xliff:g id="COUNT">%1$s</xliff:g>台打印机"</item>
+    <item quantity="other" msgid="6533817036607128241">"找到<xliff:g id="COUNT">%1$s</xliff:g>台打印机"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"选择打印服务"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜索打印机"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"找不到打印机"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"正在打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"打印机在打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”时出错"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"打印机拒绝打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"“<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>”打印作业"</item>
+    <item quantity="other" msgid="8746611264734222865">"“<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g>”打印作业"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"取消"</string>
+    <string name="restart" msgid="2472034227037808749">"重新开始"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"未与打印机建立连接"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"未知"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> - 无法使用"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"无法生成打印作业"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"黑白"</item>
+    <item msgid="2762241247228983754">"彩色"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"纵向"</item>
+    <item msgid="3199660090246166812">"横向"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"全部"</item>
+    <item msgid="6812869625222503603">"范围"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..2c2422a9
--- /dev/null
+++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"列印多工緩衝處理器"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"打印機設定"</string>
+    <string name="print_button" msgid="645164566271246268">"列印"</string>
+    <string name="save_button" msgid="1921310454071758999">"儲存"</string>
+    <string name="label_destination" msgid="9132510997381599275">"目的地"</string>
+    <string name="label_copies" msgid="3634531042822968308">"份數"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"紙張大小"</string>
+    <string name="label_color" msgid="1108690305218188969">"顏色"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
+    <string name="label_pages" msgid="6300874667546617333">"頁數 (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"例如:1-5,8,11-13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"預覽列印"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"安裝預覽所需的 PDF 檢視器"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"列印應用程式當機了"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"頁數"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"正在產生列印工作"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"儲存為 PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"所有打印機…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"列印對話方塊"</string>
+    <string name="search" msgid="5421724265322228497">"搜尋"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"所有打印機"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"新增服務"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"搜尋框已顯示"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"搜尋框已隱藏"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"新增打印機"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"選取打印機"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"移除打印機"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"找到 <xliff:g id="COUNT">%1$s</xliff:g> 部打印機"</item>
+    <item quantity="other" msgid="6533817036607128241">"找到 <xliff:g id="COUNT">%1$s</xliff:g> 部打印機"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"選擇列印服務"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜尋打印機"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"找不到打印機"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"打印機錯誤:<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"打印機已封鎖 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"一項 <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> 列印工作"</item>
+    <item quantity="other" msgid="8746611264734222865">"多項 <xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> 列印工作"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"取消"</string>
+    <string name="restart" msgid="2472034227037808749">"重新開始"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與打印機連線"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"無法產生列印工作"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"黑白"</item>
+    <item msgid="2762241247228983754">"彩色"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"直向"</item>
+    <item msgid="3199660090246166812">"橫向"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"全部"</item>
+    <item msgid="6812869625222503603">"範圍"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..0fe88d9
--- /dev/null
+++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"列印多工緩衝處理器"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"印表機設定"</string>
+    <string name="print_button" msgid="645164566271246268">"列印"</string>
+    <string name="save_button" msgid="1921310454071758999">"儲存"</string>
+    <string name="label_destination" msgid="9132510997381599275">"目的地"</string>
+    <string name="label_copies" msgid="3634531042822968308">"份數"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"紙張大小"</string>
+    <string name="label_color" msgid="1108690305218188969">"色彩"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"方向"</string>
+    <string name="label_pages" msgid="6300874667546617333">"頁數 (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"例如:1—5,8,11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"列印預覽"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"安裝預覽所需的 PDF 檢視器"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"列印應用程式當機了"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"頁數"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"正在產生列印工作"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"儲存為 PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"所有印表機…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"印表機對話方塊"</string>
+    <string name="search" msgid="5421724265322228497">"搜尋"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"所有印表機"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"新增服務"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"搜尋框已顯示"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"搜尋框已隱藏"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"新增印表機"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"選取印表機"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"移除印表機"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"找到 <xliff:g id="COUNT">%1$s</xliff:g> 台印表機"</item>
+    <item quantity="other" msgid="6533817036607128241">"找到 <xliff:g id="COUNT">%1$s</xliff:g> 台印表機"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"選擇列印服務"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜尋印表機"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"找不到印表機"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"印表機發生錯誤:<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"印表機封鎖了 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> 個列印工作"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> 個列印工作"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"取消"</string>
+    <string name="restart" msgid="2472034227037808749">"重新開始"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"尚未與印表機建立連線"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"不明"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – 無法使用"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"無法產生列印工作"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"黑白"</item>
+    <item msgid="2762241247228983754">"彩色"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"縱向"</item>
+    <item msgid="3199660090246166812">"橫向"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"全部"</item>
+    <item msgid="6812869625222503603">"範圍"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml
new file mode 100644
index 0000000..08e31e1
--- /dev/null
+++ b/packages/PrintSpooler/res/values-zu/strings.xml
@@ -0,0 +1,79 @@
+<?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="4469836075319831821">"Ispuli sephrinta"</string>
+    <string name="advanced_settings_button" msgid="5764225091289415632">"Izilungiselelo zephrinta"</string>
+    <string name="print_button" msgid="645164566271246268">"Phrinta"</string>
+    <string name="save_button" msgid="1921310454071758999">"Londoloza"</string>
+    <string name="label_destination" msgid="9132510997381599275">"Indawo"</string>
+    <string name="label_copies" msgid="3634531042822968308">"Amakhophi"</string>
+    <string name="label_paper_size" msgid="8681895607876809323">"Usayizi wephepha"</string>
+    <string name="label_color" msgid="1108690305218188969">"Umbala"</string>
+    <string name="label_orientation" msgid="2853142581990496477">"Umumo"</string>
+    <string name="label_pages" msgid="6300874667546617333">"Amakhasi (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string>
+    <string name="pages_range_example" msgid="8558694453556945172">"isb. 1—5, 8, 11—13"</string>
+    <string name="print_preview" msgid="8010217796057763343">"Ukubuka kuqala kokuphrinta"</string>
+    <string name="install_for_print_preview" msgid="6366303997385509332">"Faka isibukeli se-PDF ukuze uhlole kuqala"</string>
+    <string name="printing_app_crashed" msgid="854477616686566398">"Ukuphrinta uhlelo lokusebenza kukhubazekile"</string>
+    <string name="page_count_unknown" msgid="6058852665954511124">"Amakhasi"</string>
+    <string name="generating_print_job" msgid="3119608742651698916">"Ikhiqiza umsebenzi wokuphrinta"</string>
+    <string name="save_as_pdf" msgid="5718454119847596853">"Londoloza njenge-PDF"</string>
+    <string name="all_printers" msgid="5018829726861876202">"Wonke amaphrinta…"</string>
+    <string name="print_dialog" msgid="32628687461331979">"Ingxoxo yokuphrinta"</string>
+    <string name="search" msgid="5421724265322228497">"Sesha"</string>
+    <string name="all_printers_label" msgid="3178848870161526399">"Wonke amaphrinta"</string>
+    <string name="add_print_service_label" msgid="5356702546188981940">"Engeza isevisi"</string>
+    <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Ibhokisi lokuhlola libonisiwe"</string>
+    <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Ibhokisi lokusesha lifihliwe"</string>
+    <string name="print_add_printer" msgid="1088656468360653455">"Engeza iphrinta"</string>
+    <string name="print_select_printer" msgid="7388760939873368698">"Khetha iphrinta"</string>
+    <string name="print_forget_printer" msgid="5035287497291910766">"Khohlwa iphrinta"</string>
+  <plurals name="print_search_result_count_utterance">
+    <item quantity="one" msgid="4484953260685964252">"<xliff:g id="COUNT">%1$s</xliff:g> iphrinta itholiwe"</item>
+    <item quantity="other" msgid="6533817036607128241">"<xliff:g id="COUNT">%1$s</xliff:g> amaphrinta atholiwe"</item>
+  </plurals>
+    <string name="choose_print_service" msgid="3740309762324459694">"Khetha isevisi yephrinta"</string>
+    <string name="print_searching_for_printers" msgid="6550424555079932867">"Isesha amaphrinta"</string>
+    <string name="print_no_printers" msgid="4869403323900054866">"Awekho amaphrinta atholiwe"</string>
+    <string name="printing_notification_title_template" msgid="295903957762447362">"Iphrinta i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ikhansela i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"Iphutha lephrinta ye-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="blocked_notification_title_template" msgid="1175435827331588646">"Iphrinta engu-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ivinjelwe"</string>
+  <plurals name="composite_notification_title_template">
+    <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> umsebenzi wokuphrinta"</item>
+    <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> imisebenzi yokuphrinta"</item>
+  </plurals>
+    <string name="cancel" msgid="4373674107267141885">"Khansela"</string>
+    <string name="restart" msgid="2472034227037808749">"Qala kabusha"</string>
+    <string name="no_connection_to_printer" msgid="2159246915977282728">"Akukho ukuxhumana kuphrinta"</string>
+    <string name="reason_unknown" msgid="5507940196503246139">"akwaziwa"</string>
+    <string name="printer_unavailable" msgid="2434170617003315690">"I-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – ayitholakali"</string>
+    <string name="print_error_default_message" msgid="8568506918983980567">"Ayikwazanga ukukhiqiza umsebenzi wokuphrinta"</string>
+  <string-array name="color_mode_labels">
+    <item msgid="7602948745415174937">"Okumnyama nokumhlophe"</item>
+    <item msgid="2762241247228983754">"Umbala"</item>
+  </string-array>
+  <string-array name="orientation_labels">
+    <item msgid="4061931020926489228">"Ukuma ngobude"</item>
+    <item msgid="3199660090246166812">"Ukwakheka kwezwe"</item>
+  </string-array>
+  <string-array name="page_options_labels">
+    <item msgid="7421377442011699994">"Konke"</item>
+    <item msgid="6812869625222503603">"Ibanga"</item>
+  </string-array>
+</resources>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
index f6008d4..e3d8d05 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/PrintJobConfigActivity.java
@@ -454,7 +454,11 @@
                 return;
             }
 
-            mControllerState = CONTROLLER_STATE_LAYOUT_COMPLETED;
+            final int oldControllerState = mControllerState;
+
+            if (mControllerState == CONTROLLER_STATE_LAYOUT_STARTED) {
+                mControllerState = CONTROLLER_STATE_LAYOUT_COMPLETED;
+            }
 
             // For layout purposes we care only whether the type or the page
             // count changed. We still do not have the size since we did not
@@ -477,6 +481,8 @@
                         mPrintJobId, null);
             }
 
+            PageRange[] oldRequestedPages = mRequestedPages;
+
             // 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
@@ -504,14 +510,21 @@
                 }
             }
 
-            // If the info and the layout did not change and we already have
-            // the requested pages, then nothing else to do.
+            // If the info and the layout did not change...
             if (!infoChanged && !layoutChanged
-                    && PageRangeUtils.contains(mDocument.pages, mRequestedPages)) {
+                    // and we have the requested pages ... 
+                    && (PageRangeUtils.contains(mDocument.pages, mRequestedPages))
+                        // ...or the requested pages are being written...
+                        || (oldControllerState == CONTROLLER_STATE_WRITE_STARTED
+                            && oldRequestedPages != null
+                            && PageRangeUtils.contains(oldRequestedPages, mRequestedPages))) {
                 // Nothing interesting changed and we have all requested pages.
                 // Then update the print jobs's pages as we will not do a write
                 // and we usually update the pages in the write complete callback.
-                updatePrintJobPages(mDocument.pages, mRequestedPages);
+                if (mDocument.pages != null) {
+                    // Update the print job's pages given we have them.
+                    updatePrintJobPages(mDocument.pages, mRequestedPages);
+                }
                 mEditor.updateUi();
                 if (mEditor.isDone()) {
                     requestCreatePdfFileOrFinish();
@@ -616,7 +629,9 @@
                 // We did not get the pages we requested, then the application
                 // misbehaves, so we fail quickly.
                 mControllerState = CONTROLLER_STATE_FAILED;
-                Log.e(LOG_TAG, "Received invalid pages from the app");
+                Log.e(LOG_TAG, "Received invalid pages from the app: requested="
+                        + Arrays.toString(requestedPages) + " written="
+                        + Arrays.toString(writtenPages));
                 mEditor.showUi(Editor.UI_ERROR, null);
             }
         }
@@ -1276,7 +1291,7 @@
                     // 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) {
+                    if (!mFavoritePrinterSelected && mDestinationSpinnerAdapter.getCount() > 1) {
                         mFavoritePrinterSelected = true;
                         mDestinationSpinner.setSelection(0);
                         // Workaround again the weird spinner behavior to notify for selection
@@ -1350,6 +1365,7 @@
 
                                 if (mCurrentPrinter.getCapabilities() == null) {
                                     if (printer.getCapabilities() != null) {
+                                        updatePrintAttributes(printer.getCapabilities());
                                         capabilitiesChanged = true;
                                     }
                                 } else if (!mCurrentPrinter.getCapabilities().equals(
diff --git a/packages/SettingsProvider/res/values-az-rAZ/strings.xml b/packages/SettingsProvider/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..a4d0d43
--- /dev/null
+++ b/packages/SettingsProvider/res/values-az-rAZ/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">"Parametrlər Deposu"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-az/strings.xml b/packages/SettingsProvider/res/values-az/strings.xml
new file mode 100644
index 0000000..a4d0d43
--- /dev/null
+++ b/packages/SettingsProvider/res/values-az/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">"Parametrlər Deposu"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-be/strings.xml b/packages/SettingsProvider/res/values-be/strings.xml
deleted file mode 100644
index c164ac7..0000000
--- a/packages/SettingsProvider/res/values-be/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_label" msgid="4567566098528588863">"Захоўванне налад"</string>
-</resources>
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/strings.xml b/packages/SettingsProvider/res/values-et-rEE/strings.xml
similarity index 100%
rename from packages/SettingsProvider/res/values-et/strings.xml
rename to packages/SettingsProvider/res/values-et-rEE/strings.xml
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/strings.xml b/packages/SettingsProvider/res/values-ms-rMY/strings.xml
similarity index 100%
rename from packages/SettingsProvider/res/values-ms/strings.xml
rename to packages/SettingsProvider/res/values-ms-rMY/strings.xml
diff --git a/packages/SettingsProvider/res/values-ne-rNP/strings.xml b/packages/SettingsProvider/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..af6ef62
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ne-rNP/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-ne/strings.xml b/packages/SettingsProvider/res/values-ne/strings.xml
new file mode 100644
index 0000000..af6ef62
--- /dev/null
+++ b/packages/SettingsProvider/res/values-ne/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-si-rLK/strings.xml b/packages/SettingsProvider/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..24ef798
--- /dev/null
+++ b/packages/SettingsProvider/res/values-si-rLK/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-si/strings.xml b/packages/SettingsProvider/res/values-si/strings.xml
new file mode 100644
index 0000000..24ef798
--- /dev/null
+++ b/packages/SettingsProvider/res/values-si/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-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/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index da3ca0f..59b486f 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -174,7 +174,19 @@
          >0 is milliseconds of screen-off time after which battery sounds will not play -->
     <integer name="def_low_battery_sound_timeout">0</integer>
 
+    <!-- Initial value for the Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS setting,
+         which is a comma separated list of packages that no longer need confirmation
+         for immersive mode.
+         Override to disable immersive mode confirmation for certain packages. -->
+    <string name="def_immersive_mode_confirmations" translatable="false"></string>
+
     <!-- Default for Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE -->
     <integer name="def_wifi_scan_always_available">0</integer>
 
+    <!-- Default for Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1==on -->
+    <integer name="def_lock_screen_show_notifications">1</integer>
+
+    <!-- Default for Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED, 1==on -->
+    <integer name="def_heads_up_enabled">1</integer>
+
 </resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index ed86f42..58086c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -39,13 +39,10 @@
 import android.provider.Settings;
 import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
-import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.internal.content.PackageHelper;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.util.XmlUtils;
@@ -72,7 +69,7 @@
     // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
     // is properly propagated through your change.  Not doing so will result in a loss of user
     // settings.
-    private static final int DATABASE_VERSION = 98;
+    private static final int DATABASE_VERSION = 101;
 
     private Context mContext;
     private int mUserHandle;
@@ -1559,6 +1556,64 @@
             upgradeVersion = 98;
         }
 
+        if (upgradeVersion == 98) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                            R.integer.def_lock_screen_show_notifications);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 99;
+        }
+
+        if (upgradeVersion == 99) {
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR REPLACE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                            R.integer.def_heads_up_enabled);
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 100;
+        }
+        if (upgradeVersion == 100) {
+           // Catch devices that were initialized to version 100 and missed these in onCreate()
+            if (mUserHandle == UserHandle.USER_OWNER) {
+                db.beginTransaction();
+                SQLiteStatement stmt = null;
+                try {
+                    stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)"
+                            + " VALUES(?,?);");
+                    loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                            R.integer.def_lock_screen_show_notifications);
+
+                    loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                            R.integer.def_heads_up_enabled);
+
+                    db.setTransactionSuccessful();
+                } finally {
+                    db.endTransaction();
+                    if (stmt != null) stmt.close();
+                }
+            }
+            upgradeVersion = 101;
+        }
+
         // *** Remember to update DATABASE_VERSION above!
 
         if (upgradeVersion != currentVersion) {
@@ -2114,6 +2169,10 @@
 
             loadBooleanSetting(stmt, Settings.Secure.USER_SETUP_COMPLETE,
                     R.bool.def_user_setup_complete);
+
+            loadStringSetting(stmt, Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
+                        R.string.def_immersive_mode_confirmations);
+
         } finally {
             if (stmt != null) stmt.close();
         }
@@ -2277,6 +2336,12 @@
             loadIntegerSetting(stmt, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
                     R.integer.def_wifi_scan_always_available);
 
+            loadIntegerSetting(stmt, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                    R.integer.def_lock_screen_show_notifications);
+
+            loadIntegerSetting(stmt, Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                    R.integer.def_heads_up_enabled);
+
             // --- New global settings start here
         } finally {
             if (stmt != null) stmt.close();
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index 7b09092..45957a4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -422,7 +422,11 @@
         // If we have wifi data to restore, post a runnable to perform the
         // bounce-and-update operation a little ways in the future.
         if (mWifiRestore != null) {
-            new Handler(getMainLooper()).postDelayed(mWifiRestore, WIFI_BOUNCE_DELAY_MILLIS);
+            long wifiBounceDelayMillis = Settings.Global.getLong(
+                    getContentResolver(),
+                    Settings.Global.WIFI_BOUNCE_DELAY_OVERRIDE_MS,
+                    WIFI_BOUNCE_DELAY_MILLIS);
+            new Handler(getMainLooper()).postDelayed(mWifiRestore, wifiBounceDelayMillis);
         }
     }
 
diff --git a/packages/Shell/res/values-az-rAZ/strings.xml b/packages/Shell/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..da08e38
--- /dev/null
+++ b/packages/Shell/res/values-az-rAZ/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">"Baq raport alındı"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Xətanı şikayətini paylaşmaq üçün toxunun"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Baq raportları sistemin müxtəlif jurnal fayllarından data içərir ki, buna şəxsi və konfidensial məlumatlar da aiddir. Yalnız inandığınız adamlarla baq raportlarını paylaşın."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bu mesajı növbəti dəfə göstər"</string>
+</resources>
diff --git a/packages/Shell/res/values-az/strings.xml b/packages/Shell/res/values-az/strings.xml
new file mode 100644
index 0000000..da08e38
--- /dev/null
+++ b/packages/Shell/res/values-az/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">"Baq raport alındı"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Xətanı şikayətini paylaşmaq üçün toxunun"</string>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Baq raportları sistemin müxtəlif jurnal fayllarından data içərir ki, buna şəxsi və konfidensial məlumatlar da aiddir. Yalnız inandığınız adamlarla baq raportlarını paylaşın."</string>
+    <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bu mesajı növbəti dəfə göstər"</string>
+</resources>
diff --git a/packages/Shell/res/values-be/strings.xml b/packages/Shell/res/values-be/strings.xml
deleted file mode 100644
index e713975..0000000
--- a/packages/Shell/res/values-be/strings.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-  
-          http://www.apache.org/licenses/LICENSE-2.0
-  
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<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-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml
index effdcb9..3f1c921 100644
--- a/packages/Shell/res/values-cs/strings.xml
+++ b/packages/Shell/res/values-cs/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="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">"Zprávy o chybách obsahují data z různých souborů protokolů systému včetně osobních a soukromých informací. Zprávy o chybách sdílejte pouze s aplikacemi a uživateli, kterým důvěřujete."</string>
+    <string name="bugreport_finished_title" msgid="2293711546892863898">"Bylo vytvořeno chybové hlášení"</string>
+    <string name="bugreport_finished_text" msgid="3559904746859400732">"Chybové hlášení 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
index 01ea42b..fa30c96 100644
--- a/packages/Shell/res/values-da/strings.xml
+++ b/packages/Shell/res/values-da/strings.xml
@@ -19,6 +19,6 @@
     <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>
+    <string name="bugreport_confirm" msgid="5130698467795669780">"Fejlrapporter indeholder data fra systemets forskellige logfiler, f.eks. 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 underretning næste gang"</string>
 </resources>
diff --git a/packages/Shell/res/values-el/strings.xml b/packages/Shell/res/values-el/strings.xml
index 3669f78..9b1eb7b 100644
--- a/packages/Shell/res/values-el/strings.xml
+++ b/packages/Shell/res/values-el/strings.xml
@@ -18,7 +18,7 @@
     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_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-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-et/strings.xml b/packages/Shell/res/values-et-rEE/strings.xml
similarity index 100%
rename from packages/Shell/res/values-et/strings.xml
rename to packages/Shell/res/values-et-rEE/strings.xml
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-hi/strings.xml b/packages/Shell/res/values-hi/strings.xml
index 4ea0664..f889311 100644
--- a/packages/Shell/res/values-hi/strings.xml
+++ b/packages/Shell/res/values-hi/strings.xml
@@ -19,6 +19,6 @@
     <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" msgid="5130698467795669780">"बग रिपोर्ट में व्यक्तिगत और निजी जानकारी सहित, सिस्टम की विभिन्न लॉग फ़ाइलों का डेटा होता है. बग रिपोर्ट केवल विश्वसनीय ऐप्स  और व्यक्तियों से ही साझा करें."</string>
     <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"यह संदेश अगली बार दिखाएं"</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-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml
index e7715e9..ded860c 100644
--- a/packages/Shell/res/values-iw/strings.xml
+++ b/packages/Shell/res/values-iw/strings.xml
@@ -19,6 +19,6 @@
     <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" 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-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-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/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml
similarity index 100%
rename from packages/Shell/res/values-ms/strings.xml
rename to packages/Shell/res/values-ms-rMY/strings.xml
diff --git a/packages/Shell/res/values-ne-rNP/strings.xml b/packages/Shell/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..cf09433
--- /dev/null
+++ b/packages/Shell/res/values-ne-rNP/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-ne/strings.xml b/packages/Shell/res/values-ne/strings.xml
new file mode 100644
index 0000000..cf09433
--- /dev/null
+++ b/packages/Shell/res/values-ne/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-si-rLK/strings.xml b/packages/Shell/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..0780789
--- /dev/null
+++ b/packages/Shell/res/values-si-rLK/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-si/strings.xml b/packages/Shell/res/values-si/strings.xml
new file mode 100644
index 0000000..0780789
--- /dev/null
+++ b/packages/Shell/res/values-si/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-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/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 8d6fe41..b09cc1d 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -52,6 +52,7 @@
     <uses-permission android:name="android.permission.START_ANY_ACTIVITY" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
     <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" />
+    <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
 
     <!-- WindowManager -->
     <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
@@ -140,6 +141,18 @@
             </intent-filter>
         </receiver>
 
+        <!-- Alternate Recents -->
+        <activity android:name=".recents.RecentsActivity"
+                  android:launchMode="singleInstance"
+                  android:excludeFromRecents="true"
+                  android:theme="@style/RecentsTheme">
+            <intent-filter>
+                <action android:name="com.android.systemui.recents.TOGGLE_RECENTS" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".recents.RecentsService" />
+
         <!-- started from UsbDeviceSettingsManager -->
         <activity android:name=".usb.UsbConfirmActivity"
             android:exported="true"
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 1ff93d2..48d9722 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -6,6 +6,11 @@
   public void setGlowAlpha(float);
   public void setGlowScale(float);
 }
+-keep class com.android.systemui.recents.views.TaskIconView {
+	public void setCircularClipRadius(float);
+	public float getCircularClipRadius();
+}
 
 -keep class com.android.systemui.statusbar.phone.PhoneStatusBar
 -keep class com.android.systemui.statusbar.tv.TvStatusBar
+-keep class com.android.systemui.recents.*
\ No newline at end of file
diff --git a/packages/SystemUI/res/anim/heads_up_exit.xml b/packages/SystemUI/res/anim/heads_up_exit.xml
index 05c144a..2cad8f6 100644
--- a/packages/SystemUI/res/anim/heads_up_exit.xml
+++ b/packages/SystemUI/res/anim/heads_up_exit.xml
@@ -1,13 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <set xmlns:android="http://schemas.android.com/apk/res/android"
         >
-    <scale
-        android:interpolator="@android:interpolator/accelerate_quad"
-        android:fromXScale="1.0" android:toXScale="0.7"
-        android:fromYScale="1.0" android:toYScale="0.7"
-        android:pivotX="50%" android:pivotY="50%"
-        android:duration="@android:integer/config_shortAnimTime" />
-    <alpha 
+    <translate
+            android:interpolator="@android:interpolator/overshoot"
+            android:fromYDelta="0" android:toYDelta="-50%"
+            android:duration="@android:integer/config_shortAnimTime" />
+    <alpha
         android:interpolator="@android:interpolator/accelerate_quad"
         android:fromAlpha="1.0" android:toAlpha="0.0"
         android:duration="@android:integer/config_shortAnimTime" />
diff --git a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml b/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
deleted file mode 100644
index 5b6778e..0000000
--- a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/res/anim/ease_out_interpolator.xml
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
--->
-
-<decelerateInterpolator 
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:factor="10.0" />
diff --git a/packages/SystemUI/res/anim/lights_out_in.xml b/packages/SystemUI/res/anim/lights_out_in.xml
deleted file mode 100644
index f76a452..0000000
--- a/packages/SystemUI/res/anim/lights_out_in.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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromYDelta="-100%p" android:toYDelta="0"
-        android:duration="@android:integer/config_mediumAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:fromAlpha="0.5" android:toAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/lights_out_out.xml b/packages/SystemUI/res/anim/lights_out_out.xml
deleted file mode 100644
index 610ac7a..0000000
--- a/packages/SystemUI/res/anim/lights_out_out.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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toYDelta="-100%p" android:fromYDelta="0" 
-        android:duration="@android:integer/config_mediumAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-    <alpha android:toAlpha="0.5" android:fromAlpha="1.0"
-        android:duration="@android:integer/config_longAnimTime" 
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/notification_dnd_off.xml b/packages/SystemUI/res/anim/notification_dnd_off.xml
deleted file mode 100644
index 4e88855..0000000
--- a/packages/SystemUI/res/anim/notification_dnd_off.xml
+++ /dev/null
@@ -1,23 +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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:fromXDelta="100%p" android:toXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/notification_dnd_on.xml b/packages/SystemUI/res/anim/notification_dnd_on.xml
deleted file mode 100644
index 309943b..0000000
--- a/packages/SystemUI/res/anim/notification_dnd_on.xml
+++ /dev/null
@@ -1,23 +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.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
-    >
-    <translate android:toXDelta="100%p" android:fromXDelta="0"
-        android:duration="@android:integer/config_longAnimTime" 
-        android:interpolator="@anim/hydraulic_brake_interpolator"
-        />
-</set>
diff --git a/packages/SystemUI/res/anim/recents_from_launcher_enter.xml b/packages/SystemUI/res/anim/recents_from_launcher_enter.xml
new file mode 100644
index 0000000..4bd7e82
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_from_launcher_enter.xml
@@ -0,0 +1,28 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:zAdjustment="top">
+  <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+         android:fillEnabled="true"
+         android:fillBefore="true" android:fillAfter="true"
+         android:interpolator="@android:interpolator/accelerate_cubic"
+         android:duration="250"/>
+</set>
diff --git a/packages/SystemUI/res/anim/recents_from_launcher_exit.xml b/packages/SystemUI/res/anim/recents_from_launcher_exit.xml
new file mode 100644
index 0000000..becc9d0
--- /dev/null
+++ b/packages/SystemUI/res/anim/recents_from_launcher_exit.xml
@@ -0,0 +1,28 @@
+<?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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:shareInterpolator="false"
+     android:zAdjustment="normal">
+  <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+         android:fillEnabled="true"
+         android:fillBefore="true" android:fillAfter="true"
+         android:interpolator="@android:interpolator/decelerate_cubic"
+         android:duration="250"/>
+</set>
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
deleted file mode 100644
index 3b952d0..0000000
--- a/packages/SystemUI/res/drawable-hdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-hdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-hdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-hdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-hdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..fe6dc52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..0f9dfc7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..aea75c1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-hdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..267e7ba
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..fa23e85
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..aa8635c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_zen_limited.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..46d2a16
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..704b4ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..d56efb5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-ldpi/ic_qs_inversion_alpha.png
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
deleted file mode 100644
index a0ab991..0000000
--- a/packages/SystemUI/res/drawable-mdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-mdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-mdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-mdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-mdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..18b6029
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..a4dd087
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..b6ea14e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-mdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..db51f6b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..b0185a5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..949ab10
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/stat_sys_zen_limited.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png
new file mode 100644
index 0000000..b30cf15
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.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
index 6002cfb..31eb8f7 100644
--- 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
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
index 586a738..c76d0e1 100644
--- 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
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
deleted file mode 100644
index 42e5593..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_activated.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_action_assist_generic_normal.png b/packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-xhdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..95cf67f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..9331e52
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..efd8b9e
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-xhdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..8d22ce2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..7f7cb63
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..abdeb3b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/stat_sys_zen_limited.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
deleted file mode 100644
index 586a738..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_action_assist_generic_activated.png b/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_action_assist_generic_activated.png
rename to packages/SystemUI/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/packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
rename to packages/SystemUI/res/drawable-xxhdpi/ic_action_assist_generic_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/ic_lockscreen_glowdot.png b/packages/SystemUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
similarity index 100%
rename from core/res/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
rename to packages/SystemUI/res/drawable-xxhdpi/ic_lockscreen_glowdot.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png
new file mode 100644
index 0000000..7f441c8
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_color_space_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png
new file mode 100644
index 0000000..82c3842
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_contrast_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png
new file mode 100644
index 0000000..ce9bae2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_inversion_alpha.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/spinner_default_holo_dark_am_no_underline.9.png b/packages/SystemUI/res/drawable-xxhdpi/spinner_default_holo_dark_am_no_underline.9.png
new file mode 100644
index 0000000..29fb50f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/spinner_default_holo_dark_am_no_underline.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_full.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_full.png
new file mode 100644
index 0000000..afe85b4
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_full.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_limited.png b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_limited.png
new file mode 100644
index 0000000..5e5053f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/stat_sys_zen_limited.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml b/packages/SystemUI/res/drawable/heads_up_notification_row_bg.xml
deleted file mode 100644
index 59d9fcf..0000000
--- a/packages/SystemUI/res/drawable/heads_up_notification_row_bg.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.
--->
-
-<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/core/res/res/drawable/ic_action_assist_generic.xml b/packages/SystemUI/res/drawable/ic_action_assist_generic.xml
similarity index 100%
rename from core/res/res/drawable/ic_action_assist_generic.xml
rename to packages/SystemUI/res/drawable/ic_action_assist_generic.xml
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml b/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml
new file mode 100644
index 0000000..cf34ba6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_color_space_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_qs_color_space_alpha"
+    android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml b/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml
new file mode 100644
index 0000000..1806688
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_color_space_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_qs_color_space_alpha"
+    android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml b/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml
new file mode 100644
index 0000000..5f65d8a
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_contrast_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_qs_contrast_alpha"
+    android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml b/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml
new file mode 100644
index 0000000..a018929
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_contrast_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_qs_contrast_alpha"
+    android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
new file mode 100644
index 0000000..9018a90
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_off.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_qs_inversion_alpha"
+    android:tint="@color/ic_qs_off" />
diff --git a/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
new file mode 100644
index 0000000..9110201
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_qs_inversion_on.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_qs_inversion_alpha"
+    android:tint="@color/ic_qs_on" />
diff --git a/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml b/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml
new file mode 100644
index 0000000..4ac67c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notification_icon_legacy_bg.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <solid
+            android:color="@color/notification_icon_legacy_bg_color"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml b/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml
new file mode 100644
index 0000000..96c5573
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notification_icon_legacy_bg_inset.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2014 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:drawable="@drawable/notification_icon_legacy_bg" android:insetBottom="8dp"
+       android:insetLeft="8dp" android:insetRight="8dp" android:insetTop="8dp"
+       android:visible="true"/>
diff --git a/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml b/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
index 0e1bdd3..ce3372e 100644
--- a/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_row_legacy_bg.xml
@@ -17,6 +17,6 @@
 <selector xmlns:android="http://schemas.android.com/apk/res/android"
         android:exitFadeDuration="@android:integer/config_mediumAnimTime">
 
-    <item android:state_pressed="true"  android:drawable="@*android:drawable/notification_item_background_color_pressed" />
+    <item android:state_pressed="true"  android:drawable="@drawable/notification_item_background_color_pressed" />
     <item android:state_pressed="false" android:drawable="@drawable/notification_item_background_legacy_color" />
 </selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_item_background.xml b/packages/SystemUI/res/drawable/status_bar_item_background.xml
index b82fed9..3a50aa9 100644
--- a/packages/SystemUI/res/drawable/status_bar_item_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_item_background.xml
@@ -19,7 +19,7 @@
     android:opacity="translucent"
     >
     <item
-        android:drawable="@*android:drawable/notification_item_background_color"
+        android:drawable="@drawable/notification_item_background_color"
         />
 </layer-list>
 
diff --git a/packages/SystemUI/res/drawable/status_bar_ticker_background.xml b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
deleted file mode 100644
index 7cb64c0..0000000
--- a/packages/SystemUI/res/drawable/status_bar_ticker_background.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="@*android:drawable/notify_panel_notification_icon_bg"
-    />
diff --git a/packages/SystemUI/res/drawable/system_bar_ticker_background.xml b/packages/SystemUI/res/drawable/system_bar_ticker_background.xml
deleted file mode 100644
index 7cb64c0..0000000
--- a/packages/SystemUI/res/drawable/system_bar_ticker_background.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="@*android:drawable/notify_panel_notification_icon_bg"
-    />
diff --git a/packages/SystemUI/res/drawable/ticker_background.xml b/packages/SystemUI/res/drawable/ticker_background.xml
index 07b44ca..7320fa0 100644
--- a/packages/SystemUI/res/drawable/ticker_background.xml
+++ b/packages/SystemUI/res/drawable/ticker_background.xml
@@ -20,7 +20,7 @@
     >
     <!-- the large icon extends 12dp beyond the edge of the status bar -->
     <item
-        android:drawable="@*android:drawable/notification_item_background_color"
+        android:drawable="@drawable/notification_item_background_color"
         android:top="12dp"
         />
 </layer-list>
diff --git a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
index a109191..ddffd6e 100644
--- a/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_search_panel.xml
@@ -51,13 +51,13 @@
                 prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
                 prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
                 prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-                prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+                prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
                 prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
                 prvandroid:feedbackCount="0"
                 prvandroid:vibrationDuration="@integer/config_vibration_duration"
                 prvandroid:alwaysTrackFinger="true"
-                prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
-                prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+                prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+                prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
                 />
 
         </RelativeLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/heads_up.xml b/packages/SystemUI/res/layout-sw600dp/heads_up.xml
new file mode 100644
index 0000000..71f7c21
--- /dev/null
+++ b/packages/SystemUI/res/layout-sw600dp/heads_up.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<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"
+    >
+    <FrameLayout
+        android:id="@+id/content_holder"
+        android:layout_height="wrap_content"
+        android:layout_width="@dimen/notification_panel_width"
+        android:layout_marginStart="@dimen/notification_panel_margin_left"
+        android:background="@drawable/heads_up_window_bg"
+        />
+</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
index 1fa67bd..08f61bb 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_search_panel.xml
@@ -37,12 +37,12 @@
         prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
         prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
         prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-        prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+        prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
         prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
         prvandroid:feedbackCount="0"
         prvandroid:vibrationDuration="@integer/config_vibration_duration"
         prvandroid:alwaysTrackFinger="true"
-        prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
-        prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"/>
+        prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+        prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"/>
 
 </com.android.systemui.SearchPanelView>
diff --git a/packages/SystemUI/res/layout/heads_up.xml b/packages/SystemUI/res/layout/heads_up.xml
index 564dc51..3a58b84 100644
--- a/packages/SystemUI/res/layout/heads_up.xml
+++ b/packages/SystemUI/res/layout/heads_up.xml
@@ -17,25 +17,11 @@
 ** 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>
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_height="wrap_content"
+        android:layout_width="@dimen/notification_panel_width"
+        android:id="@+id/content_holder"
+        android:layout_marginStart="@dimen/notification_panel_margin_left"
+        android:background="@drawable/notification_panel_bg"
+        />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/quick_settings_tile_battery.xml b/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
index f3b894c..1f39aef 100644
--- a/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
+++ b/packages/SystemUI/res/layout/quick_settings_tile_battery.xml
@@ -15,6 +15,7 @@
 -->
 <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="match_parent"
         android:layout_gravity="top"
@@ -27,6 +28,7 @@
             android:layout_height="32dp"
             android:padding="3dp"
             android:layout_gravity="top|center_horizontal"
+            systemui:frameColor="@color/qs_batterymeter_frame_color"
             />
     <TextView
             style="@style/TextAppearance.QuickSettings.TileView"
diff --git a/packages/SystemUI/res/layout/recents_empty.xml b/packages/SystemUI/res/layout/recents_empty.xml
new file mode 100644
index 0000000..6268628
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_empty.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:gravity="center"
+    android:textSize="40sp"
+    android:textColor="#ffffffff"
+    android:text="@string/recents_empty_message"
+    android:fontFamily="sans-serif-thin"
+    android:visibility="gone" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index eb66908..ea6be1b 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -62,7 +62,11 @@
                 android:src="@drawable/stat_notify_more"
                 android:visibility="gone"
                 />
-
+            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/modeIcon"
+                android:layout_width="@dimen/status_bar_icon_size"
+                android:layout_height="match_parent"
+                android:visibility="gone"
+                />
             <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index f827967..e74e568 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -25,7 +25,7 @@
         android:paddingStart="8dp"
         />
 
-    <com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
+    <com.android.systemui.statusbar.LatestItemView android:id="@+id/container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/notification_divider_height"
@@ -34,10 +34,13 @@
         android:clickable="true"
         >
 
-        <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/adaptive"
+        <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expanded"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
 
+        <com.android.internal.widget.SizeAdaptiveLayout android:id="@+id/expandedPublic"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
     </com.android.systemui.statusbar.LatestItemView>
 
     <View
diff --git a/packages/SystemUI/res/layout/status_bar_search_panel.xml b/packages/SystemUI/res/layout/status_bar_search_panel.xml
index b871bef..c01db7c 100644
--- a/packages/SystemUI/res/layout/status_bar_search_panel.xml
+++ b/packages/SystemUI/res/layout/status_bar_search_panel.xml
@@ -51,13 +51,13 @@
                 prvandroid:directionDescriptions="@array/navbar_search_direction_descriptions"
                 prvandroid:outerRingDrawable="@drawable/navbar_search_outerring"
                 prvandroid:outerRadius="@dimen/navbar_search_outerring_radius"
-                prvandroid:innerRadius="@*android:dimen/glowpadview_inner_radius"
+                prvandroid:innerRadius="@dimen/glowpadview_inner_radius"
                 prvandroid:snapMargin="@dimen/navbar_search_snap_margin"
                 prvandroid:feedbackCount="0"
                 prvandroid:vibrationDuration="@integer/config_vibration_duration"
                 prvandroid:alwaysTrackFinger="true"
-                prvandroid:glowRadius="@*android:dimen/glowpadview_glow_radius"
-                prvandroid:pointDrawable="@*android:drawable/ic_lockscreen_glowdot"
+                prvandroid:glowRadius="@dimen/glowpadview_glow_radius"
+                prvandroid:pointDrawable="@drawable/ic_lockscreen_glowdot"
                />
 
         </RelativeLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9ddf42a..98d132a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Tuis"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Kieslys"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Onlangse programme"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Deursoek"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knoppie vir wissel van invoermetode."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Versoenbaarheid-zoem se knoppie."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoem kleiner na groter skerm."</string>
@@ -153,6 +153,7 @@
     <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">"Vliegtuigmodus <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_location" msgid="4577282329866813100">"Ligging <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Wekker gestel vir <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data gedeaktiveer"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G data gedeaktiveer"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Nageregkas"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Sluimer"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Vliegtuigmodus"</string>
@@ -181,11 +183,11 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Helderheid"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Gesluit op portret"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Gesluit op landskap"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Invoermetode"</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_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>
@@ -196,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nie gekoppel nie"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Geen netwerk nie"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi af"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi-skerm"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Draadlose aansig"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Saai na skerm uit"</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.\nSleep weer af vir stelselkontroles."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Sleep rand van skerm om balk te wys"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Sleep van rand van skerm af om stelselbalk te wys"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Kleur-omkeringmodus"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Verbeterde kontrasmodus"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Kleurregstellingmodus"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ONLANGS"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk word\ndalk gemonitor"</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_left" msgid="7207478719805562165">"Gly links vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 1d81ea7..d7457f0 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"መነሻ"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"ምናሌ"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"የቅርብ ጊዜ  መተግበሪያዎች"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"ፈልግ"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"ካሜራ"</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>
@@ -153,6 +153,7 @@
     <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_location" msgid="4577282329866813100">"አካባቢ <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>
@@ -164,12 +165,13 @@
     <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="dessert_case" msgid="1295161776223959221">"የማወራረጃ ምግቦች መያዣ"</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>
@@ -181,6 +183,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"ወደ ቁመት አቀማመጥ ተቆልፏል"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"ወደ መሬት ገጽታ ተቆልፏል"</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>
@@ -194,12 +198,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"ማያ ገጽ ውሰድ"</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">"ወደ ታች በማንሸራተት በማንኛውም ጊዜ ይድረሱባቸው።\nSwipe የስርዓት መቆጣጠሪያዎችን ለማምጣት እንደገና ወደ ታች ያንሸራትቱ።"</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"አሞሌውን ለማሳየት የማያ ገጹን ጠርዝ ላይ ያንሸራትቱ"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"አሞሌውን ለማሳየት ከማያ ገጹ ጠርዝ ጀምረው ያንሸራትቱ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"የተቃራኒ ቀለም ሁነታ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"የተሻሻለ ንፅፅር ሁነታ"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"የቀለም እርማት ሁነታ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"የቅርብ ጊዜዎች"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"አውታረ መረብ\nክትትል ሊደረግበት ይችላል"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ግራ አንሸራትት።"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index c31d6d9..596f612 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -27,15 +27,15 @@
     <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>
+    <item quantity="other" msgid="1040784359794890744">"‏%d من التطبيقات الحديثة"</item>
   </plurals>
-    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ليس هناك أي تنبيهات"</string>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ليس هناك أي اشعارات"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"مستمر"</string>
-    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"التنبيهات"</string>
+    <string name="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="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>
@@ -43,26 +43,24 @@
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"التدوير التلقائي للشاشة"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"كتم"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"تلقائي"</string>
-    <string name="status_bar_settings_notifications" msgid="397146176280905137">"التنبيهات"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"الإشعارات"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"تم إنشاء الاتصال بالإنترنت عن طريق البلوتوث."</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"إعداد أسلوب الإدخال"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"لوحة مفاتيح فعلية"</string>
-    <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">"لا يعمل أي تطبيق مثبت مع ملحق UEB هذا. مزيد من المعلومات عن هذا الملحق على <xliff:g id="URL">%1$s</xliff:g>."</string>
-    <string name="title_usb_accessory" msgid="4966265263465181372">"ملحق USB"</string>
+    <string name="usb_device_permission_prompt" msgid="834698001271562057">"‏هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى جهاز USB؟"</string>
+    <string name="usb_accessory_permission_prompt" msgid="5171775411178865750">"‏هل تريد السماح للتطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> بالدخول إلى ملحق USB؟"</string>
+    <string name="usb_device_confirm_prompt" msgid="5161205258635253206">"‏هل تريد فتح <xliff:g id="ACTIVITY">%1$s</xliff:g> عند توصيل جهاز USB هذا؟"</string>
+    <string name="usb_accessory_confirm_prompt" msgid="3808984931830229888">"‏هل تريد فتح <xliff:g id="ACTIVITY">%1$s</xliff:g> عند توصيل ملحق USB هذا؟"</string>
+    <string name="usb_accessory_uri_prompt" msgid="513450621413733343">"‏لا يعمل أي تطبيق مثبت مع ملحق UEB هذا. مزيد من المعلومات عن هذا الملحق على <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="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>
@@ -70,14 +68,16 @@
     <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="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_search_light" msgid="1103867596330271848">"بحث"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"الكاميرا"</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>
@@ -98,17 +98,17 @@
     <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">"تم إيقاف Wi-Fi."</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">"إشارة Wi-Fi تتكون من ثلاثة أشرطة."</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_wifi_off" msgid="3177380296697933627">"‏تم إيقاف Wi-Fi."</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">"‏إشارة Wi-Fi تتكون من ثلاثة أشرطة."</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>
@@ -123,22 +123,22 @@
     <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">"شبكة الجيل الثالث"</string>
-    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"شبكة 3.5G"</string>
+    <string name="accessibility_data_connection_3.5g" msgid="8664845609981692001">"‏شبكة 3.5G"</string>
     <string name="accessibility_data_connection_4g" msgid="7741000750630089612">"شبكة الجيل الرابع"</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_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_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>
@@ -153,6 +153,7 @@
     <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_location" msgid="4577282329866813100">"حالة الموقع: <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">"تم تعطيل بيانات شبكات الجيل الثاني والجيل الثالث"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"تم تعطيل بيانات شبكة الجيل الرابع"</string>
@@ -161,15 +162,16 @@
     <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="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="dessert_case" msgid="1295161776223959221">"حالة الحلويات"</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>
@@ -181,6 +183,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"تم القفل على الوضع العمودي"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"تم القفل على الوضع الأفقي"</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>
@@ -193,13 +197,16 @@
     <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_wifi_off_label" msgid="7558778100843885864">"‏إيقاف Wi-Fi"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"بث الشاشة"</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="hideybar_confirmation_message" msgid="9050869548951044371">"مرر سريعًا لحافة الشاشة لإظهار الشريط"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"مرر سريعًا من حافة الشاشة لإظهار شريط النظام"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"وضع انعكاس اللون"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"وضع التباين المحسن"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"وضع تصحيح الألوان"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"الأخيرة"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"قد تكون الشبكة\nخاضعة للرقابة"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"تمرير لليسار لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az-land/strings.xml b/packages/SystemUI/res/values-az-land/strings.xml
new file mode 100644
index 0000000..8eb6978
--- /dev/null
+++ b/packages/SystemUI/res/values-az-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-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
deleted file mode 100644
index 6608b79..0000000
--- a/packages/SystemUI/res/values-be/strings.xml
+++ /dev/null
@@ -1,211 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources 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">"Закрыць нядаўнія прыкладаннi"</string>
-  <plurals name="status_bar_accessibility_recent_apps">
-    <item quantity="one" msgid="5854176083865845541">"1 нядаўняе прыкладанне"</item>
-    <item quantity="other" msgid="1040784359794890744">"Нядаўнія прыкладаннi: %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> атрымлiваць доступ да прылады 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">"Адб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>
-    <string name="screenshot_saved_title" msgid="6461865960961414961">"Скрыншот зроблены"</string>
-    <string name="screenshot_saved_text" msgid="1152839647677558815">"Націсніце, каб прагледзець скрыншот"</string>
-    <string name="screenshot_failed_title" msgid="705781116746922771">"Не атрымалася зрабiць скрыншот."</string>
-    <string name="screenshot_failed_text" msgid="8134011269572415402">"Немагчыма захаваць скрыншот. Магчыма, назапашвальнiк выкарыстоўваецца."</string>
-    <string name="usb_preference_title" msgid="6551050377388882787">"Парам. перадачы файлаў па USB"</string>
-    <string name="use_mtp_button_title" msgid="4333504413563023626">"Падлучыць як медыяпрайгравальнік (ССП)"</string>
-    <string name="use_ptp_button_title" msgid="7517127540301625751">"Падлучыць як камеру (PTP)"</string>
-    <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">"2 планкі акумулятара."</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">"2 планкі тэлефона."</string>
-    <string name="accessibility_phone_three_bars" msgid="8521904843919971885">"3 планкі тэлефона."</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">"Wi-Fi выключаны."</string>
-    <string name="accessibility_no_wifi" msgid="1425476551827924474">"Wi-Fi адключаны."</string>
-    <string name="accessibility_wifi_one_bar" msgid="7735893178010724377">"Адзiн слупок Wi-Fi."</string>
-    <string name="accessibility_wifi_two_bars" msgid="4994274250497262434">"Два слупкi Wi-Fi."</string>
-    <string name="accessibility_wifi_three_bars" msgid="3495755044276588384">"Тры слупкi Wi-Fi."</string>
-    <string name="accessibility_wifi_signal_full" msgid="6853561303586480376">"Поўны сігнал Wi-Fi."</string>
-    <string name="accessibility_no_wimax" msgid="4329180129727630368">"Няма сiгналу WiMAX."</string>
-    <string name="accessibility_wimax_one_bar" msgid="4170994299011863648">"Адзiн слупок сiгналу WiMAX."</string>
-    <string name="accessibility_wimax_two_bars" msgid="9176236858336502288">"Два слупкi сiгналу WiMAX."</string>
-    <string name="accessibility_wimax_three_bars" msgid="6116551636752103927">"Тры слупкi сiгналу WiMAX."</string>
-    <string name="accessibility_wimax_signal_full" msgid="2768089986795579558">"Моцны сiгнал 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">"Адзiн слупок."</string>
-    <string name="accessibility_two_bars" msgid="6437363648385206679">"Два слупкi."</string>
-    <string name="accessibility_three_bars" msgid="2648241415119396648">"Тры слупкi."</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.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 уключаны."</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">"Мабiльны сiгнал: <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">"Наладжаны будзiльнiк: <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">"Вы перавыс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>
-    <string name="accessibility_clear_all" msgid="5235938559247164925">"Выдалiць усе апавяшчэннi."</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">"Экран заблакiраваны ў альбомнай арыентацыі."</string>
-    <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Экран заблакiраваны ў партрэтнай арыентацыі."</string>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
-    <string name="start_dreams" msgid="7219575858348719790">"Мроi"</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>
-    <!-- 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>
-    <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">"Няма сеткi"</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>
-    <!-- no translation found for hideybar_confirmation_message (9050869548951044371) -->
-    <skip />
-    <!-- no translation found for hideybar_confirmation_message_long (7117692795163620626) -->
-    <skip />
-</resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 6194fd8..335c33a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Начало"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Скорошни приложения"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Търсене"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</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>
@@ -153,6 +153,7 @@
     <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_location" msgid="4577282329866813100">"Местоположението е <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>
@@ -164,12 +165,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Витрина с десерти"</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>
@@ -181,11 +183,11 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Заключено във вертикален режим"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Заключено в хоризонтален режим"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Метод на въвеждане"</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_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>
@@ -196,12 +198,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"Екран за предаване"</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="hideybar_confirmation_message" msgid="9050869548951044371">"Прекарайте пръст по ръба на екрана, за да се покаже лентата"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Прекарайте пръст от ръба на екрана, за да се покаже системната лента"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим на инвертиране на цветовете"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим на подобрен контраст"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим на коригиране на цветовете"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"СКОРОШНИ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежата може\nда се наблюдава"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Търсене"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Плъзнете наляво за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index eddeda3..e79e094 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -61,9 +61,7 @@
     <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_ticker" msgid="7403652894056693515">"S\'està 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>
     <string name="screenshot_saved_title" msgid="6461865960961414961">"S\'ha fet una captura de pantalla."</string>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Pàgina d\'inici"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Aplicacions recents"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Cerca"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Càmera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botó de canvi del mètode d\'entrada."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botó de zoom de compatibilitat."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Amplia menys com més gran sigui la pantalla."</string>
@@ -155,6 +155,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Bateria <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Mode d\'avió <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_location" msgid="4577282329866813100">"Ubicació: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarma establerta a les <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dades 2G-3G desactivades"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dades 4G desactivades"</string>
@@ -166,12 +167,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Capsa de postres"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Estalvi de pantalla"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Mode d\'avió"</string>
@@ -183,6 +185,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brillantor"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Bloquejat en mode vertical"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Bloquejat en mode horitzontal"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mètode d\'entrada"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Ubicació"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Ubicació desactivada"</string>
@@ -196,12 +200,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Desconnectat"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No hi ha cap xarxa"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desconnectada"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Pantalla Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla sense fil"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Pantalla d\'emissió"</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.\nTorna a fer lliscar el dit cap avall per fer que es mostrin els controls del sistema."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Fes lliscar el dit per la vora de la pantalla perquè es mostri la barra"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Fes lliscar el dit des de la vora de la pantalla perquè es mostri la barra del sistema"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversió de color"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode de contrast millorat"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correcció de color"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"És possible que la xarxa\nestigui controlada"</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_left" msgid="7207478719805562165">"Fes lliscar el dit cap a l\'esquerra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 87ba67a..60bbe3b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Domů"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Nové aplikace"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Hledat"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparát"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačítko přepnutí metody zadávání"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačítko úpravy velikosti z důvodu kompatibility"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zvětšit menší obrázek na větší obrazovku."</string>
@@ -155,6 +155,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Baterie: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Režim V letadle: <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_location" msgid="4577282329866813100">"Poloha: <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Budík je nastaven na <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datové přenosy 2G a 3G jsou zakázány"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datové přenosy 4G jsou zakázány"</string>
@@ -166,12 +167,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Pult se sladkostmi"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Spořič obrazovky"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Režim V letadle"</string>
@@ -183,11 +185,11 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Jas"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Uzamčen režim na výšku"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Uzamčen režim na šířku"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metoda zadávání dat"</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_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>
@@ -198,12 +200,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nepřipojeno"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Žádná síť"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi vypnuta"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Displej přes Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrátový displej"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Vzdálená obrazovka"</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ů.\nPřejedete-li prstem dolů ještě jednou, zobrazí se ovládací prvky systému."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Panel zobrazíte přejetím přes okraj obrazovky"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Systémový panel zobrazíte přejetím přes okraj obrazovky"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim převrácení barev"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekce barev"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"POSLEDNÍ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Síť může být\nmonitorována"</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_left" msgid="7207478719805562165">"Přejeďte prstem doleva: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index af4bb33..9c920f2 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -29,7 +29,7 @@
     <item quantity="one" msgid="5854176083865845541">"1 seneste app"</item>
     <item quantity="other" msgid="1040784359794890744">"%d seneste apps"</item>
   </plurals>
-    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen meddelelser"</string>
+    <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ingen underretninger"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"I gang"</string>
     <string name="status_bar_latest_events_title" msgid="6594767438577593172">"Underretninger"</string>
     <string name="battery_low_title" msgid="2783104807551211639">"Tilslut oplader"</string>
@@ -44,7 +44,7 @@
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"LYDLØS"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTO"</string>
     <string name="status_bar_settings_notifications" msgid="397146176280905137">"Underretninger"</string>
-    <string name="bluetooth_tethered" msgid="7094101612161133267">"Bluetooth-tethering anvendt"</string>
+    <string name="bluetooth_tethered" msgid="7094101612161133267">"Netdeling via Bluetooth anvendt"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"Konfigurer inputmetoder"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"Fysisk tastatur"</string>
     <string name="usb_device_permission_prompt" msgid="834698001271562057">"Tillad, at appen <xliff:g id="APPLICATION">%1$s</xliff:g> kan få adgang til USB-enheden?"</string>
@@ -61,12 +61,10 @@
     <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>
-    <string name="screenshot_saved_title" msgid="6461865960961414961">"Skærmbilledet er taget."</string>
+    <string name="screenshot_saved_title" msgid="6461865960961414961">"Skærmbilledet er gemt."</string>
     <string name="screenshot_saved_text" msgid="1152839647677558815">"Tryk for at se dit skærmbillede."</string>
     <string name="screenshot_failed_title" msgid="705781116746922771">"Skærmbilledet kunne ikke tages."</string>
     <string name="screenshot_failed_text" msgid="8134011269572415402">"Skærmbilledet kunne ikke gemmes. Eksternt lager kan være i brug."</string>
@@ -75,9 +73,11 @@
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Isæt som et kamera (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Installer appen Android Filoverførsel til Mac"</string>
     <string name="accessibility_back" msgid="567011538994429120">"Tilbage"</string>
-    <string name="accessibility_home" msgid="8217216074895377641">"Startside"</string>
+    <string name="accessibility_home" msgid="8217216074895377641">"Startskærm"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Seneste apps"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Søg"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Skift indtastningsmetode-knappen."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knap for kompatibilitetszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom mindre til større skærm."</string>
@@ -136,7 +136,7 @@
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batteri <xliff:g id="NUMBER">%d</xliff:g> procent."</string>
     <string name="accessibility_settings_button" msgid="799583911231893380">"Systemindstillinger."</string>
     <string name="accessibility_notifications_button" msgid="4498000369779421892">"Underretninger."</string>
-    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ryd meddelelse."</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"Ryd underretning."</string>
     <string name="accessibility_gps_enabled" msgid="3511469499240123019">"GPS aktiveret."</string>
     <string name="accessibility_gps_acquiring" msgid="8959333351058967158">"GPS samler data."</string>
     <string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter aktiveret."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batteri <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Flytilstand <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_location" msgid="4577282329866813100">"Placering <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmen er indstillet til <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data er deaktiveret"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktiveret"</string>
@@ -164,12 +165,13 @@
     <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_clear_all" msgid="5235938559247164925">"Ryd alle meddelelser."</string>
+    <string name="accessibility_location_active" msgid="2427290146138169014">"Aktive placeringsanmodninger"</string>
+    <string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle underretninger."</string>
     <string name="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Oplysninger om appen"</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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessertcase"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Dagdrøm"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Flytilstand"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Lysstyrke"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Låst i portræt"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Låst i landskab"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inputmetode"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Placering"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Placering fra"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ikke forbundet"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Intet netværk"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi slået fra"</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">"Trådløs skærm"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Cast 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.\nStryg ned igen for at komme til systemindstillingerne."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Stryg kanten af skærmen for at se bjælken"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Stryg fra skærmens kant for at se systembjælken"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farveinverteringstilstand"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tilstand for forbedret kontrast"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Farvekorrigeringstilstand"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"SENESTE"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netværket kan\nvære overvåget"</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_left" msgid="7207478719805562165">"Glid til venstre for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index ec52ede..c8cb0a4 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Startbildschirm"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Kürzlich geöffnete Apps"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Suchen"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Schaltfläche zum Ändern der Eingabemethode"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Schaltfläche für Kompatibilitätszoom"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom auf einen größeren Bildschirm"</string>
@@ -155,6 +155,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Akku: <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Flugmodus: <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_location" msgid="4577282329866813100">"Standort <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Wecker gestellt für <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-/3G-Daten deaktiviert"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-Daten deaktiviert"</string>
@@ -166,12 +167,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessertbehälter"</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">"Flugmodus"</string>
@@ -183,11 +185,11 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Helligkeit"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Auf Hochformat gesperrt"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Auf Querformat gesperrt"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Eingabemethode"</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_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>
@@ -198,12 +200,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nicht verbunden"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Kein Netz"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WLAN aus"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"WLAN-Display"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Kabellose Übertragung (WiDi)"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Bildschirm übertragen"</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.\nWischen Sie für Systemeinstellungen erneut nach unten."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Zum Einblenden der Leiste vom Rand wischen"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Zum Einblenden der Systemleiste vom Display-Rand weg wischen"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farbinversionsmodus"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastverbesserungsmodus"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Farbkorrekturmodus"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"Letzte"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netzwerk wird\neventuell überwacht."</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_left" msgid="7207478719805562165">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach links schieben"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index ab43081..79025b6 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Αρχική σελίδα"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Μενού"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Πρόσφατες εφαρμογές"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Αναζήτηση"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Φωτογραφική μηχανή"</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>
@@ -155,6 +155,7 @@
     <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_location" msgid="4577282329866813100">"Τοποθεσία <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>
@@ -166,12 +167,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Επιδόρπιο"</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>
@@ -183,6 +185,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Κλειδωμένο στην κατακόρυφη προβολή"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Κλειδωμένο στην οριζόντια προβολή"</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>
@@ -196,12 +200,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"Μετάδοση οθόνης"</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="hideybar_confirmation_message" msgid="9050869548951044371">"Σύρετε από την άκρη της οθόνης για να εμφανίσετε τη γραμμή"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Σύρετε από την άκρη της οθόνης για να εμφανίσετε τη γραμμή συστήματος"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Λειτουργία αναστροφής χρώματος"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Λειτουργία βελτίωσης αντίθεσης"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Λειτουργία διόρθωσης χρώματος"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ΠΡΟΣΦΑΤΑ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Το δίκτυο μπορεί\nνα παρακολουθείται"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Αναζήτηση"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Κύλιση προς τα επάνω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Κύλιση προς τα αριστερά για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 6027553f..338c8ac 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <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_search_light" msgid="1103867596330271848">"Search"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</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>
@@ -153,6 +153,7 @@
     <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_location" msgid="4577282329866813100">"Location <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>
@@ -164,12 +165,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Dessert Case"</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>
@@ -181,6 +183,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Locked to Portrait"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Locked to Landscape"</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>
@@ -194,12 +198,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"Cast Screen"</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.\nSwipe down again for system controls."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Swipe edge of screen to reveal bar"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Swipe from edge of screen to reveal system bar"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</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_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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..338c8ac
--- /dev/null
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"Search"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</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_location" msgid="4577282329866813100">"Location <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="dessert_case" msgid="1295161776223959221">"Dessert Case"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"Locked to Portrait"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Locked to Landscape"</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_remote_display_no_connection_label" msgid="372107699274391290">"Cast Screen"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</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_left" msgid="7207478719805562165">"Slide left for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 62f6c20..89fe58b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Página principal"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Aplicaciones recientes"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de entrada"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
@@ -155,6 +155,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batería <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modo avión <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_location" msgid="4577282329866813100">"Ubicación <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarma: <xliff:g id="TIME">%s</xliff:g>"</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datos de 2G-3G inhabilitados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos de 4G inhabilitados"</string>
@@ -166,12 +167,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Caja para postres"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Activar protector"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modo avión"</string>
@@ -183,11 +185,11 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brillo"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Bloqueada en vertical"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Bloqueada en horizontal"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de introducción"</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_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>
@@ -198,12 +200,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Sin conexión"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Sin red"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desactivada"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Pantalla Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla inalámbrica"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Pantalla de Cast"</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.\nVuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Desliza el dedo desde el borde de la pantalla para mostrar la barra."</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Desliza el dedo desde el borde de la pantalla para mostrar la barra del sistema."</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Es posible que la red\nesté supervisada."</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_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 64c3cab..4999f71 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Inicio"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Aplicaciones recientes"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Botón Cambiar método de entrada"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botón de zoom de compatibilidad"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom de pantalla más pequeña a más grande"</string>
@@ -116,8 +116,8 @@
     <string name="accessibility_two_bars" msgid="6437363648385206679">"Dos barras"</string>
     <string name="accessibility_three_bars" msgid="2648241415119396648">"Tres barras"</string>
     <string name="accessibility_signal_full" msgid="9122922886519676839">"Señal al máximo"</string>
-    <string name="accessibility_desc_on" msgid="2385254693624345265">"Activado"</string>
-    <string name="accessibility_desc_off" msgid="6475508157786853157">"Desactivado"</string>
+    <string name="accessibility_desc_on" msgid="2385254693624345265">"Sí"</string>
+    <string name="accessibility_desc_off" msgid="6475508157786853157">"No"</string>
     <string name="accessibility_desc_connected" msgid="8366256693719499665">"Conectado"</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batería <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modo avión <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_location" msgid="4577282329866813100">"Ubicación <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"La alarma sonará a la(s) <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datos 2G-3G inhabilitados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datos 4G inhabilitados"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Caja para postres"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Salvapantallas"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modo avión"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brillo"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Bloqueado en vertical"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Bloqueado en horizontal"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"No conectado"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"No hay red."</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desactivado"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Pantalla Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Pantalla inalámbrica"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Pantalla de Cast"</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.\nVuelve a deslizar el dedo hacia abajo para acceder a los controles del sistema."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Desliza el borde de la pantalla para mostrar la barra"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Desliza el borde de la pantalla para mostrar la barra del sistema"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La red se\npuede supervisar"</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_left" msgid="7207478719805562165">"Desliza el dedo hacia la izquierda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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..b734fa8
--- /dev/null
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"Otsing"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kaamera"</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_location" msgid="4577282329866813100">"Asukoht: <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="dessert_case" msgid="1295161776223959221">"Maiustusekorv"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"Lukustatud vertikaalpaigutusse"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Lukustatud horisontaalpaigutusse"</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_remote_display_no_connection_label" msgid="372107699274391290">"Cast-ekraan"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Heledus"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Värvide ümberpööramise režiim"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Täiustatud kontrasti režiim"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Värviparandusrežiim"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"HILJUTISED"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Võrku võidakse\njälgida"</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_left" msgid="7207478719805562165">"Lohistage vasakule: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
deleted file mode 100644
index 6d9c838..0000000
--- a/packages/SystemUI/res/values-et/strings.xml
+++ /dev/null
@@ -1,205 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources 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="compat_mode_help_header" msgid="7969493989397529910">"Sobivussuum"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Kui rakendus on mõeldud väiksemale ekraanile, kuvatakse kella kõrval suumi juhtnupp."</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_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="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.\nSüsteemi juhtnuppude jaoks pühkige uuesti alla."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Riba kuvamiseks pühkige ekraani serva"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Süsteemiriba kuvamiseks pühkige ekraani servast"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index b095519..5780a57 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -27,7 +27,7 @@
     <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="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>
@@ -35,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>
@@ -47,22 +47,20 @@
     <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="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="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>
@@ -70,14 +68,16 @@
     <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="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_search_light" msgid="1103867596330271848">"جستجو"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"دوربین"</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>
@@ -98,17 +98,17 @@
     <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">"Wi‑Fi خاموش."</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">"سه نوار برای Wi‑Fi."</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_wifi_off" msgid="3177380296697933627">"‏Wi‑Fi خاموش."</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">"‏سه نوار برای Wi‑Fi."</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>
@@ -137,9 +137,9 @@
     <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_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>
@@ -153,23 +153,25 @@
     <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_location" msgid="4577282329866813100">"مکان <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_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="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="dessert_case" msgid="1295161776223959221">"ویترین دسر"</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>
@@ -181,11 +183,11 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"قفل شده در حالت عمودی"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"قفل شده در حالت افقی"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"روش ورودی"</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_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>
@@ -195,13 +197,16 @@
     <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_wifi_off_label" msgid="7558778100843885864">"‏Wi-Fi خاموش است"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"فرستادن صفحه"</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="hideybar_confirmation_message" msgid="9050869548951044371">"برای نمایش نوار، انگشت خود را از لبه‌ صفحه به داخل بکشید"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"برای نمایش نوار سیستم، انگشت خود را از لبه‌ صفحه به داخل بکشید"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"حالت وارونگی رنگ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"حالت کنتراست بهبودیافته"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"حالت تصحیح رنگ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"موارد اخیر"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ممکن است شبکه\nتحت نظارت باشد"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"لغزاندن به چپ برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 06e1926..4809741 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Aloituspainike"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Valikko"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Viimeaikaiset sovellukset"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Haku"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Syöttötavan vaihtopainike."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Yhteensopivuuszoomaus-painike."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoomaa pienemmältä suuremmalle ruudulle."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Akku: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Lentokonetila <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_location" msgid="4577282329866813100">"Sijainti <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Hälytys asetettu, aika: <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-tiedonsiirto pois käytöstä"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-tiedonsiirto pois käytöstä"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Jälkiruokavitriini"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Unelmat"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Lentokonetila"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Kirkkaus"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Vaaka lukittu"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Pysty lukittu"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Syöttötapa"</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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ei yhteyttä"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Ei verkkoa"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wifi-yhteys pois käytöstä"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wifi-näyttö"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Langaton näyttö"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Lähetysnä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.\nVoit palauttaa järjestelmän ohjaimet näkyviin liu\'uttamalla sormea alas uudelleen."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Tuo palkki näkyviin liu\'uttamalla ruudun reunasta"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Tuo järjestelmäpalkki näkyviin liu\'uttamalla ruudun reunasta"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Käänteinen väritila"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastinparannustila"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Värinkorjaustila"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"VIIMEISIMMÄT"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Verkkoa saatetaan\nvalvoa"</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_left" msgid="7207478719805562165">"Liu\'uta vasemmalle ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</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..36b54ce
--- /dev/null
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -0,0 +1,214 @@
+<?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_search_light" msgid="1103867596330271848">"Rechercher"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Appareil photo"</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_location" msgid="4577282329866813100">"Localisation <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="dessert_case" msgid="1295161776223959221">"Vitrine des desserts"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"Verrouillé en mode portrait"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Verrouillé en mode paysage"</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_remote_display_no_connection_label" msgid="372107699274391290">"Écran distant"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Faites glisser votre doigt vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7db07e2..5b81975 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Accueil"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Applications récentes"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Rechercher"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Appareil photo"</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>
@@ -155,6 +155,7 @@
     <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_location" msgid="4577282329866813100">"Localisation <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>
@@ -166,12 +167,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Vitrine des desserts"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Écran de veille interactif"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Mode avion"</string>
@@ -183,14 +185,14 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Luminosité"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Verrouillé en mode portrait"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Verrouillé en mode paysage"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mode de saisie"</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_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>
+    <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Appels d\'urgence"</string>
     <string name="quick_settings_settings_label" msgid="5326556592578065401">"Paramètres"</string>
     <string name="quick_settings_time_label" msgid="4635969182239736408">"Heure"</string>
     <string name="quick_settings_user_label" msgid="5238995632130897840">"Moi"</string>
@@ -198,12 +200,15 @@
     <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">"Wi-Fi Display"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Affichage sans fil"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Caster l\'écran"</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.\nRépétez l\'opération pour accéder aux commandes du système."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Faites glisser votre doigt sur le côté de l\'écran pour afficher la barre."</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Faites glisser votre doigt à partir d\'un côté de l\'écran pour afficher la barre système."</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</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_left" msgid="7207478719805562165">"Faites glisser vers la gauche pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 862e2ef..9be9550 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -22,12 +22,12 @@
     <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>
+    <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>
@@ -40,18 +40,18 @@
     <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>
@@ -61,8 +61,6 @@
     <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>
@@ -73,11 +71,13 @@
     <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 File Transfer एप्लि. इंस्टॉल करें"</string>
+    <string name="installer_cd_button_title" msgid="2312667578562201583">"Mac के लिए Android File Transfer ऐप्स इंस्टॉल करें"</string>
     <string name="accessibility_back" msgid="567011538994429120">"वापस जाएं"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"होम"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string>
-    <string name="accessibility_recent" msgid="8571350598987952883">"हाल ही के एप्‍लिकेशन"</string>
+    <string name="accessibility_recent" msgid="8571350598987952883">"हाल ही के ऐप्स"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"खोजें"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"कैमरा"</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>
@@ -146,13 +146,14 @@
     <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>
     <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_location" msgid="4577282329866813100">"स्थान <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>
@@ -164,13 +165,14 @@
     <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="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="dessert_case" msgid="1295161776223959221">"मिठाई का डिब्बा"</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>
@@ -178,9 +180,11 @@
     <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_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_rotation_locked_portrait_label" msgid="1553131290066230775">"पोर्ट्रेट पर लॉक किया गया"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"भू-दृश्य पर लॉक किया गया"</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>
@@ -194,12 +198,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"स्क्रीन कास्ट करें"</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="hideybar_confirmation_message" msgid="9050869548951044371">"बार दिखाने के लिए स्क्रीन के किनारे को स्वाइप करें"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"सिस्टम बार दिखाने के लिए स्क्रीन के किनारे से स्वाइप करें"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"रंग व्युत्क्रम मोड"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"उन्नत कंट्रास्ट मोड"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"रंग सुधार मोड"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"हाल ही का"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"नेटवर्क को\nमॉनीटर किया जा सकता है"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए बाएं स्‍लाइड करें."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 631d549..21d6ef5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Početna"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Izbornik"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Nedavne aplikacije"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Pretraži"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparat"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Gumb za promjenu načina unosa."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb za kompatibilnost zumiranja."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zumiranje manjeg zaslona na veći."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Baterija – <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Način rada u zrakoplovu <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_location" msgid="4577282329866813100">"Lokacija <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Vrijeme alarma: <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Onemogućeni su 2G-3G podaci"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Onemogućeni su 4G podaci"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Izlog za slastice"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Sanjarenje"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Način rada u zrakoplovu"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Svjetlina"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Blokirano u portretnom prikazu"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Blokirano u pejzažnom prikazu"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Način unosa"</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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nije povezano"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nema mreže"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi isključen"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi zaslon"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bežični prikaz"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Emitiranje zaslona"</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. \nPonovo prstom trznite prema dolje za kontrole sustava."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Prijeđite prstom po rubu zaslona da bi se prikazala traka"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Prijeđite prstom od ruba zaslona da bi se prikazala traka sustava"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije boje"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način pojačanog kontrasta"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Način korekcije boje"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNO"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža se\nmožda prati"</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_left" msgid="7207478719805562165">"Kliznite lijevo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index c1c9136..8e6ee4f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Főoldal"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Legújabb alkalmazás"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Keresés"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Beviteli mód váltása gomb."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kompatibilitási zoom gomb."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kicsinyítsen a nagyobb képernyőhöz."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Akkumulátor <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Repülős üzemmód <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_location" msgid="4577282329866813100">"Helyadatok: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Ébresztés időpontja: <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G adatforgalom letiltva"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G adatforgalom letiltva"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Álmodozás"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Repülőgép üzemmód"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Fényerő"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Álló nézet zárolva"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Fekvő nézet zárolva"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Beviteli módszer"</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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nincs kapcsolat"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nincs hálózat"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi kikapcsolva"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi kijelző"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Vezeték nélküli kijelző"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Képernyő tartalmának átküldése"</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.\nHúzza le az ujját még egyszer a rendszerbeállítások eléréséhez."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Csúsztassa ujját a képernyő szélén a sáv megjelenítéséhez"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Csúsztassa ujját a képernyő szélétől a rendszersáv megjelenítéséhez"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Színinvertálás mód"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrasztjavítás mód"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Színjavítás mód"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"LEGUTÓBBIAK"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Lehet, hogy a\nhálózat felügyelt"</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_left" msgid="7207478719805562165">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa balra."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy-land/strings.xml b/packages/SystemUI/res/values-hy-land/strings.xml
new file mode 100644
index 0000000..7c0535c
--- /dev/null
+++ b/packages/SystemUI/res/values-hy-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-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..a787983
--- /dev/null
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"Որոնել"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Ֆոտոխցիկ"</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_location" msgid="4577282329866813100">"Տեղադրությունը՝ <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="dessert_case" msgid="1295161776223959221">"Dessert Case"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"Միայն ուղղաձիգ"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Միայն հորիզոնական"</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_remote_display_no_connection_label" msgid="372107699274391290">"Հեռակա էկրան"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Պայծառություն"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Ինքնաշխատ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Գունաշրջման ռեժիմ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Ընդլայնված ցայտունության ռեժիմ"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Գույների կարգավորման ռեժիմ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ՎԵՐՋԻՆՆԵՐԸ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ցանցը կարող է\nվերահսկվել"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Սահեցրեք ձախ` <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 6a702b9..13fc534 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Utama"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Apl terbaru"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Telusuri"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tombol beralih metode masukan."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tombol perbesar/perkecil kompatibilitas."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Perbesar dari layar kecil ke besar."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Baterai <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Mode 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_location" msgid="4577282329866813100">"Lokasi <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm disetel ke <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data 2G-3G dinonaktifkan"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data 4G dinonaktifkan"</string>
@@ -164,28 +165,29 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Etalase Hidangan Penutup"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Lamunan"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Mode pesawat"</string>
     <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Mengisi baterai, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
-    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Ditagih"</string>
+    <string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Terisi"</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> Perangkat)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth Mati"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Kecerahan"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Terkunci ke Potret"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Terkunci ke Lanskap"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metode Masukan"</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_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>
@@ -196,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Tidak Tersambung"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Tidak Ada Jaringan"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Mati"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Tampilan Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Layar Nirkabel"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Layar Transmisi"</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.\nGesek ke bawah sekali lagi untuk kontrol sistem."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Gesek tepi layar untuk membuka bilah"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Gesek dari bagian tepi layar untuk membuka bilah sistem"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode inversi warna"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode kontras yang disempurnakan"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode koreksi warna"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"TERBARU"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Jaringan bisa\ndiawasi"</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_left" msgid="7207478719805562165">"Geser ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index a350d38..7671ef1 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Applicazioni recenti"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Cerca"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Fotocamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Pulsante per cambiare metodo di immissione."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Pulsante zoom compatibilità."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom inferiore per schermo più grande."</string>
@@ -116,8 +116,8 @@
     <string name="accessibility_two_bars" msgid="6437363648385206679">"Due barre."</string>
     <string name="accessibility_three_bars" msgid="2648241415119396648">"Tre barre."</string>
     <string name="accessibility_signal_full" msgid="9122922886519676839">"Massimo segnale."</string>
-    <string name="accessibility_desc_on" msgid="2385254693624345265">"Attivo."</string>
-    <string name="accessibility_desc_off" msgid="6475508157786853157">"Non attivo."</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">"Connesso."</string>
     <string name="accessibility_data_connection_gprs" msgid="1606477224486747751">"GPRS"</string>
     <string name="accessibility_data_connection_1x" msgid="994133468120244018">"1 X"</string>
@@ -155,6 +155,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batteria: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modalità aereo: <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_location" msgid="4577282329866813100">"Posizione: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Allarme impostato per: <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dati 2G-3G disattivati"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dati 4G disattivati"</string>
@@ -166,12 +167,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Vetrina di dolci"</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">"Modalità aereo"</string>
@@ -183,8 +185,10 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Luminosità"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Bloccato in verticale"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Bloccato in orizzontale"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metodo di immissione"</string>
-    <string name="quick_settings_location_label" msgid="5011327048748762257">"Posizione"</string>
+    <string name="quick_settings_location_label" msgid="5011327048748762257">"Geolocalizzazione"</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>
@@ -196,12 +200,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Non connesso"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nessuna rete"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi disattivato"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Display Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Visualizzazione wireless"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Trasmetti schermo"</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.\nFai scorrere di nuovo verso il basso per visualizzare i controlli del sistema."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Fai scorrere il bordo dello schermo per visualizzare la barra"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Fai scorrere il dito dal bordo dello schermo per visualizzare la barra di sistema"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modalità inversione colori"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modalità di contrasto avanzata"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modalità di correzione del colore"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"MESSAGGI RECENTI"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La rete potrebbe\nessere monitorata"</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_left" msgid="7207478719805562165">"A sinistra per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b274dcc..798e8c3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -22,12 +22,12 @@
     <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>
+    <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>
+    <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>
@@ -35,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>
@@ -44,25 +44,23 @@
     <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="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="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="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>
@@ -70,19 +68,21 @@
     <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="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_recent" msgid="8571350598987952883">"אפליקציות אחרונות"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"חפש"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"מצלמה"</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_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>
@@ -98,17 +98,17 @@
     <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">"Wi-Fi כבוי."</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">"שלושה פסים של Wi-Fi."</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_wifi_off" msgid="3177380296697933627">"‏Wi-Fi כבוי."</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">"‏שלושה פסים של Wi-Fi."</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>
@@ -130,57 +130,61 @@
     <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"נדידה"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"קצה"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
-    <string name="accessibility_no_sim" msgid="8274017118472455155">"אין כרטיס SIM."</string>
-    <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"שיתוף אינטרנט בין ניידים של Bluetooth"</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">"TeleTypewriter מופעל"</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_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_bluetooth" msgid="5749054971341882340">"‏Bluetooth ‏<xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_location" msgid="4577282329866813100">"המיקום <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_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="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="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="dessert_case" msgid="1295161776223959221">"מזנון קינוחים"</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_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_rotation_locked_portrait_label" msgid="1553131290066230775">"נעול במצב הצגה לאורך"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"נעול במצב הצגה לרוחב"</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>
@@ -193,13 +197,16 @@
     <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">"תצוגת Wi-Fi"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"‏Wi-Fi כבוי"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"העבר מסך"</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="hideybar_confirmation_message" msgid="9050869548951044371">"החלק מקצה המסך כדי להציג את הסרגל"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"החלק מקצה המסך כדי להציג את סרגל המערכת"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"מצב היפוך צבעים"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"מצב ניגודיות מוגברת"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"מצב תיקון צבע"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"אחרונים"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ייתכן שהרשת\nמנוטרת"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"חיפוש"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"הסט למעלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"הסט שמאלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 7392ae9..c5070a8 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"ホーム"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"メニュー"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"最近使ったアプリ"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"検索"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"カメラ"</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>
@@ -155,6 +155,7 @@
     <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_location" msgid="4577282329866813100">"現在地: <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>
@@ -166,12 +167,13 @@
     <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="dessert_case" msgid="1295161776223959221">"デザートケース"</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>
@@ -183,6 +185,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"縦向きにロック済み"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"横向きにロック済み"</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">"現在地OFF"</string>
@@ -196,12 +200,15 @@
     <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 OFF"</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_remote_display_no_connection_label" msgid="372107699274391290">"画面のキャスト"</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="hideybar_confirmation_message" msgid="9050869548951044371">"バーを表示するには、画面の端からスワイプします"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"システムバーを表示するには、画面の端からスワイプします"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"色反転モード"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"拡張コントラストモード"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色補正モード"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ネットワークが監視される\n場合があります"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"左にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka-land/strings.xml b/packages/SystemUI/res/values-ka-land/strings.xml
new file mode 100644
index 0000000..3f20938
--- /dev/null
+++ b/packages/SystemUI/res/values-ka-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-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..bbdce19
--- /dev/null
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"ძიება"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"კამერა"</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_location" msgid="4577282329866813100">"მდებარეობა <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="dessert_case" msgid="1295161776223959221">"სადესერტო ყუთი"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"პორტრეტზე ჩაკეტილი"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"ლანდშაფტზე ჩაკეტილი"</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_remote_display_no_connection_label" msgid="372107699274391290">"Cast Screen"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"განათება"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ავტომატურად"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"ფერთა ინვერსიის რეჟიმი"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"გაუმჯობესებული კონტრასტის რეჟიმი"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"ფერთა კორექციის რეჟიმი"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ბოლო დროის"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"შესაძლოა ქსელზე\nმონიტორინგი ხორციელდებოდეს"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"გაასრიალეთ მარცხნივ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-km-land/strings.xml b/packages/SystemUI/res/values-km-land/strings.xml
new file mode 100644
index 0000000..f148cc3
--- /dev/null
+++ b/packages/SystemUI/res/values-km-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-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..61ca77d
--- /dev/null
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"ស្វែងរក"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"ម៉ាស៊ីន​ថត"</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_location" msgid="4577282329866813100">"ទីតាំង <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="dessert_case" msgid="1295161776223959221">"ករណី Dessert"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"ចាក់​សោ​​បញ្ឈរ"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"ចាក់​សោ​​​ផ្ដេក"</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_remote_display_no_connection_label" msgid="372107699274391290">"ចាត់​ថ្នាក់​អេក្រង់"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ពន្លឺ"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ស្វ័យប្រវត្តិ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"របៀប​​បញ្ច្រាស​ពណ៌"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"របៀប​កម្រិត​ពណ៌​ប្រ​សើ​រ​ឡើង"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"របៀប​កែ​ពណ៌"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ថ្មីៗ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញ​អាច​\nត្រូវ​បាន​ត្រួតពិនិត្យ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"រុញ​ទៅ​ឆ្វេង​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1437601..8108daa 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"홈"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"메뉴"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"최근에 사용한 앱"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"검색"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"카메라"</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>
@@ -153,6 +153,7 @@
     <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_location" msgid="4577282329866813100">"위치 <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>
@@ -164,12 +165,13 @@
     <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="dessert_case" msgid="1295161776223959221">"디저트 케이스"</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>
@@ -181,11 +183,11 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"세로 모드로 고정됨"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"가로 모드로 고정됨"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"입력 방법"</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_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>
@@ -196,12 +198,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"화면 전송"</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="hideybar_confirmation_message" msgid="9050869548951044371">"화면 가장자리에서 스와이프하여 표시줄 표시"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"화면 가장자리에서 스와이프하여 시스템 표시줄 표시"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"색상 반전 모드"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"향상된 대비 모드"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"색상 보정 모드"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"최근"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"네트워크가\n모니터링될 수 있음"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"검색"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 왼쪽으로 슬라이드"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-land/arrays.xml b/packages/SystemUI/res/values-land/arrays.xml
index 74a6c81..c32ce12 100644
--- a/packages/SystemUI/res/values-land/arrays.xml
+++ b/packages/SystemUI/res/values-land/arrays.xml
@@ -22,21 +22,21 @@
     <array name="navbar_search_targets">
         <item>@null</item>
         <item>@null</item>
-        <item>@*android:drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_action_assist_generic</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_target_descriptions">
         <item>@null</item>
         <item>@null</item>
-        <item>@*android:string/description_target_search</item>
+        <item>@string/description_target_search</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_direction_descriptions">
         <item>@null</item>
         <item>@null</item>
-        <item>@*android:string/description_direction_left</item>
+        <item>@string/description_direction_left</item>
         <item>@null</item>
     </array>
 
diff --git a/packages/SystemUI/res/values-lo-land/strings.xml b/packages/SystemUI/res/values-lo-land/strings.xml
new file mode 100644
index 0000000..a838a15
--- /dev/null
+++ b/packages/SystemUI/res/values-lo-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-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..c2e5990
--- /dev/null
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"ຊອກຫາ"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"ກ້ອງ"</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_location" msgid="4577282329866813100">"ສະ​ຖານ​ທີ່ <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="dessert_case" msgid="1295161776223959221">"ກ່ອງຂອງຫວານ"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"ລັອກເປັນຮູບລວງຕັ້ງ"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"ລັອກເປັນຮູບລວງນອນ"</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_remote_display_no_connection_label" msgid="372107699274391290">"ດຶງໜ້າຈໍ"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ຄວາມແຈ້ງ"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ອັດຕະໂນມັດ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"ໂໝດສະລັບສີ"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"ໂໝດຄວາມຕ່າງແສງ"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"ໂໝດການແກ້ໄຂສີ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ບໍ່​ດົນ​ມາ​ນີ້"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ເຄືອຄ່າຍອາດ\nຖືກຕິດຕາມ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"ເລື່ອນໄປທາງຊ້າຍເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index bf8662a..1d8b051 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -71,13 +69,15 @@
     <string name="screenshot_failed_title" msgid="705781116746922771">"Nepavyko užfiksuoti ekrano kopijos."</string>
     <string name="screenshot_failed_text" msgid="8134011269572415402">"Nepavyko išsaugoti ekrano kopijos. Gali būti naudojama atmintis."</string>
     <string name="usb_preference_title" msgid="6551050377388882787">"USB failo perdavimo parinktys"</string>
-    <string name="use_mtp_button_title" msgid="4333504413563023626">"Įmontuoti kaip medijos grotuvą (MTP)"</string>
+    <string name="use_mtp_button_title" msgid="4333504413563023626">"Įmontuoti kaip medijos leistuvą (MTP)"</string>
     <string name="use_ptp_button_title" msgid="7517127540301625751">"Įmontuoti kaip fotoaparatą (PTP)"</string>
     <string name="installer_cd_button_title" msgid="2312667578562201583">"Įdiegti „Mac“ skirtą „Android“ perkėl. priem. pr."</string>
     <string name="accessibility_back" msgid="567011538994429120">"Atgal"</string>
     <string name="accessibility_home" msgid="8217216074895377641">"Pagrindinis"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Meniu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Naujausios programos"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Ieškoti"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparatas"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Perjungti įvesties metodo mygtuką."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Suderinamumo priartinimo mygtukas."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Padidinti ekraną."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Akumuliatorius <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Lėktuvo režimas <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_location" msgid="4577282329866813100">"Vietovė – <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Signalas nustatytas <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G duomenys neleidžiami"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G duomenys neleidžiami"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Desertų dėklas"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Svajonė"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Eternetas"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Lėktuvo režimas"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Skaistis"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Užrakinta stačia padėtis"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Užrakinta gulsčia padėtis"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Įvesties metodas"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Vietovė"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Vietovė išjungta"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Neprisijungta"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Tinklo nėra"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"„Wi-Fi“ išjungta"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"„Wi-Fi“ pateiktis"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Belaidis rodymas"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Perduoti ekraną"</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.\nJei norite naudoti sistemos valdiklius, perbraukite žemyn dar kartą."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Jei norite, kad būtų rodoma juosta, perbraukite ekrano krašte"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Jei norite, kad būtų rodoma sistemos juosta, perbraukite iš ekrano krašto"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Spalvų inversijos režimas"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Patobulinto kontrasto režimas"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Spalvų taisymo režimas"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"PASTARIEJI"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tinklas gali\nbūti stebimas"</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_left" msgid="7207478719805562165">"Slyskite į kairę link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index b96a786..603fa1a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Sākums"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Izvēlne"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Nesen izmantotās lietotnes"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Meklēt"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ievades metodes maiņas poga."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Saderības tālummaiņas poga."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Veikt tālummaiņu no mazāka ekrāna uz lielāku."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Akumulatora statuss: <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Lidojuma režīma statuss: <xliff:g id="STATE">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"Bluetooth statuss: <xliff:g id="STATE">%s</xliff:g>"</string>
+    <string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Atrašanās vieta: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Signāls ir iestatīts uz: <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G–3G dati atspējoti"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G dati atspējoti"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Saldo ēdienu stends"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Ekrānsaudzētājs"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Tīkls Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Lidojuma režīms"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Spilgtums"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Fiksēts portreta režīmā"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Fiksēts ainavas režīmā"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Ievades metode"</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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nav izveidots savienojums"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nav tīkla"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ir izslēgts"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi displejs"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezvadu attēlošana"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Apraides ekrāns"</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.\nVēlreiz velciet, lai tiktu parādītas sistēmas vadīklas."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Velciet no ekrāna malas, lai piekļūtu joslai."</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Velciet no ekrāna malas, lai piekļūtu sistēmas joslai."</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Krāsu inversijas režīms"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Uzlabota kontrasta režīms"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Krāsu korekcijas režīms"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"JAUNĀKIE"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tīkls var\ntikt uzraudzīts"</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_left" msgid="7207478719805562165">"Velciet pa kreisi, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn-land/strings.xml b/packages/SystemUI/res/values-mn-land/strings.xml
new file mode 100644
index 0000000..ec4616f
--- /dev/null
+++ b/packages/SystemUI/res/values-mn-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-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..110cfd2
--- /dev/null
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"Хайх"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Камер"</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_location" msgid="4577282329866813100">"Байршил <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="dessert_case" msgid="1295161776223959221">"Амттаны хайрцаг"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"Босоо байдлаар түгжсэн"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Хэвтээ байдлаар түгжсэн"</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_remote_display_no_connection_label" msgid="372107699274391290">"Дамжуулах дэлгэц"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Тодрол"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОМАТ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Өнгө урвуулах горим"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Сайжруулсан ялгаралтай горим"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Өнгө залруулах горим"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"СҮҮЛИЙН"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Сүлжээ хянагдаж\nбайж болзошгүй"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> хийх зүүнлүү гулсуулах."</string>
+</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..62c90ab
--- /dev/null
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -0,0 +1,212 @@
+<?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_search_light" msgid="1103867596330271848">"Cari"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</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_location" msgid="4577282329866813100">"Lokasi <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="dessert_case" msgid="1295161776223959221">"Bekas Pencuci Mulut"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"Dikunci kepada Potret"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Dikunci kepada Landskap"</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_remote_display_no_connection_label" msgid="372107699274391290">"Skrin Cast"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod penyongsangan warna"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod kontras dipertingkat"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod pembetulan warna"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"TERBAHARU"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rangkaian mungkin\nboleh dipantau"</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_left" msgid="7207478719805562165">"Luncurkan ke kiri untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+</resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
deleted file mode 100644
index 5312ccb..0000000
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ /dev/null
@@ -1,207 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/**
- * Copyright (c) 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); 
- * you may not use this file except in compliance with the License. 
- * You may obtain a copy of the License at 
- *
- *     http://www.apache.org/licenses/LICENSE-2.0 
- *
- * Unless required by applicable law or agreed to in writing, software 
- * distributed under the License is distributed on an "AS IS" BASIS, 
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- * See the License for the specific language governing permissions and 
- * limitations under the License.
- */
- -->
-
-<resources 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="compat_mode_help_header" msgid="7969493989397529910">"Zum keserasian"</string>
-    <string name="compat_mode_help_body" msgid="4946726776359270040">"Apabila apl direka untuk skrin yang lebih kecil, kawalan zum akan muncul di tepi jam."</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_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>
-    <!-- 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">"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="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.\nLeret ke bawah sekali lagi untuk mendapatkan kawalan sistem."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Leret ke bahagian tepi skrin untuk menampakkan bar"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Leret dari tepi skrin untuk menampakkan bar sistem"</string>
-</resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 778be83..0e914ea 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -22,7 +22,7 @@
     <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_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_recent_inspect_item_title" msgid="7793624864528818569">"Info om appen"</string>
     <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Ingen nylige apper"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Avvis nylige apper"</string>
   <plurals name="status_bar_accessibility_recent_apps">
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Startside"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Meny"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Nylige apper"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Søk"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Bytt knapp for inndatametode."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Zoomknapp for kompatibilitet."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom fra mindre til større skjerm."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batteri – <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Flymodus – <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_location" msgid="4577282329866813100">"Posisjon <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmen ble stilt for <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G-data er deaktivert"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-data er deaktivert"</string>
@@ -164,12 +165,13 @@
     <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="status_bar_notification_inspect_item_title" msgid="1163547729015390250">"Info om appen"</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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessertmonter"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Dagdrøm"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Flymodus"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Lysstyrke"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Låst til stående format"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Låst til liggende format"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inndatametode"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Sted"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Posisjon av"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ikke tilkoblet"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Ingen nettverk"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi er av"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi-skjerm"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådløs skjerm"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Cast skjermen"</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.\nSveip nedover igjen for å gå til systemkontrollene."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Sveip på kanten av skjermen for å få frem feltet"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Sveip fra kanten på skjermen for å få frem systemfeltet"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus for fargeinvertering"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Forbedret kontrastmodus"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus for fargekorrigering"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NYLIGE"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nettverket kan\nvære overvåket"</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_left" msgid="7207478719805562165">"Dra til venstre for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne-land/strings.xml b/packages/SystemUI/res/values-ne-land/strings.xml
new file mode 100644
index 0000000..8d5286e
--- /dev/null
+++ b/packages/SystemUI/res/values-ne-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-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..19e2744
--- /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 ab77839..032fa34 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -61,8 +61,6 @@
     <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">"Screenshot opslaan..."</string>
     <string name="screenshot_saving_title" msgid="8242282144535555697">"Screenshot opslaan..."</string>
     <string name="screenshot_saving_text" msgid="2419718443411738818">"Screenshot wordt opgeslagen."</string>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Startpagina"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Recente apps"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Zoeken"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knop voor wijzigen invoermethode."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knop voor compatibiliteitszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kleiner scherm uitzoomen naar groter scherm."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Accu: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Vliegmodus: <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_location" msgid="4577282329866813100">"Locatie <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm is ingesteld op <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-/3G-gegevens uitgeschakeld"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G-gegevens uitgeschakeld"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessertshowcase"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Dagdroom"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Vliegmodus"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Helderheid"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Vergrendeld in staande stand"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Vergrendeld in liggende stand"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Invoermethode"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Locatie"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Locatie uit"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Niet verbonden"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Geen netwerk"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wifi uit"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wifi-weergave"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Draadloze display"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Scherm casten"</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.\nVeeg nogmaals met uw vinger omlaag om de systeembesturingselementen weer te geven."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Veeg vanaf de rand om balk weer te geven"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Veeg vanaf de rand van het scherm om de systeembalk weer te geven"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus voor kleurinversie"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modus voor verbeterd contrast"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus voor kleurcorrectie"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTE"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk kan\nworden gecontroleerd"</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_left" msgid="7207478719805562165">"Veeg naar links voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index c94cfc8..c21230c 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Ekran główny"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Ostatnie aplikacje"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Szukaj"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Aparat"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Przycisk przełączania metody wprowadzania."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Przycisk powiększenia na potrzeby zgodności."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Powiększa mniejszy ekran do większego."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Bateria: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Tryb samolotowy: <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_location" msgid="4577282329866813100">"Lokalizacja <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm ustawiony na <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Wyłączono transmisję danych 2G/3G"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Wyłączono transmisję danych 4G"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Półka ze słodkościami"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Wygaszacz ekranu"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Tryb samolotowy"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Jasność"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Zablokowano w orientacji pionowej"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Zablokowano w orientacji poziomej"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metoda wprowadzania"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokalizacja"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokalizacja wyłączona"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Brak połączenia"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Brak sieci"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wyłącz Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wyświetlacz Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wyświetlacz bezprzewodowy"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Ekran Cast"</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ół.\nPrzesuń jeszcze raz w dół, by otworzyć ustawienia systemowe."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Przesuń palcem od krawędzi ekranu, by odkryć pasek"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Przesuń palcem od krawędzi ekranu, by odkryć pasek systemu"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Tryb odwrócenia kolorów"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tryb zwiększonego kontrastu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Tryb korekcji kolorów"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"OSTATNIE"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieć może być\nmonitorowana"</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_left" msgid="7207478719805562165">"Przesuń w lewo: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c106329..771daf2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Página inicial"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Aplicações recentes"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Pesquisar"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Câmara"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alternar botão de método de introdução."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão zoom de compatibilidade."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zoom menor para ecrã maior."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Bateria <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modo de Avião <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_location" msgid="4577282329866813100">"Localização <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Os dados 2G-3G estão desativados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Os dados 4G estão desativados"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Vitrina de sobremesas"</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">"Modo de avião"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brilho"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Bloqueado em retrato"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Bloqueado em paisagem"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de Introduçã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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Não Ligado"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Sem Rede"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Desligado"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Visualização Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Display Sem Fios"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Transmitir ecrã"</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.\nDeslize novamente para baixo para aceder aos controlos do sistema."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Deslize da extremidade do ecrã para revelar a barra"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Deslize da extremidade do ecrã para revelar a barra do sistema"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cor"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste melhorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode ser\nmonitorizada"</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_left" msgid="7207478719805562165">"Deslize para a esquerda para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 91e7f02..b643bae 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Página inicial"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Aplicativos recentes"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Pesquisar"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Câmera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Alterar botão do método de entrada."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Botão de zoom da compatibilidade."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Aumentar a tela com zoom."</string>
@@ -155,6 +155,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Bateria <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Modo avião <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_location" msgid="4577282329866813100">"Localização <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarme definido para <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dados 2G e 3G desativados"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dados 4G desativados"</string>
@@ -166,12 +167,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Mostruário de sobremesas"</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">"Modo avião"</string>
@@ -183,11 +185,11 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brilho"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Bloqueado no modo retrato"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Bloqueado no modo paisagem"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Método de entrada"</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_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>
@@ -198,12 +200,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Não conectado"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Sem rede"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi desligado"</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">"Display sem fio"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Transmitir tela"</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.\nDeslize para baixo novamente para acessar os controles do sistema."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Deslize a borda da tela para ver a barra"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Deslize a partir da borda da tela ver a barra do sistema"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cores"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste aprimorado"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode estar\nsob monitoração"</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_left" msgid="7207478719805562165">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para a esquerda."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index d7772ed..33cb355 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -92,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) -->
@@ -126,6 +122,10 @@
     <skip />
     <!-- no translation found for accessibility_recent (8571350598987952883) -->
     <skip />
+    <!-- no translation found for accessibility_search_light (1103867596330271848) -->
+    <skip />
+    <!-- no translation found for accessibility_camera_button (8064671582820358152) -->
+    <skip />
     <!-- no translation found for accessibility_ime_switch_button (5032926134740456424) -->
     <skip />
     <!-- no translation found for accessibility_compatibility_zoom_button (8461115318742350699) -->
@@ -276,6 +276,8 @@
     <skip />
     <!-- no translation found for accessibility_quick_settings_bluetooth (5749054971341882340) -->
     <skip />
+    <!-- no translation found for accessibility_quick_settings_location (4577282329866813100) -->
+    <skip />
     <!-- no translation found for accessibility_quick_settings_alarm (3959908972897295660) -->
     <skip />
     <!-- no translation found for data_usage_disabled_dialog_3g_title (5257833881698644687) -->
@@ -298,6 +300,8 @@
     <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) -->
@@ -308,7 +312,7 @@
     <skip />
     <!-- no translation found for accessibility_rotation_lock_on_portrait (5809367521644012115) -->
     <skip />
-    <!-- no translation found for jelly_bean_dream_name (5992026543636816792) -->
+    <!-- no translation found for dessert_case (1295161776223959221) -->
     <skip />
     <!-- no translation found for start_dreams (7219575858348719790) -->
     <skip />
@@ -332,6 +336,10 @@
     <skip />
     <!-- no translation found for quick_settings_rotation_locked_label (8058646447242565486) -->
     <skip />
+    <!-- no translation found for quick_settings_rotation_locked_portrait_label (1553131290066230775) -->
+    <skip />
+    <!-- no translation found for quick_settings_rotation_locked_landscape_label (7216265671276086593) -->
+    <skip />
     <!-- no translation found for quick_settings_ime_label (7073463064369468429) -->
     <skip />
     <!-- no translation found for quick_settings_location_label (5011327048748762257) -->
@@ -358,20 +366,26 @@
     <skip />
     <!-- no translation found for quick_settings_wifi_off_label (7558778100843885864) -->
     <skip />
-    <!-- no translation found for quick_settings_wifi_display_label (6893592964463624333) -->
-    <skip />
-    <!-- no translation found for quick_settings_wifi_display_no_connection_label (2355298740765736918) -->
+    <!-- no translation found for quick_settings_remote_display_no_connection_label (372107699274391290) -->
     <skip />
     <!-- no translation found for quick_settings_brightness_dialog_title (8599674057673605368) -->
     <skip />
     <!-- no translation found for quick_settings_brightness_dialog_auto_brightness_label (5064982743784071218) -->
     <skip />
-    <!-- no translation found for status_bar_help_title (1199237744086469217) -->
+    <!-- no translation found for quick_settings_inversion_label (1666358784283020762) -->
     <skip />
-    <!-- no translation found for status_bar_help_text (7874607155052076323) -->
+    <!-- no translation found for quick_settings_contrast_label (3319507551689108692) -->
     <skip />
-    <!-- no translation found for hideybar_confirmation_message (9050869548951044371) -->
+    <!-- no translation found for quick_settings_color_space_label (853443689745584770) -->
     <skip />
-    <!-- no translation found for hideybar_confirmation_message_long (7117692795163620626) -->
+    <!-- no translation found for recents_empty_message (2269156590813544104) -->
+    <skip />
+    <!-- no translation found for ssl_ca_cert_warning (9005954106902053641) -->
+    <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_left (7207478719805562165) -->
     <skip />
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 42e2d48..87f9c0c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Ecranul de pornire"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Meniu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Aplicaţii recente"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Căutați"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Cameră foto"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Buton pentru comutarea metodei de introducere."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Buton zoom pentru compatibilitate."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Faceţi zoom de la o imagine mai mică la una mai mare."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Baterie <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Mod 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_location" msgid="4577282329866813100">"Locație: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmă setată pentru <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Datele 2G-3G au fost dezactivate"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Datele 4G au fost dezactivate"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Vitrina cu dulciuri"</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">"Mod Avion"</string>
@@ -181,11 +183,11 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Luminozitate"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Blocat la afișarea „portret”"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Blocat la afișarea „peisaj”"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metodă de introducere"</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_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>
@@ -196,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Neconectat"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Nicio reţea"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi deconectat"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Afişaj Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ecran wireless"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Ecran de afișare a transmisiunii"</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.\nGlisaţi în jos din nou pentru comenzile sistemului."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Glisați dinspre marginea ecranului pentru a afișa bara"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Glisați dinspre marginea ecranului pentru a afișa bara de sistem"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod de inversare a culorilor"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod contrast îmbunătățit"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod de corectare a culorilor"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTE"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rețeaua poate\nfi monitorizată"</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_left" msgid="7207478719805562165">"Glisaţi spre stânga pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 233fee8a8..e79a0dd 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Домой"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Недавние приложения"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Поиск"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</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>
@@ -155,6 +155,7 @@
     <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_location" msgid="4577282329866813100">"Доступ к геоданным <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>
@@ -166,12 +167,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Коробка со сладостями"</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>
@@ -185,11 +187,11 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Только вертикально"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Только горизонтально"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Способ ввода"</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_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>
@@ -200,12 +202,15 @@
     <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">"Wi-Fi-монитор"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"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="hideybar_confirmation_message" msgid="9050869548951044371">"Чтобы открыть панель, проведите пальцем от края к центру экрана"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Чтобы открыть панель навигации, проведите пальцем от края к центру экрана"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Инверсия цвета"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Контрастность"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Коррекция цвета"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"НЕДАВНИЕ СООБЩЕНИЯ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Действия в сети\nмогут отслеживаться"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Проведите влево, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si-land/strings.xml b/packages/SystemUI/res/values-si-land/strings.xml
new file mode 100644
index 0000000..b5aba2a
--- /dev/null
+++ b/packages/SystemUI/res/values-si-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-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 c54540c..d39c8bd 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -24,7 +24,7 @@
     <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>
-    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Odmietnuť nové aplikácie"</string>
+    <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Zatvoriť nedávne aplikácie"</string>
   <plurals name="status_bar_accessibility_recent_apps">
     <item quantity="one" msgid="5854176083865845541">"1 nová aplikácia"</item>
     <item quantity="other" msgid="1040784359794890744">"Počet nových aplikácií: %d"</item>
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Plocha"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Nové aplikácie"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Hľadať"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparát"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Tlačidlo prepnutia metódy vstupu."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Tlačidlo úpravy veľkosti z dôvodu kompatibility."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zväčšiť menší obrázok na väčšiu obrazovku."</string>
@@ -155,6 +155,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batéria: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Režim V lietadle: <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_location" msgid="4577282329866813100">"Poloha: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Budík nastavený na <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Dátové prenosy 2G a 3G sú zakázané"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Dátové prenosy 4G sú zakázané"</string>
@@ -166,12 +167,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Pult s dezertami"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Šetrič obrazovky"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Režim V lietadle"</string>
@@ -183,6 +185,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Jas"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Uzamknuté na výšku"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Uzamknuté na šírku"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Metóda vstupu"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Poloha"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Poloha vypnutá"</string>
@@ -196,12 +200,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Nepripojené"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Žiadna sieť"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Sieť Wi-Fi je vypnutá"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Obrazovka Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Bezdrôtový displej"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Vzdialená obrazovka"</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.\nAk posuniete prstom nadol ešte raz, zobrazia sa ovládacie prvky systému."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Panel zobrazíte posunutím cez okraj obrazovky"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Systémový panel zobrazíte posunutím cez okraj obrazovky"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim prevrátenia farieb"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekcie farieb"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NEDÁVNE"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieť môže byť\nmonitorovaná"</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_left" msgid="7207478719805562165">"Prejdite prstom doľava: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 3fc4882..c49b6c2 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Začetni zaslon"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Meni"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Nedavni programi"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Iskanje"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Fotoaparat"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Gumb za preklop načina vnosa."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Gumb povečave za združljivost."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Povečava manjšega na večji zaslon."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Baterija: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Letalski način: <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_location" msgid="4577282329866813100">"Lokacija: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm je nastavljen na <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Podatki 2G-3G so onemogočeni"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Podatki 4G so onemogočeni"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Vitrina za sladice"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Sanjarjenje"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Način za letalo"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Svetlost"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Zaklenjeno na navpično postavitev"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Zaklenjeno na ležečo postavitev"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Način vnosa"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Lokacija"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Lokacija izklopljena"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Povezava ni vzpostavljena"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Ni omrežja"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi izklopljen"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Zaslon Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Prikaz brezžičnih naprav"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Zaslon za predvajanje"</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.\nZa prikaz sistemskih kontrolnikov znova povlecite navzdol."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Vrstico prikažete tako, da povlečete z roba zaslona"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Sistemsko vrstico prikažete tako, da povlečete z roba zaslona"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije barv"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način izboljšanega kontrasta"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Način popravljanja barv"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNI"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Omrežje je\nlahko spremljano"</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_left" msgid="7207478719805562165">"Povlecite v levo za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 7ba2da5..89bc3c5 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Почетна"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Мени"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Недавне апликације"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Претражите"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</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>
@@ -153,6 +153,7 @@
     <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_location" msgid="4577282329866813100">"Локација је <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>
@@ -164,12 +165,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Витрина са посластицама"</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>
@@ -181,6 +183,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Закључано на Усправно"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Закључано на Водоравно"</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>
@@ -194,12 +198,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"Пребаци екран"</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="hideybar_confirmation_message" msgid="9050869548951044371">"Превуците по ивици екрана да би се приказала трака"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Превуците од ивице екрана да би се приказала системска трака"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим инверзије боје"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим унапређеног контраста"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим корекције боје"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"НАЈНОВИЈЕ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежа се можда\nнадгледа"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Превуците улево за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 022e2f2..1b47be5 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -23,7 +23,7 @@
     <string name="status_bar_clear_all_button" msgid="7774721344716731603">"Ta bort"</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>
+    <string name="status_bar_no_recent_apps" msgid="6576392951053994640">"Inga aktiva appar"</string>
     <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Avvisa nya appar"</string>
   <plurals name="status_bar_accessibility_recent_apps">
     <item quantity="one" msgid="5854176083865845541">"1 ny app"</item>
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Startsida"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Meny"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Senaste apparna"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Sök"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Knapp för byte av inmatningsmetod."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Knapp för kompatibilitetszoom."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Zooma mindre skärm till större."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Batteri <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Flygplansläge <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_location" msgid="4577282329866813100">"Plats <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarmet ringer <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data via 2G-3G har inaktiverats"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data via 4G har inaktiverats"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessertdisken"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Dagdröm"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Flygplansläge"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Ljusstyrka"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Låst i stående läge"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Låst i liggande läge"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Inmatningsmetod"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Plats"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Plats har inaktiverats"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Ej ansluten"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Inget nätverk"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi av"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Wi-Fi-skärm"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Trådlös skärm"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Överför skärmen"</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.\nDra nedåt igen om du vill visa systemkontroller."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Dra från kanten av skärmen om du vill visa fältet"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Dra från kanten av skärmen om du vill visa systemfältet"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Färginverteringsläge"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastförbättringsläge"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Färgkorrigeringsläge"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NYA"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nätverket kan\nvara övervakat"</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_left" msgid="7207478719805562165">"Dra åt vänster för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 27f556c..3702196 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -59,8 +59,6 @@
     <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>
@@ -76,6 +74,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Nyumbani"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menyu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Programu za hivi karibuni"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Tafuta"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Swichi kitufe cha mbinu ingizi."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Kichupo cha kukuza kwa utangamanifu"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Kuza kidogo kwa skrini kubwa."</string>
@@ -125,12 +125,12 @@
     <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">"Inatumia data nje mtandao wako"</string>
+    <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"Inatumia data nje mtandao wako wa kawaida"</string>
     <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Ukingo"</string>
     <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>
@@ -151,6 +151,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Betri <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Hali ya Ndege <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_location" msgid="4577282329866813100">"Mahali <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Kengele imewekwa <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Data ya 2G-3G imelemazwa"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Data ya 4G imelemazwa"</string>
@@ -162,28 +163,29 @@
     <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="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="dessert_case" msgid="1295161776223959221">"Sanduku la Vitindamlo"</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_battery_charged_label" msgid="8865413079414246081">"Betri imejaa"</string>
     <string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
     <string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (Vifaa <xliff:g id="NUMBER">%d</xliff:g>)"</string>
     <string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth Imezimwa"</string>
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Ung\'avu"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Imefungwa katika mkamo Wima"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Imefungwa katika mkao Mlalo"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Mbinu ya uingizaji"</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_location_label" msgid="5011327048748762257">"Kutambua Eneo"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Kitambua eneo kimezimwa"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Kifaa cha midia"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Simu za Dharura Pekee"</string>
@@ -194,12 +196,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Haijaunganishwa"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Hakuna Mtandao"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi Imezimwa"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Onyesho la Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Uonyeshaji Pasiwaya"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Utumaji wa Skrini"</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.\nTelezesha chini tena kupata vidhibiti vya mfumo."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Papasa kwa kasi kutoka ukingo wa skrini ili kuonyesha upau"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Papasa kwa kasi kutoka ukingo wa skrini ili kuonyesha upau wa mfumo"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Hali ya ugeuzaji kinyume wa rangi"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Hali ya utofautishaji ulioboreshwa"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Hali ya kusahihisha rangi"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"YA HIVI KARIBUNI"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Huenda mtandao\nunafuatiliwa"</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_left" msgid="7207478719805562165">"Sogeza kushoto kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw600dp/arrays.xml b/packages/SystemUI/res/values-sw600dp/arrays.xml
index f3a1771..21c4bd3 100644
--- a/packages/SystemUI/res/values-sw600dp/arrays.xml
+++ b/packages/SystemUI/res/values-sw600dp/arrays.xml
@@ -21,21 +21,21 @@
 
     <array name="navbar_search_targets">
         <item>@null</item>
-        <item>@*android:drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_action_assist_generic</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_target_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_target_search</item>
+        <item>@string/description_target_search</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_direction_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_direction_left</item>
+        <item>@string/description_direction_left</item>
         <item>@null</item>
         <item>@null</item>
     </array>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 48a02ab..b77f1e0 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -29,9 +29,6 @@
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
 
-    <!-- Whether rotation lock shows up in quick settings or not -->
-    <bool name="quick_settings_show_rotation_lock">true</bool>
-
     <!-- Enable the "flip settings" panel -->
     <bool name="config_hasFlipSettingsPanel">false</bool>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index dc643c4..0188563 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -74,10 +72,12 @@
     <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_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_search_light" msgid="1103867596330271848">"ค้นหา"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"กล้องถ่ายรูป"</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>
@@ -151,8 +151,9 @@
     <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_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_location" msgid="4577282329866813100">"สถานที่ <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>
@@ -164,15 +165,16 @@
     <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="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="dessert_case" msgid="1295161776223959221">"ชั้นแสดงของหวาน"</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_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>
@@ -181,6 +183,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"ล็อกที่แนวตั้ง"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"ล็อกที่แนวนอน"</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>
@@ -194,12 +198,15 @@
     <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">"ปิด WiFi"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"การแสดงผล WiFi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"จอแสดงผลไร้สาย"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"ส่งหน้าจอ"</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="hideybar_confirmation_message" msgid="9050869548951044371">"กวาดขอบของหน้าจอเพื่อแสดงแถบ"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"กวาดจากขอบของหน้าจอเพื่อแสดงแถบระบบ"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"โหมดการกลับสี"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"โหมดคอนทราสต์ที่ปรับปรุงแล้ว"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"โหมดการแก้ไขสี"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ล่าสุด"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"เครือข่ายอาจ\nถูกตรวจสอบ"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"เลื่อนไปทางซ้ายเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 0053be4..d7502cb 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Home"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Kamakailang apps"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Hanapin"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Ilipat ang button na pamamaraan ng pag-input."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Button ng zoom ng pagiging tugma."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Mag-zoom nang mas maliit sa mas malaking screen."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"<xliff:g id="STATE">%s</xliff:g> ng baterya."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"<xliff:g id="STATE">%s</xliff:g> ng Airplane Mode."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"<xliff:g id="STATE">%s</xliff:g> ng Bluetooth."</string>
+    <string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Lokasyon <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm set para sa <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Di pinapagana ang 2G-3G na data"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Hindi pinapagana ang 4G na data"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Dessert Case"</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">"Airplane mode"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Brightness"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Naka-lock sa Portrait"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Naka-lock sa Landscape"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Pamamaraan ng Pag-input"</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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Hindi Nakakonekta"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Walang Network"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Naka-off ang Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Display ng Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Wireless Display"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"I-cast ang Screen"</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.\nMuling mag-swipe pababa para sa mga kontrol ng system."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Mag-swipe sa gilid ng screen upang ipakita ang bar"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Mag-swipe mula sa gilid ng screen upang ipakita ang system bar"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode ng pag-invert ng kulay"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode na dinagdagan ang contrast"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode ng pagtatama ng kulay"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"MGA KAMAKAILAN"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Maaaring\nsinusubaybayan ang network"</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_left" msgid="7207478719805562165">"Mag-slide pakaliwa para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index f39f8bc..f56293b 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Ana sayfa"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Menü"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Son uygulamalar"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Ara"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Giriş yöntemini değiştirme düğmesi."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Uyumluluk zum düğmesi."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Daha büyük ekrana daha küçük yakınlaştır."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Pil <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Uçak Modu <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_location" msgid="4577282329866813100">"Konum: <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Alarm saati: <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"2G-3G verileri devre dışı bırakıldı"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"4G verileri devre dışı"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Tatlı Kutusu"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Hafif uyku"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Uçak modu"</string>
@@ -181,11 +183,11 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Parlaklık"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Dikey Görünüme Kilitlendi"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Yatay Görünüme Kilitlendi"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Giriş Yöntemi"</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_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>
@@ -196,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Bağlı Değil"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Ağ yok"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Kablosuz Kapalı"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Kablosuz Ekran"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Kablosuz Ekran"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Yayınlama 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.\nSistem denetimleri için tekrar hızlıca aşağı kaydırın."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Çubuğu görüntülemek için ekranın kenarından hızlıca kaydırın"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Sistem çubuğunu görüntülemek için ekranın kenarından hızlıca kaydırın"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Renk ters çevirme modu"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Geliştirilmiş kontrast modu"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Renk düzeltme modu"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"SON İLETİLER"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ağ izleniyor\nolabilir"</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_left" msgid="7207478719805562165">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için sola kaydırın."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 18f67a2..df94b26 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Головна"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Меню"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Останні програми"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Пошук"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Камера"</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>
@@ -153,6 +153,7 @@
     <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_location" msgid="4577282329866813100">"Місцезнаходження <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>
@@ -164,12 +165,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Вітрина десертів"</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>
@@ -181,6 +183,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Заблоковано в книжковій орієнтації"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Заблоковано в альбомній орієнтації"</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>
@@ -194,12 +198,15 @@
     <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_remote_display_no_connection_label" msgid="372107699274391290">"Транслювати екран"</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="hideybar_confirmation_message" msgid="9050869548951044371">"Гортайте від краю екрана, щоб з’явилась панель"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Проведіть пальцем від краю екрана, щоб з’явилась навігаційна панель"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим інверсії кольорів"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим посиленого контрасту"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим коригування кольору"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ОСТАННІ"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мережа може\nвідстежуватися"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"Проведіть пальцем ліворуч, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index acc7e0e..471cbd3 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"Trang chủ"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"Trình đơn"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"Ứng dụng gần đây"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Tìm kiếm"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Máy ảnh"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Nút chuyển phương thức nhập."</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Nút thu phóng khả năng tương thích."</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Thu phóng màn hình lớn hơn hoặc nhỏ hơn."</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Pin <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Chế độ trên máy bay <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_location" msgid="4577282329866813100">"Vị trí <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"Báo thức được đặt cho <xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"Đã tắt dữ liệu 2G-3G"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Đã tắt dữ liệu 4G"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Tủ trưng bày bánh ngọt"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Chế độ ngủ"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Chế độ trên máy bay"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Độ sáng"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Đã khóa ở chế độ xoay dọc"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Đã khóa ở chế độ xoay ngang"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Phương thức nhập"</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>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Chưa được kết nối"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Không có mạng nào"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Tắt Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Hiển thị Wi-Fi"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Hiển thị không dây"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Truyền màn hình"</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.\nVuốt lại xuống để hiển thị các điều khiển hệ thống."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Vuốt cạnh màn hình để hiển thị thanh"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Vuốt từ cạnh màn hình để hiển thị thanh hệ thống"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Chế độ đảo ngược màu sắc"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Chế độ tương phản tăng cường"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Chế độ hiệu chỉnh màu sắc"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"GẦN ĐÂY"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mạng có thể\nđược giám sát"</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_left" msgid="7207478719805562165">"Trượt sang trái để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0a62ee3..e53c1fb 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"主屏幕"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"菜单"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"最近运行的应用"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"搜索"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"相机"</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>
@@ -147,7 +147,7 @@
     <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_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>
@@ -155,23 +155,25 @@
     <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_location" msgid="4577282329866813100">"位置信息服务<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_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">"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="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">"果冻豆大乱舞"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"甜品盒"</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>
@@ -179,15 +181,15 @@
     <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_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_rotation_locked_label" msgid="8058646447242565486">"屏幕方向:锁定"</string>
+    <string name="quick_settings_rotation_locked_portrait_label" msgid="1553131290066230775">"锁定为纵向"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"锁定为横向"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"输入法"</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_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>
@@ -197,13 +199,16 @@
     <string name="quick_settings_wifi_label" msgid="9135344704899546041">"WLAN"</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">"WLAN 已关闭"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"WLAN 显示"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"无线显示"</string>
+    <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"WLAN:关闭"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"投射屏幕"</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="hideybar_confirmation_message" msgid="9050869548951044371">"从边缘向里滑可显示系统栏"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"从屏幕边缘向里滑动即可显示系统栏"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"颜色反转模式"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增强对比度模式"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"颜色校正模式"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"网络可能会\n受到监控"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"搜索"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"向上滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"向左滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
 </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..d4defa4
--- /dev/null
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -0,0 +1,214 @@
+<?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_search_light" msgid="1103867596330271848">"搜尋"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"相機"</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_location" msgid="4577282329866813100">"定位服務<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="dessert_case" msgid="1295161776223959221">"Dessert Case"</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_rotation_locked_portrait_label" msgid="1553131290066230775">"已鎖定為直向"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"已鎖定為橫向"</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_remote_display_no_connection_label" msgid="372107699274391290">"放送螢幕"</string>
+    <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
+    <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"色彩反轉模式"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校準模式"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"近期"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網絡可能會\n受到監控"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+</resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 2cfdb59..163ef2a 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -61,8 +61,6 @@
     <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>
@@ -78,6 +76,8 @@
     <string name="accessibility_home" msgid="8217216074895377641">"主螢幕"</string>
     <string name="accessibility_menu" msgid="316839303324695949">"選單"</string>
     <string name="accessibility_recent" msgid="8571350598987952883">"最近使用的應用程式"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"搜尋"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"相機"</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>
@@ -155,6 +155,7 @@
     <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_location" msgid="4577282329866813100">"定位服務<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>
@@ -166,12 +167,13 @@
     <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="dessert_case" msgid="1295161776223959221">"Dessert Case"</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>
@@ -183,6 +185,8 @@
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"已鎖定為縱向"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"已鎖定為橫向"</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>
@@ -195,13 +199,16 @@
     <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_wifi_off_label" msgid="7558778100843885864">"Wi-Fi 已關閉"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"投放螢幕"</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="hideybar_confirmation_message" msgid="9050869548951044371">"滑動螢幕邊緣即可顯示導覽列"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"從螢幕邊緣向內滑動即可顯示導覽列"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"彩色反轉模式"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校正模式"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"近期"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網路可能\n受到監控"</string>
+    <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
+    <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
+    <string name="description_direction_left" msgid="7207478719805562165">"向左滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 007d338..92e3382 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -24,10 +24,10 @@
     <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>
@@ -47,11 +47,11 @@
     <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>
@@ -61,8 +61,6 @@
     <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>
@@ -73,11 +71,13 @@
     <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>
     <string name="accessibility_recent" msgid="8571350598987952883">"Izinhlelo zokusebenza zakamuva"</string>
+    <string name="accessibility_search_light" msgid="1103867596330271848">"Sesha"</string>
+    <string name="accessibility_camera_button" msgid="8064671582820358152">"Ikhamela"</string>
     <string name="accessibility_ime_switch_button" msgid="5032926134740456424">"Vula indlela yokungena yenkinobho"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Inkinobho evumelekile yokusondeza"</string>
     <string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"Sondeza kancane esikrinini esikhudlwana"</string>
@@ -153,6 +153,7 @@
     <string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Ibhethri <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_airplane" msgid="4196876722090224753">"Imodi yendiza <xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_bluetooth" msgid="5749054971341882340">"I-Bluetooth <xliff:g id="STATE">%s</xliff:g>."</string>
+    <string name="accessibility_quick_settings_location" msgid="4577282329866813100">"Indawo i-<xliff:g id="STATE">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_alarm" msgid="3959908972897295660">"I-alamu isethiwe ngo-<xliff:g id="TIME">%s</xliff:g>."</string>
     <string name="data_usage_disabled_dialog_3g_title" msgid="5257833881698644687">"idatha ye-2G-3G ivimbelwe"</string>
     <string name="data_usage_disabled_dialog_4g_title" msgid="4789143363492682629">"Idatha ye-4G ivimbelwe"</string>
@@ -164,12 +165,13 @@
     <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="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>
-    <string name="jelly_bean_dream_name" msgid="5992026543636816792">"I-BeanFlinger"</string>
+    <string name="dessert_case" msgid="1295161776223959221">"Isikhwama soswidi"</string>
     <string name="start_dreams" msgid="7219575858348719790">"Ukuphupha emini"</string>
     <string name="ethernet_label" msgid="7967563676324087464">"I-Ethernet"</string>
     <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Isimo sendiza"</string>
@@ -181,6 +183,8 @@
     <string name="quick_settings_brightness_label" msgid="6968372297018755815">"Ukugqama"</string>
     <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_rotation_locked_portrait_label" msgid="1553131290066230775">"Kukhiyelwe ekumeni ngobude"</string>
+    <string name="quick_settings_rotation_locked_landscape_label" msgid="7216265671276086593">"Kukhiyelwe ekwakhiweni kwezwe"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Indlela yokungenayo"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Indawo"</string>
     <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Indawo ivaliwe"</string>
@@ -194,12 +198,15 @@
     <string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"Akuxhunyiwe"</string>
     <string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"Ayikho inethiwekhi"</string>
     <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"I-Wi-Fi icimile"</string>
-    <string name="quick_settings_wifi_display_label" msgid="6893592964463624333">"Ukuboniswa kwe-Wi-"</string>
-    <string name="quick_settings_wifi_display_no_connection_label" msgid="2355298740765736918">"Ukubonisa okungenazintambo"</string>
+    <string name="quick_settings_remote_display_no_connection_label" msgid="372107699274391290">"Isikrini sabalingisi"</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.\nSwayiphela phansi futhi ngezilawuli zesistimu."</string>
-    <string name="hideybar_confirmation_message" msgid="9050869548951044371">"Swayipha unqenqema wesikrini ukuze uveze ibha"</string>
-    <string name="hideybar_confirmation_message_long" msgid="7117692795163620626">"Swayipha kusukela kunqenqema ukuze uveze ibha yesistimu"</string>
+    <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Imodi yokuguqulwa kombala"</string>
+    <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Imodi ethuthukisiwe yokugqama"</string>
+    <string name="quick_settings_color_space_label" msgid="853443689745584770">"Imodi yokulungisa umbala"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"OKWAKAMUVA"</string>
+    <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Kungenzeka inethiwekhi\niqashiwe"</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_left" msgid="7207478719805562165">"Shelelisela ngakwesokunxele ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
 </resources>
diff --git a/packages/SystemUI/res/values/arrays.xml b/packages/SystemUI/res/values/arrays.xml
index bfb600d..1ce4983 100644
--- a/packages/SystemUI/res/values/arrays.xml
+++ b/packages/SystemUI/res/values/arrays.xml
@@ -21,21 +21,21 @@
     
     <array name="navbar_search_targets">
         <item>@null</item>
-        <item>@*android:drawable/ic_action_assist_generic</item>
+        <item>@drawable/ic_action_assist_generic</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_target_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_target_search</item>
+        <item>@string/description_target_search</item>
         <item>@null</item>
         <item>@null</item>
     </array>
 
     <array name="navbar_search_direction_descriptions">
         <item>@null</item>
-        <item>@*android:string/description_direction_up</item>
+        <item>@string/description_direction_up</item>
         <item>@null</item>
         <item>@null</item>
     </array>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 047570f..734abdc 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -42,7 +42,9 @@
         <attr name="decayTime" format="integer" />
         <attr name="orientation" />
     </declare-styleable>
-
+    <declare-styleable name="BatteryMeterView">
+        <attr name="frameColor" format="color" />
+    </declare-styleable>
     <attr name="orientation">
         <enum name="horizontal" value="0" />
         <enum name="vertical" value="1" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 0bbdead..a59dc75 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -34,6 +34,17 @@
     <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="batterymeter_bolt_color">#B2000000</color><!-- 70% black -->
+    <color name="batterymeter_bolt_color">#FFFFFFFF</color>
+    <color name="qs_batterymeter_frame_color">#FF404040</color>
     <color name="status_bar_clock_color">#FFFFFFFF</color>
+    <drawable name="notification_item_background_color">#ff111111</drawable>
+    <drawable name="notification_item_background_color_pressed">#ff454545</drawable>
+    <color name="notification_icon_legacy_bg_color">#ff4285F4</color>
+    <color name="notification_action_legacy_color_filter">#ff555555</color>
+
+    <!-- Tint color for inactive Quick Settings icons. -->
+    <color name="ic_qs_off">#ff404040</color>
+
+    <!-- Tint color for active Quick Settings icons. -->
+    <color name="ic_qs_on">#ffffffff</color>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 3869db3..1dd9300 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -50,7 +50,7 @@
     <!-- When true, show 1/2G networks as 3G. -->
     <bool name="config_showMin3G">false</bool>
 
-    <!-- Show rotation lock button in phone-style notification panel. -->
+    <!-- Show rotation lock toggle in System UI-->
     <bool name="config_showRotationLock">true</bool>
 
     <!-- Amount of time to hold off before showing the search panel when the user presses home -->
@@ -84,9 +84,6 @@
     <!-- The number of columns that the top level tiles span in the QuickSettings -->
     <integer name="quick_settings_user_time_settings_tile_span">1</integer>
 
-    <!-- Whether rotation lock shows up in quick settings or not -->
-    <bool name="quick_settings_show_rotation_lock">false</bool>
-
     <!-- Whether or not the RSSI tile is capitalized or not. -->
     <bool name="quick_settings_rssi_tile_capitalization">true</bool>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index cc78cb4..65cd231 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -79,6 +79,9 @@
     <!-- Height of a large notification in the status bar -->
     <dimen name="notification_max_height">256dp</dimen>
 
+    <!-- Height of a medium notification in the status bar -->
+    <dimen name="notification_mid_height">128dp</dimen>
+
     <!-- Height of a small notification in the status bar plus glow, padding, etc -->
     <dimen name="notification_row_min_height">70dp</dimen>
 
@@ -220,4 +223,10 @@
 
     <!-- used by DessertCase -->
     <dimen name="dessert_case_cell_size">192dp</dimen>
+
+    <!-- Default glow radius for GlowPadView -->
+    <dimen name="glowpadview_glow_radius">75dip</dimen>
+
+    <!-- Default distance from each snap target that GlowPadView considers a "hit" -->
+    <dimen name="glowpadview_inner_radius">15dip</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e36ca8e..ce05639 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -464,6 +464,10 @@
     <string name="quick_settings_rotation_unlocked_label">Auto Rotate</string>
     <!-- QuickSettings: Rotation Locked [CHAR LIMIT=NONE] -->
     <string name="quick_settings_rotation_locked_label">Rotation Locked</string>
+    <!-- QuickSettings: Locked to Portrait [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_rotation_locked_portrait_label">Locked to Portrait</string>
+    <!-- QuickSettings: Locked to Landscape [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_rotation_locked_landscape_label">Locked to Landscape</string>
     <!-- QuickSettings: IME [CHAR LIMIT=NONE] -->
     <string name="quick_settings_ime_label">Input Method</string>
     <!-- QuickSettings: Location [CHAR LIMIT=NONE] -->
@@ -496,6 +500,15 @@
     <string name="quick_settings_brightness_dialog_title">Brightness</string>
     <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
     <string name="quick_settings_brightness_dialog_auto_brightness_label">AUTO</string>
+    <!-- QuickSettings: Label for the toggle that controls whether display inversion is enabled. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_inversion_label">Color inversion mode</string>
+    <!-- QuickSettings: Label for the toggle that controls whether display contrast enhancement is enabled. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_contrast_label">Enhanced contrast mode</string>
+    <!-- QuickSettings: Label for the toggle that controls whether display color correction is enabled. [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_color_space_label">Color correction mode</string>
+
+    <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
+    <string name="recents_empty_message">RECENTS</string>
 
 
     <!-- Glyph to be overlaid atop the battery when the level is extremely low. Do not translate. -->
@@ -507,4 +520,10 @@
          linebreak to position it correctly.  [CHAR LIMIT=45] -->
     <string name="ssl_ca_cert_warning">Network may\nbe monitored</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 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>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 54f03bd..14af020 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -20,6 +20,13 @@
         <item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
     </style>
 
+    <!-- Alternate Recents theme -->
+    <style name="RecentsTheme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
+        <item name="android:windowTranslucentStatus">true</item>
+        <item name="android:windowTranslucentNavigation">true</item>
+        <item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
+    </style>
+
     <!-- Animations for a non-full-screen window or activity. -->
     <style name="Animation.RecentsActivity" parent="@android:style/Animation.Activity">
         <item name="android:activityOpenEnterAnimation">@anim/recents_launch_from_launcher_enter</item>
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 13aafb2..19d06be 100755
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -27,7 +27,6 @@
 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;
@@ -40,20 +39,20 @@
     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;
+    private static final boolean ENABLE_PERCENT = true;
+    private static final boolean SINGLE_DIGIT_PERCENT = false;
+    private static final boolean SHOW_100_PERCENT = false;
 
-    public static final int FULL = 96;
-    public static final int EMPTY = 4;
+    private static final int FULL = 96;
+    private static final int EMPTY = 4;
 
-    public static final float SUBPIXEL = 0.4f;  // inset rects for softer edges
+    private static final float SUBPIXEL = 0.4f;  // inset rects for softer edges
+    private static final float BOLT_LEVEL_THRESHOLD = 0.3f;  // opaque bolt below this fraction
 
-    int[] mColors;
+    private final int[] mColors;
 
     boolean mShowPercent = true;
-    Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint;
-    int mButtonHeight;
+    private final Paint mFramePaint, mBatteryPaint, mWarningTextPaint, mTextPaint, mBoltPaint;
     private float mTextHeight, mWarningTextHeight;
 
     private int mHeight;
@@ -65,9 +64,12 @@
 
     private final RectF mFrame = new RectF();
     private final RectF mButtonFrame = new RectF();
-    private final RectF mClipFrame = new RectF();
     private final RectF mBoltFrame = new RectF();
 
+    private final Path mShapePath = new Path();
+    private final Path mClipPath = new Path();
+    private final Path mTextPath = new Path();
+
     private class BatteryTracker extends BroadcastReceiver {
         public static final int UNKNOWN_LEVEL = -1;
 
@@ -176,6 +178,10 @@
         super(context, attrs, defStyle);
 
         final Resources res = context.getResources();
+        TypedArray atts = context.obtainStyledAttributes(attrs, R.styleable.BatteryMeterView,
+                defStyle, 0);
+        final int frameColor = atts.getColor(R.styleable.BatteryMeterView_frameColor,
+                res.getColor(R.color.batterymeter_frame_color));
         TypedArray levels = res.obtainTypedArray(R.array.batterymeter_color_levels);
         TypedArray colors = res.obtainTypedArray(R.array.batterymeter_color_values);
 
@@ -187,17 +193,16 @@
         }
         levels.recycle();
         colors.recycle();
+        atts.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));
+        mFramePaint.setColor(frameColor);
         mFramePaint.setDither(true);
         mFramePaint.setStrokeWidth(0);
         mFramePaint.setStyle(Paint.Style.FILL_AND_STROKE);
-        mFramePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));
 
         mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
         mBatteryPaint.setDither(true);
@@ -205,8 +210,7 @@
         mBatteryPaint.setStyle(Paint.Style.FILL_AND_STROKE);
 
         mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mTextPaint.setColor(0xFFFFFFFF);
-        Typeface font = Typeface.create("sans-serif-condensed", Typeface.NORMAL);
+        Typeface font = Typeface.create("sans-serif-condensed", Typeface.BOLD);
         mTextPaint.setTypeface(font);
         mTextPaint.setTextAlign(Paint.Align.CENTER);
 
@@ -218,11 +222,9 @@
 
         mChargeColor = getResources().getColor(R.color.batterymeter_charge_color);
 
-        mBoltPaint = new Paint();
-        mBoltPaint.setAntiAlias(true);
+        mBoltPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
         mBoltPaint.setColor(res.getColor(R.color.batterymeter_bolt_color));
         mBoltPoints = loadBoltPoints(res);
-        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
     }
 
     private static float[] loadBoltPoints(Resources res) {
@@ -270,36 +272,34 @@
         final int pl = getPaddingLeft();
         final int pr = getPaddingRight();
         final int pb = getPaddingBottom();
-        int height = mHeight - pt - pb;
-        int width = mWidth - pl - pr;
+        final int height = mHeight - pt - pb;
+        final int width = mWidth - pl - pr;
 
-        mButtonHeight = (int) (height * 0.12f);
+        final int buttonHeight = (int) (height * 0.12f);
 
         mFrame.set(0, 0, width, height);
         mFrame.offset(pl, pt);
 
+        // button-frame: area above the battery body
         mButtonFrame.set(
                 mFrame.left + width * 0.25f,
                 mFrame.top,
                 mFrame.right - width * 0.25f,
-                mFrame.top + mButtonHeight + 5 /*cover frame border of intersecting area*/);
+                mFrame.top + buttonHeight);
 
         mButtonFrame.top += SUBPIXEL;
         mButtonFrame.left += SUBPIXEL;
         mButtonFrame.right -= SUBPIXEL;
 
-        mFrame.top += mButtonHeight;
+        // frame: battery body area
+        mFrame.top += buttonHeight;
         mFrame.left += SUBPIXEL;
         mFrame.top += SUBPIXEL;
         mFrame.right -= SUBPIXEL;
         mFrame.bottom -= SUBPIXEL;
 
-        // first, draw the battery shape
-        c.drawRect(mFrame, mFramePaint);
-
-        // fill 'er up
-        final int color = tracker.plugged ? mChargeColor : getColorForLevel(level);
-        mBatteryPaint.setColor(color);
+        // set the battery charging color
+        mBatteryPaint.setColor(tracker.plugged ? mChargeColor : getColorForLevel(level));
 
         if (level >= FULL) {
             drawFrac = 1f;
@@ -307,18 +307,23 @@
             drawFrac = 0f;
         }
 
-        c.drawRect(mButtonFrame, drawFrac == 1f ? mBatteryPaint : mFramePaint);
+        final float levelTop = drawFrac == 1f ? mButtonFrame.top
+                : (mFrame.top + (mFrame.height() * (1f - drawFrac)));
 
-        mClipFrame.set(mFrame);
-        mClipFrame.top += (mFrame.height() * (1f - drawFrac));
-
-        c.save(Canvas.CLIP_SAVE_FLAG);
-        c.clipRect(mClipFrame);
-        c.drawRect(mFrame, mBatteryPaint);
-        c.restore();
+        // define the battery shape
+        mShapePath.reset();
+        mShapePath.moveTo(mButtonFrame.left, mButtonFrame.top);
+        mShapePath.lineTo(mButtonFrame.right, mButtonFrame.top);
+        mShapePath.lineTo(mButtonFrame.right, mFrame.top);
+        mShapePath.lineTo(mFrame.right, mFrame.top);
+        mShapePath.lineTo(mFrame.right, mFrame.bottom);
+        mShapePath.lineTo(mFrame.left, mFrame.bottom);
+        mShapePath.lineTo(mFrame.left, mFrame.top);
+        mShapePath.lineTo(mButtonFrame.left, mFrame.top);
+        mShapePath.lineTo(mButtonFrame.left, mButtonFrame.top);
 
         if (tracker.plugged) {
-            // draw the bolt
+            // define the bolt shape
             final float bl = mFrame.left + mFrame.width() / 4.5f;
             final float bt = mFrame.top + mFrame.height() / 6f;
             final float br = mFrame.right - mFrame.width() / 7f;
@@ -339,24 +344,61 @@
                         mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
                         mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
             }
-            c.drawPath(mBoltPath, mBoltPaint);
-        } else if (level <= EMPTY) {
-            final float x = mWidth * 0.5f;
-            final float y = (mHeight + mWarningTextHeight) * 0.48f;
-            c.drawText(mWarningString, x, y, mWarningTextPaint);
-        } else if (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
+
+            float boltPct = (mBoltFrame.bottom - levelTop) / (mBoltFrame.bottom - mBoltFrame.top);
+            boltPct = Math.min(Math.max(boltPct, 0), 1);
+            if (boltPct <= BOLT_LEVEL_THRESHOLD) {
+                // draw the bolt if opaque
+                c.drawPath(mBoltPath, mBoltPaint);
+            } else {
+                // otherwise cut the bolt out of the overall shape
+                mShapePath.op(mBoltPath, Path.Op.DIFFERENCE);
+            }
+        }
+
+        // compute percentage text
+        boolean pctOpaque = false;
+        float pctX = 0, pctY = 0;
+        String pctText = null;
+        if (!tracker.plugged && level > EMPTY && mShowPercent
+                && !(tracker.level == 100 && !SHOW_100_PERCENT)) {
+            mTextPaint.setColor(getColorForLevel(level));
             mTextPaint.setTextSize(height *
                     (SINGLE_DIGIT_PERCENT ? 0.75f
                             : (tracker.level == 100 ? 0.38f : 0.5f)));
             mTextHeight = -mTextPaint.getFontMetrics().ascent;
+            pctText = String.valueOf(SINGLE_DIGIT_PERCENT ? (level/10) : level);
+            pctX = mWidth * 0.5f;
+            pctY = (mHeight + mTextHeight) * 0.47f;
+            pctOpaque = levelTop > pctY;
+            if (!pctOpaque) {
+                mTextPath.reset();
+                mTextPaint.getTextPath(pctText, 0, pctText.length(), pctX, pctY, mTextPath);
+                // cut the percentage text out of the overall shape
+                mShapePath.op(mTextPath, Path.Op.DIFFERENCE);
+            }
+        }
 
-            final String str = String.valueOf(SINGLE_DIGIT_PERCENT ? (level/10) : level);
-            final float x = mWidth * 0.5f;
-            final float y = (mHeight + mTextHeight) * 0.47f;
-            c.drawText(str,
-                    x,
-                    y,
-                    mTextPaint);
+        // draw the battery shape background
+        c.drawPath(mShapePath, mFramePaint);
+
+        // draw the battery shape, clipped to charging level
+        mFrame.top = levelTop;
+        mClipPath.reset();
+        mClipPath.addRect(mFrame,  Path.Direction.CCW);
+        mShapePath.op(mClipPath, Path.Op.INTERSECT);
+        c.drawPath(mShapePath, mBatteryPaint);
+
+        if (!tracker.plugged) {
+            if (level <= EMPTY) {
+                // draw the warning text
+                final float x = mWidth * 0.5f;
+                final float y = (mHeight + mWarningTextHeight) * 0.48f;
+                c.drawText(mWarningString, x, y, mWarningTextPaint);
+            } else if (pctOpaque) {
+                // draw the percentage text
+                c.drawText(pctText, pctX, pctY, mTextPaint);
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/DemoMode.java b/packages/SystemUI/src/com/android/systemui/DemoMode.java
index 8d271e4..c16c3a1 100644
--- a/packages/SystemUI/src/com/android/systemui/DemoMode.java
+++ b/packages/SystemUI/src/com/android/systemui/DemoMode.java
@@ -31,4 +31,5 @@
     public static final String COMMAND_NETWORK = "network";
     public static final String COMMAND_BARS = "bars";
     public static final String COMMAND_STATUS = "status";
+    public static final String COMMAND_NOTIFICATIONS = "notifications";
 }
diff --git a/packages/SystemUI/src/com/android/systemui/DessertCase.java b/packages/SystemUI/src/com/android/systemui/DessertCase.java
index d797e38..a96f024 100644
--- a/packages/SystemUI/src/com/android/systemui/DessertCase.java
+++ b/packages/SystemUI/src/com/android/systemui/DessertCase.java
@@ -16,13 +16,10 @@
 
 package com.android.systemui;
 
-import android.animation.ObjectAnimator;
 import android.app.Activity;
 import android.content.ComponentName;
 import android.content.pm.PackageManager;
-import android.os.Handler;
 import android.util.Slog;
-import android.view.animation.DecelerateInterpolator;
 
 public class DessertCase extends Activity {
     DessertCaseView mView;
diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
index e1a4bb2..48a6522 100644
--- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java
@@ -22,6 +22,7 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.media.AudioManager;
 import android.os.Vibrator;
 import android.util.Log;
 import android.view.Gravity;
@@ -605,7 +606,7 @@
             mVibrator = (android.os.Vibrator)
                     mContext.getSystemService(Context.VIBRATOR_SERVICE);
         }
-        mVibrator.vibrate(duration);
+        mVibrator.vibrate(duration, AudioManager.STREAM_SYSTEM);
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/ImageUtils.java b/packages/SystemUI/src/com/android/systemui/ImageUtils.java
new file mode 100644
index 0000000..540ba20
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ImageUtils.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui;
+
+import android.graphics.Bitmap;
+
+/**
+ * Utility class for image analysis and processing.
+ */
+public class ImageUtils {
+
+    // Amount (max is 255) that two channels can differ before the color is no longer "gray".
+    private static final int TOLERANCE = 20;
+
+    // Alpha amount for which values below are considered transparent.
+    private static final int ALPHA_TOLERANCE = 50;
+
+    private int[] mTempBuffer;
+
+    /**
+     * Checks whether a bitmap is grayscale. Grayscale here means "very close to a perfect
+     * gray".
+     */
+    public boolean isGrayscale(Bitmap bitmap) {
+        final int height = bitmap.getHeight();
+        final int width = bitmap.getWidth();
+        int size = height*width;
+
+        ensureBufferSize(size);
+        bitmap.getPixels(mTempBuffer, 0, width, 0, 0, width, height);
+        for (int i = 0; i < size; i++) {
+            if (!isGrayscale(mTempBuffer[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Makes sure that {@code mTempBuffer} has at least length {@code size}.
+     */
+    private void ensureBufferSize(int size) {
+        if (mTempBuffer == null || mTempBuffer.length < size) {
+            mTempBuffer = new int[size];
+        }
+    }
+
+    /**
+     * Classifies a color as grayscale or not. Grayscale here means "very close to a perfect
+     * gray"; if all three channels are approximately equal, this will return true.
+     *
+     * Note that really transparent colors are always grayscale.
+     */
+    public boolean isGrayscale(int color) {
+        int alpha = 0xFF & (color >> 24);
+        if (alpha < ALPHA_TOLERANCE) {
+            return true;
+        }
+
+        int r = 0xFF & (color >> 16);
+        int g = 0xFF & (color >> 8);
+        int b = 0xFF & color;
+
+        return Math.abs(r - g) < TOLERANCE
+                && Math.abs(r - b) < TOLERANCE
+                && Math.abs(g - b) < TOLERANCE;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 8092ab3..74483cc 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -536,7 +536,7 @@
 
             checkGlError();
 
-            if (w < 0 || h < 0) {
+            if (w > 0 || h > 0) {
                 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
                 glClear(GL_COLOR_BUFFER_BIT);
             }
diff --git a/packages/SystemUI/src/com/android/systemui/LoadAverageService.java b/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
index 610e42b..59ffe03 100644
--- a/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
+++ b/packages/SystemUI/src/com/android/systemui/LoadAverageService.java
@@ -195,9 +195,10 @@
             int systemW = (systemTime*W)/totalTime;
             int irqW = ((iowaitTime+irqTime+softIrqTime)*W)/totalTime;
 
-            int x = RIGHT - mPaddingRight;
-            int top = mPaddingTop + 2;
-            int bottom = mPaddingTop + mFH - 2;
+            int paddingRight = getPaddingRight();
+            int x = RIGHT - paddingRight;
+            int top = getPaddingTop() + 2;
+            int bottom = getPaddingTop() + mFH - 2;
 
             if (irqW > 0) {
                 canvas.drawRect(x-irqW, top, x, bottom, mIrqPaint);
@@ -212,16 +213,16 @@
                 x -= userW;
             }
 
-            int y = mPaddingTop - (int)mAscent;
-            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1,
+            int y = getPaddingTop() - (int)mAscent;
+            canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth-1,
                     y-1, mShadowPaint);
-            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth-1,
+            canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth-1,
                     y+1, mShadowPaint);
-            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1,
+            canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth+1,
                     y-1, mShadow2Paint);
-            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth+1,
+            canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth+1,
                     y+1, mShadow2Paint);
-            canvas.drawText(stats.mLoadText, RIGHT-mPaddingRight-stats.mLoadWidth,
+            canvas.drawText(stats.mLoadText, RIGHT-paddingRight-stats.mLoadWidth,
                     y, mLoadPaint);
 
             int N = stats.countWorkingStats();
@@ -233,7 +234,7 @@
 
                 userW = (st.rel_utime*W)/totalTime;
                 systemW = (st.rel_stime*W)/totalTime;
-                x = RIGHT - mPaddingRight;
+                x = RIGHT - paddingRight;
                 if (systemW > 0) {
                     canvas.drawRect(x-systemW, top, x, bottom, mSystemPaint);
                     x -= systemW;
@@ -243,18 +244,18 @@
                     x -= userW;
                 }
 
-                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1,
+                canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth-1,
                         y-1, mShadowPaint);
-                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth-1,
+                canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth-1,
                         y+1, mShadowPaint);
-                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1,
+                canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth+1,
                         y-1, mShadow2Paint);
-                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth+1,
+                canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth+1,
                         y+1, mShadow2Paint);
                 Paint p = mLoadPaint;
                 if (st.added) p = mAddedPaint;
                 if (st.removed) p = mRemovedPaint;
-                canvas.drawText(st.name, RIGHT-mPaddingRight-st.nameWidth, y, p);
+                canvas.drawText(st.name, RIGHT-paddingRight-st.nameWidth, y, p);
             }
         }
 
@@ -270,8 +271,8 @@
                 }
             }
 
-            int neededWidth = mPaddingLeft + mPaddingRight + maxWidth;
-            int neededHeight = mPaddingTop + mPaddingBottom + (mFH*(1+NW));
+            int neededWidth = getPaddingLeft() + getPaddingRight() + maxWidth;
+            int neededHeight = getPaddingTop() + getPaddingBottom() + (mFH*(1+NW));
             if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
                 mNeededWidth = neededWidth;
                 mNeededHeight = neededHeight;
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index c7f0e17..09aa60f 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
+import android.media.AudioManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -135,7 +136,7 @@
         public void onTrigger(View v, final int target) {
             final int resId = mGlowPadView.getResourceIdForTarget(target);
             switch (resId) {
-                case com.android.internal.R.drawable.ic_action_assist_generic:
+                case R.drawable.ic_action_assist_generic:
                     mWaitingForLaunch = true;
                     startAssistActivity();
                     vibrate();
@@ -175,7 +176,7 @@
             ComponentName component = intent.getComponent();
             if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
                     ASSIST_ICON_METADATA_NAME,
-                    com.android.internal.R.drawable.ic_action_assist_generic)) {
+                    R.drawable.ic_action_assist_generic)) {
                 if (DEBUG) Log.v(TAG, "Couldn't grab icon for component " + component);
             }
         }
@@ -207,7 +208,8 @@
                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0) {
             Resources res = context.getResources();
             Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
-            vibrator.vibrate(res.getInteger(R.integer.config_search_panel_view_vibration_duration));
+            vibrator.vibrate(res.getInteger(R.integer.config_search_panel_view_vibration_duration),
+                    AudioManager.STREAM_SYSTEM);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
new file mode 100644
index 0000000..feec87c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerDialogWarnings.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.power;
+
+import android.app.AlertDialog;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.Ringtone;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+
+import java.io.PrintWriter;
+
+public class PowerDialogWarnings implements PowerUI.WarningsUI {
+    private static final String TAG = PowerUI.TAG + ".Dialog";
+    private static final boolean DEBUG = PowerUI.DEBUG;
+
+    private final Context mContext;
+
+    private int mBatteryLevel;
+    private int mBucket;
+    private long mScreenOffTime;
+
+    private AlertDialog mInvalidChargerDialog;
+    private AlertDialog mLowBatteryDialog;
+    private TextView mBatteryLevelTextView;
+
+    public PowerDialogWarnings(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        pw.print("mInvalidChargerDialog=");
+        pw.println(mInvalidChargerDialog == null ? "null" : mInvalidChargerDialog.toString());
+        pw.print("mLowBatteryDialog=");
+        pw.println(mLowBatteryDialog == null ? "null" : mLowBatteryDialog.toString());
+    }
+
+    @Override
+    public void update(int batteryLevel, int bucket, long screenOffTime) {
+        mBatteryLevel = batteryLevel;
+        mBucket = bucket;
+        mScreenOffTime = screenOffTime;
+    }
+
+    @Override
+    public boolean isInvalidChargerWarningShowing() {
+        return mInvalidChargerDialog != null;
+    }
+
+    @Override
+    public void updateLowBatteryWarning() {
+        if (mBatteryLevelTextView != null) {
+            showLowBatteryWarning(false /*playSound*/);
+        }
+    }
+
+    @Override
+    public void dismissLowBatteryWarning() {
+        if (mLowBatteryDialog != null) {
+            Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
+            mLowBatteryDialog.dismiss();
+        }
+    }
+
+    @Override
+    public void showLowBatteryWarning(boolean playSound) {
+        Slog.i(TAG,
+                ((mBatteryLevelTextView == null) ? "showing" : "updating")
+                + " low battery warning: level=" + mBatteryLevel
+                + " [" + mBucket + "]");
+
+        CharSequence levelText = mContext.getString(
+                R.string.battery_low_percent_format, mBatteryLevel);
+
+        if (mBatteryLevelTextView != null) {
+            mBatteryLevelTextView.setText(levelText);
+        } else {
+            View v = View.inflate(mContext, R.layout.battery_low, null);
+            mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
+
+            mBatteryLevelTextView.setText(levelText);
+
+            AlertDialog.Builder b = new AlertDialog.Builder(mContext);
+                b.setCancelable(true);
+                b.setTitle(R.string.battery_low_title);
+                b.setView(v);
+                b.setIconAttribute(android.R.attr.alertDialogIcon);
+                b.setPositiveButton(android.R.string.ok, null);
+
+            final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                    | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
+                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
+                    | Intent.FLAG_ACTIVITY_NO_HISTORY);
+            if (intent.resolveActivity(mContext.getPackageManager()) != null) {
+                b.setNegativeButton(R.string.battery_low_why,
+                        new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
+                        dismissLowBatteryWarning();
+                    }
+                });
+            }
+
+            AlertDialog d = b.create();
+            d.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                    @Override
+                    public void onDismiss(DialogInterface dialog) {
+                        mLowBatteryDialog = null;
+                        mBatteryLevelTextView = null;
+                    }
+                });
+            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+            d.getWindow().getAttributes().privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+            d.show();
+            mLowBatteryDialog = d;
+            if (playSound) {
+                playLowBatterySound();
+            }
+        }
+    }
+
+    private void playLowBatterySound() {
+        final ContentResolver cr = mContext.getContentResolver();
+
+        final int silenceAfter = Settings.Global.getInt(cr,
+                Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
+        final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
+        if (silenceAfter > 0
+                && mScreenOffTime > 0
+                && offTime > silenceAfter) {
+            Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
+                    + "ms): not waking up the user with low battery sound");
+            return;
+        }
+
+        if (DEBUG) {
+            Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
+        }
+
+        if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
+            final String soundPath = Settings.Global.getString(cr,
+                    Settings.Global.LOW_BATTERY_SOUND);
+            if (soundPath != null) {
+                final Uri soundUri = Uri.parse("file://" + soundPath);
+                if (soundUri != null) {
+                    final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+                    if (sfx != null) {
+                        sfx.setStreamType(AudioManager.STREAM_SYSTEM);
+                        sfx.play();
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void dismissInvalidChargerWarning() {
+        if (mInvalidChargerDialog != null) {
+            mInvalidChargerDialog.dismiss();
+        }
+    }
+
+    @Override
+    public void showInvalidChargerWarning() {
+        Slog.d(TAG, "showing invalid charger dialog");
+
+        dismissLowBatteryWarning();
+
+        AlertDialog.Builder b = new AlertDialog.Builder(mContext);
+            b.setCancelable(true);
+            b.setMessage(R.string.invalid_charger);
+            b.setIconAttribute(android.R.attr.alertDialogIcon);
+            b.setPositiveButton(android.R.string.ok, null);
+
+        AlertDialog d = b.create();
+            d.setOnDismissListener(new DialogInterface.OnDismissListener() {
+                    public void onDismiss(DialogInterface dialog) {
+                        mInvalidChargerDialog = null;
+                        mBatteryLevelTextView = null;
+                    }
+                });
+
+        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
+        d.show();
+        mInvalidChargerDialog = d;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 28c2772..0fb0f8b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -16,29 +16,17 @@
 
 package com.android.systemui.power;
 
-import android.app.AlertDialog;
 import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
 import android.content.Context;
-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.PowerManager;
 import android.os.SystemClock;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.TextView;
 
-import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 
 import java.io.FileDescriptor;
@@ -50,19 +38,17 @@
 
     static final boolean DEBUG = false;
 
-    Handler mHandler = new Handler();
+    private WarningsUI mWarnings;
 
-    int mBatteryLevel = 100;
-    int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
-    int mPlugType = 0;
-    int mInvalidCharger = 0;
+    private final Handler mHandler = new Handler();
 
-    int mLowBatteryAlertCloseLevel;
-    int[] mLowBatteryReminderLevels = new int[2];
+    private int mBatteryLevel = 100;
+    private int mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+    private int mPlugType = 0;
+    private int mInvalidCharger = 0;
 
-    AlertDialog mInvalidChargerDialog;
-    AlertDialog mLowBatteryDialog;
-    TextView mBatteryLevelTextView;
+    private int mLowBatteryAlertCloseLevel;
+    private final int[] mLowBatteryReminderLevels = new int[2];
 
     private long mScreenOffTime = -1;
 
@@ -77,6 +63,7 @@
 
         final PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mScreenOffTime = pm.isScreenOn() ? -1 : SystemClock.elapsedRealtime();
+        mWarnings = new PowerDialogWarnings(mContext);
 
         // Register for Intent broadcasts for...
         IntentFilter filter = new IntentFilter();
@@ -145,13 +132,14 @@
                     Slog.d(TAG, "plugged        " + oldPlugged + " --> " + plugged);
                 }
 
+                mWarnings.update(mBatteryLevel, bucket, mScreenOffTime);
                 if (oldInvalidCharger == 0 && mInvalidCharger != 0) {
                     Slog.d(TAG, "showing invalid charger warning");
-                    showInvalidChargerDialog();
+                    mWarnings.showInvalidChargerWarning();
                     return;
                 } else if (oldInvalidCharger != 0 && mInvalidCharger == 0) {
-                    dismissInvalidChargerDialog();
-                } else if (mInvalidChargerDialog != null) {
+                    mWarnings.dismissInvalidChargerWarning();
+                } else if (mWarnings.isInvalidChargerWarningShowing()) {
                     // if invalid charger is showing, don't show low battery
                     return;
                 }
@@ -160,16 +148,13 @@
                         && (bucket < oldBucket || oldPlugged)
                         && mBatteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
                         && bucket < 0) {
-                    showLowBatteryWarning();
-
                     // only play SFX when the dialog comes up or the bucket changes
-                    if (bucket != oldBucket || oldPlugged) {
-                        playLowBatterySound();
-                    }
+                    final boolean playSound = bucket != oldBucket || oldPlugged;
+                    mWarnings.showLowBatteryWarning(playSound);
                 } else if (plugged || (bucket > oldBucket && bucket > 0)) {
-                    dismissLowBatteryWarning();
-                } else if (mBatteryLevelTextView != null) {
-                    showLowBatteryWarning();
+                    mWarnings.dismissLowBatteryWarning();
+                } else {
+                    mWarnings.updateLowBatteryWarning();
                 }
             } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                 mScreenOffTime = SystemClock.elapsedRealtime();
@@ -181,142 +166,11 @@
         }
     };
 
-    void dismissLowBatteryWarning() {
-        if (mLowBatteryDialog != null) {
-            Slog.i(TAG, "closing low battery warning: level=" + mBatteryLevel);
-            mLowBatteryDialog.dismiss();
-        }
-    }
-
-    void showLowBatteryWarning() {
-        Slog.i(TAG,
-                ((mBatteryLevelTextView == null) ? "showing" : "updating")
-                + " low battery warning: level=" + mBatteryLevel
-                + " [" + findBatteryLevelBucket(mBatteryLevel) + "]");
-
-        CharSequence levelText = mContext.getString(
-                R.string.battery_low_percent_format, mBatteryLevel);
-
-        if (mBatteryLevelTextView != null) {
-            mBatteryLevelTextView.setText(levelText);
-        } else {
-            View v = View.inflate(mContext, R.layout.battery_low, null);
-            mBatteryLevelTextView = (TextView)v.findViewById(R.id.level_percent);
-
-            mBatteryLevelTextView.setText(levelText);
-
-            AlertDialog.Builder b = new AlertDialog.Builder(mContext);
-                b.setCancelable(true);
-                b.setTitle(R.string.battery_low_title);
-                b.setView(v);
-                b.setIconAttribute(android.R.attr.alertDialogIcon);
-                b.setPositiveButton(android.R.string.ok, null);
-
-            final Intent intent = new Intent(Intent.ACTION_POWER_USAGE_SUMMARY);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_MULTIPLE_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
-                    | Intent.FLAG_ACTIVITY_NO_HISTORY);
-            if (intent.resolveActivity(mContext.getPackageManager()) != null) {
-                b.setNegativeButton(R.string.battery_low_why,
-                        new DialogInterface.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        mContext.startActivityAsUser(intent, UserHandle.CURRENT);
-                        dismissLowBatteryWarning();
-                    }
-                });
-            }
-
-            AlertDialog d = b.create();
-            d.setOnDismissListener(new DialogInterface.OnDismissListener() {
-                    @Override
-                    public void onDismiss(DialogInterface dialog) {
-                        mLowBatteryDialog = null;
-                        mBatteryLevelTextView = null;
-                    }
-                });
-            d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-            d.getWindow().getAttributes().privateFlags |=
-                    WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
-            d.show();
-            mLowBatteryDialog = d;
-        }
-    }
-
-    void playLowBatterySound() {
-        final ContentResolver cr = mContext.getContentResolver();
-
-        final int silenceAfter = Settings.Global.getInt(cr,
-                Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0);
-        final long offTime = SystemClock.elapsedRealtime() - mScreenOffTime;
-        if (silenceAfter > 0
-                && mScreenOffTime > 0
-                && offTime > silenceAfter) {
-            Slog.i(TAG, "screen off too long (" + offTime + "ms, limit " + silenceAfter
-                    + "ms): not waking up the user with low battery sound");
-            return;
-        }
-
-        if (DEBUG) {
-            Slog.d(TAG, "playing low battery sound. pick-a-doop!"); // WOMP-WOMP is deprecated
-        }
-
-        if (Settings.Global.getInt(cr, Settings.Global.POWER_SOUNDS_ENABLED, 1) == 1) {
-            final String soundPath = Settings.Global.getString(cr,
-                    Settings.Global.LOW_BATTERY_SOUND);
-            if (soundPath != null) {
-                final Uri soundUri = Uri.parse("file://" + soundPath);
-                if (soundUri != null) {
-                    final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
-                    if (sfx != null) {
-                        sfx.setStreamType(AudioManager.STREAM_SYSTEM);
-                        sfx.play();
-                    }
-                }
-            }
-        }
-    }
-
-    void dismissInvalidChargerDialog() {
-        if (mInvalidChargerDialog != null) {
-            mInvalidChargerDialog.dismiss();
-        }
-    }
-
-    void showInvalidChargerDialog() {
-        Slog.d(TAG, "showing invalid charger dialog");
-
-        dismissLowBatteryWarning();
-
-        AlertDialog.Builder b = new AlertDialog.Builder(mContext);
-            b.setCancelable(true);
-            b.setMessage(R.string.invalid_charger);
-            b.setIconAttribute(android.R.attr.alertDialogIcon);
-            b.setPositiveButton(android.R.string.ok, null);
-
-        AlertDialog d = b.create();
-            d.setOnDismissListener(new DialogInterface.OnDismissListener() {
-                    public void onDismiss(DialogInterface dialog) {
-                        mInvalidChargerDialog = null;
-                        mBatteryLevelTextView = null;
-                    }
-                });
-
-        d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        d.show();
-        mInvalidChargerDialog = d;
-    }
-
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.print("mLowBatteryAlertCloseLevel=");
         pw.println(mLowBatteryAlertCloseLevel);
         pw.print("mLowBatteryReminderLevels=");
         pw.println(Arrays.toString(mLowBatteryReminderLevels));
-        pw.print("mInvalidChargerDialog=");
-        pw.println(mInvalidChargerDialog == null ? "null" : mInvalidChargerDialog.toString());
-        pw.print("mLowBatteryDialog=");
-        pw.println(mLowBatteryDialog == null ? "null" : mLowBatteryDialog.toString());
         pw.print("mBatteryLevel=");
         pw.println(Integer.toString(mBatteryLevel));
         pw.print("mBatteryStatus=");
@@ -338,6 +192,18 @@
                 Settings.Global.LOW_BATTERY_SOUND_TIMEOUT, 0));
         pw.print("bucket: ");
         pw.println(Integer.toString(findBatteryLevelBucket(mBatteryLevel)));
+        mWarnings.dump(pw);
+    }
+
+    public interface WarningsUI {
+        void update(int batteryLevel, int bucket, long screenOffTime);
+        void dismissLowBatteryWarning();
+        void showLowBatteryWarning(boolean playSound);
+        void dismissInvalidChargerWarning();
+        void showInvalidChargerWarning();
+        void updateLowBatteryWarning();
+        boolean isInvalidChargerWarningShowing();
+        void dump(PrintWriter pw);
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index c714d8b..9d2d6ee 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -367,8 +367,9 @@
     public TaskDescription loadFirstTask() {
         final ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
 
-        final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasksForUser(
-                1, ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.CURRENT.getIdentifier());
+        final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasksForUser(1,
+                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED,
+                UserHandle.CURRENT.getIdentifier());
         TaskDescription item = null;
         if (recentTasks.size() > 0) {
             ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(0);
@@ -439,7 +440,8 @@
                 mContext.getSystemService(Context.ACTIVITY_SERVICE);
 
                 final List<ActivityManager.RecentTaskInfo> recentTasks =
-                        am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                        am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+                        | ActivityManager.RECENT_INCLUDE_RELATED);
                 int numTasks = recentTasks.size();
                 ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN)
                         .addCategory(Intent.CATEGORY_HOME).resolveActivityInfo(pm, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
index f5670e1..10b6d49 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -26,27 +26,47 @@
 import android.graphics.Paint;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.os.SystemProperties;
 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;
+import com.android.systemui.recents.AlternateRecentsComponent;
+
 
 public class Recents extends SystemUI implements RecentsComponent {
     private static final String TAG = "Recents";
-    private static final boolean DEBUG = false;
+    private static final boolean DEBUG = true;
+
+    // Which recents to use
+    boolean mUseAlternateRecents;
+    AlternateRecentsComponent mAlternateRecents;
 
     @Override
     public void start() {
+        mUseAlternateRecents = SystemProperties.getBoolean("persist.recents.use_alternate", false);
+        if (mUseAlternateRecents) {
+            if (mAlternateRecents == null) {
+                mAlternateRecents = new AlternateRecentsComponent(mContext);
+            }
+            mAlternateRecents.onStart();
+        }
+
         putComponent(RecentsComponent.class, this);
     }
 
     @Override
     public void toggleRecents(Display display, int layoutDirection, View statusBarView) {
+        if (mUseAlternateRecents) {
+            // Launch the alternate recents if required
+            mAlternateRecents.onToggleRecents(display, layoutDirection, statusBarView);
+            return;
+        }
+
         if (DEBUG) Log.d(TAG, "toggle recents panel");
         try {
             TaskDescription firstTask = RecentTasksLoader.getInstance(mContext).getFirstTask();
@@ -191,32 +211,50 @@
     }
 
     @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));
+    protected void onConfigurationChanged(Configuration newConfig) {
+        if (mUseAlternateRecents) {
+            mAlternateRecents.onConfigurationChanged(newConfig);
+        }
+    }
 
-        RecentTasksLoader.getInstance(mContext).preloadFirstTask();
+    @Override
+    public void preloadRecentTasksList() {
+        if (mUseAlternateRecents) {
+            mAlternateRecents.onPreloadRecents();
+        } else {
+            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));
+        if (mUseAlternateRecents) {
+            mAlternateRecents.onCancelPreloadingRecents();
+        } else {
+            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();
+            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));
+        if (mUseAlternateRecents) {
+            mAlternateRecents.onCloseRecents();
+        } else {
+            Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
+            intent.setPackage("com.android.systemui");
+            mContext.sendBroadcastAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+
+            RecentTasksLoader.getInstance(mContext).cancelPreloadingFirstTask();
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
index 09a7a5e..f75ea92 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
@@ -164,7 +164,8 @@
             final List<ActivityManager.RecentTaskInfo> recentTasks =
                     am.getRecentTasks(2,
                             ActivityManager.RECENT_WITH_EXCLUDED |
-                            ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                            ActivityManager.RECENT_IGNORE_UNAVAILABLE |
+                            ActivityManager.RECENT_INCLUDE_RELATED);
             if (recentTasks.size() > 1 &&
                     mRecentsPanel.simulateClick(recentTasks.get(1).persistentId)) {
                 // recents panel will take care of calling show(false) through simulateClick
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index be42bc0..35c824b 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -57,7 +57,7 @@
     public RecentsHorizontalScrollView(Context context, AttributeSet attrs) {
         super(context, attrs, 0);
         float densityScale = getResources().getDisplayMetrics().density;
-        float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
         mSwipeHelper = new SwipeHelper(SwipeHelper.Y, this, densityScale, pagingTouchSlop);
         mFadedEdgeDrawHelper = FadedEdgeDrawHelper.create(context, attrs, this, false);
         mRecycledViews = new HashSet<View>();
@@ -239,9 +239,9 @@
         if (mFadedEdgeDrawHelper != null) {
 
             mFadedEdgeDrawHelper.drawCallback(canvas,
-                    left, right, top, bottom, mScrollX, mScrollY,
+                    left, right, top, bottom, getScrollX(), getScrollY(),
                     0, 0,
-                    getLeftFadingEdgeStrength(), getRightFadingEdgeStrength(), mPaddingTop);
+                    getLeftFadingEdgeStrength(), getRightFadingEdgeStrength(), getPaddingTop());
         }
     }
 
@@ -280,7 +280,7 @@
         super.onFinishInflate();
         setScrollbarFadingEnabled(true);
         mLinearLayout = (LinearLayout) findViewById(R.id.recents_linear_layout);
-        final int leftPadding = mContext.getResources()
+        final int leftPadding = getContext().getResources()
             .getDimensionPixelOffset(R.dimen.status_bar_recents_thumbnail_left_margin);
         setOverScrollEffectPadding(leftPadding, 0);
     }
@@ -297,7 +297,7 @@
         super.onConfigurationChanged(newConfig);
         float densityScale = getResources().getDisplayMetrics().density;
         mSwipeHelper.setDensityScale(densityScale);
-        float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
         mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 788e843..ef56044 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -330,7 +330,7 @@
     }
 
     private void showImpl(boolean show) {
-        sendCloseSystemWindows(mContext, BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
+        sendCloseSystemWindows(getContext(), BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
 
         mShowing = show;
 
@@ -372,11 +372,11 @@
     }
 
     public void dismiss() {
-        ((RecentsActivity) mContext).dismissAndGoHome();
+        ((RecentsActivity) getContext()).dismissAndGoHome();
     }
 
     public void dismissAndGoBack() {
-        ((RecentsActivity) mContext).dismissAndGoBack();
+        ((RecentsActivity) getContext()).dismissAndGoBack();
     }
 
     public void onAnimationCancel(Animator animation) {
@@ -424,7 +424,7 @@
     }
 
     public void updateValuesFromResources() {
-        final Resources res = mContext.getResources();
+        final Resources res = getContext().getResources();
         mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
         mFitThumbnailToXY = res.getBoolean(R.bool.config_recents_thumbnail_image_fits_to_xy);
     }
@@ -440,7 +440,7 @@
                 invalidate();
             }
         });
-        mListAdapter = new TaskDescriptionAdapter(mContext);
+        mListAdapter = new TaskDescriptionAdapter(getContext());
         mRecentsContainer.setAdapter(mListAdapter);
         mRecentsContainer.setCallback(this);
 
@@ -474,7 +474,7 @@
             if (show && h.iconView.getVisibility() != View.VISIBLE) {
                 if (anim) {
                     h.iconView.setAnimation(
-                            AnimationUtils.loadAnimation(mContext, R.anim.recent_appear));
+                            AnimationUtils.loadAnimation(getContext(), R.anim.recent_appear));
                 }
                 h.iconView.setVisibility(View.VISIBLE);
             }
@@ -506,7 +506,7 @@
             if (show && h.thumbnailView.getVisibility() != View.VISIBLE) {
                 if (anim) {
                     h.thumbnailView.setAnimation(
-                            AnimationUtils.loadAnimation(mContext, R.anim.recent_appear));
+                            AnimationUtils.loadAnimation(getContext(), R.anim.recent_appear));
                 }
                 h.thumbnailView.setVisibility(View.VISIBLE);
             }
@@ -617,7 +617,7 @@
         } else {
             mRecentTaskDescriptions.addAll(tasks);
         }
-        if (((RecentsActivity) mContext).isActivityShowing()) {
+        if (((RecentsActivity) getContext()).isActivityShowing()) {
             refreshViews();
         }
     }
@@ -726,13 +726,13 @@
         // Currently, either direction means the same thing, so ignore direction and remove
         // the task.
         final ActivityManager am = (ActivityManager)
-                mContext.getSystemService(Context.ACTIVITY_SERVICE);
+                getContext().getSystemService(Context.ACTIVITY_SERVICE);
         if (am != null) {
             am.removeTask(ad.persistentTaskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
 
             // Accessibility feedback
             setContentDescription(
-                    mContext.getString(R.string.accessibility_recents_item_dismissed, ad.getLabel()));
+                    getContext().getString(R.string.accessibility_recents_item_dismissed, ad.getLabel()));
             sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
             setContentDescription(null);
         }
@@ -741,7 +741,7 @@
     private void startApplicationDetailsActivity(String packageName) {
         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                 Uri.fromParts("package", packageName, null));
-        intent.setComponent(intent.resolveActivity(mContext.getPackageManager()));
+        intent.setComponent(intent.resolveActivity(getContext().getPackageManager()));
         TaskStackBuilder.create(getContext())
                 .addNextIntentWithParentStack(intent).startActivities();
     }
@@ -758,7 +758,7 @@
             final View selectedView, final View anchorView, final View thumbnailView) {
         thumbnailView.setSelected(true);
         final PopupMenu popup =
-            new PopupMenu(mContext, anchorView == null ? selectedView : anchorView);
+            new PopupMenu(getContext(), anchorView == null ? selectedView : anchorView);
         mPopup = popup;
         popup.getMenuInflater().inflate(R.menu.recent_popup_menu, popup.getMenu());
         popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@@ -793,15 +793,15 @@
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
 
-        int paddingLeft = mPaddingLeft;
+        int paddingLeft = getPaddingLeft();
         final boolean offsetRequired = isPaddingOffsetRequired();
         if (offsetRequired) {
             paddingLeft += getLeftPaddingOffset();
         }
 
-        int left = mScrollX + paddingLeft;
-        int right = left + mRight - mLeft - mPaddingRight - paddingLeft;
-        int top = mScrollY + getFadeTop(offsetRequired);
+        int left = getScrollX() + paddingLeft;
+        int right = left + getRight() - getLeft() - getPaddingRight() - paddingLeft;
+        int top = getScrollY() + getFadeTop(offsetRequired);
         int bottom = top + getFadeHeight(offsetRequired);
 
         if (offsetRequired) {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 6dddc39..297fe0d 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -57,7 +57,7 @@
     public RecentsVerticalScrollView(Context context, AttributeSet attrs) {
         super(context, attrs, 0);
         float densityScale = getResources().getDisplayMetrics().density;
-        float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
 
         mFadedEdgeDrawHelper = FadedEdgeDrawHelper.create(context, attrs, this, true);
@@ -69,7 +69,7 @@
     }
 
     private int scrollPositionOfMostRecent() {
-        return mLinearLayout.getHeight() - getHeight() + mPaddingTop;
+        return mLinearLayout.getHeight() - getHeight() + getPaddingTop();
     }
 
     private void addToRecycledViews(View v) {
@@ -248,9 +248,9 @@
         if (mFadedEdgeDrawHelper != null) {
             final boolean offsetRequired = isPaddingOffsetRequired();
             mFadedEdgeDrawHelper.drawCallback(canvas,
-                    left, right, top + getFadeTop(offsetRequired), bottom, mScrollX, mScrollY,
+                    left, right, top + getFadeTop(offsetRequired), bottom, getScrollX(), getScrollY(),
                     getTopFadingEdgeStrength(), getBottomFadingEdgeStrength(),
-                    0, 0, mPaddingTop);
+                    0, 0, getPaddingTop());
         }
     }
 
@@ -289,7 +289,7 @@
         super.onFinishInflate();
         setScrollbarFadingEnabled(true);
         mLinearLayout = (LinearLayout) findViewById(R.id.recents_linear_layout);
-        final int leftPadding = mContext.getResources()
+        final int leftPadding = getContext().getResources()
             .getDimensionPixelOffset(R.dimen.status_bar_recents_thumbnail_left_margin);
         setOverScrollEffectPadding(leftPadding, 0);
     }
@@ -306,7 +306,7 @@
         super.onConfigurationChanged(newConfig);
         float densityScale = getResources().getDisplayMetrics().density;
         mSwipeHelper.setDensityScale(densityScale);
-        float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
         mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
index 2bc2821..2e0ee36 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/TaskDescription.java
@@ -18,7 +18,6 @@
 
 import android.content.Intent;
 import android.content.pm.ResolveInfo;
-import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 
 public final class TaskDescription {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
new file mode 100644
index 0000000..1a616a0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+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.os.SystemProperties;
+import android.os.UserHandle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.View;
+import android.view.WindowManager;
+import com.android.systemui.R;
+import com.android.systemui.RecentsComponent;
+import com.android.systemui.SystemUI;
+
+import java.util.List;
+
+/** A proxy implementation for the recents component */
+public class AlternateRecentsComponent {
+
+    /** A handler for messages from the recents implementation */
+    class RecentsMessageHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_UPDATE_FOR_CONFIGURATION) {
+                Resources res = mContext.getResources();
+                float statusBarHeight = res.getDimensionPixelSize(
+                        com.android.internal.R.dimen.status_bar_height);
+                mFirstTaskRect = (Rect) msg.getData().getParcelable("taskRect");
+                mFirstTaskRect.offset(0, (int) statusBarHeight);
+            }
+        }
+    }
+
+    /** A service connection to the recents implementation */
+    class RecentsServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            Console.log(Constants.DebugFlags.App.RecentsComponent,
+                    "[RecentsComponent|ServiceConnection|onServiceConnected]",
+                    "toggleRecents: " + mToggleRecentsUponServiceBound);
+            mService = new Messenger(service);
+            mServiceIsBound = true;
+
+            // Toggle recents if this service connection was triggered by hitting the recents button
+            if (mToggleRecentsUponServiceBound) {
+                startAlternateRecentsActivity();
+            }
+            mToggleRecentsUponServiceBound = false;
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            Console.log(Constants.DebugFlags.App.RecentsComponent,
+                    "[RecentsComponent|ServiceConnection|onServiceDisconnected]");
+            mService = null;
+            mServiceIsBound = false;
+        }
+    }
+
+    final static int MSG_UPDATE_FOR_CONFIGURATION = 0;
+    final static int MSG_UPDATE_TASK_THUMBNAIL = 1;
+    final static int MSG_PRELOAD_TASKS = 2;
+    final static int MSG_CANCEL_PRELOAD_TASKS = 3;
+    final static int MSG_CLOSE_RECENTS = 4;
+    final static int MSG_TOGGLE_RECENTS = 5;
+
+    final static int sMinToggleDelay = 425;
+
+    final static String sToggleRecentsAction = "com.android.systemui.recents.SHOW_RECENTS";
+    final static String sRecentsPackage = "com.android.systemui";
+    final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity";
+    final static String sRecentsService = "com.android.systemui.recents.RecentsService";
+
+    Context mContext;
+
+    // Recents service binding
+    Messenger mService = null;
+    Messenger mMessenger;
+    boolean mServiceIsBound = false;
+    boolean mToggleRecentsUponServiceBound;
+    RecentsServiceConnection mConnection = new RecentsServiceConnection();
+
+    View mStatusBarView;
+    Rect mFirstTaskRect = new Rect();
+    long mLastToggleTime;
+
+    public AlternateRecentsComponent(Context context) {
+        mContext = context;
+        mMessenger = new Messenger(new RecentsMessageHandler());
+    }
+
+    public void onStart() {
+        Console.log(Constants.DebugFlags.App.RecentsComponent, "[RecentsComponent|start]");
+
+        // Try to create a long-running connection to the recents service
+        bindToRecentsService(false);
+    }
+
+    /** Toggles the alternate recents activity */
+    public void onToggleRecents(Display display, int layoutDirection, View statusBarView) {
+        Console.logStartTracingTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                Constants.DebugFlags.App.TimeRecentsStartupKey);
+        Console.logStartTracingTime(Constants.DebugFlags.App.TimeRecentsLaunchTask,
+                Constants.DebugFlags.App.TimeRecentsLaunchKey);
+        Console.log(Constants.DebugFlags.App.RecentsComponent, "[RecentsComponent|toggleRecents]",
+                "serviceIsBound: " + mServiceIsBound);
+        mStatusBarView = statusBarView;
+        if (!mServiceIsBound) {
+            // Try to create a long-running connection to the recents service before toggling
+            // recents
+            bindToRecentsService(true);
+            return;
+        }
+
+        try {
+            startAlternateRecentsActivity();
+        } catch (ActivityNotFoundException e) {
+            Console.logRawError("Failed to launch RecentAppsIntent", e);
+        }
+    }
+
+    public void onPreloadRecents() {
+        // Do nothing
+    }
+
+    public void onCancelPreloadingRecents() {
+        // Do nothing
+    }
+
+    public void onCloseRecents() {
+        Console.log(Constants.DebugFlags.App.RecentsComponent, "[RecentsComponent|closeRecents]");
+        if (mServiceIsBound) {
+            // Try and update the recents configuration
+            try {
+                Bundle data = new Bundle();
+                Message msg = Message.obtain(null, MSG_CLOSE_RECENTS, 0, 0);
+                msg.setData(data);
+                mService.send(msg);
+            } catch (RemoteException re) {
+                re.printStackTrace();
+            }
+        }
+    }
+
+    public void onConfigurationChanged(Configuration newConfig) {
+        if (mServiceIsBound) {
+            Resources res = mContext.getResources();
+            int statusBarHeight = res.getDimensionPixelSize(
+                    com.android.internal.R.dimen.status_bar_height);
+            int navBarHeight = res.getDimensionPixelSize(
+                    com.android.internal.R.dimen.navigation_bar_height);
+            Rect rect = new Rect();
+            WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+            wm.getDefaultDisplay().getRectSize(rect);
+
+            // Try and update the recents configuration
+            try {
+                Bundle data = new Bundle();
+                data.putParcelable("windowRect", rect);
+                data.putParcelable("systemInsets", new Rect(0, statusBarHeight, 0, 0));
+                Message msg = Message.obtain(null, MSG_UPDATE_FOR_CONFIGURATION, 0, 0);
+                msg.setData(data);
+                msg.replyTo = mMessenger;
+                mService.send(msg);
+            } catch (RemoteException re) {
+                re.printStackTrace();
+            }
+        }
+    }
+
+    /** Binds to the recents implementation */
+    private void bindToRecentsService(boolean toggleRecentsUponConnection) {
+        mToggleRecentsUponServiceBound = toggleRecentsUponConnection;
+        Intent intent = new Intent();
+        intent.setClassName(sRecentsPackage, sRecentsService);
+        mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    /** Loads the first task thumbnail */
+    Bitmap loadFirstTaskThumbnail() {
+        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1,
+                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED,
+                UserHandle.CURRENT.getIdentifier());
+        for (ActivityManager.RecentTaskInfo t : tasks) {
+            // Skip tasks in the home stack
+            if (am.isInHomeStack(t.persistentId)) {
+                return null;
+            }
+
+            Bitmap thumbnail = am.getTaskTopThumbnail(t.persistentId);
+            return thumbnail;
+        }
+        return null;
+    }
+
+    /** Returns whether there is a first task */
+    boolean hasFirstTask() {
+        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1,
+                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED,
+                UserHandle.CURRENT.getIdentifier());
+        for (ActivityManager.RecentTaskInfo t : tasks) {
+            // Skip tasks in the home stack
+            if (am.isInHomeStack(t.persistentId)) {
+                continue;
+            }
+
+            return true;
+        }
+        return false;
+    }
+
+    /** Converts from the device rotation to the degree */
+    float getDegreesForRotation(int value) {
+        switch (value) {
+            case Surface.ROTATION_90:
+                return 360f - 90f;
+            case Surface.ROTATION_180:
+                return 360f - 180f;
+            case Surface.ROTATION_270:
+                return 360f - 270f;
+        }
+        return 0f;
+    }
+
+    /** Takes a screenshot of the surface */
+    Bitmap takeScreenshot(Display display) {
+        DisplayMetrics dm = new DisplayMetrics();
+        display.getRealMetrics(dm);
+        float[] dims = {dm.widthPixels, dm.heightPixels};
+        float degrees = getDegreesForRotation(display.getRotation());
+        boolean requiresRotation = (degrees > 0);
+        if (requiresRotation) {
+            // Get the dimensions of the device in its native orientation
+            Matrix m = new Matrix();
+            m.preRotate(-degrees);
+            m.mapPoints(dims);
+            dims[0] = Math.abs(dims[0]);
+            dims[1] = Math.abs(dims[1]);
+        }
+        return SurfaceControl.screenshot((int) dims[0], (int) dims[1]);
+    }
+
+    /** Starts the recents activity */
+    void startAlternateRecentsActivity() {
+        // If the user has toggled it too quickly, then just eat up the event here (it's better than
+        // showing a janky screenshot).
+        // NOTE: Ideally, the screenshot mechanism would take the window transform into account
+        if (System.currentTimeMillis() - mLastToggleTime < sMinToggleDelay) {
+            return;
+        }
+
+        // If Recents is the front most activity, then we should just communicate with it directly
+        // to launch the first task or dismiss itself
+        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
+        if (!tasks.isEmpty()) {
+            ComponentName topActivity = tasks.get(0).topActivity;
+
+            // Check if the front most activity is recents
+            if (topActivity.getPackageName().equals(sRecentsPackage) &&
+                    topActivity.getClassName().equals(sRecentsActivity)) {
+                // Notify Recents to toggle itself
+                try {
+                    Bundle data = new Bundle();
+                    Message msg = Message.obtain(null, MSG_TOGGLE_RECENTS, 0, 0);
+                    msg.setData(data);
+                    mService.send(msg);
+
+                    // Time this path
+                    Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                            Constants.DebugFlags.App.TimeRecentsStartupKey, "sendToggleRecents");
+                    Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsLaunchTask,
+                            Constants.DebugFlags.App.TimeRecentsLaunchKey, "sendToggleRecents");
+                } catch (RemoteException re) {
+                    re.printStackTrace();
+                }
+                mLastToggleTime = System.currentTimeMillis();
+                return;
+            }
+        }
+
+        // Otherwise, Recents is not the front-most activity and we should animate into it
+        Rect taskRect = mFirstTaskRect;
+        if (taskRect != null && taskRect.width() > 0 && taskRect.height() > 0 && hasFirstTask()) {
+            // Loading from thumbnail
+            Bitmap thumbnail;
+            Bitmap firstThumbnail = loadFirstTaskThumbnail();
+            if (firstThumbnail == null) {
+                // Load the thumbnail from the screenshot
+                WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+                Display display = wm.getDefaultDisplay();
+                Bitmap screenshot = takeScreenshot(display);
+                Resources res = mContext.getResources();
+                int size = Math.min(screenshot.getWidth(), screenshot.getHeight());
+                int statusBarHeight = res.getDimensionPixelSize(
+                        com.android.internal.R.dimen.status_bar_height);
+                thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(),
+                        Bitmap.Config.ARGB_8888);
+                Canvas c = new Canvas(thumbnail);
+                c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight + size),
+                        new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null);
+                c.setBitmap(null);
+                // Recycle the old screenshot
+                screenshot.recycle();
+            } else {
+                // Create the thumbnail
+                thumbnail = Bitmap.createBitmap(mFirstTaskRect.width(), mFirstTaskRect.height(),
+                        Bitmap.Config.ARGB_8888);
+                int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight());
+                Canvas c = new Canvas(thumbnail);
+                c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size),
+                        new Rect(0, 0, mFirstTaskRect.width(), mFirstTaskRect.height()), null);
+                c.setBitmap(null);
+                // Recycle the old thumbnail
+                firstThumbnail.recycle();
+            }
+
+            ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView,
+                    thumbnail, mFirstTaskRect.left, mFirstTaskRect.top, null);
+            startAlternateRecentsActivity(opts);
+        } else {
+            ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
+                    R.anim.recents_from_launcher_enter,
+                    R.anim.recents_from_launcher_exit);
+            startAlternateRecentsActivity(opts);
+        }
+
+        Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                Constants.DebugFlags.App.TimeRecentsStartupKey, "startRecentsActivity");
+        mLastToggleTime = System.currentTimeMillis();
+    }
+
+    /** Starts the recents activity */
+    void startAlternateRecentsActivity(ActivityOptions opts) {
+        Intent intent = new Intent(sToggleRecentsAction);
+        intent.setClassName(sRecentsPackage, sRecentsActivity);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        if (opts != null) {
+            mContext.startActivityAsUser(intent, opts.toBundle(), new UserHandle(
+                    UserHandle.USER_CURRENT));
+        } else {
+            mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Console.java b/packages/SystemUI/src/com/android/systemui/recents/Console.java
new file mode 100644
index 0000000..4b75c99
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/Console.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+
+import android.content.ComponentCallbacks2;
+import android.content.Context;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.widget.Toast;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+public class Console {
+    // Timer
+    public static final Map<Object, Long> mTimeLogs = new HashMap<Object, Long>();
+
+    // Colors
+    public static final String AnsiReset = "\u001B[0m";
+    public static final String AnsiBlack = "\u001B[30m";
+    public static final String AnsiRed = "\u001B[31m";      // SystemUIHandshake
+    public static final String AnsiGreen = "\u001B[32m";    // MeasureAndLayout
+    public static final String AnsiYellow = "\u001B[33m";   // SynchronizeViewsWithModel
+    public static final String AnsiBlue = "\u001B[34m";     // TouchEvents
+    public static final String AnsiPurple = "\u001B[35m";   // Draw
+    public static final String AnsiCyan = "\u001B[36m";     // ClickEvents
+    public static final String AnsiWhite = "\u001B[37m";
+
+    /** Logs a key */
+    public static void log(String key) {
+        log(true, key, "", AnsiReset);
+    }
+
+    /** Logs a conditioned key */
+    public static void log(boolean condition, String key) {
+        if (condition) {
+            log(condition, key, "", AnsiReset);
+        }
+    }
+
+    /** Logs a key in a specific color */
+    public static void log(boolean condition, String key, Object data) {
+        if (condition) {
+            log(condition, key, data, AnsiReset);
+        }
+    }
+
+    /** Logs a key with data in a specific color */
+    public static void log(boolean condition, String key, Object data, String color) {
+        if (condition) {
+            System.out.println(color + key + AnsiReset + " " + data.toString());
+        }
+    }
+
+    /** Logs an error */
+    public static void logError(Context context, String msg) {
+        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
+        Log.e("Recents", msg);
+    }
+
+    /** Logs a raw error */
+    public static void logRawError(String msg, Exception e) {
+        Log.e("Recents", msg, e);
+    }
+
+    /** Logs a divider bar */
+    public static void logDivider(boolean condition) {
+        if (condition) {
+            System.out.println("==== [" + System.currentTimeMillis() +
+                    "] ============================================================");
+        }
+    }
+
+    /** Starts a time trace */
+    public static void logStartTracingTime(boolean condition, String key) {
+        if (condition) {
+            long curTime = System.currentTimeMillis();
+            mTimeLogs.put(key, curTime);
+            Console.log(condition, "[Recents|" + key + "]",
+                    "started @ " + curTime);
+        }
+    }
+
+    /** Continues a time trace */
+    public static void logTraceTime(boolean condition, String key, String desc) {
+        if (condition) {
+            long timeDiff = System.currentTimeMillis() - mTimeLogs.get(key);
+            Console.log(condition, "[Recents|" + key + "|" + desc + "]",
+                    "+" + timeDiff + "ms");
+        }
+    }
+
+    /** Logs a stack trace */
+    public static void logStackTrace() {
+        logStackTrace("", 99);
+    }
+
+    /** Logs a stack trace to a certain depth */
+    public static void logStackTrace(int depth) {
+        logStackTrace("", depth);
+    }
+
+    /** Logs a stack trace to a certain depth with a key */
+    public static void logStackTrace(String key, int depth) {
+        int offset = 0;
+        StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        String tinyStackTrace = "";
+        // Skip over the known stack trace classes
+        for (int i = 0; i < callStack.length; i++) {
+            StackTraceElement el = callStack[i];
+            String className = el.getClassName();
+            if (className.indexOf("dalvik.system.VMStack") == -1 &&
+                className.indexOf("java.lang.Thread") == -1 &&
+                className.indexOf("recents.Console") == -1) {
+                break;
+            } else {
+                offset++;
+            }
+        }
+        // Build the pretty stack trace
+        int start = Math.min(offset + depth, callStack.length);
+        int end = offset;
+        String indent = "";
+        for (int i = start - 1; i >= end; i--) {
+            StackTraceElement el = callStack[i];
+            tinyStackTrace += indent + " -> " + el.getClassName() +
+                    "[" + el.getLineNumber() + "]." + el.getMethodName();
+            if (i > end) {
+                tinyStackTrace += "\n";
+                indent += "  ";
+            }
+        }
+        log(true, key, tinyStackTrace, AnsiRed);
+    }
+
+
+    /** Returns the stringified MotionEvent action */
+    public static String motionEventActionToString(int action) {
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                return "Down";
+            case MotionEvent.ACTION_UP:
+                return "Up";
+            case MotionEvent.ACTION_MOVE:
+                return "Move";
+            case MotionEvent.ACTION_CANCEL:
+                return "Cancel";
+            case MotionEvent.ACTION_POINTER_DOWN:
+                return "Pointer Down";
+            case MotionEvent.ACTION_POINTER_UP:
+                return "Pointer Up";
+            default:
+                return "" + action;
+        }
+    }
+
+    public static String trimMemoryLevelToString(int level) {
+        switch (level) {
+            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+                return "UI Hidden";
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+                return "Running Moderate";
+            case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+                return "Background";
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+                return "Running Low";
+            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+                return "Moderate";
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+                return "Critical";
+            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+                return "Complete";
+            default:
+                return "" + level;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
new file mode 100644
index 0000000..2dc4b88
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+/**
+ * Constants
+ * XXX: We are going to move almost all of these into a resource.
+ */
+public class Constants {
+    public static class DebugFlags {
+        // Enable this with any other debug flag to see more info
+        public static final boolean Verbose = false;
+
+        public static class App {
+            public static final boolean EnableTaskFiltering = false;
+            public static final boolean EnableTaskStackClipping = false;
+            public static final boolean EnableToggleNewRecentsActivity = false;
+            // This disables the bitmap and icon caches to
+            public static final boolean DisableBackgroundCache = false;
+
+            // Timing certain paths
+            public static final String TimeRecentsStartupKey = "startup";
+            public static final String TimeRecentsLaunchKey = "launchTask";
+            public static final boolean TimeRecentsStartup = false;
+            public static final boolean TimeRecentsLaunchTask = false;
+
+            public static final boolean RecentsComponent = false;
+            public static final boolean TaskDataLoader = false;
+            public static final boolean SystemUIHandshake = false;
+            public static final boolean TimeSystemCalls = false;
+            public static final boolean Memory = false;
+        }
+
+        public static class UI {
+            public static final boolean Draw = false;
+            public static final boolean ClickEvents = false;
+            public static final boolean TouchEvents = false;
+            public static final boolean MeasureAndLayout = false;
+            public static final boolean Clipping = false;
+            public static final boolean HwLayers = false;
+        }
+
+        public static class TaskStack {
+            public static final boolean SynchronizeViewsWithModel = false;
+        }
+
+        public static class ViewPool {
+            public static final boolean PoolCallbacks = false;
+        }
+    }
+
+    public static class Values {
+        public static class Window {
+            // The dark background dim is set behind the empty recents view
+            public static final float DarkBackgroundDim = 0.5f;
+            // The background dim is set behind the card stack
+            public static final float BackgroundDim = 0.35f;
+        }
+
+        public static class RecentsTaskLoader {
+            // XXX: This should be calculated on the first load
+            public static final int PreloadFirstTasksCount = 5;
+            // For debugging, this allows us to multiply the number of cards for each task
+            public static final int TaskEntryMultiplier = 1;
+        }
+
+        public static class TaskStackView {
+            public static class Animation {
+                public static final int TaskRemovedReshuffleDuration = 200;
+                public static final int SnapScrollBackDuration = 650;
+            }
+
+            public static final int TaskStackOverscrollRange = 150;
+
+            // The padding will be applied to the smallest dimension, and then applied to all sides
+            public static final float StackPaddingPct = 0.15f;
+            // The overlap height relative to the task height
+            public static final float StackOverlapPct = 0.65f;
+            // The height of the peek space relative to the stack height
+            public static final float StackPeekHeightPct = 0.1f;
+            // The min scale of the last card in the peek area
+            public static final float StackPeekMinScale = 0.9f;
+            // The number of cards we see in the peek space
+            public static final int StackPeekNumCards = 3;
+        }
+
+        public static class TaskView {
+            public static class Animation {
+                public static final int TaskDataUpdatedFadeDuration = 250;
+                public static final int TaskIconOnEnterDuration = 175;
+                public static final int TaskIconOnLeavingDuration = 75;
+            }
+
+            public static final boolean AnimateFrontTaskIconOnEnterRecents = true;
+            public static final boolean AnimateFrontTaskIconOnLeavingRecents = true;
+            public static final boolean AnimateFrontTaskIconOnEnterUseClip = false;
+            public static final boolean AnimateFrontTaskIconOnLeavingUseClip = false;
+            public static final boolean DrawColoredTaskBars = false;
+            public static final boolean UseRoundedCorners = true;
+            public static final float RoundedCornerRadiusDps = 3;
+
+            public static final float TaskBarHeightDps = 54;
+            public static final float TaskIconSizeDps = 60;
+        }
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
new file mode 100644
index 0000000..b65b864
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.FrameLayout;
+import com.android.systemui.R;
+import com.android.systemui.recents.model.SpaceNode;
+import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.RecentsView;
+
+import java.util.ArrayList;
+
+
+/* Activity */
+public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks {
+    FrameLayout mContainerView;
+    RecentsView mRecentsView;
+    View mEmptyView;
+
+    boolean mVisible;
+    boolean mTaskLaunched;
+
+    BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+                    "[RecentsActivity|serviceBroadcast]", action, Console.AnsiRed);
+            if (action.equals(RecentsService.ACTION_FINISH_RECENTS_ACTIVITY)) {
+                if (Constants.DebugFlags.App.EnableToggleNewRecentsActivity) {
+                    finish();
+                }
+            } else if (action.equals(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY)) {
+                // Dismiss recents and launch the first task if possible
+                dismissRecentsIfVisible();
+            }
+        }
+    };
+
+    /** Updates the set of recent tasks */
+    void updateRecentsTasks() {
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
+        ArrayList<TaskStack> stacks = root.getStacks();
+        if (!stacks.isEmpty()) {
+            mRecentsView.setBSP(root);
+        }
+
+        // Add the default no-recents layout
+        if (stacks.size() == 1 && stacks.get(0).getTaskCount() == 0) {
+            mEmptyView.setVisibility(View.VISIBLE);
+
+            // Dim the background even more
+            WindowManager.LayoutParams wlp = getWindow().getAttributes();
+            wlp.dimAmount = Constants.Values.Window.DarkBackgroundDim;
+            getWindow().setAttributes(wlp);
+            getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+        } else {
+            mEmptyView.setVisibility(View.GONE);
+        }
+    }
+
+    /** Dismisses recents if we are already visible and the intent is to toggle the recents view */
+    boolean dismissRecentsIfVisible() {
+        if (mVisible) {
+            if (!mRecentsView.launchFirstTask()) {
+                finish();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /** Called with the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Console.logDivider(Constants.DebugFlags.App.SystemUIHandshake);
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onCreate]",
+                getIntent().getAction() + " visible: " + mVisible, Console.AnsiRed);
+        Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                Constants.DebugFlags.App.TimeRecentsStartupKey, "onCreate");
+
+        // Initialize the loader and the configuration
+        RecentsTaskLoader.initialize(this);
+        RecentsConfiguration.reinitialize(this);
+
+        // Set the background dim
+        WindowManager.LayoutParams wlp = getWindow().getAttributes();
+        wlp.dimAmount = Constants.Values.Window.BackgroundDim;
+        getWindow().setAttributes(wlp);
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+
+        // Create the view hierarchy
+        mRecentsView = new RecentsView(this);
+        mRecentsView.setCallbacks(this);
+        mRecentsView.setLayoutParams(new FrameLayout.LayoutParams(
+                FrameLayout.LayoutParams.MATCH_PARENT,
+                FrameLayout.LayoutParams.MATCH_PARENT));
+
+        // Create the empty view
+        LayoutInflater inflater = LayoutInflater.from(this);
+        mEmptyView = inflater.inflate(R.layout.recents_empty, mContainerView, false);
+
+        mContainerView = new FrameLayout(this);
+        mContainerView.addView(mRecentsView);
+        mContainerView.addView(mEmptyView);
+        setContentView(mContainerView);
+
+        // Update the recent tasks
+        updateRecentsTasks();
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        // Reset the task launched flag if we encounter an onNewIntent() before onStop()
+        mTaskLaunched = false;
+
+        Console.logDivider(Constants.DebugFlags.App.SystemUIHandshake);
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onNewIntent]",
+                intent.getAction() + " visible: " + mVisible, Console.AnsiRed);
+        Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                Constants.DebugFlags.App.TimeRecentsStartupKey, "onNewIntent");
+
+        // Initialize the loader and the configuration
+        RecentsTaskLoader.initialize(this);
+        RecentsConfiguration.reinitialize(this);
+
+        // Update the recent tasks
+        updateRecentsTasks();
+    }
+
+    @Override
+    protected void onStart() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onStart]", "",
+                Console.AnsiRed);
+        super.onStart();
+        mVisible = true;
+    }
+
+    @Override
+    protected void onResume() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onResume]", "",
+                Console.AnsiRed);
+        super.onResume();
+
+        // Register the broadcast receiver to handle messages from our service
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
+        filter.addAction(RecentsService.ACTION_FINISH_RECENTS_ACTIVITY);
+        registerReceiver(mServiceBroadcastReceiver, filter);
+    }
+
+    @Override
+    protected void onPause() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onPause]", "",
+                Console.AnsiRed);
+        super.onPause();
+
+        // Unregister any broadcast receivers we have registered
+        unregisterReceiver(mServiceBroadcastReceiver);
+    }
+
+    @Override
+    protected void onStop() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onStop]", "",
+                Console.AnsiRed);
+        super.onStop();
+
+        // Finish the current recents activity after we have launched a task
+        if (mTaskLaunched && Constants.DebugFlags.App.EnableToggleNewRecentsActivity) {
+            finish();
+        }
+
+        mVisible = false;
+        mTaskLaunched = false;
+    }
+
+    @Override
+    protected void onDestroy() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onDestroy]", "",
+                Console.AnsiRed);
+        super.onDestroy();
+    }
+
+    @Override
+    public void onTrimMemory(int level) {
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        if (loader != null) {
+            loader.onTrimMemory(level);
+        }
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (!mRecentsView.unfilterFilteredStacks()) {
+            super.onBackPressed();
+        }
+    }
+
+    @Override
+    public void onTaskLaunching() {
+        mTaskLaunched = true;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
new file mode 100644
index 0000000..3d47cb6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
+
+
+/** A static Recents configuration for the current context
+ * NOTE: We should not hold any references to a Context from a static instance */
+public class RecentsConfiguration {
+    static RecentsConfiguration sInstance;
+
+    DisplayMetrics mDisplayMetrics;
+
+    public Rect systemInsets = new Rect();
+    public Rect displayRect = new Rect();
+
+    /** Private constructor */
+    private RecentsConfiguration() {}
+
+    /** Updates the configuration to the current context */
+    public static RecentsConfiguration reinitialize(Context context) {
+        if (sInstance == null) {
+            sInstance = new RecentsConfiguration();
+        }
+        sInstance.update(context);
+        return sInstance;
+    }
+
+    /** Returns the current recents configuration */
+    public static RecentsConfiguration getInstance() {
+        return sInstance;
+    }
+
+    /** Updates the state, given the specified context */
+    void update(Context context) {
+        Resources res = context.getResources();
+        DisplayMetrics dm = res.getDisplayMetrics();
+        mDisplayMetrics = dm;
+
+        displayRect.set(0, 0, dm.widthPixels, dm.heightPixels);
+    }
+
+    public void updateSystemInsets(Rect insets) {
+        systemInsets.set(insets);
+    }
+
+    /** Converts from DPs to PXs */
+    public int pxFromDp(float size) {
+        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+                size, mDisplayMetrics));
+    }
+    /** Converts from SPs to PXs */
+    public int pxFromSp(float size) {
+        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
+                size, mDisplayMetrics));
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
new file mode 100644
index 0000000..515cec1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+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 com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.views.TaskStackView;
+import com.android.systemui.recents.views.TaskViewTransform;
+
+import java.lang.ref.WeakReference;
+
+
+/** The message handler to process Recents SysUI messages */
+class SystemUIMessageHandler extends Handler {
+    WeakReference<Context> mContext;
+
+    SystemUIMessageHandler(Context context) {
+        // Keep a weak ref to the context instead of a strong ref
+        mContext = new WeakReference<Context>(context);
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+                "[RecentsService|handleMessage]", msg);
+
+        Context context = mContext.get();
+        if (context == null) return;
+
+        if (msg.what == RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION) {
+            RecentsTaskLoader.initialize(context);
+            RecentsConfiguration.reinitialize(context);
+
+            try {
+                Bundle data = msg.getData();
+                Rect windowRect = (Rect) data.getParcelable("windowRect");
+                Rect systemInsets = (Rect) data.getParcelable("systemInsets");
+
+                // Create a dummy task stack & compute the rect for the thumbnail to animate to
+                TaskStack stack = new TaskStack(context);
+                TaskStackView tsv = new TaskStackView(context, stack);
+                // Since the nav bar height is already accounted for in the windowRect, don't pass
+                // in a bottom inset
+                tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top, 0);
+                tsv.boundScroll();
+                TaskViewTransform transform = tsv.getStackTransform(0);
+                Rect taskRect = new Rect(transform.rect);
+
+                data.putParcelable("taskRect", taskRect);
+                Message reply = Message.obtain(null,
+                        RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0);
+                reply.setData(data);
+                msg.replyTo.send(reply);
+            } catch (RemoteException re) {
+                re.printStackTrace();
+            }
+        } else if (msg.what == RecentsService.MSG_CLOSE_RECENTS) {
+            // Do nothing
+        } else if (msg.what == RecentsService.MSG_TOGGLE_RECENTS) {
+            // Send a broadcast to toggle recents
+            Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
+            intent.setPackage(context.getPackageName());
+            context.sendBroadcast(intent);
+
+            // Time this path
+            Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                    Constants.DebugFlags.App.TimeRecentsStartupKey, "receivedToggleRecents");
+            Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsLaunchTask,
+                    Constants.DebugFlags.App.TimeRecentsLaunchKey, "receivedToggleRecents");
+        }
+    }
+}
+
+/* Service */
+public class RecentsService extends Service {
+    final static String ACTION_FINISH_RECENTS_ACTIVITY = "action_finish_recents_activity";
+    final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
+
+    // XXX: This should be getting the message from recents definition
+    final static int MSG_UPDATE_RECENTS_FOR_CONFIGURATION = 0;
+    final static int MSG_CLOSE_RECENTS = 4;
+    final static int MSG_TOGGLE_RECENTS = 5;
+
+    Messenger mSystemUIMessenger = new Messenger(new SystemUIMessageHandler(this));
+
+    @Override
+    public void onCreate() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onCreate]");
+        super.onCreate();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onBind]");
+        return mSystemUIMessenger.getBinder();
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onUnbind]");
+        return super.onUnbind(intent);
+    }
+
+    @Override
+    public void onRebind(Intent intent) {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onRebind]");
+        super.onRebind(intent);
+    }
+
+    @Override
+    public void onDestroy() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onDestroy]");
+        super.onDestroy();
+    }
+
+    @Override
+    public void onTrimMemory(int level) {
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        if (loader != null) {
+            loader.onTrimMemory(level);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
new file mode 100644
index 0000000..cdbee82
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+import android.app.ActivityManager;
+import android.content.ComponentCallbacks2;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.UserHandle;
+import android.util.LruCache;
+import android.util.Pair;
+import com.android.systemui.recents.model.SpaceNode;
+import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.model.TaskStack;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+
+/** A bitmap load queue */
+class TaskResourceLoadQueue {
+    ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<Task>();
+    ConcurrentHashMap<Task.TaskKey, Boolean> mForceLoadSet =
+            new ConcurrentHashMap<Task.TaskKey, Boolean>();
+
+    static final Boolean sFalse = new Boolean(false);
+
+    /** Adds a new task to the load queue */
+    void addTask(Task t, boolean forceLoad) {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [TaskResourceLoadQueue|addTask]");
+        if (!mQueue.contains(t)) {
+            mQueue.add(t);
+        }
+        if (forceLoad) {
+            mForceLoadSet.put(t.key, new Boolean(true));
+        }
+        synchronized(this) {
+            notifyAll();
+        }
+    }
+
+    /**
+     * Retrieves the next task from the load queue, as well as whether we want that task to be
+     * force reloaded.
+     */
+    Pair<Task, Boolean> nextTask() {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [TaskResourceLoadQueue|nextTask]");
+        Task task = mQueue.poll();
+        Boolean forceLoadTask = null;
+        if (task != null) {
+            forceLoadTask = mForceLoadSet.remove(task.key);
+        }
+        if (forceLoadTask == null) {
+            forceLoadTask = sFalse;
+        }
+        return new Pair<Task, Boolean>(task, forceLoadTask);
+    }
+
+    /** Removes a task from the load queue */
+    void removeTask(Task t) {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [TaskResourceLoadQueue|removeTask]");
+        mQueue.remove(t);
+        mForceLoadSet.remove(t.key);
+    }
+
+    /** Clears all the tasks from the load queue */
+    void clearTasks() {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [TaskResourceLoadQueue|clearTasks]");
+        mQueue.clear();
+        mForceLoadSet.clear();
+    }
+
+    /** Returns whether the load queue is empty */
+    boolean isEmpty() {
+        return mQueue.isEmpty();
+    }
+}
+
+/* Task resource loader */
+class TaskResourceLoader implements Runnable {
+    Context mContext;
+    HandlerThread mLoadThread;
+    Handler mLoadThreadHandler;
+    Handler mMainThreadHandler;
+
+    TaskResourceLoadQueue mLoadQueue;
+    DrawableLruCache mIconCache;
+    BitmapLruCache mThumbnailCache;
+
+    boolean mCancelled;
+    boolean mWaitingOnLoadQueue;
+
+    /** Constructor, creates a new loading thread that loads task resources in the background */
+    public TaskResourceLoader(TaskResourceLoadQueue loadQueue, DrawableLruCache iconCache,
+                              BitmapLruCache thumbnailCache) {
+        mLoadQueue = loadQueue;
+        mIconCache = iconCache;
+        mThumbnailCache = thumbnailCache;
+        mMainThreadHandler = new Handler();
+        mLoadThread = new HandlerThread("Recents-TaskResourceLoader");
+        mLoadThread.setPriority(Thread.NORM_PRIORITY - 1);
+        mLoadThread.start();
+        mLoadThreadHandler = new Handler(mLoadThread.getLooper());
+        mLoadThreadHandler.post(this);
+    }
+
+    /** Restarts the loader thread */
+    void start(Context context) {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|start]");
+        mContext = context;
+        mCancelled = false;
+        // Notify the load thread to start loading
+        synchronized(mLoadThread) {
+            mLoadThread.notifyAll();
+        }
+    }
+
+    /** Requests the loader thread to stop after the current iteration */
+    void stop() {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|stop]");
+        // Mark as cancelled for the thread to pick up
+        mCancelled = true;
+        // If we are waiting for the load queue for more tasks, then we can just reset the
+        // Context now, since nothing is using it
+        if (mWaitingOnLoadQueue) {
+            mContext = null;
+        }
+    }
+
+    @Override
+    public void run() {
+        while (true) {
+            Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                    "[TaskResourceLoader|run|" + Thread.currentThread().getId() + "]");
+            if (mCancelled) {
+                Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                        "[TaskResourceLoader|cancel|" + Thread.currentThread().getId() + "]");
+                // We have to unset the context here, since the background thread may be using it
+                // when we call stop()
+                mContext = null;
+                // If we are cancelled, then wait until we are started again
+                synchronized(mLoadThread) {
+                    try {
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "[TaskResourceLoader|waitOnLoadThreadCancelled]");
+                        mLoadThread.wait();
+                    } catch (InterruptedException ie) {
+                        ie.printStackTrace();
+                    }
+                }
+            } else {
+                // Load the next item from the queue
+                Pair<Task, Boolean> nextTaskData = mLoadQueue.nextTask();
+                final Task t = nextTaskData.first;
+                final boolean forceLoadTask = nextTaskData.second;
+                if (t != null) {
+                    try {
+                        Drawable loadIcon = mIconCache.get(t.key);
+                        Bitmap loadThumbnail = mThumbnailCache.get(t.key);
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "  [TaskResourceLoader|load]",
+                                t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail +
+                                        " forceLoad: " + forceLoadTask);
+                        // Load the icon
+                        if (loadIcon == null || forceLoadTask) {
+                            PackageManager pm = mContext.getPackageManager();
+                            ActivityInfo info = pm.getActivityInfo(t.key.intent.getComponent(),
+                                    PackageManager.GET_META_DATA);
+                            Drawable icon = info.loadIcon(pm);
+                            if (!mCancelled) {
+                                if (icon != null) {
+                                    Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                            "    [TaskResourceLoader|loadIcon]",
+                                            icon);
+                                    loadIcon = icon;
+                                    mIconCache.put(t.key, icon);
+                                }
+                            }
+                        }
+                        // Load the thumbnail
+                        if (loadThumbnail == null || forceLoadTask) {
+                            ActivityManager am = (ActivityManager)
+                                    mContext.getSystemService(Context.ACTIVITY_SERVICE);
+                            Bitmap thumbnail = am.getTaskTopThumbnail(t.key.id);
+                            if (!mCancelled) {
+                                if (thumbnail != null) {
+                                    Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                            "    [TaskResourceLoader|loadThumbnail]",
+                                            thumbnail);
+                                    loadThumbnail = thumbnail;
+                                    mThumbnailCache.put(t.key, thumbnail);
+                                } else {
+                                    Console.logError(mContext,
+                                            "Failed to load task top thumbnail for: " +
+                                                    t.key.intent.getComponent().getPackageName());
+                                }
+                            }
+                        }
+                        if (!mCancelled) {
+                            // Notify that the task data has changed
+                            final Drawable newIcon = loadIcon;
+                            final Bitmap newThumbnail = loadThumbnail;
+                            mMainThreadHandler.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    t.notifyTaskDataLoaded(newThumbnail, newIcon, forceLoadTask);
+                                }
+                            });
+                        }
+                    } catch (PackageManager.NameNotFoundException ne) {
+                        ne.printStackTrace();
+                    }
+                }
+
+                // If there are no other items in the list, then just wait until something is added
+                if (!mCancelled && mLoadQueue.isEmpty()) {
+                    synchronized(mLoadQueue) {
+                        try {
+                            Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                    "[TaskResourceLoader|waitOnLoadQueue]");
+                            mWaitingOnLoadQueue = true;
+                            mLoadQueue.wait();
+                            mWaitingOnLoadQueue = false;
+                        } catch (InterruptedException ie) {
+                            ie.printStackTrace();
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**
+ * The drawable cache.  By using the Task's key, we can prevent holding onto a reference to the Task
+ * resource data, while keeping the cache data in memory where necessary.
+ */
+class DrawableLruCache extends LruCache<Task.TaskKey, Drawable> {
+    public DrawableLruCache(int cacheSize) {
+        super(cacheSize);
+    }
+
+    @Override
+    protected int sizeOf(Task.TaskKey t, Drawable d) {
+        // The cache size will be measured in kilobytes rather than number of items
+        // NOTE: this isn't actually correct, as the icon may be smaller
+        int maxBytes = (d.getIntrinsicWidth() * d.getIntrinsicHeight() * 4);
+        return maxBytes / 1024;
+    }
+}
+
+/**
+ * The bitmap cache.  By using the Task's key, we can prevent holding onto a reference to the Task
+ * resource data, while keeping the cache data in memory where necessary.
+ */
+class BitmapLruCache extends LruCache<Task.TaskKey, Bitmap> {
+    public BitmapLruCache(int cacheSize) {
+        super(cacheSize);
+    }
+
+    @Override
+    protected int sizeOf(Task.TaskKey t, Bitmap bitmap) {
+        // The cache size will be measured in kilobytes rather than number of items
+        return bitmap.getAllocationByteCount() / 1024;
+    }
+}
+
+/* Recents task loader
+ * NOTE: We should not hold any references to a Context from a static instance */
+public class RecentsTaskLoader {
+    static RecentsTaskLoader sInstance;
+
+    DrawableLruCache mIconCache;
+    BitmapLruCache mThumbnailCache;
+    TaskResourceLoadQueue mLoadQueue;
+    TaskResourceLoader mLoader;
+
+    int mMaxThumbnailCacheSize;
+    int mMaxIconCacheSize;
+
+    BitmapDrawable mDefaultIcon;
+    Bitmap mDefaultThumbnail;
+
+    /** Private Constructor */
+    private RecentsTaskLoader(Context context) {
+        // Calculate the cache sizes, we just use a reasonable number here similar to those
+        // suggested in the Android docs, 1/8th for the thumbnail cache and 1/32 of the max memory
+        // for icons.
+        int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
+        mMaxThumbnailCacheSize = maxMemory / 8;
+        mMaxIconCacheSize = mMaxThumbnailCacheSize / 4;
+        int iconCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
+                mMaxIconCacheSize;
+        int thumbnailCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
+                mMaxThumbnailCacheSize;
+
+        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                "[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +
+                " iconCache: " + iconCacheSize);
+
+        // Initialize the cache and loaders
+        mLoadQueue = new TaskResourceLoadQueue();
+        mIconCache = new DrawableLruCache(iconCacheSize);
+        mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
+        mLoader = new TaskResourceLoader(mLoadQueue, mIconCache, mThumbnailCache);
+
+        // Create the default assets
+        Bitmap icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        mDefaultThumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+        Canvas c = new Canvas();
+        c.setBitmap(icon);
+        c.drawColor(0x00000000);
+        c.setBitmap(mDefaultThumbnail);
+        c.drawColor(0x00000000);
+        c.setBitmap(null);
+        mDefaultIcon = new BitmapDrawable(context.getResources(), icon);
+        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                "[RecentsTaskLoader|defaultBitmaps]",
+                "icon: " + mDefaultIcon + " thumbnail: " + mDefaultThumbnail, Console.AnsiRed);
+    }
+
+    /** Initializes the recents task loader */
+    public static RecentsTaskLoader initialize(Context context) {
+        if (sInstance == null) {
+            sInstance = new RecentsTaskLoader(context);
+        }
+        return sInstance;
+    }
+
+    /** Returns the current recents task loader */
+    public static RecentsTaskLoader getInstance() {
+        return sInstance;
+    }
+
+    /** Reload the set of recent tasks */
+    SpaceNode reload(Context context, int preloadCount) {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
+        ArrayList<Task> tasksToForceLoad = new ArrayList<Task>();
+        TaskStack stack = new TaskStack(context);
+        SpaceNode root = new SpaceNode(context);
+        root.setStack(stack);
+
+        try {
+            long t1 = System.currentTimeMillis();
+
+            PackageManager pm = context.getPackageManager();
+            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+
+            // Get the recent tasks
+            List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(25,
+                    ActivityManager.RECENT_IGNORE_UNAVAILABLE |
+                    ActivityManager.RECENT_INCLUDE_RELATED, UserHandle.CURRENT.getIdentifier());
+            Collections.reverse(tasks);
+            Console.log(Constants.DebugFlags.App.TimeSystemCalls,
+                    "[RecentsTaskLoader|getRecentTasks]",
+                    "" + (System.currentTimeMillis() - t1) + "ms");
+            Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                    "[RecentsTaskLoader|tasks]", "" + tasks.size());
+
+            // Remove home/recents tasks
+            Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
+            while (iter.hasNext()) {
+                ActivityManager.RecentTaskInfo t = iter.next();
+
+                // Skip tasks in the home stack
+                if (am.isInHomeStack(t.persistentId)) {
+                    iter.remove();
+                    continue;
+                }
+                // Skip tasks from this Recents package
+                if (t.baseIntent.getComponent().getPackageName().equals(context.getPackageName())) {
+                    iter.remove();
+                    continue;
+                }
+            }
+
+            // Add each task to the task stack
+            t1 = System.currentTimeMillis();
+            int taskCount = tasks.size();
+            for (int i = 0; i < taskCount; i++) {
+                ActivityManager.RecentTaskInfo t = tasks.get(i);
+                ActivityInfo info = pm.getActivityInfo(t.baseIntent.getComponent(),
+                        PackageManager.GET_META_DATA);
+                String title = info.loadLabel(pm).toString();
+                boolean isForemostTask = (i == (taskCount - 1));
+
+                // Preload the specified number of apps
+                if (i >= (taskCount - preloadCount)) {
+                    Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                            "[RecentsTaskLoader|preloadTask]",
+                            "i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
+
+                    Task task = new Task(t.persistentId, t.baseIntent, title);
+
+                    // Load the icon (if possible and not the foremost task, from the cache)
+                    if (!isForemostTask) {
+                        task.icon = mIconCache.get(task.key);
+
+                        if (task.icon != null) {
+                            // Even though we get things from the cache, we should update them if
+                            // they've changed in the bg
+                            tasksToForceLoad.add(task);
+                        }
+                    }
+                    if (task.icon == null) {
+                        task.icon = info.loadIcon(pm);
+                        if (task.icon != null) {
+                            mIconCache.put(task.key, task.icon);
+                        } else {
+                            task.icon = mDefaultIcon;
+                        }
+                    }
+
+                    // Load the thumbnail (if possible and not the foremost task, from the cache)
+                    if (!isForemostTask) {
+                        task.thumbnail = mThumbnailCache.get(task.key);
+
+                        if (task.thumbnail != null) {
+                            // Even though we get things from the cache, we should update them if
+                            // they've changed in the bg
+                            tasksToForceLoad.add(task);
+                        }
+                    }
+                    if (task.thumbnail == null) {
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "[RecentsTaskLoader|loadingTaskThumbnail]");
+                        task.thumbnail = am.getTaskTopThumbnail(t.id);
+                        if (task.thumbnail != null) {
+                            mThumbnailCache.put(task.key, task.thumbnail);
+                        } else {
+                            task.thumbnail = mDefaultThumbnail;
+                        }
+                    }
+
+                    // Create as many tasks a we want to multiply by
+                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
+                        stack.addTask(task);
+                    }
+                } else {
+                    // Create as many tasks a we want to multiply by
+                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
+                        stack.addTask(new Task(t.persistentId, t.baseIntent, title));
+                    }
+                }
+            }
+            Console.log(Constants.DebugFlags.App.TimeSystemCalls,
+                    "[RecentsTaskLoader|getAllTaskTopThumbnail]",
+                    "" + (System.currentTimeMillis() - t1) + "ms");
+
+            /*
+            // Get all the stacks
+            t1 = System.currentTimeMillis();
+            List<ActivityManager.StackInfo> stackInfos = ams.getAllStackInfos();
+            Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getAllStackInfos]", "" + (System.currentTimeMillis() - t1) + "ms");
+            Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stacks]", "" + tasks.size());
+            for (ActivityManager.StackInfo s : stackInfos) {
+                Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [RecentsTaskLoader|stack]", s.toString());
+                if (stacks.containsKey(s.stackId)) {
+                    stacks.get(s.stackId).setRect(s.bounds);
+                }
+            }
+            */
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        // Start the task loader
+        mLoader.start(context);
+
+        // Add all the tasks that we are force/re-loading
+        for (Task t : tasksToForceLoad) {
+            mLoadQueue.addTask(t, true);
+        }
+
+        return root;
+    }
+
+    /** Acquires the task resource data from the pool. */
+    public void loadTaskData(Task t) {
+        Drawable icon = mIconCache.get(t.key);
+        Bitmap thumbnail = mThumbnailCache.get(t.key);
+
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
+                t + " icon: " + icon + " thumbnail: " + thumbnail +
+                        " thumbnailCacheSize: " + mThumbnailCache.size());
+
+        boolean requiresLoad = false;
+        if (icon == null) {
+            icon = mDefaultIcon;
+            requiresLoad = true;
+        }
+        if (thumbnail == null) {
+            thumbnail = mDefaultThumbnail;
+            requiresLoad = true;
+        }
+        if (requiresLoad) {
+            mLoadQueue.addTask(t, false);
+        }
+        t.notifyTaskDataLoaded(thumbnail, icon, false);
+    }
+
+    /** Releases the task resource data back into the pool. */
+    public void unloadTaskData(Task t) {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                "[RecentsTaskLoader|unloadTask]", t +
+                " thumbnailCacheSize: " + mThumbnailCache.size());
+
+        mLoadQueue.removeTask(t);
+        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
+    }
+
+    /** Completely removes the resource data from the pool. */
+    public void deleteTaskData(Task t) {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                "[RecentsTaskLoader|deleteTask]", t);
+
+        mLoadQueue.removeTask(t);
+        mThumbnailCache.remove(t.key);
+        mIconCache.remove(t.key);
+        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
+    }
+
+    /** Stops the task loader and clears all pending tasks */
+    void stopLoader() {
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stopLoader]");
+        mLoader.stop();
+        mLoadQueue.clearTasks();
+    }
+
+    void onTrimMemory(int level) {
+        Console.log(Constants.DebugFlags.App.Memory, "[RecentsTaskLoader|onTrimMemory]",
+                Console.trimMemoryLevelToString(level));
+
+        switch (level) {
+            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+                // Stop the loader immediately when the UI is no longer visible
+                stopLoader();
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+            case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+                // We are leaving recents, so trim the data a bit
+                mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
+                mIconCache.trimToSize(mMaxIconCacheSize / 2);
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+                // We are going to be low on memory
+                mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
+                mIconCache.trimToSize(mMaxIconCacheSize / 4);
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+                // We are low on memory, so release everything
+                mThumbnailCache.evictAll();
+                mIconCache.evictAll();
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/Utilities.java
new file mode 100644
index 0000000..33e4246
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/Utilities.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents;
+
+import android.graphics.Rect;
+
+/* Common code */
+public class Utilities {
+    public static final Rect tmpRect = new Rect();
+    public static final Rect tmpRect2 = new Rect();
+
+    /** Scales a rect about its centroid */
+    public static void scaleRectAboutCenter(Rect r, float scale) {
+        if (scale != 1.0f) {
+            int cx = r.centerX();
+            int cy = r.centerY();
+            r.offset(-cx, -cy);
+            r.left = (int) (r.left * scale + 0.5f);
+            r.top = (int) (r.top * scale + 0.5f);
+            r.right = (int) (r.right * scale + 0.5f);
+            r.bottom = (int) (r.bottom * scale + 0.5f);
+            r.offset(cx, cy);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
new file mode 100644
index 0000000..1dd1be6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.model;
+
+import android.content.Context;
+import android.graphics.Rect;
+
+import java.util.ArrayList;
+
+
+/**
+ * The full recents space is partitioned using a BSP into various nodes that define where task
+ * stacks should be placed.
+ */
+public class SpaceNode {
+    /* BSP node callbacks */
+    public interface SpaceNodeCallbacks {
+        /** Notifies when a node is added */
+        public void onSpaceNodeAdded(SpaceNode node);
+        /** Notifies when a node is measured */
+        public void onSpaceNodeMeasured(SpaceNode node, Rect rect);
+    }
+
+    Context mContext;
+
+    SpaceNode mStartNode;
+    SpaceNode mEndNode;
+
+    TaskStack mStack;
+
+    public SpaceNode(Context context) {
+        mContext = context;
+    }
+
+    /** Sets the current stack for this space node */
+    public void setStack(TaskStack stack) {
+        mStack = stack;
+    }
+
+    /** Returns the task stack (not null if this is a leaf) */
+    TaskStack getStack() {
+        return mStack;
+    }
+
+    /** Returns whether this is a leaf node */
+    boolean isLeafNode() {
+        return (mStartNode == null) && (mEndNode == null);
+    }
+
+    /** Returns all the descendent task stacks */
+    private void getStacksRec(ArrayList<TaskStack> stacks) {
+        if (isLeafNode()) {
+            stacks.add(mStack);
+        } else {
+            mStartNode.getStacksRec(stacks);
+            mEndNode.getStacksRec(stacks);
+        }
+    }
+    public ArrayList<TaskStack> getStacks() {
+        ArrayList<TaskStack> stacks = new ArrayList<TaskStack>();
+        getStacksRec(stacks);
+        return stacks;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
new file mode 100644
index 0000000..edcf9b2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.model;
+
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import com.android.systemui.recents.Constants;
+
+
+/**
+ * A task represents the top most task in the system's task stack.
+ */
+public class Task {
+    /* Task callbacks */
+    public interface TaskCallbacks {
+        /* Notifies when a task has been bound */
+        public void onTaskDataLoaded(boolean reloadingTaskData);
+        /* Notifies when a task has been unbound */
+        public void onTaskDataUnloaded();
+    }
+
+    /* The Task Key represents the unique primary key for the task */
+    public static class TaskKey {
+        public final int id;
+        public final Intent intent;
+
+        public TaskKey(int id, Intent intent) {
+            this.id = id;
+            this.intent = intent;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return hashCode() == o.hashCode();
+        }
+
+        @Override
+        public int hashCode() {
+            return id;
+        }
+
+        @Override
+        public String toString() {
+            return "Task.Key: " + id + ", " + intent.getComponent().getPackageName();
+        }
+    }
+
+    public TaskKey key;
+    public String title;
+    public Drawable icon;
+    public Bitmap thumbnail;
+
+    TaskCallbacks mCb;
+
+    public Task(int id, Intent intent, String activityTitle) {
+        this(id, intent, activityTitle, null, null);
+    }
+
+    public Task(int id, Intent intent, String activityTitle, Drawable icon, Bitmap thumbnail) {
+        this.key = new TaskKey(id, intent);
+        this.title = activityTitle;
+        this.icon = icon;
+        this.thumbnail = thumbnail;
+    }
+
+    /** Set the callbacks */
+    public void setCallbacks(TaskCallbacks cb) {
+        mCb = cb;
+    }
+
+    /** Notifies the callback listeners that this task has been loaded */
+    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon, boolean reloadingTaskData) {
+        this.icon = icon;
+        this.thumbnail = thumbnail;
+        if (mCb != null) {
+            mCb.onTaskDataLoaded(reloadingTaskData);
+        }
+    }
+
+    /** Notifies the callback listeners that this task has been unloaded */
+    public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultIcon) {
+        icon = defaultIcon;
+        thumbnail = defaultThumbnail;
+        if (mCb != null) {
+            mCb.onTaskDataUnloaded();
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        // If we have multiple task entries for the same task, then we do the simple object
+        // equality check
+        if (Constants.Values.RecentsTaskLoader.TaskEntryMultiplier > 1) {
+            return super.equals(o);
+        }
+
+        // Otherwise, check that the id and intent match (the other fields can be asynchronously
+        // loaded and is unsuitable to testing the identity of this Task)
+        Task t = (Task) o;
+        return key.equals(t.key);
+    }
+
+    @Override
+    public String toString() {
+        return "Task: " + key.intent.getComponent().getPackageName() + " [" + super.toString() + "]";
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
new file mode 100644
index 0000000..f2f89ae
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.model;
+
+import android.content.Context;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * An interface for a task filter to query whether a particular task should show in a stack.
+ */
+interface TaskFilter {
+    /** Returns whether the filter accepts the specified task */
+    public boolean acceptTask(Task t, int index);
+}
+
+/**
+ * A list of filtered tasks.
+ */
+class FilteredTaskList {
+    ArrayList<Task> mTasks = new ArrayList<Task>();
+    ArrayList<Task> mFilteredTasks = new ArrayList<Task>();
+    TaskFilter mFilter;
+
+    /** Sets the task filter, saving the current touch state */
+    void setFilter(TaskFilter filter) {
+        mFilter = filter;
+        updateFilteredTasks();
+    }
+
+    /** Removes the task filter and returns the previous touch state */
+    void removeFilter() {
+        mFilter = null;
+        updateFilteredTasks();
+    }
+
+    /** Adds a new task to the task list */
+    void add(Task t) {
+        mTasks.add(t);
+        updateFilteredTasks();
+    }
+
+    /** Sets the list of tasks */
+    void set(List<Task> tasks) {
+        mTasks.clear();
+        mTasks.addAll(tasks);
+        updateFilteredTasks();
+    }
+
+    /** Removes a task from the base list only if it is in the filtered list */
+    boolean remove(Task t) {
+        if (mFilteredTasks.contains(t)) {
+            boolean removed = mTasks.remove(t);
+            updateFilteredTasks();
+            return removed;
+        }
+        return false;
+    }
+
+    /** Returns the index of this task in the list of filtered tasks */
+    int indexOf(Task t) {
+        return mFilteredTasks.indexOf(t);
+    }
+
+    /** Returns the size of the list of filtered tasks */
+    int size() {
+        return mFilteredTasks.size();
+    }
+
+    /** Returns whether the filtered list contains this task */
+    boolean contains(Task t) {
+        return mFilteredTasks.contains(t);
+    }
+
+    /** Updates the list of filtered tasks whenever the base task list changes */
+    private void updateFilteredTasks() {
+        mFilteredTasks.clear();
+        if (mFilter != null) {
+            int taskCount = mTasks.size();
+            for (int i = 0; i < taskCount; i++) {
+                Task t = mTasks.get(i);
+                if (mFilter.acceptTask(t, i)) {
+                    mFilteredTasks.add(t);
+                }
+            }
+        } else {
+            mFilteredTasks.addAll(mTasks);
+        }
+    }
+
+    /** Returns whether this task list is filtered */
+    boolean hasFilter() {
+        return (mFilter != null);
+    }
+
+    /** Returns the list of filtered tasks */
+    ArrayList<Task> getTasks() {
+        return mFilteredTasks;
+    }
+}
+
+/**
+ * The task stack contains a list of multiple tasks.
+ */
+public class TaskStack {
+    /* Task stack callbacks */
+    public interface TaskStackCallbacks {
+        /* Notifies when a task has been added to the stack */
+        public void onStackTaskAdded(TaskStack stack, Task t);
+        /* Notifies when a task has been removed from the stack */
+        public void onStackTaskRemoved(TaskStack stack, Task t);
+        /** Notifies when the stack was filtered */
+        public void onStackFiltered(TaskStack stack);
+        /** Notifies when the stack was un-filtered */
+        public void onStackUnfiltered(TaskStack stack);
+    }
+
+    Context mContext;
+
+    FilteredTaskList mTaskList = new FilteredTaskList();
+    TaskStackCallbacks mCb;
+
+    public TaskStack(Context context) {
+        mContext = context;
+    }
+
+    /** Sets the callbacks for this task stack */
+    public void setCallbacks(TaskStackCallbacks cb) {
+        mCb = cb;
+    }
+
+    /** Adds a new task */
+    public void addTask(Task t) {
+        mTaskList.add(t);
+        if (mCb != null) {
+            mCb.onStackTaskAdded(this, t);
+        }
+    }
+
+    /** Removes a task */
+    public void removeTask(Task t) {
+        if (mTaskList.contains(t)) {
+            mTaskList.remove(t);
+            if (mCb != null) {
+                mCb.onStackTaskRemoved(this, t);
+            }
+        }
+    }
+
+    /** Sets a few tasks in one go */
+    public void setTasks(List<Task> tasks) {
+        int taskCount = mTaskList.getTasks().size();
+        for (int i = 0; i < taskCount; i++) {
+            Task t = mTaskList.getTasks().get(i);
+            if (mCb != null) {
+                mCb.onStackTaskRemoved(this, t);
+            }
+        }
+        mTaskList.set(tasks);
+        for (Task t : tasks) {
+            if (mCb != null) {
+                mCb.onStackTaskAdded(this, t);
+            }
+        }
+    }
+
+    /** Gets the tasks */
+    public ArrayList<Task> getTasks() {
+        return mTaskList.getTasks();
+    }
+
+    /** Gets the number of tasks */
+    public int getTaskCount() {
+        return mTaskList.size();
+    }
+
+    /** Returns the index of this task in this current task stack */
+    public int indexOfTask(Task t) {
+        return mTaskList.indexOf(t);
+    }
+
+    /** Tests whether a task is in this current task stack */
+    public boolean containsTask(Task t) {
+        return mTaskList.contains(t);
+    }
+
+    /** Filters the stack into tasks similar to the one specified */
+    public void filterTasks(Task t) {
+        // Set the task list filter
+        // XXX: This is a dummy filter that currently just accepts every other task.
+        mTaskList.setFilter(new TaskFilter() {
+            @Override
+            public boolean acceptTask(Task t, int i) {
+                if (i % 2 == 0) {
+                    return true;
+                }
+                return false;
+            }
+        });
+        if (mCb != null) {
+            mCb.onStackFiltered(this);
+        }
+    }
+
+    /** Unfilters the current stack */
+    public void unfilterTasks() {
+        // Unset the filter, then update the virtual scroll
+        mTaskList.removeFilter();
+        if (mCb != null) {
+            mCb.onStackUnfiltered(this);
+        }
+    }
+
+    /** Returns whether tasks are currently filtered */
+    public boolean hasFilteredTasks() {
+        return mTaskList.hasFilter();
+    }
+
+    @Override
+    public String toString() {
+        String str = "Tasks:\n";
+        for (Task t : mTaskList.getTasks()) {
+            str += "  " + t.toString() + "\n";
+        }
+        return str;
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
new file mode 100644
index 0000000..d997222
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.os.UserHandle;
+import android.view.View;
+import android.widget.FrameLayout;
+import com.android.systemui.recents.Console;
+import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.model.SpaceNode;
+import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.model.TaskStack;
+
+import java.util.ArrayList;
+
+
+/**
+ * This view is the the top level layout that contains TaskStacks (which are laid out according
+ * to their SpaceNode bounds.
+ */
+public class RecentsView extends FrameLayout implements TaskStackView.TaskStackViewCallbacks {
+
+    /** The RecentsView callbacks */
+    public interface RecentsViewCallbacks {
+        public void onTaskLaunching();
+    }
+
+    // The space partitioning root of this container
+    SpaceNode mBSP;
+    // Recents view callbacks
+    RecentsViewCallbacks mCb;
+
+    public RecentsView(Context context) {
+        super(context);
+        setWillNotDraw(false);
+    }
+
+    /** Sets the callbacks */
+    public void setCallbacks(RecentsViewCallbacks cb) {
+        mCb = cb;
+    }
+
+    /** Set/get the bsp root node */
+    public void setBSP(SpaceNode n) {
+        mBSP = n;
+
+        // Create and add all the stacks for this partition of space.
+        removeAllViews();
+        ArrayList<TaskStack> stacks = mBSP.getStacks();
+        for (TaskStack stack : stacks) {
+            TaskStackView stackView = new TaskStackView(getContext(), stack);
+            stackView.setCallbacks(this);
+            addView(stackView);
+        }
+    }
+
+    /** Launches the first task from the first stack if possible */
+    public boolean launchFirstTask() {
+        // Get the first stack view
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            TaskStackView stackView = (TaskStackView) getChildAt(i);
+            TaskStack stack = stackView.mStack;
+            ArrayList<Task> tasks = stack.getTasks();
+
+            // Get the first task in the stack
+            if (!tasks.isEmpty()) {
+                Task task = tasks.get(tasks.size() - 1);
+                TaskView tv = null;
+
+                // Try and use the first child task view as the source of the launch animation
+                if (stackView.getChildCount() > 0) {
+                    TaskView stv = (TaskView) stackView.getChildAt(stackView.getChildCount() - 1);
+                    if (stv.getTask() == task) {
+                        tv = stv;
+                    }
+                }
+                onTaskLaunched(stackView, tv, stack, task);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        int height = MeasureSpec.getSize(heightMeasureSpec);
+        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|measure]",
+                "width: " + width + " height: " + height, Console.AnsiGreen);
+        Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                Constants.DebugFlags.App.TimeRecentsStartupKey, "RecentsView.onMeasure");
+
+        // We measure our stack views sans the status bar.  It will handle the nav bar itself.
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        int childHeight = height - config.systemInsets.top;
+
+        // Measure each child
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                child.measure(widthMeasureSpec,
+                        MeasureSpec.makeMeasureSpec(childHeight, heightMode));
+            }
+        }
+
+        setMeasuredDimension(width, height);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|layout]",
+                new Rect(left, top, right, bottom) + " changed: " + changed, Console.AnsiGreen);
+        Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsStartup,
+                Constants.DebugFlags.App.TimeRecentsStartupKey, "RecentsView.onLayout");
+
+        // We offset our stack views by the status bar height.  It will handle the nav bar itself.
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        top += config.systemInsets.top;
+
+        // Layout each child
+        // XXX: Based on the space node for that task view
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() != GONE) {
+                final int width = child.getMeasuredWidth();
+                final int height = child.getMeasuredHeight();
+                child.layout(left, top, left + width, top + height);
+            }
+        }
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        Console.log(Constants.DebugFlags.UI.Draw, "[RecentsView|dispatchDraw]", "",
+                Console.AnsiPurple);
+        super.dispatchDraw(canvas);
+    }
+
+    @Override
+    protected boolean fitSystemWindows(Rect insets) {
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout,
+                "[RecentsView|fitSystemWindows]", "insets: " + insets, Console.AnsiGreen);
+
+        // Update the configuration with the latest system insets and trigger a relayout
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        config.updateSystemInsets(insets);
+        requestLayout();
+
+        return true;
+    }
+
+    /** Unfilters any filtered stacks */
+    public boolean unfilterFilteredStacks() {
+        if (mBSP != null) {
+            // Check if there are any filtered stacks and unfilter them before we back out of Recents
+            boolean stacksUnfiltered = false;
+            ArrayList<TaskStack> stacks = mBSP.getStacks();
+            for (TaskStack stack : stacks) {
+                if (stack.hasFilteredTasks()) {
+                    stack.unfilterTasks();
+                    stacksUnfiltered = true;
+                }
+            }
+            return stacksUnfiltered;
+        }
+        return false;
+    }
+
+    /**** TaskStackView.TaskStackCallbacks Implementation ****/
+
+    @Override
+    public void onTaskLaunched(final TaskStackView stackView, final TaskView tv,
+                               final TaskStack stack, final Task task) {
+        // Notify any callbacks of the launching of a new task
+        if (mCb != null) {
+            mCb.onTaskLaunching();
+        }
+
+        final Runnable launchRunnable = new Runnable() {
+            @Override
+            public void run() {
+                TaskViewTransform transform;
+                View sourceView = tv;
+                int offsetX = 0;
+                int offsetY = 0;
+                if (tv == null) {
+                    // If there is no actual task view, then use the stack view as the source view
+                    // and then offset to the expected transform rect, but bound this to just
+                    // outside the display rect (to ensure we don't animate from too far away)
+                    RecentsConfiguration config = RecentsConfiguration.getInstance();
+                    sourceView = stackView;
+                    transform = stackView.getStackTransform(stack.indexOfTask(task));
+                    offsetX = transform.rect.left;
+                    offsetY = Math.min(transform.rect.top, config.displayRect.height());
+                } else {
+                    transform = stackView.getStackTransform(stack.indexOfTask(task));
+                }
+
+                // Compute the thumbnail to scale up from
+                ActivityOptions opts = null;
+                int thumbnailWidth = transform.rect.width();
+                int thumbnailHeight = transform.rect.height();
+                if (task.thumbnail != null && thumbnailWidth > 0 && thumbnailHeight > 0 &&
+                        task.thumbnail.getWidth() > 0 && task.thumbnail.getHeight() > 0) {
+                    // Resize the thumbnail to the size of the view that we are animating from
+                    Bitmap b = Bitmap.createBitmap(thumbnailWidth, thumbnailHeight,
+                            Bitmap.Config.ARGB_8888);
+                    Canvas c = new Canvas(b);
+                    c.drawBitmap(task.thumbnail,
+                            new Rect(0, 0, task.thumbnail.getWidth(), task.thumbnail.getHeight()),
+                            new Rect(0, 0, thumbnailWidth, thumbnailHeight), null);
+                    c.setBitmap(null);
+                    opts = ActivityOptions.makeThumbnailScaleUpAnimation(sourceView,
+                            b, offsetX, offsetY);
+                }
+
+                // Launch the activity with the desired animation
+                Intent i = new Intent(task.key.intent);
+                i.setFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
+                        | Intent.FLAG_ACTIVITY_TASK_ON_HOME
+                        | Intent.FLAG_ACTIVITY_NEW_TASK);
+                try {
+                    if (opts != null) {
+                        getContext().startActivityAsUser(i, opts.toBundle(), UserHandle.CURRENT);
+                    } else {
+                        getContext().startActivityAsUser(i, UserHandle.CURRENT);
+                    }
+                } catch (ActivityNotFoundException anfe) {
+                    Console.logError(getContext(), "Could not start Activity");
+                }
+
+                Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsLaunchTask,
+                        Constants.DebugFlags.App.TimeRecentsLaunchKey, "startActivity");
+            }
+        };
+
+        Console.logTraceTime(Constants.DebugFlags.App.TimeRecentsLaunchTask,
+                Constants.DebugFlags.App.TimeRecentsLaunchKey, "onTaskLaunched");
+
+        // Launch the app right away if there is no task view, otherwise, animate the icon out first
+        if (tv == null || !Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingRecents) {
+            post(launchRunnable);
+        } else {
+            tv.animateOnLeavingRecents(launchRunnable);
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
new file mode 100644
index 0000000..21ef9ff
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.util.DisplayMetrics;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.animation.LinearInterpolator;
+import com.android.systemui.recents.Console;
+import com.android.systemui.recents.Constants;
+
+/**
+ * This class facilitates swipe to dismiss. It defines an interface to be implemented by the
+ * by the class hosting the views that need to swiped, and, using this interface, handles touch
+ * events and translates / fades / animates the view as it is dismissed.
+ */
+public class SwipeHelper {
+    static final String TAG = "SwipeHelper";
+    private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
+    private static final boolean CONSTRAIN_SWIPE = true;
+    private static final boolean FADE_OUT_DURING_SWIPE = true;
+    private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true;
+
+    public static final int X = 0;
+    public static final int Y = 1;
+
+    private static LinearInterpolator sLinearInterpolator = new LinearInterpolator();
+
+    private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
+    private int DEFAULT_ESCAPE_ANIMATION_DURATION = 75; // ms
+    private int MAX_ESCAPE_ANIMATION_DURATION = 150; // ms
+    private int MAX_DISMISS_VELOCITY = 2000; // dp/sec
+    private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
+
+    public static float ALPHA_FADE_START = 0.15f; // fraction of thumbnail width
+                                                 // where fade starts
+    static final float ALPHA_FADE_END = 0.65f; // fraction of thumbnail width
+                                              // beyond which alpha->0
+    private float mMinAlpha = 0f;
+
+    private float mPagingTouchSlop;
+    Callback mCallback;
+    private int mSwipeDirection;
+    private VelocityTracker mVelocityTracker;
+
+    private float mInitialTouchPos;
+    private boolean mDragging;
+
+    private View mCurrView;
+    private boolean mCanCurrViewBeDimissed;
+    private float mDensityScale;
+
+    public boolean mAllowSwipeTowardsStart = true;
+    public boolean mAllowSwipeTowardsEnd = true;
+    private boolean mRtl;
+
+    public SwipeHelper(int swipeDirection, Callback callback, float densityScale,
+            float pagingTouchSlop) {
+        mCallback = callback;
+        mSwipeDirection = swipeDirection;
+        mVelocityTracker = VelocityTracker.obtain();
+        mDensityScale = densityScale;
+        mPagingTouchSlop = pagingTouchSlop;
+    }
+
+    public void setDensityScale(float densityScale) {
+        mDensityScale = densityScale;
+    }
+
+    public void setPagingTouchSlop(float pagingTouchSlop) {
+        mPagingTouchSlop = pagingTouchSlop;
+    }
+
+    public void cancelOngoingDrag() {
+        if (mDragging) {
+            if (mCurrView != null) {
+                mCallback.onDragCancelled(mCurrView);
+                setTranslation(mCurrView, 0);
+                mCallback.onSnapBackCompleted(mCurrView);
+                mCurrView = null;
+            }
+            mDragging = false;
+        }
+    }
+
+    public void resetTranslation(View v) {
+        setTranslation(v, 0);
+    }
+
+    private float getPos(MotionEvent ev) {
+        return mSwipeDirection == X ? ev.getX() : ev.getY();
+    }
+
+    private float getTranslation(View v) {
+        return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY();
+    }
+
+    private float getVelocity(VelocityTracker vt) {
+        return mSwipeDirection == X ? vt.getXVelocity() :
+                vt.getYVelocity();
+    }
+
+    private ObjectAnimator createTranslationAnimation(View v, float newPos) {
+        ObjectAnimator anim = ObjectAnimator.ofFloat(v,
+                mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
+        return anim;
+    }
+
+    private float getPerpendicularVelocity(VelocityTracker vt) {
+        return mSwipeDirection == X ? vt.getYVelocity() :
+                vt.getXVelocity();
+    }
+
+    private void setTranslation(View v, float translate) {
+        if (mSwipeDirection == X) {
+            v.setTranslationX(translate);
+        } else {
+            v.setTranslationY(translate);
+        }
+    }
+
+    private float getSize(View v) {
+        final DisplayMetrics dm = v.getContext().getResources().getDisplayMetrics();
+        return mSwipeDirection == X ? dm.widthPixels : dm.heightPixels;
+    }
+
+    public void setMinAlpha(float minAlpha) {
+        mMinAlpha = minAlpha;
+    }
+
+    float getAlphaForOffset(View view) {
+        float viewSize = getSize(view);
+        final float fadeSize = ALPHA_FADE_END * viewSize;
+        float result = 1.0f;
+        float pos = getTranslation(view);
+        if (pos >= viewSize * ALPHA_FADE_START) {
+            result = 1.0f - (pos - viewSize * ALPHA_FADE_START) / fadeSize;
+        } else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) {
+            result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize;
+        }
+        result = Math.min(result, 1.0f);
+        result = Math.max(result, 0f);
+        return Math.max(mMinAlpha, result);
+    }
+
+    /**
+     * Determines whether the given view has RTL layout.
+     */
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    public static boolean isLayoutRtl(View view) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            return View.LAYOUT_DIRECTION_RTL == view.getLayoutDirection();
+        } else {
+            return false;
+        }
+    }
+
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        Console.log(Constants.DebugFlags.UI.TouchEvents,
+                "[SwipeHelper|interceptTouchEvent]",
+                Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
+        final int action = ev.getAction();
+
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                mDragging = false;
+                mCurrView = mCallback.getChildAtPosition(ev);
+                mVelocityTracker.clear();
+                if (mCurrView != null) {
+                    mRtl = isLayoutRtl(mCurrView);
+                    mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
+                    mVelocityTracker.addMovement(ev);
+                    mInitialTouchPos = getPos(ev);
+                } else {
+                    mCanCurrViewBeDimissed = false;
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                if (mCurrView != null) {
+                    mVelocityTracker.addMovement(ev);
+                    float pos = getPos(ev);
+                    float delta = pos - mInitialTouchPos;
+                    if (Math.abs(delta) > mPagingTouchSlop) {
+                        mCallback.onBeginDrag(mCurrView);
+                        mDragging = true;
+                        mInitialTouchPos = pos - getTranslation(mCurrView);
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mDragging = false;
+                mCurrView = null;
+                break;
+        }
+        return mDragging;
+    }
+
+    /**
+     * @param view The view to be dismissed
+     * @param velocity The desired pixels/second speed at which the view should move
+     */
+    private void dismissChild(final View view, float velocity) {
+        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
+        float newPos;
+        if (velocity < 0
+                || (velocity == 0 && getTranslation(view) < 0)
+                // if we use the Menu to dismiss an item in landscape, animate up
+                || (velocity == 0 && getTranslation(view) == 0 && mSwipeDirection == Y)) {
+            newPos = -getSize(view);
+        } else {
+            newPos = getSize(view);
+        }
+        int duration = MAX_ESCAPE_ANIMATION_DURATION;
+        if (velocity != 0) {
+            duration = Math.min(duration,
+                                (int) (Math.abs(newPos - getTranslation(view)) *
+                                        1000f / Math.abs(velocity)));
+        } else {
+            duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
+        }
+
+        ValueAnimator anim = createTranslationAnimation(view, newPos);
+        anim.setInterpolator(sLinearInterpolator);
+        anim.setDuration(duration);
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mCallback.onChildDismissed(view);
+                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
+                    view.setAlpha(1.f);
+                }
+            }
+        });
+        anim.addUpdateListener(new AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
+                    view.setAlpha(getAlphaForOffset(view));
+                }
+            }
+        });
+        anim.start();
+    }
+
+    private void snapChild(final View view, float velocity) {
+        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
+        ValueAnimator anim = createTranslationAnimation(view, 0);
+        int duration = SNAP_ANIM_LEN;
+        anim.setDuration(duration);
+        anim.addUpdateListener(new AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
+                    view.setAlpha(getAlphaForOffset(view));
+                }
+            }
+        });
+        anim.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
+                    view.setAlpha(1.0f);
+                }
+                mCallback.onSnapBackCompleted(view);
+            }
+        });
+        anim.start();
+    }
+
+    public boolean onTouchEvent(MotionEvent ev) {
+        Console.log(Constants.DebugFlags.UI.TouchEvents,
+                "[SwipeHelper|touchEvent]",
+                Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
+
+        if (!mDragging) {
+            if (!onInterceptTouchEvent(ev)) {
+                return mCanCurrViewBeDimissed;
+            }
+        }
+
+        mVelocityTracker.addMovement(ev);
+        final int action = ev.getAction();
+        switch (action) {
+            case MotionEvent.ACTION_OUTSIDE:
+            case MotionEvent.ACTION_MOVE:
+                if (mCurrView != null) {
+                    float delta = getPos(ev) - mInitialTouchPos;
+                    setSwipeAmount(delta);
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                if (mCurrView != null) {
+                    endSwipe(mVelocityTracker);
+                }
+                break;
+        }
+        return true;
+    }
+
+    private void setSwipeAmount(float amount) {
+        // don't let items that can't be dismissed be dragged more than
+        // maxScrollDistance
+        if (CONSTRAIN_SWIPE
+                && (!isValidSwipeDirection(amount) || !mCallback.canChildBeDismissed(mCurrView))) {
+            float size = getSize(mCurrView);
+            float maxScrollDistance = 0.15f * size;
+            if (Math.abs(amount) >= size) {
+                amount = amount > 0 ? maxScrollDistance : -maxScrollDistance;
+            } else {
+                amount = maxScrollDistance * (float) Math.sin((amount/size)*(Math.PI/2));
+            }
+        }
+        setTranslation(mCurrView, amount);
+        if (FADE_OUT_DURING_SWIPE && mCanCurrViewBeDimissed) {
+            float alpha = getAlphaForOffset(mCurrView);
+            mCurrView.setAlpha(alpha);
+        }
+    }
+
+    private boolean isValidSwipeDirection(float amount) {
+        if (mSwipeDirection == X) {
+            if (mRtl) {
+                return (amount <= 0) ? mAllowSwipeTowardsEnd : mAllowSwipeTowardsStart;
+            } else {
+                return (amount <= 0) ? mAllowSwipeTowardsStart : mAllowSwipeTowardsEnd;
+            }
+        }
+
+        // Vertical swipes are always valid.
+        return true;
+    }
+
+    private void endSwipe(VelocityTracker velocityTracker) {
+        float maxVelocity = MAX_DISMISS_VELOCITY * mDensityScale;
+        velocityTracker.computeCurrentVelocity(1000 /* px/sec */, maxVelocity);
+        float velocity = getVelocity(velocityTracker);
+        float perpendicularVelocity = getPerpendicularVelocity(velocityTracker);
+        float escapeVelocity = SWIPE_ESCAPE_VELOCITY * mDensityScale;
+        float translation = getTranslation(mCurrView);
+        // Decide whether to dismiss the current view
+        boolean childSwipedFarEnough = DISMISS_IF_SWIPED_FAR_ENOUGH &&
+                Math.abs(translation) > 0.6 * getSize(mCurrView);
+        boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) &&
+                (Math.abs(velocity) > Math.abs(perpendicularVelocity)) &&
+                (velocity > 0) == (translation > 0);
+
+        boolean dismissChild = mCallback.canChildBeDismissed(mCurrView)
+                && isValidSwipeDirection(translation)
+                && (childSwipedFastEnough || childSwipedFarEnough);
+
+        if (dismissChild) {
+            // flingadingy
+            dismissChild(mCurrView, childSwipedFastEnough ? velocity : 0f);
+        } else {
+            // snappity
+            mCallback.onDragCancelled(mCurrView);
+            snapChild(mCurrView, velocity);
+        }
+    }
+
+    public interface Callback {
+        View getChildAtPosition(MotionEvent ev);
+
+        boolean canChildBeDismissed(View v);
+
+        void onBeginDrag(View v);
+
+        void onChildDismissed(View v);
+
+        void onSnapBackCompleted(View v);
+
+        void onDragCancelled(View v);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
new file mode 100644
index 0000000..2b27a06
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -0,0 +1,1063 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewParent;
+import android.widget.FrameLayout;
+import android.widget.OverScroller;
+import com.android.systemui.recents.Console;
+import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.RecentsTaskLoader;
+import com.android.systemui.recents.Utilities;
+import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.model.TaskStack;
+
+import java.util.ArrayList;
+
+
+/* The visual representation of a task stack view */
+public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks,
+        TaskView.TaskViewCallbacks, ViewPool.ViewPoolConsumer<TaskView, Task>,
+        View.OnClickListener {
+
+    /** The TaskView callbacks */
+    interface TaskStackViewCallbacks {
+        public void onTaskLaunched(TaskStackView stackView, TaskView tv, TaskStack stack, Task t);
+    }
+
+    TaskStack mStack;
+    TaskStackViewTouchHandler mTouchHandler;
+    TaskStackViewCallbacks mCb;
+    ViewPool<TaskView, Task> mViewPool;
+
+    // The various rects that define the stack view
+    Rect mRect = new Rect();
+    Rect mStackRect = new Rect();
+    Rect mStackRectSansPeek = new Rect();
+    Rect mTaskRect = new Rect();
+
+    // The virtual stack scroll that we use for the card layout
+    int mStackScroll;
+    int mMinScroll;
+    int mMaxScroll;
+    OverScroller mScroller;
+    ObjectAnimator mScrollAnimator;
+
+    // Optimizations
+    int mHwLayersRefCount;
+    int mStackViewsAnimationDuration;
+    boolean mStackViewsDirty = true;
+    boolean mAwaitingFirstLayout = true;
+
+    public TaskStackView(Context context, TaskStack stack) {
+        super(context);
+        mStack = stack;
+        mStack.setCallbacks(this);
+        mScroller = new OverScroller(context);
+        mTouchHandler = new TaskStackViewTouchHandler(context, this);
+        mViewPool = new ViewPool<TaskView, Task>(context, this);
+    }
+
+    /** Sets the callbacks */
+    void setCallbacks(TaskStackViewCallbacks cb) {
+        mCb = cb;
+    }
+
+    /** Requests that the views be synchronized with the model */
+    void requestSynchronizeStackViewsWithModel() {
+        requestSynchronizeStackViewsWithModel(0);
+    }
+    void requestSynchronizeStackViewsWithModel(int duration) {
+        Console.log(Constants.DebugFlags.TaskStack.SynchronizeViewsWithModel,
+                "[TaskStackView|requestSynchronize]", "", Console.AnsiYellow);
+        if (!mStackViewsDirty) {
+            invalidate();
+        }
+        if (mAwaitingFirstLayout) {
+            // Skip the animation if we are awaiting first layout
+            mStackViewsAnimationDuration = 0;
+        } else {
+            mStackViewsAnimationDuration = Math.max(mStackViewsAnimationDuration, duration);
+        }
+        mStackViewsDirty = true;
+    }
+
+    // XXX: Optimization: Use a mapping of Task -> View
+    private TaskView getChildViewForTask(Task t) {
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            TaskView tv = (TaskView) getChildAt(i);
+            if (tv.getTask() == t) {
+                return tv;
+            }
+        }
+        return null;
+    }
+
+    /** Update/get the transform */
+    public TaskViewTransform getStackTransform(int indexInStack) {
+        TaskViewTransform transform = new TaskViewTransform();
+
+        // Map the items to an continuous position relative to the current scroll
+        int numPeekCards = Constants.Values.TaskStackView.StackPeekNumCards;
+        float overlapHeight = Constants.Values.TaskStackView.StackOverlapPct * mTaskRect.height();
+        float peekHeight = Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height();
+        float t = ((indexInStack * overlapHeight) - getStackScroll()) / overlapHeight;
+        float boundedT = Math.max(t, -(numPeekCards + 1));
+
+        // Set the scale relative to its position
+        float minScale = Constants.Values.TaskStackView.StackPeekMinScale;
+        float scaleRange = 1f - minScale;
+        float scaleInc = scaleRange / numPeekCards;
+        float scale = Math.max(minScale, Math.min(1f, 1f + (boundedT * scaleInc)));
+        float scaleYOffset = ((1f - scale) * mTaskRect.height()) / 2;
+        transform.scale = scale;
+
+        // Set the translation
+        if (boundedT < 0f) {
+            transform.translationY = (int) ((Math.max(-numPeekCards, boundedT) /
+                    numPeekCards) * peekHeight - scaleYOffset);
+        } else {
+            transform.translationY = (int) (boundedT * overlapHeight - scaleYOffset);
+        }
+
+        // Update the rect and visibility
+        transform.rect.set(mTaskRect);
+        if (t < -(numPeekCards + 1)) {
+            transform.visible = false;
+        } else {
+            transform.rect.offset(0, transform.translationY);
+            Utilities.scaleRectAboutCenter(transform.rect, scale);
+            transform.visible = Rect.intersects(mRect, transform.rect);
+        }
+        transform.t = t;
+        return transform;
+    }
+
+    /** Synchronizes the views with the model */
+    void synchronizeStackViewsWithModel() {
+        Console.log(Constants.DebugFlags.TaskStack.SynchronizeViewsWithModel,
+                "[TaskStackView|synchronizeViewsWithModel]",
+                "mStackViewsDirty: " + mStackViewsDirty, Console.AnsiYellow);
+        if (mStackViewsDirty) {
+
+            // XXX: Optimization: Use binary search to find the visible range
+            // XXX: Optimize to not call getStackTransform() so many times
+            // XXX: Consider using TaskViewTransform pool to prevent allocations
+            // XXX: Iterate children views, update transforms and remove all that are not visible
+            //      For all remaining tasks, update transforms and if visible add the view
+
+            // Update the visible state of all the tasks
+            ArrayList<Task> tasks = mStack.getTasks();
+            int taskCount = tasks.size();
+            for (int i = 0; i < taskCount; i++) {
+                Task task = tasks.get(i);
+                TaskViewTransform transform = getStackTransform(i);
+                TaskView tv = getChildViewForTask(task);
+
+                if (transform.visible) {
+                    if (tv == null) {
+                        tv = mViewPool.pickUpViewFromPool(task, task);
+                        // When we are picking up a new view from the view pool, prepare it for any
+                        // following animation by putting it in a reasonable place
+                        if (mStackViewsAnimationDuration > 0 && i != 0) {
+                            // XXX: We have to animate when filtering, etc. Maybe we should have a
+                            //      runnable that ensures that tasks are animated in a special way
+                            //      when they are entering the scene?
+                            int fromIndex = (transform.t < 0) ? (i - 1) : (i + 1);
+                            tv.updateViewPropertiesFromTask(null, getStackTransform(fromIndex), 0);
+                        }
+                    }
+                } else {
+                    if (tv != null) {
+                        mViewPool.returnViewToPool(tv);
+                    }
+                }
+            }
+
+            // Update all the current view children
+            // NOTE: We have to iterate in reverse where because we are removing views directly
+            int childCount = getChildCount();
+            for (int i = childCount - 1; i >= 0; i--) {
+                TaskView tv = (TaskView) getChildAt(i);
+                Task task = tv.getTask();
+                TaskViewTransform transform = getStackTransform(mStack.indexOfTask(task));
+                if (!transform.visible) {
+                    mViewPool.returnViewToPool(tv);
+                } else {
+                    tv.updateViewPropertiesFromTask(null, transform, mStackViewsAnimationDuration);
+                }
+            }
+
+            Console.log(Constants.DebugFlags.TaskStack.SynchronizeViewsWithModel,
+                    "  [TaskStackView|viewChildren]", "" + getChildCount());
+
+            mStackViewsAnimationDuration = 0;
+            mStackViewsDirty = false;
+        }
+    }
+
+    /** Sets the current stack scroll */
+    public void setStackScroll(int value) {
+        mStackScroll = value;
+        requestSynchronizeStackViewsWithModel();
+    }
+
+    /** Gets the current stack scroll */
+    public int getStackScroll() {
+        return mStackScroll;
+    }
+
+    /** Animates the stack scroll into bounds */
+    ObjectAnimator animateBoundScroll(int duration) {
+        int curScroll = getStackScroll();
+        int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll, curScroll));
+        if (newScroll != curScroll) {
+            // Enable hw layers on the stack
+            addHwLayersRefCount("animateBoundScroll");
+
+            // Abort any current animations
+            abortScroller();
+            if (mScrollAnimator != null) {
+                mScrollAnimator.cancel();
+                mScrollAnimator.removeAllListeners();
+            }
+
+            // Start a new scroll animation
+            mScrollAnimator = ObjectAnimator.ofInt(this, "stackScroll", curScroll, newScroll);
+            mScrollAnimator.setDuration(duration);
+            mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    setStackScroll((Integer) animation.getAnimatedValue());
+                }
+            });
+            mScrollAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    // Disable hw layers on the stack
+                    decHwLayersRefCount("animateBoundScroll");
+                }
+            });
+            mScrollAnimator.start();
+        }
+        return mScrollAnimator;
+    }
+
+    /** Aborts any current stack scrolls */
+    void abortBoundScrollAnimation() {
+        if (mScrollAnimator != null) {
+            mScrollAnimator.cancel();
+        }
+    }
+
+    void abortScroller() {
+        if (!mScroller.isFinished()) {
+            // Abort the scroller
+            mScroller.abortAnimation();
+            // And disable hw layers on the stack
+            decHwLayersRefCount("flingScroll");
+        }
+    }
+
+    /** Bounds the current scroll if necessary */
+    public boolean boundScroll() {
+        int curScroll = getStackScroll();
+        int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll, curScroll));
+        if (newScroll != curScroll) {
+            setStackScroll(newScroll);
+            return true;
+        }
+        return false;
+    }
+
+    /** Returns whether the current scroll is out of bounds */
+    boolean isScrollOutOfBounds() {
+        return (getStackScroll() < 0) || (getStackScroll() > mMaxScroll);
+    }
+
+    /** Updates the min and max virtual scroll bounds */
+    void updateMinMaxScroll(boolean boundScrollToNewMinMax) {
+        // Compute the min and max scroll values
+        int numTasks = Math.max(1, mStack.getTaskCount());
+        int taskHeight = mTaskRect.height();
+        int stackHeight = mStackRectSansPeek.height();
+        int maxScrollHeight = taskHeight + (int) ((numTasks - 1) *
+                Constants.Values.TaskStackView.StackOverlapPct * taskHeight);
+        mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight;
+        mMaxScroll = maxScrollHeight - stackHeight;
+
+        // Debug logging
+        if (Constants.DebugFlags.UI.MeasureAndLayout) {
+            Console.log("  [TaskStack|minScroll] " + mMinScroll);
+            Console.log("  [TaskStack|maxScroll] " + mMaxScroll);
+        }
+
+        if (boundScrollToNewMinMax) {
+            boundScroll();
+        }
+    }
+
+    /** Enables the hw layers and increments the hw layer requirement ref count */
+    void addHwLayersRefCount(String reason) {
+        Console.log(Constants.DebugFlags.UI.HwLayers,
+                "[TaskStackView|addHwLayersRefCount] refCount: " +
+                        mHwLayersRefCount + "->" + (mHwLayersRefCount + 1) + " " + reason);
+        if (mHwLayersRefCount == 0) {
+            // Enable hw layers on each of the children
+            int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                TaskView tv = (TaskView) getChildAt(i);
+                tv.enableHwLayers();
+            }
+        }
+        mHwLayersRefCount++;
+    }
+
+    /** Decrements the hw layer requirement ref count and disables the hw layers when we don't
+        need them anymore. */
+    void decHwLayersRefCount(String reason) {
+        Console.log(Constants.DebugFlags.UI.HwLayers,
+                "[TaskStackView|decHwLayersRefCount] refCount: " +
+                        mHwLayersRefCount + "->" + (mHwLayersRefCount - 1) + " " + reason);
+        mHwLayersRefCount--;
+        if (mHwLayersRefCount == 0) {
+            // Disable hw layers on each of the children
+            int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                TaskView tv = (TaskView) getChildAt(i);
+                tv.disableHwLayers();
+            }
+        } else if (mHwLayersRefCount < 0) {
+            new Throwable("Invalid hw layers ref count").printStackTrace();
+            Console.logError(getContext(), "Invalid HW layers ref count");
+        }
+    }
+
+    @Override
+    public void computeScroll() {
+        if (mScroller.computeScrollOffset()) {
+            setStackScroll(mScroller.getCurrY());
+            invalidate();
+
+            // If we just finished scrolling, then disable the hw layers
+            if (mScroller.isFinished()) {
+                decHwLayersRefCount("finishedFlingScroll");
+            }
+        }
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        return mTouchHandler.onInterceptTouchEvent(ev);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        return mTouchHandler.onTouchEvent(ev);
+    }
+
+    @Override
+    public void dispatchDraw(Canvas canvas) {
+        Console.log(Constants.DebugFlags.UI.Draw, "[TaskStackView|dispatchDraw]", "",
+                Console.AnsiPurple);
+        synchronizeStackViewsWithModel();
+        super.dispatchDraw(canvas);
+    }
+
+    @Override
+    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+        if (Constants.DebugFlags.App.EnableTaskStackClipping) {
+            TaskView tv = (TaskView) child;
+            TaskView nextTv = null;
+            int curIndex = indexOfChild(tv);
+            if (curIndex < (getChildCount() - 1)) {
+                // Clip against the next view (if we aren't animating its alpha)
+                nextTv = (TaskView) getChildAt(curIndex + 1);
+                if (nextTv.getAlpha() == 1f) {
+                    Rect curRect = tv.getClippingRect(Utilities.tmpRect, false);
+                    Rect nextRect = nextTv.getClippingRect(Utilities.tmpRect2, true);
+                    RecentsConfiguration config = RecentsConfiguration.getInstance();
+                    // The hit rects are relative to the task view, which needs to be offset by the
+                    // system bar height
+                    curRect.offset(0, config.systemInsets.top);
+                    nextRect.offset(0, config.systemInsets.top);
+                    // Compute the clip region
+                    Region clipRegion = new Region();
+                    clipRegion.op(curRect, Region.Op.UNION);
+                    clipRegion.op(nextRect, Region.Op.DIFFERENCE);
+                    // Clip the canvas
+                    int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
+                    canvas.clipRegion(clipRegion);
+                    boolean invalidate = super.drawChild(canvas, child, drawingTime);
+                    canvas.restoreToCount(saveCount);
+                    return invalidate;
+                }
+            }
+        }
+        return super.drawChild(canvas, child, drawingTime);
+    }
+
+    /** Computes the stack and task rects */
+    public void computeRects(int width, int height, int insetBottom) {
+        // Note: We let the stack view be the full height because we want the cards to go under the
+        //       navigation bar if possible.  However, the stack rects which we use to calculate
+        //       max scroll, etc. need to take the nav bar into account
+
+        // Compute the stack rects
+        mRect.set(0, 0, width, height);
+        mStackRect.set(mRect);
+        mStackRect.bottom -= insetBottom;
+
+        int smallestDimension = Math.min(width, height);
+        int padding = (int) (Constants.Values.TaskStackView.StackPaddingPct * smallestDimension / 2f);
+        mStackRect.inset(padding, padding);
+        mStackRectSansPeek.set(mStackRect);
+        mStackRectSansPeek.top += Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height();
+
+        // Compute the task rect
+        int minHeight = (int) (mStackRect.height() -
+                (Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height()));
+        int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height()));
+        int centerX = mStackRect.centerX();
+        mTaskRect.set(centerX - size / 2, mStackRectSansPeek.top,
+                centerX + size / 2, mStackRectSansPeek.top + size);
+
+        // Update the scroll bounds
+        updateMinMaxScroll(false);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        int height = MeasureSpec.getSize(heightMeasureSpec);
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[TaskStackView|measure]",
+                "width: " + width + " height: " + height +
+                " awaitingFirstLayout: " + mAwaitingFirstLayout, Console.AnsiGreen);
+
+        // Compute our stack/task rects
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        computeRects(width, height, config.systemInsets.bottom);
+
+        // Debug logging
+        if (Constants.DebugFlags.UI.MeasureAndLayout) {
+            Console.log("  [TaskStack|fullRect] " + mRect);
+            Console.log("  [TaskStack|stackRect] " + mStackRect);
+            Console.log("  [TaskStack|stackRectSansPeek] " + mStackRectSansPeek);
+            Console.log("  [TaskStack|taskRect] " + mTaskRect);
+        }
+
+        // If this is the first layout, then scroll to the front of the stack and synchronize the
+        // stack views immediately
+        if (mAwaitingFirstLayout) {
+            setStackScroll(mMaxScroll);
+            requestSynchronizeStackViewsWithModel();
+            synchronizeStackViewsWithModel();
+
+            // Animate the icon of the first task view
+            if (Constants.Values.TaskView.AnimateFrontTaskIconOnEnterRecents) {
+                TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
+                if (tv != null) {
+                    tv.animateOnEnterRecents();
+                }
+            }
+        }
+
+        // Measure each of the children
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            TaskView t = (TaskView) getChildAt(i);
+            t.measure(MeasureSpec.makeMeasureSpec(mTaskRect.width(), MeasureSpec.EXACTLY),
+                    MeasureSpec.makeMeasureSpec(mTaskRect.height(), MeasureSpec.EXACTLY));
+        }
+
+        setMeasuredDimension(width, height);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[TaskStackView|layout]",
+                "" + new Rect(left, top, right, bottom), Console.AnsiGreen);
+
+        // Debug logging
+        if (Constants.DebugFlags.UI.MeasureAndLayout) {
+            Console.log("  [TaskStack|fullRect] " + mRect);
+            Console.log("  [TaskStack|stackRect] " + mStackRect);
+            Console.log("  [TaskStack|stackRectSansPeek] " + mStackRectSansPeek);
+            Console.log("  [TaskStack|taskRect] " + mTaskRect);
+        }
+
+        // Layout each of the children
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            TaskView t = (TaskView) getChildAt(i);
+            t.layout(mTaskRect.left, mStackRectSansPeek.top,
+                    mTaskRect.right, mStackRectSansPeek.top + mTaskRect.height());
+        }
+
+        if (!mAwaitingFirstLayout) {
+            requestSynchronizeStackViewsWithModel();
+        } else {
+            mAwaitingFirstLayout = false;
+        }
+    }
+
+    @Override
+    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+        super.onScrollChanged(l, t, oldl, oldt);
+        requestSynchronizeStackViewsWithModel();
+    }
+
+    public boolean isTransformedTouchPointInView(float x, float y, View child) {
+        return isTransformedTouchPointInView(x, y, child, null);
+    }
+
+    /**** TaskStackCallbacks Implementation ****/
+
+    @Override
+    public void onStackTaskAdded(TaskStack stack, Task t) {
+        requestSynchronizeStackViewsWithModel();
+    }
+
+    @Override
+    public void onStackTaskRemoved(TaskStack stack, Task t) {
+        // Remove the view associated with this task, we can't rely on updateTransforms
+        // to work here because the task is no longer in the list
+        int childCount = getChildCount();
+        for (int i = childCount - 1; i >= 0; i--) {
+            TaskView tv = (TaskView) getChildAt(i);
+            if (tv.getTask() == t) {
+                mViewPool.returnViewToPool(tv);
+                break;
+            }
+        }
+
+        updateMinMaxScroll(true);
+        requestSynchronizeStackViewsWithModel(Constants.Values.TaskStackView.Animation.TaskRemovedReshuffleDuration);
+    }
+
+    @Override
+    public void onStackFiltered(TaskStack stack) {
+        requestSynchronizeStackViewsWithModel();
+    }
+
+    @Override
+    public void onStackUnfiltered(TaskStack stack) {
+        requestSynchronizeStackViewsWithModel();
+    }
+
+    /**** ViewPoolConsumer Implementation ****/
+
+    @Override
+    public TaskView createView(Context context) {
+        Console.log(Constants.DebugFlags.ViewPool.PoolCallbacks, "[TaskStackView|createPoolView]");
+        return new TaskView(context);
+    }
+
+    @Override
+    public void prepareViewToEnterPool(TaskView tv) {
+        Task task = tv.getTask();
+        tv.resetViewProperties();
+        Console.log(Constants.DebugFlags.ViewPool.PoolCallbacks, "[TaskStackView|returnToPool]",
+                tv.getTask() + " tv: " + tv);
+
+        // Report that this tasks's data is no longer being used
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        loader.unloadTaskData(task);
+
+        // Detach the view from the hierarchy
+        detachViewFromParent(tv);
+
+        // Disable hw layers on this view
+        tv.disableHwLayers();
+    }
+
+    @Override
+    public void prepareViewToLeavePool(TaskView tv, Task prepareData, boolean isNewView) {
+        Console.log(Constants.DebugFlags.ViewPool.PoolCallbacks, "[TaskStackView|leavePool]",
+                "isNewView: " + isNewView);
+
+        // Setup and attach the view to the window
+        Task task = prepareData;
+        // We try and rebind the task (this MUST be done before the task filled)
+        tv.onTaskBound(task);
+        // Request that this tasks's data be filled
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        loader.loadTaskData(task);
+
+        // Find the index where this task should be placed in the children
+        int insertIndex = -1;
+        int childCount = getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            Task tvTask = ((TaskView) getChildAt(i)).getTask();
+            if (mStack.containsTask(task) && (mStack.indexOfTask(task) < mStack.indexOfTask(tvTask))) {
+                insertIndex = i;
+                break;
+            }
+        }
+
+        // Add/attach the view to the hierarchy
+        Console.log(Constants.DebugFlags.ViewPool.PoolCallbacks, "  [TaskStackView|insertIndex]",
+                "" + insertIndex);
+        if (isNewView) {
+            addView(tv, insertIndex);
+
+            // Set the callbacks and listeners for this new view
+            tv.setOnClickListener(this);
+            tv.setCallbacks(this);
+        } else {
+            attachViewToParent(tv, insertIndex, tv.getLayoutParams());
+        }
+
+        // Enable hw layers on this view if hw layers are enabled on the stack
+        if (mHwLayersRefCount > 0) {
+            tv.enableHwLayers();
+        }
+    }
+
+    @Override
+    public boolean hasPreferredData(TaskView tv, Task preferredData) {
+        return (tv.getTask() == preferredData);
+    }
+
+    /**** TaskViewCallbacks Implementation ****/
+
+    @Override
+    public void onTaskIconClicked(TaskView tv) {
+        Console.log(Constants.DebugFlags.UI.ClickEvents, "[TaskStack|Clicked|Icon]",
+                tv.getTask() + " is currently filtered: " + mStack.hasFilteredTasks(),
+                Console.AnsiCyan);
+        if (Constants.DebugFlags.App.EnableTaskFiltering) {
+            if (mStack.hasFilteredTasks()) {
+                mStack.unfilterTasks();
+            } else {
+                mStack.filterTasks(tv.getTask());
+            }
+        } else {
+            Console.logError(getContext(), "Task Filtering TBD");
+        }
+    }
+
+    /**** View.OnClickListener Implementation ****/
+
+    @Override
+    public void onClick(View v) {
+        TaskView tv = (TaskView) v;
+        Task task = tv.getTask();
+        Console.log(Constants.DebugFlags.UI.ClickEvents, "[TaskStack|Clicked|Thumbnail]",
+                task + " cb: " + mCb);
+
+        if (mCb != null) {
+            mCb.onTaskLaunched(this, tv, mStack, task);
+        }
+    }
+}
+
+/* Handles touch events */
+class TaskStackViewTouchHandler implements SwipeHelper.Callback {
+    static int INACTIVE_POINTER_ID = -1;
+
+    TaskStackView mSv;
+    VelocityTracker mVelocityTracker;
+
+    boolean mIsScrolling;
+
+    int mInitialMotionX, mInitialMotionY;
+    int mLastMotionX, mLastMotionY;
+    int mActivePointerId = INACTIVE_POINTER_ID;
+    TaskView mActiveTaskView = null;
+
+    int mTotalScrollMotion;
+    int mMinimumVelocity;
+    int mMaximumVelocity;
+    // The scroll touch slop is used to calculate when we start scrolling
+    int mScrollTouchSlop;
+    // The page touch slop is used to calculate when we start swiping
+    float mPagingTouchSlop;
+
+    SwipeHelper mSwipeHelper;
+    boolean mInterceptedBySwipeHelper;
+
+    public TaskStackViewTouchHandler(Context context, TaskStackView sv) {
+        ViewConfiguration configuration = ViewConfiguration.get(context);
+        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
+        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+        mScrollTouchSlop = configuration.getScaledTouchSlop();
+        mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
+        mSv = sv;
+
+
+        float densityScale = context.getResources().getDisplayMetrics().density;
+        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, mPagingTouchSlop);
+        mSwipeHelper.setMinAlpha(1f);
+    }
+
+    /** Velocity tracker helpers */
+    void initOrResetVelocityTracker() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        } else {
+            mVelocityTracker.clear();
+        }
+    }
+    void initVelocityTrackerIfNotExists() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+    }
+    void recycleVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    /** Returns the view at the specified coordinates */
+    TaskView findViewAtPoint(int x, int y) {
+        int childCount = mSv.getChildCount();
+        for (int i = childCount - 1; i >= 0; i--) {
+            TaskView tv = (TaskView) mSv.getChildAt(i);
+            if (tv.getVisibility() == View.VISIBLE) {
+                if (mSv.isTransformedTouchPointInView(x, y, tv)) {
+                    return tv;
+                }
+            }
+        }
+        return null;
+    }
+
+    /** Touch preprocessing for handling below */
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        Console.log(Constants.DebugFlags.UI.TouchEvents,
+                "[TaskStackViewTouchHandler|interceptTouchEvent]",
+                Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
+
+        // Return early if we have no children
+        boolean hasChildren = (mSv.getChildCount() > 0);
+        if (!hasChildren) {
+            return false;
+        }
+
+        // Pass through to swipe helper if we are swiping
+        mInterceptedBySwipeHelper = mSwipeHelper.onInterceptTouchEvent(ev);
+        if (mInterceptedBySwipeHelper) {
+            return true;
+        }
+
+        boolean wasScrolling = !mSv.mScroller.isFinished() ||
+                (mSv.mScrollAnimator != null && mSv.mScrollAnimator.isRunning());
+        int action = ev.getAction();
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_DOWN: {
+                // Save the touch down info
+                mInitialMotionX = mLastMotionX = (int) ev.getX();
+                mInitialMotionY = mLastMotionY = (int) ev.getY();
+                mActivePointerId = ev.getPointerId(0);
+                mActiveTaskView = findViewAtPoint(mLastMotionX, mLastMotionY);
+                // Stop the current scroll if it is still flinging
+                mSv.abortScroller();
+                mSv.abortBoundScrollAnimation();
+                // Initialize the velocity tracker
+                initOrResetVelocityTracker();
+                mVelocityTracker.addMovement(ev);
+                // Check if the scroller is finished yet
+                mIsScrolling = !mSv.mScroller.isFinished();
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                if (mActivePointerId == INACTIVE_POINTER_ID) break;
+
+                int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                int y = (int) ev.getY(activePointerIndex);
+                int x = (int) ev.getX(activePointerIndex);
+                if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
+                    // Save the touch move info
+                    mIsScrolling = true;
+                    // Initialize the velocity tracker if necessary
+                    initVelocityTrackerIfNotExists();
+                    mVelocityTracker.addMovement(ev);
+                    // Disallow parents from intercepting touch events
+                    final ViewParent parent = mSv.getParent();
+                    if (parent != null) {
+                        parent.requestDisallowInterceptTouchEvent(true);
+                    }
+                    // Enable HW layers
+                    mSv.addHwLayersRefCount("stackScroll");
+                }
+
+                mLastMotionX = x;
+                mLastMotionY = y;
+                break;
+            }
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP: {
+                // Animate the scroll back if we've cancelled
+                mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
+                // Disable HW layers
+                if (mIsScrolling) {
+                    mSv.decHwLayersRefCount("stackScroll");
+                }
+                // Reset the drag state and the velocity tracker
+                mIsScrolling = false;
+                mActivePointerId = INACTIVE_POINTER_ID;
+                mActiveTaskView = null;
+                mTotalScrollMotion = 0;
+                recycleVelocityTracker();
+                break;
+            }
+        }
+
+        return wasScrolling || mIsScrolling;
+    }
+
+    /** Handles touch events once we have intercepted them */
+    public boolean onTouchEvent(MotionEvent ev) {
+        Console.log(Constants.DebugFlags.TaskStack.SynchronizeViewsWithModel,
+                "[TaskStackViewTouchHandler|touchEvent]",
+                Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
+
+        // Short circuit if we have no children
+        boolean hasChildren = (mSv.getChildCount() > 0);
+        if (!hasChildren) {
+            return false;
+        }
+
+        // Pass through to swipe helper if we are swiping
+        if (mInterceptedBySwipeHelper && mSwipeHelper.onTouchEvent(ev)) {
+            return true;
+        }
+
+        // Update the velocity tracker
+        initVelocityTrackerIfNotExists();
+        mVelocityTracker.addMovement(ev);
+
+        int action = ev.getAction();
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_DOWN: {
+                // Save the touch down info
+                mInitialMotionX = mLastMotionX = (int) ev.getX();
+                mInitialMotionY = mLastMotionY = (int) ev.getY();
+                mActivePointerId = ev.getPointerId(0);
+                mActiveTaskView = findViewAtPoint(mLastMotionX, mLastMotionY);
+                // Stop the current scroll if it is still flinging
+                mSv.abortScroller();
+                mSv.abortBoundScrollAnimation();
+                // Initialize the velocity tracker
+                initOrResetVelocityTracker();
+                mVelocityTracker.addMovement(ev);
+                // Disallow parents from intercepting touch events
+                final ViewParent parent = mSv.getParent();
+                if (parent != null) {
+                    parent.requestDisallowInterceptTouchEvent(true);
+                }
+                break;
+            }
+            case MotionEvent.ACTION_POINTER_DOWN: {
+                final int index = ev.getActionIndex();
+                mActivePointerId = ev.getPointerId(index);
+                mLastMotionX = (int) ev.getX(index);
+                mLastMotionY = (int) ev.getY(index);
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                if (mActivePointerId == INACTIVE_POINTER_ID) break;
+
+                int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                int x = (int) ev.getX(activePointerIndex);
+                int y = (int) ev.getY(activePointerIndex);
+                int deltaY = mLastMotionY - y;
+                if (!mIsScrolling) {
+                    if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
+                        mIsScrolling = true;
+                        // Initialize the velocity tracker
+                        initOrResetVelocityTracker();
+                        mVelocityTracker.addMovement(ev);
+                        // Disallow parents from intercepting touch events
+                        final ViewParent parent = mSv.getParent();
+                        if (parent != null) {
+                            parent.requestDisallowInterceptTouchEvent(true);
+                        }
+                        // Enable HW layers
+                        mSv.addHwLayersRefCount("stackScroll");
+                    }
+                }
+                if (mIsScrolling) {
+                    mSv.setStackScroll(mSv.getStackScroll() + deltaY);
+                    if (mSv.isScrollOutOfBounds()) {
+                        mVelocityTracker.clear();
+                    }
+                }
+                mLastMotionX = x;
+                mLastMotionY = y;
+                mTotalScrollMotion += Math.abs(deltaY);
+                break;
+            }
+            case MotionEvent.ACTION_UP: {
+                final VelocityTracker velocityTracker = mVelocityTracker;
+                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
+
+                if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
+                    // Enable HW layers on the stack
+                    mSv.addHwLayersRefCount("flingScroll");
+                    int overscrollRange = (int) (Math.min(1f,
+                            Math.abs((float) velocity / mMaximumVelocity)) *
+                            Constants.Values.TaskStackView.TaskStackOverscrollRange);
+
+                    Console.log(Constants.DebugFlags.UI.TouchEvents,
+                            "[TaskStackViewTouchHandler|fling]",
+                            "scroll: " + mSv.getStackScroll() + " velocity: " + velocity +
+                                    " maxVelocity: " + mMaximumVelocity +
+                                    " overscrollRange: " + overscrollRange,
+                            Console.AnsiGreen);
+
+                    // Fling scroll
+                    mSv.mScroller.fling(0, mSv.getStackScroll(),
+                            0, -velocity,
+                            0, 0,
+                            mSv.mMinScroll, mSv.mMaxScroll,
+                            0, overscrollRange);
+                    // Invalidate to kick off computeScroll
+                    mSv.invalidate();
+                } else if (mSv.isScrollOutOfBounds()) {
+                    // Animate the scroll back into bounds
+                    // XXX: Make this animation a function of the velocity OR distance
+                    mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
+                }
+
+                if (mIsScrolling) {
+                    // Disable HW layers
+                    mSv.decHwLayersRefCount("stackScroll");
+                }
+                mActivePointerId = INACTIVE_POINTER_ID;
+                mIsScrolling = false;
+                mTotalScrollMotion = 0;
+                recycleVelocityTracker();
+                break;
+            }
+            case MotionEvent.ACTION_POINTER_UP: {
+                int pointerIndex = ev.getActionIndex();
+                int pointerId = ev.getPointerId(pointerIndex);
+                if (pointerId == mActivePointerId) {
+                    // Select a new active pointer id and reset the motion state
+                    final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
+                    mActivePointerId = ev.getPointerId(newPointerIndex);
+                    mLastMotionX = (int) ev.getX(newPointerIndex);
+                    mLastMotionY = (int) ev.getY(newPointerIndex);
+                    mVelocityTracker.clear();
+                }
+                break;
+            }
+            case MotionEvent.ACTION_CANCEL: {
+                if (mIsScrolling) {
+                    // Disable HW layers
+                    mSv.decHwLayersRefCount("stackScroll");
+                }
+                if (mSv.isScrollOutOfBounds()) {
+                    // Animate the scroll back into bounds
+                    // XXX: Make this animation a function of the velocity OR distance
+                    mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
+                }
+                mActivePointerId = INACTIVE_POINTER_ID;
+                mIsScrolling = false;
+                mTotalScrollMotion = 0;
+                recycleVelocityTracker();
+                break;
+            }
+        }
+        return true;
+    }
+
+    /**** SwipeHelper Implementation ****/
+
+    @Override
+    public View getChildAtPosition(MotionEvent ev) {
+        return findViewAtPoint((int) ev.getX(), (int) ev.getY());
+    }
+
+    @Override
+    public boolean canChildBeDismissed(View v) {
+        return true;
+    }
+
+    @Override
+    public void onBeginDrag(View v) {
+        // Enable HW layers
+        mSv.addHwLayersRefCount("swipeBegin");
+        // Disallow parents from intercepting touch events
+        final ViewParent parent = mSv.getParent();
+        if (parent != null) {
+            parent.requestDisallowInterceptTouchEvent(true);
+        }
+    }
+
+    @Override
+    public void onChildDismissed(View v) {
+        TaskView tv = (TaskView) v;
+        Task task = tv.getTask();
+        Activity activity = (Activity) mSv.getContext();
+
+        // Remove the task from the view
+        mSv.mStack.removeTask(task);
+
+        // Remove any stored data from the loader
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        loader.deleteTaskData(task);
+
+        // Remove the task from activity manager
+        final ActivityManager am = (ActivityManager)
+                activity.getSystemService(Context.ACTIVITY_SERVICE);
+        if (am != null) {
+            am.removeTask(tv.getTask().key.id,
+                    ActivityManager.REMOVE_TASK_KILL_PROCESS);
+        }
+
+        // If there are no remaining tasks, then just close the activity
+        if (mSv.mStack.getTaskCount() == 0) {
+            activity.finish();
+        }
+
+        // Disable HW layers
+        mSv.decHwLayersRefCount("swipeComplete");
+    }
+
+    @Override
+    public void onSnapBackCompleted(View v) {
+        // Do Nothing
+    }
+
+    @Override
+    public void onDragCancelled(View v) {
+        // Disable HW layers
+        mSv.decHwLayersRefCount("swipeCancelled");
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
new file mode 100644
index 0000000..e6dce37
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.view.Gravity;
+import android.view.View;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import com.android.systemui.recents.Console;
+import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
+import com.android.systemui.recents.model.Task;
+
+
+/** The task thumbnail view */
+class TaskThumbnailView extends ImageView {
+    Task mTask;
+    int mBarColor;
+
+    Path mRoundedRectClipPath = new Path();
+
+    public TaskThumbnailView(Context context) {
+        super(context);
+        setScaleType(ScaleType.FIT_XY);
+    }
+
+    /** Binds the thumbnail view to the task */
+    void rebindToTask(Task t, boolean animate) {
+        mTask = t;
+        if (t.thumbnail != null) {
+            // Update the bar color
+            if (Constants.Values.TaskView.DrawColoredTaskBars) {
+                int[] colors = {0xFFCC0C39, 0xFFE6781E, 0xFFC8CF02, 0xFF1693A7};
+                mBarColor = colors[mTask.key.intent.getComponent().getPackageName().length() % colors.length];
+            }
+
+            setImageBitmap(t.thumbnail);
+            if (animate) {
+                // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
+            }
+        }
+    }
+
+    /** Unbinds the thumbnail view from the task */
+    void unbindFromTask() {
+        mTask = null;
+        setImageDrawable(null);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        // Update the rounded rect clip path
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps);
+        mRoundedRectClipPath.reset();
+        mRoundedRectClipPath.addRoundRect(new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()),
+                radius, radius, Path.Direction.CW);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (Constants.Values.TaskView.UseRoundedCorners) {
+            canvas.clipPath(mRoundedRectClipPath);
+        }
+
+        super.onDraw(canvas);
+
+        if (Constants.Values.TaskView.DrawColoredTaskBars) {
+            RecentsConfiguration config = RecentsConfiguration.getInstance();
+            int taskBarHeight = config.pxFromDp(Constants.Values.TaskView.TaskBarHeightDps);
+            // XXX: If we actually use this, this should be pulled out into a TextView that we
+            // inflate
+
+            // Draw the task bar
+            Rect r = new Rect();
+            Paint p = new Paint();
+            p.setAntiAlias(true);
+            p.setSubpixelText(true);
+            p.setColor(mBarColor);
+            p.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
+            canvas.drawRect(0, 0, getMeasuredWidth(), taskBarHeight, p);
+            p.setColor(0xFFffffff);
+            p.setTextSize(68);
+            p.getTextBounds("X", 0, 1, r);
+            int offset = (int) (taskBarHeight - r.height()) / 2;
+            canvas.drawText(mTask.title, offset, offset + r.height(), p);
+        }
+    }
+}
+
+/* The task icon view */
+class TaskIconView extends ImageView {
+    Task mTask;
+
+    Path mClipPath = new Path();
+    float mClipRadius;
+    Point mClipOrigin = new Point();
+    ObjectAnimator mCircularClipAnimator;
+
+    public TaskIconView(Context context) {
+        super(context);
+        mClipPath = new Path();
+        mClipRadius = 1f;
+    }
+
+    /** Binds the icon view to the task */
+    void rebindToTask(Task t, boolean animate) {
+        mTask = t;
+        if (t.icon != null) {
+            setImageDrawable(t.icon);
+            if (animate) {
+                // XXX: Investigate how expensive it will be to create a second bitmap and crossfade
+            }
+        }
+    }
+
+    /** Unbinds the icon view from the task */
+    void unbindFromTask() {
+        mTask = null;
+        setImageDrawable(null);
+    }
+
+    /** Sets the circular clip radius on the icon */
+    public void setCircularClipRadius(float r) {
+        Console.log(Constants.DebugFlags.UI.Clipping, "[TaskView|setCircularClip]", "" + r);
+        mClipRadius = r;
+        invalidate();
+    }
+
+    /** Gets the circular clip radius on the icon */
+    public float getCircularClipRadius() {
+        return mClipRadius;
+    }
+
+    /** Animates the circular clip radius on the icon */
+    void animateCircularClip(boolean brNotTl, float newRadius, int duration, int startDelay,
+                             TimeInterpolator interpolator,
+                             AnimatorListenerAdapter listener) {
+        if (mCircularClipAnimator != null) {
+            mCircularClipAnimator.cancel();
+            mCircularClipAnimator.removeAllListeners();
+        }
+        if (brNotTl) {
+            mClipOrigin.set(0, 0);
+        } else {
+            mClipOrigin.set(getMeasuredWidth(), getMeasuredHeight());
+        }
+        mCircularClipAnimator = ObjectAnimator.ofFloat(this, "circularClipRadius", newRadius);
+        mCircularClipAnimator.setStartDelay(startDelay);
+        mCircularClipAnimator.setDuration(duration);
+        mCircularClipAnimator.setInterpolator(interpolator);
+        if (listener != null) {
+            mCircularClipAnimator.addListener(listener);
+        }
+        mCircularClipAnimator.start();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
+        int width = getMeasuredWidth();
+        int height = getMeasuredHeight();
+        int maxSize = (int) Math.ceil(Math.sqrt(width * width + height * height));
+        mClipPath.reset();
+        mClipPath.addCircle(mClipOrigin.x, mClipOrigin.y, mClipRadius * maxSize, Path.Direction.CW);
+        canvas.clipPath(mClipPath);
+        super.onDraw(canvas);
+        canvas.restoreToCount(saveCount);
+    }
+}
+
+/* A task view */
+public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
+    /** The TaskView callbacks */
+    interface TaskViewCallbacks {
+        public void onTaskIconClicked(TaskView tv);
+        // public void onTaskViewReboundToTask(TaskView tv, Task t);
+    }
+
+    Task mTask;
+    TaskThumbnailView mThumbnailView;
+    TaskIconView mIconView;
+    TaskViewCallbacks mCb;
+
+    public TaskView(Context context) {
+        super(context);
+        mThumbnailView = new TaskThumbnailView(context);
+        mIconView = new TaskIconView(context);
+        mIconView.setOnClickListener(this);
+        addView(mThumbnailView);
+        addView(mIconView);
+
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        int barHeight = config.pxFromDp(Constants.Values.TaskView.TaskBarHeightDps);
+        int iconSize = config.pxFromDp(Constants.Values.TaskView.TaskIconSizeDps);
+        int offset = barHeight - (iconSize / 2);
+
+        // XXX: Lets keep the icon in the corner for the time being
+        offset = iconSize / 4;
+
+        /*
+        ((LayoutParams) mThumbnailView.getLayoutParams()).leftMargin = barHeight / 2;
+        ((LayoutParams) mThumbnailView.getLayoutParams()).rightMargin = barHeight / 2;
+        ((LayoutParams) mThumbnailView.getLayoutParams()).bottomMargin = barHeight;
+        */
+        ((LayoutParams) mIconView.getLayoutParams()).gravity = Gravity.END;
+        ((LayoutParams) mIconView.getLayoutParams()).width = iconSize;
+        ((LayoutParams) mIconView.getLayoutParams()).height = iconSize;
+        ((LayoutParams) mIconView.getLayoutParams()).topMargin = offset;
+        ((LayoutParams) mIconView.getLayoutParams()).rightMargin = offset;
+    }
+
+    /** Set callback */
+    void setCallbacks(TaskViewCallbacks cb) {
+        mCb = cb;
+    }
+
+    /** Gets the task */
+    Task getTask() {
+        return mTask;
+    }
+
+    /** Synchronizes this view's properties with the task's transform */
+    void updateViewPropertiesFromTask(TaskViewTransform animateFromTransform,
+                                      TaskViewTransform transform, int duration) {
+        if (duration > 0) {
+            if (animateFromTransform != null) {
+                setTranslationY(animateFromTransform.translationY);
+                setScaleX(animateFromTransform.scale);
+                setScaleY(animateFromTransform.scale);
+            }
+            animate().translationY(transform.translationY)
+                    .scaleX(transform.scale)
+                    .scaleY(transform.scale)
+                    .setDuration(duration)
+                    .setInterpolator(new AccelerateDecelerateInterpolator())
+                    .start();
+        } else {
+            setTranslationY(transform.translationY);
+            setScaleX(transform.scale);
+            setScaleY(transform.scale);
+        }
+    }
+
+    /** Resets this view's properties */
+    void resetViewProperties() {
+        setTranslationX(0f);
+        setTranslationY(0f);
+        setScaleX(1f);
+        setScaleY(1f);
+        setAlpha(1f);
+    }
+
+    /** Animates this task view as it enters recents */
+    public void animateOnEnterRecents() {
+        if (Constants.Values.TaskView.AnimateFrontTaskIconOnEnterUseClip) {
+            mIconView.setCircularClipRadius(0f);
+            mIconView.animateCircularClip(true, 1f,
+                Constants.Values.TaskView.Animation.TaskIconOnEnterDuration,
+                300, new AccelerateInterpolator(), null);
+        } else {
+            RecentsConfiguration config = RecentsConfiguration.getInstance();
+            int translate = config.pxFromDp(10);
+            mIconView.setScaleX(1.25f);
+            mIconView.setScaleY(1.25f);
+            mIconView.setAlpha(0f);
+            mIconView.setTranslationX(translate / 2);
+            mIconView.setTranslationY(-translate);
+            mIconView.animate()
+                    .alpha(1f)
+                    .scaleX(1f)
+                    .scaleY(1f)
+                    .translationX(0)
+                    .translationY(0)
+                    .setStartDelay(235)
+                    .setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
+                    .withLayer()
+                    .start();
+        }
+    }
+
+    /** Animates this task view as it exits recents */
+    public void animateOnLeavingRecents(final Runnable r) {
+        if (Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingUseClip) {
+            mIconView.animateCircularClip(false, 0f,
+                Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration, 0,
+                new DecelerateInterpolator(),
+                new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        r.run();
+                    }
+                });
+        } else {
+            mIconView.animate()
+                .alpha(0f)
+                .setStartDelay(0)
+                .setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
+                .setInterpolator(new DecelerateInterpolator())
+                .withLayer()
+                .withEndAction(r)
+                .start();
+        }
+    }
+
+    /** Returns the rect we want to clip (it may not be the full rect) */
+    Rect getClippingRect(Rect outRect, boolean accountForRoundedRects) {
+        getHitRect(outRect);
+        // XXX: We should get the hit rect of the thumbnail view and intersect, but this is faster
+        outRect.right = outRect.left + mThumbnailView.getRight();
+        outRect.bottom = outRect.top + mThumbnailView.getBottom();
+        // We need to shrink the next rect by the rounded corners since those are draw on
+        // top of the current view
+        if (accountForRoundedRects) {
+            RecentsConfiguration config = RecentsConfiguration.getInstance();
+            float radius = config.pxFromDp(Constants.Values.TaskView.RoundedCornerRadiusDps);
+            outRect.inset((int) radius, (int) radius);
+        }
+        return outRect;
+    }
+
+    /** Enable the hw layers on this task view */
+    void enableHwLayers() {
+        mThumbnailView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+    }
+
+    /** Disable the hw layers on this task view */
+    void disableHwLayers() {
+        mThumbnailView.setLayerType(View.LAYER_TYPE_NONE, null);
+    }
+
+    /**** TaskCallbacks Implementation ****/
+
+    /** Binds this task view to the task */
+    public void onTaskBound(Task t) {
+        mTask = t;
+        mTask.setCallbacks(this);
+    }
+
+    @Override
+    public void onTaskDataLoaded(boolean reloadingTaskData) {
+        // Bind each of the views to the new task data
+        mThumbnailView.rebindToTask(mTask, reloadingTaskData);
+        mIconView.rebindToTask(mTask, reloadingTaskData);
+    }
+
+    @Override
+    public void onTaskDataUnloaded() {
+        // Unbind each of the views from the task data and remove the task callback
+        mTask.setCallbacks(null);
+        mThumbnailView.unbindFromTask();
+        mIconView.unbindFromTask();
+    }
+
+    @Override
+    public void onClick(View v) {
+        mCb.onTaskIconClicked(this);
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
new file mode 100644
index 0000000..66c52a0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.graphics.Rect;
+
+
+/* The transform state for a task view */
+public class TaskViewTransform {
+    public int translationY = 0;
+    public float scale = 1f;
+    public boolean visible = true;
+    public Rect rect = new Rect();
+    float t;
+
+    @Override
+    public String toString() {
+        return "TaskViewTransform y: " + translationY + " scale: " + scale +
+                " visible: " + visible + " rect: " + rect;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
new file mode 100644
index 0000000..af0094e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.views;
+
+import android.content.Context;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+
+/* A view pool to manage more views than we can visibly handle */
+public class ViewPool<V, T> {
+
+    /* An interface to the consumer of a view pool */
+    public interface ViewPoolConsumer<V, T> {
+        public V createView(Context context);
+        public void prepareViewToEnterPool(V v);
+        public void prepareViewToLeavePool(V v, T prepareData, boolean isNewView);
+        public boolean hasPreferredData(V v, T preferredData);
+    }
+
+    Context mContext;
+    ViewPoolConsumer<V, T> mViewCreator;
+    LinkedList<V> mPool = new LinkedList<V>();
+
+    /** Initializes the pool with a fixed predetermined pool size */
+    public ViewPool(Context context, ViewPoolConsumer<V, T> viewCreator) {
+        mContext = context;
+        mViewCreator = viewCreator;
+    }
+
+    /** Returns a view into the pool */
+    void returnViewToPool(V v) {
+        mViewCreator.prepareViewToEnterPool(v);
+        mPool.push(v);
+    }
+
+    /** Gets a view from the pool and prepares it */
+    V pickUpViewFromPool(T preferredData, T prepareData) {
+        V v = null;
+        boolean isNewView = false;
+        if (mPool.isEmpty()) {
+            v = mViewCreator.createView(mContext);
+            isNewView = true;
+        } else {
+            // Try and find a preferred view
+            Iterator<V> iter = mPool.iterator();
+            while (iter.hasNext()) {
+                V vpv = iter.next();
+                if (mViewCreator.hasPreferredData(vpv, preferredData)) {
+                    v = vpv;
+                    iter.remove();
+                    break;
+                }
+            }
+            // Otherwise, just grab the first view
+            if (v == null) {
+                v = mPool.pop();
+            }
+        }
+        mViewCreator.prepareViewToLeavePool(v, prepareData, isNewView);
+        return v;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 74d982a..e516bb8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -98,7 +98,7 @@
 
     private final int mNotificationId;
     private final NotificationManager mNotificationManager;
-    private final Notification.Builder mNotificationBuilder;
+    private final Notification.Builder mNotificationBuilder, mPublicNotificationBuilder;
     private final File mScreenshotDir;
     private final String mImageFileName;
     private final String mImageFilePath;
@@ -152,18 +152,30 @@
         mTickerAddSpace = !mTickerAddSpace;
         mNotificationId = nId;
         mNotificationManager = nManager;
+        final long now = System.currentTimeMillis();
+
         mNotificationBuilder = new Notification.Builder(context)
             .setTicker(r.getString(R.string.screenshot_saving_ticker)
                     + (mTickerAddSpace ? " " : ""))
             .setContentTitle(r.getString(R.string.screenshot_saving_title))
             .setContentText(r.getString(R.string.screenshot_saving_text))
             .setSmallIcon(R.drawable.stat_notify_image)
-            .setWhen(System.currentTimeMillis());
+            .setWhen(now);
 
         mNotificationStyle = new Notification.BigPictureStyle()
             .bigPicture(preview);
         mNotificationBuilder.setStyle(mNotificationStyle);
 
+        // For "public" situations we want to show all the same info but
+        // omit the actual screenshot image.
+        mPublicNotificationBuilder = new Notification.Builder(context)
+                .setContentTitle(r.getString(R.string.screenshot_saving_title))
+                .setContentText(r.getString(R.string.screenshot_saving_text))
+                .setSmallIcon(R.drawable.stat_notify_image)
+                .setWhen(now);
+
+        mNotificationBuilder.setPublicVersion(mPublicNotificationBuilder.build());
+
         Notification n = mNotificationBuilder.build();
         n.flags |= Notification.FLAG_NO_CLEAR;
         mNotificationManager.notify(nId, n);
@@ -280,13 +292,25 @@
             launchIntent.setDataAndType(params.imageUri, "image/png");
             launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
+            final long now = System.currentTimeMillis();
+
             mNotificationBuilder
                 .setContentTitle(r.getString(R.string.screenshot_saved_title))
                 .setContentText(r.getString(R.string.screenshot_saved_text))
                 .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0))
-                .setWhen(System.currentTimeMillis())
+                .setWhen(now)
                 .setAutoCancel(true);
 
+            // Update the text in the public version as well
+            mPublicNotificationBuilder
+                .setContentTitle(r.getString(R.string.screenshot_saved_title))
+                .setContentText(r.getString(R.string.screenshot_saved_text))
+                .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0))
+                .setWhen(now)
+                .setAutoCancel(true);
+
+            mNotificationBuilder.setPublicVersion(mPublicNotificationBuilder.build());
+
             Notification n = mNotificationBuilder.build();
             n.flags &= ~Notification.FLAG_NO_CLEAR;
             mNotificationManager.notify(mNotificationId, n);
@@ -669,6 +693,7 @@
             .setContentText(r.getString(R.string.screenshot_failed_text))
             .setSmallIcon(R.drawable.stat_notify_image_error)
             .setWhen(System.currentTimeMillis())
+            .setVisibility(Notification.VISIBILITY_PUBLIC) // ok to show outside lockscreen
             .setAutoCancel(true);
         Notification n =
             new Notification.BigTextStyle(b)
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index ff79f04..bd5e5e8 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -21,6 +21,8 @@
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.Handler;
+import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.Window;
 import android.view.WindowManager;
 import android.widget.ImageView;
@@ -67,9 +69,15 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         Window window = getWindow();
-        window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
-        window.getAttributes().privateFlags |=
+        window.setGravity(Gravity.TOP);
+        WindowManager.LayoutParams lp = window.getAttributes();
+        // Offset from the top
+        lp.y = getContext().getResources().getDimensionPixelOffset(
+                com.android.internal.R.dimen.volume_panel_top);
+        lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
+        lp.privateFlags |=
                 WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+        window.setAttributes(lp);
         window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         window.requestFeature(Window.FEATURE_NO_TITLE);
 
@@ -108,4 +116,13 @@
         mHandler.removeCallbacks(mDismissDialogRunnable);
     }
 
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
+                keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+                keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
+            dismiss();
+        }
+        return super.onKeyDown(keyCode, event);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
index 7d3e870..9839fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AnimatedImageView.java
@@ -38,7 +38,7 @@
     }
 
     private void updateAnim() {
-        Drawable drawable = mAttached ? getDrawable() : null;
+        Drawable drawable = getDrawable();
         if (mAttached && mAnim != null) {
             mAnim.stop();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index ed00398..68c8364 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -26,10 +26,18 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Handler;
@@ -39,12 +47,19 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
 import android.service.notification.StatusBarNotification;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
 import android.text.TextUtils;
+import android.text.style.TextAppearanceSpan;
 import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.LayoutInflater;
@@ -55,6 +70,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.PopupMenu;
@@ -65,6 +81,7 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.statusbar.StatusBarIconList;
 import com.android.internal.widget.SizeAdaptiveLayout;
+import com.android.systemui.ImageUtils;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
 import com.android.systemui.SearchPanelView;
@@ -74,6 +91,7 @@
 
 import java.util.ArrayList;
 import java.util.Locale;
+import java.util.Stack;
 
 public abstract class BaseStatusBar extends SystemUI implements
         CommandQueue.Callbacks {
@@ -93,8 +111,8 @@
 
     protected static final boolean ENABLE_HEADS_UP = true;
     // scores above this threshold should be displayed in heads up mode.
-    protected static final int INTERRUPTION_THRESHOLD = 11;
-    protected static final String SETTING_HEADS_UP = "heads_up_enabled";
+    protected static final int INTERRUPTION_THRESHOLD = 10;
+    protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
 
     // Should match the value in PhoneWindowManager
     public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
@@ -102,6 +120,9 @@
     public static final int EXPANDED_LEAVE_ALONE = -10000;
     public static final int EXPANDED_FULL_OPEN = -10001;
 
+    private static final String EXTRA_INTERCEPT = "android.intercept";
+    private static final float INTERCEPTED_ALPHA = .2f;
+
     protected CommandQueue mCommandQueue;
     protected IStatusBarService mBarService;
     protected H mHandler = createHandler();
@@ -122,15 +143,25 @@
     protected PopupMenu mNotificationBlamePopup;
 
     protected int mCurrentUserId = 0;
+    final protected SparseArray<UserInfo> mRelatedUsers = new SparseArray<UserInfo>();
 
     protected int mLayoutDirection = -1; // invalid
     private Locale mLocale;
     protected boolean mUseHeadsUp = false;
+    protected boolean mHeadsUpTicker = false;
 
     protected IDreamManager mDreamManager;
     PowerManager mPowerManager;
     protected int mRowHeight;
 
+    // public mode, private notifications, etc
+    private boolean mLockscreenPublicMode = false;
+    private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
+    private Context mLightThemeContext;
+    private ImageUtils mImageUtils = new ImageUtils();
+
+    private UserManager mUserManager;
+
     // UI-specific methods
 
     /**
@@ -149,6 +180,8 @@
 
     private RecentsComponent mRecents;
 
+    protected int mZenMode;
+
     public IStatusBarService getStatusBarService() {
         return mBarService;
     }
@@ -157,7 +190,7 @@
         return mDeviceProvisioned;
     }
 
-    private ContentObserver mProvisioningObserver = new ContentObserver(new Handler()) {
+    protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
         @Override
         public void onChange(boolean selfChange) {
             final boolean provisioned = 0 != Settings.Global.getInt(
@@ -166,6 +199,20 @@
                 mDeviceProvisioned = provisioned;
                 updateNotificationIcons();
             }
+            final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+            setZenMode(mode);
+        }
+    };
+
+    private final ContentObserver mLockscreenSettingsObserver = new ContentObserver(mHandler) {
+        @Override
+        public void onChange(boolean selfChange) {
+            // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
+            // so we just dump our cache ...
+            mUsersAllowingPrivateNotifications.clear();
+            // ... and refresh all the notifications
+            updateNotificationIcons();
         }
     };
 
@@ -207,12 +254,26 @@
             String action = intent.getAction();
             if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                 mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                updateRelatedUserCache();
                 if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
                 userSwitched(mCurrentUserId);
+            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+                updateRelatedUserCache();
             }
         }
     };
 
+    private void updateRelatedUserCache() {
+        synchronized (mRelatedUsers) {
+            mRelatedUsers.clear();
+            if (mUserManager != null) {
+                for (UserInfo related : mUserManager.getRelatedUsers(mCurrentUserId)) {
+                    mRelatedUsers.put(related.id, related);
+                }
+            }
+        }
+    }
+
     public void start() {
         mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
@@ -222,10 +283,21 @@
                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
-        mProvisioningObserver.onChange(false); // set up
+        mSettingsObserver.onChange(false); // set up
         mContext.getContentResolver().registerContentObserver(
                 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
-                mProvisioningObserver);
+                mSettingsObserver);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
+                mSettingsObserver);
+
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+                true,
+                mLockscreenSettingsObserver,
+                UserHandle.USER_ALL);
+        mLightThemeContext = new RemoteViewsThemeContextWrapper(mContext,
+                android.R.style.Theme_Holo_Light);
 
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -235,6 +307,8 @@
         mLocale = mContext.getResources().getConfiguration().locale;
         mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
 
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
         // Connect in to the status bar manager service
         StatusBarIconList iconList = new StatusBarIconList();
         ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>();
@@ -296,22 +370,28 @@
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
+        filter.addAction(Intent.ACTION_USER_ADDED);
         mContext.registerReceiver(mBroadcastReceiver, filter);
+
+        updateRelatedUserCache();
     }
 
     public void userSwitched(int newUserId) {
         // should be overridden
     }
 
-    public boolean notificationIsForCurrentUser(StatusBarNotification n) {
+    public boolean notificationIsForCurrentOrRelatedUser(StatusBarNotification n) {
         final int thisUserId = mCurrentUserId;
         final int notificationUserId = n.getUserId();
         if (DEBUG && MULTIUSER_DEBUG) {
             Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
                     n, thisUserId, notificationUserId));
         }
-        return notificationUserId == UserHandle.USER_ALL
-                || thisUserId == notificationUserId;
+        synchronized (mRelatedUsers) {
+            return notificationUserId == UserHandle.USER_ALL
+                    || thisUserId == notificationUserId
+                    || mRelatedUsers.get(notificationUserId) != null;
+        }
     }
 
     @Override
@@ -337,13 +417,14 @@
             final String _pkg = n.getPackageName();
             final String _tag = n.getTag();
             final int _id = n.getId();
+            final int _userId = n.getUserId();
             vetoButton.setOnClickListener(new View.OnClickListener() {
                     public void onClick(View v) {
                         // Accessibility feedback
                         v.announceForAccessibility(
                                 mContext.getString(R.string.accessibility_notification_dismissed));
                         try {
-                            mBarService.onNotificationClear(_pkg, _tag, _id);
+                            mBarService.onNotificationClear(_pkg, _tag, _id, _userId);
 
                         } catch (RemoteException ex) {
                             // system process is dead if we're here.
@@ -377,6 +458,158 @@
         }
     }
 
+    private void processLegacyHoloNotification(StatusBarNotification sbn, View content) {
+
+        // TODO: Also skip processing if it is a holo-style notification.
+        // If the notification is custom, we can't process it.
+        if (!sbn.getNotification().extras.getBoolean(Notification.EXTRA_BUILDER_REMOTE_VIEWS)) {
+            return;
+        }
+
+        processLegacyHoloLargeIcon(content);
+        processLegacyHoloActions(content);
+        processLegacyNotificationIcon(content);
+        processLegacyTextViews(content);
+    }
+
+    /**
+     * @return the context to be used for the inflation of the specified {@code sbn}; this is
+     *      dependent whether the notification is quantum-style or holo-style
+     */
+    private Context getInflationContext(StatusBarNotification sbn) {
+
+        // TODO: Adjust this logic when we change the theme of the status bar windows.
+        if (sbn.getNotification().extras.getBoolean(Notification.EXTRA_BUILDER_REMOTE_VIEWS)) {
+            return mLightThemeContext;
+        } else {
+            return mContext;
+        }
+    }
+
+    private void processLegacyNotificationIcon(View content) {
+        View v = content.findViewById(com.android.internal.R.id.right_icon);
+        if (v != null & v instanceof ImageView) {
+            ImageView iv = (ImageView) v;
+            Drawable d = iv.getDrawable();
+            if (isMonochrome(d)) {
+                d.mutate();
+                d.setColorFilter(mLightThemeContext.getResources().getColor(
+                        R.color.notification_action_legacy_color_filter), PorterDuff.Mode.MULTIPLY);
+            }
+        }
+    }
+
+    private void processLegacyHoloLargeIcon(View content) {
+        View v = content.findViewById(com.android.internal.R.id.icon);
+        if (v != null & v instanceof ImageView) {
+            ImageView iv = (ImageView) v;
+            if (isMonochrome(iv.getDrawable())) {
+                iv.setBackground(mLightThemeContext.getResources().getDrawable(
+                        R.drawable.notification_icon_legacy_bg_inset));
+            }
+        }
+    }
+
+    private boolean isMonochrome(Drawable d) {
+        if (d == null) {
+            return false;
+        } else if (d instanceof BitmapDrawable) {
+            BitmapDrawable bd = (BitmapDrawable) d;
+            return bd.getBitmap() != null && mImageUtils.isGrayscale(bd.getBitmap());
+        } else if (d instanceof AnimationDrawable) {
+            AnimationDrawable ad = (AnimationDrawable) d;
+            int count = ad.getNumberOfFrames();
+            return count > 0 && isMonochrome(ad.getFrame(0));
+        } else {
+            return false;
+        }
+    }
+
+    private void processLegacyHoloActions(View content) {
+        View v = content.findViewById(com.android.internal.R.id.actions);
+        if (v != null & v instanceof ViewGroup) {
+            ViewGroup vg = (ViewGroup) v;
+            int childCount = vg.getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                View child = vg.getChildAt(i);
+                if (child instanceof Button) {
+                    Button button = (Button) child;
+                    Drawable[] compoundDrawables = button.getCompoundDrawablesRelative();
+                    if (isMonochrome(compoundDrawables[0])) {
+                        Drawable d = compoundDrawables[0];
+                        d.mutate();
+                        d.setColorFilter(mLightThemeContext.getResources().getColor(
+                                R.color.notification_action_legacy_color_filter),
+                                PorterDuff.Mode.MULTIPLY);
+                    }
+                }
+            }
+        }
+    }
+
+    private void processLegacyTextViews(View content) {
+        Stack<View> viewStack = new Stack<View>();
+        viewStack.push(content);
+        while(!viewStack.isEmpty()) {
+            View current = viewStack.pop();
+            if(current instanceof ViewGroup){
+                ViewGroup currentGroup = (ViewGroup) current;
+                int numChildren = currentGroup.getChildCount();
+                for(int i=0;i<numChildren;i++){
+                    viewStack.push(currentGroup.getChildAt(i));
+                }
+            }
+            if (current instanceof TextView) {
+                processLegacyTextView((TextView) current);
+            }
+        }
+    }
+
+    private void processLegacyTextView(TextView textView) {
+        if (textView.getText() instanceof Spanned) {
+            Spanned ss = (Spanned) textView.getText();
+            Object[] spans = ss.getSpans(0, ss.length(), Object.class);
+            SpannableStringBuilder builder = new SpannableStringBuilder(ss.toString());
+            for (Object span : spans) {
+                Object resultSpan = span;
+                if (span instanceof TextAppearanceSpan) {
+                    resultSpan = processTextAppearanceSpan((TextAppearanceSpan) span);
+                }
+                builder.setSpan(resultSpan, ss.getSpanStart(span), ss.getSpanEnd(span),
+                        ss.getSpanFlags(span));
+            }
+            textView.setText(builder);
+        }
+    }
+
+    private TextAppearanceSpan processTextAppearanceSpan(TextAppearanceSpan span) {
+        ColorStateList colorStateList = span.getTextColor();
+        if (colorStateList != null) {
+            int[] colors = colorStateList.getColors();
+            boolean changed = false;
+            for (int i = 0; i < colors.length; i++) {
+                if (mImageUtils.isGrayscale(colors[i])) {
+                    colors[i] = processColor(colors[i]);
+                    changed = true;
+                }
+            }
+            if (changed) {
+                return new TextAppearanceSpan(
+                        span.getFamily(), span.getTextStyle(), span.getTextSize(),
+                        new ColorStateList(colorStateList.getStates(), colors),
+                        span.getLinkTextColor());
+            }
+        }
+        return span;
+    }
+
+    private int processColor(int color) {
+        return Color.argb(Color.alpha(color),
+                255 - Color.red(color),
+                255 - Color.green(color),
+                255 - Color.blue(color));
+    }
+
     private void startApplicationDetailsActivity(String packageName) {
         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                 Uri.fromParts("package", packageName, null));
@@ -524,6 +757,7 @@
 
     protected void toggleRecentsActivity() {
         if (mRecents != null) {
+            sendCloseSystemWindows(mContext, SYSTEM_DIALOG_REASON_RECENT_APPS);
             mRecents.toggleRecents(mDisplay, mLayoutDirection, getStatusBarView());
         }
     }
@@ -548,6 +782,37 @@
 
     public abstract void resetHeadsUpDecayTimer();
 
+    /**
+     * Save the current "public" (locked and secure) state of the lockscreen.
+     */
+    public void setLockscreenPublicMode(boolean publicMode) {
+        mLockscreenPublicMode = publicMode;
+    }
+
+    public boolean isLockscreenPublicMode() {
+        return mLockscreenPublicMode;
+    }
+
+    /**
+     * Has the given user chosen to allow their private (full) notifications to be shown even
+     * when the lockscreen is in "public" (secure & locked) mode?
+     */
+    public boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
+        if (userHandle == UserHandle.USER_ALL) {
+            return true;
+        }
+
+        if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
+            final boolean allowed = 0 != Settings.Secure.getIntForUser(
+                    mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle);
+            mUsersAllowingPrivateNotifications.append(userHandle, allowed);
+            return allowed;
+        }
+
+        return mUsersAllowingPrivateNotifications.get(userHandle);
+    }
+
     protected class H extends Handler {
         public void handleMessage(Message m) {
             Intent intent;
@@ -614,6 +879,14 @@
     }
 
     public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
+            return inflateViews(entry, parent, false);
+    }
+
+    public boolean inflateViewsForHeadsUp(NotificationData.Entry entry, ViewGroup parent) {
+            return inflateViews(entry, parent, true);
+    }
+
+    public boolean inflateViews(NotificationData.Entry entry, ViewGroup parent, boolean isHeadsUp) {
         int minHeight =
                 mContext.getResources().getDimensionPixelSize(R.dimen.notification_min_height);
         int maxHeight =
@@ -621,10 +894,22 @@
         StatusBarNotification sbn = entry.notification;
         RemoteViews contentView = sbn.getNotification().contentView;
         RemoteViews bigContentView = sbn.getNotification().bigContentView;
+
+        if (isHeadsUp) {
+            maxHeight =
+                    mContext.getResources().getDimensionPixelSize(R.dimen.notification_mid_height);
+            bigContentView = sbn.getNotification().headsUpContentView;
+        }
+
         if (contentView == null) {
             return false;
         }
 
+        Log.v(TAG, "publicNotification: "
+                + sbn.getNotification().publicVersion);
+
+        Notification publicNotification = sbn.getNotification().publicVersion;
+
         // create the row view
         LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
@@ -642,26 +927,31 @@
         // NB: the large icon is now handled entirely by the template
 
         // bind the click event to the content area
-        ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
-        ViewGroup adaptive = (ViewGroup)row.findViewById(R.id.adaptive);
+        ViewGroup content = (ViewGroup)row.findViewById(R.id.container);
+        SizeAdaptiveLayout expanded = (SizeAdaptiveLayout)row.findViewById(R.id.expanded);
+        SizeAdaptiveLayout expandedPublic
+                = (SizeAdaptiveLayout)row.findViewById(R.id.expandedPublic);
 
         content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
 
         PendingIntent contentIntent = sbn.getNotification().contentIntent;
         if (contentIntent != null) {
-            final View.OnClickListener listener = new NotificationClicker(contentIntent,
-                    sbn.getPackageName(), sbn.getTag(), sbn.getId());
+            final View.OnClickListener listener = makeClicker(contentIntent,
+                    sbn.getPackageName(), sbn.getTag(), sbn.getId(), isHeadsUp, sbn.getUserId());
             content.setOnClickListener(listener);
         } else {
             content.setOnClickListener(null);
         }
 
+        // set up the adaptive layout
         View contentViewLocal = null;
         View bigContentViewLocal = null;
         try {
-            contentViewLocal = contentView.apply(mContext, adaptive, mOnClickHandler);
+            contentViewLocal = contentView.apply(getInflationContext(sbn), expanded,
+                    mOnClickHandler);
             if (bigContentView != null) {
-                bigContentViewLocal = bigContentView.apply(mContext, adaptive, mOnClickHandler);
+                bigContentViewLocal = bigContentView.apply(getInflationContext(sbn), expanded,
+                        mOnClickHandler);
             }
         }
         catch (RuntimeException e) {
@@ -671,41 +961,108 @@
         }
 
         if (contentViewLocal != null) {
+            contentViewLocal.setIsRootNamespace(true);
             SizeAdaptiveLayout.LayoutParams params =
                     new SizeAdaptiveLayout.LayoutParams(contentViewLocal.getLayoutParams());
             params.minHeight = minHeight;
             params.maxHeight = minHeight;
-            adaptive.addView(contentViewLocal, params);
+            expanded.addView(contentViewLocal, params);
         }
         if (bigContentViewLocal != null) {
+            bigContentViewLocal.setIsRootNamespace(true);
             SizeAdaptiveLayout.LayoutParams params =
                     new SizeAdaptiveLayout.LayoutParams(bigContentViewLocal.getLayoutParams());
             params.minHeight = minHeight+1;
             params.maxHeight = maxHeight;
-            adaptive.addView(bigContentViewLocal, params);
+            expanded.addView(bigContentViewLocal, params);
         }
+
+        PackageManager pm = mContext.getPackageManager();
+
+        // now the public version
+        View publicViewLocal = null;
+        if (publicNotification != null) {
+            try {
+                publicViewLocal = publicNotification.contentView.apply(getInflationContext(sbn),
+                        expandedPublic, mOnClickHandler);
+
+                if (publicViewLocal != null) {
+                    publicViewLocal.setIsRootNamespace(true);
+                    SizeAdaptiveLayout.LayoutParams params =
+                            new SizeAdaptiveLayout.LayoutParams(publicViewLocal.getLayoutParams());
+                    params.minHeight = minHeight;
+                    params.maxHeight = minHeight;
+                    expandedPublic.addView(publicViewLocal, params);
+                }
+            }
+            catch (RuntimeException e) {
+                final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
+                Log.e(TAG, "couldn't inflate public view for notification " + ident, e);
+                publicViewLocal = null;
+            }
+        }
+
+        if (publicViewLocal == null) {
+            // Add a basic notification template
+            publicViewLocal = LayoutInflater.from(mContext).inflate(
+                    com.android.internal.R.layout.notification_template_base, expandedPublic, true);
+
+            final TextView title = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.title);
+            try {
+                title.setText(pm.getApplicationLabel(
+                        pm.getApplicationInfo(entry.notification.getPackageName(), 0)));
+            } catch (NameNotFoundException e) {
+                title.setText(entry.notification.getPackageName());
+            }
+
+            final ImageView icon = (ImageView) publicViewLocal.findViewById(com.android.internal.R.id.icon);
+
+            final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(),
+                    entry.notification.getUser(),
+                    entry.notification.getNotification().icon,
+                    entry.notification.getNotification().iconLevel,
+                    entry.notification.getNotification().number,
+                    entry.notification.getNotification().tickerText);
+
+            icon.setImageDrawable(StatusBarIconView.getIcon(mContext, ic));
+
+            final TextView text = (TextView) publicViewLocal.findViewById(com.android.internal.R.id.text);
+            text.setText("Unlock your device to see this notification.");
+
+            // TODO: fill out "time" as well
+        }
+
         row.setDrawingCacheEnabled(true);
 
         applyLegacyRowBackground(sbn, content);
+        processLegacyHoloNotification(sbn, contentViewLocal);
+        if (bigContentViewLocal != null) {
+            processLegacyHoloNotification(sbn, bigContentViewLocal);
+        }
+        if (publicViewLocal != null) {
+            processLegacyHoloNotification(sbn, publicViewLocal);
+        }
 
         if (MULTIUSER_DEBUG) {
             TextView debug = (TextView) row.findViewById(R.id.debug_info);
             if (debug != null) {
                 debug.setVisibility(View.VISIBLE);
-                debug.setText("U " + entry.notification.getUserId());
+                debug.setText("CU " + mCurrentUserId +" NU " + entry.notification.getUserId());
             }
         }
         entry.row = row;
         entry.row.setRowHeight(mRowHeight);
         entry.content = content;
         entry.expanded = contentViewLocal;
+        entry.expandedPublic = publicViewLocal;
         entry.setBigContentView(bigContentViewLocal);
 
         return true;
     }
 
-    public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id) {
-        return new NotificationClicker(intent, pkg, tag, id);
+    public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag,
+            int id, boolean forHun, int userId) {
+        return new NotificationClicker(intent, pkg, tag, id, forHun, userId);
     }
 
     protected class NotificationClicker implements View.OnClickListener {
@@ -713,12 +1070,17 @@
         private String mPkg;
         private String mTag;
         private int mId;
+        private boolean mIsHeadsUp;
+        private int mUserId;
 
-        public NotificationClicker(PendingIntent intent, String pkg, String tag, int id) {
+        public NotificationClicker(PendingIntent intent, String pkg, String tag, int id,
+                boolean forHun, int userId) {
             mIntent = intent;
             mPkg = pkg;
             mTag = tag;
             mId = id;
+            mIsHeadsUp = forHun;
+            mUserId = userId;
         }
 
         public void onClick(View v) {
@@ -751,7 +1113,10 @@
             }
 
             try {
-                mBarService.onNotificationClick(mPkg, mTag, mId);
+                if (mIsHeadsUp) {
+                    mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+                }
+                mBarService.onNotificationClick(mPkg, mTag, mId, mUserId);
             } catch (RemoteException ex) {
                 // system process is dead if we're here.
             }
@@ -761,6 +1126,7 @@
             visibilityChanged(false);
         }
     }
+
     /**
      * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
      * This was added last-minute and is inconsistent with the way the rest of the notifications
@@ -788,7 +1154,8 @@
     void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
         removeNotification(key);
         try {
-            mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(), n.getInitialPid(), message);
+            mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(),
+                    n.getInitialPid(), message, n.getUserId());
         } catch (RemoteException ex) {
             // The end is nigh.
         }
@@ -846,6 +1213,7 @@
         if (DEBUG) {
             Log.d(TAG, "addNotificationViews: added at " + pos);
         }
+        updateInterceptedState(entry);
         updateExpansionStates();
         updateNotificationIcons();
     }
@@ -876,6 +1244,35 @@
         }
     }
 
+    protected void setZenMode(int mode) {
+        if (!isDeviceProvisioned()) return;
+        final boolean change = mZenMode != mode;
+        mZenMode = mode;
+        final int N = mNotificationData.size();
+        for (int i = 0; i < N; i++) {
+            final NotificationData.Entry entry = mNotificationData.get(i);
+            if (change && !shouldIntercept()) {
+                entry.notification.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false);
+            }
+            updateInterceptedState(entry);
+        }
+        updateNotificationIcons();
+    }
+
+    private boolean shouldIntercept() {
+        return mZenMode == Settings.Global.ZEN_MODE_LIMITED
+                || mZenMode == Settings.Global.ZEN_MODE_FULL;
+    }
+
+    protected boolean shouldIntercept(Notification n) {
+        return shouldIntercept() && n.extras.getBoolean(EXTRA_INTERCEPT);
+    }
+
+    private void updateInterceptedState(NotificationData.Entry entry) {
+        final boolean intercepted = shouldIntercept(entry.notification.getNotification());
+        entry.row.findViewById(R.id.container).setAlpha(intercepted ? INTERCEPTED_ALPHA : 1);
+    }
+
     protected abstract void haltTicker();
     protected abstract void setAreThereNotifications();
     protected abstract void updateNotificationIcons();
@@ -904,6 +1301,14 @@
         final RemoteViews contentView = notification.getNotification().contentView;
         final RemoteViews oldBigContentView = oldNotification.getNotification().bigContentView;
         final RemoteViews bigContentView = notification.getNotification().bigContentView;
+        final RemoteViews oldHeadsUpContentView = oldNotification.getNotification().headsUpContentView;
+        final RemoteViews headsUpContentView = notification.getNotification().headsUpContentView;
+        final Notification oldPublicNotification = oldNotification.getNotification().publicVersion;
+        final RemoteViews oldPublicContentView = oldPublicNotification != null
+                ? oldPublicNotification.contentView : null;
+        final Notification publicNotification = notification.getNotification().publicVersion;
+        final RemoteViews publicContentView = publicNotification != null
+                ? publicNotification.contentView : null;
 
         if (DEBUG) {
             Log.d(TAG, "old notification: when=" + oldNotification.getNotification().when
@@ -911,11 +1316,13 @@
                     + " expanded=" + oldEntry.expanded
                     + " contentView=" + oldContentView
                     + " bigContentView=" + oldBigContentView
+                    + " publicView=" + oldPublicContentView
                     + " rowParent=" + oldEntry.row.getParent());
             Log.d(TAG, "new notification: when=" + notification.getNotification().when
                     + " ongoing=" + oldNotification.isOngoing()
                     + " contentView=" + contentView
-                    + " bigContentView=" + bigContentView);
+                    + " bigContentView=" + bigContentView
+                    + " publicView=" + publicContentView);
         }
 
         // Can we just reapply the RemoteViews in place?  If when didn't change, the order
@@ -935,8 +1342,24 @@
                     && oldBigContentView.getPackage() != null
                     && oldBigContentView.getPackage().equals(bigContentView.getPackage())
                     && oldBigContentView.getLayoutId() == bigContentView.getLayoutId());
+        boolean headsUpContentsUnchanged =
+                (oldHeadsUpContentView == null && headsUpContentView == null)
+                || ((oldHeadsUpContentView != null && headsUpContentView != null)
+                    && headsUpContentView.getPackage() != null
+                    && oldHeadsUpContentView.getPackage() != null
+                    && oldHeadsUpContentView.getPackage().equals(headsUpContentView.getPackage())
+                    && oldHeadsUpContentView.getLayoutId() == headsUpContentView.getLayoutId());
+        boolean publicUnchanged  =
+                (oldPublicContentView == null && publicContentView == null)
+                || ((oldPublicContentView != null && publicContentView != null)
+                        && publicContentView.getPackage() != null
+                        && oldPublicContentView.getPackage() != null
+                        && oldPublicContentView.getPackage().equals(publicContentView.getPackage())
+                        && oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
+
         ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
-        boolean orderUnchanged = notification.getNotification().when== oldNotification.getNotification().when
+        boolean orderUnchanged =
+                   notification.getNotification().when == oldNotification.getNotification().when
                 && notification.getScore() == oldNotification.getScore();
                 // score now encompasses/supersedes isOngoing()
 
@@ -944,7 +1367,8 @@
                 && !TextUtils.equals(notification.getNotification().tickerText,
                         oldEntry.notification.getNotification().tickerText);
         boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
-        if (contentsUnchanged && bigContentsUnchanged && (orderUnchanged || isTopAnyway)) {
+        if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged
+                && (orderUnchanged || isTopAnyway)) {
             if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
             oldEntry.notification = notification;
             try {
@@ -958,7 +1382,7 @@
                     } else {
                         if (DEBUG) Log.d(TAG, "updating the current heads up:" + notification);
                         mInterruptingNotificationEntry.notification = notification;
-                        updateNotificationViews(mInterruptingNotificationEntry, notification);
+                        updateHeadsUpViews(mInterruptingNotificationEntry, notification);
                     }
                 }
 
@@ -1000,7 +1424,7 @@
         updateNotificationVetoButton(oldEntry.row, notification);
 
         // Is this for you?
-        boolean isForCurrentUser = notificationIsForCurrentUser(notification);
+        boolean isForCurrentUser = notificationIsForCurrentOrRelatedUser(notification);
         if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
 
         // Restart the ticker if it's still running
@@ -1016,22 +1440,48 @@
 
     private void updateNotificationViews(NotificationData.Entry entry,
             StatusBarNotification notification) {
+        updateNotificationViews(entry, notification, false);
+    }
+
+    private void updateHeadsUpViews(NotificationData.Entry entry,
+            StatusBarNotification notification) {
+        updateNotificationViews(entry, notification, true);
+    }
+
+    private void updateNotificationViews(NotificationData.Entry entry,
+            StatusBarNotification notification, boolean isHeadsUp) {
         final RemoteViews contentView = notification.getNotification().contentView;
-        final RemoteViews bigContentView = notification.getNotification().bigContentView;
+        final RemoteViews bigContentView = isHeadsUp
+                ? notification.getNotification().headsUpContentView
+                : notification.getNotification().bigContentView;
+        final Notification publicVersion = notification.getNotification().publicVersion;
+        final RemoteViews publicContentView = publicVersion != null ? publicVersion.contentView
+                : null;
+
         // Reapply the RemoteViews
-        contentView.reapply(mContext, entry.expanded, mOnClickHandler);
+        contentView.reapply(getInflationContext(notification), entry.expanded, mOnClickHandler);
+        processLegacyHoloNotification(notification, entry.expanded);
         if (bigContentView != null && entry.getBigContentView() != null) {
-            bigContentView.reapply(mContext, entry.getBigContentView(), mOnClickHandler);
+            bigContentView.reapply(getInflationContext(notification), entry.getBigContentView(),
+                    mOnClickHandler);
+            processLegacyHoloNotification(notification, entry.getBigContentView());
+        }
+        if (publicContentView != null && entry.getPublicContentView() != null) {
+            publicContentView.reapply(getInflationContext(notification),
+                    entry.getPublicContentView(), mOnClickHandler);
+            processLegacyHoloNotification(notification, entry.getPublicContentView());
         }
         // update the contentIntent
         final PendingIntent contentIntent = notification.getNotification().contentIntent;
         if (contentIntent != null) {
             final View.OnClickListener listener = makeClicker(contentIntent,
-                    notification.getPackageName(), notification.getTag(), notification.getId());
+                    notification.getPackageName(), notification.getTag(), notification.getId(),
+                    isHeadsUp, notification.getUserId());
             entry.content.setOnClickListener(listener);
         } else {
             entry.content.setOnClickListener(null);
         }
+        updateInterceptedState(entry);
     }
 
     protected void notifyHeadsUpScreenOn(boolean screenOn) {
@@ -1049,11 +1499,12 @@
                 || notification.vibrate != null;
         boolean isHighPriority = sbn.getScore() >= INTERRUPTION_THRESHOLD;
         boolean isFullscreen = notification.fullScreenIntent != null;
+        boolean hasTicker = mHeadsUpTicker && !TextUtils.isEmpty(notification.tickerText);
         boolean isAllowed = notification.extras.getInt(Notification.EXTRA_AS_HEADS_UP,
                 Notification.HEADS_UP_ALLOWED) != Notification.HEADS_UP_NEVER;
 
         final KeyguardTouchDelegate keyguard = KeyguardTouchDelegate.getInstance(mContext);
-        boolean interrupt = (isFullscreen || (isHighPriority && isNoisy))
+        boolean interrupt = (isFullscreen || (isHighPriority && (isNoisy || hasTicker)))
                 && isAllowed
                 && mPowerManager.isScreenOn()
                 && !keyguard.isShowingAndNotHidden()
@@ -1071,17 +1522,8 @@
     // A: Almost none! Only things coming from the system (package is "android") that also
     // have special "kind" tags marking them as relevant for setup (see below).
     protected boolean showNotificationEvenIfUnprovisioned(StatusBarNotification sbn) {
-        if ("android".equals(sbn.getPackageName())) {
-            if (sbn.getNotification().kind != null) {
-                for (String aKind : sbn.getNotification().kind) {
-                    // IME switcher, created by InputMethodManagerService
-                    if ("android.system.imeswitcher".equals(aKind)) return true;
-                    // OTA availability & errors, created by SystemUpdateService
-                    if ("android.system.update".equals(aKind)) return true;
-                }
-            }
-        }
-        return false;
+        return "android".equals(sbn.getPackageName())
+                && sbn.getNotification().extras.getBoolean(Notification.EXTRA_ALLOW_DURING_SETUP);
     }
 
     public boolean inKeyguardRestrictedInputMode() {
@@ -1098,4 +1540,35 @@
         }
         mContext.unregisterReceiver(mBroadcastReceiver);
     }
+
+    /**
+     * A custom context theme wrapper that applies a platform theme to a created package context.
+     * This is useful if you want to inflate {@link RemoteViews} with a custom theme (normally, the
+     * theme used there is the default platform theme).
+     */
+    private static class RemoteViewsThemeContextWrapper extends ContextThemeWrapper {
+
+        private int mThemeRes;
+
+        private RemoteViewsThemeContextWrapper(Context base, int themeres) {
+            super(base, themeres);
+            mThemeRes = themeres;
+        }
+
+        @Override
+        public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
+                throws NameNotFoundException {
+            Context c = super.createPackageContextAsUser(packageName, flags, user);
+            c.setTheme(mThemeRes);
+            return c;
+        }
+
+        @Override
+        public Context createPackageContext(String packageName, int flags)
+                throws NameNotFoundException {
+            Context c = super.createPackageContext(packageName, flags);
+            c.setTheme(mThemeRes);
+            return c;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index cd6495f..b3d8688 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -18,9 +18,12 @@
 
 import android.content.Context;
 import android.util.AttributeSet;
+import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
+import com.android.systemui.R;
+
 public class ExpandableNotificationRow extends FrameLayout {
     private int mRowHeight;
 
@@ -30,6 +33,8 @@
     private boolean mUserExpanded;
     /** is the user touching this row */
     private boolean mUserLocked;
+    /** are we showing the "public" version */
+    private boolean mShowingPublic;
 
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -76,4 +81,16 @@
         }
         setLayoutParams(lp);
     }
+
+    public void setShowingPublic(boolean show) {
+        mShowingPublic = show;
+        final ViewGroup publicLayout = (ViewGroup) findViewById(R.id.expandedPublic);
+
+        // bail out if no public version
+        if (publicLayout.getChildCount() == 0) return;
+
+        // TODO: animation?
+        publicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
+        findViewById(R.id.expanded).setVisibility(show ? View.GONE : View.VISIBLE);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 5264998..b9a59dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -21,8 +21,6 @@
 import android.view.View;
 import android.widget.ImageView;
 
-import com.android.systemui.R;
-
 import java.util.ArrayList;
 import java.util.Comparator;
 
@@ -37,6 +35,7 @@
         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 View expandedPublic; // for insecure lockscreens
         public ImageView largeIcon;
         private View expandedBig;
         private boolean interruption;
@@ -53,6 +52,7 @@
         public View getBigContentView() {
             return expandedBig;
         }
+        public View getPublicContentView() { return expandedPublic; }
         /**
          * Set the flag indicating that this is being touched by the user.
          */
@@ -71,9 +71,9 @@
             final StatusBarNotification na = a.notification;
             final StatusBarNotification nb = b.notification;
             int d = na.getScore() - nb.getScore();
-	    if (a.interruption != b.interruption) {
-	      return a.interruption ? 1 : -1;
-	    } else if (d != 0) {
+            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);
@@ -110,19 +110,6 @@
         return i;
     }
 
-    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;
-        entry.row = row;
-        entry.content = content;
-        entry.expanded = expanded;
-        entry.icon = icon;
-        entry.largeIcon = null; // TODO add support for large icons
-        return add(entry);
-    }
-
     public Entry remove(IBinder key) {
         Entry e = findByKey(key);
         if (e != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 9f9524b..6f839bd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -119,7 +119,7 @@
         }
 
         if (!numberEquals) {
-            if (icon.number > 0 && mContext.getResources().getBoolean(
+            if (icon.number > 0 && getContext().getResources().getBoolean(
                         R.bool.config_statusBarShowNumber)) {
                 if (mNumberBackground == null) {
                     mNumberBackground = getContext().getResources().getDrawable(
@@ -240,10 +240,10 @@
 
     void placeNumber() {
         final String str;
-        final int tooBig = mContext.getResources().getInteger(
+        final int tooBig = getContext().getResources().getInteger(
                 android.R.integer.status_bar_notification_info_maxnum);
         if (mIcon.number > tooBig) {
-            str = mContext.getResources().getString(
+            str = getContext().getResources().getString(
                         android.R.string.status_bar_notification_info_overflow);
         } else {
             NumberFormat f = NumberFormat.getIntegerInstance();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index aba7afa..a3cf0f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -143,7 +143,7 @@
             }
         }
         StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.CURRENT, iconId, 0, 0, "Demo");
-        StatusBarIconView v = new StatusBarIconView(mContext, null);
+        StatusBarIconView v = new StatusBarIconView(getContext(), null);
         v.setTag(slot);
         v.set(icon);
         addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
index c1646ba..1ea920d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardTouchDelegate.java
@@ -26,10 +26,11 @@
 import android.util.Slog;
 import android.view.MotionEvent;
 
-import com.android.internal.policy.IKeyguardExitCallback;
-import com.android.internal.policy.IKeyguardShowCallback;
 import com.android.internal.policy.IKeyguardService;
 
+import java.util.ArrayList;
+import java.util.List;
+
 
 /**
  * Facilitates event communication between navigation bar and keyguard.  Currently used to
@@ -42,6 +43,8 @@
     static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService";
 
     private static KeyguardTouchDelegate sInstance;
+    private static final List<OnKeyguardConnectionListener> sConnectionListeners =
+            new ArrayList<OnKeyguardConnectionListener>();
 
     private volatile IKeyguardService mService;
 
@@ -54,6 +57,10 @@
             Slog.v(TAG, "Connected to keyguard");
             mService = IKeyguardService.Stub.asInterface(service);
 
+            for (int i = 0; i < sConnectionListeners.size(); i++) {
+                OnKeyguardConnectionListener listener = sConnectionListeners.get(i);
+                listener.onKeyguardServiceConnected(KeyguardTouchDelegate.this);
+            }
         }
 
         @Override
@@ -61,6 +68,11 @@
             Slog.v(TAG, "Disconnected from keyguard");
             mService = null;
             sInstance = null; // force reconnection if this goes away
+
+            for (int i = 0; i < sConnectionListeners.size(); i++) {
+                OnKeyguardConnectionListener listener = sConnectionListeners.get(i);
+                listener.onKeyguardServiceDisconnected(KeyguardTouchDelegate.this);
+            }
         }
 
     };
@@ -184,4 +196,13 @@
         }
     }
 
+    public static void addListener(OnKeyguardConnectionListener listener) {
+        sConnectionListeners.add(listener);
+    }
+
+    public interface OnKeyguardConnectionListener {
+
+        void onKeyguardServiceConnected(KeyguardTouchDelegate keyguardTouchDelegate);
+        void onKeyguardServiceDisconnected(KeyguardTouchDelegate keyguardTouchDelegate);
+    }
 }
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 9589e8b..d9e0903 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -57,6 +57,8 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import static com.android.systemui.statusbar.phone.KeyguardTouchDelegate.OnKeyguardConnectionListener;
+
 public class NavigationBarView extends LinearLayout {
     final static boolean DEBUG = false;
     final static String TAG = "PhoneStatusBar/NavigationBarView";
@@ -172,6 +174,25 @@
         }
     };
 
+    private final OnKeyguardConnectionListener mKeyguardConnectionListener =
+            new OnKeyguardConnectionListener() {
+                @Override
+                public void onKeyguardServiceConnected(
+                        KeyguardTouchDelegate keyguardTouchDelegate) {
+                    post(new Runnable() {
+                        @Override
+                        public void run() {
+                            mCameraDisabledByDpm = isCameraDisabledByDpm();
+                        }
+                    });
+                }
+
+                @Override
+                public void onKeyguardServiceDisconnected(
+                        KeyguardTouchDelegate keyguardTouchDelegate) {
+                }
+            };
+
     private class H extends Handler {
         public void handleMessage(Message m) {
             switch (m.what) {
@@ -201,7 +222,7 @@
         mDisplay = ((WindowManager)context.getSystemService(
                 Context.WINDOW_SERVICE)).getDefaultDisplay();
 
-        final Resources res = mContext.getResources();
+        final Resources res = getContext().getResources();
         mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
         mVertical = false;
         mShowMenu = false;
@@ -211,6 +232,7 @@
 
         mBarTransitions = new NavigationBarTransitions(this);
 
+        KeyguardTouchDelegate.addListener(mKeyguardConnectionListener);
         mCameraDisabledByDpm = isCameraDisabledByDpm();
         watchForDevicePolicyChanges();
     }
@@ -218,7 +240,7 @@
     private void watchForDevicePolicyChanges() {
         final IntentFilter filter = new IntentFilter();
         filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
-        mContext.registerReceiver(new BroadcastReceiver() {
+        getContext().registerReceiver(new BroadcastReceiver() {
             public void onReceive(Context context, Intent intent) {
                 post(new Runnable() {
                     @Override
@@ -302,7 +324,7 @@
 
     @Override
     public void setLayoutDirection(int layoutDirection) {
-        getIcons(mContext.getResources());
+        getIcons(getContext().getResources());
 
         super.setLayoutDirection(layoutDirection);
     }
@@ -323,7 +345,7 @@
             mTransitionListener.onBackAltCleared();
         }
         if (DEBUG) {
-            android.widget.Toast.makeText(mContext,
+            android.widget.Toast.makeText(getContext(),
                 "Navigation icon hints = " + hints,
                 500).show();
         }
@@ -395,7 +417,7 @@
 
     private boolean isCameraDisabledByDpm() {
         final DevicePolicyManager dpm =
-                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+                (DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
         if (dpm != null) {
             try {
                 final int userId = ActivityManagerNative.getDefault().getCurrentUser().id;
@@ -457,7 +479,7 @@
 
     private void watchForAccessibilityChanges() {
         final AccessibilityManager am =
-                (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+                (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
 
         // Set the initial state
         enableAccessibility(am.isTouchExplorationEnabled());
@@ -494,7 +516,7 @@
         if (hasCamera) {
             // Warm up KeyguardTouchDelegate so it's ready by the time the camera button is touched.
             // This will connect to KeyguardService so that touch events are processed.
-            KeyguardTouchDelegate.getInstance(mContext);
+            KeyguardTouchDelegate.getInstance(getContext());
         }
     }
 
@@ -575,7 +597,7 @@
 
     private String getResourceName(int resId) {
         if (resId != 0) {
-            final android.content.res.Resources res = mContext.getResources();
+            final android.content.res.Resources res = getContext().getResources();
             try {
                 return res.getResourceName(resId);
             } catch (android.content.res.Resources.NotFoundException ex) {
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 bbac4ef..60ec787 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -49,6 +49,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.inputmethodservice.InputMethodService;
+import android.media.AudioManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -189,6 +190,8 @@
     IconMerger mNotificationIcons;
     // [+>
     View mMoreIcon;
+    // mode indicator icon
+    ImageView mModeIcon;
 
     // expanded notifications
     NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -310,13 +313,17 @@
         @Override
         public void onChange(boolean selfChange) {
             boolean wasUsing = mUseHeadsUp;
-            mUseHeadsUp = ENABLE_HEADS_UP && 0 != Settings.Global.getInt(
-                    mContext.getContentResolver(), SETTING_HEADS_UP, 0);
+            mUseHeadsUp = ENABLE_HEADS_UP && Settings.Global.HEADS_UP_OFF != Settings.Global.getInt(
+                    mContext.getContentResolver(), Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                    Settings.Global.HEADS_UP_OFF);
+            mHeadsUpTicker = mUseHeadsUp && 0 != Settings.Global.getInt(
+                    mContext.getContentResolver(), SETTING_HEADS_UP_TICKER, 0);
             Log.d(TAG, "heads up is " + (mUseHeadsUp ? "enabled" : "disabled"));
             if (wasUsing != mUseHeadsUp) {
                 if (!mUseHeadsUp) {
                     Log.d(TAG, "dismissing any existing heads up notification on disable event");
-                    mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+                    setHeadsUpVisibility(false);
+                    mHeadsUpNotificationView.setNotification(null);
                     removeHeadsUpView();
                 } else {
                     addHeadsUpView();
@@ -341,6 +348,20 @@
         }};
 
     @Override
+    public void setZenMode(int mode) {
+        super.setZenMode(mode);
+        if (mModeIcon == null) return;
+        if (!isDeviceProvisioned()) return;
+        final boolean limited = mode == Settings.Global.ZEN_MODE_LIMITED;
+        final boolean full = mode == Settings.Global.ZEN_MODE_FULL;
+        mModeIcon.setVisibility(full || limited ? View.VISIBLE : View.GONE);
+        final int icon = limited ? R.drawable.stat_sys_zen_limited : R.drawable.stat_sys_zen_full;
+        if (full || limited) {
+            mModeIcon.setImageResource(icon);
+        }
+    }
+
+    @Override
     public void start() {
         mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
@@ -352,11 +373,15 @@
 
         // Lastly, call to the icon policy to install/update all the icons.
         mIconPolicy = new PhoneStatusBarPolicy(mContext);
+        mSettingsObserver.onChange(false); // set up
 
         mHeadsUpObserver.onChange(true); // set up
         if (ENABLE_HEADS_UP) {
             mContext.getContentResolver().registerContentObserver(
-                    Settings.Global.getUriFor(SETTING_HEADS_UP), true,
+                    Settings.Global.getUriFor(Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED), true,
+                    mHeadsUpObserver);
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
                     mHeadsUpObserver);
         }
     }
@@ -455,6 +480,7 @@
         mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
         mMoreIcon = mStatusBarView.findViewById(R.id.moreIcon);
         mNotificationIcons.setOverflowIndicator(mMoreIcon);
+        mModeIcon = (ImageView)mStatusBarView.findViewById(R.id.modeIcon);
         mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
         mTickerView = mStatusBarView.findViewById(R.id.ticker);
 
@@ -514,7 +540,6 @@
         mScrollView.setVerticalScrollBarEnabled(false); // less drawing during pulldowns
         if (!mNotificationPanelIsFullScreenWidth) {
             mScrollView.setSystemUiVisibility(
-                    View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER |
                     View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS |
                     View.STATUS_BAR_DISABLE_CLOCK);
         }
@@ -534,7 +559,10 @@
         mBatteryController = new BatteryController(mContext);
         mNetworkController = new NetworkController(mContext);
         mBluetoothController = new BluetoothController(mContext);
-        mRotationLockController = new RotationLockController(mContext);
+        if (mContext.getResources().getBoolean(R.bool.config_showRotationLock)
+                || QuickSettings.DEBUG_GONE_TILES) {
+            mRotationLockController = new RotationLockController(mContext);
+        }
         final SignalClusterView signalCluster =
                 (SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
 
@@ -618,7 +646,7 @@
                 mQS = new QuickSettings(mContext, mSettingsContainer);
                 if (!mNotificationPanelIsFullScreenWidth) {
                     mSettingsContainer.setSystemUiVisibility(
-                            View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
+                            View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS
                             | View.STATUS_BAR_DISABLE_SYSTEM_INFO);
                 }
                 if (mSettingsPanel != null) {
@@ -853,7 +881,6 @@
                 PixelFormat.TRANSLUCENT);
         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_HeadsUp;
@@ -907,40 +934,43 @@
         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();
+        if (!shouldIntercept(notification.getNotification())) {
+            if (mUseHeadsUp && shouldInterrupt(notification)) {
+                if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
+                Entry interruptionCandidate = new Entry(key, notification, null);
+                ViewGroup holder = mHeadsUpNotificationView.getHolder();
+                if (inflateViewsForHeadsUp(interruptionCandidate, holder)) {
+                    mInterruptingNotificationTime = System.currentTimeMillis();
+                    mInterruptingNotificationEntry = interruptionCandidate;
+                    shadeEntry.setInterruption();
 
-                // 1. Populate mHeadsUpNotificationView
-                mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
+                    // 1. Populate mHeadsUpNotificationView
+                    mHeadsUpNotificationView.setNotification(mInterruptingNotificationEntry);
 
-                // 2. Animate mHeadsUpNotificationView in
-                mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
+                    // 2. Animate mHeadsUpNotificationView in
+                    mHandler.sendEmptyMessage(MSG_SHOW_HEADS_UP);
 
-                // 3. Set alarm to age the notification off
-                resetHeadsUpDecayTimer();
-            }
-        } else if (notification.getNotification().fullScreenIntent != null) {
-            // Stop screensaver if the notification has a full-screen intent.
-            // (like an incoming phone call)
-            awakenDreams();
+                    // 3. Set alarm to age the notification off
+                    resetHeadsUpDecayTimer();
+                }
+            } 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) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
-            try {
-                notification.getNotification().fullScreenIntent.send();
-            } catch (PendingIntent.CanceledException e) {
-            }
-        } else {
-            // usual case: status bar visible & not immersive
+                // not immersive & a full-screen alert should be shown
+                if (DEBUG) Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
+                try {
+                    notification.getNotification().fullScreenIntent.send();
+                } catch (PendingIntent.CanceledException e) {
+                }
+            } else {
+                // usual case: status bar visible & not immersive
 
-            // show the ticker if there isn't already a heads up
-            if (mInterruptingNotificationEntry == null) {
-                tick(null, notification, true);
+                // show the ticker if there isn't already a heads up
+                if (mInterruptingNotificationEntry == null) {
+                    tick(null, notification, true);
+                }
             }
         }
         addNotificationViews(shadeEntry);
@@ -1027,8 +1057,18 @@
         for (int i=0; i<N; i++) {
             Entry ent = mNotificationData.get(N-i-1);
             if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
-            if (!notificationIsForCurrentUser(ent.notification)) continue;
-            toShow.add(ent.row);
+
+            // TODO How do we want to badge notifcations from related users.
+            if (!notificationIsForCurrentOrRelatedUser(ent.notification)) continue;
+
+            final int vis = ent.notification.getNotification().visibility;
+            if (vis != Notification.VISIBILITY_SECRET) {
+                // when isLockscreenPublicMode() we show the public form of VISIBILITY_PRIVATE notifications
+                ent.row.setShowingPublic(isLockscreenPublicMode()
+                        && vis == Notification.VISIBILITY_PRIVATE
+                        && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId()));
+                toShow.add(ent.row);
+            }
         }
 
         ArrayList<View> toRemove = new ArrayList<View>();
@@ -1078,7 +1118,17 @@
             Entry ent = mNotificationData.get(N-i-1);
             if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
                     || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
-            if (!notificationIsForCurrentUser(ent.notification)) continue;
+            if (!notificationIsForCurrentOrRelatedUser(ent.notification)) continue;
+            if (isLockscreenPublicMode()
+                    && ent.notification.getNotification().visibility
+                            == Notification.VISIBILITY_SECRET
+                    && !userAllowsPrivateNotificationsInPublic(ent.notification.getUserId())) {
+                // in "public" mode (atop a secure keyguard), secret notifs are totally hidden
+                continue;
+            }
+            if (shouldIntercept(ent.notification.getNotification())) {
+                continue;
+            }
             toShow.add(ent.icon);
         }
 
@@ -1240,8 +1290,8 @@
         flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "ALERTS" : "alerts");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) ? "* " : " ");
-        flagdbg.append(((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "TICKER" : "ticker");
-        flagdbg.append(((diff  & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) ? "* " : " ");
+        flagdbg.append(((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "PRIVATE" : "private");
+        flagdbg.append(((diff  & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "SYSTEM_INFO" : "system_info");
         flagdbg.append(((diff  & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) ? "* " : " ");
         flagdbg.append(((state & StatusBarManager.DISABLE_BACK) != 0) ? "BACK" : "back");
@@ -1326,10 +1376,15 @@
                     .setDuration(175)
                     .start();
             }
-        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
-            if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
-                haltTicker();
+        } else if ((diff & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
+            if ((state & StatusBarManager.DISABLE_PRIVATE_NOTIFICATIONS) != 0) {
+                // we are outside a secure keyguard, so we need to switch to "public" mode
+                setLockscreenPublicMode(true);
+            } else {
+                // user has authenticated the device; full notifications may be shown
+                setLockscreenPublicMode(false);
             }
+            updateNotificationIcons();
         }
     }
 
@@ -1429,6 +1484,7 @@
     }
 
     private void releaseFocus() {
+        if (mStatusBarWindow == null) return;
         WindowManager.LayoutParams lp =
                 (WindowManager.LayoutParams) mStatusBarWindow.getLayoutParams();
         lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
@@ -1460,8 +1516,10 @@
             mHandler.sendEmptyMessage(MSG_CLOSE_SEARCH_PANEL);
         }
 
-        mStatusBarWindow.cancelExpandHelper();
-        mStatusBarView.collapseAllPanels(true);
+        if (mStatusBarWindow != null) {
+            mStatusBarWindow.cancelExpandHelper();
+            mStatusBarView.collapseAllPanels(true);
+        }
     }
 
     public ViewPropertyAnimator setVisibilityWhenDone(
@@ -1670,7 +1728,7 @@
         if (SPEW) Log.d(TAG, "makeExpandedInvisible: mExpandedVisible=" + mExpandedVisible
                 + " mExpandedVisible=" + mExpandedVisible);
 
-        if (!mExpandedVisible) {
+        if (!mExpandedVisible || mStatusBarWindow == null) {
             return;
         }
 
@@ -1893,7 +1951,7 @@
             }
             if (sbModeChanged || nbModeChanged) {
                 // update transient bar autohide
-                if (sbMode == MODE_SEMI_TRANSPARENT || nbMode == MODE_SEMI_TRANSPARENT) {
+                if (mStatusBarMode == MODE_SEMI_TRANSPARENT || mNavigationBarMode == MODE_SEMI_TRANSPARENT) {
                     scheduleAutohide();
                 } else {
                     cancelAutohide();
@@ -2067,13 +2125,14 @@
         if (!isDeviceProvisioned()) return;
 
         // not for you
-        if (!notificationIsForCurrentUser(n)) return;
+        if (!notificationIsForCurrentOrRelatedUser(n)) 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 (n.getNotification().tickerText != null && mStatusBarWindow.getWindowToken() != null) {
+        if (n.getNotification().tickerText != null && mStatusBarWindow != null
+                && mStatusBarWindow.getWindowToken() != null) {
             if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS
                             | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) {
                 mTicker.addEntry(n);
@@ -2157,6 +2216,12 @@
         pw.println(windowStateToString(mStatusBarWindowState));
         pw.print("  mStatusBarMode=");
         pw.println(BarTransitions.modeToString(mStatusBarMode));
+        pw.print("  mZenMode=");
+        pw.println(Settings.Global.zenModeToString(mZenMode));
+        pw.print("  mUseHeadsUp=");
+        pw.println(mUseHeadsUp);
+        pw.print("  interrupting package: ");
+        pw.println(hunStateToString(mInterruptingNotificationEntry));
         dumpBarTransitions(pw, "mStatusBarView", mStatusBarView.getBarTransitions());
         if (mNavigationBarView != null) {
             pw.print("  mNavigationBarWindowState=");
@@ -2231,6 +2296,12 @@
         mNetworkController.dump(fd, pw, args);
     }
 
+    private String hunStateToString(Entry entry) {
+        if (entry == null) return "null";
+        if (entry.notification == null) return "corrupt";
+        return entry.notification.getPackageName();
+    }
+
     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()));
@@ -2371,7 +2442,7 @@
                                 }
                                 try {
                                     mPile.setViewRemoval(true);
-                                    mBarService.onClearAllNotifications();
+                                    mBarService.onClearAllNotifications(mCurrentUserId);
                                 } catch (Exception ex) { }
                             }
                         };
@@ -2549,7 +2620,8 @@
                 mBarService.onNotificationClear(
                         mInterruptingNotificationEntry.notification.getPackageName(),
                         mInterruptingNotificationEntry.notification.getTag(),
-                        mInterruptingNotificationEntry.notification.getId());
+                        mInterruptingNotificationEntry.notification.getId(),
+                        mInterruptingNotificationEntry.notification.getUserId());
             } catch (android.os.RemoteException ex) {
                 // oh well
             }
@@ -2651,7 +2723,7 @@
     void vibrate() {
         android.os.Vibrator vib = (android.os.Vibrator)mContext.getSystemService(
                 Context.VIBRATOR_SERVICE);
-        vib.vibrate(250);
+        vib.vibrate(250, AudioManager.STREAM_SYSTEM);
     }
 
     Runnable mStartTracing = new Runnable() {
@@ -2684,6 +2756,12 @@
                 || (mDisabled & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
+    public void startSettingsActivity(String action) {
+        if (mQS != null) {
+            mQS.startSettingsActivity(action);
+        }
+    }
+
     private static class FastColorDrawable extends Drawable {
         private final int mColor;
 
@@ -2723,9 +2801,11 @@
         super.destroy();
         if (mStatusBarWindow != null) {
             mWindowManager.removeViewImmediate(mStatusBarWindow);
+            mStatusBarWindow = null;
         }
         if (mNavigationBarView != null) {
             mWindowManager.removeViewImmediate(mNavigationBarView);
+            mNavigationBarView = null;
         }
         mContext.unregisterReceiver(mBroadcastReceiver);
     }
@@ -2766,6 +2846,15 @@
         if (mNetworkController != null && (modeChange || command.equals(COMMAND_NETWORK))) {
             mNetworkController.dispatchDemoCommand(command, args);
         }
+        if (modeChange || command.equals(COMMAND_NOTIFICATIONS)) {
+            View notifications = mStatusBarView == null ? null
+                    : mStatusBarView.findViewById(R.id.notification_icon_area);
+            if (notifications != null) {
+                String visible = args.getString("visible");
+                int vis = mDemoMode && "false".equals(visible) ? View.INVISIBLE : View.VISIBLE;
+                notifications.setVisibility(vis);
+            }
+        }
         if (command.equals(COMMAND_BARS)) {
             String mode = args.getString("mode");
             int barMode = "opaque".equals(mode) ? MODE_OPAQUE :
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 d0e9a99..d9e3fdf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -170,7 +170,7 @@
         mBar.makeExpandedInvisibleSoon();
         mFadingPanel = null;
         mLastFullyOpenedPanel = null;
-        if (mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
+        if (mScrimColor != 0 && ActivityManager.isHighEndGfx() && mBar.mStatusBarWindow != null) {
             mBar.mStatusBarWindow.setBackgroundColor(0);
         }
     }
@@ -214,7 +214,8 @@
             Log.v(TAG, "panelExpansionChanged: f=" + frac);
         }
 
-        if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
+        if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()
+                && mBar.mStatusBarWindow != null) {
             if (mShouldFade) {
                 frac = mPanelExpandedFractionSum; // don't judge me
                 // let's start this 20% of the way down the screen
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 e7b8fa1..8170b5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -25,6 +25,7 @@
 import android.bluetooth.BluetoothAdapter;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.DialogInterface.OnClickListener;
@@ -51,13 +52,16 @@
 import android.provider.ContactsContract.Profile;
 import android.provider.Settings;
 import android.security.KeyChain;
+import android.text.TextUtils.TruncateAt;
 import android.util.Log;
 import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
@@ -84,6 +88,7 @@
     static final boolean DEBUG_GONE_TILES = false;
     private static final String TAG = "QuickSettings";
     public static final boolean SHOW_IME_TILE = false;
+    public static final boolean SHOW_ACCESSIBILITY_TILES = true;
 
     public static final boolean LONG_PRESS_TOGGLES = true;
 
@@ -174,7 +179,9 @@
         bluetoothController.addStateChangedCallback(mModel);
         batteryController.addStateChangedCallback(mModel);
         locationController.addSettingsChangedCallback(mModel);
-        rotationLockController.addRotationLockControllerCallback(mModel);
+        if (rotationLockController != null) {
+            rotationLockController.addRotationLockControllerCallback(mModel);
+        }
     }
 
     private void queryForSslCaCerts() {
@@ -274,7 +281,7 @@
         mTilesSetUp = true;
     }
 
-    private void startSettingsActivity(String action) {
+    public void startSettingsActivity(String action) {
         Intent intent = new Intent(action);
         startSettingsActivity(intent);
     }
@@ -308,7 +315,7 @@
             public void onClick(View v) {
                 collapsePanels();
                 final UserManager um = UserManager.get(mContext);
-                if (um.getUsers(true).size() > 1) {
+                if (um.isUserSwitcherEnabled()) {
                     // Since keyguard and systemui were merged into the same process to save
                     // memory, they share the same Looper and graphics context.  As a result,
                     // there's no way to allow concurrent animation while keyguard inflates.
@@ -374,6 +381,35 @@
                 new QuickSettingsModel.BasicRefreshCallback(settingsTile));
         parent.addView(settingsTile);
         mDynamicSpannedTiles.add(settingsTile);
+
+        if (SHOW_ACCESSIBILITY_TILES) {
+            // Color inversion tile
+            final SystemSettingTile inversionTile = new SystemSettingTile(mContext);
+            inversionTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
+                    SystemSettingTile.TYPE_SECURE);
+            inversionTile.setFragment("Settings$AccessibilityInversionSettingsActivity");
+            mModel.addInversionTile(inversionTile, inversionTile.getRefreshCallback());
+            parent.addView(inversionTile);
+            mDynamicSpannedTiles.add(inversionTile);
+
+            // Contrast enhancement tile
+            final SystemSettingTile contrastTile = new SystemSettingTile(mContext);
+            contrastTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED,
+                    SystemSettingTile.TYPE_SECURE);
+            contrastTile.setFragment("Settings$AccessibilityContrastSettingsActivity");
+            mModel.addContrastTile(contrastTile, contrastTile.getRefreshCallback());
+            parent.addView(contrastTile);
+            mDynamicSpannedTiles.add(contrastTile);
+
+            // Color space adjustment tile
+            final SystemSettingTile colorSpaceTile = new SystemSettingTile(mContext);
+            colorSpaceTile.setUri(Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
+                    SystemSettingTile.TYPE_SECURE);
+            colorSpaceTile.setFragment("Settings$AccessibilityDaltonizerSettingsActivity");
+            mModel.addColorSpaceTile(colorSpaceTile, colorSpaceTile.getRefreshCallback());
+            parent.addView(colorSpaceTile);
+            mDynamicSpannedTiles.add(colorSpaceTile);
+        }
     }
 
     private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
@@ -472,8 +508,7 @@
         }
 
         // Rotation Lock
-        if (mContext.getResources().getBoolean(R.bool.quick_settings_show_rotation_lock)
-                || DEBUG_GONE_TILES) {
+        if (mRotationLockController != null) {
             final QuickSettingsBasicTile rotationLockTile
                     = new QuickSettingsBasicTile(mContext);
             rotationLockTile.setOnClickListener(new View.OnClickListener() {
@@ -554,6 +589,31 @@
         });
         parent.addView(airplaneTile);
 
+        // Zen Mode
+        final QuickSettingsBasicTile zenModeTile = new QuickSettingsBasicTile(mContext);
+        zenModeTile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showZenModeDialog();
+            }
+        });
+        mModel.addZenModeTile(zenModeTile, new QuickSettingsModel.RefreshCallback() {
+            @Override
+            public void refreshView(QuickSettingsTileView unused, State state) {
+                zenModeTile.setImageResource(state.iconId);
+                // TODO cut new assets
+                zenModeTile.getImageView().setAlpha(state.enabled ? 1 : .2f);
+                zenModeTile.getImageView().setScaleX(1.5f);
+                zenModeTile.getImageView().setScaleY(1.5f);
+                // for landscape version
+                zenModeTile.getTextView().setMaxLines(2);
+                zenModeTile.getTextView().setEllipsize(TruncateAt.END);
+                // TODO content description
+                zenModeTile.setText(state.label);
+            }
+        });
+        parent.addView(zenModeTile);
+
         // Bluetooth
         if (mModel.deviceSupportsBluetooth()
                 || DEBUG_GONE_TILES) {
@@ -832,6 +892,31 @@
         dialog.show();
     }
 
+    private void showZenModeDialog() {
+        final Dialog d = new Dialog(mContext);
+        d.requestWindowFeature(Window.FEATURE_NO_TITLE);
+        d.setCancelable(true);
+        d.setCanceledOnTouchOutside(true);
+        final ZenModeView v = new ZenModeView(mContext);
+        v.setAdapter(new ZenModeViewAdapter(mContext) {
+            @Override
+            public void configure() {
+                if (mStatusBarService != null) {
+                    mStatusBarService.startSettingsActivity(Settings.ACTION_ZEN_MODE_SETTINGS);
+                }
+                d.dismiss();
+            }
+            @Override
+            public void close() {
+                d.dismiss();
+            }
+        });
+        d.setContentView(v);
+        d.create();
+        d.getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        d.show();
+    }
+
     private void applyBluetoothStatus() {
         mModel.onBluetoothStateChange(mBluetoothState);
     }
@@ -918,4 +1003,108 @@
             }
         }
     }
+
+    /**
+     * Quick Setting tile that represents a secure setting. This type of tile
+     * can toggle a URI within Settings.Secure on click and launch a Settings
+     * fragment on long-click.
+     */
+    public class SystemSettingTile extends QuickSettingsBasicTile {
+        private static final int TYPE_GLOBAL = 0;
+        private static final int TYPE_SECURE = 1;
+        private static final int TYPE_SYSTEM = 2;
+
+        private final QuickSettingsModel.BasicRefreshCallback mRefreshCallback;
+
+        private String mFragment;
+        private String mName;
+        private int mType;
+
+        public SystemSettingTile(Context context) {
+            super(context);
+
+            mRefreshCallback = new QuickSettingsModel.BasicRefreshCallback(this);
+            mRefreshCallback.setShowWhenEnabled(true);
+        }
+
+        @Override
+        public boolean performLongClick() {
+            if (mFragment != null) {
+                collapsePanels();
+
+                final Intent intent = new Intent();
+                intent.setComponent(new ComponentName(
+                        "com.android.settings", "com.android.settings." + mFragment));
+                startSettingsActivity(intent);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean performClick() {
+            if (mName != null) {
+                collapsePanels();
+
+                final ContentResolver cr = mContext.getContentResolver();
+                switch (mType) {
+                    case TYPE_GLOBAL: {
+                        final boolean enable = Settings.Global.getInt(cr, mName, 0) == 0;
+                        Settings.Global.putInt(cr, mName, enable ? 1 : 0);
+                    } break;
+                    case TYPE_SECURE: {
+                        final boolean enable = Settings.Secure.getIntForUser(
+                                cr, mName, 0, UserHandle.USER_CURRENT) == 0;
+                        Settings.Secure.putIntForUser(
+                                cr, mName, enable ? 1 : 0, UserHandle.USER_CURRENT);
+                    } break;
+                    case TYPE_SYSTEM: {
+                        final boolean enable = Settings.System.getIntForUser(
+                                cr, mName, 0, UserHandle.USER_CURRENT) == 0;
+                        Settings.System.putIntForUser(
+                                cr, mName, enable ? 1 : 0, UserHandle.USER_CURRENT);
+                    } break;
+                }
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Specifies the fragment within the com.android.settings package to
+         * launch when this tile is long-clicked.
+         *
+         * @param fragment a fragment name within the com.android.settings
+         *            package
+         */
+        public void setFragment(String fragment) {
+            mFragment = fragment;
+            setLongClickable(fragment != null);
+        }
+
+        /**
+         * Specifies the setting name and type to toggle when this tile is
+         * clicked.
+         *
+         * @param name a setting name
+         * @param type the type of setting, one of:
+         *            <ul>
+         *            <li>{@link #TYPE_GLOBAL}
+         *            <li>{@link #TYPE_SECURE}
+         *            <li>{@link #TYPE_SYSTEM}
+         *            </ul>
+         */
+        public void setUri(String name, int type) {
+            mName = name;
+            mType = type;
+            setClickable(mName != null);
+        }
+
+        /**
+         * @return the refresh callback for this tile
+         */
+        public QuickSettingsModel.BasicRefreshCallback getRefreshCallback() {
+            return mRefreshCallback;
+        }
+    }
 }
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 42201c5..c3c281c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -24,6 +24,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.drawable.Drawable;
@@ -37,6 +38,7 @@
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.WindowManager;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
@@ -91,6 +93,19 @@
     static class BrightnessState extends State {
         boolean autoBrightness;
     }
+    static class InversionState extends State {
+        boolean toggled;
+        int type;
+    }
+    static class ContrastState extends State {
+        boolean toggled;
+        float contrast;
+        float brightness;
+    }
+    static class ColorSpaceState extends State {
+        boolean toggled;
+        int type;
+    }
     public static class BluetoothState extends State {
         boolean connected = false;
         String stateContentDescription;
@@ -98,6 +113,9 @@
     public static class RotationLockState extends State {
         boolean visible = false;
     }
+    public static class ZenModeState extends State {
+        int zenMode = Settings.Global.ZEN_MODE_OFF;
+    }
 
     /** The callback to update a given tile. */
     interface RefreshCallback {
@@ -199,6 +217,106 @@
         }
     }
 
+    /** ContentObserver to watch display inversion */
+    private class DisplayInversionObserver extends ContentObserver {
+        public DisplayInversionObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onInversionChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION),
+                    false, this, mUserTracker.getCurrentUserId());
+        }
+    }
+
+    /** ContentObserver to watch display contrast */
+    private class DisplayContrastObserver extends ContentObserver {
+        public DisplayContrastObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onContrastChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS),
+                    false, this, mUserTracker.getCurrentUserId());
+        }
+    }
+
+    /** ContentObserver to watch display color space adjustment */
+    private class DisplayColorSpaceObserver extends ContentObserver {
+        public DisplayColorSpaceObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onColorSpaceChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED),
+                    false, this, mUserTracker.getCurrentUserId());
+            cr.registerContentObserver(Settings.Secure.getUriFor(
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER),
+                    false, this, mUserTracker.getCurrentUserId());
+        }
+    }
+
+    /** ContentObserver to watch display color space adjustment */
+    private class ZenModeObserver extends ContentObserver {
+        public ZenModeObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onZenModeChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false, this);
+        }
+    }
+
     /** Callback for changes to remote display routes. */
     private class RemoteDisplayRouteCallback extends MediaRouter.SimpleCallback {
         @Override
@@ -229,6 +347,10 @@
     private final NextAlarmObserver mNextAlarmObserver;
     private final BugreportObserver mBugreportObserver;
     private final BrightnessObserver mBrightnessObserver;
+    private final DisplayInversionObserver mInversionObserver;
+    private final DisplayContrastObserver mContrastObserver;
+    private final DisplayColorSpaceObserver mColorSpaceObserver;
+    private final ZenModeObserver mZenModeObserver;
 
     private final MediaRouter mMediaRouter;
     private final RemoteDisplayRouteCallback mRemoteDisplayRouteCallback;
@@ -251,6 +373,10 @@
     private RefreshCallback mAirplaneModeCallback;
     private State mAirplaneModeState = new State();
 
+    private QuickSettingsTileView mZenModeTile;
+    private RefreshCallback mZenModeCallback;
+    private ZenModeState mZenModeState = new ZenModeState();
+
     private QuickSettingsTileView mWifiTile;
     private RefreshCallback mWifiCallback;
     private WifiState mWifiState = new WifiState();
@@ -287,6 +413,18 @@
     private RefreshCallback mBrightnessCallback;
     private BrightnessState mBrightnessState = new BrightnessState();
 
+    private QuickSettingsTileView mInversionTile;
+    private RefreshCallback mInversionCallback;
+    private InversionState mInversionState = new InversionState();
+
+    private QuickSettingsTileView mContrastTile;
+    private RefreshCallback mContrastCallback;
+    private ContrastState mContrastState = new ContrastState();
+
+    private QuickSettingsTileView mColorSpaceTile;
+    private RefreshCallback mColorSpaceCallback;
+    private ColorSpaceState mColorSpaceState = new ColorSpaceState();
+
     private QuickSettingsTileView mBugreportTile;
     private RefreshCallback mBugreportCallback;
     private State mBugreportState = new State();
@@ -300,6 +438,7 @@
     private State mSslCaCertWarningState = new State();
 
     private RotationLockController mRotationLockController;
+    private int mRotationLockedLabel;
 
     public QuickSettingsModel(Context context) {
         mContext = context;
@@ -308,8 +447,14 @@
             @Override
             public void onUserSwitched(int newUserId) {
                 mBrightnessObserver.startObserving();
+                mInversionObserver.startObserving();
+                mContrastObserver.startObserving();
+                mColorSpaceObserver.startObserving();
                 refreshRotationLockTile();
                 onBrightnessLevelChanged();
+                onInversionChanged();
+                onContrastChanged();
+                onColorSpaceChanged();
                 onNextAlarmChanged();
                 onBugreportChanged();
                 rebindMediaRouterAsCurrentUser();
@@ -322,6 +467,14 @@
         mBugreportObserver.startObserving();
         mBrightnessObserver = new BrightnessObserver(mHandler);
         mBrightnessObserver.startObserving();
+        mInversionObserver = new DisplayInversionObserver(mHandler);
+        mInversionObserver.startObserving();
+        mContrastObserver = new DisplayContrastObserver(mHandler);
+        mContrastObserver.startObserving();
+        mColorSpaceObserver = new DisplayColorSpaceObserver(mHandler);
+        mColorSpaceObserver.startObserving();
+        mZenModeObserver = new ZenModeObserver(mHandler);
+        mZenModeObserver.startObserving();
 
         mMediaRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
         rebindMediaRouterAsCurrentUser();
@@ -444,6 +597,30 @@
         mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
     }
 
+    // Zen Mode
+    void addZenModeTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mZenModeTile = view;
+        mZenModeCallback = cb;
+        onZenModeChanged();
+    }
+    private void onZenModeChanged() {
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+        mZenModeState.enabled = mode != Settings.Global.ZEN_MODE_OFF;
+        mZenModeState.zenMode = mode;
+        if (mode == Settings.Global.ZEN_MODE_FULL) {
+            mZenModeState.iconId = R.drawable.stat_sys_zen_full;
+            mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_FULL);
+        } else if (mode == Settings.Global.ZEN_MODE_LIMITED) {
+            mZenModeState.iconId = R.drawable.stat_sys_zen_limited;
+            mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED);
+        } else {
+            mZenModeState.iconId = R.drawable.stat_sys_zen_limited;
+            mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED);
+        }
+        mZenModeCallback.refreshView(mZenModeTile, mZenModeState);
+    }
+
     // Wifi
     void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) {
         mWifiTile = view;
@@ -659,7 +836,6 @@
     void addRemoteDisplayTile(QuickSettingsTileView view, RefreshCallback cb) {
         mRemoteDisplayTile = view;
         mRemoteDisplayCallback = cb;
-        final int[] count = new int[1];
         mRemoteDisplayTile.setOnPrepareListener(new QuickSettingsTileView.OnPrepareListener() {
             @Override
             public void onPrepare() {
@@ -798,6 +974,12 @@
         mRotationLockTile = view;
         mRotationLockCallback = cb;
         mRotationLockController = rotationLockController;
+        final int lockOrientation = mRotationLockController.getRotationLockOrientation();
+        mRotationLockedLabel = lockOrientation == Configuration.ORIENTATION_PORTRAIT
+                    ? R.string.quick_settings_rotation_locked_portrait_label
+                    : lockOrientation == Configuration.ORIENTATION_LANDSCAPE
+                    ? R.string.quick_settings_rotation_locked_landscape_label
+                    : R.string.quick_settings_rotation_locked_label;
         onRotationLockChanged();
     }
     void onRotationLockChanged() {
@@ -812,7 +994,7 @@
                 ? R.drawable.ic_qs_rotation_locked
                 : R.drawable.ic_qs_auto_rotate;
         mRotationLockState.label = rotationLocked
-                ? mContext.getString(R.string.quick_settings_rotation_locked_label)
+                ? mContext.getString(mRotationLockedLabel)
                 : mContext.getString(R.string.quick_settings_rotation_unlocked_label);
         mRotationLockCallback.refreshView(mRotationLockTile, mRotationLockState);
     }
@@ -847,6 +1029,90 @@
         onBrightnessLevelChanged();
     }
 
+    // Color inversion
+    void addInversionTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mInversionTile = view;
+        mInversionCallback = cb;
+        onInversionChanged();
+    }
+    public void onInversionChanged() {
+        final Resources res = mContext.getResources();
+        final ContentResolver cr = mContext.getContentResolver();
+        final int currentUserId = mUserTracker.getCurrentUserId();
+        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_QUICK_SETTING_ENABLED, 0,
+                currentUserId) == 1;
+        final boolean enabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, currentUserId) == 1;
+        final int type = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION, 0, currentUserId);
+        mInversionState.enabled = quickSettingEnabled;
+        mInversionState.toggled = enabled;
+        mInversionState.type = type;
+        // TODO: Add real icon assets.
+        mInversionState.iconId = enabled ? R.drawable.ic_qs_inversion_on
+                : R.drawable.ic_qs_inversion_off;
+        mInversionState.label = res.getString(R.string.quick_settings_inversion_label);
+        mInversionCallback.refreshView(mInversionTile, mInversionState);
+    }
+
+    // Contrast enhancement
+    void addContrastTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mContrastTile = view;
+        mContrastCallback = cb;
+        onContrastChanged();
+    }
+    public void onContrastChanged() {
+        final Resources res = mContext.getResources();
+        final ContentResolver cr = mContext.getContentResolver();
+        final int currentUserId = mUserTracker.getCurrentUserId();
+        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_QUICK_SETTING_ENABLED, 0,
+                currentUserId) == 1;
+        final boolean enabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, currentUserId) == 1;
+        final float contrast = Settings.Secure.getFloatForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, 1, currentUserId);
+        final float brightness = Settings.Secure.getFloatForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, 0, currentUserId);
+        mContrastState.enabled = quickSettingEnabled;
+        mContrastState.toggled = enabled;
+        mContrastState.contrast = contrast;
+        mContrastState.brightness = brightness;
+        // TODO: Add real icon assets.
+        mContrastState.iconId = enabled ? R.drawable.ic_qs_contrast_on
+                : R.drawable.ic_qs_contrast_off;
+        mContrastState.label = res.getString(R.string.quick_settings_contrast_label);
+        mContrastCallback.refreshView(mContrastTile, mContrastState);
+    }
+
+    // Color space adjustment
+    void addColorSpaceTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mColorSpaceTile = view;
+        mColorSpaceCallback = cb;
+        onColorSpaceChanged();
+    }
+    public void onColorSpaceChanged() {
+        final Resources res = mContext.getResources();
+        final ContentResolver cr = mContext.getContentResolver();
+        final int currentUserId = mUserTracker.getCurrentUserId();
+        final boolean quickSettingEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_QUICK_SETTING_ENABLED, 0,
+                currentUserId) == 1;
+        final boolean enabled = Settings.Secure.getIntForUser(cr,
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, currentUserId) == 1;
+        final int type = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, 0, currentUserId);
+        mColorSpaceState.enabled = quickSettingEnabled;
+        mColorSpaceState.toggled = enabled;
+        mColorSpaceState.type = type;
+        // TODO: Add real icon assets.
+        mColorSpaceState.iconId = enabled ? R.drawable.ic_qs_color_space_on
+                : R.drawable.ic_qs_color_space_off;
+        mColorSpaceState.label = res.getString(R.string.quick_settings_color_space_label);
+        mColorSpaceCallback.refreshView(mColorSpaceTile, mColorSpaceState);
+    }
+
     // SSL CA Cert warning.
     public void addSslCaCertWarningTile(QuickSettingsTileView view, RefreshCallback cb) {
         mSslCaCertWarningTile = view;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsScrollView.java
index 8a2f8d6..175805a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsScrollView.java
@@ -42,7 +42,7 @@
         if (getChildCount() > 0) {
             View child = getChildAt(0);
             scrollRange = Math.max(0,
-                    child.getHeight() - (getHeight() - mPaddingBottom - mPaddingTop));
+                    child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop()));
         }
         return scrollRange;
     }
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 4901823..7b03195 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -60,7 +60,7 @@
         mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
         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 = new ExpandHelper(getContext(), latestItems, minHeight, maxHeight);
         mExpandHelper.setEventSource(this);
         mExpandHelper.setScrollView(mScrollView);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
new file mode 100644
index 0000000..d1c7a41
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Typeface;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.PathShape;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
+import android.text.method.LinkMovementMethod;
+import android.text.style.URLSpan;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.ZenModeView.Adapter.ExitCondition;
+
+public class ZenModeView extends RelativeLayout {
+    private static final String TAG = ZenModeView.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private static final Typeface CONDENSED =
+            Typeface.create("sans-serif-condensed", Typeface.NORMAL);
+    private static final int GRAY = 0xff999999; //TextAppearance.StatusBar.Expanded.Network
+    private static final int BACKGROUND = 0xff282828;
+    private static final long DURATION = new ValueAnimator().getDuration();
+    private static final long BOUNCE_DURATION = DURATION / 3;
+    private static final float BOUNCE_SCALE = 0.8f;
+    private static final float SETTINGS_ALPHA = 0.6f;
+
+    private static final String FULL_TEXT =
+            "You won't hear any calls, alarms or timers.";
+
+    private final Context mContext;
+    private final Paint mPathPaint;
+    private final ImageView mSettingsButton;
+    private final ModeSpinner mModeSpinner;
+    private final TextView mActionButton;
+    private final View mDivider;
+    private final UntilPager mUntilPager;
+    private final AlarmWarning mAlarmWarning;
+
+    private Adapter mAdapter;
+
+    public ZenModeView(Context context) {
+        this(context, null);
+    }
+
+    public ZenModeView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        if (DEBUG) log("new %s()", getClass().getSimpleName());
+        mContext = context;
+
+        final int iconSize = mContext.getResources()
+                .getDimensionPixelSize(com.android.internal.R.dimen.notification_large_icon_width);
+        final int topRowSize = iconSize * 2 / 3;
+        final int p = topRowSize / 7;
+
+        mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPathPaint.setStyle(Paint.Style.STROKE);
+        mPathPaint.setColor(GRAY);
+        mPathPaint.setStrokeWidth(p / 2);
+
+        mSettingsButton = new ImageView(mContext);
+        mSettingsButton.setPadding(p, p, p, p);
+        mSettingsButton.setImageResource(R.drawable.ic_notify_settings_normal);
+        LayoutParams lp = new LayoutParams(topRowSize, topRowSize);
+        lp.topMargin = p;
+        lp.leftMargin = p;
+        addView(mSettingsButton, lp);
+        mSettingsButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (mAdapter != null && mAdapter.getMode() == Adapter.MODE_LIMITED) {
+                    mAdapter.configure();
+                }
+                bounce(mSettingsButton, null);
+            }
+        });
+
+        mModeSpinner = new ModeSpinner(mContext);
+        mModeSpinner.setId(android.R.id.title);
+        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize);
+        lp.topMargin = p;
+        lp.addRule(CENTER_HORIZONTAL);
+        addView(mModeSpinner, lp);
+
+        mActionButton = new TextView(mContext);
+        mActionButton.setTextColor(GRAY);
+        mActionButton.setTypeface(CONDENSED);
+        mActionButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mActionButton.getTextSize() * 1.2f);
+        mActionButton.setAllCaps(true);
+        mActionButton.setGravity(Gravity.CENTER);
+        mActionButton.setPadding(p, 0, p * 2, 0);
+        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize);
+        lp.topMargin = p;
+        lp.addRule(ALIGN_PARENT_RIGHT);
+        lp.addRule(ALIGN_BASELINE, mModeSpinner.getId());
+        addView(mActionButton, lp);
+        mActionButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                bounce(v, null);
+                beginOrEnd();
+            }
+        });
+
+        mDivider = new View(mContext);
+        mDivider.setId(android.R.id.empty);
+        mDivider.setBackgroundColor(GRAY);
+        lp = new LayoutParams(LayoutParams.MATCH_PARENT, 2);
+        lp.addRule(BELOW, mModeSpinner.getId());
+        lp.topMargin = p;
+        lp.bottomMargin = p;
+        addView(mDivider, lp);
+
+        mUntilPager = new UntilPager(mContext, mPathPaint, iconSize * 3 / 4);
+        mUntilPager.setId(android.R.id.tabhost);
+        lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+        lp.addRule(BELOW, mDivider.getId());
+        addView(mUntilPager, lp);
+
+        mAlarmWarning = new AlarmWarning(mContext);
+        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+        lp.addRule(CENTER_HORIZONTAL);
+        lp.addRule(BELOW, mUntilPager.getId());
+        lp.bottomMargin = p;
+        addView(mAlarmWarning, lp);
+    }
+
+    private void beginOrEnd() {
+        if (mAdapter == null) return;
+        if (mAdapter.getMode() == mAdapter.getCommittedMode()) {
+            // end
+            mAdapter.setCommittedMode(Adapter.MODE_OFF);
+        } else {
+            // begin
+            mAdapter.setCommittedMode(mAdapter.getMode());
+        }
+        mAdapter.close();
+    }
+
+    public void setAdapter(Adapter adapter) {
+        mAdapter = adapter;
+        mAdapter.setCallbacks(new Adapter.Callbacks() {
+            @Override
+            public void onChanged() {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        updateState(true);
+                    }
+                });
+            }
+        });
+        updateState(false);
+    }
+
+    private void updateState(boolean animate) {
+        mModeSpinner.updateState();
+        mUntilPager.updateState();
+        mAlarmWarning.updateState(animate);
+        final float settingsAlpha = isFull() ? 0 : SETTINGS_ALPHA;
+        if (settingsAlpha != mSettingsButton.getAlpha()) {
+            if (animate) {
+                mSettingsButton.animate().alpha(settingsAlpha).start();
+            } else {
+                mSettingsButton.setAlpha(settingsAlpha);
+            }
+        }
+        final boolean committed = mAdapter != null
+                && mAdapter.getMode() == mAdapter.getCommittedMode();
+        mActionButton.setText(committed ? "End" : "Begin");
+    }
+
+    private boolean isFull() {
+        return mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (DEBUG) log("onMeasure %s %s",
+                MeasureSpec.toString(widthMeasureSpec), MeasureSpec.toString(heightMeasureSpec));
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (!isFull()) {
+            final LayoutParams lp = (LayoutParams) mModeSpinner.getLayoutParams();
+            final int mh = vh(mModeSpinner) + vh(mDivider) + vh(mUntilPager) + lp.topMargin;
+            setMeasuredDimension(getMeasuredWidth(), mh);
+        }
+    }
+
+    private int vh(View v) {
+        LayoutParams lp = (LayoutParams) v.getLayoutParams();
+        return v.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
+    }
+
+    private static void log(String msg, Object... args) {
+        Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
+    }
+
+    private static ShapeDrawable sd(Path p, int size, Paint pt) {
+        final ShapeDrawable sd = new ShapeDrawable(new PathShape(p, size, size));
+        sd.getPaint().set(pt);
+        sd.setIntrinsicHeight(size);
+        sd.setIntrinsicWidth(size);
+        return sd;
+    }
+
+    private static void bounce(final View v, final Runnable midBounce) {
+        v.animate().scaleX(BOUNCE_SCALE).scaleY(BOUNCE_SCALE).setDuration(DURATION / 3)
+            .setListener(new AnimatorListenerAdapter() {
+                private boolean mFired;
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (!mFired) {
+                        mFired = true;
+                        if (midBounce != null) {
+                            midBounce.run();
+                        }
+                        v.animate().scaleX(1).scaleY(1).setListener(null).start();
+                    }
+                }
+            }).start();
+    }
+
+    public static String modeToString(int mode) {
+        if (mode == Adapter.MODE_OFF) return "MODE_OFF";
+        if (mode == Adapter.MODE_LIMITED) return "MODE_LIMITED";
+        if (mode == Adapter.MODE_FULL) return "MODE_FULL";
+        throw new IllegalArgumentException("Invalid mode: " + mode);
+    }
+
+    public static String modeToLabel(int mode) {
+        if (mode == Adapter.MODE_LIMITED) return "Limited interruptions";
+        if (mode == Adapter.MODE_FULL) return "Zero interruptions";
+        throw new UnsupportedOperationException("Unsupported mode: " + mode);
+    }
+
+    private final class UntilPager extends RelativeLayout {
+        private final ImageView mPrev;
+        private final ImageView mNext;
+        private final TextView mText1;
+        private final TextView mText2;
+
+        private TextView mText;
+
+        public UntilPager(Context context, Paint pathPaint, int iconSize) {
+            super(context);
+            mText1 = new TextView(mContext);
+            mText1.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize() * 1.2f);
+            mText1.setTypeface(CONDENSED);
+            mText1.setTextColor(GRAY);
+            mText1.setGravity(Gravity.CENTER);
+            LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, iconSize);
+            addView(mText1, lp);
+            mText = mText1;
+
+            mText2 = new TextView(mContext);
+            mText2.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize());
+            mText2.setTypeface(CONDENSED);
+            mText2.setTextColor(GRAY);
+            mText2.setAlpha(0);
+            mText2.setGravity(Gravity.CENTER);
+            addView(mText2, lp);
+
+            lp = new LayoutParams(iconSize, iconSize);
+            final View v = new View(mContext);
+            v.setBackgroundColor(BACKGROUND);
+            addView(v, lp);
+            mPrev = new ImageView(mContext);
+            mPrev.setId(android.R.id.button1);
+            mPrev.setImageDrawable(sd(prevPath(iconSize), iconSize, pathPaint));
+            addView(mPrev, lp);
+            mPrev.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onNav(v, -1);
+                }
+            });
+
+            lp = new LayoutParams(iconSize, iconSize);
+            lp.addRule(ALIGN_PARENT_RIGHT);
+            final View v2 = new View(mContext);
+            v2.setBackgroundColor(BACKGROUND);
+            addView(v2, lp);
+            mNext = new ImageView(mContext);
+            mNext.setId(android.R.id.button2);
+            mNext.setImageDrawable(sd(nextPath(iconSize), iconSize, pathPaint));
+            addView(mNext, lp);
+            mNext.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    onNav(v, 1);
+                }
+            });
+
+            updateState();
+        }
+
+        private void onNav(View v, int d) {
+            bounce(v, null);
+            if (mAdapter == null) {
+                return;
+            }
+            if (mAdapter.getExitConditionCount() == 1) {
+                horBounce(d);
+                return;
+            }
+            final int w = getWidth();
+            final float s = Math.signum(d);
+            final TextView current = mText;
+            final TextView other = mText == mText1 ? mText2 : mText1;
+            final ExitCondition ec = mAdapter.getExitCondition(d);
+            setText(other, ec);
+            other.setTranslationX(-s * w);
+            other.animate().translationX(0).alpha(1).setDuration(DURATION).start();
+            current.animate().translationX(s * w).alpha(0).setDuration(DURATION).start();
+            mText = other;
+            mAdapter.select(ec);
+        }
+
+        private void horBounce(int d) {
+            final int w = getWidth();
+            mText.animate()
+                    .setDuration(BOUNCE_DURATION)
+                    .translationX(Math.signum(d) * w / 20)
+                    .setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            mText.animate().translationX(0).setListener(null).start();
+                        }
+                    }).start();
+        }
+
+        private void setText(final TextView textView, final ExitCondition ec) {
+            SpannableStringBuilder ss = new SpannableStringBuilder(ec.summary);
+            if (ec.action != null) {
+                ss.setSpan(new CustomLinkSpan() {
+                    @Override
+                    public void onClick() {
+                        // TODO wire up links
+                        Toast.makeText(mContext, ec.action, Toast.LENGTH_SHORT).show();
+                    }
+                }, 0, ss.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+                textView.setMovementMethod(LinkMovementMethod.getInstance());
+            } else {
+                textView.setMovementMethod(null);
+            }
+            textView.setText(ss);
+        }
+
+        private void updateState() {
+            if (mAdapter == null) {
+                return;
+            }
+            setText(mText, mAdapter.getExitCondition(0));
+        }
+
+        private Path prevPath(int size) {
+            final int hp = size * 3 / 8;
+            final int vp = size / 4;
+            final Path p = new Path();
+            p.moveTo(size - hp, vp);
+            p.lineTo(hp, size / 2);
+            p.lineTo(size - hp, size - vp);
+            return p;
+        }
+
+        private Path nextPath(int size) {
+            final int hp = size * 3 / 8;
+            final int vp = size / 4;
+            Path p = new Path();
+            p.moveTo(hp, vp);
+            p.lineTo(size - hp, size / 2);
+            p.lineTo(hp, size - vp);
+            return p;
+        }
+    }
+
+    private abstract static class CustomLinkSpan extends URLSpan {
+        abstract public void onClick();
+
+        public CustomLinkSpan() {
+            super("#");
+        }
+
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            super.updateDrawState(ds);
+            ds.setUnderlineText(false);
+            ds.bgColor = BACKGROUND;
+        }
+
+        @Override
+        public void onClick(View widget) {
+            onClick();
+        }
+    }
+
+    public interface Adapter {
+        public static final int MODE_OFF = 0;
+        public static final int MODE_LIMITED = 1;
+        public static final int MODE_FULL = 2;
+
+        void configure();
+        void close();
+        int getMode();
+        void setMode(int mode);
+        int getCommittedMode();
+        void setCommittedMode(int mode);
+        void select(ExitCondition ec);
+        void init();
+        void setCallbacks(Callbacks callbacks);
+        ExitCondition getExitCondition(int d);
+        int getExitConditionCount();
+
+        public static class ExitCondition {
+            public String summary;
+            public String line1;
+            public String line2;
+            public String action;
+        }
+
+        public interface Callbacks {
+            void onChanged();
+        }
+    }
+
+    private final class ModeSpinner extends Spinner {
+        public ModeSpinner(final Context context) {
+            super(context);
+            setBackgroundResource(R.drawable.spinner_default_holo_dark_am_no_underline);
+            final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(mContext, 0) {
+                @Override
+                public View getView(int position, View convertView,  ViewGroup parent) {
+                    if (DEBUG) log("getView %s parent=%s", position, parent);
+                    return getDropDownView(position, convertView, parent);
+                }
+
+                @Override
+                public View getDropDownView(final int position, View convertView, ViewGroup parent) {
+                    if (DEBUG) log("getDropDownView %s cv=%s parent=%s",
+                            position, convertView, parent);
+                    final TextView tv = convertView != null ? (TextView) convertView
+                            : new TextView(context);
+                    final int mode = getItem(position);
+                    tv.setText(modeToLabel(mode));
+                    final boolean inDropdown = parent instanceof ListView;
+                    if (convertView == null) {
+                        if (DEBUG) log(" setting up view");
+                        tv.setTextColor(GRAY);
+                        tv.setTypeface(CONDENSED);
+                        tv.setAllCaps(true);
+                        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.2f);
+                        final int p = (int) tv.getTextSize() / 2;
+                        if (inDropdown) {
+                            tv.setPadding(p, p, 0, p);
+                        } else {
+                            tv.setGravity(Gravity.CENTER_HORIZONTAL);
+                            tv.setPadding(p, 0, 0, 0);
+                        }
+                    }
+                    tv.setOnTouchListener(new OnTouchListener(){
+                        @Override
+                        public boolean onTouch(View v, MotionEvent event) {
+                            if (DEBUG) log("onTouch %s %s inDropdown=%s", tv.getText(),
+                                    MotionEvent.actionToString(event.getAction()), inDropdown);
+                            if (inDropdown && mAdapter != null) {
+                                mAdapter.setMode(mode);
+                            }
+                            return false;
+                        }
+                    });
+                    return tv;
+                }
+            };
+            adapter.add(Adapter.MODE_LIMITED);
+            adapter.add(Adapter.MODE_FULL);
+            setAdapter(adapter);
+        }
+
+        public void updateState() {
+            int mode = mAdapter != null ? mAdapter.getMode() : Adapter.MODE_LIMITED;
+            if (mode == Adapter.MODE_OFF) {
+                mode = Adapter.MODE_LIMITED;
+            }
+            if (DEBUG) log("setSelectedMode " + mode);
+            for (int i = 0; i < getAdapter().getCount(); i++) {
+                if (getAdapter().getItem(i).equals(mode)) {
+                    if (DEBUG) log("  setting selection = " + i);
+                    setSelection(i, true);
+                    onDetachedFromWindow();
+                }
+            }
+        }
+    }
+
+    private final class AlarmWarning extends LinearLayout {
+        public AlarmWarning(Context context) {
+            super(context);
+            setOrientation(HORIZONTAL);
+
+            final TextView tv = new TextView(mContext);
+            tv.setTextColor(GRAY);
+            tv.setGravity(Gravity.TOP);
+            tv.setTypeface(CONDENSED);
+            tv.setText(FULL_TEXT);
+            addView(tv);
+
+            final ImageView icon = new ImageView(mContext);
+            icon.setAlpha(.75f);
+            int size = (int)tv.getTextSize();
+            icon.setImageResource(android.R.drawable.ic_dialog_alert);
+            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(size, size);
+            final int p = size / 4;
+            lp.bottomMargin = lp.topMargin = lp.rightMargin = lp.leftMargin = p;
+            addView(icon, 0, lp);
+            setPadding(p, 0, p, p);
+        }
+
+        public void updateState(boolean animate) {
+            final float alpha = isFull() ? 1 : 0;
+            if (alpha == getAlpha()) {
+                return;
+            }
+            if (animate) {
+                animate().alpha(alpha).start();
+            } else {
+                setAlpha(alpha);
+                requestLayout();
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
new file mode 100644
index 0000000..d2067a4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.List;
+
+public abstract class ZenModeViewAdapter implements ZenModeView.Adapter {
+    private static final String TAG = "ZenModeViewAdapter";
+
+    private final Context mContext;
+    private final ContentResolver mResolver;
+    private final Handler mHandler = new Handler();
+    private final SettingsObserver mObserver;
+    private final List<ExitCondition> mExits = Arrays.asList(
+            newExit("Until you turn this off", "Until", "You turn this off"));
+
+    private Callbacks mCallbacks;
+    private int mExitIndex;
+    private int mMode;
+    private int mCommittedMode;
+
+    public ZenModeViewAdapter(Context context) {
+        mContext = context;
+        mResolver = mContext.getContentResolver();
+        mObserver = new SettingsObserver(mHandler);
+        mObserver.init();
+        init();
+    }
+
+    @Override
+    public int getMode() {
+        return mMode;
+    }
+
+    @Override
+    public void setMode(int mode) {
+        if (mode == mMode) return;
+        mMode = mode;
+        dispatchChanged();
+    }
+
+    @Override
+    public int getCommittedMode() {
+        return mCommittedMode;
+    }
+
+    @Override
+    public void setCommittedMode(int mode) {
+        final int v = mode == MODE_LIMITED ? Settings.Global.ZEN_MODE_LIMITED
+                    : mode == MODE_FULL ? Settings.Global.ZEN_MODE_FULL
+                    : Settings.Global.ZEN_MODE_OFF;
+        AsyncTask.execute(new Runnable() {
+            @Override
+            public void run() {
+                Settings.Global.putInt(mContext.getContentResolver(),
+                        Settings.Global.ZEN_MODE, v);
+            }
+        });
+    }
+
+    @Override
+    public void init() {
+        if (mExitIndex != 0) {
+            mExitIndex = 0;
+            dispatchChanged();
+        }
+        final int mode = mCommittedMode == MODE_FULL ? MODE_FULL : MODE_LIMITED;
+        if (mode != mMode) {
+            mMode = mode;
+            dispatchChanged();
+        }
+    }
+
+    private void dispatchChanged() {
+        mHandler.removeCallbacks(mChanged);
+        mHandler.post(mChanged);
+    }
+
+    @Override
+    public void setCallbacks(final Callbacks callbacks) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mCallbacks = callbacks;
+            }
+        });
+    }
+
+    @Override
+    public ExitCondition getExitCondition(int d) {
+        final int n = mExits.size();
+        final int i = (n + (mExitIndex + (int)Math.signum(d))) % n;
+        return mExits.get(i);
+    }
+
+    @Override
+    public int getExitConditionCount() {
+        return mExits.size();
+    }
+
+    @Override
+    public void select(ExitCondition ec) {
+        final int i = mExits.indexOf(ec);
+        if (i == -1 || i == mExitIndex) {
+            return;
+        }
+        mExitIndex = i;
+        dispatchChanged();
+    }
+
+    private static ExitCondition newExit(String summary, String line1, String line2) {
+        final ExitCondition rt = new ExitCondition();
+        rt.summary = summary;
+        rt.line1 = line1;
+        rt.line2 = line2;
+        return rt;
+    }
+
+    private final Runnable mChanged = new Runnable() {
+        public void run() {
+            if (mCallbacks == null) {
+                return;
+            }
+            try {
+                mCallbacks.onChanged();
+            } catch (Throwable t) {
+                Log.w(TAG, "Error dispatching onChanged to " + mCallbacks, t);
+            }
+        }
+    };
+
+    private final class SettingsObserver extends ContentObserver {
+        public SettingsObserver(Handler handler) {
+            super(handler);
+        }
+
+        public void init() {
+            loadSettings();
+            mResolver.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
+                    false, this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            loadSettings();
+            mChanged.run();  // already on handler
+        }
+
+        private void loadSettings() {
+            mCommittedMode = getModeFromSetting();
+        }
+
+        private int getModeFromSetting() {
+            final int v = Settings.Global.getInt(mResolver,
+                    Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+            if (v == Settings.Global.ZEN_MODE_LIMITED) return MODE_LIMITED;
+            if (v == Settings.Global.ZEN_MODE_FULL) return MODE_FULL;
+            return MODE_OFF;
+        }
+    }
+}
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 b7f3cfe..cadb44a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -21,9 +21,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewParent;
 import android.widget.TextView;
 
 import com.android.systemui.R;
@@ -73,7 +70,7 @@
         filter.addAction(Intent.ACTION_TIME_CHANGED);
         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
         filter.addAction(Intent.ACTION_LOCALE_CHANGED);
-        mContext.registerReceiver(mIntentReceiver, filter, null, null);
+        getContext().registerReceiver(mIntentReceiver, filter, null, null);
 
         updateClock();
     }
@@ -83,7 +80,7 @@
         super.onDetachedFromWindow();
 
         mDateFormat = null; // reload the locale next time
-        mContext.unregisterReceiver(mIntentReceiver);
+        getContext().unregisterReceiver(mIntentReceiver);
     }
 
     protected void updateClock() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index f1fda78..79932a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.app.Notification;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
@@ -27,9 +26,9 @@
 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.Gefingerpoken;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.statusbar.BaseStatusBar;
@@ -44,13 +43,13 @@
 
     private final int mTouchSensitivityDelay;
     private SwipeHelper mSwipeHelper;
+    private EdgeSwipeHelper mEdgeSwipeHelper;
 
     private BaseStatusBar mBar;
     private ExpandHelper mExpandHelper;
-    private long mStartTouchTime;
 
+    private long mStartTouchTime;
     private ViewGroup mContentHolder;
-    private ViewGroup mContentSlider;
 
     private NotificationData.Entry mHeadsUp;
 
@@ -74,18 +73,24 @@
 
     public boolean setNotification(NotificationData.Entry headsUp) {
         mHeadsUp = headsUp;
-        mHeadsUp.row.setExpanded(false);
-        if (mContentHolder == null) {
-            // too soon!
-            return false;
+        if (mContentHolder != null) {
+            mContentHolder.removeAllViews();
         }
-        mContentHolder.setX(0);
-        mContentHolder.setVisibility(View.VISIBLE);
-        mContentHolder.setAlpha(1f);
-        mContentHolder.removeAllViews();
-        mContentHolder.addView(mHeadsUp.row);
-        mSwipeHelper.snapChild(mContentSlider, 1f);
-        mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+
+        if (mHeadsUp != null) {
+            mHeadsUp.row.setExpanded(true);
+            mHeadsUp.row.setShowingPublic(false);
+            if (mContentHolder == null) {
+                // too soon!
+                return false;
+            }
+            mContentHolder.setX(0);
+            mContentHolder.setVisibility(View.VISIBLE);
+            mContentHolder.setAlpha(1f);
+            mContentHolder.addView(mHeadsUp.row);
+            mSwipeHelper.snapChild(mContentHolder, 1f);
+            mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
+        }
         return true;
     }
 
@@ -95,10 +100,11 @@
 
     public void setMargin(int notificationPanelMarginPx) {
         if (SPEW) Log.v(TAG, "setMargin() " + notificationPanelMarginPx);
-        if (mContentSlider != null) {
-            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentSlider.getLayoutParams();
+        if (mContentHolder != null &&
+                mContentHolder.getLayoutParams() instanceof FrameLayout.LayoutParams) {
+            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentHolder.getLayoutParams();
             lp.setMarginStart(notificationPanelMarginPx);
-            mContentSlider.setLayoutParams(lp);
+            mContentHolder.setLayoutParams(lp);
         }
     }
 
@@ -123,15 +129,17 @@
     @Override
     public void onAttachedToWindow() {
         float densityScale = getResources().getDisplayMetrics().density;
-        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
+        final ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext());
+        float pagingTouchSlop = viewConfiguration.getScaledPagingTouchSlop();
+        float touchSlop = viewConfiguration.getScaledTouchSlop();
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+        mEdgeSwipeHelper = new EdgeSwipeHelper(touchSlop);
 
         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);
+        mExpandHelper = new ExpandHelper(getContext(), 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!
@@ -145,7 +153,8 @@
         if (System.currentTimeMillis() < mStartTouchTime) {
             return true;
         }
-        return mSwipeHelper.onInterceptTouchEvent(ev)
+        return mEdgeSwipeHelper.onInterceptTouchEvent(ev)
+                || mSwipeHelper.onInterceptTouchEvent(ev)
                 || mExpandHelper.onInterceptTouchEvent(ev)
                 || super.onInterceptTouchEvent(ev);
     }
@@ -158,7 +167,8 @@
             return false;
         }
         mBar.resetHeadsUpDecayTimer();
-        return mSwipeHelper.onTouchEvent(ev)
+        return mEdgeSwipeHelper.onTouchEvent(ev)
+                || mSwipeHelper.onTouchEvent(ev)
                 || mExpandHelper.onTouchEvent(ev)
                 || super.onTouchEvent(ev);
     }
@@ -227,11 +237,65 @@
 
     @Override
     public View getChildAtPosition(MotionEvent ev) {
-        return mContentSlider;
+        return mContentHolder;
     }
 
     @Override
     public View getChildContentView(View v) {
-        return mContentSlider;
+        return mContentHolder;
+    }
+
+    private class EdgeSwipeHelper implements Gefingerpoken {
+        private static final boolean DEBUG_EDGE_SWIPE = false;
+        private final float mTouchSlop;
+        private boolean mConsuming;
+        private float mFirstY;
+        private float mFirstX;
+
+        public EdgeSwipeHelper(float touchSlop) {
+            mTouchSlop = touchSlop;
+        }
+
+        @Override
+        public boolean onInterceptTouchEvent(MotionEvent ev) {
+            switch (ev.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN:
+                    if (DEBUG_EDGE_SWIPE) Log.d(TAG, "action down " + ev.getY());
+                    mFirstX = ev.getX();
+                    mFirstY = ev.getY();
+                    mConsuming = false;
+                    break;
+
+                case MotionEvent.ACTION_MOVE:
+                    if (DEBUG_EDGE_SWIPE) Log.d(TAG, "action move " + ev.getY());
+                    final float dY = ev.getY() - mFirstY;
+                    final float daX = Math.abs(ev.getX() - mFirstX);
+                    final float daY = Math.abs(dY);
+                    if (!mConsuming && (4f * daX) < daY && daY > mTouchSlop) {
+                        if (dY > 0) {
+                            if (DEBUG_EDGE_SWIPE) Log.d(TAG, "found an open");
+                            mBar.animateExpandNotificationsPanel();
+                        }
+                        if (dY < 0) {
+                            if (DEBUG_EDGE_SWIPE) Log.d(TAG, "found a close");
+                            mBar.onHeadsUpDismissed();
+                        }
+                        mConsuming = true;
+                    }
+                    break;
+
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL:
+                    if (DEBUG_EDGE_SWIPE) Log.d(TAG, "action done" );
+                    mConsuming = false;
+                    break;
+            }
+            return mConsuming;
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent ev) {
+            return mConsuming;
+        }
     }
 }
\ No newline at end of file
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 312bba3..f5ee95b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationController.java
@@ -24,7 +24,6 @@
 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;
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 259422d..266cecf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -33,7 +33,6 @@
 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;
 
@@ -94,7 +93,7 @@
         }
 
         float densityScale = getResources().getDisplayMetrics().density;
-        float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
         mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
     }
 
@@ -219,7 +218,7 @@
         super.onConfigurationChanged(newConfig);
         float densityScale = getResources().getDisplayMetrics().density;
         mSwipeHelper.setDensityScale(densityScale);
-        float pagingTouchSlop = ViewConfiguration.get(mContext).getScaledPagingTouchSlop();
+        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
         mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java
index 6f61ec8..98d205a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RotationLockController.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.policy;
 
 import android.content.Context;
+import android.content.res.Configuration;
 import android.os.UserHandle;
 
 import com.android.internal.view.RotationPolicy;
@@ -42,42 +43,32 @@
 
     public RotationLockController(Context context) {
         mContext = context;
-        notifyChanged();
-        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
-            RotationPolicy.registerRotationPolicyListener(mContext,
-                    mRotationPolicyListener, UserHandle.USER_ALL);
-        }
+        RotationPolicy.registerRotationPolicyListener(mContext,
+                mRotationPolicyListener, UserHandle.USER_ALL);
     }
 
     public void addRotationLockControllerCallback(RotationLockControllerCallback callback) {
         mCallbacks.add(callback);
     }
 
+    public int getRotationLockOrientation() {
+        return RotationPolicy.getRotationLockOrientation(mContext);
+    }
+
     public boolean isRotationLocked() {
-        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
-            return RotationPolicy.isRotationLocked(mContext);
-        }
-        return false;
+        return RotationPolicy.isRotationLocked(mContext);
     }
 
     public void setRotationLocked(boolean locked) {
-        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
-            RotationPolicy.setRotationLock(mContext, locked);
-        }
+        RotationPolicy.setRotationLock(mContext, locked);
     }
 
     public boolean isRotationLockAffordanceVisible() {
-        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
-            return RotationPolicy.isRotationLockToggleVisible(mContext);
-        }
-        return false;
+        return RotationPolicy.isRotationLockToggleVisible(mContext);
     }
 
     public void release() {
-        if (RotationPolicy.isRotationLockToggleSupported(mContext)) {
-            RotationPolicy.unregisterRotationPolicyListener(mContext,
-                    mRotationPolicyListener);
-        }
+        RotationPolicy.unregisterRotationPolicyListener(mContext, mRotationPolicyListener);
     }
 
     private void notifyChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 2c36ab7..0adb32f 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -311,6 +311,8 @@
             }
 
             mUsbStorageNotification.setLatestEventInfo(mContext, title, message, pi);
+            mUsbStorageNotification.visibility = Notification.VISIBILITY_PUBLIC;
+
             final boolean adbOn = 1 == Settings.Global.getInt(
                 mContext.getContentResolver(),
                 Settings.Global.ADB_ENABLED,
@@ -401,6 +403,7 @@
 
             mMediaStorageNotification.icon = icon;
             mMediaStorageNotification.setLatestEventInfo(mContext, title, message, pi);
+            mMediaStorageNotification.visibility = Notification.VISIBILITY_PUBLIC;
         }
 
         final int notificationId = mMediaStorageNotification.icon;
diff --git a/packages/VpnDialogs/res/values-am/strings.xml b/packages/VpnDialogs/res/values-am/strings.xml
index 7fc9897..a305e30 100644
--- a/packages/VpnDialogs/res/values-am/strings.xml
+++ b/packages/VpnDialogs/res/values-am/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-ar/strings.xml b/packages/VpnDialogs/res/values-ar/strings.xml
index 2380fa2..bf83a41 100644
--- a/packages/VpnDialogs/res/values-ar/strings.xml
+++ b/packages/VpnDialogs/res/values-ar/strings.xml
@@ -16,10 +16,10 @@
 
 <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="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="legacy_title" msgid="192936250066580964">"‏VPN متصلة"</string>
     <string name="configure" msgid="4905518375574791375">"تهيئة"</string>
     <string name="disconnect" msgid="971412338304200056">"قطع الاتصال"</string>
     <string name="session" msgid="6470628549473641030">"الجلسة"</string>
diff --git a/packages/VpnDialogs/res/values-az-rAZ/strings.xml b/packages/VpnDialogs/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..fdeb06f
--- /dev/null
+++ b/packages/VpnDialogs/res/values-az-rAZ/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">"VPN bağlantısı yaratmaq üçün <xliff:g id="APP">%s</xliff:g> cəhdləri."</string>
+    <string name="warning" msgid="5470743576660160079">"Bunu həyata keçirməklə, siz tətbiqə bütün şəbəkə hərəkətinə qarışmağa icazə verirsiniz. "<b>" Tətbiqə güvənmirsizsə qəbul etməyin. "</b>" Əks halda, datanızın təhlükəli proqramlar tərəfindən ələ keçirilmə riskini alırsınız."</string>
+    <string name="accept" msgid="2889226408765810173">"Bu tətbiqə güvənirəm."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN qoşuludur"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiqurasiya edin"</string>
+    <string name="disconnect" msgid="971412338304200056">"Əlaqəni kəs"</string>
+    <string name="session" msgid="6470628549473641030">"Sessiya:"</string>
+    <string name="duration" msgid="3584782459928719435">"Müddət:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Göndərilən:"</string>
+    <string name="data_received" msgid="4062776929376067820">"Qəbul edilən:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-az/strings.xml b/packages/VpnDialogs/res/values-az/strings.xml
new file mode 100644
index 0000000..fdeb06f
--- /dev/null
+++ b/packages/VpnDialogs/res/values-az/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">"VPN bağlantısı yaratmaq üçün <xliff:g id="APP">%s</xliff:g> cəhdləri."</string>
+    <string name="warning" msgid="5470743576660160079">"Bunu həyata keçirməklə, siz tətbiqə bütün şəbəkə hərəkətinə qarışmağa icazə verirsiniz. "<b>" Tətbiqə güvənmirsizsə qəbul etməyin. "</b>" Əks halda, datanızın təhlükəli proqramlar tərəfindən ələ keçirilmə riskini alırsınız."</string>
+    <string name="accept" msgid="2889226408765810173">"Bu tətbiqə güvənirəm."</string>
+    <string name="legacy_title" msgid="192936250066580964">"VPN qoşuludur"</string>
+    <string name="configure" msgid="4905518375574791375">"Konfiqurasiya edin"</string>
+    <string name="disconnect" msgid="971412338304200056">"Əlaqəni kəs"</string>
+    <string name="session" msgid="6470628549473641030">"Sessiya:"</string>
+    <string name="duration" msgid="3584782459928719435">"Müddət:"</string>
+    <string name="data_transmitted" msgid="7988167672982199061">"Göndərilən:"</string>
+    <string name="data_received" msgid="4062776929376067820">"Qəbul edilən:"</string>
+    <string name="data_value_format" msgid="2192466557826897580">"<xliff:g id="NUMBER_0">%1$s</xliff:g> bayt / <xliff:g id="NUMBER_1">%2$s</xliff:g> paket"</string>
+</resources>
diff --git a/packages/VpnDialogs/res/values-be/strings.xml b/packages/VpnDialogs/res/values-be/strings.xml
deleted file mode 100644
index af43aef..0000000
--- a/packages/VpnDialogs/res/values-be/strings.xml
+++ /dev/null
@@ -1,30 +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.
- -->
-
-<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-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/strings.xml b/packages/VpnDialogs/res/values-et-rEE/strings.xml
similarity index 100%
rename from packages/VpnDialogs/res/values-et/strings.xml
rename to packages/VpnDialogs/res/values-et-rEE/strings.xml
diff --git a/packages/VpnDialogs/res/values-fa/strings.xml b/packages/VpnDialogs/res/values-fa/strings.xml
index ec163af..7c0aafe 100644
--- a/packages/VpnDialogs/res/values-fa/strings.xml
+++ b/packages/VpnDialogs/res/values-fa/strings.xml
@@ -16,10 +16,10 @@
 
 <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="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="legacy_title" msgid="192936250066580964">"‏VPN متصل است"</string>
     <string name="configure" msgid="4905518375574791375">"پیکربندی"</string>
     <string name="disconnect" msgid="971412338304200056">"قطع اتصال"</string>
     <string name="session" msgid="6470628549473641030">"جلسه:"</string>
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..b570a6d 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-iw/strings.xml b/packages/VpnDialogs/res/values-iw/strings.xml
index bb845ee..335f5e4 100644
--- a/packages/VpnDialogs/res/values-iw/strings.xml
+++ b/packages/VpnDialogs/res/values-iw/strings.xml
@@ -16,10 +16,10 @@
 
 <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="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>
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/strings.xml b/packages/VpnDialogs/res/values-ms-rMY/strings.xml
similarity index 100%
rename from packages/VpnDialogs/res/values-ms/strings.xml
rename to packages/VpnDialogs/res/values-ms-rMY/strings.xml
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-ne-rNP/strings.xml b/packages/VpnDialogs/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..03211cb
--- /dev/null
+++ b/packages/VpnDialogs/res/values-ne-rNP/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-ne/strings.xml b/packages/VpnDialogs/res/values-ne/strings.xml
new file mode 100644
index 0000000..03211cb
--- /dev/null
+++ b/packages/VpnDialogs/res/values-ne/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-si-rLK/strings.xml b/packages/VpnDialogs/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..67e0ed6
--- /dev/null
+++ b/packages/VpnDialogs/res/values-si-rLK/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">"VPN සම්බන්ධතාවයක් සැදීමට <xliff:g id="APP">%s</xliff:g> උත්සාහ කරයි."</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-si/strings.xml b/packages/VpnDialogs/res/values-si/strings.xml
new file mode 100644
index 0000000..67e0ed6
--- /dev/null
+++ b/packages/VpnDialogs/res/values-si/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">"VPN සම්බන්ධතාවයක් සැදීමට <xliff:g id="APP">%s</xliff:g> උත්සාහ කරයි."</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-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/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
index 6faf4e0..ddafc66 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.net.IConnectivityManager;
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index 3d5654a..eb20995 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.net.IConnectivityManager;
@@ -28,9 +27,6 @@
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.View;
-import android.widget.Button;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
 import android.widget.TextView;
 
 import com.android.internal.app.AlertActivity;
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
index f00362b..0531cba 100644
--- a/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/exif/ExifModifier.java
@@ -18,7 +18,6 @@
 
 import android.util.Log;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
diff --git a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
index 305e905..5b07477 100644
--- a/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
+++ b/packages/WallpaperCropper/src/com/android/gallery3d/glrenderer/GLCanvas.java
@@ -20,8 +20,6 @@
 import android.graphics.Rect;
 import android.graphics.RectF;
 
-import javax.microedition.khronos.opengles.GL11;
-
 //
 // GLCanvas gives a convenient interface to draw using OpenGL.
 //
diff --git a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
index 8511de2..764156d 100644
--- a/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
+++ b/packages/WallpaperCropper/src/com/android/photos/BitmapRegionTileSource.java
@@ -24,9 +24,7 @@
 import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
 import android.graphics.Canvas;
-import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.Build;
@@ -247,6 +245,9 @@
             try {
                 ei.readExif(mPath);
                 return true;
+            } catch (NullPointerException e) {
+                Log.w("BitmapRegionTileSource", "reading exif failed", e);
+                return false;
             } catch (IOException e) {
                 Log.w("BitmapRegionTileSource", "getting decoder failed", e);
                 return false;
@@ -313,6 +314,9 @@
             } catch (IOException e) {
                 Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
                 return false;
+            } catch (NullPointerException e) {
+                Log.e("BitmapRegionTileSource", "Failed to read EXIF for URI " + mUri, e);
+                return false;
             } finally {
                 Utils.closeSilently(is);
             }
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index 9c4600942..d6c0c99 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -71,6 +71,8 @@
     public static final int MAX_BMAP_IN_INTENT = 750000;
     private static final float WALLPAPER_SCREENS_SPAN = 2f;
 
+    protected static Point sDefaultWallpaperSize;
+
     protected CropView mCropView;
     protected Uri mUri;
     private View mSetWallpaperButton;
@@ -139,7 +141,21 @@
         final AsyncTask<Void, Void, Void> loadBitmapTask = new AsyncTask<Void, Void, Void>() {
             protected Void doInBackground(Void...args) {
                 if (!isCancelled()) {
-                    bitmapSource.loadInBackground();
+                    try {
+                        bitmapSource.loadInBackground();
+                    } catch (SecurityException securityException) {
+                        if (isDestroyed()) {
+                            // Temporarily granted permissions are revoked when the activity
+                            // finishes, potentially resulting in a SecurityException here.
+                            // Even though {@link #isDestroyed} might also return true in different
+                            // situations where the configuration changes, we are fine with
+                            // catching these cases here as well.
+                            cancel(false);
+                        } else {
+                            // otherwise it had a different cause and we throw it further
+                            throw securityException;
+                        }
+                    }
                 }
                 return null;
             }
@@ -209,32 +225,34 @@
     }
 
     static protected Point getDefaultWallpaperSize(Resources res, WindowManager windowManager) {
-        Point minDims = new Point();
-        Point maxDims = new Point();
-        windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
+        if (sDefaultWallpaperSize == null) {
+            Point minDims = new Point();
+            Point maxDims = new Point();
+            windowManager.getDefaultDisplay().getCurrentSizeRange(minDims, maxDims);
 
-        int maxDim = Math.max(maxDims.x, maxDims.y);
-        int minDim = Math.max(minDims.x, minDims.y);
+            int maxDim = Math.max(maxDims.x, maxDims.y);
+            int minDim = Math.max(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);
-            minDim = Math.min(realSize.x, realSize.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);
+                minDim = Math.min(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;
+            }
+            sDefaultWallpaperSize = new Point(defaultWidth, defaultHeight);
         }
-
-        // 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);
+        return sDefaultWallpaperSize;
     }
 
     public static int getRotationFromExif(String path) {
@@ -272,6 +290,9 @@
             }
         } catch (IOException e) {
             Log.w(LOGTAG, "Getting exif data failed", e);
+        } catch (NullPointerException e) {
+            // Sometimes the ExifInterface has an internal NPE if Exif data isn't valid
+            Log.w(LOGTAG, "Getting exif data failed", e);
         } finally {
             Utils.closeSilently(bis);
             Utils.closeSilently(is);
@@ -286,7 +307,6 @@
         final Point bounds = cropTask.getImageBounds();
         Runnable onEndCrop = new Runnable() {
             public void run() {
-                updateWallpaperDimensions(bounds.x, bounds.y);
                 if (finishActivityWhenDone) {
                     setResult(Activity.RESULT_OK);
                     finish();
@@ -310,9 +330,6 @@
                 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();
@@ -404,7 +421,6 @@
 
         Runnable onEndCrop = new Runnable() {
             public void run() {
-                updateWallpaperDimensions(outWidth, outHeight);
                 if (finishActivityWhenDone) {
                     setResult(Activity.RESULT_OK);
                     finish();
@@ -785,40 +801,6 @@
         }
     }
 
-    protected void updateWallpaperDimensions(int width, int height) {
-        String spKey = getSharedPreferencesKey();
-        SharedPreferences sp = getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
-        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 = getDefaultWallpaperSize(res, windowManager);
-
-        new AsyncTask<Void, Void, Void>() {
-            public Void doInBackground(Void ... args) {
-                // 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);
-                return null;
-            }
-        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
-    }
-
     protected static RectF getMaxCropRect(
             int inWidth, int inHeight, int outWidth, int outHeight, boolean leftAligned) {
         RectF cropRect = new RectF();
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
index 10bcdad..edb1630 100644
--- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
+++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyServer.java
@@ -15,7 +15,6 @@
  */
 package com.android.proxyhandler;
 
-import android.net.ProxyProperties;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -25,7 +24,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
 import java.net.ProxySelector;
diff --git a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
index 109435c..cbea188 100644
--- a/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
+++ b/packages/services/Proxy/src/com/android/proxyhandler/ProxyService.java
@@ -17,12 +17,8 @@
 
 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;
diff --git a/policy/src/com/android/internal/policy/impl/BarController.java b/policy/src/com/android/internal/policy/impl/BarController.java
index 0ce4b12..fc49a569 100644
--- a/policy/src/com/android/internal/policy/impl/BarController.java
+++ b/policy/src/com/android/internal/policy/impl/BarController.java
@@ -108,7 +108,7 @@
         if (mWin != null) {
             if (win != null && (win.getAttrs().privateFlags
                     & WindowManager.LayoutParams.PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR) == 0) {
-                if ((win.getAttrs().flags & mTranslucentWmFlag) != 0) {
+                if ((PolicyControl.getWindowFlags(win, null) & mTranslucentWmFlag) != 0) {
                     vis |= mTranslucentFlag;
                 } else {
                     vis &= ~mTranslucentFlag;
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index 7c0735b..0120a03 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -363,36 +363,38 @@
     }
 
     private void addUsersToMenu(ArrayList<Action> items) {
-        List<UserInfo> users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
-                .getUsers();
-        if (users.size() > 1) {
+        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        if (um.isUserSwitcherEnabled()) {
+            List<UserInfo> users = um.getUsers();
             UserInfo currentUser = getCurrentUser();
             for (final UserInfo user : users) {
-                boolean isCurrentUser = currentUser == null
-                        ? user.id == 0 : (currentUser.id == user.id);
-                Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
-                        : null;
-                SinglePressAction switchToUser = new SinglePressAction(
-                        com.android.internal.R.drawable.ic_menu_cc, icon,
-                        (user.name != null ? user.name : "Primary")
-                        + (isCurrentUser ? " \u2714" : "")) {
-                    public void onPress() {
-                        try {
-                            ActivityManagerNative.getDefault().switchUser(user.id);
-                        } catch (RemoteException re) {
-                            Log.e(TAG, "Couldn't switch user " + re);
+                if (user.supportsSwitchTo()) {
+                    boolean isCurrentUser = currentUser == null
+                            ? user.id == 0 : (currentUser.id == user.id);
+                    Drawable icon = user.iconPath != null ? Drawable.createFromPath(user.iconPath)
+                            : null;
+                    SinglePressAction switchToUser = new SinglePressAction(
+                            com.android.internal.R.drawable.ic_menu_cc, icon,
+                            (user.name != null ? user.name : "Primary")
+                            + (isCurrentUser ? " \u2714" : "")) {
+                        public void onPress() {
+                            try {
+                                ActivityManagerNative.getDefault().switchUser(user.id);
+                            } catch (RemoteException re) {
+                                Log.e(TAG, "Couldn't switch user " + re);
+                            }
                         }
-                    }
 
-                    public boolean showDuringKeyguard() {
-                        return true;
-                    }
+                        public boolean showDuringKeyguard() {
+                            return true;
+                        }
 
-                    public boolean showBeforeProvisioning() {
-                        return false;
-                    }
-                };
-                items.add(switchToUser);
+                        public boolean showBeforeProvisioning() {
+                            return false;
+                        }
+                    };
+                    items.add(switchToUser);
+                }
             }
         }
     }
@@ -591,7 +593,7 @@
                 icon.setImageDrawable(mIcon);
                 icon.setScaleType(ScaleType.CENTER_CROP);
             } else if (mIconResId != 0) {
-                icon.setImageDrawable(context.getResources().getDrawable(mIconResId));
+                icon.setImageDrawable(context.getDrawable(mIconResId));
             }
             if (mMessage != null) {
                 messageView.setText(mMessage);
@@ -681,7 +683,7 @@
 
             boolean on = ((mState == State.On) || (mState == State.TurningOn));
             if (icon != null) {
-                icon.setImageDrawable(context.getResources().getDrawable(
+                icon.setImageDrawable(context.getDrawable(
                         (on ? mEnabledIconResId : mDisabledIconResid)));
                 icon.setEnabled(enabled);
             }
diff --git a/policy/src/com/android/internal/policy/impl/IconUtilities.java b/policy/src/com/android/internal/policy/impl/IconUtilities.java
index a47c904..82f26ad 100644
--- a/policy/src/com/android/internal/policy/impl/IconUtilities.java
+++ b/policy/src/com/android/internal/policy/impl/IconUtilities.java
@@ -24,22 +24,13 @@
 import android.graphics.BlurMaskFilter;
 import android.graphics.Canvas;
 import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.graphics.PaintFlagsDrawFilter;
-import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.graphics.TableMaskFilter;
-import android.graphics.Typeface;
-import android.text.Layout.Alignment;
-import android.text.StaticLayout;
-import android.text.TextPaint;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
 import android.content.res.Resources;
 import android.content.Context;
 
diff --git a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
index b734c41..5602206 100644
--- a/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
+++ b/policy/src/com/android/internal/policy/impl/ImmersiveModeConfirmation.java
@@ -19,6 +19,7 @@
 import android.animation.ArgbEvaluator;
 import android.animation.ValueAnimator;
 import android.app.ActivityManager;
+import android.app.ActivityManagerNative;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -27,12 +28,12 @@
 import android.graphics.drawable.ColorDrawable;
 import android.os.Handler;
 import android.os.Message;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.Slog;
+import android.util.SparseBooleanArray;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
@@ -46,8 +47,6 @@
 
 import com.android.internal.R;
 
-import java.util.Arrays;
-
 /**
  *  Helper to manage showing/hiding a confirmation prompt when the navigation bar is hidden
  *  entering immersive mode.
@@ -56,19 +55,19 @@
     private static final String TAG = "ImmersiveModeConfirmation";
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_SHOW_EVERY_TIME = false; // super annoying, use with caution
+    private static final String CONFIRMED = "confirmed";
 
     private final Context mContext;
     private final H mHandler;
-    private final ArraySet<String> mConfirmedPackages = new ArraySet<String>();
     private final long mShowDelayMs;
     private final long mPanicThresholdMs;
+    private final SparseBooleanArray mUserPanicResets = new SparseBooleanArray();
 
+    private boolean mConfirmed;
     private ClingWindowView mClingWindow;
-    private String mLastPackage;
-    private String mPromptPackage;
     private long mPanicTime;
-    private String mPanicPackage;
     private WindowManager mWindowManager;
+    private int mCurrentUserId;
 
     public ImmersiveModeConfirmation(Context context) {
         mContext = context;
@@ -85,83 +84,84 @@
         return exit != null ? exit.getDuration() : 0;
     }
 
-    public void loadSetting() {
-        if (DEBUG) Slog.d(TAG, "loadSetting()");
-        mConfirmedPackages.clear();
-        String packages = null;
+    public void loadSetting(int currentUserId) {
+        mConfirmed = false;
+        mCurrentUserId = currentUserId;
+        if (DEBUG) Slog.d(TAG, String.format("loadSetting() mCurrentUserId=%d resetForPanic=%s",
+                mCurrentUserId, mUserPanicResets.get(mCurrentUserId, false)));
+        String value = null;
         try {
-            packages = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+            value = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                     Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
                     UserHandle.USER_CURRENT);
-            if (packages != null) {
-                mConfirmedPackages.addAll(Arrays.asList(packages.split(",")));
-                if (DEBUG) Slog.d(TAG, "Loaded mConfirmedPackages=" + mConfirmedPackages);
-            }
+            mConfirmed = CONFIRMED.equals(value);
+            if (DEBUG) Slog.d(TAG, "Loaded mConfirmed=" + mConfirmed);
         } catch (Throwable t) {
-            Slog.w(TAG, "Error loading confirmations, packages=" + packages, t);
+            Slog.w(TAG, "Error loading confirmations, value=" + value, t);
         }
     }
 
     private void saveSetting() {
         if (DEBUG) Slog.d(TAG, "saveSetting()");
         try {
-            final String packages = TextUtils.join(",", mConfirmedPackages);
+            final String value = mConfirmed ? CONFIRMED : null;
             Settings.Secure.putStringForUser(mContext.getContentResolver(),
                     Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
-                    packages,
+                    value,
                     UserHandle.USER_CURRENT);
-            if (DEBUG) Slog.d(TAG, "Saved packages=" + packages);
+            if (DEBUG) Slog.d(TAG, "Saved value=" + value);
         } catch (Throwable t) {
-            Slog.w(TAG, "Error saving confirmations, mConfirmedPackages=" + mConfirmedPackages, t);
+            Slog.w(TAG, "Error saving confirmations, mConfirmed=" + mConfirmed, t);
         }
     }
 
     public void immersiveModeChanged(String pkg, boolean isImmersiveMode) {
-        if (pkg == null) {
-            return;
-        }
         mHandler.removeMessages(H.SHOW);
         if (isImmersiveMode) {
-            mLastPackage = pkg;
-            if (DEBUG_SHOW_EVERY_TIME || !mConfirmedPackages.contains(pkg)) {
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(H.SHOW, pkg), mShowDelayMs);
+            final boolean disabled = PolicyControl.disableImmersiveConfirmation(pkg);
+            if (DEBUG) Slog.d(TAG, String.format("immersiveModeChanged() disabled=%s mConfirmed=%s",
+                    disabled, mConfirmed));
+            if (!disabled && (DEBUG_SHOW_EVERY_TIME || !mConfirmed)) {
+                mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs);
             }
         } else {
-            mLastPackage = null;
             mHandler.sendEmptyMessage(H.HIDE);
         }
     }
 
-    public void onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
-        if (mPanicPackage != null && !isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
+    public boolean onPowerKeyDown(boolean isScreenOn, long time, boolean inImmersiveMode) {
+        if (!isScreenOn && (time - mPanicTime < mPanicThresholdMs)) {
             // turning the screen back on within the panic threshold
-            unconfirmPackage(mPanicPackage);
+            mHandler.sendEmptyMessage(H.PANIC);
+            return mClingWindow == null;
         }
         if (isScreenOn && inImmersiveMode) {
             // turning the screen off, remember if we were in immersive mode
             mPanicTime = time;
-            mPanicPackage = mLastPackage;
         } else {
             mPanicTime = 0;
-            mPanicPackage = null;
         }
+        return false;
     }
 
     public void confirmCurrentPrompt() {
-        mHandler.post(confirmAction(mPromptPackage));
+        if (mClingWindow != null) {
+            if (DEBUG) Slog.d(TAG, "confirmCurrentPrompt()");
+            mHandler.post(mConfirm);
+        }
     }
 
-    private void unconfirmPackage(String pkg) {
-        if (pkg != null) {
-            if (DEBUG) Slog.d(TAG, "Unconfirming immersive mode confirmation for " + pkg);
-            mConfirmedPackages.remove(pkg);
-            saveSetting();
-        }
+    private void handlePanic() {
+        if (DEBUG) Slog.d(TAG, "handlePanic()");
+        if (mUserPanicResets.get(mCurrentUserId, false)) return;  // already reset for panic
+        mUserPanicResets.put(mCurrentUserId, true);
+        mConfirmed = false;
+        saveSetting();
     }
 
     private void handleHide() {
         if (mClingWindow != null) {
-            if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation for " + mPromptPackage);
+            if (DEBUG) Slog.d(TAG, "Hiding immersive mode confirmation");
             mWindowManager.removeView(mClingWindow);
             mClingWindow = null;
         }
@@ -297,11 +297,10 @@
         }
     }
 
-    private void handleShow(String pkg) {
-        mPromptPackage = pkg;
-        if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation for " + pkg);
+    private void handleShow() {
+        if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation");
 
-        mClingWindow = new ClingWindowView(mContext, confirmAction(pkg));
+        mClingWindow = new ClingWindowView(mContext, mConfirm);
 
         // we will be hiding the nav bar, so layout as if it's already hidden
         mClingWindow.setSystemUiVisibility(
@@ -313,33 +312,35 @@
         mWindowManager.addView(mClingWindow, lp);
     }
 
-    private Runnable confirmAction(final String pkg) {
-        return new Runnable() {
-            @Override
-            public void run() {
-                if (pkg != null && !mConfirmedPackages.contains(pkg)) {
-                    if (DEBUG) Slog.d(TAG, "Confirming immersive mode for " + pkg);
-                    mConfirmedPackages.add(pkg);
-                    saveSetting();
-                }
-                handleHide();
+    private final Runnable mConfirm = new Runnable() {
+        @Override
+        public void run() {
+            if (DEBUG) Slog.d(TAG, "mConfirm.run()");
+            if (!mConfirmed) {
+                mConfirmed = true;
+                saveSetting();
             }
-        };
-    }
+            handleHide();
+        }
+    };
 
     private final class H extends Handler {
-        private static final int SHOW = 0;
-        private static final int HIDE = 1;
+        private static final int SHOW = 1;
+        private static final int HIDE = 2;
+        private static final int PANIC = 3;
 
         @Override
         public void handleMessage(Message msg) {
             switch(msg.what) {
                 case SHOW:
-                    handleShow((String)msg.obj);
+                    handleShow();
                     break;
                 case HIDE:
                     handleHide();
                     break;
+                case PANIC:
+                    handlePanic();
+                    break;
             }
         }
     }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
index 968976b..df6fca4c 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneLayoutInflater.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.policy.impl;
 
-import java.util.Map;
-
 import android.content.Context;
 import android.util.AttributeSet;
 import android.view.View;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 7c047c3..977c2e7 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,15 @@
 import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
 import static android.view.WindowManager.LayoutParams.*;
 
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.app.ActivityOptions;
+import android.transition.Scene;
+import android.transition.Transition;
+import android.transition.TransitionInflater;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
+import android.util.ArrayMap;
 import android.view.ViewConfiguration;
 
 import com.android.internal.R;
@@ -53,7 +62,6 @@
 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;
@@ -63,7 +71,6 @@
 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;
@@ -86,6 +93,7 @@
 import android.view.ViewParent;
 import android.view.ViewRootImpl;
 import android.view.ViewStub;
+import android.view.ViewTreeObserver;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
@@ -100,6 +108,9 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Android-specific Window.
@@ -112,6 +123,15 @@
     private final static String TAG = "PhoneWindow";
 
     private final static boolean SWEEP_OPEN_MENU = false;
+    private static final long MAX_TRANSITION_START_WAIT = 500;
+    private static final long MAX_TRANSITION_FINISH_WAIT = 1000;
+
+    private static final String KEY_SCREEN_X = "shared_element:screenX";
+    private static final String KEY_SCREEN_Y = "shared_element:screenY";
+    private static final String KEY_TRANSLATION_Z = "shared_element:translationZ";
+    private static final String KEY_WIDTH = "shared_element:width";
+    private static final String KEY_HEIGHT = "shared_element:height";
+    private static final String KEY_NAME = "shared_element:name";
 
     /**
      * Simple callback used by the context menu and its submenus. The options
@@ -134,19 +154,22 @@
     private ViewGroup mContentParent;
 
     SurfaceHolder.Callback2 mTakeSurfaceCallback;
-    
+
     InputQueue.Callback mTakeInputQueueCallback;
-    
+
     private boolean mIsFloating;
 
     private LayoutInflater mLayoutInflater;
 
     private TextView mTitleView;
-    
+
     private ActionBarView mActionBar;
     private ActionMenuPresenterCallback mActionMenuPresenterCallback;
     private PanelMenuPresenterCallback mPanelMenuPresenterCallback;
 
+    private TransitionManager mTransitionManager;
+    private Scene mContentScene;
+
     // 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;
@@ -227,6 +250,11 @@
         }
     };
 
+    private ActivityOptions mActivityOptions;
+    private SceneTransitionListener mSceneTransitionListener;
+    private boolean mTriggerEarly = true;
+    private Map<String, String> mSharedElementsMap;
+
     static class WindowManagerHolder {
         static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService("window"));
@@ -291,13 +319,38 @@
     }
 
     @Override
+    public TransitionManager getTransitionManager() {
+        return mTransitionManager;
+    }
+
+    @Override
+    public void setTransitionManager(TransitionManager tm) {
+        mTransitionManager = tm;
+    }
+
+    @Override
+    public Scene getContentScene() {
+        return mContentScene;
+    }
+
+    @Override
     public void setContentView(int layoutResID) {
+        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
+        // decor, when theme attributes and the like are crystalized. Do not check the feature
+        // before this happens.
         if (mContentParent == null) {
             installDecor();
-        } else {
+        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
             mContentParent.removeAllViews();
         }
-        mLayoutInflater.inflate(layoutResID, mContentParent);
+
+        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
+                    getContext());
+            transitionTo(newScene);
+        } else {
+            mLayoutInflater.inflate(layoutResID, mContentParent);
+        }
         final Callback cb = getCallback();
         if (cb != null && !isDestroyed()) {
             cb.onContentChanged();
@@ -311,12 +364,22 @@
 
     @Override
     public void setContentView(View view, ViewGroup.LayoutParams params) {
+        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
+        // decor, when theme attributes and the like are crystalized. Do not check the feature
+        // before this happens.
         if (mContentParent == null) {
             installDecor();
-        } else {
+        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
             mContentParent.removeAllViews();
         }
-        mContentParent.addView(view, params);
+
+        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+            view.setLayoutParams(params);
+            final Scene newScene = new Scene(mContentParent, view);
+            transitionTo(newScene);
+        } else {
+            mContentParent.addView(view, params);
+        }
         final Callback cb = getCallback();
         if (cb != null && !isDestroyed()) {
             cb.onContentChanged();
@@ -328,6 +391,11 @@
         if (mContentParent == null) {
             installDecor();
         }
+        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+            // TODO Augment the scenes/transitions API to support this.
+            throw new UnsupportedOperationException(
+                    "addContentView does not support content transitions");
+        }
         mContentParent.addView(view, params);
         final Callback cb = getCallback();
         if (cb != null && !isDestroyed()) {
@@ -335,6 +403,18 @@
         }
     }
 
+    private void transitionTo(Scene scene) {
+        if (mContentScene == null) {
+            scene.enter();
+            if (mActivityOptions != null) {
+                new EnterScene().start();
+            }
+        } else {
+            mTransitionManager.transitionTo(scene);
+        }
+        mContentScene = scene;
+    }
+
     @Override
     public View getCurrentFocus() {
         return mDecor != null ? mDecor.findFocus() : null;
@@ -344,11 +424,11 @@
     public void takeSurface(SurfaceHolder.Callback2 callback) {
         mTakeSurfaceCallback = callback;
     }
-    
+
     public void takeInputQueue(InputQueue.Callback callback) {
         mTakeInputQueueCallback = callback;
     }
-    
+
     @Override
     public boolean isFloating() {
         return mIsFloating;
@@ -376,6 +456,7 @@
     }
 
     @Override
+    @Deprecated
     public void setTitleColor(int textColor) {
         if (mTitleView != null) {
             mTitleView.setTextColor(textColor);
@@ -634,7 +715,7 @@
                 // Otherwise, set the normal panel background
                 backgroundResId = st.background;
             }
-            st.decorView.setWindowBackground(getContext().getResources().getDrawable(
+            st.decorView.setWindowBackground(getContext().getDrawable(
                     backgroundResId));
 
             ViewParent shownPanelParent = st.shownPanelView.getParent();
@@ -1219,7 +1300,7 @@
             if (st.resid != resId) {
                 st.resid = resId;
                 st.uri = null;
-                st.local = getContext().getResources().getDrawable(resId);
+                st.local = getContext().getDrawable(resId);
                 updateDrawable(featureId, st, false);
             }
         } else {
@@ -2235,7 +2316,7 @@
                     if (mMenuBackground == null && mFeatureId < 0
                             && getAttributes().height
                             == WindowManager.LayoutParams.MATCH_PARENT) {
-                        mMenuBackground = getContext().getResources().getDrawable(
+                        mMenuBackground = getContext().getDrawable(
                                 com.android.internal.R.drawable.menu_background);
                     }
                     if (mMenuBackground != null) {
@@ -2504,6 +2585,11 @@
             return super.fitSystemWindows(insets);
         }
 
+        @Override
+        public boolean isTransitionGroup() {
+            return false;
+        }
+
         private void updateStatusGuard(Rect insets) {
             boolean showStatusGuard = false;
             // Show the status guard when the non-overlay contextual action bar is showing
@@ -2904,6 +2990,9 @@
             a.getValue(com.android.internal.R.styleable.Window_windowFixedHeightMinor,
                     mFixedHeightMinor);
         }
+        if (a.getBoolean(com.android.internal.R.styleable.Window_windowContentTransitions, false)) {
+            requestFeature(FEATURE_CONTENT_TRANSITIONS);
+        }
 
         final Context context = getContext();
         final int targetSdk = context.getApplicationInfo().targetSdkVersion;
@@ -3059,12 +3148,12 @@
         if (getContainer() == null) {
             Drawable drawable = mBackgroundDrawable;
             if (mBackgroundResource != 0) {
-                drawable = getContext().getResources().getDrawable(mBackgroundResource);
+                drawable = getContext().getDrawable(mBackgroundResource);
             }
             mDecor.setWindowBackground(drawable);
             drawable = null;
             if (mFrameResource != 0) {
-                drawable = getContext().getResources().getDrawable(mFrameResource);
+                drawable = getContext().getDrawable(mFrameResource);
             }
             mDecor.setWindowFrame(drawable);
 
@@ -3199,6 +3288,20 @@
                     });
                 }
             }
+
+            // Only inflate or create a new TransitionManager if the caller hasn't
+            // already set a custom one.
+            if (hasFeature(FEATURE_CONTENT_TRANSITIONS) && mTransitionManager == null) {
+                final int transitionRes = getWindowStyle().getResourceId(
+                        com.android.internal.R.styleable.Window_windowContentTransitionManager, 0);
+                if (transitionRes != 0) {
+                    final TransitionInflater inflater = TransitionInflater.from(getContext());
+                    mTransitionManager = inflater.inflateTransitionManager(transitionRes,
+                            mContentParent);
+                } else {
+                    mTransitionManager = new TransitionManager();
+                }
+            }
         }
     }
 
@@ -3523,6 +3626,12 @@
         return mVolumeControlStreamType;
     }
 
+    private boolean isTranslucent() {
+        TypedArray a = getWindowStyle();
+        return a.getBoolean(a.getResourceId(
+                com.android.internal.R.styleable.Window_windowIsTranslucent, 0), false);
+    }
+
     private static final class DrawableFeatureState {
         DrawableFeatureState(int _featureId) {
             featureId = _featureId;
@@ -3956,4 +4065,393 @@
     void sendCloseSystemWindows(String reason) {
         PhoneWindowManager.sendCloseSystemWindows(getContext(), reason);
     }
+
+    @Override
+    public void setTransitionOptions(ActivityOptions options, SceneTransitionListener listener) {
+        mSceneTransitionListener = listener;
+        mActivityOptions = options;
+    }
+
+    @Override
+    public void setTriggerEarlyEnterTransition(boolean triggerEarly) {
+        mTriggerEarly = triggerEarly;
+    }
+
+    @Override
+    public void mapTransitionTargets(Map<String, String> sharedElementNames) {
+        mSharedElementsMap = sharedElementNames;
+    }
+
+    @Override
+    public Bundle startExitTransition(ActivityOptions activityOptions) {
+        if (mContentScene == null) {
+            return null;
+        }
+        Transition transition = mTransitionManager.getExitTransition(mContentScene);
+        if (transition == null) {
+            return null;
+        }
+
+        ArrayMap<String, View> sharedElements = findSharedElements(activityOptions);
+
+        // Find exiting Views and shared elements
+        final ArrayList<View> transitioningViews = new ArrayList<View>();
+        mDecor.captureTransitioningViews(transitioningViews);
+        transitioningViews.removeAll(sharedElements.values());
+
+        Transition exitTransition = cloneAndSetTransitionTargets(transition,
+                transitioningViews, true);
+        Transition sharedElementTransition = cloneAndSetTransitionTargets(transition,
+                transitioningViews, false);
+
+        // transitionSet is the total exit transition, including hero animation.
+        TransitionSet transitionSet = new TransitionSet();
+        transitionSet.addTransition(exitTransition);
+        transitionSet.addTransition(sharedElementTransition);
+
+        updateExitActivityOptions(activityOptions, sharedElements,
+                sharedElementTransition, exitTransition);
+
+        // Start exiting the Views that need to exit
+        TransitionManager.beginDelayedTransition(mDecor, transitionSet);
+        setViewVisibility(transitioningViews, View.INVISIBLE);
+
+        return activityOptions.toBundle();
+    }
+
+    private ArrayMap<String, View> findSharedElements(ActivityOptions activityOptions) {
+        ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
+        mDecor.findSharedElements(sharedElements);
+        ArrayList<String> localNames = activityOptions.getLocalElementNames();
+        sharedElements.keySet().retainAll(localNames);
+
+        ArrayList<String> targetNames = activityOptions.getSharedElementNames();
+        for (int i = 0; i < localNames.size(); i++) {
+            String localName = localNames.get(i);
+            View sharedElement = sharedElements.remove(localName);
+            String targetName = targetNames.get(i);
+            sharedElements.put(targetName, sharedElement);
+        }
+        return sharedElements;
+    }
+
+    private void updateExitActivityOptions(ActivityOptions activityOptions,
+            final Map<String, View> sharedElements, Transition sharedElementTransition,
+            Transition exitTransition) {
+
+        // Schedule capturing of the shared element state
+        final Bundle sharedElementArgs = new Bundle();
+        captureTerminalSharedElementState(sharedElements, sharedElementArgs);
+
+        ActivityOptions.SharedElementSource sharedElementSource
+                = new ActivityOptions.SharedElementSource() {
+            @Override
+            public Bundle getSharedElementExitState() {
+                return sharedElementArgs;
+            }
+
+            @Override
+            public void acceptedSharedElements(ArrayList<String> sharedElementNames) {
+                if (sharedElementNames.size() == sharedElements.size()) {
+                    return; // They were all accepted
+                }
+                Transition transition = mTransitionManager.getExitTransition(mContentScene).clone();
+                TransitionManager.beginDelayedTransition(mDecor, transition);
+                for (String name: sharedElements.keySet()) {
+                    if (!sharedElementNames.contains(name)) {
+                        sharedElements.get(name).setVisibility(View.INVISIBLE);
+                    }
+                }
+                sharedElements.keySet().retainAll(sharedElementNames);
+            }
+
+            @Override
+            public void hideSharedElements() {
+                if (sharedElements != null) {
+                    setViewVisibility(sharedElements.values(), View.INVISIBLE);
+                }
+            }
+        };
+
+        activityOptions.updateSceneTransitionAnimation(
+                exitTransition, sharedElementTransition, sharedElementSource);
+    }
+
+    private void captureTerminalSharedElementState(final Map<String, View> sharedElements,
+            final Bundle sharedElementArgs) {
+        mDecor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+            @Override
+            public boolean onPreDraw() {
+                mDecor.getViewTreeObserver().removeOnPreDrawListener(this);
+                int[] tempLoc = new int[2];
+                for (String name : sharedElements.keySet()) {
+                    View sharedElement = sharedElements.get(name);
+                    captureSharedElementState(sharedElement, name, sharedElementArgs, tempLoc);
+                }
+                return true;
+            }
+        });
+    }
+
+    private static Transition cloneAndSetTransitionTargets(Transition transition,
+            List<View> views, boolean add) {
+        transition = transition.clone();
+        if (!transition.getTargetIds().isEmpty() || !transition.getTargets().isEmpty()) {
+            TransitionSet set = new TransitionSet();
+            set.addTransition(transition);
+            transition = set;
+        }
+        for (View view: views) {
+            if (add) {
+                transition.addTarget(view);
+            } else {
+                transition.excludeTarget(view, true);
+            }
+        }
+        return transition;
+    }
+
+    private static void setViewVisibility(Collection<View> views, int visibility) {
+        for (View view : views) {
+            view.setVisibility(visibility);
+        }
+    }
+
+    /**
+     * Sets the captured values from a previous
+     * {@link #captureSharedElementState(android.view.View, String, android.os.Bundle, int[])}
+     * @param view The View to apply placement changes to.
+     * @param name The shared element name given from the source Activity.
+     * @param transitionArgs A <code>Bundle</code> containing all placementinformation for named
+     *                       shared elements in the scene.
+     * @param tempLoc A temporary int[2] for capturing the current location of views.
+     */
+    private static void setSharedElementState(View view, String name, Bundle transitionArgs,
+            int[] tempLoc) {
+        Bundle sharedElementBundle = transitionArgs.getBundle(name);
+        if (sharedElementBundle == null) {
+            return;
+        }
+
+        int x = sharedElementBundle.getInt(KEY_SCREEN_X);
+        view.getLocationOnScreen(tempLoc);
+        int offsetX = x - tempLoc[0];
+        view.offsetLeftAndRight(offsetX);
+
+        int width = sharedElementBundle.getInt(KEY_WIDTH);
+        view.setRight(view.getLeft() + width);
+
+        int y = sharedElementBundle.getInt(KEY_SCREEN_Y);
+        int offsetY = y - tempLoc[1];
+        view.offsetTopAndBottom(offsetY);
+
+        int height = sharedElementBundle.getInt(KEY_HEIGHT);
+        view.setBottom(view.getTop() + height);
+
+        float z = sharedElementBundle.getFloat(KEY_TRANSLATION_Z);
+        view.setTranslationZ(z);
+    }
+
+    /**
+     * Captures placement information for Views with a shared element name for
+     * Activity Transitions.
+     * @param view The View to capture the placement information for.
+     * @param name The shared element name in the target Activity to apply the placement
+     *             information for.
+     * @param transitionArgs Bundle to store shared element placement information.
+     * @param tempLoc A temporary int[2] for capturing the current location of views.
+     * @see #setSharedElementState(android.view.View, String, android.os.Bundle, int[])
+     */
+    private static void captureSharedElementState(View view, String name, Bundle transitionArgs,
+            int[] tempLoc) {
+        Bundle sharedElementBundle = new Bundle();
+        view.getLocationOnScreen(tempLoc);
+        float scaleX = view.getScaleX();
+        sharedElementBundle.putInt(KEY_SCREEN_X, tempLoc[0]);
+        int width = Math.round(view.getWidth() * scaleX);
+        sharedElementBundle.putInt(KEY_WIDTH, width);
+
+        float scaleY = view.getScaleY();
+        sharedElementBundle.putInt(KEY_SCREEN_Y, tempLoc[1]);
+        int height= Math.round(view.getHeight() * scaleY);
+        sharedElementBundle.putInt(KEY_HEIGHT, height);
+
+        sharedElementBundle.putFloat(KEY_TRANSLATION_Z, view.getTranslationZ());
+
+        sharedElementBundle.putString(KEY_NAME, view.getSharedElementName());
+
+        transitionArgs.putBundle(name, sharedElementBundle);
+    }
+
+    /**
+     * Provides code for handling the Activity transition entering scene.
+     * When the first scene is laid out (onPreDraw), it makes views invisible.
+     * It then starts the entering transition by making non-shared elements visible. When
+     * the entering transition is started, the calling Activity is notified that
+     * this Activity is ready to receive the shared element. When the calling Activity notifies
+     * that the shared element is ready, this Activity is notified through the
+     * SceneTransitionListener.
+     *
+     * This class also takes into account fading the background -- either waiting until the
+     * shared element is ready or the calling Activity's exit transition is complete.
+     */
+    private class EnterScene implements ViewTreeObserver.OnPreDrawListener, Runnable,
+            ActivityOptions.ActivityTransitionTarget, Animator.AnimatorListener {
+        private boolean mSharedElementReadyReceived;
+        private boolean mAllDone;
+        private Handler mHandler = new Handler();
+        private boolean mEnterTransitionStarted;
+        private ArrayMap<String, View> mSharedElementTargets = new ArrayMap<String, View>();
+        private ArrayList<View> mEnteringViews = new ArrayList<View>();
+
+        public EnterScene() {
+            mSceneTransitionListener.nullPendingTransition();
+            Drawable background = getDecorView().getBackground();
+            if (background != null) {
+                background.setAlpha(0);
+                mDecor.drawableChanged();
+            }
+            mSceneTransitionListener.convertToTranslucent();
+        }
+
+        @Override
+        public boolean onPreDraw() {
+            ViewTreeObserver observer = mDecor.getViewTreeObserver();
+            observer.removeOnPreDrawListener(this);
+            if (!mEnterTransitionStarted && mSceneTransitionListener != null) {
+                mEnterTransitionStarted = true;
+                mDecor.captureTransitioningViews(mEnteringViews);
+                ArrayList<String> sharedElementNames = mActivityOptions.getSharedElementNames();
+                if (sharedElementNames != null) {
+                    mDecor.findSharedElements(mSharedElementTargets);
+                    if (mSharedElementsMap != null) {
+                        for (Map.Entry<String, String> entry : mSharedElementsMap.entrySet()) {
+                            View sharedElement = mSharedElementTargets.remove(entry.getValue());
+                            if (sharedElement != null) {
+                                mSharedElementTargets.put(entry.getKey(), sharedElement);
+                            }
+                        }
+                    }
+                    mSharedElementTargets.keySet().retainAll(sharedElementNames);
+                    mEnteringViews.removeAll(mSharedElementTargets.values());
+                }
+
+                setViewVisibility(mEnteringViews, View.INVISIBLE);
+                setViewVisibility(mSharedElementTargets.values(), View.INVISIBLE);
+                if (mTriggerEarly) {
+                    beginEnterScene();
+                }
+                observer.addOnPreDrawListener(this);
+            } else {
+                mHandler.postDelayed(this, MAX_TRANSITION_START_WAIT);
+                mActivityOptions.dispatchSceneTransitionStarted(this,
+                        new ArrayList<String>(mSharedElementTargets.keySet()));
+            }
+            return true;
+        }
+
+        public void start() {
+            ViewTreeObserver observer = mDecor.getViewTreeObserver();
+            observer.addOnPreDrawListener(this);
+        }
+
+        @Override
+        public void run() {
+            exitTransitionComplete();
+        }
+
+        @Override
+        public void sharedElementTransitionComplete(Bundle transitionArgs) {
+            if (!mSharedElementReadyReceived) {
+                mSharedElementReadyReceived = true;
+                mHandler.removeCallbacks(this);
+                mHandler.postDelayed(this, MAX_TRANSITION_FINISH_WAIT);
+                if (!mSharedElementTargets.isEmpty()) {
+                    Transition transition = getTransitionManager().getEnterTransition(
+                            mContentScene);
+                    if (transition == null) {
+                        transition = TransitionManager.getDefaultTransition();
+                    }
+                    transition = transition.clone();
+                    if (transitionArgs == null) {
+                        TransitionManager.beginDelayedTransition(mDecor, transition);
+                        setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
+                    } else {
+                        int[] tempLoc = new int[2];
+                        for (Map.Entry<String, View> entry: mSharedElementTargets.entrySet()) {
+                            setSharedElementState(entry.getValue(), entry.getKey(), transitionArgs,
+                                    tempLoc);
+                        }
+                        setViewVisibility(mSharedElementTargets.values(), View.VISIBLE);
+                        mSceneTransitionListener.sharedElementStart(transition);
+                        mDecor.getViewTreeObserver().addOnPreDrawListener(
+                                new ViewTreeObserver.OnPreDrawListener() {
+                                    @Override
+                                    public boolean onPreDraw() {
+                                        mDecor.getViewTreeObserver().removeOnPreDrawListener(this);
+                                        mSceneTransitionListener.sharedElementEnd();
+                                        mActivityOptions.dispatchSharedElementsReady();
+                                        return true;
+                                    }
+                                });
+                        TransitionManager.beginDelayedTransition(mDecor, transition);
+                    }
+                }
+                if (mTriggerEarly) {
+                    fadeInBackground();
+                }
+            }
+        }
+
+        private void fadeInBackground() {
+            Drawable background = getDecorView().getBackground();
+            if (background == null) {
+                mSceneTransitionListener.convertFromTranslucent();
+            } else {
+                ObjectAnimator animator = ObjectAnimator.ofInt(background, "alpha", 255);
+                animator.addListener(this);
+                animator.start();
+            }
+        }
+
+        @Override
+        public void exitTransitionComplete() {
+            if (mAllDone) {
+                return;
+            }
+            mAllDone = true;
+            sharedElementTransitionComplete(null);
+            mHandler.removeCallbacks(this);
+            if (!mTriggerEarly) {
+                beginEnterScene();
+                fadeInBackground();
+            }
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mSceneTransitionListener.convertFromTranslucent();
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+        }
+
+        private void beginEnterScene() {
+            Transition transition = getTransitionManager().getEnterTransition(mContentScene);
+            if (transition == null) {
+                transition = TransitionManager.getDefaultTransition().clone();
+            }
+            TransitionManager.beginDelayedTransition(mDecor, transition);
+            setViewVisibility(mEnteringViews, View.VISIBLE);
+        }
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 36b9679..ededbb2 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -91,6 +91,7 @@
 import android.view.WindowManagerGlobal;
 import android.view.WindowManagerPolicy;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
@@ -105,6 +106,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;
@@ -212,6 +214,7 @@
     final Object mServiceAquireLock = new Object();
     Vibrator mVibrator; // Vibrator for giving feedback of orientation changes
     SearchManager mSearchManager;
+    AccessibilityManager mAccessibilityManager;
 
     // Vibrator pattern for haptic feedback of a long press.
     long[] mLongPressVibePattern;
@@ -222,6 +225,9 @@
     // Vibrator pattern for a short vibration.
     long[] mKeyboardTapVibePattern;
 
+    // Vibrator pattern for a short vibration when tapping on an hour/minute tick of a Clock.
+    long[] mClockTickVibePattern;
+
     // Vibrator pattern for haptic feedback during boot when safe mode is disabled.
     long[] mSafeModeDisabledVibePattern;
 
@@ -296,7 +302,6 @@
     boolean mOrientationSensorEnabled = false;
     int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
     boolean mHasSoftInput = false;
-    boolean mTouchExplorationEnabled = false;
     boolean mTranslucentDecorEnabled = true;
 
     int mPointerLocationMode = 0; // guarded by mLock
@@ -305,17 +310,6 @@
     WindowState mFocusedWindow;
     IApplicationToken mFocusedApp;
 
-    private final class PointerLocationPointerEventListener implements PointerEventListener {
-        @Override
-        public void onPointerEvent(MotionEvent motionEvent) {
-            if (mPointerLocationView != null) {
-                mPointerLocationView.addPointerEvent(motionEvent);
-            }
-        }
-    }
-
-    // Pointer location view state, only modified on the mHandler Looper.
-    PointerLocationPointerEventListener mPointerLocationPointerEventListener;
     PointerLocationView mPointerLocationView;
 
     // The current size of the screen; really; extends into the overscan area of
@@ -381,7 +375,7 @@
     static final Rect mTmpNavigationFrame = new Rect();
 
     WindowState mTopFullscreenOpaqueWindowState;
-    boolean mHideWindowBehindKeyguard;
+    HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>();
     boolean mTopIsFullscreen;
     boolean mForceStatusBar;
     boolean mForceStatusBarFromKeyguard;
@@ -533,9 +527,12 @@
             resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
                     UserHandle.USER_ALL);
-            resolver.registerContentObserver(Settings.System.getUriFor(
+            resolver.registerContentObserver(Settings.Secure.getUriFor(
                     Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this,
                     UserHandle.USER_ALL);
+            resolver.registerContentObserver(Settings.Global.getUriFor(
+                    Settings.Global.POLICY_CONTROL), false, this,
+                    UserHandle.USER_ALL);
             updateSettings();
         }
 
@@ -910,6 +907,9 @@
                 com.android.internal.R.bool.config_enableTranslucentDecor);
         readConfigurationDependentBehaviors();
 
+        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
+                Context.ACCESSIBILITY_SERVICE);
+
         // register for dock events
         IntentFilter filter = new IntentFilter();
         filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE);
@@ -970,6 +970,8 @@
                 com.android.internal.R.array.config_virtualKeyVibePattern);
         mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_keyboardTapVibePattern);
+        mClockTickVibePattern = getLongIntArray(mContext.getResources(),
+                com.android.internal.R.array.config_clockTickVibePattern);
         mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(),
                 com.android.internal.R.array.config_safeModeDisabledVibePattern);
         mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(),
@@ -1108,7 +1110,8 @@
      *         navigation bar and touch exploration is not enabled
      */
     private boolean canHideNavigationBar() {
-        return mHasNavigationBar && !mTouchExplorationEnabled;
+        return mHasNavigationBar
+                && !mAccessibilityManager.isTouchExplorationEnabled();
     }
 
     @Override
@@ -1177,8 +1180,9 @@
                 updateRotation = true;
             }
             if (mImmersiveModeConfirmation != null) {
-                mImmersiveModeConfirmation.loadSetting();
+                mImmersiveModeConfirmation.loadSetting(mCurrentUserId);
             }
+            PolicyControl.reloadFromSetting(mContext);
         }
         if (updateRotation) {
             updateRotation(true);
@@ -1189,7 +1193,6 @@
         if (mPointerLocationView == null) {
             mPointerLocationView = new PointerLocationView(mContext);
             mPointerLocationView.setPrintCoords(false);
-
             WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                     WindowManager.LayoutParams.MATCH_PARENT,
                     WindowManager.LayoutParams.MATCH_PARENT);
@@ -1209,22 +1212,14 @@
                     mContext.getSystemService(Context.WINDOW_SERVICE);
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
             wm.addView(mPointerLocationView, lp);
-
-            mPointerLocationPointerEventListener = new PointerLocationPointerEventListener();
-            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationPointerEventListener);
+            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView);
         }
     }
 
     private void disablePointerLocation() {
-        if (mPointerLocationPointerEventListener != null) {
-            mWindowManagerFuncs.unregisterPointerEventListener(
-                    mPointerLocationPointerEventListener);
-            mPointerLocationPointerEventListener = null;
-        }
-
         if (mPointerLocationView != null) {
-            WindowManager wm = (WindowManager)
-                    mContext.getSystemService(Context.WINDOW_SERVICE);
+            mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView);
+            WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
             wm.removeView(mPointerLocationView);
             mPointerLocationView = null;
         }
@@ -2586,8 +2581,9 @@
 
     @Override
     public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) {
-        final int fl = attrs.flags;
-        final int systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
+        final int fl = PolicyControl.getWindowFlags(null, attrs);
+        final int sysuiVis = PolicyControl.getSystemUiVisibility(null, attrs);
+        final int systemUiVisibility = (sysuiVis | attrs.subtreeSystemUiVisibility);
 
         if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR))
                 == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
@@ -2759,7 +2755,8 @@
                         // We currently want to hide the navigation UI.
                         mNavigationBarController.setBarShowingLw(false);
                     }
-                    if (navVisible && !navTranslucent && !mNavigationBar.isAnimatingLw()
+                    if (navVisible && !navTranslucent && !navAllowedHidden
+                            && !mNavigationBar.isAnimatingLw()
                             && !mNavigationBarController.wasRecentlyTranslucent()) {
                         // If the opaque nav bar is currently requested to be visible,
                         // and not in the process of animating on or off, then
@@ -2968,9 +2965,9 @@
             offsetInputMethodWindowLw(mLastInputMethodWindow);
         }
 
-        final int fl = attrs.flags;
+        final int fl = PolicyControl.getWindowFlags(win, attrs);
         final int sim = attrs.softInputMode;
-        final int sysUiFl = win.getSystemUiVisibility();
+        final int sysUiFl = PolicyControl.getSystemUiVisibility(win, null);
 
         final Rect pf = mTmpParentFrame;
         final Rect df = mTmpDisplayFrame;
@@ -3370,7 +3367,7 @@
     @Override
     public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
         mTopFullscreenOpaqueWindowState = null;
-        mHideWindowBehindKeyguard = false;
+        mAppsToBeHidden.clear();
         mForceStatusBar = false;
         mForceStatusBarFromKeyguard = false;
         mForcingShowNavBar = false;
@@ -3389,6 +3386,7 @@
                                 WindowManager.LayoutParams attrs) {
         if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
                 + win.isVisibleOrBehindKeyguardLw());
+        final int fl = PolicyControl.getWindowFlags(win, attrs);
         if (mTopFullscreenOpaqueWindowState == null
                 && win.isVisibleLw() && attrs.type == TYPE_INPUT_METHOD) {
             mForcingShowNavBar = true;
@@ -3396,7 +3394,7 @@
         }
         if (mTopFullscreenOpaqueWindowState == null &&
                 win.isVisibleOrBehindKeyguardLw() && !win.isGoneForLayoutLw()) {
-            if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
+            if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
                 if (attrs.type == TYPE_KEYGUARD) {
                     mForceStatusBarFromKeyguard = true;
                 } else {
@@ -3418,21 +3416,26 @@
                 }
             }
 
-            final boolean showWhenLocked = (attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0;
+            final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
             if (appWindow) {
+                if (showWhenLocked) {
+                    mAppsToBeHidden.remove(win.getAppToken());
+                } else {
+                    mAppsToBeHidden.add(win.getAppToken());
+                }
                 if (attrs.x == 0 && attrs.y == 0
                         && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
                         && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
-                    if (!mHideWindowBehindKeyguard) {
+                    if (mAppsToBeHidden.isEmpty()) {
                         if (showWhenLocked) {
                             if (DEBUG_LAYOUT) Slog.v(TAG,
                                     "Setting mHideLockScreen to true by win " + win);
                             mHideLockScreen = true;
                             mForceStatusBarFromKeyguard = false;
                         }
-                        if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0
+                        if ((fl & FLAG_DISMISS_KEYGUARD) != 0
                                 && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
                             if (DEBUG_LAYOUT) Slog.v(TAG,
                                     "Setting mDismissKeyguard true by win " + win);
@@ -3442,11 +3445,9 @@
                             mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
                         }
                     }
-                    if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
+                    if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
                         mAllowLockscreenWhenOn = true;
                     }
-                } else if (!showWhenLocked) {
-                    mHideWindowBehindKeyguard = true;
                 }
             }
         }
@@ -3487,13 +3488,14 @@
                             mLastSystemUiFlags, mLastSystemUiFlags);
                 }
             } else if (mTopFullscreenOpaqueWindowState != null) {
+                final int fl = PolicyControl.getWindowFlags(null, lp);
                 if (localLOGV) {
                     Slog.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw()
                             + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw());
                     Slog.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()
-                            + " lp.flags=0x" + Integer.toHexString(lp.flags));
+                            + " lp.flags=0x" + Integer.toHexString(fl));
                 }
-                topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
+                topIsFullscreen = (fl & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0
                         || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
                 // The subtle difference between the window for mTopFullscreenOpaqueWindowState
                 // and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window
@@ -3977,8 +3979,11 @@
             case KeyEvent.KEYCODE_POWER: {
                 result &= ~ACTION_PASS_TO_USER;
                 if (down) {
-                    mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn, event.getDownTime(),
-                            isImmersiveMode(mLastSystemUiFlags));
+                    boolean panic = mImmersiveModeConfirmation.onPowerKeyDown(isScreenOn,
+                            event.getDownTime(), isImmersiveMode(mLastSystemUiFlags));
+                    if (panic) {
+                        mHandler.post(mRequestTransientNav);
+                    }
                     if (isScreenOn && !mPowerKeyTriggered
                             && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                         mPowerKeyTriggered = true;
@@ -4262,6 +4267,13 @@
         }
     };
 
+    private final Runnable mRequestTransientNav = new Runnable() {
+        @Override
+        public void run() {
+            requestTransientBars(mNavigationBar);
+        }
+    };
+
     private void requestTransientBars(WindowState swipeTarget) {
         synchronized (mWindowManagerFuncs.getWindowManagerLock()) {
             boolean sb = mStatusBarController.checkShowTransientBarLw();
@@ -5057,6 +5069,9 @@
             case HapticFeedbackConstants.KEYBOARD_TAP:
                 pattern = mKeyboardTapVibePattern;
                 break;
+            case HapticFeedbackConstants.CLOCK_TICK:
+                pattern = mClockTickVibePattern;
+                break;
             case HapticFeedbackConstants.SAFE_MODE_DISABLED:
                 pattern = mSafeModeDisabledVibePattern;
                 break;
@@ -5077,10 +5092,10 @@
         }
         if (pattern.length == 1) {
             // One-shot vibration
-            mVibrator.vibrate(owningUid, owningPackage, pattern[0]);
+            mVibrator.vibrate(owningUid, owningPackage, pattern[0], AudioManager.STREAM_SYSTEM);
         } else {
             // Pattern vibration
-            mVibrator.vibrate(owningUid, owningPackage, pattern, -1);
+            mVibrator.vibrate(owningUid, owningPackage, pattern, -1, AudioManager.STREAM_SYSTEM);
         }
         return true;
     }
@@ -5092,7 +5107,6 @@
     @Override
     public void keepScreenOnStoppedLw() {
         if (mKeyguardDelegate != null && !mKeyguardDelegate.isShowingAndNotHidden()) {
-            long curTime = SystemClock.uptimeMillis();
             mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
         }
     }
@@ -5114,11 +5128,11 @@
             return 0;
         }
 
-        int tmpVisibility = win.getSystemUiVisibility()
+        int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)
                 & ~mResettingSystemUiFlags
                 & ~mForceClearedSystemUiFlags;
         if (mForcingShowNavBar && win.getSurfaceLayer() < mForcingShowNavBarLayer) {
-            tmpVisibility &= ~View.SYSTEM_UI_CLEARABLE_FLAGS;
+            tmpVisibility &= ~PolicyControl.adjustClearableFlags(win, View.SYSTEM_UI_CLEARABLE_FLAGS);
         }
         final int visibility = updateSystemBarsLw(win, mLastSystemUiFlags, tmpVisibility);
         final int diff = visibility ^ mLastSystemUiFlags;
@@ -5177,7 +5191,7 @@
                 (vis & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0;
         boolean hideStatusBarWM =
                 mTopFullscreenOpaqueWindowState != null &&
-                (mTopFullscreenOpaqueWindowState.getAttrs().flags
+                (PolicyControl.getWindowFlags(mTopFullscreenOpaqueWindowState, null)
                         & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0;
         boolean hideStatusBarSysui =
                 (vis & View.SYSTEM_UI_FLAG_FULLSCREEN) != 0;
@@ -5241,7 +5255,8 @@
      * R.boolean.config_enableTranslucentDecor is false.
      */
     private boolean areTranslucentBarsAllowed() {
-        return mTranslucentDecorEnabled && !mTouchExplorationEnabled;
+        return mTranslucentDecorEnabled
+                && !mAccessibilityManager.isTouchExplorationEnabled();
     }
 
     // Use this instead of checking config_showNavigationBar so that it can be consistently
@@ -5258,6 +5273,11 @@
     }
 
     @Override
+    public int getInputMethodWindowVisibleHeightLw() {
+        return mDockBottom - mCurBottom;
+    }
+
+    @Override
     public void setCurrentUserLw(int newUserId) {
         mCurrentUserId = newUserId;
         if (mKeyguardDelegate != null) {
@@ -5287,11 +5307,6 @@
     }
 
     @Override
-    public void setTouchExplorationEnabled(boolean enabled) {
-        mTouchExplorationEnabled = enabled;
-    }
-
-    @Override
     public boolean isTopLevelWindow(int windowType) {
         if (windowType >= WindowManager.LayoutParams.FIRST_SUB_WINDOW
                 && windowType <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
@@ -5461,5 +5476,6 @@
         pw.print(prefix); pw.print("mUndockedHdmiRotation="); pw.println(mUndockedHdmiRotation);
         mStatusBarController.dump(pw, prefix);
         mNavigationBarController.dump(pw, prefix);
+        PolicyControl.dump(prefix, pw);
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/PolicyControl.java b/policy/src/com/android/internal/policy/impl/PolicyControl.java
new file mode 100644
index 0000000..ffdb520
--- /dev/null
+++ b/policy/src/com/android/internal/policy/impl/PolicyControl.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.policy.impl;
+
+import android.content.Context;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams;
+import android.view.WindowManagerPolicy.WindowState;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Runtime adjustments applied to the global window policy.
+ *
+ * This includes forcing immersive mode behavior for one or both system bars (based on a package
+ * list) and permanently disabling immersive mode confirmations for specific packages.
+ *
+ * Control by setting {@link Settings.Global.POLICY_CONTROL} to one or more name-value pairs.
+ * e.g.
+ *   to force immersive mode everywhere:
+ *     "immersive.full=*"
+ *   to force transient status for all apps except a specific package:
+ *     "immersive.status=apps,-com.package"
+ *   to disable the immersive mode confirmations for specific packages:
+ *     "immersive.preconfirms=com.package.one,com.package.two"
+ *
+ * Separate multiple name-value pairs with ':'
+ *   e.g. "immersive.status=apps:immersive.preconfirms=*"
+ */
+public class PolicyControl {
+    private static String TAG = "PolicyControl";
+    private static boolean DEBUG = false;
+
+    private static final String NAME_IMMERSIVE_FULL = "immersive.full";
+    private static final String NAME_IMMERSIVE_STATUS = "immersive.status";
+    private static final String NAME_IMMERSIVE_NAVIGATION = "immersive.navigation";
+    private static final String NAME_IMMERSIVE_PRECONFIRMATIONS = "immersive.preconfirms";
+
+    private static String sSettingValue;
+    private static Filter sImmersivePreconfirmationsFilter;
+    private static Filter sImmersiveStatusFilter;
+    private static Filter sImmersiveNavigationFilter;
+
+    public static int getSystemUiVisibility(WindowState win, LayoutParams attrs) {
+        attrs = attrs != null ? attrs : win.getAttrs();
+        int vis = win != null ? win.getSystemUiVisibility() : attrs.systemUiVisibility;
+        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
+            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+            vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.STATUS_BAR_TRANSLUCENT);
+        }
+        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
+            vis |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+            vis &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.NAVIGATION_BAR_TRANSLUCENT);
+        }
+        return vis;
+    }
+
+    public static int getWindowFlags(WindowState win, LayoutParams attrs) {
+        attrs = attrs != null ? attrs : win.getAttrs();
+        int flags = attrs.flags;
+        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
+            flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
+            flags &= ~(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
+                    | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
+        }
+        if (sImmersiveNavigationFilter != null && sImmersiveNavigationFilter.matches(attrs)) {
+            flags &= ~WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
+        }
+        return flags;
+    }
+
+    public static int adjustClearableFlags(WindowState win, int clearableFlags) {
+        final LayoutParams attrs = win != null ? win.getAttrs() : null;
+        if (sImmersiveStatusFilter != null && sImmersiveStatusFilter.matches(attrs)) {
+            clearableFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
+        }
+        return clearableFlags;
+    }
+
+    public static boolean disableImmersiveConfirmation(String pkg) {
+        return sImmersivePreconfirmationsFilter != null
+                && sImmersivePreconfirmationsFilter.matches(pkg);
+    }
+
+    public static void reloadFromSetting(Context context) {
+        if (DEBUG) Slog.d(TAG, "reloadFromSetting()");
+        String value = null;
+        try {
+            value = Settings.Global.getStringForUser(context.getContentResolver(),
+                    Settings.Global.POLICY_CONTROL,
+                    UserHandle.USER_CURRENT);
+            if (sSettingValue != null && sSettingValue.equals(value)) return;
+            setFilters(value);
+            sSettingValue = value;
+        } catch (Throwable t) {
+            Slog.w(TAG, "Error loading policy control, value=" + value, t);
+        }
+    }
+
+    public static void dump(String prefix, PrintWriter pw) {
+        dump("sImmersiveStatusFilter", sImmersiveStatusFilter, prefix, pw);
+        dump("sImmersiveNavigationFilter", sImmersiveNavigationFilter, prefix, pw);
+        dump("sImmersivePreconfirmationsFilter", sImmersivePreconfirmationsFilter, prefix, pw);
+    }
+
+    private static void dump(String name, Filter filter, String prefix, PrintWriter pw) {
+        pw.print(prefix); pw.print("PolicyControl."); pw.print(name); pw.print('=');
+        if (filter == null) {
+            pw.println("null");
+        } else {
+            filter.dump(pw); pw.println();
+        }
+    }
+
+    private static void setFilters(String value) {
+        if (DEBUG) Slog.d(TAG, "setFilters: " + value);
+        sImmersiveStatusFilter = null;
+        sImmersiveNavigationFilter = null;
+        sImmersivePreconfirmationsFilter = null;
+        if (value != null) {
+            String[] nvps = value.split(":");
+            for (String nvp : nvps) {
+                int i = nvp.indexOf('=');
+                if (i == -1) continue;
+                String n = nvp.substring(0, i);
+                String v = nvp.substring(i + 1);
+                if (n.equals(NAME_IMMERSIVE_FULL)) {
+                    Filter f = Filter.parse(v);
+                    sImmersiveStatusFilter = sImmersiveNavigationFilter = f;
+                    if (sImmersivePreconfirmationsFilter == null) {
+                        sImmersivePreconfirmationsFilter = f;
+                    }
+                } else if (n.equals(NAME_IMMERSIVE_STATUS)) {
+                    Filter f = Filter.parse(v);
+                    sImmersiveStatusFilter = f;
+                } else if (n.equals(NAME_IMMERSIVE_NAVIGATION)) {
+                    Filter f = Filter.parse(v);
+                    sImmersiveNavigationFilter = f;
+                    if (sImmersivePreconfirmationsFilter == null) {
+                        sImmersivePreconfirmationsFilter = f;
+                    }
+                } else if (n.equals(NAME_IMMERSIVE_PRECONFIRMATIONS)) {
+                    Filter f = Filter.parse(v);
+                    sImmersivePreconfirmationsFilter = f;
+                }
+            }
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "immersiveStatusFilter: " + sImmersiveStatusFilter);
+            Slog.d(TAG, "immersiveNavigationFilter: " + sImmersiveNavigationFilter);
+            Slog.d(TAG, "immersivePreconfirmationsFilter: " + sImmersivePreconfirmationsFilter);
+        }
+    }
+
+    private static class Filter {
+        private static final String ALL = "*";
+        private static final String APPS = "apps";
+
+        private final ArraySet<String> mWhitelist;
+        private final ArraySet<String> mBlacklist;
+
+        private Filter(ArraySet<String> whitelist, ArraySet<String> blacklist) {
+            mWhitelist = whitelist;
+            mBlacklist = blacklist;
+        }
+
+        boolean matches(LayoutParams attrs) {
+            if (attrs == null) return false;
+            boolean isApp = attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
+                    && attrs.type <= WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+            if (isApp && mBlacklist.contains(APPS)) return false;
+            if (onBlacklist(attrs.packageName)) return false;
+            if (isApp && mWhitelist.contains(APPS)) return true;
+            return onWhitelist(attrs.packageName);
+        }
+
+        boolean matches(String packageName) {
+            return !onBlacklist(packageName) && onWhitelist(packageName);
+        }
+
+        private boolean onBlacklist(String packageName) {
+            return mBlacklist.contains(packageName) || mBlacklist.contains(ALL);
+        }
+
+        private boolean onWhitelist(String packageName) {
+            return mWhitelist.contains(ALL) || mWhitelist.contains(packageName);
+        }
+
+        void dump(PrintWriter pw) {
+            pw.print("Filter[");
+            dump("whitelist", mWhitelist, pw); pw.print(',');
+            dump("blacklist", mBlacklist, pw); pw.print(']');
+        }
+
+        private void dump(String name, ArraySet<String> set, PrintWriter pw) {
+            pw.print(name); pw.print("=(");
+            final int n = set.size();
+            for (int i = 0; i < n; i++) {
+                if (i > 0) pw.print(',');
+                pw.print(set.valueAt(i));
+            }
+            pw.print(')');
+        }
+
+        @Override
+        public String toString() {
+            StringWriter sw = new StringWriter();
+            dump(new PrintWriter(sw, true));
+            return sw.toString();
+        }
+
+        // value = comma-delimited list of tokens, where token = (package name|apps|*)
+        // e.g. "com.package1", or "apps, com.android.keyguard" or "*"
+        static Filter parse(String value) {
+            if (value == null) return null;
+            ArraySet<String> whitelist = new ArraySet<String>();
+            ArraySet<String> blacklist = new ArraySet<String>();
+            for (String token : value.split(",")) {
+                token = token.trim();
+                if (token.startsWith("-") && token.length() > 1) {
+                    token = token.substring(1);
+                    blacklist.add(token);
+                } else {
+                    whitelist.add(token);
+                }
+            }
+            return new Filter(whitelist, blacklist);
+        }
+    }
+}
diff --git a/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java b/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
index 8d87728..3490bd4 100644
--- a/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
+++ b/policy/src/com/android/internal/policy/impl/RecentApplicationsBackground.java
@@ -21,7 +21,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 import android.widget.LinearLayout;
diff --git a/policy/src/com/android/internal/policy/impl/ShortcutManager.java b/policy/src/com/android/internal/policy/impl/ShortcutManager.java
index 75a1b01..bb898f7 100644
--- a/policy/src/com/android/internal/policy/impl/ShortcutManager.java
+++ b/policy/src/com/android/internal/policy/impl/ShortcutManager.java
@@ -25,7 +25,6 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.KeyCharacterMap;
-import android.view.KeyEvent;
 
 import java.net.URISyntaxException;
 
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
index e5af716..812e817 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardServiceDelegate.java
@@ -12,7 +12,6 @@
 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;
diff --git a/preloaded-classes b/preloaded-classes
index 02bd0bc..35c52ad 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -400,7 +400,6 @@
 android.ddm.DdmHandleThread
 android.ddm.DdmHandleViewDebug
 android.ddm.DdmRegister
-android.debug.JNITest
 android.drm.DrmManagerClient
 android.emoji.EmojiFactory
 android.graphics.AvoidXfermode
@@ -661,7 +660,6 @@
 android.net.wifi.IWifiManager$Stub$Proxy
 android.net.wifi.WifiManager
 android.net.wifi.WifiManager$ServiceHandler
-android.net.wifi.WifiNative
 android.nfc.IAppCallback
 android.nfc.IAppCallback$Stub
 android.nfc.INfcAdapter
@@ -977,18 +975,14 @@
 android.view.DisplayInfo
 android.view.DisplayInfo$1
 android.view.DisplayList
+android.view.DisplayList$DisplayListFinalizer
 android.view.FallbackEventHandler
 android.view.FocusFinder
 android.view.FocusFinder$1
 android.view.FocusFinder$SequentialFocusComparator
 android.view.GLES20Canvas
 android.view.GLES20Canvas$CanvasFinalizer
-android.view.GLES20DisplayList
-android.view.GLES20DisplayList$DisplayListFinalizer
-android.view.GLES20Layer
-android.view.GLES20Layer$Finalizer
 android.view.GLES20RecordingCanvas
-android.view.GLES20RenderLayer
 android.view.GestureDetector
 android.view.GestureDetector$GestureHandler
 android.view.GestureDetector$OnDoubleTapListener
@@ -998,12 +992,6 @@
 android.view.HardwareCanvas
 android.view.HardwareLayer
 android.view.HardwareRenderer
-android.view.HardwareRenderer$Gl20Renderer
-android.view.HardwareRenderer$Gl20Renderer$1
-android.view.HardwareRenderer$Gl20Renderer$2
-android.view.HardwareRenderer$Gl20Renderer$Gl20RendererEglContext
-android.view.HardwareRenderer$GlRenderer
-android.view.HardwareRenderer$GlRenderer$FunctorsRunnable
 android.view.HardwareRenderer$HardwareDrawCallbacks
 android.view.IRotationWatcher
 android.view.IRotationWatcher$Stub
@@ -1114,7 +1102,6 @@
 android.view.ViewParent
 android.view.ViewRootImpl
 android.view.ViewRootImpl$3
-android.view.ViewRootImpl$4
 android.view.ViewRootImpl$AccessibilityInteractionConnectionManager
 android.view.ViewRootImpl$AsyncInputStage
 android.view.ViewRootImpl$ConsumeBatchedInputRunnable
@@ -1453,14 +1440,6 @@
 com.android.internal.view.RootViewSurfaceTaker
 com.android.internal.view.menu.ActionMenuItem
 com.android.internal.view.menu.ActionMenuItemView
-com.android.internal.view.menu.ActionMenuPresenter
-com.android.internal.view.menu.ActionMenuPresenter$OverflowMenuButton
-com.android.internal.view.menu.ActionMenuPresenter$PopupPresenterCallback
-com.android.internal.view.menu.ActionMenuPresenter$SavedState
-com.android.internal.view.menu.ActionMenuPresenter$SavedState$1
-com.android.internal.view.menu.ActionMenuView
-com.android.internal.view.menu.ActionMenuView$ActionMenuChildView
-com.android.internal.view.menu.ActionMenuView$LayoutParams
 com.android.internal.view.menu.BaseMenuPresenter
 com.android.internal.view.menu.ListMenuItemView
 com.android.internal.view.menu.MenuBuilder
@@ -1701,7 +1680,6 @@
 com.android.org.conscrypt.OpenSSLX509CertificateFactory$Parser
 com.android.org.conscrypt.ProtocolVersion
 com.android.org.conscrypt.SSLClientSessionCache
-com.android.org.conscrypt.SSLContextImpl
 com.android.org.conscrypt.SSLParametersImpl
 com.android.org.conscrypt.ServerSessionContext
 com.android.org.conscrypt.TrustManagerFactoryImpl
@@ -1888,7 +1866,6 @@
 java.lang.ThreadLocal$Values
 java.lang.Throwable
 java.lang.TypeNotPresentException
-java.lang.UnsafeByteSequence
 java.lang.UnsatisfiedLinkError
 java.lang.UnsupportedOperationException
 java.lang.VMClassLoader
@@ -2197,8 +2174,6 @@
 java.util.concurrent.Callable
 java.util.concurrent.CancellationException
 java.util.concurrent.ConcurrentHashMap
-java.util.concurrent.ConcurrentHashMap$HashEntry
-java.util.concurrent.ConcurrentHashMap$HashIterator
 java.util.concurrent.ConcurrentHashMap$Segment
 java.util.concurrent.ConcurrentLinkedQueue
 java.util.concurrent.ConcurrentLinkedQueue$Node
@@ -2258,7 +2233,6 @@
 java.util.jar.Attributes$Name
 java.util.jar.JarEntry
 java.util.jar.JarFile
-java.util.jar.JarFile$1JarFileEnumerator
 java.util.jar.JarVerifier
 java.util.jar.Manifest
 java.util.logging.ConsoleHandler
@@ -2383,7 +2357,6 @@
 libcore.io.StructUtsname
 libcore.math.MathUtils
 libcore.net.MimeUtils
-libcore.net.RawSocket
 libcore.net.UriCodec
 libcore.net.http.HttpDate
 libcore.net.http.HttpDate$1
diff --git a/rs/java/android/renderscript/Allocation.java b/rs/java/android/renderscript/Allocation.java
index c2bab91..2191b54 100644
--- a/rs/java/android/renderscript/Allocation.java
+++ b/rs/java/android/renderscript/Allocation.java
@@ -16,16 +16,12 @@
 
 package android.renderscript;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.HashMap;
 import android.content.res.Resources;
-import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.view.Surface;
 import android.util.Log;
-import android.util.TypedValue;
 import android.graphics.Canvas;
 import android.os.Trace;
 
@@ -602,7 +598,6 @@
      * without reinterpretation.
      *
      * @param array The source data array
-     * @hide
      */
     public void copyFromUnchecked(Object array) {
         Trace.traceBegin(RenderScript.TRACE_TAG, "copyFromUnchecked");
@@ -662,8 +657,7 @@
      * android.renderscript.Element} does not match the array's
      * primitive type.
      *
-     * @param d the source data array
-     * @hide
+     * @param array The source data array
      */
     public void copyFrom(Object array) {
         Trace.traceBegin(RenderScript.TRACE_TAG, "copyFrom");
@@ -862,7 +856,6 @@
      * @param off The offset of the first element to be copied.
      * @param count The number of elements to be copied.
      * @param array The source data array
-     * @hide
      */
     public void copy1DRangeFromUnchecked(int off, int count, Object array) {
         copy1DRangeFromUnchecked(off, count, array,
@@ -927,7 +920,6 @@
      * @param off The offset of the first element to be copied.
      * @param count The number of elements to be copied.
      * @param array The source data array.
-     * @hide
      */
     public void copy1DRangeFrom(int off, int count, Object array) {
         copy1DRangeFromUnchecked(off, count, array,
@@ -1043,8 +1035,7 @@
      * @param yoff Y offset of the region to update in this Allocation
      * @param w Width of the region to update
      * @param h Height of the region to update
-     * @param data to be placed into the Allocation
-     * @hide
+     * @param array Data to be placed into the Allocation
      */
     public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
         Trace.traceBegin(RenderScript.TRACE_TAG, "copy2DRangeFrom");
@@ -1274,7 +1265,6 @@
      * type of the array passed in.
      *
      * @param array The array to be set from the Allocation.
-     * @hide
      */
     public void copyTo(Object array) {
         copyTo(array, validateObjectIsPrimitiveArray(array, true),
@@ -1876,4 +1866,3 @@
     }
 
 }
-
diff --git a/rs/java/android/renderscript/AllocationAdapter.java b/rs/java/android/renderscript/AllocationAdapter.java
index fd20cae..3522a52 100644
--- a/rs/java/android/renderscript/AllocationAdapter.java
+++ b/rs/java/android/renderscript/AllocationAdapter.java
@@ -16,11 +16,6 @@
 
 package android.renderscript;
 
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.TypedValue;
-
 /**
  * Only intended for use by generated reflected code.
  *
diff --git a/rs/java/android/renderscript/Byte2.java b/rs/java/android/renderscript/Byte2.java
index f796de3..3ad79e4 100644
--- a/rs/java/android/renderscript/Byte2.java
+++ b/rs/java/android/renderscript/Byte2.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript byte2 type back to the Android system.
diff --git a/rs/java/android/renderscript/Byte3.java b/rs/java/android/renderscript/Byte3.java
index f2a95ac..a138313 100644
--- a/rs/java/android/renderscript/Byte3.java
+++ b/rs/java/android/renderscript/Byte3.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript byte3 type back to the Android system.
diff --git a/rs/java/android/renderscript/Byte4.java b/rs/java/android/renderscript/Byte4.java
index b8a8a6b..fa4c13d 100644
--- a/rs/java/android/renderscript/Byte4.java
+++ b/rs/java/android/renderscript/Byte4.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript byte4 type back to the Android system.
diff --git a/rs/java/android/renderscript/Element.java b/rs/java/android/renderscript/Element.java
index aa5d687..55b671d 100644
--- a/rs/java/android/renderscript/Element.java
+++ b/rs/java/android/renderscript/Element.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Field;
-import android.util.Log;
-
 /**
  * <p>An Element represents one item within an {@link
  * android.renderscript.Allocation}.  An Element is roughly equivalent to a C
diff --git a/rs/java/android/renderscript/FieldPacker.java b/rs/java/android/renderscript/FieldPacker.java
index cf20e63..723ab24 100644
--- a/rs/java/android/renderscript/FieldPacker.java
+++ b/rs/java/android/renderscript/FieldPacker.java
@@ -16,7 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
 import java.util.BitSet;
 
 /**
diff --git a/rs/java/android/renderscript/FileA3D.java b/rs/java/android/renderscript/FileA3D.java
index 04bc7c6..4164810 100644
--- a/rs/java/android/renderscript/FileA3D.java
+++ b/rs/java/android/renderscript/FileA3D.java
@@ -17,15 +17,10 @@
 package android.renderscript;
 
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 
 import android.content.res.AssetManager;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.Log;
-import android.util.TypedValue;
 
 /**
  * @hide
diff --git a/rs/java/android/renderscript/Float2.java b/rs/java/android/renderscript/Float2.java
index 26193d2..e9f8ca7 100644
--- a/rs/java/android/renderscript/Float2.java
+++ b/rs/java/android/renderscript/Float2.java
@@ -26,7 +26,7 @@
 
     public Float2() {
     }
-    /** @hide */ 
+    /** @hide */
     public Float2(Float2 data) {
         this.x = data.x;
         this.y = data.y;
diff --git a/rs/java/android/renderscript/Font.java b/rs/java/android/renderscript/Font.java
index cfd11c0..b22aeb7 100644
--- a/rs/java/android/renderscript/Font.java
+++ b/rs/java/android/renderscript/Font.java
@@ -17,7 +17,6 @@
 package android.renderscript;
 
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashMap;
 import java.util.Map;
@@ -26,8 +25,6 @@
 
 import android.content.res.AssetManager;
 import android.content.res.Resources;
-import android.util.Log;
-import android.util.TypedValue;
 
 /**
  * @hide
diff --git a/rs/java/android/renderscript/Int3.java b/rs/java/android/renderscript/Int3.java
index c770395..5431b9a7 100644
--- a/rs/java/android/renderscript/Int3.java
+++ b/rs/java/android/renderscript/Int3.java
@@ -27,7 +27,7 @@
 
     public Int3() {
     }
-    
+
     /** @hide */
     public Int3(int i) {
         this.x = this.y = this.z = i;
diff --git a/rs/java/android/renderscript/Long3.java b/rs/java/android/renderscript/Long3.java
index 88ff855..8e243cc 100644
--- a/rs/java/android/renderscript/Long3.java
+++ b/rs/java/android/renderscript/Long3.java
@@ -27,7 +27,7 @@
 
     public Long3() {
     }
-    
+
     /** @hide */
     public Long3(long i) {
         this.x = this.y = this.z = i;
diff --git a/rs/java/android/renderscript/Matrix2f.java b/rs/java/android/renderscript/Matrix2f.java
index d3621fa..048262d 100644
--- a/rs/java/android/renderscript/Matrix2f.java
+++ b/rs/java/android/renderscript/Matrix2f.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
diff --git a/rs/java/android/renderscript/Matrix3f.java b/rs/java/android/renderscript/Matrix3f.java
index 8c3c330..9a4af77 100644
--- a/rs/java/android/renderscript/Matrix3f.java
+++ b/rs/java/android/renderscript/Matrix3f.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.Math;
-import android.util.Log;
-
 
 /**
  * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
diff --git a/rs/java/android/renderscript/Matrix4f.java b/rs/java/android/renderscript/Matrix4f.java
index cd18e30..5d5bf5f 100644
--- a/rs/java/android/renderscript/Matrix4f.java
+++ b/rs/java/android/renderscript/Matrix4f.java
@@ -17,7 +17,6 @@
 package android.renderscript;
 
 import java.lang.Math;
-import android.util.Log;
 
 
 /**
diff --git a/rs/java/android/renderscript/Mesh.java b/rs/java/android/renderscript/Mesh.java
index ca0da9d..1a5dc9e 100644
--- a/rs/java/android/renderscript/Mesh.java
+++ b/rs/java/android/renderscript/Mesh.java
@@ -18,8 +18,6 @@
 
 import java.util.Vector;
 
-import android.util.Log;
-
 /**
  * @hide
  * @deprecated in API 16
diff --git a/rs/java/android/renderscript/Path.java b/rs/java/android/renderscript/Path.java
index 5cc67de..f3502aa 100644
--- a/rs/java/android/renderscript/Path.java
+++ b/rs/java/android/renderscript/Path.java
@@ -16,9 +16,6 @@
 
 package android.renderscript;
 
-import java.util.Vector;
-import android.util.Log;
-
 /**
  * @hide
  *
diff --git a/rs/java/android/renderscript/ProgramFragment.java b/rs/java/android/renderscript/ProgramFragment.java
index 4bb527b..5f71bd1 100644
--- a/rs/java/android/renderscript/ProgramFragment.java
+++ b/rs/java/android/renderscript/ProgramFragment.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
diff --git a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
index 2fe68be..2b647c76 100644
--- a/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramFragmentFixedFunction.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
diff --git a/rs/java/android/renderscript/ProgramRaster.java b/rs/java/android/renderscript/ProgramRaster.java
index e294b05..8c7c9aa 100644
--- a/rs/java/android/renderscript/ProgramRaster.java
+++ b/rs/java/android/renderscript/ProgramRaster.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
diff --git a/rs/java/android/renderscript/ProgramStore.java b/rs/java/android/renderscript/ProgramStore.java
index 969cc25..c0fa9c4 100644
--- a/rs/java/android/renderscript/ProgramStore.java
+++ b/rs/java/android/renderscript/ProgramStore.java
@@ -17,9 +17,6 @@
 package android.renderscript;
 
 
-import android.util.Log;
-
-
 /**
  * @hide
  * <p>ProgramStore contains a set of parameters that control how
diff --git a/rs/java/android/renderscript/ProgramVertex.java b/rs/java/android/renderscript/ProgramVertex.java
index d3a51de..0d7e2d9 100644
--- a/rs/java/android/renderscript/ProgramVertex.java
+++ b/rs/java/android/renderscript/ProgramVertex.java
@@ -39,10 +39,6 @@
 package android.renderscript;
 
 
-import android.graphics.Matrix;
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
diff --git a/rs/java/android/renderscript/ProgramVertexFixedFunction.java b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
index a350154..5173af2 100644
--- a/rs/java/android/renderscript/ProgramVertexFixedFunction.java
+++ b/rs/java/android/renderscript/ProgramVertexFixedFunction.java
@@ -17,10 +17,6 @@
 package android.renderscript;
 
 
-import android.graphics.Matrix;
-import android.util.Log;
-
-
 /**
  * @hide
  * @deprecated in API 16
diff --git a/rs/java/android/renderscript/RSSurfaceView.java b/rs/java/android/renderscript/RSSurfaceView.java
index 308d97a..5db72d9 100644
--- a/rs/java/android/renderscript/RSSurfaceView.java
+++ b/rs/java/android/renderscript/RSSurfaceView.java
@@ -16,16 +16,8 @@
 
 package android.renderscript;
 
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
 import android.content.Context;
-import android.os.Handler;
-import android.os.Message;
 import android.util.AttributeSet;
-import android.util.Log;
-import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
diff --git a/rs/java/android/renderscript/RSTextureView.java b/rs/java/android/renderscript/RSTextureView.java
index 7eeeeae..af3258a 100644
--- a/rs/java/android/renderscript/RSTextureView.java
+++ b/rs/java/android/renderscript/RSTextureView.java
@@ -16,16 +16,9 @@
 
 package android.renderscript;
 
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-
 import android.content.Context;
 import android.graphics.SurfaceTexture;
-import android.os.Handler;
-import android.os.Message;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.TextureView;
 
 /**
diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java
index ea25f58..dce4f581 100644
--- a/rs/java/android/renderscript/RenderScript.java
+++ b/rs/java/android/renderscript/RenderScript.java
@@ -17,16 +17,12 @@
 package android.renderscript;
 
 import java.io.File;
-import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.res.AssetManager;
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.SurfaceTexture;
 import android.os.Process;
 import android.util.Log;
diff --git a/rs/java/android/renderscript/RenderScriptGL.java b/rs/java/android/renderscript/RenderScriptGL.java
index c9cbe3e..714e835 100644
--- a/rs/java/android/renderscript/RenderScriptGL.java
+++ b/rs/java/android/renderscript/RenderScriptGL.java
@@ -16,17 +16,10 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Field;
-
 import android.content.Context;
-import android.graphics.PixelFormat;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.SurfaceTexture;
-import android.util.Log;
 import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.view.SurfaceView;
 
 /**
  * @hide
diff --git a/rs/java/android/renderscript/Sampler.java b/rs/java/android/renderscript/Sampler.java
index 8d0e29e..a4edbb5 100644
--- a/rs/java/android/renderscript/Sampler.java
+++ b/rs/java/android/renderscript/Sampler.java
@@ -16,17 +16,6 @@
 
 package android.renderscript;
 
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.util.Log;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-
 /**
  * Sampler object that defines how Allocations can be read as textures within a
  * kernel. Samplers are used in conjunction with the {@code rsSample} runtime
diff --git a/rs/java/android/renderscript/ScriptC.java b/rs/java/android/renderscript/ScriptC.java
index cdb2b08..9e76f52 100644
--- a/rs/java/android/renderscript/ScriptC.java
+++ b/rs/java/android/renderscript/ScriptC.java
@@ -16,18 +16,11 @@
 
 package android.renderscript;
 
-import android.content.Context;
 import android.content.res.Resources;
-import android.util.Log;
 
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Map.Entry;
-import java.util.HashMap;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
 
 /**
  * The superclass for all user-defined scripts. This is only
diff --git a/rs/java/android/renderscript/ScriptGroup.java b/rs/java/android/renderscript/ScriptGroup.java
index 1200a66..51c838f 100644
--- a/rs/java/android/renderscript/ScriptGroup.java
+++ b/rs/java/android/renderscript/ScriptGroup.java
@@ -16,7 +16,6 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 
 /**
diff --git a/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
index 96ec875..ce149d9 100644
--- a/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
+++ b/rs/java/android/renderscript/ScriptIntrinsic3DLUT.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  *
  * Intrinsic for converting RGB to RGBA by using a 3D lookup table.  The
@@ -86,10 +84,23 @@
      * @param aout Output allocation
      */
     public void forEach(Allocation ain, Allocation aout) {
-        forEach(0, ain, aout, null);
+        forEach(ain, aout, null);
     }
 
     /**
+     * Invoke the kernel and apply the lookup to each cell of ain
+     * and copy to aout.
+     *
+     * @param ain Input allocation
+     * @param aout Output allocation
+     * @param opt Launch options for kernel
+     */
+    public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        forEach(0, ain, aout, null, opt);
+    }
+
+
+    /**
      * Get a KernelID for this intrinsic kernel.
      *
      * @return Script.KernelID The KernelID object.
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlend.java b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
index 40f1a3e..d4038c2 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlend.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlend.java
@@ -40,14 +40,14 @@
 
     }
 
-    private void blend(int id, Allocation ain, Allocation aout) {
+    private void blend(int id, Allocation ain, Allocation aout, Script.LaunchOptions opt) {
         if (!ain.getElement().isCompatible(Element.U8_4(mRS))) {
             throw new RSIllegalArgumentException("Input is not of expected format.");
         }
         if (!aout.getElement().isCompatible(Element.U8_4(mRS))) {
             throw new RSIllegalArgumentException("Output is not of expected format.");
         }
-        forEach(id, ain, aout, null);
+        forEach(id, ain, aout, null, opt);
     }
 
     /**
@@ -57,7 +57,18 @@
      * @param aout The destination buffer
      */
     public void forEachClear(Allocation ain, Allocation aout) {
-        blend(0, ain, aout);
+        forEachClear(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = {0, 0, 0, 0}
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachClear(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(0, ain, aout, opt);
     }
 
     /**
@@ -77,7 +88,18 @@
      * @param aout The destination buffer
      */
     public void forEachSrc(Allocation ain, Allocation aout) {
-        blend(1, ain, aout);
+        forEachSrc(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = src
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachSrc(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        forEachDst(ain, aout, null);
     }
 
     /**
@@ -102,6 +124,19 @@
     }
 
     /**
+     * Sets dst = dst
+     *
+     * This is a NOP.
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachDst(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        // N, optOP
+    }
+
+    /**
      * Get a KernelID for the Dst kernel.
      *
      * @return Script.KernelID The KernelID object.
@@ -117,7 +152,18 @@
      * @param aout The destination buffer
      */
     public void forEachSrcOver(Allocation ain, Allocation aout) {
-        blend(3, ain, aout);
+        forEachSrcOver(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = src + dst * (1.0 - src.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachSrcOver(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(3, ain, aout, opt);
     }
 
     /**
@@ -136,7 +182,18 @@
      * @param aout The destination buffer
      */
     public void forEachDstOver(Allocation ain, Allocation aout) {
-        blend(4, ain, aout);
+        forEachDstOver(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = dst + src * (1.0 - dst.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachDstOver(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(4, ain, aout, opt);
     }
 
     /**
@@ -155,7 +212,18 @@
      * @param aout The destination buffer
      */
     public void forEachSrcIn(Allocation ain, Allocation aout) {
-        blend(5, ain, aout);
+        forEachSrcIn(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = src * dst.a
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachSrcIn(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(5, ain, aout, opt);
     }
 
     /**
@@ -174,7 +242,18 @@
      * @param aout The destination buffer
      */
     public void forEachDstIn(Allocation ain, Allocation aout) {
-        blend(6, ain, aout);
+        forEachDstIn(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = dst * src.a
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachDstIn(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(6, ain, aout, opt);
     }
 
     /**
@@ -193,7 +272,18 @@
      * @param aout The destination buffer
      */
     public void forEachSrcOut(Allocation ain, Allocation aout) {
-        blend(7, ain, aout);
+        forEachSrcOut(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = src * (1.0 - dst.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachSrcOut(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(7, ain, aout, opt);
     }
 
     /**
@@ -212,7 +302,18 @@
      * @param aout The destination buffer
      */
     public void forEachDstOut(Allocation ain, Allocation aout) {
-        blend(8, ain, aout);
+        forEachDstOut(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = dst * (1.0 - src.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachDstOut(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(8, ain, aout, opt);
     }
 
     /**
@@ -232,7 +333,19 @@
      * @param aout The destination buffer
      */
     public void forEachSrcAtop(Allocation ain, Allocation aout) {
-        blend(9, ain, aout);
+        forEachSrcAtop(ain, aout, null);
+    }
+
+    /**
+     * dst.rgb = src.rgb * dst.a + (1.0 - src.a) * dst.rgb
+     * dst.a = dst.a
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachSrcAtop(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(9, ain, aout, opt);
     }
 
     /**
@@ -252,7 +365,19 @@
      * @param aout The destination buffer
      */
     public void forEachDstAtop(Allocation ain, Allocation aout) {
-        blend(10, ain, aout);
+        forEachDstAtop(ain, aout, null);
+    }
+
+    /**
+     * dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb
+     * dst.a = src.a
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachDstAtop(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(10, ain, aout, opt);
     }
 
     /**
@@ -271,7 +396,18 @@
      * @param aout The destination buffer
      */
     public void forEachXor(Allocation ain, Allocation aout) {
-        blend(11, ain, aout);
+        forEachXor(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachXor(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(11, ain, aout, opt);
     }
 
     /**
@@ -300,7 +436,18 @@
      * @param aout The destination buffer
      */
     public void forEachMultiply(Allocation ain, Allocation aout) {
-        blend(14, ain, aout);
+        forEachMultiply(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = src * dst
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachMultiply(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(14, ain, aout, opt);
     }
 
     /**
@@ -396,7 +543,18 @@
      * @param aout The destination buffer
      */
     public void forEachAdd(Allocation ain, Allocation aout) {
-        blend(34, ain, aout);
+        forEachAdd(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = min(src + dst, 1.0)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachAdd(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(34, ain, aout, opt);
     }
 
     /**
@@ -415,7 +573,18 @@
      * @param aout The destination buffer
      */
     public void forEachSubtract(Allocation ain, Allocation aout) {
-        blend(35, ain, aout);
+        forEachSubtract(ain, aout, null);
+    }
+
+    /**
+     * Sets dst = max(dst - src, 0.0)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEachSubtract(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        blend(35, ain, aout, opt);
     }
 
     /**
diff --git a/rs/java/android/renderscript/ScriptIntrinsicBlur.java b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
index d1a6fed..e7e33b8 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicBlur.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicBlur.java
@@ -16,10 +16,6 @@
 
 package android.renderscript;
 
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
 /**
  * Intrinsic Gausian blur filter. Applies a gaussian blur of the
  * specified radius to all elements of an allocation.
@@ -88,10 +84,23 @@
      *             type.
      */
     public void forEach(Allocation aout) {
-        forEach(0, null, aout, null);
+        forEach(aout, null);
     }
 
     /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation aout, Script.LaunchOptions opt) {
+        forEach(0, null, aout, null, opt);
+    }
+
+
+    /**
      * Get a KernelID for this intrinsic kernel.
      *
      * @return Script.KernelID The KernelID object.
diff --git a/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
index 601db17..57d917c 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicColorMatrix.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a color matrix to allocations.
  *
@@ -208,7 +206,6 @@
         setMatrix();
     }
 
-
     /**
      * Invoke the kernel and apply the matrix to each cell of input
      * {@link Allocation} and copy to the output {@link Allocation}.
@@ -225,6 +222,26 @@
      * @param aout Output allocation
      */
     public void forEach(Allocation ain, Allocation aout) {
+        forEach(ain, aout, null);
+    }
+
+    /**
+     * 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
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
         if (!ain.getElement().isCompatible(Element.U8(mRS)) &&
             !ain.getElement().isCompatible(Element.U8_2(mRS)) &&
             !ain.getElement().isCompatible(Element.U8_3(mRS)) &&
@@ -249,7 +266,7 @@
             throw new RSIllegalArgumentException("Unsuported element type.");
         }
 
-        forEach(0, ain, aout, null);
+        forEach(0, ain, aout, null, opt);
     }
 
     /**
diff --git a/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
index 25f3ee8..fb91fdc 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a 3x3 convolve to an allocation.
  *
@@ -108,7 +106,19 @@
      *             type.
      */
     public void forEach(Allocation aout) {
-        forEach(0, null, aout, null);
+        forEach(aout, null);
+    }
+
+    /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation aout, Script.LaunchOptions opt) {
+        forEach(0, null, aout, null, opt);
     }
 
     /**
diff --git a/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
index 71ea4cbc..0357560 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a 5x5 convolve to an allocation.
  *
@@ -109,10 +107,23 @@
      *             type.
      */
     public void forEach(Allocation aout) {
-        forEach(0, null, aout, null);
+        forEach(aout, null);
     }
 
     /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation aout, Script.LaunchOptions opt) {
+        forEach(0, null, aout, null, opt);
+    }
+
+
+    /**
      * Get a KernelID for this intrinsic kernel.
      *
      * @return Script.KernelID The KernelID object.
diff --git a/rs/java/android/renderscript/ScriptIntrinsicHistogram.java b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
index 42e4d04..95b610a 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicHistogram.java
@@ -16,10 +16,6 @@
 
 package android.renderscript;
 
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
 /**
  * Intrinsic Histogram filter.
  *
@@ -71,6 +67,24 @@
      * @param ain The input image
      */
     public void forEach(Allocation ain) {
+        forEach(ain, null);
+    }
+
+    /**
+     * 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
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation ain, Script.LaunchOptions opt) {
         if (ain.getType().getElement().getVectorSize() <
             mOut.getType().getElement().getVectorSize()) {
 
@@ -82,9 +96,11 @@
             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
         }
 
-        forEach(0, ain, null, null);
+        forEach(0, ain, null, null, opt);
     }
 
+
+
     /**
      * Set the coefficients used for the RGBA to Luminocity
      * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
@@ -141,6 +157,7 @@
         setVar(1, aout);
     }
 
+
     /**
      * Process an input buffer and place the histogram into the
      * output allocation. The dot product of the input channel and
@@ -152,6 +169,21 @@
      * @param ain The input image
      */
     public void forEach_Dot(Allocation ain) {
+        forEach_Dot(ain, null);
+    }
+
+    /**
+     * 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
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
         if (mOut.getType().getElement().getVectorSize() != 1) {
             throw new RSIllegalArgumentException("Output vector size must be one.");
         }
@@ -160,7 +192,7 @@
             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
         }
 
-        forEach(1, ain, null, null);
+        forEach(1, ain, null, null, opt);
     }
 
 
diff --git a/rs/java/android/renderscript/ScriptIntrinsicLUT.java b/rs/java/android/renderscript/ScriptIntrinsicLUT.java
index c45c015..69ff64a 100644
--- a/rs/java/android/renderscript/ScriptIntrinsicLUT.java
+++ b/rs/java/android/renderscript/ScriptIntrinsicLUT.java
@@ -16,8 +16,6 @@
 
 package android.renderscript;
 
-import android.util.Log;
-
 /**
  * Intrinsic for applying a per-channel lookup table. Each
  * channel of the input has an independant lookup table. The
@@ -116,7 +114,6 @@
         mDirty = true;
     }
 
-
     /**
      * Invoke the kernel and apply the lookup to each cell of ain
      * and copy to aout.
@@ -125,11 +122,23 @@
      * @param aout Output allocation
      */
     public void forEach(Allocation ain, Allocation aout) {
+        forEach(ain, aout, null);
+    }
+
+    /**
+     * Invoke the kernel and apply the lookup to each cell of ain
+     * and copy to aout.
+     *
+     * @param ain Input allocation
+     * @param aout Output allocation
+     * @param opt Options for clipping
+     */
+    public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
         if (mDirty) {
             mDirty = false;
             mTables.copyFromUnchecked(mCache);
         }
-        forEach(0, ain, aout, null);
+        forEach(0, ain, aout, null, opt);
     }
 
     /**
diff --git a/rs/java/android/renderscript/Short2.java b/rs/java/android/renderscript/Short2.java
index 070d608..24809f7 100644
--- a/rs/java/android/renderscript/Short2.java
+++ b/rs/java/android/renderscript/Short2.java
@@ -16,7 +16,10 @@
 
 package android.renderscript;
 
-/** 
+
+/**
+ * Class for exposing the native RenderScript Short2 type back to the Android system.
+ *
  * Vector version of the basic short type.
  * Provides two short fields packed.
  */
diff --git a/rs/java/android/renderscript/Type.java b/rs/java/android/renderscript/Type.java
index 1b5f1a2..98aeaa9 100644
--- a/rs/java/android/renderscript/Type.java
+++ b/rs/java/android/renderscript/Type.java
@@ -16,12 +16,6 @@
 
 package android.renderscript;
 
-
-import java.lang.reflect.Field;
-
-import android.graphics.ImageFormat;
-import android.util.Log;
-
 /**
  * <p>A Type describes the {@link android.renderscript.Element} and dimensions used for an {@link
  * android.renderscript.Allocation} or a parallel operation. Types are created through {@link
diff --git a/rs/jni/Android.mk b/rs/jni/Android.mk
index cbb5b3b..07933b4 100644
--- a/rs/jni/Android.mk
+++ b/rs/jni/Android.mk
@@ -23,8 +23,7 @@
 LOCAL_C_INCLUDES += \
 	$(JNI_H_INCLUDE) \
 	frameworks/rs \
-	$(rs_generated_include_dir) \
-	$(call include-path-for, corecg graphics)
+	$(rs_generated_include_dir)
 
 LOCAL_CFLAGS += -Wno-unused-parameter
 
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index 352bd49..671b43d 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -23,10 +23,7 @@
 #include <math.h>
 #include <utils/misc.h>
 
-#include <core/SkBitmap.h>
-#include <core/SkPixelRef.h>
-#include <core/SkStream.h>
-#include <core/SkTemplates.h>
+#include <SkBitmap.h>
 
 #include <androidfw/Asset.h>
 #include <androidfw/AssetManager.h>
@@ -392,7 +389,7 @@
     jint len = 0;
     if (data) {
         len = _env->GetArrayLength(data);
-        jint *ptr = _env->GetIntArrayElements(data, NULL);
+        ptr = _env->GetIntArrayElements(data, NULL);
     }
     LOG_API("nContextSendMessage, con(%p), id(%i), len(%i)", (RsContext)con, id, len);
     rsContextSendMessage((RsContext)con, id, (const uint8_t *)ptr, len * sizeof(int));
diff --git a/sax/java/android/sax/Element.java b/sax/java/android/sax/Element.java
index 8c8334c..c3e275f 100644
--- a/sax/java/android/sax/Element.java
+++ b/sax/java/android/sax/Element.java
@@ -21,8 +21,6 @@
 
 import java.util.ArrayList;
 
-import android.util.Log;
-
 /**
  * An XML element. Provides access to child elements and hooks to listen
  * for events related to this element.
diff --git a/services/Android.mk b/services/Android.mk
index 5260540..165f456 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -8,6 +8,10 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under,java)
 
+# EventLogTags files.
+LOCAL_SRC_FILES += \
+        core/java/com/android/server/EventLogTags.logtags
+
 # Uncomment to enable output of certain warnings (deprecated, unchecked)
 # LOCAL_JAVACFLAGS := -Xlint
 
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index ccac0d3..0edce11 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -61,24 +61,27 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.TextUtils.SimpleStringSplitter;
+import android.util.LongArray;
 import android.util.Pools.Pool;
 import android.util.Pools.SimplePool;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.IWindow;
-import android.view.IWindowManager;
 import android.view.InputDevice;
 import android.view.InputEventConsistencyVerifier;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
+import android.view.WindowInfo;
 import android.view.WindowManager;
+import android.view.WindowManagerInternal;
 import android.view.WindowManagerPolicy;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityInteractionClient;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
 import android.view.accessibility.IAccessibilityInteractionConnection;
 import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
 import android.view.accessibility.IAccessibilityManager;
@@ -87,6 +90,7 @@
 import com.android.internal.R;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.server.LocalServices;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -164,7 +168,7 @@
 
     private final PackageManager mPackageManager;
 
-    private final IWindowManager mWindowManagerService;
+    private final WindowManagerInternal mWindowManagerService;
 
     private final SecurityPolicy mSecurityPolicy;
 
@@ -195,9 +199,13 @@
 
     private int mCurrentUserId = UserHandle.USER_OWNER;
 
+    private final LongArray mTempLongArray = new LongArray();
+
     //TODO: Remove this hack
     private boolean mInitialized;
 
+    private WindowsForAccessibilityCallback mWindowsForAccessibilityCallback;
+
     private UserState getCurrentUserStateLocked() {
         return getUserStateLocked(mCurrentUserId);
     }
@@ -219,7 +227,7 @@
     public AccessibilityManagerService(Context context) {
         mContext = context;
         mPackageManager = mContext.getPackageManager();
-        mWindowManagerService = (IWindowManager) ServiceManager.getService(Context.WINDOW_SERVICE);
+        mWindowManagerService = LocalServices.getService(WindowManagerInternal.class);
         mSecurityPolicy = new SecurityPolicy();
         mMainHandler = new MainHandler(mContext.getMainLooper());
         //TODO: (multi-display) We need to support multiple displays.
@@ -388,7 +396,7 @@
             if (resolvedUserId != mCurrentUserId) {
                 return true; // yes, recycle the event
             }
-            if (mSecurityPolicy.canDispatchAccessibilityEvent(event)) {
+            if (mSecurityPolicy.canDispatchAccessibilityEventLocked(event)) {
                 mSecurityPolicy.updateEventSourceLocked(event);
                 mMainHandler.obtainMessage(MainHandler.MSG_UPDATE_ACTIVE_WINDOW,
                         event.getWindowId(), event.getEventType()).sendToTarget();
@@ -630,11 +638,7 @@
         mSecurityPolicy.enforceCallingPermission(
                 Manifest.permission.TEMPORARY_ENABLE_ACCESSIBILITY,
                 TEMPORARY_ENABLE_ACCESSIBILITY_UNTIL_KEYGUARD_REMOVED);
-        try {
-            if (!mWindowManagerService.isKeyguardLocked()) {
-                return;
-            }
-        } catch (RemoteException re) {
+        if (!mWindowManagerService.isKeyguardLocked()) {
             return;
         }
         synchronized (mLock) {
@@ -737,6 +741,8 @@
      * @param outBounds The output to which to write the bounds.
      */
     boolean getActiveWindowBounds(Rect outBounds) {
+        // TODO: This should be refactored to work with accessibility
+        // focus in multiple windows.
         IBinder token;
         synchronized (mLock) {
             final int windowId = mSecurityPolicy.mActiveWindowId;
@@ -745,13 +751,9 @@
                 token = getCurrentUserStateLocked().mWindowTokens.get(windowId);
             }
         }
-        try {
-            mWindowManagerService.getWindowFrame(token, outBounds);
-            if (!outBounds.isEmpty()) {
-                return true;
-            }
-        } catch (RemoteException re) {
-            /* ignore */
+        mWindowManagerService.getWindowFrame(token, outBounds);
+        if (!outBounds.isEmpty()) {
+            return true;
         }
         return false;
     }
@@ -769,7 +771,7 @@
     }
 
     void onMagnificationStateChanged() {
-        notifyClearAccessibilityNodeInfoCacheLocked();
+        notifyClearAccessibilityCacheLocked();
     }
 
     private void switchUser(int userId) {
@@ -877,7 +879,7 @@
         return false;
     }
 
-    private void notifyClearAccessibilityNodeInfoCacheLocked() {
+    private void notifyClearAccessibilityCacheLocked() {
         UserState state = getCurrentUserStateLocked();
         for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
             Service service = state.mBoundServices.get(i);
@@ -885,6 +887,16 @@
         }
     }
 
+    private void notifyWindowsChangedLocked(List<AccessibilityWindowInfo> windows) {
+        UserState state = getCurrentUserStateLocked();
+        for (int i = state.mBoundServices.size() - 1; i >= 0; i--) {
+            Service service = state.mBoundServices.get(i);
+            if (mSecurityPolicy.canRetrieveWindowsLocked(service)) {
+                service.notifyWindowsChangedLocked(windows);
+            }
+        }
+    }
+
     /**
      * Removes an AccessibilityInteractionConnection.
      *
@@ -992,7 +1004,8 @@
                 Service service = state.mBoundServices.get(i);
 
                 if (service.mIsDefault == isDefault) {
-                    if (canDispathEventLocked(service, event, state.mHandledFeedbackTypes)) {
+                    if (canDispatchEventToServiceLocked(service, event,
+                            state.mHandledFeedbackTypes)) {
                         state.mHandledFeedbackTypes |= service.mFeedbackType;
                         service.notifyAccessibilityEvent(event);
                     }
@@ -1041,7 +1054,7 @@
      * @param handledFeedbackTypes The feedback types for which services have been notified.
      * @return True if the listener should be notified, false otherwise.
      */
-    private boolean canDispathEventLocked(Service service, AccessibilityEvent event,
+    private boolean canDispatchEventToServiceLocked(Service service, AccessibilityEvent event,
             int handledFeedbackTypes) {
 
         if (!service.canReceiveEventsLocked()) {
@@ -1230,11 +1243,7 @@
             }
         }
         if (setInputFilter) {
-            try {
-                mWindowManagerService.setInputFilter(inputFilter);
-            } catch (RemoteException re) {
-                /* ignore */
-            }
+            mWindowManagerService.setInputFilter(inputFilter);
         }
     }
 
@@ -1294,13 +1303,52 @@
         mInitialized = true;
         updateLegacyCapabilities(userState);
         updateServicesLocked(userState);
+        updateWindowsForAccessibilityCallback(userState);
         updateFilterKeyEventsLocked(userState);
         updateTouchExplorationLocked(userState);
         updateEnhancedWebAccessibilityLocked(userState);
+        updateDisplayColorAdjustmentSettingsLocked(userState);
         scheduleUpdateInputFilter(userState);
         scheduleUpdateClientsIfNeededLocked(userState);
     }
 
+    private void updateWindowsForAccessibilityCallback(UserState userState) {
+        if (userState.mIsAccessibilityEnabled) {
+            // We observe windows for accessibility only if there is at least
+            // one bound service that can retrieve window content that specified
+            // it is interested in accessing such windows. For services that are
+            // binding we do an update pass after each bind event, so we run this
+            // code and register the callback if needed.
+            boolean boundServiceCanRetrieveInteractiveWindows = false;
+
+            List<Service> boundServices = userState.mBoundServices;
+            final int boundServiceCount = boundServices.size();
+            for (int i = 0; i < boundServiceCount; i++) {
+                Service boundService = boundServices.get(i);
+                if (mSecurityPolicy.canRetrieveWindowContentLocked(boundService)
+                        && boundService.mRetrieveInteractiveWindows) {
+                    boundServiceCanRetrieveInteractiveWindows = true;
+                    break;
+                }
+            }
+
+            if (boundServiceCanRetrieveInteractiveWindows) {
+                if (mWindowsForAccessibilityCallback == null) {
+                    mWindowsForAccessibilityCallback = new WindowsForAccessibilityCallback();
+                    mWindowManagerService.setWindowsForAccessibilityCallback(
+                            mWindowsForAccessibilityCallback);
+                }
+                return;
+            }
+        }
+
+        if (mWindowsForAccessibilityCallback != null) {
+            mWindowsForAccessibilityCallback = null;
+            mWindowManagerService.setWindowsForAccessibilityCallback(
+                    mWindowsForAccessibilityCallback);
+        }
+    }
+
     private void updateLegacyCapabilities(UserState userState) {
         // Up to JB-MR1 we had a white list with services that can enable touch
         // exploration. When a service is first started we show a dialog to the
@@ -1355,6 +1403,7 @@
         somthingChanged |= readTouchExplorationEnabledSettingLocked(userState);
         somthingChanged |= readEnhancedWebAccessibilityEnabledChangedLocked(userState);
         somthingChanged |= readDisplayMagnificationEnabledSettingLocked(userState);
+        somthingChanged |= readDisplayColorAdjustmentSettingsLocked(userState);
         return somthingChanged;
     }
 
@@ -1403,6 +1452,18 @@
          return false;
     }
 
+    private boolean readDisplayColorAdjustmentSettingsLocked(UserState userState) {
+        final boolean displayAdjustmentsEnabled = DisplayAdjustmentUtils.hasAdjustments(mContext,
+                userState.mUserId);
+        if (displayAdjustmentsEnabled != userState.mHasDisplayColorAdjustment) {
+            userState.mHasDisplayColorAdjustment = displayAdjustmentsEnabled;
+            return true;
+        }
+        // If display adjustment is enabled, always assume there was a change in
+        // the adjustment settings.
+        return displayAdjustmentsEnabled;
+    }
+
     private void updateTouchExplorationLocked(UserState userState) {
         boolean enabled = false;
         final int serviceCount = userState.mBoundServices.size();
@@ -1419,11 +1480,6 @@
                     Settings.Secure.TOUCH_EXPLORATION_ENABLED, enabled ? 1 : 0,
                     userState.mUserId);
         }
-        try {
-            mWindowManagerService.setTouchExplorationEnabled(enabled);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
     }
 
     private boolean canRequestAndRequestsTouchExplorationLocked(Service service) {
@@ -1490,6 +1546,10 @@
         return false;
     }
 
+    private void updateDisplayColorAdjustmentSettingsLocked(UserState userState) {
+        DisplayAdjustmentUtils.applyAdjustments(mContext, userState.mUserId);
+    }
+
     @Override
     public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
         mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
@@ -1585,6 +1645,7 @@
                     }
                     event.recycle();
                 } break;
+
                 case MSG_SEND_KEY_EVENT_TO_INPUT_FILTER: {
                     KeyEvent event = (KeyEvent) msg.obj;
                     final int policyFlags = msg.arg1;
@@ -1595,28 +1656,34 @@
                     }
                     event.recycle();
                 } break;
+
                 case MSG_SEND_STATE_TO_CLIENTS: {
                     final int clientState = msg.arg1;
                     final int userId = msg.arg2;
                     sendStateToClients(clientState, mGlobalClients);
                     sendStateToClientsForUser(clientState, userId);
                 } break;
+
                 case MSG_SEND_CLEARED_STATE_TO_CLIENTS_FOR_USER: {
                     final int userId = msg.arg1;
                     sendStateToClientsForUser(0, userId);
                 } break;
+
                 case MSG_UPDATE_ACTIVE_WINDOW: {
                     final int windowId = msg.arg1;
                     final int eventType = msg.arg2;
                     mSecurityPolicy.updateActiveWindow(windowId, eventType);
                 } break;
+
                 case MSG_ANNOUNCE_NEW_USER_IF_NEEDED: {
                     announceNewUserIfNeeded();
                 } break;
+
                 case MSG_UPDATE_INPUT_FILTER: {
                     UserState userState = (UserState) msg.obj;
                     updateInputFilter(userState);
                 } break;
+
                 case MSG_SHOW_ENABLED_TOUCH_EXPLORATION_DIALOG: {
                     Service service = (Service) msg.obj;
                     showEnableTouchExplorationDialog(service);
@@ -1635,7 +1702,6 @@
                     AccessibilityEvent event = AccessibilityEvent.obtain(
                             AccessibilityEvent.TYPE_ANNOUNCEMENT);
                     event.getText().add(message);
-                    event.setWindowId(mSecurityPolicy.getRetrievalAllowingWindowLocked());
                     sendAccessibilityEvent(event, mCurrentUserId);
                 }
             }
@@ -1683,6 +1749,19 @@
         mPendingEventPool.release(pendingEvent);
     }
 
+    private int findWindowIdLocked(IBinder token) {
+        final int globalIndex = mGlobalWindowTokens.indexOfValue(token);
+        if (globalIndex >= 0) {
+            return mGlobalWindowTokens.keyAt(globalIndex);
+        }
+        UserState userState = getCurrentUserStateLocked();
+        final int userIndex = userState.mWindowTokens.indexOfValue(token);
+        if (userIndex >= 0) {
+            return userState.mWindowTokens.keyAt(userIndex);
+        }
+        return -1;
+    }
+
     /**
      * This class represents an accessibility service. It stores all per service
      * data required for the service management, provides API for starting/stopping the
@@ -1718,6 +1797,8 @@
 
         boolean mRequestFilterKeyEvents;
 
+        boolean mRetrieveInteractiveWindows;
+
         int mFetchFlags;
 
         long mNotificationTimeout;
@@ -1728,7 +1809,9 @@
 
         boolean mIsAutomation;
 
-        final Rect mTempBounds = new Rect();
+        final Rect mTempBounds1 = new Rect();
+
+        final Rect mTempBounds2 = new Rect();
 
         final ResolveInfo mResolveInfo;
 
@@ -1738,6 +1821,9 @@
 
         final KeyEventDispatcher mKeyEventDispatcher = new KeyEventDispatcher();
 
+        final SparseArray<AccessibilityWindowInfo> mIntrospectedWindows =
+                new SparseArray<AccessibilityWindowInfo>();
+
         boolean mWasConnectedAndDied;
 
         // Handler only for dispatching accessibility events since we use event
@@ -1802,7 +1888,13 @@
             mRequestEnhancedWebAccessibility = (info.flags
                     & AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY) != 0;
             mRequestFilterKeyEvents = (info.flags
-                    & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS)  != 0;
+                    & AccessibilityServiceInfo.FLAG_REQUEST_FILTER_KEY_EVENTS) != 0;
+            mRetrieveInteractiveWindows = (info.flags
+                    & AccessibilityServiceInfo.FLAG_RETRIEVE_INTERACTIVE_WINDOWS) != 0;
+
+            if (!mRetrieveInteractiveWindows) {
+                clearIntrospectedWindows();
+            }
         }
 
         /**
@@ -1912,6 +2004,59 @@
         }
 
         @Override
+        public List<AccessibilityWindowInfo> getWindows() {
+            synchronized (mLock) {
+                final int resolvedUserId = mSecurityPolicy
+                        .resolveCallingUserIdEnforcingPermissionsLocked(
+                                UserHandle.getCallingUserId());
+                if (resolvedUserId != mCurrentUserId) {
+                    return null;
+                }
+                final boolean permissionGranted =
+                        mSecurityPolicy.canRetrieveWindowsLocked(this);
+                if (!permissionGranted) {
+                    return null;
+                }
+                List<AccessibilityWindowInfo> windows = new ArrayList<AccessibilityWindowInfo>();
+                final int windowCount = mSecurityPolicy.mWindows.size();
+                for (int i = 0; i < windowCount; i++) {
+                    AccessibilityWindowInfo window = mSecurityPolicy.mWindows.get(i);
+                    AccessibilityWindowInfo windowClone =
+                            AccessibilityWindowInfo.obtain(window);
+                    windowClone.setConnectionId(mId);
+                    mIntrospectedWindows.put(window.getId(), windowClone);
+                    windows.add(windowClone);
+                }
+                return windows;
+            }
+        }
+
+        @Override
+        public AccessibilityWindowInfo getWindow(int windowId) {
+            synchronized (mLock) {
+                final int resolvedUserId = mSecurityPolicy
+                        .resolveCallingUserIdEnforcingPermissionsLocked(
+                                UserHandle.getCallingUserId());
+                if (resolvedUserId != mCurrentUserId) {
+                    return null;
+                }
+                final boolean permissionGranted =
+                        mSecurityPolicy.canRetrieveWindowsLocked(this);
+                if (!permissionGranted) {
+                    return null;
+                }
+                AccessibilityWindowInfo window = mSecurityPolicy.findWindowById(windowId);
+                if (window != null) {
+                    AccessibilityWindowInfo windowClone = AccessibilityWindowInfo.obtain(window);
+                    windowClone.setConnectionId(mId);
+                    mIntrospectedWindows.put(windowId, windowClone);
+                    return windowClone;
+                }
+                return null;
+            }
+        }
+
+        @Override
         public boolean findAccessibilityNodeInfosByViewId(int accessibilityWindowId,
                 long accessibilityNodeId, String viewIdResName, int interactionId,
                 IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
@@ -1925,12 +2070,12 @@
                 if (resolvedUserId != mCurrentUserId) {
                     return false;
                 }
-                mSecurityPolicy.enforceCanRetrieveWindowContent(this);
-                final boolean permissionGranted = mSecurityPolicy.canRetrieveWindowContent(this);
+                resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
+                final boolean permissionGranted =
+                        mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
                 if (!permissionGranted) {
                     return false;
                 } else {
-                    resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
                     connection = getConnectionLocked(resolvedWindowId);
                     if (connection == null) {
                         return false;
@@ -1969,7 +2114,6 @@
                 if (resolvedUserId != mCurrentUserId) {
                     return false;
                 }
-                mSecurityPolicy.enforceCanRetrieveWindowContent(this);
                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
                 final boolean permissionGranted =
                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
@@ -2014,7 +2158,6 @@
                 if (resolvedUserId != mCurrentUserId) {
                     return false;
                 }
-                mSecurityPolicy.enforceCanRetrieveWindowContent(this);
                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
                 final boolean permissionGranted =
                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
@@ -2059,7 +2202,6 @@
                 if (resolvedUserId != mCurrentUserId) {
                     return false;
                 }
-                mSecurityPolicy.enforceCanRetrieveWindowContent(this);
                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
                 final boolean permissionGranted =
                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
@@ -2103,7 +2245,6 @@
                 if (resolvedUserId != mCurrentUserId) {
                     return false;
                 }
-                mSecurityPolicy.enforceCanRetrieveWindowContent(this);
                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
                 final boolean permissionGranted =
                     mSecurityPolicy.canGetAccessibilityNodeInfoLocked(this, resolvedWindowId);
@@ -2147,7 +2288,6 @@
                 if (resolvedUserId != mCurrentUserId) {
                     return false;
                 }
-                mSecurityPolicy.enforceCanRetrieveWindowContent(this);
                 resolvedWindowId = resolveAccessibilityWindowIdLocked(accessibilityWindowId);
                 final boolean permissionGranted = mSecurityPolicy.canPerformActionLocked(this,
                         resolvedWindowId, action, arguments);
@@ -2345,7 +2485,7 @@
                 }
 
                 mPendingEvents.remove(eventType);
-                if (mSecurityPolicy.canRetrieveWindowContent(this)) {
+                if (mSecurityPolicy.canRetrieveWindowContentLocked(this)) {
                     event.setConnectionId(mId);
                 } else {
                     event.setSource(null);
@@ -2376,12 +2516,69 @@
         }
 
         public void notifyClearAccessibilityNodeInfoCache() {
+            clearIntrospectedWindows();
             mInvocationHandler.sendEmptyMessage(
-                    InvocationHandler.MSG_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE);
+                    InvocationHandler.MSG_CLEAR_ACCESSIBILITY_CACHE);
+        }
+
+        private void clearIntrospectedWindows() {
+            final int windowCount = mIntrospectedWindows.size();
+            for (int i = windowCount - 1; i >= 0; i--) {
+                mIntrospectedWindows.valueAt(i).recycle();
+                mIntrospectedWindows.removeAt(i);
+            }
+        }
+
+        public void notifyWindowsChangedLocked(List<AccessibilityWindowInfo> windows) {
+            LongArray changedWindows = mTempLongArray;
+            changedWindows.clear();
+
+            // Figure out which windows the service cares about changed.
+            final int windowCount = windows.size();
+            for (int i = 0; i < windowCount; i++) {
+                AccessibilityWindowInfo newState = windows.get(i);
+                final int windowId = newState.getId();
+                AccessibilityWindowInfo oldState = mIntrospectedWindows.get(windowId);
+                if (oldState != null && oldState.changed(newState)) {
+                    oldState.recycle();
+                    mIntrospectedWindows.put(newState.getId(),
+                            AccessibilityWindowInfo.obtain(newState));
+                    changedWindows.add(windowId);
+                }
+            }
+
+            // Figure out which windows the service cares about went away.
+            final int introspectedWindowCount = mIntrospectedWindows.size();
+            for (int i = introspectedWindowCount - 1; i >= 0; i--) {
+                AccessibilityWindowInfo window = mIntrospectedWindows.valueAt(i);
+                if (changedWindows.indexOf(window.getId()) < 0 && !windows.contains(window)) {
+                    changedWindows.add(window.getId());
+                    mIntrospectedWindows.removeAt(i);
+                    window.recycle();
+                }
+            }
+
+            int[] windowIds = null;
+
+            final int changedWindowCount = changedWindows.size();
+            if (changedWindowCount > 0) {
+                windowIds = new int[changedWindowCount];
+                for (int i = 0; i < changedWindowCount; i++) {
+                    // Cast is fine as we use long array to cache ints.
+                    windowIds[i] = (int) changedWindows.get(i);
+                }
+                changedWindows.clear();
+            }
+
+            mInvocationHandler.obtainMessage(InvocationHandler.MSG_ON_WINDOWS_CHANGED,
+                    windowIds).sendToTarget();
         }
 
         private void notifyGestureInternal(int gestureId) {
-            IAccessibilityServiceClient listener = mServiceInterface;
+            final IAccessibilityServiceClient listener;
+            synchronized (mLock) {
+                listener = mServiceInterface;
+            }
             if (listener != null) {
                 try {
                     listener.onGesture(gestureId);
@@ -2396,11 +2593,14 @@
             mKeyEventDispatcher.notifyKeyEvent(event, policyFlags);
         }
 
-        private void notifyClearAccessibilityNodeInfoCacheInternal() {
-            IAccessibilityServiceClient listener = mServiceInterface;
+        private void notifyClearAccessibilityCacheInternal() {
+            final IAccessibilityServiceClient listener;
+            synchronized (mLock) {
+                listener = mServiceInterface;
+            }
             if (listener != null) {
                 try {
-                    listener.clearAccessibilityNodeInfoCache();
+                    listener.clearAccessibilityCache();
                 } catch (RemoteException re) {
                     Slog.e(LOG_TAG, "Error during requesting accessibility info cache"
                             + " to be cleared.", re);
@@ -2408,6 +2608,20 @@
             }
         }
 
+        private void notifyWindowsChangedInternal(int[] windowIds) {
+            final IAccessibilityServiceClient listener;
+            synchronized (mLock) {
+                listener = mServiceInterface;
+            }
+            if (listener != null) {
+                try {
+                    listener.onWindowsChanged(windowIds);
+                } catch (RemoteException re) {
+                    Slog.e(LOG_TAG, "Error during sending windows to: " + mService, re);
+                }
+            }
+        }
+
         private void sendDownAndUpKeyEvents(int keyCode) {
             final long token = Binder.clearCallingIdentity();
 
@@ -2491,27 +2705,23 @@
         }
 
         private MagnificationSpec getCompatibleMagnificationSpec(int windowId) {
-            try {
-                IBinder windowToken = mGlobalWindowTokens.get(windowId);
-                if (windowToken == null) {
-                    windowToken = getCurrentUserStateLocked().mWindowTokens.get(windowId);
-                }                    
-                if (windowToken != null) {
-                    return mWindowManagerService.getCompatibleMagnificationSpecForWindow(
-                            windowToken);
-                }
-            } catch (RemoteException re) {
-                /* ignore */
+            IBinder windowToken = mGlobalWindowTokens.get(windowId);
+            if (windowToken == null) {
+                windowToken = getCurrentUserStateLocked().mWindowTokens.get(windowId);
+            }
+            if (windowToken != null) {
+                return mWindowManagerService.getCompatibleMagnificationSpecForWindow(
+                        windowToken);
             }
             return null;
         }
 
         private final class InvocationHandler extends Handler {
-
             public static final int MSG_ON_GESTURE = 1;
             public static final int MSG_ON_KEY_EVENT = 2;
-            public static final int MSG_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE = 3;
+            public static final int MSG_CLEAR_ACCESSIBILITY_CACHE = 3;
             public static final int MSG_ON_KEY_EVENT_TIMEOUT = 4;
+            public static final int MSG_ON_WINDOWS_CHANGED = 5;
 
             public InvocationHandler(Looper looper) {
                 super(looper, null, true);
@@ -2525,18 +2735,27 @@
                         final int gestureId = message.arg1;
                         notifyGestureInternal(gestureId);
                     } break;
+
                     case MSG_ON_KEY_EVENT: {
                         KeyEvent event = (KeyEvent) message.obj;
                         final int policyFlags = message.arg1;
                         notifyKeyEventInternal(event, policyFlags);
                     } break;
-                    case MSG_CLEAR_ACCESSIBILITY_NODE_INFO_CACHE: {
-                        notifyClearAccessibilityNodeInfoCacheInternal();
+
+                    case MSG_CLEAR_ACCESSIBILITY_CACHE: {
+                        notifyClearAccessibilityCacheInternal();
                     } break;
+
                     case MSG_ON_KEY_EVENT_TIMEOUT: {
                         PendingEvent eventState = (PendingEvent) message.obj;
                         setOnKeyEventResult(false, eventState.sequence);
                     } break;
+
+                    case MSG_ON_WINDOWS_CHANGED: {
+                        final int[] windowIds = (int[]) message.obj;
+                        notifyWindowsChangedInternal(windowIds);
+                    } break;
+
                     default: {
                         throw new IllegalArgumentException("Unknown message: " + type);
                     }
@@ -2680,6 +2899,113 @@
         }
     }
 
+    final class WindowsForAccessibilityCallback implements
+            WindowManagerInternal.WindowsForAccessibilityCallback {
+
+        @Override
+        public void onWindowsForAccessibilityChanged(List<WindowInfo> windows) {
+            synchronized (mLock) {
+                List<WindowInfo> receivedWindows = (List<WindowInfo>) windows;
+
+                // Populate the windows to report.
+                List<AccessibilityWindowInfo> reportedWindows =
+                        new ArrayList<AccessibilityWindowInfo>();
+                final int receivedWindowCount = receivedWindows.size();
+                for (int i = 0; i < receivedWindowCount; i++) {
+                    WindowInfo receivedWindow = receivedWindows.get(i);
+                    AccessibilityWindowInfo reportedWindow = populateReportedWindow(
+                            receivedWindow);
+                    if (reportedWindow != null) {
+                        reportedWindows.add(reportedWindow);
+                    }
+                }
+
+                if (DEBUG) {
+                    Slog.i(LOG_TAG, "Windows changed: " + reportedWindows);
+                }
+
+                // Let the policy update the focused and active windows.
+                mSecurityPolicy.updateWindowsLocked(reportedWindows);
+            }
+        }
+
+        private AccessibilityWindowInfo populateReportedWindow(WindowInfo window) {
+            final int windowId = findWindowIdLocked(window.token);
+            if (windowId < 0) {
+                return null;
+            }
+
+            AccessibilityWindowInfo reportedWindow = AccessibilityWindowInfo.obtain();
+
+            reportedWindow.setId(windowId);
+            reportedWindow.setType(getTypeForWindowManagerWindowType(window.type));
+            reportedWindow.setLayer(window.layer);
+            reportedWindow.setFocused(window.focused);
+            reportedWindow.setBoundsInScreen(window.boundsInScreen);
+
+            final int parentId = findWindowIdLocked(window.parentToken);
+            if (parentId >= 0) {
+                reportedWindow.setParentId(parentId);
+            }
+
+            if (window.childTokens != null) {
+                final int childCount = window.childTokens.size();
+                for (int i = 0; i < childCount; i++) {
+                    IBinder childToken = window.childTokens.get(i);
+                    final int childId = findWindowIdLocked(childToken);
+                    if (childId >= 0) {
+                        reportedWindow.addChild(childId);
+                    }
+                }
+            }
+
+            return reportedWindow;
+        }
+
+        private int getTypeForWindowManagerWindowType(int windowType) {
+            switch (windowType) {
+                case WindowManager.LayoutParams.TYPE_APPLICATION:
+                case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
+                case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
+                case WindowManager.LayoutParams.TYPE_APPLICATION_STARTING:
+                case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
+                case WindowManager.LayoutParams.TYPE_BASE_APPLICATION:
+                case WindowManager.LayoutParams.TYPE_PHONE:
+                case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
+                case WindowManager.LayoutParams.TYPE_TOAST:
+                case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG: {
+                    return AccessibilityWindowInfo.TYPE_APPLICATION;
+                }
+
+                case WindowManager.LayoutParams.TYPE_INPUT_METHOD:
+                case WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG: {
+                    return AccessibilityWindowInfo.TYPE_INPUT_METHOD;
+                }
+
+                case WindowManager.LayoutParams.TYPE_KEYGUARD:
+                case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
+                case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR:
+                case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
+                case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
+                case WindowManager.LayoutParams.TYPE_STATUS_BAR:
+                case WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL:
+                case WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL:
+                case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY:
+                case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
+                case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
+                case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
+                case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
+                case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY: {
+                    return AccessibilityWindowInfo.TYPE_SYSTEM;
+                }
+
+                default: {
+                    return -1;
+                }
+            }
+        }
+    }
+
     final class SecurityPolicy {
         private static final int VALID_ACTIONS =
             AccessibilityNodeInfo.ACTION_CLICK
@@ -2702,7 +3028,8 @@
             | AccessibilityNodeInfo.ACTION_SET_SELECTION
             | AccessibilityNodeInfo.ACTION_EXPAND
             | AccessibilityNodeInfo.ACTION_COLLAPSE
-            | AccessibilityNodeInfo.ACTION_DISMISS;
+            | AccessibilityNodeInfo.ACTION_DISMISS
+            | AccessibilityNodeInfo.ACTION_SET_TEXT;
 
         private static final int RETRIEVAL_ALLOWING_EVENT_TYPES =
             AccessibilityEvent.TYPE_VIEW_CLICKED
@@ -2717,17 +3044,37 @@
             | AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED
             | AccessibilityEvent.TYPE_VIEW_SCROLLED
             | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED
-            | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED;
+            | AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED
+            | AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY;
 
-        private int mActiveWindowId;
+        public final List<AccessibilityWindowInfo> mWindows =
+                new ArrayList<AccessibilityWindowInfo>();
+
+        public int mActiveWindowId;
+        public int mFocusedWindowId;
+        public AccessibilityEvent mShowingFocusedWindowEvent;
+
         private boolean mTouchInteractionInProgress;
 
-        private boolean canDispatchAccessibilityEvent(AccessibilityEvent event) {
+        private boolean canDispatchAccessibilityEventLocked(AccessibilityEvent event) {
             final int eventType = event.getEventType();
             switch (eventType) {
                 // All events that are for changes in a global window
                 // state should *always* be dispatched.
                 case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
+                    if (mWindowsForAccessibilityCallback != null) {
+                        // OK, this is fun. Sometimes the focused window is notified
+                        // it has focus before being shown. Historically this event
+                        // means that the window is focused and can be introspected.
+                        // But we still have not gotten the window state from the
+                        // window manager, so delay the notification until then.
+                        AccessibilityWindowInfo window = findWindowById(event.getWindowId());
+                        if (window == null || !window.isFocused()) {
+                            mShowingFocusedWindowEvent = AccessibilityEvent.obtain(event);
+                            return false;
+                        }
+                    }
+                // $fall-through$
                 case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                 // All events generated by the user touching the
                 // screen should *always* be dispatched.
@@ -2737,15 +3084,81 @@
                 case AccessibilityEvent.TYPE_GESTURE_DETECTION_END:
                 case AccessibilityEvent.TYPE_TOUCH_INTERACTION_START:
                 case AccessibilityEvent.TYPE_TOUCH_INTERACTION_END:
-                // These will change the active window, so dispatch.
                 case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER:
                 case AccessibilityEvent.TYPE_VIEW_HOVER_EXIT: {
                     return true;
                 }
                 // All events for changes in window content should be
-                // dispatched *only* if this window is the active one.
-                default:
-                    return event.getWindowId() == mActiveWindowId;
+                // dispatched *only* if this window is one of the windows
+                // the accessibility layer reports which are windows
+                // that a sighted user can touch.
+                default: {
+                    return isRetrievalAllowingWindow(event.getWindowId());
+                }
+            }
+        }
+
+        public void updateWindowsLocked(List<AccessibilityWindowInfo> windows) {
+            final int oldWindowCount = mWindows.size();
+            for (int i = oldWindowCount - 1; i >= 0; i--) {
+                mWindows.remove(i).recycle();
+            }
+
+            mFocusedWindowId = -1;
+            if (!mTouchInteractionInProgress) {
+                mActiveWindowId = -1;
+            }
+
+            // If the active window goes away while the user is touch exploring we
+            // reset the active window id and wait for the next hover event from
+            // under the user's finger to determine which one is the new one. It
+            // is possible that the finger is not moving and the input system
+            // filters out such events.
+            boolean activeWindowGone = true;
+
+            final int windowCount = windows.size();
+            if (windowCount > 0) {
+                for (int i = 0; i < windowCount; i++) {
+                    AccessibilityWindowInfo window = windows.get(i);
+                    final int windowId = window.getId();
+                    if (window.isFocused()) {
+                        mFocusedWindowId = windowId;
+                        if (!mTouchInteractionInProgress) {
+                            mActiveWindowId = windowId;
+                            window.setActive(true);
+                        } else if (windowId == mActiveWindowId) {
+                            activeWindowGone = false;
+                        }
+                    }
+                    mWindows.add(window);
+                }
+
+                if (mTouchInteractionInProgress && activeWindowGone) {
+                    mActiveWindowId = -1;
+                }
+
+                // Focused window may change the active one, so set the
+                // active window once we decided which it is.
+                for (int i = 0; i < windowCount; i++) {
+                    AccessibilityWindowInfo window = mWindows.get(i);
+                    if (window.getId() == mActiveWindowId) {
+                       window.setActive(true);
+                    }
+                }
+            }
+
+            notifyWindowsChangedLocked(mWindows);
+
+            // If we are delaying a window state change event as the window
+            // source was showing when it was fired, now is the time to send.
+            if (mShowingFocusedWindowEvent != null) {
+                final int windowId = mShowingFocusedWindowEvent.getWindowId();
+                AccessibilityWindowInfo window = findWindowById(windowId);
+                if (window != null && window.isFocused()) {
+                    // Sending does the recycle.
+                    sendAccessibilityEvent(mShowingFocusedWindowEvent, mCurrentUserId);
+                }
+                mShowingFocusedWindowEvent = null;
             }
         }
 
@@ -2760,67 +3173,96 @@
             // the window that the user is currently touching. If the user is
             // touching a window that does not have input focus as soon as the
             // the user stops touching that window the focused window becomes
-            // the active one.
+            // the active one. Here we detect the touched window and make it
+            // active. In updateWindowsLocked() we update the focused window
+            // and if the user is not touching the screen, we make the focused
+            // window the active one.
             switch (eventType) {
                 case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED: {
-                    if (getFocusedWindowId() == windowId) {
-                        mActiveWindowId = windowId;
+                    // If no service has the capability to introspect screen,
+                    // we do not register callback in the window manager for
+                    // window changes, so we have to ask the window manager
+                    // what the focused window is to update the active one.
+                    // The active window also determined events from which
+                    // windows are delivered.
+                    boolean focusedWindowActive = false;
+                    synchronized (mLock) {
+                        if (mWindowsForAccessibilityCallback == null) {
+                            focusedWindowActive = true;
+                        }
+                    }
+                    if (focusedWindowActive) {
+                        if (windowId == getFocusedWindowId()) {
+                            synchronized (mLock) {
+                                mActiveWindowId = windowId;
+                            }
+                        }
                     }
                 } break;
+
                 case AccessibilityEvent.TYPE_VIEW_HOVER_ENTER: {
                     // Do not allow delayed hover events to confuse us
                     // which the active window is.
-                    if (mTouchInteractionInProgress) {
-                        mActiveWindowId = windowId;
+                    synchronized (mLock) {
+                        if (mTouchInteractionInProgress && mActiveWindowId != windowId) {
+                            setActiveWindowLocked(windowId);
+                        }
                     }
                 } break;
             }
         }
 
         public void onTouchInteractionStart() {
-            mTouchInteractionInProgress = true;
+            synchronized (mLock) {
+                mTouchInteractionInProgress = true;
+            }
         }
 
         public void onTouchInteractionEnd() {
-            mTouchInteractionInProgress = false;
-            // We want to set the active window to be current immediately
-            // after the user has stopped touching the screen since if the
-            // user types with the IME he should get a feedback for the
-            // letter typed in the text view which is in the input focused
-            // window. Note that we always deliver hover accessibility events
-            // (they are a result of user touching the screen) so change of
-            // the active window before all hover accessibility events from
-            // the touched window are delivered is fine.
-            mActiveWindowId = getFocusedWindowId();
+            synchronized (mLock) {
+                mTouchInteractionInProgress = false;
+                // We want to set the active window to be current immediately
+                // after the user has stopped touching the screen since if the
+                // user types with the IME he should get a feedback for the
+                // letter typed in the text view which is in the input focused
+                // window. Note that we always deliver hover accessibility events
+                // (they are a result of user touching the screen) so change of
+                // the active window before all hover accessibility events from
+                // the touched window are delivered is fine.
+                setActiveWindowLocked(mFocusedWindowId);
+            }
         }
 
-        public int getRetrievalAllowingWindowLocked() {
-            return mActiveWindowId;
+        private void setActiveWindowLocked(int windowId) {
+            if (mActiveWindowId != windowId) {
+                mActiveWindowId = windowId;
+                final int windowCount = mWindows.size();
+                for (int i = 0; i < windowCount; i++) {
+                    AccessibilityWindowInfo window = mWindows.get(i);
+                    window.setActive(window.getId() == windowId);
+                }
+                notifyWindowsChangedLocked(mWindows);
+            }
         }
 
         public boolean canGetAccessibilityNodeInfoLocked(Service service, int windowId) {
-            return canRetrieveWindowContent(service) && isRetrievalAllowingWindow(windowId);
+            return canRetrieveWindowContentLocked(service) && isRetrievalAllowingWindow(windowId);
         }
 
         public boolean canPerformActionLocked(Service service, int windowId, int action,
                 Bundle arguments) {
-            return canRetrieveWindowContent(service)
+            return canRetrieveWindowContentLocked(service)
                 && isRetrievalAllowingWindow(windowId)
                 && isActionPermitted(action);
         }
 
-        public boolean canRetrieveWindowContent(Service service) {
-            return (service.mAccessibilityServiceInfo.getCapabilities()
-                    & AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
+        public boolean canRetrieveWindowsLocked(Service service) {
+            return canRetrieveWindowContentLocked(service) && service.mRetrieveInteractiveWindows;
         }
 
-        public void enforceCanRetrieveWindowContent(Service service) throws RemoteException {
-            // This happens due to incorrect registration so make it apparent.
-            if (!canRetrieveWindowContent(service)) {
-                Slog.e(LOG_TAG, "Accessibility serivce " + service.mComponentName + " does not " +
-                        "declare android:canRetrieveWindowContent.");
-                throw new RemoteException();
-            }
+        public boolean canRetrieveWindowContentLocked(Service service) {
+            return (service.mAccessibilityServiceInfo.getCapabilities()
+                    & AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT) != 0;
         }
 
         public int resolveCallingUserIdEnforcingPermissionsLocked(int userId) {
@@ -2857,7 +3299,21 @@
         }
 
         private boolean isRetrievalAllowingWindow(int windowId) {
-            return (mActiveWindowId == windowId);
+            if (windowId == mActiveWindowId) {
+                return true;
+            }
+            return findWindowById(windowId) != null;
+        }
+
+        private AccessibilityWindowInfo findWindowById(int windowId) {
+            final int windowCount = mWindows.size();
+            for (int i = 0; i < windowCount; i++) {
+                AccessibilityWindowInfo window = mWindows.get(i);
+                if (window.getId() == windowId) {
+                    return window;
+                }
+            }
+            return null;
         }
 
         private boolean isActionPermitted(int action) {
@@ -2880,35 +3336,8 @@
         }
 
         private int getFocusedWindowId() {
-            try {
-                // We call this only on window focus change or after touch
-                // exploration gesture end and the shown windows are not that
-                // many, so the linear look up is just fine.
-                IBinder token = mWindowManagerService.getFocusedWindowToken();
-                if (token != null) {
-                    synchronized (mLock) {
-                        int windowId = getFocusedWindowIdLocked(token, mGlobalWindowTokens);
-                        if (windowId < 0) {
-                            windowId = getFocusedWindowIdLocked(token,
-                                    getCurrentUserStateLocked().mWindowTokens);
-                        }
-                        return windowId;
-                    }
-                }
-            } catch (RemoteException re) {
-                /* ignore */
-            }
-            return -1;
-        }
-
-        private int getFocusedWindowIdLocked(IBinder token, SparseArray<IBinder> windows) {
-            final int windowCount = windows.size();
-            for (int i = 0; i < windowCount; i++) {
-                if (windows.valueAt(i) == token) {
-                    return windows.keyAt(i);
-                }
-            }
-            return -1;
+            IBinder token = mWindowManagerService.getFocusedWindowToken();
+            return findWindowIdLocked(token);
         }
     }
 
@@ -2952,6 +3381,7 @@
         public boolean mIsEnhancedWebAccessibilityEnabled;
         public boolean mIsDisplayMagnificationEnabled;
         public boolean mIsFilterKeyEventsEnabled;
+        public boolean mHasDisplayColorAdjustment;
 
         private Service mUiAutomationService;
         private IAccessibilityServiceClient mUiAutomationServiceClient;
@@ -3043,6 +3473,23 @@
         private final Uri mEnhancedWebAccessibilityUri = Settings.Secure
                 .getUriFor(Settings.Secure.ACCESSIBILITY_SCRIPT_INJECTION);
 
+        private final Uri mDisplayContrastEnabledUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED);
+        private final Uri mDisplayContrastUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST);
+        private final Uri mDisplayBrightnessUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS);
+
+        private final Uri mDisplayInversionEnabledUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+        private final Uri mDisplayInversionUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION);
+
+        private final Uri mDisplayDaltonizerEnabledUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
+        private final Uri mDisplayDaltonizerUri = Settings.Secure.getUriFor(
+                Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER);
+
         public AccessibilityContentObserver(Handler handler) {
             super(handler);
         }
@@ -3061,6 +3508,20 @@
                     false, this, UserHandle.USER_ALL);
             contentResolver.registerContentObserver(mEnhancedWebAccessibilityUri,
                     false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayContrastEnabledUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayContrastUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayBrightnessUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayInversionEnabledUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayInversionUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayDaltonizerEnabledUri, false, this, UserHandle.USER_ALL);
+            contentResolver.registerContentObserver(
+                    mDisplayDaltonizerUri, false, this, UserHandle.USER_ALL);
         }
 
         @Override
@@ -3125,6 +3586,22 @@
                         }
                     }
                 }
+            } else if (mDisplayContrastEnabledUri.equals(uri)
+                    || mDisplayInversionEnabledUri.equals(uri)
+                    || mDisplayDaltonizerEnabledUri.equals(uri)
+                    || mDisplayContrastUri.equals(uri)
+                    || mDisplayBrightnessUri.equals(uri)
+                    || mDisplayInversionUri.equals(uri)
+                    || mDisplayDaltonizerUri.equals(uri)) {
+                synchronized (mLock) {
+                    // We will update when the automation service dies.
+                    UserState userState = getCurrentUserStateLocked();
+                    if (userState.mUiAutomationService == null) {
+                        if (readDisplayColorAdjustmentSettingsLocked(userState)) {
+                            updateDisplayColorAdjustmentSettingsLocked(userState);
+                        }
+                    }
+                }
             }
         }
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java b/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
new file mode 100644
index 0000000..52bdeda
--- /dev/null
+++ b/services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.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.server.accessibility;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.opengl.Matrix;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.util.Slog;
+import android.view.accessibility.AccessibilityManager;
+
+/**
+ * Utility methods for performing accessibility display adjustments.
+ */
+class DisplayAdjustmentUtils {
+    private static final String LOG_TAG = DisplayAdjustmentUtils.class.getSimpleName();
+
+    /** Matrix and offset used for converting color to gray-scale. */
+    private static final float[] GRAYSCALE_MATRIX = new float[] {
+        .2126f, .2126f, .2126f, 0,
+        .7152f, .7152f, .7152f, 0,
+        .0722f, .0722f, .0722f, 0,
+             0,      0,      0, 1
+    };
+
+    /** Matrix and offset used for standard display inversion. */
+    private static final float[] INVERSION_MATRIX_STANDARD = new float[] {
+        -1,  0,  0, 0,
+         0, -1,  0, 0,
+         0,  0, -1, 0,
+         1,  1,  1, 1
+    };
+
+    /** Matrix and offset used for hue-only display inversion. */
+    private static final float[] INVERSION_MATRIX_HUE_ONLY = new float[] {
+          0, .5f, .5f, 0,
+        .5f,   0, .5f, 0,
+        .5f, .5f,   0, 0,
+          0,   0,   0, 1
+    };
+
+    /** Matrix and offset used for value-only display inversion. */
+    private static final float[] INVERSION_MATRIX_VALUE_ONLY = new float[] {
+           0, -.5f, -.5f, 0,
+        -.5f,    0, -.5f, 0,
+        -.5f, -.5f,    0, 0,
+           1,    1,    1, 1
+    };
+
+    /** Default contrast for display contrast enhancement. */
+    private static final float DEFAULT_DISPLAY_CONTRAST = 2;
+
+    /** Default brightness for display contrast enhancement. */
+    private static final float DEFAULT_DISPLAY_BRIGHTNESS = 0;
+
+    /** Default inversion mode for display color inversion. */
+    private static final int DEFAULT_DISPLAY_INVERSION = AccessibilityManager.INVERSION_STANDARD;
+
+    /** Default inversion mode for display color correction. */
+    private static final int DEFAULT_DISPLAY_DALTONIZER =
+            AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY;
+
+    /**
+     * Returns whether the specified user with has any display color
+     * adjustments.
+     */
+    public static boolean hasAdjustments(Context context, int userId) {
+        final ContentResolver cr = context.getContentResolver();
+
+        boolean hasColorTransform = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) == 1;
+
+        if (!hasColorTransform) {
+            hasColorTransform |= Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, userId) == 1;
+        }
+
+        if (!hasColorTransform) {
+            hasColorTransform |= Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) == 1;
+        }
+
+        return hasColorTransform;
+    }
+
+    /**
+     * Applies the specified user's display color adjustments.
+     */
+    public static void applyAdjustments(Context context, int userId) {
+        final ContentResolver cr = context.getContentResolver();
+        float[] colorMatrix = new float[16];
+        float[] outputMatrix = new float[16];
+        boolean hasColorTransform = false;
+
+        Matrix.setIdentityM(colorMatrix, 0);
+
+        final boolean inversionEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, 0, userId) == 1;
+        if (inversionEnabled) {
+            final int inversionMode = Settings.Secure.getIntForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION, DEFAULT_DISPLAY_INVERSION,
+                    userId);
+            final float[] inversionMatrix;
+            switch (inversionMode) {
+                case AccessibilityManager.INVERSION_HUE_ONLY:
+                    inversionMatrix = INVERSION_MATRIX_HUE_ONLY;
+                    break;
+                case AccessibilityManager.INVERSION_VALUE_ONLY:
+                    inversionMatrix = INVERSION_MATRIX_VALUE_ONLY;
+                    break;
+                default:
+                    inversionMatrix = INVERSION_MATRIX_STANDARD;
+            }
+
+            Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, inversionMatrix, 0);
+
+            colorMatrix = outputMatrix;
+            outputMatrix = colorMatrix;
+
+            hasColorTransform = true;
+        }
+
+        final boolean contrastEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST_ENABLED, 0, userId) == 1;
+        if (contrastEnabled) {
+            final float contrast = Settings.Secure.getFloatForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_CONTRAST, DEFAULT_DISPLAY_CONTRAST,
+                    userId);
+            final float brightness = Settings.Secure.getFloatForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_BRIGHTNESS, DEFAULT_DISPLAY_BRIGHTNESS,
+                    userId);
+            final float off = brightness * contrast - 0.5f * contrast + 0.5f;
+            final float[] contrastMatrix = {
+                    contrast, 0, 0, 0,
+                    0, contrast, 0, 0,
+                    0, 0, contrast, 0,
+                    off, off, off, 1
+            };
+
+            Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, contrastMatrix, 0);
+
+            colorMatrix = outputMatrix;
+            outputMatrix = colorMatrix;
+
+            hasColorTransform = true;
+        }
+
+        final boolean daltonizerEnabled = Settings.Secure.getIntForUser(
+                cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, 0, userId) != 0;
+        if (daltonizerEnabled) {
+            final int daltonizerMode = Settings.Secure.getIntForUser(cr,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, DEFAULT_DISPLAY_DALTONIZER,
+                    userId);
+            // Monochromacy isn't supported by the native Daltonizer.
+            if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) {
+                Matrix.multiplyMM(outputMatrix, 0, colorMatrix, 0, GRAYSCALE_MATRIX, 0);
+
+                final float[] temp = colorMatrix;
+                colorMatrix = outputMatrix;
+                outputMatrix = temp;
+
+                hasColorTransform = true;
+                nativeSetDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
+            } else {
+                nativeSetDaltonizerMode(daltonizerMode);
+            }
+        } else {
+            nativeSetDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED);
+        }
+
+        if (hasColorTransform) {
+            nativeSetColorTransform(colorMatrix);
+        } else {
+            nativeSetColorTransform(null);
+        }
+    }
+
+    /**
+     * Sets the surface flinger's Daltonization mode. This adjusts the color
+     * space to correct for or simulate various types of color blindness.
+     *
+     * @param mode new Daltonization mode
+     */
+    private static void nativeSetDaltonizerMode(int mode) {
+        try {
+            final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+            if (flinger != null) {
+                final Parcel data = Parcel.obtain();
+                data.writeInterfaceToken("android.ui.ISurfaceComposer");
+                data.writeInt(mode);
+                flinger.transact(1014, data, null, 0);
+                data.recycle();
+            }
+        } catch (RemoteException ex) {
+            Slog.e(LOG_TAG, "Failed to set Daltonizer mode", ex);
+        }
+    }
+
+    /**
+     * Sets the surface flinger's color transformation as a 4x4 matrix. If the
+     * matrix is null, color transformations are disabled.
+     *
+     * @param m the float array that holds the transformation matrix, or null to
+     *            disable transformation
+     */
+    private static void nativeSetColorTransform(float[] m) {
+        try {
+            final IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+            if (flinger != null) {
+                final Parcel data = Parcel.obtain();
+                data.writeInterfaceToken("android.ui.ISurfaceComposer");
+                if (m != null) {
+                    data.writeInt(1);
+                    for (int i = 0; i < 16; i++) {
+                        data.writeFloat(m[i]);
+                    }
+                } else {
+                    data.writeInt(0);
+                }
+                flinger.transact(1015, data, null, 0);
+                data.recycle();
+            }
+        } catch (RemoteException ex) {
+            Slog.e(LOG_TAG, "Failed to set color transform", ex);
+        }
+    }
+
+}
diff --git a/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java b/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java
index 5f12cf4..c8b080e 100644
--- a/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java
+++ b/services/accessibility/java/com/android/server/accessibility/ScreenMagnifier.java
@@ -29,8 +29,6 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.Message;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.text.TextUtils;
@@ -38,8 +36,6 @@
 import android.util.Slog;
 import android.view.GestureDetector;
 import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.IMagnificationCallbacks;
-import android.view.IWindowManager;
 import android.view.MagnificationSpec;
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
@@ -48,10 +44,12 @@
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.WindowManagerInternal;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.DecelerateInterpolator;
 
 import com.android.internal.os.SomeArgs;
+import com.android.server.LocalServices;
 
 import java.util.Locale;
 
@@ -94,8 +92,8 @@
  *
  * 6. The magnification scale will be persisted in settings and in the cloud.
  */
-public final class ScreenMagnifier extends IMagnificationCallbacks.Stub
-        implements EventStreamTransformation {
+public final class ScreenMagnifier implements WindowManagerInternal.MagnificationCallbacks,
+        EventStreamTransformation {
 
     private static final String LOG_TAG = ScreenMagnifier.class.getSimpleName();
 
@@ -127,7 +125,7 @@
     private final Rect mTempRect1 = new Rect();
 
     private final Context mContext;
-    private final IWindowManager mWindowManager;
+    private final WindowManagerInternal mWindowManager;
     private final MagnificationController mMagnificationController;
     private final ScreenStateObserver mScreenStateObserver;
 
@@ -191,8 +189,7 @@
 
     public ScreenMagnifier(Context context, int displayId, AccessibilityManagerService service) {
         mContext = context;
-        mWindowManager = IWindowManager.Stub.asInterface(
-                ServiceManager.getService("window"));
+        mWindowManager = LocalServices.getService(WindowManagerInternal.class);
         mAms = service;
 
         mLongAnimationDuration = context.getResources().getInteger(
@@ -208,11 +205,7 @@
         mMagnificationController = new MagnificationController(mLongAnimationDuration);
         mScreenStateObserver = new ScreenStateObserver(context, mMagnificationController);
 
-        try {
-            mWindowManager.setMagnificationCallbacks(this);
-        } catch (RemoteException re) {
-            /* ignore */
-        }
+        mWindowManager.setMagnificationCallbacks(this);
 
         transitionToState(STATE_DETECTING);
     }
@@ -378,11 +371,7 @@
     @Override
     public void onDestroy() {
         mScreenStateObserver.destroy();
-        try {
-            mWindowManager.setMagnificationCallbacks(null);
-        } catch (RemoteException re) {
-            /* ignore */
-        }
+        mWindowManager.setMagnificationCallbacks(null);
     }
 
     private void handleMotionEventStateDelegating(MotionEvent event,
@@ -462,7 +451,7 @@
         }
         return mTempPointerProperties;
     }
-    
+
     private void transitionToState(int state) {
         if (DEBUG_STATE_TRANSITIONS) {
             switch (state) {
@@ -1120,15 +1109,10 @@
             if (DEBUG_SET_MAGNIFICATION_SPEC) {
                 Slog.i(LOG_TAG, "Sending: " + spec);
             }
-            try {
-                mSentMagnificationSpec.scale = spec.scale;
-                mSentMagnificationSpec.offsetX = spec.offsetX;
-                mSentMagnificationSpec.offsetY = spec.offsetY;
-                mWindowManager.setMagnificationSpec(
-                        MagnificationSpec.obtain(spec));
-            } catch (RemoteException re) {
-                /* ignore */
-            }
+            mSentMagnificationSpec.scale = spec.scale;
+            mSentMagnificationSpec.offsetX = spec.offsetX;
+            mSentMagnificationSpec.offsetY = spec.offsetY;
+            mWindowManager.setMagnificationSpec(MagnificationSpec.obtain(spec));
         }
     }
 
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
index e208677..77d5076 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
@@ -23,7 +23,6 @@
 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;
@@ -38,18 +37,19 @@
 import com.android.internal.appwidget.IAppWidgetService;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.AppWidgetBackupBridge;
+import com.android.server.WidgetBackupProvider;
 import com.android.server.SystemService;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.List;
-import java.util.Locale;
 
 
 /**
  * SystemService that publishes an IAppWidgetService.
  */
-public class AppWidgetService extends SystemService {
+public class AppWidgetService extends SystemService implements WidgetBackupProvider {
 
     static final String TAG = "AppWidgetService";
 
@@ -72,6 +72,7 @@
     @Override
     public void onStart() {
         publishBinderService(Context.APPWIDGET_SERVICE, mServiceImpl);
+        AppWidgetBackupBridge.register(this);
     }
 
     @Override
@@ -81,13 +82,40 @@
         }
     }
 
+
+    // backup <-> app widget service bridge surface
+    @Override
+    public List<String> getWidgetParticipants(int userId) {
+        return mServiceImpl.getWidgetParticipants(userId);
+    }
+
+    @Override
+    public byte[] getWidgetState(String packageName, int userId) {
+        return mServiceImpl.getWidgetState(packageName, userId);
+    }
+
+    @Override
+    public void restoreStarting(int userId) {
+        mServiceImpl.restoreStarting(userId);
+    }
+
+    @Override
+    public void restoreWidgetState(String packageName, byte[] restoredState, int userId) {
+        mServiceImpl.restoreWidgetState(packageName, restoredState, userId);
+    }
+
+    @Override
+    public void restoreFinished(int userId) {
+        mServiceImpl.restoreFinished(userId);
+    }
+
+
+    // implementation entry point and binder service
     private final AppWidgetServiceStub mServiceImpl = new AppWidgetServiceStub();
 
-    private class AppWidgetServiceStub extends IAppWidgetService.Stub {
+    class AppWidgetServiceStub extends IAppWidgetService.Stub {
 
         private boolean mSafeMode;
-        private Locale mLocale;
-        private PackageManager mPackageManager;
 
         public void systemRunning(boolean safeMode) {
             mSafeMode = safeMode;
@@ -227,6 +255,29 @@
             }
         }
 
+
+        // support of the widget/backup bridge
+        public List<String> getWidgetParticipants(int userId) {
+            return getImplForUser(userId).getWidgetParticipants();
+        }
+
+        public byte[] getWidgetState(String packageName, int userId) {
+            return getImplForUser(userId).getWidgetState(packageName);
+        }
+
+        public void restoreStarting(int userId) {
+            getImplForUser(userId).restoreStarting();
+        }
+
+        public void restoreWidgetState(String packageName, byte[] restoredState, int userId) {
+            getImplForUser(userId).restoreWidgetState(packageName, restoredState);
+        }
+
+        public void restoreFinished(int userId) {
+            getImplForUser(userId).restoreFinished();
+        }
+
+
         private void checkPermission(int userId) {
             int realUserId = ActivityManager.handleIncomingUser(
                     Binder.getCallingPid(),
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 98dead3..b84df79 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -31,6 +31,7 @@
 import android.content.pm.IPackageManager;
 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.content.res.Resources;
@@ -42,18 +43,16 @@
 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.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.util.AtomicFile;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.TypedValue;
 import android.util.Xml;
 import android.view.Display;
@@ -69,6 +68,8 @@
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -82,8 +83,11 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map.Entry;
 import java.util.Set;
 
+import libcore.util.MutableInt;
+
 class AppWidgetServiceImpl {
 
     private static final String KEYGUARD_HOST_PACKAGE = "com.android.keyguard";
@@ -92,8 +96,10 @@
     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 final int WIDGET_STATE_VERSION = 1;  // version of backed-up widget state
 
-    private static boolean DBG = false;
+    private static boolean DBG = true;
+    private static boolean DEBUG_BACKUP = DBG || true;
 
     /*
      * When identifying a Host or Provider based on the calling process, use the uid field. When
@@ -108,6 +114,25 @@
         boolean zombie; // if we're in safe mode, don't prune this just because nobody references it
 
         int tag; // for use while saving state (the index)
+
+        // is there an instance of this provider hosted by the given app?
+        public boolean isHostedBy(String packageName) {
+            final int N = instances.size();
+            for (int i = 0; i < N; i++) {
+                AppWidgetId id = instances.get(i);
+                if (packageName.equals(id.host.packageName)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "Provider{" + ((info == null) ? "null" : info.provider)
+                    + (zombie ? " Z" : "")
+                    + '}';
+        }
     }
 
     static class Host {
@@ -128,14 +153,62 @@
                 return this.uid == callingUid;
             }
         }
+
+        boolean hostsPackage(String pkg) {
+            final int N = instances.size();
+            for (int i = 0; i < N; i++) {
+                Provider p = instances.get(i).provider;
+                if (p.info != null && pkg.equals(p.info.provider.getPackageName())) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "Host{" + packageName + ":" + hostId + '}';
+        }
     }
 
     static class AppWidgetId {
         int appWidgetId;
+        int restoredId;  // tracking & remapping any restored state
         Provider provider;
         RemoteViews views;
         Bundle options;
         Host host;
+
+        @Override
+        public String toString() {
+            return "AppWidgetId{" + appWidgetId + ':' + host + ':' + provider + '}';
+        }
+    }
+
+    AppWidgetId findRestoredWidgetLocked(int restoredId, Host host, Provider p) {
+        if (DEBUG_BACKUP) {
+            Slog.i(TAG, "Find restored widget: id=" + restoredId
+                    + " host=" + host + " provider=" + p);
+        }
+
+        if (p == null || host == null) {
+            return null;
+        }
+
+        final int N = mAppWidgetIds.size();
+        for (int i = 0; i < N; i++) {
+            AppWidgetId widget = mAppWidgetIds.get(i);
+            if (widget.restoredId == restoredId
+                    && widget.host.hostId == host.hostId
+                    && widget.host.packageName.equals(host.packageName)
+                    && widget.provider.info.provider.equals(p.info.provider)) {
+                if (DEBUG_BACKUP) {
+                    Slog.i(TAG, "   Found at " + i + " : " + widget);
+                }
+                return widget;
+            }
+        }
+        return null;
     }
 
     /**
@@ -197,6 +270,22 @@
     boolean mStateLoaded;
     int mMaxWidgetBitmapMemory;
 
+    // Map old (restored) widget IDs to new AppWidgetId instances.  This object is used
+    // as the lock around manipulation of the overall restored-widget state, just as
+    // mAppWidgetIds is used as the lock object around all "live" widget state
+    // manipulations.  Methods that must be called with this lock held are decorated
+    // with the suffix "Lr".
+    //
+    // In cases when both of those locks must be held concurrently, mRestoredWidgetIds
+    // must be acquired *first.*
+    private final SparseArray<AppWidgetId> mRestoredWidgetIds = new SparseArray<AppWidgetId>();
+
+    // We need to make sure to wipe the pre-restore widget state only once for
+    // a given package.  Keep track of what we've done so far here; the list is
+    // cleared at the start of every system restore pass, but preserved through
+    // any install-time restore operations.
+    HashSet<String> mPrunedApps = new HashSet<String>();
+
     private final Handler mSaveStateHandler;
 
     // These are for debugging only -- widgets are going missing in some rare instances
@@ -303,10 +392,19 @@
                         providersModified |= updateProvidersForPackageLocked(pkgName, null);
                     }
                 } else {
-                    // The package was just added
+                    // The package was just added.  Fix up the providers...
                     for (String pkgName : pkgList) {
                         providersModified |= addProvidersForPackageLocked(pkgName);
                     }
+                    // ...and see if these are hosts we've been awaiting
+                    for (String pkg : pkgList) {
+                        try {
+                            int uid = getUidForPackage(pkg);
+                            resolveHostUidLocked(pkg, uid);
+                        } catch (NameNotFoundException e) {
+                            // shouldn't happen; we just installed it!
+                        }
+                    }
                 }
                 saveStateAsync();
             }
@@ -334,6 +432,19 @@
         }
     }
 
+    void resolveHostUidLocked(String pkg, int uid) {
+        final int N = mHosts.size();
+        for (int i = 0; i < N; i++) {
+            Host h = mHosts.get(i);
+            if (h.uid == -1 && pkg.equals(h.packageName)) {
+                if (DEBUG_BACKUP) {
+                    Slog.i(TAG, "host " + pkg + ":" + h.hostId + " resolved to uid " + uid);
+                }
+                h.uid = uid;
+            }
+        }
+    }
+
     private void dumpProvider(Provider p, int index, PrintWriter pw) {
         AppWidgetProviderInfo info = p.info;
         pw.print("  ["); pw.print(index); pw.print("] provider ");
@@ -436,7 +547,7 @@
             if (!mHasFeature) {
                 return;
             }
-            loadAppWidgetListLocked();
+            loadWidgetProviderListLocked();
             loadStateLocked();
             mStateLoaded = true;
         }
@@ -519,6 +630,7 @@
     }
 
     void deleteHostLocked(Host host) {
+        if (DBG) log("Deleting host " + host);
         final int N = host.instances.size();
         for (int i = N - 1; i >= 0; i--) {
             AppWidgetId id = host.instances.get(i);
@@ -722,7 +834,7 @@
             }
             final ComponentName componentName = intent.getComponent();
             try {
-                final ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(componentName,
+                final ServiceInfo si = mPm.getServiceInfo(componentName,
                         PackageManager.GET_PERMISSIONS, mUserId);
                 if (!android.Manifest.permission.BIND_REMOTEVIEWS.equals(si.permission)) {
                     throw new SecurityException("Selected service does not require "
@@ -984,7 +1096,6 @@
             if (!mHasFeature) {
                 return;
             }
-            options = cloneIfLocalBinder(options);
             ensureStateLoadedLocked();
             AppWidgetId id = lookupAppWidgetIdLocked(appWidgetId);
 
@@ -994,7 +1105,7 @@
 
             Provider p = id.provider;
             // Merge the options
-            id.options.putAll(options);
+            id.options.putAll(cloneIfLocalBinder(options));
 
             // send the broacast saying that this appWidgetId has been deleted
             Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED);
@@ -1281,9 +1392,13 @@
     }
 
     Provider lookupProviderLocked(ComponentName provider) {
-        final int N = mInstalledProviders.size();
+        return lookupProviderLocked(provider, mInstalledProviders);
+    }
+
+    Provider lookupProviderLocked(ComponentName provider, ArrayList<Provider> installedProviders) {
+        final int N = installedProviders.size();
         for (int i = 0; i < N; i++) {
-            Provider p = mInstalledProviders.get(i);
+            Provider p = installedProviders.get(i);
             if (p.info.provider.equals(provider)) {
                 return p;
             }
@@ -1320,11 +1435,12 @@
 
     void pruneHostLocked(Host host) {
         if (host.instances.size() == 0 && host.callbacks == null) {
+            if (DBG) log("Pruning host " + host);
             mHosts.remove(host);
         }
     }
 
-    void loadAppWidgetListLocked() {
+    void loadWidgetProviderListLocked() {
         Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
         try {
             List<ResolveInfo> broadcastReceivers = mPm.queryIntentReceivers(intent,
@@ -1351,7 +1467,23 @@
         Provider p = parseProviderInfoXml(new ComponentName(ri.activityInfo.packageName,
                 ri.activityInfo.name), ri);
         if (p != null) {
-            mInstalledProviders.add(p);
+            // we might have an inactive entry for this provider already due to
+            // a preceding restore operation.  if so, fix it up in place; otherwise
+            // just add this new one.
+            Provider existing = lookupProviderLocked(p.info.provider);
+            if (existing != null) {
+                if (existing.zombie && !mSafeMode) {
+                    // it's a placeholder that was set up during an app restore
+                    existing.zombie = false;
+                    existing.info = p.info; // the real one filled out from the ResolveInfo
+                    existing.uid = p.uid;
+                    if (DEBUG_BACKUP) {
+                        Slog.i(TAG, "Provider placeholder now reified: " + existing);
+                    }
+                }
+            } else {
+                mInstalledProviders.add(p);
+            }
             return true;
         } else {
             return false;
@@ -1466,6 +1598,554 @@
         }
     }
 
+    public List<String> getWidgetParticipants() {
+        HashSet<String> packages = new HashSet<String>();
+        synchronized (mAppWidgetIds) {
+            final int N = mAppWidgetIds.size();
+            for (int i = 0; i < N; i++) {
+                final AppWidgetId id = mAppWidgetIds.get(i);
+                packages.add(id.host.packageName);
+                packages.add(id.provider.info.provider.getPackageName());
+            }
+        }
+        return new ArrayList<String>(packages);
+    }
+
+    private void serializeProvider(XmlSerializer out, Provider p) throws IOException {
+        out.startTag(null, "p");
+        out.attribute(null, "pkg", p.info.provider.getPackageName());
+        out.attribute(null, "cl", p.info.provider.getClassName());
+        out.endTag(null, "p");
+    }
+
+    private void serializeHost(XmlSerializer out, Host host) throws IOException {
+        out.startTag(null, "h");
+        out.attribute(null, "pkg", host.packageName);
+        out.attribute(null, "id", Integer.toHexString(host.hostId));
+        out.endTag(null, "h");
+    }
+
+    private void serializeAppWidgetId(XmlSerializer out, AppWidgetId id) throws IOException {
+        out.startTag(null, "g");
+        out.attribute(null, "id", Integer.toHexString(id.appWidgetId));
+        out.attribute(null, "rid", Integer.toHexString(id.restoredId));
+        out.attribute(null, "h", Integer.toHexString(id.host.tag));
+        if (id.provider != null) {
+            out.attribute(null, "p", Integer.toHexString(id.provider.tag));
+        }
+        if (id.options != null) {
+            out.attribute(null, "min_width", Integer.toHexString(id.options.getInt(
+                    AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)));
+            out.attribute(null, "min_height", Integer.toHexString(id.options.getInt(
+                    AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)));
+            out.attribute(null, "max_width", Integer.toHexString(id.options.getInt(
+                    AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)));
+            out.attribute(null, "max_height", Integer.toHexString(id.options.getInt(
+                    AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)));
+            out.attribute(null, "host_category", Integer.toHexString(id.options.getInt(
+                    AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)));
+        }
+        out.endTag(null, "g");
+    }
+
+    private Bundle parseWidgetIdOptions(XmlPullParser parser) {
+        Bundle options = new Bundle();
+        String minWidthString = parser.getAttributeValue(null, "min_width");
+        if (minWidthString != null) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH,
+                    Integer.parseInt(minWidthString, 16));
+        }
+        String minHeightString = parser.getAttributeValue(null, "min_height");
+        if (minHeightString != null) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT,
+                    Integer.parseInt(minHeightString, 16));
+        }
+        String maxWidthString = parser.getAttributeValue(null, "max_width");
+        if (maxWidthString != null) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH,
+                    Integer.parseInt(maxWidthString, 16));
+        }
+        String maxHeightString = parser.getAttributeValue(null, "max_height");
+        if (maxHeightString != null) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT,
+                    Integer.parseInt(maxHeightString, 16));
+        }
+        String categoryString = parser.getAttributeValue(null, "host_category");
+        if (categoryString != null) {
+            options.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+                    Integer.parseInt(categoryString, 16));
+        }
+        return options;
+    }
+
+    // Does this package either host or provide any active widgets?
+    private boolean packageNeedsWidgetBackupLocked(String packageName) {
+        int N = mAppWidgetIds.size();
+        for (int i = 0; i < N; i++) {
+            AppWidgetId id = mAppWidgetIds.get(i);
+            if (packageName.equals(id.host.packageName)) {
+                // this package is hosting widgets, so it knows widget IDs
+                return true;
+            }
+            Provider p = id.provider;
+            if (p != null && packageName.equals(p.info.provider.getPackageName())) {
+                // someone is hosting this app's widgets, so it knows widget IDs
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // build the widget-state blob that we save for the app during backup.
+    public byte[] getWidgetState(String backupTarget) {
+        if (!mHasFeature) {
+            return null;
+        }
+
+        ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        synchronized (mAppWidgetIds) {
+            // Preflight: if this app neither hosts nor provides any live widgets
+            // we have no work to do.
+            if (!packageNeedsWidgetBackupLocked(backupTarget)) {
+                return null;
+            }
+
+            try {
+                XmlSerializer out = new FastXmlSerializer();
+                out.setOutput(stream, "utf-8");
+                out.startDocument(null, true);
+                out.startTag(null, "ws");      // widget state
+                out.attribute(null, "version", String.valueOf(WIDGET_STATE_VERSION));
+                out.attribute(null, "pkg", backupTarget);
+
+                // Remember all the providers that are currently hosted or published
+                // by this package: that is, all of the entities related to this app
+                // which will need to be told about id remapping.
+                int N = mInstalledProviders.size();
+                int index = 0;
+                for (int i = 0; i < N; i++) {
+                    Provider p = mInstalledProviders.get(i);
+                    if (p.instances.size() > 0) {
+                        if (backupTarget.equals(p.info.provider.getPackageName())
+                                || p.isHostedBy(backupTarget)) {
+                            serializeProvider(out, p);
+                            p.tag = index++;
+                        }
+                    }
+                }
+
+                N = mHosts.size();
+                index = 0;
+                for (int i = 0; i < N; i++) {
+                    Host host = mHosts.get(i);
+                    if (backupTarget.equals(host.packageName)
+                            || host.hostsPackage(backupTarget)) {
+                        serializeHost(out, host);
+                        host.tag = index++;
+                    }
+                }
+
+                // All widget instances involving this package,
+                // either as host or as provider
+                N = mAppWidgetIds.size();
+                for (int i = 0; i < N; i++) {
+                    AppWidgetId id = mAppWidgetIds.get(i);
+                    if (backupTarget.equals(id.host.packageName)
+                            || backupTarget.equals(id.provider.info.provider.getPackageName())) {
+                        serializeAppWidgetId(out, id);
+                    }
+                }
+
+                out.endTag(null, "ws");
+                out.endDocument();
+            } catch (IOException e) {
+                Slog.w(TAG, "Unable to save widget state for " + backupTarget);
+                return null;
+            }
+
+        }
+        return stream.toByteArray();
+    }
+
+    public void restoreStarting() {
+        if (DEBUG_BACKUP) {
+            Slog.i(TAG, "restore starting for user " + mUserId);
+        }
+        synchronized (mRestoredWidgetIds) {
+            // We're starting a new "system" restore operation, so any widget restore
+            // state that we see from here on is intended to replace the current
+            // widget configuration of any/all of the affected apps.
+            mPrunedApps.clear();
+            mUpdatesByProvider.clear();
+            mUpdatesByHost.clear();
+        }
+    }
+
+    // We're restoring widget state for 'pkg', so we start by wiping (a) all widget
+    // instances that are hosted by that app, and (b) all instances in other hosts
+    // for which 'pkg' is the provider.  We assume that we'll be restoring all of
+    // these hosts & providers, so will be reconstructing a correct live state.
+    private void pruneWidgetStateLr(String pkg) {
+        if (!mPrunedApps.contains(pkg)) {
+            if (DEBUG_BACKUP) {
+                Slog.i(TAG, "pruning widget state for restoring package " + pkg);
+            }
+            for (int i = mAppWidgetIds.size() - 1; i >= 0; i--) {
+                AppWidgetId id = mAppWidgetIds.get(i);
+                Provider p = id.provider;
+                if (id.host.packageName.equals(pkg)
+                        || p.info.provider.getPackageName().equals(pkg)) {
+                    // 'pkg' is either the host or the provider for this instances,
+                    // so we tear it down in anticipation of it (possibly) being
+                    // reconstructed due to the restore
+                    p.instances.remove(id);
+
+                    unbindAppWidgetRemoteViewsServicesLocked(id);
+                    mAppWidgetIds.remove(i);
+                }
+            }
+            mPrunedApps.add(pkg);
+        } else {
+            if (DEBUG_BACKUP) {
+                Slog.i(TAG, "already pruned " + pkg + ", continuing normally");
+            }
+        }
+    }
+
+    // Accumulate a list of updates that affect the given provider for a final
+    // coalesced notification broadcast once restore is over.
+    class RestoreUpdateRecord {
+        public int oldId;
+        public int newId;
+        public boolean notified;
+
+        public RestoreUpdateRecord(int theOldId, int theNewId) {
+            oldId = theOldId;
+            newId = theNewId;
+            notified = false;
+        }
+    }
+
+    HashMap<Provider, ArrayList<RestoreUpdateRecord>> mUpdatesByProvider
+            = new HashMap<Provider, ArrayList<RestoreUpdateRecord>>();
+    HashMap<Host, ArrayList<RestoreUpdateRecord>> mUpdatesByHost
+            = new HashMap<Host, ArrayList<RestoreUpdateRecord>>();
+
+    private boolean alreadyStashed(ArrayList<RestoreUpdateRecord> stash,
+            final int oldId, final int newId) {
+        final int N = stash.size();
+        for (int i = 0; i < N; i++) {
+            RestoreUpdateRecord r = stash.get(i);
+            if (r.oldId == oldId && r.newId == newId) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void stashProviderRestoreUpdateLr(Provider provider, int oldId, int newId) {
+        ArrayList<RestoreUpdateRecord> r = mUpdatesByProvider.get(provider);
+        if (r == null) {
+            r = new ArrayList<RestoreUpdateRecord>();
+            mUpdatesByProvider.put(provider, r);
+        } else {
+            // don't duplicate
+            if (alreadyStashed(r, oldId, newId)) {
+                if (DEBUG_BACKUP) {
+                    Slog.i(TAG, "ID remap " + oldId + " -> " + newId
+                            + " already stashed for " + provider);
+                }
+                return;
+            }
+        }
+        r.add(new RestoreUpdateRecord(oldId, newId));
+    }
+
+    private void stashHostRestoreUpdateLr(Host host, int oldId, int newId) {
+        ArrayList<RestoreUpdateRecord> r = mUpdatesByHost.get(host);
+        if (r == null) {
+            r = new ArrayList<RestoreUpdateRecord>();
+            mUpdatesByHost.put(host, r);
+        } else {
+            if (alreadyStashed(r, oldId, newId)) {
+                if (DEBUG_BACKUP) {
+                    Slog.i(TAG, "ID remap " + oldId + " -> " + newId
+                            + " already stashed for " + host);
+                }
+                return;
+            }
+        }
+        r.add(new RestoreUpdateRecord(oldId, newId));
+    }
+
+    public void restoreWidgetState(String packageName, byte[] restoredState) {
+        if (!mHasFeature) {
+            return;
+        }
+
+        if (DEBUG_BACKUP) {
+            Slog.i(TAG, "Restoring widget state for " + packageName);
+        }
+
+        ByteArrayInputStream stream = new ByteArrayInputStream(restoredState);
+        try {
+            // Providers mentioned in the widget dataset by ordinal
+            ArrayList<Provider> restoredProviders = new ArrayList<Provider>();
+
+            // Hosts mentioned in the widget dataset by ordinal
+            ArrayList<Host> restoredHosts = new ArrayList<Host>();
+
+            //HashSet<String> toNotify = new HashSet<String>();
+
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(stream, null);
+
+            synchronized (mAppWidgetIds) {
+                synchronized (mRestoredWidgetIds) {
+                    int type;
+                    do {
+                        type = parser.next();
+                        if (type == XmlPullParser.START_TAG) {
+                            final String tag = parser.getName();
+                            if ("ws".equals(tag)) {
+                                String v = parser.getAttributeValue(null, "version");
+                                String pkg = parser.getAttributeValue(null, "pkg");
+
+                                // TODO: fix up w.r.t. canonical vs current package names
+                                if (!packageName.equals(pkg)) {
+                                    Slog.w(TAG, "Package mismatch in ws");
+                                    return;
+                                }
+
+                                int version = Integer.parseInt(v);
+                                if (version > WIDGET_STATE_VERSION) {
+                                    Slog.w(TAG, "Unable to process state version " + version);
+                                    return;
+                                }
+                            } else if ("p".equals(tag)) {
+                                String pkg = parser.getAttributeValue(null, "pkg");
+                                String cl = parser.getAttributeValue(null, "cl");
+
+                                // hostedProviders index will match 'p' attribute in widget's
+                                // entry in the xml file being restored
+                                // If there's no live entry for this provider, add an inactive one
+                                // so that widget IDs referring to them can be properly allocated
+                                final ComponentName cn = new ComponentName(pkg, cl);
+                                Provider p = lookupProviderLocked(cn, mInstalledProviders);
+                                if (p == null) {
+                                    p = new Provider();
+                                    p.info = new AppWidgetProviderInfo();
+                                    p.info.provider = cn;
+                                    p.zombie = true;
+                                    mInstalledProviders.add(p);
+                                }
+                                if (DEBUG_BACKUP) {
+                                    Slog.i(TAG, "   provider " + cn);
+                                }
+                                restoredProviders.add(p);
+                            } else if ("h".equals(tag)) {
+                                // The host app may not yet exist on the device.  If it's here we
+                                // just use the existing Host entry, otherwise we create a
+                                // placeholder whose uid will be fixed up at PACKAGE_ADDED time.
+                                String pkg = parser.getAttributeValue(null, "pkg");
+                                int uid;
+                                try {
+                                    uid = getUidForPackage(pkg);
+                                } catch (NameNotFoundException e) {
+                                    uid = -1;
+                                }
+                                int hostId = Integer.parseInt(
+                                        parser.getAttributeValue(null, "id"), 16);
+                                Host h = lookupOrAddHostLocked(uid, pkg, hostId);
+                                if (DEBUG_BACKUP) {
+                                    Slog.i(TAG, "   host[" + restoredHosts.size()
+                                            + "]: {" + h.packageName + ":" + h.hostId + "}");
+                                }
+                                restoredHosts.add(h);
+                            } else if ("g".equals(tag)) {
+                                int restoredId = Integer.parseInt(
+                                        parser.getAttributeValue(null, "id"), 16);
+                                int hostIndex = Integer.parseInt(
+                                        parser.getAttributeValue(null, "h"), 16);
+                                Host host = restoredHosts.get(hostIndex);
+                                Provider p = null;
+                                String prov = parser.getAttributeValue(null, "p");
+                                if (prov != null) {
+                                    // could have been null if the app had allocated an id
+                                    // but not yet established a binding under that id
+                                    int which = Integer.parseInt(prov, 16);
+                                    p = restoredProviders.get(which);
+                                }
+
+                                // We'll be restoring widget state for both the host and
+                                // provider sides of this widget ID, so make sure we are
+                                // beginning from a clean slate on both fronts.
+                                pruneWidgetStateLr(host.packageName);
+                                if (p != null) {
+                                    pruneWidgetStateLr(p.info.provider.getPackageName());
+                                }
+
+                                // Have we heard about this ancestral widget instance before?
+                                AppWidgetId id = findRestoredWidgetLocked(restoredId, host, p);
+                                if (id == null) {
+                                    id = new AppWidgetId();
+                                    id.appWidgetId = mNextAppWidgetId++;
+                                    id.restoredId = restoredId;
+                                    id.options = parseWidgetIdOptions(parser);
+                                    id.host = host;
+                                    id.host.instances.add(id);
+                                    id.provider = p;
+                                    if (id.provider != null) {
+                                        id.provider.instances.add(id);
+                                    }
+                                    if (DEBUG_BACKUP) {
+                                        Slog.i(TAG, "New restored id " + restoredId
+                                                + " now " + id);
+                                    }
+                                    mAppWidgetIds.add(id);
+                                }
+                                if (id.provider.info != null) {
+                                    stashProviderRestoreUpdateLr(id.provider,
+                                            restoredId, id.appWidgetId);
+                                } else {
+                                    Slog.w(TAG, "Missing provider for restored widget " + id);
+                                }
+                                stashHostRestoreUpdateLr(id.host, restoredId, id.appWidgetId);
+
+                                if (DEBUG_BACKUP) {
+                                    Slog.i(TAG, "   instance: " + restoredId
+                                            + " -> " + id.appWidgetId
+                                            + " :: p=" + id.provider);
+                                }
+                            }
+                        }
+                    } while (type != XmlPullParser.END_DOCUMENT);
+
+                    // We've updated our own bookkeeping.  We'll need to notify the hosts and
+                    // providers about the changes, but we can't do that yet because the restore
+                    // target is not necessarily fully live at this moment.  Set aside the
+                    // information for now; the backup manager will call us once more at the
+                    // end of the process when all of the targets are in a known state, and we
+                    // will update at that point.
+                }
+            }
+        } catch (XmlPullParserException e) {
+            Slog.w(TAG, "Unable to restore widget state for " + packageName);
+        } catch (IOException e) {
+            Slog.w(TAG, "Unable to restore widget state for " + packageName);
+        } finally {
+            saveStateAsync();
+        }
+    }
+
+    // Called once following the conclusion of a restore operation.  This is when we
+    // send out updates to apps involved in widget-state restore telling them about
+    // the new widget ID space.
+    public void restoreFinished() {
+        if (DEBUG_BACKUP) {
+            Slog.i(TAG, "restoreFinished for " + mUserId);
+        }
+
+        final UserHandle userHandle = new UserHandle(mUserId);
+        synchronized (mRestoredWidgetIds) {
+            // Build the providers' broadcasts and send them off
+            Set<Entry<Provider, ArrayList<RestoreUpdateRecord>>> providerEntries
+                    = mUpdatesByProvider.entrySet();
+            for (Entry<Provider, ArrayList<RestoreUpdateRecord>> e : providerEntries) {
+                // For each provider there's a list of affected IDs
+                Provider provider = e.getKey();
+                ArrayList<RestoreUpdateRecord> updates = e.getValue();
+                final int pending = countPendingUpdates(updates);
+                if (DEBUG_BACKUP) {
+                    Slog.i(TAG, "Provider " + provider + " pending: " + pending);
+                }
+                if (pending > 0) {
+                    int[] oldIds = new int[pending];
+                    int[] newIds = new int[pending];
+                    final int N = updates.size();
+                    int nextPending = 0;
+                    for (int i = 0; i < N; i++) {
+                        RestoreUpdateRecord r = updates.get(i);
+                        if (!r.notified) {
+                            r.notified = true;
+                            oldIds[nextPending] = r.oldId;
+                            newIds[nextPending] = r.newId;
+                            nextPending++;
+                            if (DEBUG_BACKUP) {
+                                Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
+                            }
+                        }
+                    }
+                    sendWidgetRestoreBroadcast(AppWidgetManager.ACTION_APPWIDGET_RESTORED,
+                            provider, null, oldIds, newIds, userHandle);
+                }
+            }
+
+            // same thing per host
+            Set<Entry<Host, ArrayList<RestoreUpdateRecord>>> hostEntries
+                    = mUpdatesByHost.entrySet();
+            for (Entry<Host, ArrayList<RestoreUpdateRecord>> e : hostEntries) {
+                Host host = e.getKey();
+                if (host.uid > 0) {
+                    ArrayList<RestoreUpdateRecord> updates = e.getValue();
+                    final int pending = countPendingUpdates(updates);
+                    if (DEBUG_BACKUP) {
+                        Slog.i(TAG, "Host " + host + " pending: " + pending);
+                    }
+                    if (pending > 0) {
+                        int[] oldIds = new int[pending];
+                        int[] newIds = new int[pending];
+                        final int N = updates.size();
+                        int nextPending = 0;
+                        for (int i = 0; i < N; i++) {
+                            RestoreUpdateRecord r = updates.get(i);
+                            if (!r.notified) {
+                                r.notified = true;
+                                oldIds[nextPending] = r.oldId;
+                                newIds[nextPending] = r.newId;
+                                nextPending++;
+                                if (DEBUG_BACKUP) {
+                                    Slog.i(TAG, "   " + r.oldId + " => " + r.newId);
+                                }
+                            }
+                        }
+                        sendWidgetRestoreBroadcast(AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED,
+                                null, host, oldIds, newIds, userHandle);
+                    }
+                }
+            }
+        }
+    }
+
+    private int countPendingUpdates(ArrayList<RestoreUpdateRecord> updates) {
+        int pending = 0;
+        final int N = updates.size();
+        for (int i = 0; i < N; i++) {
+            RestoreUpdateRecord r = updates.get(i);
+            if (!r.notified) {
+                pending++;
+            }
+        }
+        return pending;
+    }
+
+    void sendWidgetRestoreBroadcast(String action, Provider provider, Host host,
+            int[] oldIds, int[] newIds, UserHandle userHandle) {
+        Intent intent = new Intent(action);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OLD_IDS, oldIds);
+        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, newIds);
+        if (provider != null) {
+            intent.setComponent(provider.info.provider);
+            mContext.sendBroadcastAsUser(intent, userHandle);
+        }
+        if (host != null) {
+            intent.setComponent(null);
+            intent.setPackage(host.packageName);
+            intent.putExtra(AppWidgetManager.EXTRA_HOST_ID, host.hostId);
+            mContext.sendBroadcastAsUser(intent, userHandle);
+        }
+    }
+
     private Provider parseProviderInfoXml(ComponentName component, ResolveInfo ri) {
         Provider p = null;
 
@@ -1663,10 +2343,7 @@
             for (int i = 0; i < N; i++) {
                 Provider p = mInstalledProviders.get(i);
                 if (p.instances.size() > 0) {
-                    out.startTag(null, "p");
-                    out.attribute(null, "pkg", p.info.provider.getPackageName());
-                    out.attribute(null, "cl", p.info.provider.getClassName());
-                    out.endTag(null, "p");
+                    serializeProvider(out, p);
                     p.tag = providerIndex;
                     providerIndex++;
                 }
@@ -1675,35 +2352,14 @@
             N = mHosts.size();
             for (int i = 0; i < N; i++) {
                 Host host = mHosts.get(i);
-                out.startTag(null, "h");
-                out.attribute(null, "pkg", host.packageName);
-                out.attribute(null, "id", Integer.toHexString(host.hostId));
-                out.endTag(null, "h");
+                serializeHost(out, host);
                 host.tag = i;
             }
 
             N = mAppWidgetIds.size();
             for (int i = 0; i < N; i++) {
                 AppWidgetId id = mAppWidgetIds.get(i);
-                out.startTag(null, "g");
-                out.attribute(null, "id", Integer.toHexString(id.appWidgetId));
-                out.attribute(null, "h", Integer.toHexString(id.host.tag));
-                if (id.provider != null) {
-                    out.attribute(null, "p", Integer.toHexString(id.provider.tag));
-                }
-                if (id.options != null) {
-                    out.attribute(null, "min_width", Integer.toHexString(id.options.getInt(
-                            AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)));
-                    out.attribute(null, "min_height", Integer.toHexString(id.options.getInt(
-                            AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)));
-                    out.attribute(null, "max_width", Integer.toHexString(id.options.getInt(
-                            AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)));
-                    out.attribute(null, "max_height", Integer.toHexString(id.options.getInt(
-                            AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT)));
-                    out.attribute(null, "host_category", Integer.toHexString(id.options.getInt(
-                            AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY)));
-                }
-                out.endTag(null, "g");
+                serializeAppWidgetId(out, id);
             }
 
             Iterator<String> it = mPackagesWithBindWidgetPermission.iterator();
@@ -1804,6 +2460,11 @@
                             mNextAppWidgetId = id.appWidgetId + 1;
                         }
 
+                        // restored ID is allowed to be absent
+                        String restoredIdString = parser.getAttributeValue(null, "rid");
+                        id.restoredId = (restoredIdString == null) ? 0
+                                : Integer.parseInt(restoredIdString, 16);
+
                         Bundle options = new Bundle();
                         String minWidthString = parser.getAttributeValue(null, "min_width");
                         if (minWidthString != null) {
@@ -1978,8 +2639,7 @@
                 continue;
             }
             if (pkgName.equals(ai.packageName)) {
-                addProviderLocked(ri);
-                providersAdded = true;
+                providersAdded = addProviderLocked(ri);
             }
         }
 
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index b3571d7..1a1512f 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -24,6 +24,7 @@
 import android.app.IBackupAgent;
 import android.app.PendingIntent;
 import android.app.backup.BackupAgent;
+import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
 import android.app.backup.FullBackup;
 import android.app.backup.RestoreSet;
@@ -82,12 +83,14 @@
 import com.android.internal.backup.BackupConstants;
 import com.android.internal.backup.IBackupTransport;
 import com.android.internal.backup.IObbBackupService;
+import com.android.server.AppWidgetBackupBridge;
 import com.android.server.EventLogTags;
 import com.android.server.SystemService;
 import com.android.server.backup.PackageManagerBackupAgent.Metadata;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -115,10 +118,13 @@
 import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Random;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.zip.Deflater;
 import java.util.zip.DeflaterOutputStream;
@@ -136,22 +142,43 @@
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.spec.SecretKeySpec;
 
+import libcore.io.ErrnoException;
+import libcore.io.Libcore;
+
 public class BackupManagerService extends IBackupManager.Stub {
 
     private static final String TAG = "BackupManagerService";
     private static final boolean DEBUG = true;
     private static final boolean MORE_DEBUG = false;
 
+    // System-private key used for backing up an app's widget state.  Must
+    // begin with U+FFxx by convention (we reserve all keys starting
+    // with U+FF00 or higher for system use).
+    static final String KEY_WIDGET_STATE = "\uffed\uffedwidget";
+
     // Historical and current algorithm names
     static final String PBKDF_CURRENT = "PBKDF2WithHmacSHA1";
     static final String PBKDF_FALLBACK = "PBKDF2WithHmacSHA1And8bit";
 
     // Name and current contents version of the full-backup manifest file
+    //
+    // Manifest version history:
+    //
+    // 1 : initial release
     static final String BACKUP_MANIFEST_FILENAME = "_manifest";
     static final int BACKUP_MANIFEST_VERSION = 1;
+
+    // External archive format version history:
+    //
+    // 1 : initial release
+    // 2 : no format change per se; version bump to facilitate PBKDF2 version skew detection
+    // 3 : introduced "_meta" metadata file; no other format change per se
+    static final int BACKUP_FILE_VERSION = 3;
     static final String BACKUP_FILE_HEADER_MAGIC = "ANDROID BACKUP\n";
-    static final int BACKUP_FILE_VERSION = 2;
     static final int BACKUP_PW_FILE_VERSION = 2;
+    static final String BACKUP_METADATA_FILENAME = "_meta";
+    static final int BACKUP_METADATA_VERSION = 1;
+    static final int BACKUP_WIDGET_METADATA_TOKEN = 0x01FFED01;
     static final boolean COMPRESS_FULL_BACKUPS = true; // should be true in production
 
     static final String SHARED_BACKUP_AGENT_PACKAGE = "com.android.sharedstoragebackup";
@@ -186,6 +213,7 @@
     private static final int MSG_RUN_FULL_RESTORE = 10;
     private static final int MSG_RETRY_INIT = 11;
     private static final int MSG_RETRY_CLEAR = 12;
+    private static final int MSG_WIDGET_BROADCAST = 13;
 
     // backup task state machine tick
     static final int MSG_BACKUP_RESTORE_STEP = 20;
@@ -337,42 +365,47 @@
         public long token;
         public PackageInfo pkgInfo;
         public int pmToken; // in post-install restore, the PM's token for this transaction
-        public boolean needFullBackup;
+        public boolean isSystemRestore;
         public String[] filterSet;
 
+        // Restore a single package
         RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
-                long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) {
+                long _token, PackageInfo _pkg, int _pmToken) {
             transport = _transport;
             dirName = _dirName;
             observer = _obs;
             token = _token;
             pkgInfo = _pkg;
             pmToken = _pmToken;
-            needFullBackup = _needFullBackup;
+            isSystemRestore = false;
             filterSet = null;
         }
 
+        // Restore everything possible.  This is the form that Setup Wizard or similar
+        // restore UXes use.
         RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
-                long _token, boolean _needFullBackup) {
+                long _token) {
             transport = _transport;
             dirName = _dirName;
             observer = _obs;
             token = _token;
             pkgInfo = null;
             pmToken = 0;
-            needFullBackup = _needFullBackup;
+            isSystemRestore = true;
             filterSet = null;
         }
 
+        // Restore some set of packages.  Leave this one up to the caller to specify
+        // whether it's to be considered a system-level restore.
         RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
-                long _token, String[] _filterSet, boolean _needFullBackup) {
+                long _token, String[] _filterSet, boolean _isSystemRestore) {
             transport = _transport;
             dirName = _dirName;
             observer = _obs;
             token = _token;
             pkgInfo = null;
             pmToken = 0;
-            needFullBackup = _needFullBackup;
+            isSystemRestore = _isSystemRestore;
             filterSet = _filterSet;
         }
     }
@@ -413,16 +446,19 @@
         public boolean includeApks;
         public boolean includeObbs;
         public boolean includeShared;
+        public boolean doWidgets;
         public boolean allApps;
         public boolean includeSystem;
         public String[] packages;
 
         FullBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveObbs,
-                boolean saveShared, boolean doAllApps, boolean doSystem, String[] pkgList) {
+                boolean saveShared, boolean alsoWidgets, boolean doAllApps, boolean doSystem,
+                String[] pkgList) {
             fd = output;
             includeApks = saveApks;
             includeObbs = saveObbs;
             includeShared = saveShared;
+            doWidgets = alsoWidgets;
             allApps = doAllApps;
             includeSystem = doSystem;
             packages = pkgList;
@@ -618,7 +654,8 @@
                 FullBackupParams params = (FullBackupParams)msg.obj;
                 PerformFullBackupTask task = new PerformFullBackupTask(params.fd,
                         params.observer, params.includeApks, params.includeObbs,
-                        params.includeShared, params.curPassword, params.encryptPassword,
+                        params.includeShared, params.doWidgets,
+                        params.curPassword, params.encryptPassword,
                         params.allApps, params.includeSystem, params.packages, params.latch);
                 (new Thread(task)).start();
                 break;
@@ -631,7 +668,7 @@
                 PerformRestoreTask task = new PerformRestoreTask(
                         params.transport, params.dirName, params.observer,
                         params.token, params.pkgInfo, params.pmToken,
-                        params.needFullBackup, params.filterSet);
+                        params.isSystemRestore, params.filterSet);
                 Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
                 sendMessage(restoreMsg);
                 break;
@@ -770,6 +807,13 @@
                 }
                 break;
             }
+
+            case MSG_WIDGET_BROADCAST:
+            {
+                final Intent intent = (Intent) msg.obj;
+                mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+                break;
+            }
             }
         }
     }
@@ -2297,6 +2341,7 @@
             mSavedStateName = new File(mStateDir, packageName);
             mBackupDataName = new File(mDataDir, packageName + ".data");
             mNewStateName = new File(mStateDir, packageName + ".new");
+            if (MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
 
             mSavedState = null;
             mBackupData = null;
@@ -2359,10 +2404,40 @@
 
         @Override
         public void operationComplete() {
-            // Okay, the agent successfully reported back to us.  Spin the data off to the
+            // Okay, the agent successfully reported back to us.  The next thing we do is
+            // push the app widget state for the app, if any.
+            final String pkgName = mCurrentPackage.packageName;
+            final long filepos = mBackupDataName.length();
+            FileDescriptor fd = mBackupData.getFileDescriptor();
+            try {
+                BackupDataOutput out = new BackupDataOutput(fd);
+                byte[] widgetState = AppWidgetBackupBridge.getWidgetState(pkgName,
+                        UserHandle.USER_OWNER);
+                if (widgetState != null) {
+                    out.writeEntityHeader(KEY_WIDGET_STATE, widgetState.length);
+                    out.writeEntityData(widgetState, widgetState.length);
+                } else {
+                    // No widget state for this app, but push a 'delete' operation for it
+                    // in case they're trying to play games with the payload.
+                    out.writeEntityHeader(KEY_WIDGET_STATE, -1);
+                }
+            } catch (IOException e) {
+                // Hard disk error; recovery/failure policy TBD.  For now roll back,
+                // but we may want to consider this a transport-level failure (i.e.
+                // we're in such a bad state that we can't contemplate doing backup
+                // operations any more during this pass).
+                Slog.w(TAG, "Unable to save widget state for " + pkgName);
+                try {
+                    Libcore.os.ftruncate(fd, filepos);
+                } catch (ErrnoException ee) {
+                    Slog.w(TAG, "Unable to roll back!");
+                }
+            }
+
+            // Spin the data off to the
             // transport and proceed with the next stage.
             if (MORE_DEBUG) Slog.v(TAG, "operationComplete(): sending data to transport for "
-                    + mCurrentPackage.packageName);
+                    + pkgName);
             mBackupHandler.removeMessages(MSG_TIMEOUT);
             clearAgentState();
             addBackupTrace("operation complete");
@@ -2401,17 +2476,14 @@
                 if (mStatus == BackupConstants.TRANSPORT_OK) {
                     mBackupDataName.delete();
                     mNewStateName.renameTo(mSavedStateName);
-                    EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE,
-                            mCurrentPackage.packageName, size);
-                    logBackupComplete(mCurrentPackage.packageName);
+                    EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
+                    logBackupComplete(pkgName);
                 } else {
-                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE,
-                            mCurrentPackage.packageName);
+                    EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
                 }
             } catch (Exception e) {
-                Slog.e(TAG, "Transport error backing up " + mCurrentPackage.packageName, e);
-                EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE,
-                        mCurrentPackage.packageName);
+                Slog.e(TAG, "Transport error backing up " + pkgName, e);
+                EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
                 mStatus = BackupConstants.TRANSPORT_ERROR;
             } finally {
                 try { if (backupData != null) backupData.close(); } catch (IOException e) {}
@@ -2630,18 +2702,21 @@
         boolean mIncludeApks;
         boolean mIncludeObbs;
         boolean mIncludeShared;
+        boolean mDoWidgets;
         boolean mAllApps;
         final boolean mIncludeSystem;
-        String[] mPackages;
+        ArrayList<String> mPackages;
         String mCurrentPassword;
         String mEncryptPassword;
         AtomicBoolean mLatchObject;
         File mFilesDir;
         File mManifestFile;
+        File mMetadataFile;
         
 
         class FullBackupRunner implements Runnable {
             PackageInfo mPackage;
+            byte[] mWidgetData;
             IBackupAgent mAgent;
             ParcelFileDescriptor mPipe;
             int mToken;
@@ -2649,8 +2724,10 @@
             boolean mWriteManifest;
 
             FullBackupRunner(PackageInfo pack, IBackupAgent agent, ParcelFileDescriptor pipe,
-                    int token, boolean sendApk, boolean writeManifest)  throws IOException {
+                    int token, boolean sendApk, boolean writeManifest, byte[] widgetData)
+                            throws IOException {
                 mPackage = pack;
+                mWidgetData = widgetData;
                 mAgent = agent;
                 mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor());
                 mToken = token;
@@ -2665,12 +2742,24 @@
                             mPipe.getFileDescriptor());
 
                     if (mWriteManifest) {
+                        final boolean writeWidgetData = mWidgetData != null;
                         if (MORE_DEBUG) Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
-                        writeAppManifest(mPackage, mManifestFile, mSendApk);
+                        writeAppManifest(mPackage, mManifestFile, mSendApk, writeWidgetData);
                         FullBackup.backupToTar(mPackage.packageName, null, null,
                                 mFilesDir.getAbsolutePath(),
                                 mManifestFile.getAbsolutePath(),
                                 output);
+                        mManifestFile.delete();
+
+                        // We only need to write a metadata file if we have widget data to stash
+                        if (writeWidgetData) {
+                            writeMetadata(mPackage, mMetadataFile, mWidgetData);
+                            FullBackup.backupToTar(mPackage.packageName, null, null,
+                                    mFilesDir.getAbsolutePath(),
+                                    mMetadataFile.getAbsolutePath(),
+                                    output);
+                            mMetadataFile.delete();
+                        }
                     }
 
                     if (mSendApk) {
@@ -2695,16 +2784,19 @@
 
         PerformFullBackupTask(ParcelFileDescriptor fd, IFullBackupRestoreObserver observer, 
                 boolean includeApks, boolean includeObbs, boolean includeShared,
-                String curPassword, String encryptPassword, boolean doAllApps,
+                boolean doWidgets, String curPassword, String encryptPassword, boolean doAllApps,
                 boolean doSystem, String[] packages, AtomicBoolean latch) {
             mOutputFile = fd;
             mObserver = observer;
             mIncludeApks = includeApks;
             mIncludeObbs = includeObbs;
             mIncludeShared = includeShared;
+            mDoWidgets = doWidgets;
             mAllApps = doAllApps;
             mIncludeSystem = doSystem;
-            mPackages = packages;
+            mPackages = (packages == null)
+                    ? new ArrayList<String>()
+                    : new ArrayList<String>(Arrays.asList(packages));
             mCurrentPassword = curPassword;
             // when backing up, if there is a current backup password, we require that
             // the user use a nonempty encryption password as well.  if one is supplied
@@ -2719,13 +2811,28 @@
 
             mFilesDir = new File("/data/system");
             mManifestFile = new File(mFilesDir, BACKUP_MANIFEST_FILENAME);
+            mMetadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
+        }
+
+        void addPackagesToSet(TreeMap<String, PackageInfo> set, List<String> pkgNames) {
+            for (String pkgName : pkgNames) {
+                if (!set.containsKey(pkgName)) {
+                    try {
+                        PackageInfo info = mPackageManager.getPackageInfo(pkgName,
+                                PackageManager.GET_SIGNATURES);
+                        set.put(pkgName, info);
+                    } catch (NameNotFoundException e) {
+                        Slog.w(TAG, "Unknown package " + pkgName + ", skipping");
+                    }
+                }
+            }
         }
 
         @Override
         public void run() {
             Slog.i(TAG, "--- Performing full-dataset backup ---");
 
-            List<PackageInfo> packagesToBackup = new ArrayList<PackageInfo>();
+            TreeMap<String, PackageInfo> packagesToBackup = new TreeMap<String, PackageInfo>();
             FullBackupObbConnection obbConnection = new FullBackupObbConnection();
             obbConnection.establish();  // we'll want this later
 
@@ -2733,63 +2840,70 @@
 
             // doAllApps supersedes the package set if any
             if (mAllApps) {
-                packagesToBackup = mPackageManager.getInstalledPackages(
+                List<PackageInfo> allPackages = mPackageManager.getInstalledPackages(
                         PackageManager.GET_SIGNATURES);
-                // Exclude system apps if we've been asked to do so
-                if (mIncludeSystem == false) {
-                    for (int i = 0; i < packagesToBackup.size(); ) {
-                        PackageInfo pkg = packagesToBackup.get(i);
-                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                            packagesToBackup.remove(i);
-                        } else {
-                            i++;
-                        }
+                for (int i = 0; i < allPackages.size(); i++) {
+                    PackageInfo pkg = allPackages.get(i);
+                    // Exclude system apps if we've been asked to do so
+                    if (mIncludeSystem == true
+                            || ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0)) {
+                        packagesToBackup.put(pkg.packageName, pkg);
                     }
                 }
             }
 
+            // If we're doing widget state as well, ensure that we have all the involved
+            // host & provider packages in the set
+            if (mDoWidgets) {
+                List<String> pkgs =
+                        AppWidgetBackupBridge.getWidgetParticipants(UserHandle.USER_OWNER);
+                if (pkgs != null) {
+                    if (MORE_DEBUG) {
+                        Slog.i(TAG, "Adding widget participants to backup set:");
+                        StringBuilder sb = new StringBuilder(128);
+                        sb.append("   ");
+                        for (String s : pkgs) {
+                            sb.append(' ');
+                            sb.append(s);
+                        }
+                        Slog.i(TAG, sb.toString());
+                    }
+                    addPackagesToSet(packagesToBackup, pkgs);
+                }
+            }
+
             // Now process the command line argument packages, if any. Note that explicitly-
             // named system-partition packages will be included even if includeSystem was
             // set to false.
             if (mPackages != null) {
-                for (String pkgName : mPackages) {
-                    try {
-                        packagesToBackup.add(mPackageManager.getPackageInfo(pkgName,
-                                PackageManager.GET_SIGNATURES));
-                    } catch (NameNotFoundException e) {
-                        Slog.w(TAG, "Unknown package " + pkgName + ", skipping");
-                    }
-                }
+                addPackagesToSet(packagesToBackup, mPackages);
             }
 
-            // Cull any packages that have indicated that backups are not permitted, as well
-            // as any explicit mention of the 'special' shared-storage agent package (we
-            // handle that one at the end).
-            for (int i = 0; i < packagesToBackup.size(); ) {
-                PackageInfo pkg = packagesToBackup.get(i);
+            // Now we cull any inapplicable / inappropriate packages from the set
+            Iterator<Entry<String, PackageInfo>> iter = packagesToBackup.entrySet().iterator();
+            while (iter.hasNext()) {
+                PackageInfo pkg = iter.next().getValue();
                 if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0
                         || pkg.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE)) {
-                    packagesToBackup.remove(i);
-                } else {
-                    i++;
-                }
-            }
-
-            // Cull any packages that run as system-domain uids but do not define their
-            // own backup agents
-            for (int i = 0; i < packagesToBackup.size(); ) {
-                PackageInfo pkg = packagesToBackup.get(i);
-                if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
+                    // Cull any packages that have indicated that backups are not permitted, as well
+                    // as any explicit mention of the 'special' shared-storage agent package (we
+                    // handle that one at the end).
+                    iter.remove();
+                } else if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
                         && (pkg.applicationInfo.backupAgentName == null)) {
+                    // Cull any packages that run as system-domain uids but do not define their
+                    // own backup agents
                     if (MORE_DEBUG) {
                         Slog.i(TAG, "... ignoring non-agent system package " + pkg.packageName);
                     }
-                    packagesToBackup.remove(i);
-                } else {
-                    i++;
+                    iter.remove();
                 }
             }
 
+            // flatten the set of packages now so we can explicitly control the ordering
+            ArrayList<PackageInfo> backupQueue =
+                    new ArrayList<PackageInfo>(packagesToBackup.values());
+
             FileOutputStream ofstream = new FileOutputStream(mOutputFile.getFileDescriptor());
             OutputStream out = null;
 
@@ -2865,16 +2979,16 @@
                 if (mIncludeShared) {
                     try {
                         pkg = mPackageManager.getPackageInfo(SHARED_BACKUP_AGENT_PACKAGE, 0);
-                        packagesToBackup.add(pkg);
+                        backupQueue.add(pkg);
                     } catch (NameNotFoundException e) {
                         Slog.e(TAG, "Unable to find shared-storage backup handler");
                     }
                 }
 
                 // Now back up the app data via the agent mechanism
-                int N = packagesToBackup.size();
+                int N = backupQueue.size();
                 for (int i = 0; i < N; i++) {
-                    pkg = packagesToBackup.get(i);
+                    pkg = backupQueue.get(i);
                     backupOnePackage(pkg, out);
 
                     // after the app's agent runs to handle its private filesystem
@@ -3005,11 +3119,13 @@
                             && ((app.flags & ApplicationInfo.FLAG_SYSTEM) == 0 ||
                                 (app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
 
+                    byte[] widgetBlob = AppWidgetBackupBridge.getWidgetState(pkg.packageName,
+                            UserHandle.USER_OWNER);
                     sendOnBackupPackage(isSharedStorage ? "Shared storage" : pkg.packageName);
 
                     final int token = generateToken();
                     FullBackupRunner runner = new FullBackupRunner(pkg, agent, pipes[1],
-                            token, sendApk, !isSharedStorage);
+                            token, sendApk, !isSharedStorage, widgetBlob);
                     pipes[1].close();   // the runner has dup'd it
                     pipes[1] = null;
                     Thread t = new Thread(runner);
@@ -3085,8 +3201,8 @@
             }
         }
 
-        private void writeAppManifest(PackageInfo pkg, File manifestFile, boolean withApk)
-                throws IOException {
+        private void writeAppManifest(PackageInfo pkg, File manifestFile,
+                boolean withApk, boolean withWidgets) throws IOException {
             // Manifest format. All data are strings ending in LF:
             //     BACKUP_MANIFEST_VERSION, currently 1
             //
@@ -3124,6 +3240,43 @@
             outstream.close();
         }
 
+        // Widget metadata format. All header entries are strings ending in LF:
+        //
+        // Version 1 header:
+        //     BACKUP_METADATA_VERSION, currently "1"
+        //     package name
+        //
+        // File data (all integers are binary in network byte order)
+        // *N: 4 : integer token identifying which metadata blob
+        //     4 : integer size of this blob = N
+        //     N : raw bytes of this metadata blob
+        //
+        // Currently understood blobs (always in network byte order):
+        //
+        //     widgets : metadata token = 0x01FFED01 (BACKUP_WIDGET_METADATA_TOKEN)
+        //
+        // Unrecognized blobs are *ignored*, not errors.
+        private void writeMetadata(PackageInfo pkg, File destination, byte[] widgetData)
+                throws IOException {
+            StringBuilder b = new StringBuilder(512);
+            StringBuilderPrinter printer = new StringBuilderPrinter(b);
+            printer.println(Integer.toString(BACKUP_METADATA_VERSION));
+            printer.println(pkg.packageName);
+
+            FileOutputStream fout = new FileOutputStream(destination);
+            BufferedOutputStream bout = new BufferedOutputStream(fout);
+            DataOutputStream out = new DataOutputStream(bout);
+            bout.write(b.toString().getBytes());    // bypassing DataOutputStream
+
+            if (widgetData != null && widgetData.length > 0) {
+                out.writeInt(BACKUP_WIDGET_METADATA_TOKEN);
+                out.writeInt(widgetData.length);
+                out.write(widgetData);
+            }
+            bout.flush();
+            out.close();
+        }
+
         private void tearDown(PackageInfo pkg) {
             if (pkg != null) {
                 final ApplicationInfo app = pkg.applicationInfo;
@@ -3227,6 +3380,7 @@
         ApplicationInfo mTargetApp;
         FullBackupObbConnection mObbConnection = null;
         ParcelFileDescriptor[] mPipes = null;
+        byte[] mWidgetData = null;
 
         long mBytes;
 
@@ -3523,7 +3677,8 @@
                         // Clean up the previous agent relationship if necessary,
                         // and let the observer know we're considering a new app.
                         if (mAgent != null) {
-                            if (DEBUG) Slog.d(TAG, "Saw new package; tearing down old one");
+                            if (DEBUG) Slog.d(TAG, "Saw new package; finalizing old one");
+                            // Now we're really done
                             tearDownPipes();
                             tearDownAgent(mTargetApp);
                             mTargetApp = null;
@@ -3539,6 +3694,9 @@
                         // input file
                         skipTarPadding(info.size, instream);
                         sendOnRestorePackage(pkg);
+                    } else if (info.path.equals(BACKUP_METADATA_FILENAME)) {
+                        // Metadata blobs!
+                        readMetadata(info, instream);
                     } else {
                         // Non-manifest, so it's actual file data.  Is this a package
                         // we're ignoring?
@@ -3995,6 +4153,71 @@
             }
         }
 
+        // Read a widget metadata file, returning the restored blob
+        void readMetadata(FileMetadata info, InputStream instream) throws IOException {
+            byte[] data = null;
+
+            // Fail on suspiciously large widget dump files
+            if (info.size > 64 * 1024) {
+                throw new IOException("Metadata too big; corrupt? size=" + info.size);
+            }
+
+            byte[] buffer = new byte[(int) info.size];
+            if (readExactly(instream, buffer, 0, (int)info.size) == info.size) {
+                mBytes += info.size;
+            } else throw new IOException("Unexpected EOF in widget data");
+
+            String[] str = new String[1];
+            int offset = extractLine(buffer, 0, str);
+            int version = Integer.parseInt(str[0]);
+            if (version == BACKUP_MANIFEST_VERSION) {
+                offset = extractLine(buffer, offset, str);
+                final String pkg = str[0];
+                if (info.packageName.equals(pkg)) {
+                    // Data checks out -- the rest of the buffer is a concatenation of
+                    // binary blobs as described in the comment at writeAppWidgetData()
+                    ByteArrayInputStream bin = new ByteArrayInputStream(buffer,
+                            offset, buffer.length - offset);
+                    DataInputStream in = new DataInputStream(bin);
+                    while (bin.available() > 0) {
+                        int token = in.readInt();
+                        int size = in.readInt();
+                        if (size > 64 * 1024) {
+                            throw new IOException("Datum "
+                                    + Integer.toHexString(token)
+                                    + " too big; corrupt? size=" + info.size);
+                        }
+                        switch (token) {
+                            case BACKUP_WIDGET_METADATA_TOKEN:
+                            {
+                                if (MORE_DEBUG) {
+                                    Slog.i(TAG, "Got widget metadata for " + info.packageName);
+                                }
+                                mWidgetData = new byte[size];
+                                in.read(mWidgetData);
+                                break;
+                            }
+                            default:
+                            {
+                                if (DEBUG) {
+                                    Slog.i(TAG, "Ignoring metadata blob "
+                                            + Integer.toHexString(token)
+                                            + " for " + info.packageName);
+                                }
+                                in.skipBytes(size);
+                                break;
+                            }
+                        }
+                    }
+                } else {
+                    Slog.w(TAG, "Metadata mismatch: package " + info.packageName
+                            + " but widget data for " + pkg);
+                }
+            } else {
+                Slog.w(TAG, "Unsupported metadata version " + version);
+            }
+        }
+
         // Returns a policy constant; takes a buffer arg to reduce memory churn
         RestorePolicy readAppManifest(FileMetadata info, InputStream instream)
                 throws IOException {
@@ -4485,7 +4708,7 @@
         private PackageInfo mTargetPackage;
         private File mStateDir;
         private int mPmToken;
-        private boolean mNeedFullBackup;
+        private boolean mIsSystemRestore;
         private HashSet<String> mFilterSet;
         private long mStartRealtime;
         private PackageManagerBackupAgent mPmAgent;
@@ -4496,11 +4719,13 @@
         private boolean mFinished;
         private int mStatus;
         private File mBackupDataName;
+        private File mStageName;
         private File mNewStateName;
         private File mSavedStateName;
         private ParcelFileDescriptor mBackupData;
         private ParcelFileDescriptor mNewState;
         private PackageInfo mCurrentPackage;
+        private byte[] mWidgetData;
 
 
         class RestoreRequest {
@@ -4515,7 +4740,7 @@
 
         PerformRestoreTask(IBackupTransport transport, String dirName, IRestoreObserver observer,
                 long restoreSetToken, PackageInfo targetPackage, int pmToken,
-                boolean needFullBackup, String[] filterSet) {
+                boolean isSystemRestore, String[] filterSet) {
             mCurrentState = RestoreState.INITIAL;
             mFinished = false;
             mPmAgent = null;
@@ -4525,7 +4750,7 @@
             mToken = restoreSetToken;
             mTargetPackage = targetPackage;
             mPmToken = pmToken;
-            mNeedFullBackup = needFullBackup;
+            mIsSystemRestore = isSystemRestore;
 
             if (filterSet != null) {
                 mFilterSet = new HashSet<String>();
@@ -4695,8 +4920,7 @@
                 omPackage.packageName = PACKAGE_MANAGER_SENTINEL;
                 mPmAgent = new PackageManagerBackupAgent(
                         mPackageManager, mAgentPackages);
-                initiateOneRestore(omPackage, 0, IBackupAgent.Stub.asInterface(mPmAgent.onBind()),
-                        mNeedFullBackup);
+                initiateOneRestore(omPackage, 0, IBackupAgent.Stub.asInterface(mPmAgent.onBind()));
                 // The PM agent called operationComplete() already, because our invocation
                 // of it is process-local and therefore synchronous.  That means that a
                 // RUNNING_QUEUE message is already enqueued.  Only if we're unable to
@@ -4726,6 +4950,12 @@
 
             // Metadata is intact, so we can now run the restore queue.  If we get here,
             // we have already enqueued the necessary next-step message on the looper.
+            // We've deferred telling the App Widget service that we might be replacing
+            // the widget environment with something else, but now we know we've got
+            // data coming, so we do it here.
+            if (mIsSystemRestore) {
+                AppWidgetBackupBridge.restoreStarting(UserHandle.USER_OWNER);
+            }
         }
 
         void restoreNextAgent() {
@@ -4834,7 +5064,7 @@
 
                 // And then finally start the restore on this agent
                 try {
-                    initiateOneRestore(packageInfo, metaInfo.versionCode, agent, mNeedFullBackup);
+                    initiateOneRestore(packageInfo, metaInfo.versionCode, agent);
                     ++mCount;
                 } catch (Exception e) {
                     Slog.e(TAG, "Error when attempting restore: " + e.toString());
@@ -4888,6 +5118,9 @@
             mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_TIMEOUT,
                     TIMEOUT_RESTORE_INTERVAL);
 
+            // Kick off any work that may be needed regarding app widget restores
+            AppWidgetBackupBridge.restoreFinished(UserHandle.USER_OWNER);
+
             // done; we can finally release the wakelock
             Slog.i(TAG, "Restore complete.");
             mWakelock.release();
@@ -4895,43 +5128,92 @@
 
         // Call asynchronously into the app, passing it the restore data.  The next step
         // after this is always a callback, either operationComplete() or handleTimeout().
-        void initiateOneRestore(PackageInfo app, int appVersionCode, IBackupAgent agent,
-                boolean needFullBackup) {
+        void initiateOneRestore(PackageInfo app, int appVersionCode, IBackupAgent agent) {
             mCurrentPackage = app;
+            mWidgetData = null;
             final String packageName = app.packageName;
 
             if (DEBUG) Slog.d(TAG, "initiateOneRestore packageName=" + packageName);
 
             // !!! TODO: get the dirs from the transport
             mBackupDataName = new File(mDataDir, packageName + ".restore");
+            mStageName = new File(mDataDir, packageName + ".stage");
             mNewStateName = new File(mStateDir, packageName + ".new");
             mSavedStateName = new File(mStateDir, packageName);
 
+            // don't stage the 'android' package where the wallpaper data lives.  this is
+            // an optimization: we know there's no widget data hosted/published by that
+            // package, and this way we avoid doing a spurious copy of MB-sized wallpaper
+            // data following the download.
+            boolean staging = !packageName.equals("android");
+            ParcelFileDescriptor stage;
+            File downloadFile = (staging) ? mStageName : mBackupDataName;
+
             final int token = generateToken();
             try {
                 // Run the transport's restore pass
-                mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                stage = ParcelFileDescriptor.open(downloadFile,
                             ParcelFileDescriptor.MODE_READ_WRITE |
                             ParcelFileDescriptor.MODE_CREATE |
                             ParcelFileDescriptor.MODE_TRUNCATE);
 
                 if (!SELinux.restorecon(mBackupDataName)) {
-                    Slog.e(TAG, "SElinux restorecon failed for " + mBackupDataName);
+                    Slog.e(TAG, "SElinux restorecon failed for " + downloadFile);
                 }
 
-                if (mTransport.getRestoreData(mBackupData) != BackupConstants.TRANSPORT_OK) {
+                if (mTransport.getRestoreData(stage) != BackupConstants.TRANSPORT_OK) {
                     // Transport-level failure, so we wind everything up and
                     // terminate the restore operation.
                     Slog.e(TAG, "Error getting restore data for " + packageName);
                     EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
-                    mBackupData.close();
-                    mBackupDataName.delete();
+                    stage.close();
+                    downloadFile.delete();
                     executeNextState(RestoreState.FINAL);
                     return;
                 }
 
+                // We have the data from the transport. Now we extract and strip
+                // any per-package metadata (typically widget-related information)
+                // if appropriate
+                if (staging) {
+                    stage.close();
+                    stage = ParcelFileDescriptor.open(downloadFile,
+                            ParcelFileDescriptor.MODE_READ_ONLY);
+
+                    mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+                            ParcelFileDescriptor.MODE_READ_WRITE |
+                            ParcelFileDescriptor.MODE_CREATE |
+                            ParcelFileDescriptor.MODE_TRUNCATE);
+
+                    BackupDataInput in = new BackupDataInput(stage.getFileDescriptor());
+                    BackupDataOutput out = new BackupDataOutput(mBackupData.getFileDescriptor());
+                    byte[] buffer = new byte[8192]; // will grow when needed
+                    while (in.readNextHeader()) {
+                        final String key = in.getKey();
+                        final int size = in.getDataSize();
+
+                        // is this a special key?
+                        if (key.equals(KEY_WIDGET_STATE)) {
+                            if (DEBUG) {
+                                Slog.i(TAG, "Restoring widget state for " + packageName);
+                            }
+                            mWidgetData = new byte[size];
+                            in.readEntityData(mWidgetData, 0, size);
+                        } else {
+                            if (size > buffer.length) {
+                                buffer = new byte[size];
+                            }
+                            in.readEntityData(buffer, 0, size);
+                            out.writeEntityHeader(key, size);
+                            out.writeEntityData(buffer, size);
+                        }
+                    }
+
+                    mBackupData.close();
+                }
+
                 // Okay, we have the data.  Now have the agent do the restore.
-                mBackupData.close();
+                stage.close();
                 mBackupData = ParcelFileDescriptor.open(mBackupDataName,
                             ParcelFileDescriptor.MODE_READ_ONLY);
 
@@ -4942,7 +5224,8 @@
 
                 // Kick off the restore, checking for hung agents
                 prepareOperationTimeout(token, TIMEOUT_RESTORE_INTERVAL, this);
-                agent.doRestore(mBackupData, appVersionCode, mNewState, token, mBackupManagerBinder);
+                agent.doRestore(mBackupData, appVersionCode, mNewState,
+                        token, mBackupManagerBinder);
             } catch (Exception e) {
                 Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
                 EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, e.toString());
@@ -4965,6 +5248,7 @@
 
         void agentCleanup() {
             mBackupDataName.delete();
+            mStageName.delete();
             try { if (mBackupData != null) mBackupData.close(); } catch (IOException e) {}
             try { if (mNewState != null) mNewState.close(); } catch (IOException e) {}
             mBackupData = mNewState = null;
@@ -5023,9 +5307,17 @@
         public void operationComplete() {
             int size = (int) mBackupDataName.length();
             EventLog.writeEvent(EventLogTags.RESTORE_PACKAGE, mCurrentPackage.packageName, size);
+
             // Just go back to running the restore queue
             agentCleanup();
 
+            // If there was widget state associated with this app, get the OS to
+            // incorporate it into current bookeeping and then pass that along to
+            // the app as part of the restore operation.
+            if (mWidgetData != null) {
+                restoreWidgetData(mCurrentPackage.packageName, mWidgetData);
+            }
+
             executeNextState(RestoreState.RUNNING_QUEUE);
         }
 
@@ -5049,6 +5341,12 @@
         }
     }
 
+    // Used by both incremental and full restore
+    void restoreWidgetData(String packageName, byte[] widgetData) {
+        // Apply the restored widget state and generate the ID update for the app
+        AppWidgetBackupBridge.restoreWidgetState(packageName, widgetData, UserHandle.USER_OWNER);
+    }
+
     class PerformClearTask implements Runnable {
         IBackupTransport mTransport;
         PackageInfo mPackage;
@@ -5344,8 +5642,9 @@
     // Run a *full* backup pass for the given package, writing the resulting data stream
     // to the supplied file descriptor.  This method is synchronous and does not return
     // to the caller until the backup has been completed.
+    @Override
     public void fullBackup(ParcelFileDescriptor fd, boolean includeApks,
-            boolean includeObbs, boolean includeShared,
+            boolean includeObbs, boolean includeShared, boolean doWidgets,
             boolean doAllApps, boolean includeSystem, String[] pkgList) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "fullBackup");
 
@@ -5381,7 +5680,7 @@
             Slog.i(TAG, "Beginning full backup...");
 
             FullBackupParams params = new FullBackupParams(fd, includeApks, includeObbs,
-                    includeShared, doAllApps, includeSystem, pkgList);
+                    includeShared, doWidgets, doAllApps, includeSystem, pkgList);
             final int token = generateToken();
             synchronized (mFullConfirmations) {
                 mFullConfirmations.put(token, params);
@@ -5838,7 +6137,7 @@
                 mWakelock.acquire();
                 Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
                 msg.obj = new RestoreParams(transport, dirName, null,
-                        restoreSet, pkg, token, true);
+                        restoreSet, pkg, token);
                 mBackupHandler.sendMessage(msg);
             } catch (RemoteException e) {
                 // Binding to the transport broke; back off and proceed with the installation.
@@ -6019,7 +6318,7 @@
                         mWakelock.acquire();
                         Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
                         msg.obj = new RestoreParams(mRestoreTransport, dirName,
-                                observer, token, true);
+                                observer, token);
                         mBackupHandler.sendMessage(msg);
                         Binder.restoreCallingIdentity(oldId);
                         return 0;
@@ -6031,6 +6330,7 @@
             return -1;
         }
 
+        // Restores of more than a single package are treated as 'system' restores
         public synchronized int restoreSome(long token, IRestoreObserver observer,
                 String[] packages) {
             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
@@ -6089,7 +6389,7 @@
                         mWakelock.acquire();
                         Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
                         msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token,
-                                packages, true);
+                                packages, packages.length > 1);
                         mBackupHandler.sendMessage(msg);
                         Binder.restoreCallingIdentity(oldId);
                         return 0;
@@ -6168,7 +6468,7 @@
             mWakelock.acquire();
             Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
             msg.obj = new RestoreParams(mRestoreTransport, dirName,
-                    observer, token, app, 0, false);
+                    observer, token, app, 0);
             mBackupHandler.sendMessage(msg);
             Binder.restoreCallingIdentity(oldId);
             return 0;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index c14ed8b..168742f 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -39,8 +39,10 @@
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Pair;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.TimeUtils;
 
 import java.io.ByteArrayOutputStream;
@@ -53,9 +55,7 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.LinkedList;
-import java.util.Map;
 import java.util.TimeZone;
 
 import static android.app.AlarmManager.RTC_WAKEUP;
@@ -103,6 +103,7 @@
     private long mNextNonWakeup;
     int mBroadcastRefCount = 0;
     PowerManager.WakeLock mWakeLock;
+    boolean mLastWakeLockUnimportantForLogging;
     ArrayList<InFlight> mInFlight = new ArrayList<InFlight>();
     final AlarmHandler mHandler = new AlarmHandler();
     ClockReceiver mClockReceiver;
@@ -313,7 +314,22 @@
             return 0;
         }
     }
-    
+
+    final Comparator<Alarm> mAlarmDispatchComparator = new Comparator<Alarm>() {
+        @Override
+        public int compare(Alarm lhs, Alarm rhs) {
+            if (lhs.wakeup != rhs.wakeup) {
+                return lhs.wakeup ? -1 : 1;
+            }
+            if (lhs.whenElapsed < rhs.whenElapsed) {
+                return -1;
+            } else if (lhs.whenElapsed > rhs.whenElapsed) {
+                return 1;
+            }
+            return 0;
+        }
+    };
+
     // minimum recurrence period or alarm futurity for us to be able to fuzz it
     static final long MIN_FUZZABLE_INTERVAL = 10000;
     static final BatchTimeOrder sBatchOrder = new BatchTimeOrder();
@@ -411,8 +427,10 @@
         final Pair<String, ComponentName> mTarget;
         final BroadcastStats mBroadcastStats;
         final FilterStats mFilterStats;
+        final int mAlarmType;
 
-        InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource) {
+        InFlight(AlarmManagerService service, PendingIntent pendingIntent, WorkSource workSource,
+                int alarmType) {
             mPendingIntent = pendingIntent;
             mWorkSource = workSource;
             Intent intent = pendingIntent.getIntent();
@@ -426,6 +444,7 @@
                 mBroadcastStats.filterStats.put(mTarget, fs);
             }
             mFilterStats = fs;
+            mAlarmType = alarmType;
         }
     }
 
@@ -446,6 +465,7 @@
     }
     
     static final class BroadcastStats {
+        final int mUid;
         final String mPackageName;
 
         long aggregateTime;
@@ -453,16 +473,17 @@
         int numWakeup;
         long startTime;
         int nesting;
-        final HashMap<Pair<String, ComponentName>, FilterStats> filterStats
-                = new HashMap<Pair<String, ComponentName>, FilterStats>();
+        final ArrayMap<Pair<String, ComponentName>, FilterStats> filterStats
+                = new ArrayMap<Pair<String, ComponentName>, FilterStats>();
 
-        BroadcastStats(String packageName) {
+        BroadcastStats(int uid, String packageName) {
+            mUid = uid;
             mPackageName = packageName;
         }
     }
     
-    final HashMap<String, BroadcastStats> mBroadcastStats
-            = new HashMap<String, BroadcastStats>();
+    final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats
+            = new SparseArray<ArrayMap<String, BroadcastStats>>();
     
     @Override
     public void onStart() {
@@ -474,8 +495,8 @@
         setTimeZoneImpl(SystemProperties.get(TIMEZONE_PROPERTY));
 
         PowerManager pm = (PowerManager) getContext().getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
-        
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*alarm*");
+
         mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0,
                 new Intent(Intent.ACTION_TIME_TICK).addFlags(
                         Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -754,24 +775,26 @@
                 }
             };
             int len = 0;
-            for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) {
-                BroadcastStats bs = be.getValue();
-                for (Map.Entry<Pair<String, ComponentName>, FilterStats> fe
-                        : bs.filterStats.entrySet()) {
-                    FilterStats fs = fe.getValue();
-                    int pos = len > 0
-                            ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0;
-                    if (pos < 0) {
-                        pos = -pos - 1;
-                    }
-                    if (pos < topFilters.length) {
-                        int copylen = topFilters.length - pos - 1;
-                        if (copylen > 0) {
-                            System.arraycopy(topFilters, pos, topFilters, pos+1, copylen);
+            for (int iu=0; iu<mBroadcastStats.size(); iu++) {
+                ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
+                for (int ip=0; ip<uidStats.size(); ip++) {
+                    BroadcastStats bs = uidStats.valueAt(ip);
+                    for (int is=0; is<bs.filterStats.size(); is++) {
+                        FilterStats fs = bs.filterStats.valueAt(is);
+                        int pos = len > 0
+                                ? Arrays.binarySearch(topFilters, 0, len, fs, comparator) : 0;
+                        if (pos < 0) {
+                            pos = -pos - 1;
                         }
-                        topFilters[pos] = fs;
-                        if (len < topFilters.length) {
-                            len++;
+                        if (pos < topFilters.length) {
+                            int copylen = topFilters.length - pos - 1;
+                            if (copylen > 0) {
+                                System.arraycopy(topFilters, pos, topFilters, pos+1, copylen);
+                            }
+                            topFilters[pos] = fs;
+                            if (len < topFilters.length) {
+                                len++;
+                            }
                         }
                     }
                 }
@@ -785,7 +808,8 @@
                     TimeUtils.formatDuration(fs.aggregateTime, pw);
                     pw.print(" running, "); pw.print(fs.numWakeup);
                     pw.print(" wakeups, "); pw.print(fs.count);
-                    pw.print(" alarms: "); pw.print(fs.mBroadcastStats.mPackageName);
+                    pw.print(" alarms: "); UserHandle.formatUid(pw, fs.mBroadcastStats.mUid);
+                    pw.print(":"); pw.print(fs.mBroadcastStats.mPackageName);
                     pw.println();
                     pw.print("      ");
                     if (fs.mTarget.first != null) {
@@ -801,35 +825,39 @@
             pw.println(" ");
             pw.println("  Alarm Stats:");
             final ArrayList<FilterStats> tmpFilters = new ArrayList<FilterStats>();
-            for (Map.Entry<String, BroadcastStats> be : mBroadcastStats.entrySet()) {
-                BroadcastStats bs = be.getValue();
-                pw.print("  ");
-                if (bs.nesting > 0) pw.print("*ACTIVE* ");
-                pw.print(be.getKey());
-                pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw);
-                        pw.print(" running, "); pw.print(bs.numWakeup);
-                        pw.println(" wakeups:");
-                tmpFilters.clear();
-                for (Map.Entry<Pair<String, ComponentName>, FilterStats> fe
-                        : bs.filterStats.entrySet()) {
-                    tmpFilters.add(fe.getValue());
-                }
-                Collections.sort(tmpFilters, comparator);
-                for (int i=0; i<tmpFilters.size(); i++) {
-                    FilterStats fs = tmpFilters.get(i);
-                    pw.print("    ");
-                            if (fs.nesting > 0) pw.print("*ACTIVE* ");
-                            TimeUtils.formatDuration(fs.aggregateTime, pw);
-                            pw.print(" "); pw.print(fs.numWakeup);
-                            pw.print(" wakes " ); pw.print(fs.count);
-                            pw.print(" alarms:");
-                            if (fs.mTarget.first != null) {
-                                pw.print(" act="); pw.print(fs.mTarget.first);
-                            }
-                            if (fs.mTarget.second != null) {
-                                pw.print(" cmp="); pw.print(fs.mTarget.second.toShortString());
-                            }
-                            pw.println();
+            for (int iu=0; iu<mBroadcastStats.size(); iu++) {
+                ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(iu);
+                for (int ip=0; ip<uidStats.size(); ip++) {
+                    BroadcastStats bs = uidStats.valueAt(ip);
+                    pw.print("  ");
+                    if (bs.nesting > 0) pw.print("*ACTIVE* ");
+                    UserHandle.formatUid(pw, bs.mUid);
+                    pw.print(":");
+                    pw.print(bs.mPackageName);
+                    pw.print(" "); TimeUtils.formatDuration(bs.aggregateTime, pw);
+                            pw.print(" running, "); pw.print(bs.numWakeup);
+                            pw.println(" wakeups:");
+                    tmpFilters.clear();
+                    for (int is=0; is<bs.filterStats.size(); is++) {
+                        tmpFilters.add(bs.filterStats.valueAt(is));
+                    }
+                    Collections.sort(tmpFilters, comparator);
+                    for (int i=0; i<tmpFilters.size(); i++) {
+                        FilterStats fs = tmpFilters.get(i);
+                        pw.print("    ");
+                                if (fs.nesting > 0) pw.print("*ACTIVE* ");
+                                TimeUtils.formatDuration(fs.aggregateTime, pw);
+                                pw.print(" "); pw.print(fs.numWakeup);
+                                pw.print(" wakes " ); pw.print(fs.count);
+                                pw.print(" alarms:");
+                                if (fs.mTarget.first != null) {
+                                    pw.print(" act="); pw.print(fs.mTarget.first);
+                                }
+                                if (fs.mTarget.second != null) {
+                                    pw.print(" cmp="); pw.print(fs.mTarget.second.toShortString());
+                                }
+                                pw.println();
+                    }
                 }
             }
 
@@ -1049,7 +1077,8 @@
     private native int setKernelTime(long nativeData, long millis);
     private native int setKernelTimezone(long nativeData, int minuteswest);
 
-    void triggerAlarmsLocked(ArrayList<Alarm> triggerList, long nowELAPSED, long nowRTC) {
+    void triggerAlarmsLocked(ArrayList<Alarm> triggerList, final long nowELAPSED,
+            final long nowRTC) {
         // 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
@@ -1088,6 +1117,14 @@
 
             }
         }
+
+        Collections.sort(triggerList, mAlarmDispatchComparator);
+
+        if (localLOGV) {
+            for (int i=0; i<triggerList.size(); i++) {
+                Slog.v(TAG, "Triggering alarm #" + i + ": " + triggerList.get(i));
+            }
+        }
     }
 
     /**
@@ -1108,7 +1145,8 @@
     }
     
     private static class Alarm {
-        public int type;
+        public final int type;
+        public final boolean wakeup;
         public int count;
         public long when;
         public long windowLength;
@@ -1121,6 +1159,8 @@
         public Alarm(int _type, long _when, long _whenElapsed, long _windowLength, long _maxWhen,
                 long _interval, PendingIntent _op, WorkSource _ws) {
             type = _type;
+            wakeup = _type == AlarmManager.ELAPSED_REALTIME_WAKEUP
+                    || _type == AlarmManager.RTC_WAKEUP;
             when = _when;
             whenElapsed = _whenElapsed;
             windowLength = _windowLength;
@@ -1138,6 +1178,8 @@
             sb.append(Integer.toHexString(System.identityHashCode(this)));
             sb.append(" type ");
             sb.append(type);
+            sb.append(" when ");
+            sb.append(when);
             sb.append(" ");
             sb.append(operation.getTargetPackage());
             sb.append('}');
@@ -1242,11 +1284,12 @@
                             
                             // we have an active broadcast so stay awake.
                             if (mBroadcastRefCount == 0) {
-                                setWakelockWorkSource(alarm.operation, alarm.workSource);
+                                setWakelockWorkSource(alarm.operation, alarm.workSource,
+                                        alarm.type, true);
                                 mWakeLock.acquire();
                             }
                             final InFlight inflight = new InFlight(AlarmManagerService.this,
-                                    alarm.operation, alarm.workSource);
+                                    alarm.operation, alarm.workSource, alarm.type);
                             mInFlight.add(inflight);
                             mBroadcastRefCount++;
 
@@ -1270,8 +1313,16 @@
                                     || alarm.type == RTC_WAKEUP) {
                                 bs.numWakeup++;
                                 fs.numWakeup++;
-                                ActivityManagerNative.noteWakeupAlarm(
-                                        alarm.operation);
+                                if (alarm.workSource != null && alarm.workSource.size() > 0) {
+                                    for (int wi=0; wi<alarm.workSource.size(); wi++) {
+                                        ActivityManagerNative.noteWakeupAlarm(
+                                                alarm.operation, alarm.workSource.get(wi),
+                                                alarm.workSource.getName(wi));
+                                    }
+                                } else {
+                                    ActivityManagerNative.noteWakeupAlarm(
+                                            alarm.operation, -1, null);
+                                }
                             }
                         } catch (PendingIntent.CanceledException e) {
                             if (alarm.repeatInterval > 0) {
@@ -1293,8 +1344,18 @@
      * @param pi PendingIntent to attribute blame to if ws is null.
      * @param ws WorkSource to attribute blame.
      */
-    void setWakelockWorkSource(PendingIntent pi, WorkSource ws) {
+    void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, boolean first) {
         try {
+            final boolean unimportant = pi == mTimeTickSender;
+            mWakeLock.setUnimportantForLogging(unimportant);
+            if (first || mLastWakeLockUnimportantForLogging) {
+                mWakeLock.setHistoryTag(pi.getTag(
+                        type == ELAPSED_REALTIME_WAKEUP || type == RTC_WAKEUP
+                                ? "*walarm*:" : "*alarm*:"));
+            } else {
+                mWakeLock.setHistoryTag(null);
+            }
+            mLastWakeLockUnimportantForLogging = unimportant;
             if (ws != null) {
                 mWakeLock.setWorkSource(ws);
                 return;
@@ -1454,7 +1515,14 @@
                 if (pkgList != null && (pkgList.length > 0)) {
                     for (String pkg : pkgList) {
                         removeLocked(pkg);
-                        mBroadcastStats.remove(pkg);
+                        for (int i=mBroadcastStats.size()-1; i>=0; i--) {
+                            ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.valueAt(i);
+                            if (uidStats.remove(pkg) != null) {
+                                if (uidStats.size() <= 0) {
+                                    mBroadcastStats.removeAt(i);
+                                }
+                            }
+                        }
                     }
                 }
             }
@@ -1462,11 +1530,17 @@
     }
     
     private final BroadcastStats getStatsLocked(PendingIntent pi) {
-        String pkg = pi.getTargetPackage();
-        BroadcastStats bs = mBroadcastStats.get(pkg);
+        String pkg = pi.getCreatorPackage();
+        int uid = pi.getCreatorUid();
+        ArrayMap<String, BroadcastStats> uidStats = mBroadcastStats.get(uid);
+        if (uidStats == null) {
+            uidStats = new ArrayMap<String, BroadcastStats>();
+            mBroadcastStats.put(uid, uidStats);
+        }
+        BroadcastStats bs = uidStats.get(pkg);
         if (bs == null) {
-            bs = new BroadcastStats(pkg);
-            mBroadcastStats.put(pkg, bs);
+            bs = new BroadcastStats(uid, pkg);
+            uidStats.put(pkg, bs);
         }
         return bs;
     }
@@ -1514,7 +1588,8 @@
                     // the next of our alarms is now in flight.  reattribute the wakelock.
                     if (mInFlight.size() > 0) {
                         InFlight inFlight = mInFlight.get(0);
-                        setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource);
+                        setWakelockWorkSource(inFlight.mPendingIntent, inFlight.mWorkSource,
+                                inFlight.mAlarmType, false);
                     } else {
                         // should never happen
                         mLog.w("Alarm wakelock still held but sent queue empty");
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index e5615c0..e26747c 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -33,6 +33,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.media.AudioService;
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Handler;
@@ -42,6 +43,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Pair;
@@ -123,6 +125,8 @@
             = new ArrayMap<String, ArrayList<Callback>>();
     final ArrayMap<IBinder, Callback> mModeWatchers
             = new ArrayMap<IBinder, Callback>();
+    final SparseArray<SparseArray<Restriction>> mAudioRestrictions
+            = new SparseArray<SparseArray<Restriction>>();
 
     public final class Callback implements DeathRecipient {
         final IAppOpsCallback mCallback;
@@ -553,6 +557,58 @@
     }
 
     @Override
+    public int checkAudioOperation(int code, int stream, int uid, String packageName) {
+        synchronized (this) {
+            final int mode = checkRestrictionLocked(code, stream, uid, packageName);
+            if (mode != AppOpsManager.MODE_ALLOWED) {
+                return mode;
+            }
+        }
+        return checkOperation(code, uid, packageName);
+    }
+
+    private int checkRestrictionLocked(int code, int stream, int uid, String packageName) {
+        final SparseArray<Restriction> streamRestrictions = mAudioRestrictions.get(code);
+        if (streamRestrictions != null) {
+            final Restriction r = streamRestrictions.get(stream);
+            if (r != null && !r.exceptionPackages.contains(packageName)) {
+                return r.mode;
+            }
+        }
+        return AppOpsManager.MODE_ALLOWED;
+    }
+
+    @Override
+    public void setAudioRestriction(int code, int stream, int uid, int mode,
+            String[] exceptionPackages) {
+        verifyIncomingUid(uid);
+        verifyIncomingOp(code);
+        synchronized (this) {
+            SparseArray<Restriction> streamRestrictions = mAudioRestrictions.get(code);
+            if (streamRestrictions == null) {
+                streamRestrictions = new SparseArray<Restriction>();
+                mAudioRestrictions.put(code, streamRestrictions);
+            }
+            streamRestrictions.remove(stream);
+            if (mode != AppOpsManager.MODE_ALLOWED) {
+                final Restriction r = new Restriction();
+                r.mode = mode;
+                if (exceptionPackages != null) {
+                    final int N = exceptionPackages.length;
+                    r.exceptionPackages = new ArraySet<String>(N);
+                    for (int i = 0; i < N; i++) {
+                        final String pkg = exceptionPackages[i];
+                        if (pkg != null) {
+                            r.exceptionPackages.add(pkg.trim());
+                        }
+                    }
+                }
+                streamRestrictions.put(stream, r);
+            }
+        }
+    }
+
+    @Override
     public int checkPackage(int uid, String packageName) {
         synchronized (this) {
             if (getOpsLocked(uid, packageName, true) != null) {
@@ -1048,6 +1104,31 @@
                     }
                 }
             }
+            if (mAudioRestrictions.size() > 0) {
+                boolean printedHeader = false;
+                for (int o=0; o<mAudioRestrictions.size(); o++) {
+                    final String op = AppOpsManager.opToName(mAudioRestrictions.keyAt(o));
+                    final SparseArray<Restriction> restrictions = mAudioRestrictions.valueAt(o);
+                    for (int i=0; i<restrictions.size(); i++) {
+                        if (!printedHeader){
+                            pw.println("  Audio Restrictions:");
+                            printedHeader = true;
+                            needSep = true;
+                        }
+                        final int stream = restrictions.keyAt(i);
+                        pw.print("    "); pw.print(op);
+                        pw.print(" stream="); pw.print(AudioService.streamToString(stream));
+                        Restriction r = restrictions.valueAt(i);
+                        pw.print(": mode="); pw.println(r.mode);
+                        if (!r.exceptionPackages.isEmpty()) {
+                            pw.println("      Exceptions:");
+                            for (int j=0; j<r.exceptionPackages.size(); j++) {
+                                pw.print("        "); pw.println(r.exceptionPackages.valueAt(j));
+                            }
+                        }
+                    }
+                }
+            }
             if (needSep) {
                 pw.println();
             }
@@ -1080,4 +1161,10 @@
             }
         }
     }
+
+    private static final class Restriction {
+        private static final ArraySet<String> NO_EXCEPTIONS = new ArraySet<String>();
+        int mode;
+        ArraySet<String> exceptionPackages = NO_EXCEPTIONS;
+    }
 }
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index cc9055d..cb5946a 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -108,6 +108,7 @@
     private final Object mLock = new Object();
 
     private BatteryProperties mBatteryProps;
+    private final BatteryProperties mLastBatteryProps = new BatteryProperties();
     private boolean mBatteryLevelCritical;
     private int mLastBatteryStatus;
     private int mLastBatteryHealth;
@@ -157,7 +158,7 @@
                     "DEVPATH=/devices/virtual/switch/invalid_charger");
         }
 
-        IBinder b = ServiceManager.getService("batterypropreg");
+        IBinder b = ServiceManager.getService("batteryproperties");
         final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
                 IBatteryPropertiesRegistrar.Stub.asInterface(b);
         try {
@@ -281,6 +282,8 @@
                 mBatteryProps = props;
                 // Process the new values.
                 processValuesLocked();
+            } else {
+                mLastBatteryProps.set(props);
             }
         }
     }
@@ -311,8 +314,6 @@
                     + ", batteryLevel=" + mBatteryProps.batteryLevel
                     + ", batteryTechnology=" + mBatteryProps.batteryTechnology
                     + ", batteryVoltage=" + mBatteryProps.batteryVoltage
-                    + ", batteryCurrentNow=" + mBatteryProps.batteryCurrentNow
-                    + ", batteryChargeCounter=" + mBatteryProps.batteryChargeCounter
                     + ", batteryTemperature=" + mBatteryProps.batteryTemperature
                     + ", mBatteryLevelCritical=" + mBatteryLevelCritical
                     + ", mPlugType=" + mPlugType);
@@ -613,21 +614,15 @@
                 pw.println("  level: " + mBatteryProps.batteryLevel);
                 pw.println("  scale: " + BATTERY_SCALE);
                 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 {
+                    if (!mUpdatesStopped) {
+                        mLastBatteryProps.set(mBatteryProps);
+                    }
                     boolean update = true;
                     if ("ac".equals(key)) {
                         mBatteryProps.chargerAcOnline = Integer.parseInt(value) != 0;
@@ -660,13 +655,17 @@
             } else if (args.length == 1 && "reset".equals(args[0])) {
                 long ident = Binder.clearCallingIdentity();
                 try {
-                    mUpdatesStopped = false;
+                    if (mUpdatesStopped) {
+                        mUpdatesStopped = false;
+                        mBatteryProps.set(mLastBatteryProps);
+                        processValuesLocked();
+                    }
                 } finally {
                     Binder.restoreCallingIdentity(ident);
                 }
             } else {
                 pw.println("Dump current battery state, or:");
-                pw.println("  set ac|usb|wireless|status|level|invalid <value>");
+                pw.println("  set [ac|usb|wireless|status|level|invalid] <value>");
                 pw.println("  reset");
             }
         }
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 546324a..0d6f548 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1005,7 +1005,7 @@
                         mState = BluetoothAdapter.STATE_OFF;
                         // enable
                         handleEnable(mQuietEnable);
-		    } else if (mBinding || mBluetooth != null) {
+                    } else if (mBinding || mBluetooth != null) {
                         Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
                         userMsg.arg2 = 1 + msg.arg2;
                         // if user is switched when service is being binding
@@ -1014,7 +1014,7 @@
                         if (DBG) {
                             Log.d(TAG, "delay MESSAGE_USER_SWITCHED " + userMsg.arg2);
                         }
-		    }
+                    }
                     break;
                 }
             }
diff --git a/services/core/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java
index 710fb9d..60b366a 100644
--- a/services/core/java/com/android/server/CommonTimeManagementService.java
+++ b/services/core/java/com/android/server/CommonTimeManagementService.java
@@ -18,7 +18,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.net.InetAddress;
 
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -26,10 +25,8 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
 import android.net.INetworkManagementEventObserver;
 import android.net.InterfaceConfiguration;
-import android.net.NetworkInfo;
 import android.os.Binder;
 import android.os.CommonTimeConfig;
 import android.os.Handler;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 57ee031..45cdb65 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -117,6 +117,7 @@
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.XmlUtils;
 import com.android.server.am.BatteryStatsService;
@@ -147,7 +148,6 @@
 import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.URL;
-import java.net.URLConnection;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -1183,9 +1183,9 @@
 
     private INetworkManagementEventObserver mDataActivityObserver = new BaseNetworkObserver() {
         @Override
-        public void interfaceClassDataActivityChanged(String label, boolean active) {
+        public void interfaceClassDataActivityChanged(String label, boolean active, long tsNanos) {
             int deviceType = Integer.parseInt(label);
-            sendDataActivityBroadcast(deviceType, active);
+            sendDataActivityBroadcast(deviceType, active, tsNanos);
         }
     };
 
@@ -1986,7 +1986,9 @@
         mNetTrackers[prevNetType].setTeardownRequested(false);
 
         // Remove idletimer previously setup in {@code handleConnect}
-        removeDataActivityTracking(prevNetType);
+        if (mNetConfigs[prevNetType].isDefault()) {
+            removeDataActivityTracking(prevNetType);
+        }
 
         /*
          * If the disconnected network is not the active one, then don't report
@@ -2167,10 +2169,11 @@
         sendStickyBroadcastDelayed(makeGeneralIntent(info, bcastType), delayMs);
     }
 
-    private void sendDataActivityBroadcast(int deviceType, boolean active) {
+    private void sendDataActivityBroadcast(int deviceType, boolean active, long tsNanos) {
         Intent intent = new Intent(ConnectivityManager.ACTION_DATA_ACTIVITY_CHANGE);
         intent.putExtra(ConnectivityManager.EXTRA_DEVICE_TYPE, deviceType);
         intent.putExtra(ConnectivityManager.EXTRA_IS_ACTIVE, active);
+        intent.putExtra(ConnectivityManager.EXTRA_REALTIME_NS, tsNanos);
         final long ident = Binder.clearCallingIdentity();
         try {
             mContext.sendOrderedBroadcastAsUser(intent, UserHandle.ALL,
@@ -2318,8 +2321,6 @@
     private void handleConnect(NetworkInfo info) {
         final int newNetType = info.getType();
 
-        setupDataActivityTracking(newNetType);
-
         // snapshot isFailover, because sendConnectedBroadcast() resets it
         boolean isFailover = info.isFailover();
         final NetworkStateTracker thisNet = mNetTrackers[newNetType];
@@ -2357,6 +2358,7 @@
                         return;
                 }
             }
+            setupDataActivityTracking(newNetType);
             synchronized (ConnectivityService.this) {
                 // have a new default network, release the transition wakelock in a second
                 // if it's held.  The second pause is to allow apps to reconnect over the
@@ -2394,36 +2396,6 @@
         }
     }
 
-    private void handleCaptivePortalTrackerCheck(NetworkInfo info) {
-        if (DBG) log("Captive portal check " + info);
-        int type = info.getType();
-        final NetworkStateTracker thisNet = mNetTrackers[type];
-        if (mNetConfigs[type].isDefault()) {
-            if (mActiveDefaultNetwork != -1 && mActiveDefaultNetwork != type) {
-                if (isNewNetTypePreferredOverCurrentNetType(type)) {
-                    if (DBG) log("Captive check on " + info.getTypeName());
-                    mCaptivePortalTracker.detectCaptivePortal(new NetworkInfo(info));
-                    return;
-                } else {
-                    if (DBG) log("Tear down low priority net " + info.getTypeName());
-                    teardown(thisNet);
-                    return;
-                }
-            }
-        }
-
-        if (DBG) log("handleCaptivePortalTrackerCheck: call captivePortalCheckComplete ni=" + info);
-        thisNet.captivePortalCheckComplete();
-    }
-
-    /** @hide */
-    @Override
-    public void captivePortalCheckComplete(NetworkInfo info) {
-        enforceConnectivityInternalPermission();
-        if (DBG) log("captivePortalCheckComplete: ni=" + info);
-        mNetTrackers[info.getType()].captivePortalCheckComplete();
-    }
-
     /** @hide */
     @Override
     public void captivePortalCheckCompleted(NetworkInfo info, boolean isCaptivePortal) {
@@ -2436,7 +2408,7 @@
      * Setup data activity tracking for the given network interface.
      *
      * Every {@code setupDataActivityTracking} should be paired with a
-     * {@link removeDataActivityTracking} for cleanup.
+     * {@link #removeDataActivityTracking} for cleanup.
      */
     private void setupDataActivityTracking(int type) {
         final NetworkStateTracker thisNet = mNetTrackers[type];
@@ -2447,7 +2419,7 @@
         if (ConnectivityManager.isNetworkTypeMobile(type)) {
             timeout = Settings.Global.getInt(mContext.getContentResolver(),
                                              Settings.Global.DATA_ACTIVITY_TIMEOUT_MOBILE,
-                                             0);
+                                             5);
             // Canonicalize mobile network type
             type = ConnectivityManager.TYPE_MOBILE;
         } else if (ConnectivityManager.TYPE_WIFI == type) {
@@ -2461,8 +2433,10 @@
 
         if (timeout > 0 && iface != null) {
             try {
-                mNetd.addIdleTimer(iface, timeout, Integer.toString(type));
-            } catch (RemoteException e) {
+                mNetd.addIdleTimer(iface, timeout, type);
+            } catch (Exception e) {
+                // You shall not crash!
+                loge("Exception in setupDataActivityTracking " + e);
             }
         }
     }
@@ -2479,7 +2453,8 @@
             try {
                 // the call fails silently if no idletimer setup for this interface
                 mNetd.removeIdleTimer(iface);
-            } catch (RemoteException e) {
+            } catch (Exception e) {
+                loge("Exception in removeDataActivityTracking " + e);
             }
         }
     }
@@ -2534,9 +2509,9 @@
                                     "\n   car=" + car);
                         }
                     } else {
-                        if (DBG) {
-                            log("handleConnectivityChange: address are the same reset per doReset" +
-                                   " linkProperty[" + netType + "]:" +
+                        if (VDBG) {
+                            log("handleConnectivityChange: addresses are the same reset per" +
+                                   " doReset linkProperty[" + netType + "]:" +
                                    " resetMask=" + resetMask);
                         }
                     }
@@ -2727,7 +2702,7 @@
        final int mtu = nt.getLinkProperties().getMtu();
 
        if (mtu < 68 || mtu > 10000) {
-           loge("Unexpected mtu value: " + nt);
+           loge("Unexpected mtu value: " + mtu + ", " + nt);
            return;
        }
 
@@ -2974,6 +2949,9 @@
             }
         }
 
+        pw.print("Active default network: "); pw.println(getNetworkTypeName(mActiveDefaultNetwork));
+        pw.println();
+
         pw.println("Network Requester Pids:");
         pw.increaseIndent();
         for (int net : mPriorityList) {
@@ -3059,9 +3037,6 @@
                     if (info.getDetailedState() ==
                             NetworkInfo.DetailedState.FAILED) {
                         handleConnectionFailure(info);
-                    } else if (info.getDetailedState() ==
-                            DetailedState.CAPTIVE_PORTAL_CHECK) {
-                        handleCaptivePortalTrackerCheck(info);
                     } else if (info.isConnectedToProvisioningNetwork()) {
                         /**
                          * TODO: Create ConnectivityManager.TYPE_MOBILE_PROVISIONING
@@ -4629,10 +4604,13 @@
          * @param seconds
          */
         private static void sleep(int seconds) {
-            try {
-                Thread.sleep(seconds * 1000);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
+            long stopTime = System.nanoTime() + (seconds * 1000000000);
+            long sleepTime;
+            while ((sleepTime = stopTime - System.nanoTime()) > 0) {
+                try {
+                    Thread.sleep(sleepTime / 1000000);
+                } catch (InterruptedException ignored) {
+                }
             }
         }
 
@@ -4668,16 +4646,28 @@
             mdst.setEnableFailFastMobileData(DctConstants.ENABLED);
             mdst.enableMobileProvisioning(url);
         } else {
-            if (DBG) log("handleMobileProvisioningAction: not prov network, launch browser directly");
-            Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
-                    Intent.CATEGORY_APP_BROWSER);
-            newIntent.setData(Uri.parse(url));
-            newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
-                    Intent.FLAG_ACTIVITY_NEW_TASK);
-            try {
-                mContext.startActivity(newIntent);
-            } catch (ActivityNotFoundException e) {
-                loge("handleMobileProvisioningAction: startActivity failed" + e);
+            if (DBG) log("handleMobileProvisioningAction: not prov network");
+            // Check for  apps that can handle provisioning first
+            Intent provisioningIntent = new Intent(TelephonyIntents.ACTION_CARRIER_SETUP);
+            provisioningIntent.addCategory(TelephonyIntents.CATEGORY_MCCMNC_PREFIX
+                    + mTelephonyManager.getSimOperator());
+            if (mContext.getPackageManager().resolveActivity(provisioningIntent, 0 /* flags */)
+                    != null) {
+                provisioningIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
+                        Intent.FLAG_ACTIVITY_NEW_TASK);
+                mContext.startActivity(provisioningIntent);
+            } else {
+                // If no apps exist, use standard URL ACTION_VIEW method
+                Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
+                        Intent.CATEGORY_APP_BROWSER);
+                newIntent.setData(Uri.parse(url));
+                newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
+                        Intent.FLAG_ACTIVITY_NEW_TASK);
+                try {
+                    mContext.startActivity(newIntent);
+                } catch (ActivityNotFoundException e) {
+                    loge("handleMobileProvisioningAction: startActivity failed" + e);
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/ConsumerIrService.java b/services/core/java/com/android/server/ConsumerIrService.java
index 583f1bc..ea6812d 100644
--- a/services/core/java/com/android/server/ConsumerIrService.java
+++ b/services/core/java/com/android/server/ConsumerIrService.java
@@ -16,33 +16,13 @@
 
 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.lang.RuntimeException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.ListIterator;
 
 public class ConsumerIrService extends IConsumerIrService.Stub {
     private static final String TAG = "ConsumerIrService";
diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java
index ac25dc5..bc12fc5 100644
--- a/services/core/java/com/android/server/DiskStatsService.java
+++ b/services/core/java/com/android/server/DiskStatsService.java
@@ -19,7 +19,6 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.Environment;
-import android.os.FileUtils;
 import android.os.StatFs;
 import android.os.SystemClock;
 
diff --git a/services/core/java/com/android/server/EntropyMixer.java b/services/core/java/com/android/server/EntropyMixer.java
index cfdbf7d..24d8d1e 100644
--- a/services/core/java/com/android/server/EntropyMixer.java
+++ b/services/core/java/com/android/server/EntropyMixer.java
@@ -20,7 +20,6 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.io.PrintWriter;
 
 import android.content.BroadcastReceiver;
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 399e7d1..0f78c9b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -52,12 +52,12 @@
 # NotificationManagerService.java
 # ---------------------------
 # when a NotificationManager.notify is called
-2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
+2750 notification_enqueue (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
 # when someone tries to cancel a notification, the notification manager sometimes
 # calls this with flags too
-2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
+2751 notification_cancel (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
 # when someone tries to cancel all of the notifications for a particular package
-2752 notification_cancel_all (pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
+2752 notification_cancel_all (uid|1|5),(pid|1|5),(pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
 
 
 # ---------------------------
diff --git a/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java b/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java
index 6fbf713..0cf9dcd 100644
--- a/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java
+++ b/services/core/java/com/android/server/INativeDaemonConnectorCallbacks.java
@@ -20,5 +20,6 @@
 interface INativeDaemonConnectorCallbacks {
 
     void onDaemonConnected();
+    boolean onCheckHoldWakeLock(int code);
     boolean onEvent(int code, String raw, String[] cooked);
 }
diff --git a/services/core/java/com/android/server/IdleMaintenanceService.java b/services/core/java/com/android/server/IdleMaintenanceService.java
index b0a1aca..acc6abe 100644
--- a/services/core/java/com/android/server/IdleMaintenanceService.java
+++ b/services/core/java/com/android/server/IdleMaintenanceService.java
@@ -16,22 +16,38 @@
 
 package com.android.server;
 
-import android.app.Activity;
-import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
+import android.app.maintenance.IIdleCallback;
+import android.app.maintenance.IIdleService;
+import android.app.maintenance.IdleService;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.os.Handler;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.WorkSource;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
 
 /**
  * This service observes the device state and when applicable sends
@@ -47,12 +63,15 @@
  *
  * The end of a maintenance window is announced only if: a start was
  * announced AND the screen turned on or a dream was stopped.
+ *
+ * Method naming note:
+ * Methods whose name ends with "Tm" must only be called from the main thread.
  */
 public class IdleMaintenanceService extends BroadcastReceiver {
 
     private static final boolean DEBUG = false;
 
-    private static final String LOG_TAG = IdleMaintenanceService.class.getSimpleName();
+    private static final String TAG = IdleMaintenanceService.class.getSimpleName();
 
     private static final int LAST_USER_ACTIVITY_TIME_INVALID = -1;
 
@@ -74,36 +93,480 @@
     private static final String ACTION_FORCE_IDLE_MAINTENANCE =
         "com.android.server.IdleMaintenanceService.action.FORCE_IDLE_MAINTENANCE";
 
-    private static final Intent sIdleMaintenanceStartIntent;
-    static {
-        sIdleMaintenanceStartIntent = new Intent(Intent.ACTION_IDLE_MAINTENANCE_START);
-        sIdleMaintenanceStartIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-    };
+    static final int MSG_OP_COMPLETE = 1;
+    static final int MSG_IDLE_FINISHED = 2;
+    static final int MSG_TIMEOUT = 3;
 
-    private static final Intent sIdleMaintenanceEndIntent;
-    static {
-        sIdleMaintenanceEndIntent = new Intent(Intent.ACTION_IDLE_MAINTENANCE_END);
-        sIdleMaintenanceEndIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-    }
+    // when a timeout happened, what were we expecting?
+    static final int VERB_BINDING = 1;
+    static final int VERB_IDLING = 2;
+    static final int VERB_ENDING = 3;
+
+    // What are our relevant timeouts / allocated slices?
+    static final long OP_TIMEOUT = 8 * 1000;  // 8 seconds to bind or ack the start
+    static final long IDLE_TIMESLICE = 10 * 60 * 1000;  // ten minutes for each idler
 
     private final AlarmManager mAlarmService;
-
     private final BatteryService mBatteryService;
-
     private final PendingIntent mUpdateIdleMaintenanceStatePendingIntent;
-
     private final Context mContext;
-
     private final WakeLock mWakeLock;
-
-    private final Handler mHandler;
+    private final WorkSource mSystemWorkSource = new WorkSource(Process.myUid());
 
     private long mLastIdleMaintenanceStartTimeMillis;
-
     private long mLastUserActivityElapsedTimeMillis = LAST_USER_ACTIVITY_TIME_INVALID;
-
     private boolean mIdleMaintenanceStarted;
 
+    final IdleCallback mCallback;
+    final Handler mHandler;
+
+    final Random mTokenGenerator = new Random();
+
+    int makeToken() {
+        int token;
+        do  {
+            token = mTokenGenerator.nextInt(Integer.MAX_VALUE);
+        } while (token == 0);
+        return token;
+    }
+
+    class ActiveTask {
+        public IdleServiceInfo who;
+        public int verb;
+        public int token;
+
+        ActiveTask(IdleServiceInfo target, int action) {
+            who = target;
+            verb = action;
+            token = makeToken();
+        }
+
+        @Override
+        public String toString() {
+            return "ActiveTask{" + Integer.toHexString(this.hashCode())
+                    + " : verb=" + verb
+                    + " : token=" + token
+                    + " : "+ who + "}";
+        }
+    }
+
+    // What operations are in flight?
+    final SparseArray<ActiveTask> mPendingOperations = new SparseArray<ActiveTask>();
+
+    // Idle service queue management
+    class IdleServiceInfo {
+        public final ComponentName componentName;
+        public final int uid;
+        public IIdleService service;
+
+        IdleServiceInfo(ResolveInfo info, ComponentName cname) {
+            componentName = cname;  // derived from 'info' but this avoids an extra object
+            uid = info.serviceInfo.applicationInfo.uid;
+            service = null;
+        }
+
+        @Override
+        public int hashCode() {
+            return componentName.hashCode();
+        }
+
+        @Override
+        public String toString() {
+            return "IdleServiceInfo{" + componentName
+                    + " / " + (service == null ? "null" : service.asBinder()) + "}";
+        }
+    }
+
+    final ArrayMap<ComponentName, IdleServiceInfo> mIdleServices =
+            new ArrayMap<ComponentName, IdleServiceInfo>();
+    final LinkedList<IdleServiceInfo> mIdleServiceQueue = new LinkedList<IdleServiceInfo>();
+    IdleServiceInfo mCurrentIdler;  // set when we've committed to launching an idler
+    IdleServiceInfo mLastIdler;     // end of queue when idling begins
+
+    void reportNoTimeout(int token, boolean result) {
+        final Message msg = mHandler.obtainMessage(MSG_OP_COMPLETE, result ? 1 : 0, token);
+        mHandler.sendMessage(msg);
+    }
+
+    // Binder acknowledgment trampoline
+    class IdleCallback extends IIdleCallback.Stub {
+        @Override
+        public void acknowledgeStart(int token, boolean result) throws RemoteException {
+            reportNoTimeout(token, result);
+        }
+
+        @Override
+        public void acknowledgeStop(int token) throws RemoteException {
+            reportNoTimeout(token, false);
+        }
+
+        @Override
+        public void idleFinished(int token) throws RemoteException {
+            if (DEBUG) {
+                Slog.v(TAG, "idleFinished: " + token);
+            }
+            final Message msg = mHandler.obtainMessage(MSG_IDLE_FINISHED, 0, token);
+            mHandler.sendMessage(msg);
+        }
+    }
+
+    // Stuff that we run on a Handler
+    class IdleHandler extends Handler {
+        public IdleHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final int token = msg.arg2;
+
+            switch (msg.what) {
+                case MSG_OP_COMPLETE: {
+                    if (DEBUG) {
+                        Slog.i(TAG, "MSG_OP_COMPLETE of " + token);
+                    }
+                    ActiveTask task = mPendingOperations.get(token);
+                    if (task != null) {
+                        mPendingOperations.remove(token);
+                        removeMessages(MSG_TIMEOUT);
+
+                        handleOpCompleteTm(task, msg.arg1);
+                    } else {
+                        // Can happen in a race between timeout and actual
+                        // (belated) completion of a "begin idling" or similar
+                        // operation.  In that state we've already processed the
+                        // timeout, so we intentionally no-op here.
+                        if (DEBUG) {
+                            Slog.w(TAG, "Belated op-complete of " + token);
+                        }
+                    }
+                    break;
+                }
+
+                case MSG_IDLE_FINISHED: {
+                    if (DEBUG) {
+                        Slog.i(TAG, "MSG_IDLE_FINISHED of " + token);
+                    }
+                    ActiveTask task = mPendingOperations.get(token);
+                    if (task != null) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "... removing task " + token);
+                        }
+                        mPendingOperations.remove(token);
+                        removeMessages(MSG_TIMEOUT);
+
+                        handleIdleFinishedTm(task);
+                    } else {
+                        // Can happen "legitimately" from an app explicitly calling
+                        // idleFinished() after already having been told that its slice
+                        // has ended.
+                        if (DEBUG) {
+                            Slog.w(TAG, "Belated idle-finished of " + token);
+                        }
+                    }
+                    break;
+                }
+
+                case MSG_TIMEOUT: {
+                    if (DEBUG) {
+                        Slog.i(TAG, "MSG_TIMEOUT of " + token);
+                    }
+                    ActiveTask task = mPendingOperations.get(token);
+                    if (task != null) {
+                        mPendingOperations.remove(token);
+                        removeMessages(MSG_OP_COMPLETE);
+
+                        handleTimeoutTm(task);
+                    } else {
+                        // This one should not happen; we flushed timeout messages
+                        // whenever we entered a state after which we have established
+                        // that they are not appropriate.
+                        Slog.w(TAG, "Unexpected timeout of " + token);
+                    }
+                    break;
+                }
+
+                default:
+                    Slog.w(TAG, "Unknown message: " + msg.what);
+            }
+        }
+    }
+
+    void handleTimeoutTm(ActiveTask task) {
+        switch (task.verb) {
+        case VERB_BINDING: {
+            // We were trying to bind to this service, but it wedged or otherwise
+            // failed to respond in time.  Let it stay in the queue for the next
+            // time around, but just give up on it for now and go on to the next.
+            startNextIdleServiceTm();
+            break;
+        }
+        case VERB_IDLING: {
+            // The service has reached the end of its designated idle timeslice.
+            // This is not considered an error.
+            if (DEBUG) {
+                Slog.i(TAG, "Idler reached end of timeslice: " + task.who);
+            }
+            sendEndIdleTm(task.who);
+            break;
+        }
+        case VERB_ENDING: {
+            if (mCurrentIdler == task.who) {
+                if (DEBUG) {
+                    Slog.i(TAG, "Task timed out when ending; unbind needed");
+                }
+                handleIdleFinishedTm(task);
+            } else {
+                if (DEBUG) {
+                    Slog.w(TAG, "Ending timeout for non-current idle service!");
+                }
+            }
+            break;
+        }
+        default: {
+            Slog.w(TAG, "Unknown timeout state " + task.verb);
+            break;
+        }
+        }
+    }
+
+    void handleOpCompleteTm(ActiveTask task, int result) {
+        if (DEBUG) {
+            Slog.i(TAG, "handleOpComplete : task=" + task + " result=" + result);
+        }
+        if (task.verb == VERB_IDLING) {
+            // If the service was told to begin idling and responded positively, then
+            // it has begun idling and will eventually either explicitly finish, or
+            // reach the end of its allotted timeslice.  It's running free now, so we
+            // just schedule the idle-expiration timeout under the token it's already been
+            // given and let it keep going.
+            if (result != 0) {
+                scheduleOpTimeoutTm(task);
+            } else {
+                // The idle service has indicated that it does not, in fact,
+                // need to run at present, so we immediately indicate that it's
+                // to finish idling, and go on to the next idler.
+                if (DEBUG) {
+                    Slog.i(TAG, "Idler declined idling; moving along");
+                }
+                sendEndIdleTm(task.who);
+            }
+        } else {
+            // In the idling case, the task will be cleared either as the result of a timeout
+            // or of an explicit idleFinished().  For all other operations (binding, ending) we
+            // are done with the task as such, so we remove it from our bookkeeping.
+            if (DEBUG) {
+                Slog.i(TAG, "Clearing task " + task);
+            }
+            mPendingOperations.remove(task.token);
+            if (task.verb == VERB_ENDING) {
+                // The last bit of handshaking around idle cessation for this target
+                handleIdleFinishedTm(task);
+            }
+        }
+    }
+
+    void handleIdleFinishedTm(ActiveTask task) {
+        final IdleServiceInfo who = task.who;
+        if (who == mCurrentIdler) {
+            if (DEBUG) {
+                Slog.i(TAG, "Current idler has finished: " + who);
+                Slog.i(TAG, "Attributing wakelock to system work source");
+            }
+            mContext.unbindService(mConnection);
+            startNextIdleServiceTm();
+        } else {
+            Slog.w(TAG, "finish from non-current idle service? " + who);
+        }
+    }
+
+    void updateIdleServiceQueueTm() {
+        if (DEBUG) {
+            Slog.i(TAG, "Updating idle service queue");
+        }
+        PackageManager pm = mContext.getPackageManager();
+        Intent idleIntent = new Intent(IdleService.SERVICE_INTERFACE);
+        List<ResolveInfo> services = pm.queryIntentServices(idleIntent, 0);
+        for (ResolveInfo info : services) {
+            if (info.serviceInfo != null) {
+                if (IdleService.PERMISSION_BIND.equals(info.serviceInfo.permission)) {
+                    final ComponentName componentName = new ComponentName(
+                            info.serviceInfo.packageName,
+                            info.serviceInfo.name);
+                    if (DEBUG) {
+                        Slog.i(TAG, "   - " + componentName);
+                    }
+                    if (!mIdleServices.containsKey(componentName)) {
+                        if (DEBUG) {
+                            Slog.i(TAG, "      + not known; adding");
+                        }
+                        IdleServiceInfo serviceInfo = new IdleServiceInfo(info, componentName);
+                        mIdleServices.put(componentName, serviceInfo);
+                        mIdleServiceQueue.add(serviceInfo);
+                    }
+                } else {
+                    if (DEBUG) {
+                        Slog.i(TAG, "Idle service " + info.serviceInfo
+                                + " does not have required permission; ignoring");
+                    }
+                }
+            }
+        }
+    }
+
+    void startNextIdleServiceTm() {
+        mWakeLock.setWorkSource(mSystemWorkSource);
+
+        if (mLastIdler == null) {
+            // we've run the queue; nothing more to do until the next idle interval.
+            if (DEBUG) {
+                Slog.i(TAG, "Queue already drained; nothing more to do");
+            }
+            return;
+        }
+
+        if (DEBUG) {
+            Slog.i(TAG, "startNextIdleService : last=" + mLastIdler + " cur=" + mCurrentIdler);
+            if (mIdleServiceQueue.size() > 0) {
+                int i = 0;
+                Slog.i(TAG, "Queue (" + mIdleServiceQueue.size() + "):");
+                for (IdleServiceInfo info : mIdleServiceQueue) {
+                    Slog.i(TAG, "   " + i + " : " + info);
+                    i++;
+                }
+            }
+        }
+        if (mCurrentIdler != mLastIdler) {
+            if (mIdleServiceQueue.size() > 0) {
+                IdleServiceInfo target = mIdleServiceQueue.pop();
+                if (DEBUG) {
+                    Slog.i(TAG, "starting next idle service " + target);
+                }
+                Intent idleIntent = new Intent(IdleService.SERVICE_INTERFACE);
+                idleIntent.setComponent(target.componentName);
+                mCurrentIdler = target;
+                ActiveTask task = new ActiveTask(target, VERB_BINDING);
+                scheduleOpTimeoutTm(task);
+                boolean bindOk = mContext.bindServiceAsUser(idleIntent, mConnection,
+                        Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY, UserHandle.OWNER);
+                if (!bindOk) {
+                    if (DEBUG) {
+                        Slog.w(TAG, "bindService() to " + target.componentName
+                                + " failed");
+                    }
+                } else {
+                    mIdleServiceQueue.add(target);  // at the end for next time
+                    if (DEBUG) { Slog.i(TAG, "Attributing wakelock to target uid " + target.uid); }
+                    mWakeLock.setWorkSource(new WorkSource(target.uid));
+                }
+            } else {
+                // Queue is empty but mLastIdler is non-null -- eeep.  Clear *everything*
+                // and wind up until the next time around.
+                Slog.e(TAG, "Queue unexpectedly empty; resetting.  last="
+                        + mLastIdler + " cur=" + mCurrentIdler);
+                mHandler.removeMessages(MSG_TIMEOUT);
+                mPendingOperations.clear();
+                stopIdleMaintenanceTm();
+            }
+        } else {
+            // we've reached the place we started, so mark the queue as drained
+            if (DEBUG) {
+                Slog.i(TAG, "Reached end of queue.");
+            }
+            stopIdleMaintenanceTm();
+        }
+    }
+
+    void sendStartIdleTm(IdleServiceInfo who) {
+        ActiveTask task = new ActiveTask(who, VERB_IDLING);
+        scheduleOpTimeoutTm(task);
+        try {
+            who.service.startIdleMaintenance(mCallback, task.token);
+        } catch (RemoteException e) {
+            // We bound to it, but now we can't reach it.  Bail and go on to the
+            // next service.
+            mContext.unbindService(mConnection);
+            if (DEBUG) { Slog.i(TAG, "Attributing wakelock to system work source"); }
+            mHandler.removeMessages(MSG_TIMEOUT);
+            startNextIdleServiceTm();
+        }
+    }
+
+    void sendEndIdleTm(IdleServiceInfo who) {
+        ActiveTask task = new ActiveTask(who, VERB_ENDING);
+        scheduleOpTimeoutTm(task);
+        if (DEBUG) {
+            Slog.i(TAG, "Sending end-idle to " + who);
+        }
+        try {
+            who.service.stopIdleMaintenance(mCallback, task.token);
+        } catch (RemoteException e) {
+            // We bound to it, but now we can't reach it.  Bail and go on to the
+            // next service.
+            mContext.unbindService(mConnection);
+            if (DEBUG) { Slog.i(TAG, "Attributing wakelock to system work source"); }
+            mHandler.removeMessages(MSG_TIMEOUT);
+            startNextIdleServiceTm();
+        }
+    }
+
+    ServiceConnection mConnection = new ServiceConnection() {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (DEBUG) {
+                Slog.i(TAG, "onServiceConnected(" + name + ")");
+            }
+            IdleServiceInfo info = mIdleServices.get(name);
+            if (info != null) {
+                // Bound!  Cancel the bind timeout
+                mHandler.removeMessages(MSG_TIMEOUT);
+                // Now tell it to start its idle work
+                info.service = IIdleService.Stub.asInterface(service);
+                sendStartIdleTm(info);
+            } else {
+                // We bound to a service we don't know about.  That's ungood.
+                Slog.e(TAG, "Connected to unexpected component " + name);
+                mContext.unbindService(this);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            if (DEBUG) {
+                Slog.i(TAG, "onServiceDisconnected(" + name + ")");
+            }
+            IdleServiceInfo who = mIdleServices.get(name);
+            if (who == mCurrentIdler) {
+                // Hm, okay; they didn't tell us they were finished but they
+                // went away.  Crashed, probably.  Oh well.  They're gone, so
+                // we can't finish them cleanly; just force things along.
+                Slog.w(TAG, "Idler unexpectedly vanished: " + mCurrentIdler);
+                mContext.unbindService(this);
+                mHandler.removeMessages(MSG_TIMEOUT);
+                startNextIdleServiceTm();
+            } else {
+                // Not the current idler, so we don't interrupt our process...
+                if (DEBUG) {
+                    Slog.w(TAG, "Disconnect of abandoned or unexpected service " + name);
+                }
+            }
+        }
+    };
+
+    // Schedules a timeout / end-of-work based on the task verb
+    void scheduleOpTimeoutTm(ActiveTask task) {
+        final long timeoutMillis = (task.verb == VERB_IDLING) ? IDLE_TIMESLICE : OP_TIMEOUT;
+        if (DEBUG) {
+            Slog.i(TAG, "Scheduling timeout (token " + task.token
+                    + " : verb " + task.verb + ") for " + task + " in " + timeoutMillis);
+        }
+        mPendingOperations.put(task.token, task);
+        mHandler.removeMessages(MSG_TIMEOUT);
+        final Message msg = mHandler.obtainMessage(MSG_TIMEOUT, 0, task.token);
+        mHandler.sendMessageDelayed(msg, timeoutMillis);
+    }
+
+    // -------------------------------------------------------------------------------
     public IdleMaintenanceService(Context context, BatteryService batteryService) {
         mContext = context;
         mBatteryService = batteryService;
@@ -111,9 +574,10 @@
         mAlarmService = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
 
         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOG_TAG);
+        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
 
-        mHandler = new Handler(mContext.getMainLooper());
+        mHandler = new IdleHandler(mContext.getMainLooper());
+        mCallback = new IdleCallback();
 
         Intent intent = new Intent(ACTION_UPDATE_IDLE_MAINTENANCE_STATE);
         intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -159,26 +623,28 @@
         mAlarmService.cancel(mUpdateIdleMaintenanceStatePendingIntent);
     }
 
-    private void updateIdleMaintenanceState(boolean noisy) {
+    private void updateIdleMaintenanceStateTm(boolean noisy) {
         if (mIdleMaintenanceStarted) {
             // Idle maintenance can be interrupted by user activity, or duration
             // time out, or low battery.
-            if (!lastUserActivityPermitsIdleMaintenanceRunning()
-                    || !batteryLevelAndMaintenanceTimeoutPermitsIdleMaintenanceRunning()) {
+            final boolean batteryOk
+                    = batteryLevelAndMaintenanceTimeoutPermitsIdleMaintenanceRunning();
+            if (!lastUserActivityPermitsIdleMaintenanceRunning() || !batteryOk) {
                 unscheduleUpdateIdleMaintenanceState();
                 mIdleMaintenanceStarted = false;
-                EventLogTags.writeIdleMaintenanceWindowFinish(SystemClock.elapsedRealtime(),
-                        mLastUserActivityElapsedTimeMillis, mBatteryService.getBatteryLevel(),
-                        isBatteryCharging() ? 1 : 0);
-                sendIdleMaintenanceEndIntent();
                 // We stopped since we don't have enough battery or timed out but the
                 // user is not using the device, so we should be able to run maintenance
                 // in the next maintenance window since the battery may be charged
                 // without interaction and the min interval between maintenances passed.
-                if (!batteryLevelAndMaintenanceTimeoutPermitsIdleMaintenanceRunning()) {
+                if (!batteryOk) {
                     scheduleUpdateIdleMaintenanceState(
                             getNextIdleMaintenanceIntervalStartFromNow());
                 }
+
+                EventLogTags.writeIdleMaintenanceWindowFinish(SystemClock.elapsedRealtime(),
+                        mLastUserActivityElapsedTimeMillis, mBatteryService.getBatteryLevel(),
+                        isBatteryCharging() ? 1 : 0);
+                scheduleIdleFinishTm();
             }
         } else if (deviceStatePermitsIdleMaintenanceStart(noisy)
                 && lastUserActivityPermitsIdleMaintenanceStart(noisy)
@@ -191,7 +657,7 @@
                     mLastUserActivityElapsedTimeMillis, mBatteryService.getBatteryLevel(),
                     isBatteryCharging() ? 1 : 0);
             mLastIdleMaintenanceStartTimeMillis = SystemClock.elapsedRealtime();
-            sendIdleMaintenanceStartIntent();
+            startIdleMaintenanceTm();
         } else if (lastUserActivityPermitsIdleMaintenanceStart(noisy)) {
              if (lastRunPermitsIdleMaintenanceStart(noisy)) {
                 // The user does not use the device and we did not run maintenance in more
@@ -207,27 +673,57 @@
         }
     }
 
+    void startIdleMaintenanceTm() {
+        if (DEBUG) {
+            Slog.i(TAG, "*** Starting idle maintenance ***");
+        }
+        if (DEBUG) { Slog.i(TAG, "Attributing wakelock to system work source"); }
+        mWakeLock.setWorkSource(mSystemWorkSource);
+        mWakeLock.acquire();
+        updateIdleServiceQueueTm();
+        mCurrentIdler = null;
+        mLastIdler = (mIdleServiceQueue.size() > 0) ? mIdleServiceQueue.peekLast() : null;
+        startNextIdleServiceTm();
+    }
+
+    // Start a graceful wind-down of the idle maintenance state: end the current idler
+    // and pretend that we've finished running the queue.  If there's no current idler,
+    // this is a no-op.
+    void scheduleIdleFinishTm() {
+        if (mCurrentIdler != null) {
+            if (DEBUG) {
+                Slog.i(TAG, "*** Finishing idle maintenance ***");
+            }
+            mLastIdler = mCurrentIdler;
+            sendEndIdleTm(mCurrentIdler);
+        } else {
+            if (DEBUG) {
+                Slog.w(TAG, "Asked to finish idle maintenance but we're done already");
+            }
+        }
+    }
+
+    // Actual finalization of the idle maintenance sequence
+    void stopIdleMaintenanceTm() {
+        if (mLastIdler != null) {
+            if (DEBUG) {
+                Slog.i(TAG, "*** Idle maintenance shutdown ***");
+            }
+            mWakeLock.setWorkSource(mSystemWorkSource);
+            mLastIdler = mCurrentIdler = null;
+            updateIdleMaintenanceStateTm(false);   // resets 'started' and schedules next window
+            mWakeLock.release();
+        } else {
+            Slog.e(TAG, "ERROR: idle shutdown but invariants not held.  last=" + mLastIdler
+                    + " cur=" + mCurrentIdler + " size=" + mIdleServiceQueue.size());
+        }
+    }
+
     private long getNextIdleMaintenanceIntervalStartFromNow() {
         return mLastIdleMaintenanceStartTimeMillis + MIN_IDLE_MAINTENANCE_INTERVAL_MILLIS
                 - SystemClock.elapsedRealtime();
     }
 
-    private void sendIdleMaintenanceStartIntent() {
-        mWakeLock.acquire();
-        try {
-            ActivityManagerNative.getDefault().performIdleMaintenance();
-        } catch (RemoteException e) {
-        }
-        mContext.sendOrderedBroadcastAsUser(sIdleMaintenanceStartIntent, UserHandle.ALL,
-                null, this, mHandler, Activity.RESULT_OK, null, null);
-    }
-
-    private void sendIdleMaintenanceEndIntent() {
-        mWakeLock.acquire();
-        mContext.sendOrderedBroadcastAsUser(sIdleMaintenanceEndIntent, UserHandle.ALL,
-                null, this, mHandler, Activity.RESULT_OK, null, null);
-    }
-
     private boolean deviceStatePermitsIdleMaintenanceStart(boolean noisy) {
         final int minBatteryLevel = isBatteryCharging()
                 ? MIN_BATTERY_LEVEL_IDLE_MAINTENANCE_START_CHARGING
@@ -281,7 +777,7 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         if (DEBUG) {
-            Log.i(LOG_TAG, intent.getAction());
+            Log.i(TAG, intent.getAction());
         }
         String action = intent.getAction();
         if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
@@ -292,7 +788,7 @@
             // next release. The only client for this for now is internal an holds
             // a wake lock correctly.
             if (mIdleMaintenanceStarted) {
-                updateIdleMaintenanceState(false);
+                updateIdleMaintenanceStateTm(false);
             }
         } else if (Intent.ACTION_SCREEN_ON.equals(action)
                 || Intent.ACTION_DREAMING_STOPPED.equals(action)) {
@@ -302,7 +798,7 @@
             unscheduleUpdateIdleMaintenanceState();
             // If the screen went on/stopped dreaming, we know the user is using the
             // device which means that idle maintenance should be stopped if running.
-            updateIdleMaintenanceState(false);
+            updateIdleMaintenanceStateTm(false);
         } else if (Intent.ACTION_SCREEN_OFF.equals(action)
                 || Intent.ACTION_DREAMING_STARTED.equals(action)) {
             mLastUserActivityElapsedTimeMillis = SystemClock.elapsedRealtime();
@@ -311,17 +807,12 @@
             // this timeout elapses since the device may go to sleep by then.
             scheduleUpdateIdleMaintenanceState(MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START);
         } else if (ACTION_UPDATE_IDLE_MAINTENANCE_STATE.equals(action)) {
-            updateIdleMaintenanceState(false);
+            updateIdleMaintenanceStateTm(false);
         } else if (ACTION_FORCE_IDLE_MAINTENANCE.equals(action)) {
             long now = SystemClock.elapsedRealtime() - 1;
             mLastUserActivityElapsedTimeMillis = now - MIN_USER_INACTIVITY_IDLE_MAINTENANCE_START;
             mLastIdleMaintenanceStartTimeMillis = now - MIN_IDLE_MAINTENANCE_INTERVAL_MILLIS;
-            updateIdleMaintenanceState(true);
-        } else if (Intent.ACTION_IDLE_MAINTENANCE_START.equals(action)
-                || Intent.ACTION_IDLE_MAINTENANCE_END.equals(action)) {
-            // We were holding a wake lock while broadcasting the idle maintenance
-            // intents but now that we finished the broadcast release the wake lock.
-            mWakeLock.release();
+            updateIdleMaintenanceStateTm(true);
         }
     }
 }
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 26424a5..5fb6405 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -16,6 +16,8 @@
 package com.android.server;
 
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController;
+import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
 import com.android.internal.inputmethod.InputMethodUtils;
 import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
 import com.android.internal.os.HandlerCaller;
@@ -57,6 +59,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -76,6 +79,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.style.SuggestionSpan;
@@ -114,12 +118,9 @@
 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.List;
 import java.util.Locale;
-import java.util.TreeMap;
 
 /**
  * This class provides a system service that manages input methods.
@@ -150,7 +151,7 @@
 
     static final int MSG_HARD_KEYBOARD_SWITCH_CHANGED = 4000;
 
-    static final long TIME_TO_RECONNECT = 10*1000;
+    static final long TIME_TO_RECONNECT = 3 * 1000;
 
     static final int SECURE_SUGGESTION_SPANS_MAX_SIZE = 20;
 
@@ -167,7 +168,6 @@
     final HandlerCaller mCaller;
     final boolean mHasFeature;
     private InputMethodFileManager mFileManager;
-    private InputMethodAndSubtypeListManager mImListManager;
     private final HardKeyboardListener mHardKeyboardListener;
     private final WindowManagerService mWindowManagerService;
 
@@ -179,6 +179,7 @@
     final HashMap<String, InputMethodInfo> mMethodMap = new HashMap<String, InputMethodInfo>();
     private final LruCache<SuggestionSpan, InputMethodInfo> mSecureSuggestionSpans =
             new LruCache<SuggestionSpan, InputMethodInfo>(SECURE_SUGGESTION_SPANS_MAX_SIZE);
+    private final InputMethodSubtypeSwitchingController mSwitchingController;
 
     // Used to bring IME service up to visible adjustment while it is being shown.
     final ServiceConnection mVisibleConnection = new ServiceConnection() {
@@ -442,6 +443,10 @@
                 hideInputMethodMenu();
                 // No need to updateActive
                 return;
+            } else if (Intent.ACTION_USER_ADDED.equals(action)
+                    || Intent.ACTION_USER_REMOVED.equals(action)) {
+                updateRelatedUserIds();
+                return;
             } else {
                 Slog.w(TAG, "Unexpected intent " + intent);
             }
@@ -576,7 +581,12 @@
 
         @Override
         public void sessionCreated(IInputMethodSession session) {
-            mParentIMMS.onSessionCreated(mMethod, session, mChannel);
+            long ident = Binder.clearCallingIdentity();
+            try {
+                mParentIMMS.onSessionCreated(mMethod, session, mChannel);
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
         }
     }
 
@@ -632,7 +642,8 @@
         mImeSwitcherNotification.vibrate = null;
 
         // Tag this notification specially so SystemUI knows it's important
-        mImeSwitcherNotification.kind = new String[] { "android.system.imeswitcher" };
+        mImeSwitcherNotification.extras.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, true);
+        mImeSwitcherNotification.category = Notification.CATEGORY_SYSTEM;
 
         Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
         mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
@@ -643,6 +654,8 @@
         broadcastFilter.addAction(Intent.ACTION_SCREEN_ON);
         broadcastFilter.addAction(Intent.ACTION_SCREEN_OFF);
         broadcastFilter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+        broadcastFilter.addAction(Intent.ACTION_USER_ADDED);
+        broadcastFilter.addAction(Intent.ACTION_USER_REMOVED);
         mContext.registerReceiver(new ImmsBroadcastReceiver(), broadcastFilter);
 
         mNotificationShown = false;
@@ -676,8 +689,10 @@
         // mSettings should be created before buildInputMethodListLocked
         mSettings = new InputMethodSettings(
                 mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
+        updateRelatedUserIds();
         mFileManager = new InputMethodFileManager(mMethodMap, userId);
-        mImListManager = new InputMethodAndSubtypeListManager(context, this);
+        mSwitchingController = new InputMethodSubtypeSwitchingController(mSettings);
+        mSwitchingController.resetCircularListLocked(context);
 
         // Just checking if defaultImiId is empty or not
         final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -757,8 +772,8 @@
             if (DEBUG) {
                 Slog.i(TAG, "Locale has been changed to " + newLocale);
             }
-            // InputMethodAndSubtypeListManager should be reset when the locale is changed.
-            mImListManager = new InputMethodAndSubtypeListManager(mContext, this);
+            // CircularList should be reset when the locale is changed.
+            mSwitchingController.resetCircularListLocked(mContext);
             buildInputMethodListLocked(mMethodList, mMethodMap, resetDefaultEnabledIme);
             if (!updateOnlyWhenLocaleChanged) {
                 final String selectedImiId = mSettings.getSelectedInputMethod();
@@ -790,6 +805,7 @@
 
     private void switchUserLocked(int newUserId) {
         mSettings.setCurrentUserId(newUserId);
+        updateRelatedUserIds();
         // InputMethodFileManager should be reset when the user is changed
         mFileManager = new InputMethodFileManager(mMethodMap, newUserId);
         final String defaultImiId = mSettings.getSelectedInputMethod();
@@ -810,6 +826,16 @@
         }
     }
 
+    void updateRelatedUserIds() {
+        List<UserInfo> relatedUsers =
+                UserManager.get(mContext).getRelatedUsers(mSettings.getCurrentUserId());
+        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
+        for (int i = 0; i < relatedUserIds.length; i++) {
+            relatedUserIds[i] = relatedUsers.get(i).id;
+        }
+        mSettings.setRelatedUserIds(relatedUserIds);
+    }
+
     @Override
     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
             throws RemoteException {
@@ -905,7 +931,7 @@
                     + mSettings.getCurrentUserId() + ", calling pid = " + Binder.getCallingPid()
                     + InputMethodUtils.getApiCallStack());
         }
-        if (uid == Process.SYSTEM_UID || userId == mSettings.getCurrentUserId()) {
+        if (uid == Process.SYSTEM_UID || mSettings.isRelatedToOrCurrentUser(userId)) {
             return true;
         }
 
@@ -960,17 +986,6 @@
         }
     }
 
-    private HashMap<InputMethodInfo, List<InputMethodSubtype>>
-            getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked() {
-        HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledInputMethodAndSubtypes =
-                new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
-        for (InputMethodInfo imi: mSettings.getEnabledInputMethodListLocked()) {
-            enabledInputMethodAndSubtypes.put(
-                    imi, mSettings.getEnabledInputMethodSubtypeListLocked(mContext, imi, true));
-        }
-        return enabledInputMethodAndSubtypes;
-    }
-
     /**
      * @param imiId if null, returns enabled subtypes for the current imi
      * @return enabled subtypes of the specified imi
@@ -1216,7 +1231,8 @@
         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_SHOWING_UI)) {
+                | Context.BIND_NOT_VISIBLE | Context.BIND_NOT_FOREGROUND
+                | Context.BIND_SHOWING_UI)) {
             mLastBindTime = SystemClock.uptimeMillis();
             mHaveConnection = true;
             mCurId = info.getId();
@@ -1774,7 +1790,8 @@
             mInputShown = true;
             if (mHaveConnection && !mVisibleBound) {
                 bindCurrentInputMethodService(
-                        mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE);
+                        mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE
+                                | Context.BIND_TREAT_LIKE_ACTIVITY);
                 mVisibleBound = true;
             }
             res = true;
@@ -2153,7 +2170,7 @@
             return false;
         }
         synchronized (mMethodMap) {
-            final ImeSubtypeListItem nextSubtype = mImListManager.getNextInputMethod(
+            final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethod(
                     onlyCurrentIme, mMethodMap.get(mCurMethodId), mCurrentSubtype);
             if (nextSubtype == null) {
                 return false;
@@ -2169,7 +2186,7 @@
             return false;
         }
         synchronized (mMethodMap) {
-            final ImeSubtypeListItem nextSubtype = mImListManager.getNextInputMethod(
+            final ImeSubtypeListItem nextSubtype = mSwitchingController.getNextInputMethod(
                     false /* onlyCurrentIme */, mMethodMap.get(mCurMethodId), mCurrentSubtype);
             if (nextSubtype == null) {
                 return false;
@@ -2242,6 +2259,22 @@
         return;
     }
 
+    @Override
+    public int getInputMethodWindowVisibleHeight() {
+        return mWindowManagerService.getInputMethodWindowVisibleHeight();
+    }
+
+    @Override
+    public void notifyTextCommitted() {
+        if (DEBUG) {
+            Slog.d(TAG, "Got the notification of commitText");
+        }
+        final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+        if (imi != null) {
+            mSwitchingController.onCommitText(imi, mCurrentSubtype);
+        }
+    }
+
     private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) {
         synchronized (mMethodMap) {
             if (token == null) {
@@ -2620,7 +2653,8 @@
 
         synchronized (mMethodMap) {
             final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
-                    getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked();
+                    mSettings.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(
+                            mContext);
             if (immis == null || immis.size() == 0) {
                 return;
             }
@@ -2628,7 +2662,7 @@
             hideInputMethodMenuLocked();
 
             final List<ImeSubtypeListItem> imList =
-                    mImListManager.getSortedInputMethodAndSubtypeList(
+                    mSwitchingController.getSortedInputMethodAndSubtypeList(
                             showSubtypes, mInputShown, isScreenLocked);
 
             if (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
@@ -2747,66 +2781,6 @@
         }
     }
 
-    private static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
-        public final CharSequence mImeName;
-        public final CharSequence mSubtypeName;
-        public final InputMethodInfo mImi;
-        public final int mSubtypeId;
-        private final boolean mIsSystemLocale;
-        private final boolean mIsSystemLanguage;
-
-        public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
-                InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
-            mImeName = imeName;
-            mSubtypeName = subtypeName;
-            mImi = imi;
-            mSubtypeId = subtypeId;
-            if (TextUtils.isEmpty(subtypeLocale)) {
-                mIsSystemLocale = false;
-                mIsSystemLanguage = false;
-            } else {
-                mIsSystemLocale = subtypeLocale.equals(systemLocale);
-                mIsSystemLanguage = mIsSystemLocale
-                        || subtypeLocale.startsWith(systemLocale.substring(0, 2));
-            }
-        }
-
-        @Override
-        public int compareTo(ImeSubtypeListItem other) {
-            if (TextUtils.isEmpty(mImeName)) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(other.mImeName)) {
-                return -1;
-            }
-            if (!TextUtils.equals(mImeName, other.mImeName)) {
-                return mImeName.toString().compareTo(other.mImeName.toString());
-            }
-            if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) {
-                return 0;
-            }
-            if (mIsSystemLocale) {
-                return -1;
-            }
-            if (other.mIsSystemLocale) {
-                return 1;
-            }
-            if (mIsSystemLanguage) {
-                return -1;
-            }
-            if (other.mIsSystemLanguage) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(mSubtypeName)) {
-                return 1;
-            }
-            if (TextUtils.isEmpty(other.mSubtypeName)) {
-                return -1;
-            }
-            return mSubtypeName.toString().compareTo(other.mSubtypeName.toString());
-        }
-    }
-
     private static class ImeSubtypeListAdapter extends ArrayAdapter<ImeSubtypeListItem> {
         private final LayoutInflater mInflater;
         private final int mTextViewResourceId;
@@ -3178,123 +3152,6 @@
         }
     }
 
-    private static class InputMethodAndSubtypeListManager {
-        private final Context mContext;
-        // Used to load label
-        private final PackageManager mPm;
-        private final InputMethodManagerService mImms;
-        private final String mSystemLocaleStr;
-        public InputMethodAndSubtypeListManager(Context context, InputMethodManagerService imms) {
-            mContext = context;
-            mPm = context.getPackageManager();
-            mImms = imms;
-            final Locale locale = context.getResources().getConfiguration().locale;
-            mSystemLocaleStr = locale != null ? locale.toString() : "";
-        }
-
-        private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
-                new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
-                        new Comparator<InputMethodInfo>() {
-                            @Override
-                            public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
-                                if (imi2 == null) return 0;
-                                if (imi1 == null) return 1;
-                                if (mPm == null) {
-                                    return imi1.getId().compareTo(imi2.getId());
-                                }
-                                CharSequence imiId1 = imi1.loadLabel(mPm) + "/" + imi1.getId();
-                                CharSequence imiId2 = imi2.loadLabel(mPm) + "/" + imi2.getId();
-                                return imiId1.toString().compareTo(imiId2.toString());
-                            }
-                        });
-
-        public ImeSubtypeListItem getNextInputMethod(
-                boolean onlyCurrentIme, InputMethodInfo imi, InputMethodSubtype subtype) {
-            if (imi == null) {
-                return null;
-            }
-            final List<ImeSubtypeListItem> imList = getSortedInputMethodAndSubtypeList();
-            if (imList.size() <= 1) {
-                return null;
-            }
-            final int N = imList.size();
-            final int currentSubtypeId = subtype != null
-                    ? InputMethodUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode())
-                    : NOT_A_SUBTYPE_ID;
-            for (int i = 0; i < N; ++i) {
-                final ImeSubtypeListItem isli = imList.get(i);
-                if (isli.mImi.equals(imi) && isli.mSubtypeId == currentSubtypeId) {
-                    if (!onlyCurrentIme) {
-                        return imList.get((i + 1) % N);
-                    }
-                    for (int j = 0; j < N - 1; ++j) {
-                        final ImeSubtypeListItem candidate = imList.get((i + j + 1) % N);
-                        if (candidate.mImi.equals(imi)) {
-                            return candidate;
-                        }
-                    }
-                    return null;
-                }
-            }
-            return null;
-        }
-
-        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList() {
-            return getSortedInputMethodAndSubtypeList(true, false, false);
-        }
-
-        public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(boolean showSubtypes,
-                boolean inputShown, boolean isScreenLocked) {
-            final ArrayList<ImeSubtypeListItem> imList = new ArrayList<ImeSubtypeListItem>();
-            final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
-                    mImms.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked();
-            if (immis == null || immis.size() == 0) {
-                return Collections.emptyList();
-            }
-            mSortedImmis.clear();
-            mSortedImmis.putAll(immis);
-            for (InputMethodInfo imi : mSortedImmis.keySet()) {
-                if (imi == null) continue;
-                List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
-                HashSet<String> enabledSubtypeSet = new HashSet<String>();
-                for (InputMethodSubtype subtype: explicitlyOrImplicitlyEnabledSubtypeList) {
-                    enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
-                }
-                final CharSequence imeLabel = imi.loadLabel(mPm);
-                if (showSubtypes && enabledSubtypeSet.size() > 0) {
-                    final int subtypeCount = imi.getSubtypeCount();
-                    if (DEBUG) {
-                        Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
-                    }
-                    for (int j = 0; j < subtypeCount; ++j) {
-                        final InputMethodSubtype subtype = imi.getSubtypeAt(j);
-                        final String subtypeHashCode = String.valueOf(subtype.hashCode());
-                        // We show all enabled IMEs and subtypes when an IME is shown.
-                        if (enabledSubtypeSet.contains(subtypeHashCode)
-                                && ((inputShown && !isScreenLocked) || !subtype.isAuxiliary())) {
-                            final CharSequence subtypeLabel =
-                                    subtype.overridesImplicitlyEnabledSubtype() ? null
-                                            : subtype.getDisplayName(mContext, imi.getPackageName(),
-                                                    imi.getServiceInfo().applicationInfo);
-                            imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j,
-                                    subtype.getLocale(), mSystemLocaleStr));
-
-                            // Removing this subtype from enabledSubtypeSet because we no longer
-                            // need to add an entry of this subtype to imList to avoid duplicated
-                            // entries.
-                            enabledSubtypeSet.remove(subtypeHashCode);
-                        }
-                    }
-                } else {
-                    imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID,
-                            null, mSystemLocaleStr));
-                }
-            }
-            Collections.sort(imList);
-            return imList;
-        }
-    }
-
     // TODO: Cache the state for each user and reset when the cached user is removed.
     private static class InputMethodFileManager {
         private static final String SYSTEM_PATH = "system";
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index e0b568b..e6163bd 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -73,6 +73,9 @@
 import com.android.server.location.LocationFudger;
 import com.android.server.location.LocationProviderInterface;
 import com.android.server.location.LocationProviderProxy;
+import com.android.server.location.LocationRequestStatistics;
+import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
+import com.android.server.location.LocationRequestStatistics.PackageStatistics;
 import com.android.server.location.MockProvider;
 import com.android.server.location.PassiveProvider;
 
@@ -178,6 +181,8 @@
     private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider =
             new HashMap<String, ArrayList<UpdateRecord>>();
 
+    private final LocationRequestStatistics mRequestStatistics = new LocationRequestStatistics();
+
     // mapping from provider name to last known location
     private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>();
 
@@ -571,7 +576,7 @@
                     if (isAllowedByCurrentUserSettingsLocked(updateRecord.mProvider)) {
                         requestingLocation = true;
                         LocationProviderInterface locationProvider
-                            = mProvidersByName.get(updateRecord.mProvider);
+                                = mProvidersByName.get(updateRecord.mProvider);
                         ProviderProperties properties = locationProvider != null
                                 ? locationProvider.getProperties() : null;
                         if (properties != null
@@ -816,7 +821,7 @@
                     long identity = Binder.clearCallingIdentity();
                     receiver.decrementPendingBroadcastsLocked();
                     Binder.restoreCallingIdentity(identity);
-               }
+                }
             }
         }
     }
@@ -1291,13 +1296,18 @@
             if (!records.contains(this)) {
                 records.add(this);
             }
+
+            // Update statistics for historical location requests by package/provider
+            mRequestStatistics.startRequesting(
+                    mReceiver.mPackageName, provider, request.getInterval());
         }
 
         /**
-         * Method to be called when a record will no longer be used.  Calling this multiple times
-         * must have the same effect as calling it once.
+         * Method to be called when a record will no longer be used.
          */
         void disposeLocked(boolean removeReceiver) {
+            mRequestStatistics.stopRequesting(mReceiver.mPackageName, mProvider);
+
             // remove from mRecordsByProvider
             ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider);
             if (globalRecords != null) {
@@ -1544,6 +1554,7 @@
         if (oldRecords != null) {
             // Call dispose() on the obsolete update records.
             for (UpdateRecord record : oldRecords.values()) {
+                // Update statistics for historical location requests by package/provider
                 record.disposeLocked(false);
             }
             // Accumulate providers
@@ -1765,7 +1776,7 @@
     @Override
     public ProviderProperties getProviderProperties(String provider) {
         if (mProvidersByName.get(provider) == null) {
-          return null;
+            return null;
         }
 
         checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
@@ -1782,10 +1793,6 @@
 
     @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;
@@ -1968,7 +1975,7 @@
         // Fetch latest status update time
         long newStatusUpdateTime = p.getStatusUpdateTime();
 
-       // Get latest status
+        // Get latest status
         Bundle extras = new Bundle();
         int status = p.getStatus(extras);
 
@@ -2182,7 +2189,7 @@
         }
 
         if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) !=
-            PackageManager.PERMISSION_GRANTED) {
+                PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission");
         }
     }
@@ -2223,6 +2230,13 @@
     public void removeTestProvider(String provider) {
         checkMockPermissionsSafe();
         synchronized (mLock) {
+
+            // These methods can't be called after removing the test provider, so first make sure
+            // we don't leave anything dangling.
+            clearTestProviderEnabled(provider);
+            clearTestProviderLocation(provider);
+            clearTestProviderStatus(provider);
+
             MockProvider mockProvider = mMockProviders.remove(provider);
             if (mockProvider == null) {
                 throw new IllegalArgumentException("Provider \"" + provider + "\" unknown");
@@ -2354,13 +2368,20 @@
             for (Receiver receiver : mReceivers.values()) {
                 pw.println("    " + receiver);
             }
-            pw.println("  Records by Provider:");
+            pw.println("  Active Records by Provider:");
             for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
                 pw.println("    " + entry.getKey() + ":");
                 for (UpdateRecord record : entry.getValue()) {
                     pw.println("      " + record);
                 }
             }
+            pw.println("  Historical Records by Provider:");
+            for (Map.Entry<PackageProviderKey, PackageStatistics> entry
+                    : mRequestStatistics.statistics.entrySet()) {
+                PackageProviderKey key = entry.getKey();
+                PackageStatistics stats = entry.getValue();
+                pw.println("    " + key.packageName + ": " + key.providerName + ": " + stats);
+            }
             pw.println("  Last Known Locations:");
             for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
                 String provider = entry.getKey();
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 35e7afa..19e8083 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -16,7 +16,6 @@
 
 package com.android.server;
 
-import android.app.ActivityManagerNative;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -29,11 +28,13 @@
 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.IBinder;
 import android.os.RemoteException;
+import android.os.storage.IMountService;
+import android.os.ServiceManager;
+import android.os.storage.StorageManager;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -82,6 +83,7 @@
 
     private final Context mContext;
     private LockPatternUtils mLockPatternUtils;
+    private boolean mFirstCallToVold;
 
     public LockSettingsService(Context context) {
         mContext = context;
@@ -89,6 +91,7 @@
         mOpenHelper = new DatabaseHelper(mContext);
 
         mLockPatternUtils = new LockPatternUtils(context);
+        mFirstCallToVold = true;
     }
 
     public void systemReady() {
@@ -350,6 +353,33 @@
     }
 
     @Override
+    public boolean checkVoldPassword(int userId) throws RemoteException {
+        if (!mFirstCallToVold) {
+            return false;
+        }
+        mFirstCallToVold = false;
+
+        checkPasswordReadPermission(userId);
+
+        // There's no guarantee that this will safely connect, but if it fails
+        // we will simply show the lock screen when we shouldn't, so relatively
+        // benign. There is an outside chance something nasty would happen if
+        // this service restarted before vold stales out the password in this
+        // case. The nastiness is limited to not showing the lock screen when
+        // we should, within the first minute of decrypting the phone if this
+        // service can't connect to vold, it restarts, and then the new instance
+        // does successfully connect.
+        final IMountService service = getMountService();
+        String password = service.getPassword();
+        service.clearPassword();
+        if (service.getPasswordType() == StorageManager.CRYPT_TYPE_PATTERN) {
+            return checkPattern(password, userId);
+        } else {
+            return checkPassword(password, userId);
+        }
+    }
+
+    @Override
     public void removeUser(int userId) {
         checkWritePermission(userId);
 
@@ -527,4 +557,12 @@
         Secure.LOCK_SCREEN_OWNER_INFO_ENABLED,
         Secure.LOCK_SCREEN_OWNER_INFO
     };
+
+    private IMountService getMountService() {
+        final IBinder service = ServiceManager.getService("mount");
+        if (service != null) {
+            return IMountService.Stub.asInterface(service);
+        }
+        return null;
+    }
 }
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index f73a92b..b6e0d5f 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -73,6 +73,8 @@
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.DecoderException;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.File;
@@ -80,6 +82,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.math.BigInteger;
+import java.nio.charset.StandardCharsets;
 import java.security.NoSuchAlgorithmException;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.KeySpec;
@@ -108,6 +111,9 @@
 class MountService extends IMountService.Stub
         implements INativeDaemonConnectorCallbacks, Watchdog.Monitor {
 
+    // Static direct instance pointer for the tightly-coupled idle service to use
+    static MountService sSelf = null;
+
     // TODO: listen for user creation/deletion
 
     private static final boolean LOCAL_LOGD = false;
@@ -187,6 +193,12 @@
         public static final int FstrimCompleted                = 700;
     }
 
+    /** List of crypto types.
+      * These must match CRYPT_TYPE_XXX in cryptfs.h AND their
+      * corresponding commands in CommandListener.cpp */
+    public static final String[] CRYPTO_TYPES
+        = { "password", "default", "pattern", "pin" };
+
     private Context mContext;
     private NativeDaemonConnector mConnector;
 
@@ -346,6 +358,7 @@
     private static final int H_UNMOUNT_PM_DONE = 2;
     private static final int H_UNMOUNT_MS = 3;
     private static final int H_SYSTEM_READY = 4;
+    private static final int H_FSTRIM = 5;
 
     private static final int RETRY_UNMOUNT_DELAY = 30; // in ms
     private static final int MAX_UNMOUNT_RETRIES = 4;
@@ -514,6 +527,24 @@
                     }
                     break;
                 }
+                case H_FSTRIM: {
+                    waitForReady();
+                    Slog.i(TAG, "Running fstrim idle maintenance");
+                    try {
+                        // This method must be run on the main (handler) thread,
+                        // so it is safe to directly call into vold.
+                        mConnector.execute("fstrim", "dotrim");
+                        EventLogTags.writeFstrimStart(SystemClock.elapsedRealtime());
+                    } catch (NativeDaemonConnectorException ndce) {
+                        Slog.e(TAG, "Failed to run fstrim!");
+                    }
+                    // invoke the completion callback, if any
+                    Runnable callback = (Runnable) msg.obj;
+                    if (callback != null) {
+                        callback.run();
+                    }
+                    break;
+                }
             }
         }
     };
@@ -543,6 +574,14 @@
         }
     }
 
+    private boolean isReady() {
+        try {
+            return mConnectedSignal.await(0, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            return false;
+        }
+    }
+
     private void handleSystemReady() {
         // Snapshot current volume states since it's not safe to call into vold
         // while holding locks.
@@ -628,27 +667,6 @@
         }
     };
 
-    private final BroadcastReceiver mIdleMaintenanceReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            waitForReady();
-            String action = intent.getAction();
-            // Since fstrim will be run on a daily basis we do not expect
-            // fstrim to be too long, so it is not interruptible. We will
-            // implement interruption only in case we see issues.
-            if (Intent.ACTION_IDLE_MAINTENANCE_START.equals(action)) {
-                try {
-                    // This method runs on the handler thread,
-                    // so it is safe to directly call into vold.
-                    mConnector.execute("fstrim", "dotrim");
-                    EventLogTags.writeFstrimStart(SystemClock.elapsedRealtime());
-                } catch (NativeDaemonConnectorException ndce) {
-                    Slog.e(TAG, "Failed to run fstrim!");
-                }
-            }
-        }
-    };
-
     private final class MountServiceBinderListener implements IBinder.DeathRecipient {
         final IMountServiceListener mListener;
 
@@ -666,6 +684,10 @@
         }
     }
 
+    void runIdleMaintenance(Runnable callback) {
+        mHandler.sendMessage(mHandler.obtainMessage(H_FSTRIM, callback));
+    }
+
     private void doShareUnshareVolume(String path, String method, boolean enable) {
         // TODO: Add support for multiple share methods
         if (!method.equals("ums")) {
@@ -803,6 +825,13 @@
     /**
      * Callback from NativeDaemonConnector
      */
+    public boolean onCheckHoldWakeLock(int code) {
+        return false;
+    }
+
+    /**
+     * Callback from NativeDaemonConnector
+     */
     public boolean onEvent(int code, String raw, String[] cooked) {
         if (DEBUG_EVENTS) {
             StringBuilder builder = new StringBuilder();
@@ -1357,6 +1386,8 @@
      * @param context  Binder context for this service
      */
     public MountService(Context context) {
+        sSelf = this;
+
         mContext = context;
 
         synchronized (mVolumesLock) {
@@ -1383,12 +1414,6 @@
                     mUsbReceiver, new IntentFilter(UsbManager.ACTION_USB_STATE), null, mHandler);
         }
 
-        // Watch for idle maintenance changes
-        IntentFilter idleMaintenanceFilter = new IntentFilter();
-        idleMaintenanceFilter.addAction(Intent.ACTION_IDLE_MAINTENANCE_START);
-        mContext.registerReceiverAsUser(mIdleMaintenanceReceiver, UserHandle.ALL,
-                idleMaintenanceFilter, null, mHandler);
-
         // Add OBB Action Handler to MountService thread.
         mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());
 
@@ -1397,7 +1422,8 @@
          * amount of containers we'd ever expect to have. This keeps an
          * "asec list" from blocking a thread repeatedly.
          */
-        mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25);
+        mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25,
+                null);
 
         Thread thread = new Thread(mConnector, VOLD_TAG);
         thread.start();
@@ -2056,6 +2082,27 @@
         }
     }
 
+    private String toHex(String password) {
+        if (password == null) {
+            return null;
+        }
+        byte[] bytes = password.getBytes(StandardCharsets.UTF_8);
+        return new String(Hex.encodeHex(bytes));
+    }
+
+    private String fromHex(String hexPassword) {
+        if (hexPassword == null) {
+            return null;
+        }
+
+        try {
+            byte[] bytes = Hex.decodeHex(hexPassword.toCharArray());
+            return new String(bytes, StandardCharsets.UTF_8);
+        } catch (DecoderException e) {
+            return null;
+        }
+    }
+
     @Override
     public int decryptStorage(String password) {
         if (TextUtils.isEmpty(password)) {
@@ -2073,7 +2120,7 @@
 
         final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(password));
+            event = mConnector.execute("cryptfs", "checkpw", new SensitiveArg(toHex(password)));
 
             final int code = Integer.parseInt(event.getMessage());
             if (code == 0) {
@@ -2112,7 +2159,8 @@
         }
 
         try {
-            mConnector.execute("cryptfs", "enablecrypto", "inplace", new SensitiveArg(password));
+            mConnector.execute("cryptfs", "enablecrypto", "inplace",
+                               new SensitiveArg(toHex(password)));
         } catch (NativeDaemonConnectorException e) {
             // Encryption failed
             return e.getCode();
@@ -2121,11 +2169,11 @@
         return 0;
     }
 
-    public int changeEncryptionPassword(String password) {
-        if (TextUtils.isEmpty(password)) {
-            throw new IllegalArgumentException("password cannot be empty");
-        }
-
+    /** Set the password for encrypting the master key.
+     *  @param type One of the CRYPTO_TYPE_XXX consts defined in StorageManager.
+     *  @param password The password to set.
+     */
+    public int changeEncryptionPassword(int type, String password) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
             "no permission to access the crypt keeper");
 
@@ -2137,7 +2185,8 @@
 
         final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("cryptfs", "changepw", new SensitiveArg(password));
+            event = mConnector.execute("cryptfs", "changepw", CRYPTO_TYPES[type],
+                                       new SensitiveArg(toHex(password)));
             return Integer.parseInt(event.getMessage());
         } catch (NativeDaemonConnectorException e) {
             // Encryption failed
@@ -2170,7 +2219,7 @@
 
         final NativeDaemonEvent event;
         try {
-            event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(password));
+            event = mConnector.execute("cryptfs", "verifypw", new SensitiveArg(toHex(password)));
             Slog.i(TAG, "cryptfs verifypw => " + event.getMessage());
             return Integer.parseInt(event.getMessage());
         } catch (NativeDaemonConnectorException e) {
@@ -2179,6 +2228,58 @@
         }
     }
 
+    /**
+     * Get the type of encryption used to encrypt the master key.
+     * @return The type, one of the CRYPT_TYPE_XXX consts from StorageManager.
+     */
+    @Override
+    public int getPasswordType() throws RemoteException {
+
+        waitForReady();
+
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("cryptfs", "getpwtype");
+            for (int i = 0; i < CRYPTO_TYPES.length; ++i) {
+                if (CRYPTO_TYPES[i].equals(event.getMessage()))
+                    return i;
+            }
+
+            throw new IllegalStateException("unexpected return from cryptfs");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public String getPassword() throws RemoteException {
+        if (!isReady()) {
+            return new String();
+        }
+
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("cryptfs", "getpw");
+            return fromHex(event.getMessage());
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
+    @Override
+    public void clearPassword() throws RemoteException {
+        if (!isReady()) {
+            return;
+        }
+
+        final NativeDaemonEvent event;
+        try {
+            event = mConnector.execute("cryptfs", "clearpw");
+        } catch (NativeDaemonConnectorException e) {
+            throw e.rethrowAsParcelableException();
+        }
+    }
+
     @Override
     public int mkdirs(String callingPkg, String appPath) {
         final int userId = UserHandle.getUserId(Binder.getCallingUid());
diff --git a/services/core/java/com/android/server/MountServiceIdler.java b/services/core/java/com/android/server/MountServiceIdler.java
new file mode 100644
index 0000000..8b19321
--- /dev/null
+++ b/services/core/java/com/android/server/MountServiceIdler.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.maintenance.IdleService;
+import android.util.Slog;
+
+public class MountServiceIdler extends IdleService {
+    private static final String TAG = "MountServiceIdler";
+
+    private Runnable mFinishCallback = new Runnable() {
+        @Override
+        public void run() {
+            Slog.i(TAG, "Got mount service completion callback");
+            finishIdle();
+        }
+    };
+
+    @Override
+    public boolean onIdleStart() {
+        // The mount service will run an fstrim operation asynchronously
+        // on a designated separate thread, so we provide it with a callback
+        // that lets us cleanly end our idle timeslice.  It's safe to call
+        // finishIdle() from any thread.
+        MountService ms = MountService.sSelf;
+        if (ms != null) {
+            ms.runIdleMaintenance(mFinishCallback);
+        }
+        return ms != null;
+    }
+
+    @Override
+    public void onIdleStop() {
+    }
+}
diff --git a/services/core/java/com/android/server/NativeDaemonConnector.java b/services/core/java/com/android/server/NativeDaemonConnector.java
index 417d6d8..62eb663 100644
--- a/services/core/java/com/android/server/NativeDaemonConnector.java
+++ b/services/core/java/com/android/server/NativeDaemonConnector.java
@@ -21,6 +21,7 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.LocalLog;
 import android.util.Slog;
@@ -56,6 +57,8 @@
 
     private final ResponseQueue mResponseQueue;
 
+    private final PowerManager.WakeLock mWakeLock;
+
     private INativeDaemonConnectorCallbacks mCallbacks;
     private Handler mCallbackHandler;
 
@@ -70,10 +73,14 @@
     private final int BUFFER_SIZE = 4096;
 
     NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
-            int responseQueueSize, String logTag, int maxLogSize) {
+            int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl) {
         mCallbacks = callbacks;
         mSocket = socket;
         mResponseQueue = new ResponseQueue(responseQueueSize);
+        mWakeLock = wl;
+        if (mWakeLock != null) {
+            mWakeLock.setReferenceCounted(true);
+        }
         mSequenceNumber = new AtomicInteger(0);
         TAG = logTag != null ? logTag : "NativeDaemonConnector";
         mLocalLog = new LocalLog(maxLogSize);
@@ -102,6 +109,10 @@
             }
         } catch (Exception e) {
             loge("Error handling '" + event + "': " + e);
+        } finally {
+            if (mCallbacks.onCheckHoldWakeLock(msg.what) && mWakeLock != null) {
+                mWakeLock.release();
+            }
         }
         return true;
     }
@@ -154,18 +165,30 @@
                                 buffer, start, i - start, StandardCharsets.UTF_8);
                         log("RCV <- {" + rawEvent + "}");
 
+                        boolean releaseWl = false;
                         try {
                             final NativeDaemonEvent event = NativeDaemonEvent.parseRawEvent(
                                     rawEvent);
                             if (event.isClassUnsolicited()) {
                                 // TODO: migrate to sending NativeDaemonEvent instances
-                                mCallbackHandler.sendMessage(mCallbackHandler.obtainMessage(
-                                        event.getCode(), event.getRawEvent()));
+                                if (mCallbacks.onCheckHoldWakeLock(event.getCode())
+                                        && mWakeLock != null) {
+                                    mWakeLock.acquire();
+                                    releaseWl = true;
+                                }
+                                if (mCallbackHandler.sendMessage(mCallbackHandler.obtainMessage(
+                                        event.getCode(), event.getRawEvent()))) {
+                                    releaseWl = false;
+                                }
                             } else {
                                 mResponseQueue.add(event.getCmdNumber(), event);
                             }
                         } catch (IllegalArgumentException e) {
                             log("Problem parsing message: " + rawEvent + " - " + e);
+                        } finally {
+                            if (releaseWl) {
+                                mWakeLock.acquire();
+                            }
                         }
 
                         start = i + 1;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index e83d376..9629bd1 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.DUMP;
 import static android.Manifest.permission.SHUTDOWN;
 import static android.net.NetworkStats.SET_DEFAULT;
+import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.TrafficStats.UID_TETHERING;
@@ -36,6 +37,7 @@
 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
 
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetworkManagementEventObserver;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
@@ -47,7 +49,9 @@
 import android.os.BatteryStats;
 import android.os.Binder;
 import android.os.Handler;
+import android.os.INetworkActivityListener;
 import android.os.INetworkManagementService;
+import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -80,7 +84,6 @@
 import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -152,6 +155,8 @@
 
     private final Handler mMainHandler = new Handler();
 
+    private IBatteryStats mBatteryStats;
+
     private Thread mThread;
     private CountDownLatch mConnectedSignal = new CountDownLatch(1);
 
@@ -172,12 +177,12 @@
     /** Set of interfaces with active idle timers. */
     private static class IdleTimerParams {
         public final int timeout;
-        public final String label;
+        public final int type;
         public int networkCount;
 
-        IdleTimerParams(int timeout, String label) {
+        IdleTimerParams(int timeout, int type) {
             this.timeout = timeout;
-            this.label = label;
+            this.type = type;
             this.networkCount = 1;
         }
     }
@@ -186,6 +191,10 @@
     private volatile boolean mBandwidthControlEnabled;
     private volatile boolean mFirewallEnabled;
 
+    private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
+            new RemoteCallbackList<INetworkActivityListener>();
+    private boolean mNetworkActive;
+
     /**
      * Constructs a new NetworkManagementService instance
      *
@@ -198,8 +207,15 @@
             return;
         }
 
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        // Don't need this wake lock, since we now have a time stamp for when
+        // the network actually went inactive.  (It might be nice to still do this,
+        // but I don't want to do it through the power manager because that pollutes the
+        // battery stats history with pointless noise.)
+        PowerManager.WakeLock wl = null; //pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NETD_TAG);
+
         mConnector = new NativeDaemonConnector(
-                new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160);
+                new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl);
         mThread = new Thread(mConnector, NETD_TAG);
 
         // Add ourself to the Watchdog monitors.
@@ -227,6 +243,17 @@
         if (DBG) Slog.d(TAG, "Prepared");
     }
 
+    private IBatteryStats getBatteryStats() {
+        synchronized (this) {
+            if (mBatteryStats != null) {
+                return mBatteryStats;
+            }
+            mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                    BatteryStats.SERVICE_NAME));
+            return mBatteryStats;
+        }
+    }
+
     @Override
     public void registerObserver(INetworkManagementEventObserver observer) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
@@ -323,16 +350,38 @@
     /**
      * Notify our observers of a change in the data activity state of the interface
      */
-    private void notifyInterfaceClassActivity(String label, boolean active) {
+    private void notifyInterfaceClassActivity(int type, boolean active, long tsNanos) {
+        try {
+            getBatteryStats().noteDataConnectionActive(type, active, tsNanos);
+        } catch (RemoteException e) {
+        }
+
         final int length = mObservers.beginBroadcast();
         for (int i = 0; i < length; i++) {
             try {
-                mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(label, active);
+                mObservers.getBroadcastItem(i).interfaceClassDataActivityChanged(
+                        Integer.toString(type), active, tsNanos);
             } catch (RemoteException e) {
             } catch (RuntimeException e) {
             }
         }
         mObservers.finishBroadcast();
+
+        boolean report = false;
+        synchronized (mIdleTimerLock) {
+            if (mActiveIdleTimers.isEmpty()) {
+                // If there are no idle times, we are not monitoring activity, so we
+                // are always considered active.
+                active = true;
+            }
+            if (mNetworkActive != active) {
+                mNetworkActive = active;
+                report = active;
+            }
+        }
+        if (report) {
+            reportNetworkActive();
+        }
     }
 
     /**
@@ -360,8 +409,7 @@
 
         if (mBandwidthControlEnabled) {
             try {
-                IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME))
-                        .noteNetworkStatsEnabled();
+                getBatteryStats().noteNetworkStatsEnabled();
             } catch (RemoteException e) {
             }
         }
@@ -471,6 +519,11 @@
         }
 
         @Override
+        public boolean onCheckHoldWakeLock(int code) {
+            return code == NetdResponseCode.InterfaceClassActivity;
+        }
+
+        @Override
         public boolean onEvent(int code, String raw, String[] cooked) {
             String errorMessage = String.format("Invalid event from daemon (%s)", raw);
             switch (code) {
@@ -522,8 +575,15 @@
                     if (cooked.length < 4 || !cooked[1].equals("IfaceClass")) {
                         throw new IllegalStateException(errorMessage);
                     }
+                    long timestampNanos = 0;
+                    if (cooked.length == 5) {
+                        try {
+                            timestampNanos = Long.parseLong(cooked[4]);
+                        } catch(NumberFormatException ne) {}
+                    }
                     boolean isActive = cooked[2].equals("active");
-                    notifyInterfaceClassActivity(cooked[3], isActive);
+                    notifyInterfaceClassActivity(Integer.parseInt(cooked[3]),
+                            isActive, timestampNanos);
                     return true;
                     // break;
             case NetdResponseCode.InterfaceAddressChange:
@@ -1185,7 +1245,7 @@
     }
 
     @Override
-    public void addIdleTimer(String iface, int timeout, String label) {
+    public void addIdleTimer(String iface, int timeout, final int type) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         if (DBG) Slog.d(TAG, "Adding idletimer");
@@ -1199,11 +1259,22 @@
             }
 
             try {
-                mConnector.execute("idletimer", "add", iface, Integer.toString(timeout), label);
+                mConnector.execute("idletimer", "add", iface, Integer.toString(timeout),
+                        Integer.toString(type));
             } catch (NativeDaemonConnectorException e) {
                 throw e.rethrowAsParcelableException();
             }
-            mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, label));
+            mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
+
+            // Networks start up.
+            if (ConnectivityManager.isNetworkTypeMobile(type)) {
+                mNetworkActive = false;
+            }
+            mMainHandler.post(new Runnable() {
+                @Override public void run() {
+                    notifyInterfaceClassActivity(type, true, SystemClock.elapsedRealtimeNanos());
+                }
+            });
         }
     }
 
@@ -1214,18 +1285,24 @@
         if (DBG) Slog.d(TAG, "Removing idletimer");
 
         synchronized (mIdleTimerLock) {
-            IdleTimerParams params = mActiveIdleTimers.get(iface);
+            final IdleTimerParams params = mActiveIdleTimers.get(iface);
             if (params == null || --(params.networkCount) > 0) {
                 return;
             }
 
             try {
                 mConnector.execute("idletimer", "remove", iface,
-                        Integer.toString(params.timeout), params.label);
+                        Integer.toString(params.timeout), Integer.toString(params.type));
             } catch (NativeDaemonConnectorException e) {
                 throw e.rethrowAsParcelableException();
             }
             mActiveIdleTimers.remove(iface);
+            mMainHandler.post(new Runnable() {
+                @Override public void run() {
+                    notifyInterfaceClassActivity(params.type, false,
+                            SystemClock.elapsedRealtimeNanos());
+                }
+            });
         }
     }
 
@@ -1253,7 +1330,7 @@
     public NetworkStats getNetworkStatsDetail() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            return mStatsFactory.readNetworkStatsDetail(UID_ALL);
+            return mStatsFactory.readNetworkStatsDetail(UID_ALL, null, TAG_ALL, null);
         } catch (IOException e) {
             throw new IllegalStateException(e);
         }
@@ -1414,7 +1491,7 @@
     public NetworkStats getNetworkStatsUidDetail(int uid) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            return mStatsFactory.readNetworkStatsDetail(uid);
+            return mStatsFactory.readNetworkStatsDetail(uid, null, TAG_ALL, null);
         } catch (IOException e) {
             throw new IllegalStateException(e);
         }
@@ -1784,6 +1861,35 @@
         return event.getMessage().endsWith("started");
     }
 
+    @Override
+    public void registerNetworkActivityListener(INetworkActivityListener listener) {
+        mNetworkActivityListeners.register(listener);
+    }
+
+    @Override
+    public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
+        mNetworkActivityListeners.unregister(listener);
+    }
+
+    @Override
+    public boolean isNetworkActive() {
+        synchronized (mNetworkActivityListeners) {
+            return mNetworkActive || mActiveIdleTimers.isEmpty();
+        }
+    }
+
+    private void reportNetworkActive() {
+        final int length = mNetworkActivityListeners.beginBroadcast();
+        for (int i = 0; i < length; i++) {
+            try {
+                mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
+            } catch (RemoteException e) {
+            } catch (RuntimeException e) {
+            }
+        }
+        mNetworkActivityListeners.finishBroadcast();
+    }
+
     /** {@inheritDoc} */
     @Override
     public void monitor() {
@@ -1817,6 +1923,17 @@
             pw.println("]");
         }
 
+        synchronized (mIdleTimerLock) {
+            pw.println("Idle timers:");
+            for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
+                pw.print("  "); pw.print(ent.getKey()); pw.println(":");
+                IdleTimerParams params = ent.getValue();
+                pw.print("    timeout="); pw.print(params.timeout);
+                pw.print(" type="); pw.print(params.type);
+                pw.print(" networkCount="); pw.println(params.networkCount);
+            }
+        }
+
         pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
     }
 }
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index 9379955..1ed943c 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -26,11 +26,8 @@
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
 import android.os.Binder;
-import android.os.Handler;
-import android.os.HandlerThread;
 import android.os.Message;
 import android.os.Messenger;
-import android.os.IBinder;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.util.Slog;
@@ -39,20 +36,13 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.net.InetAddress;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
 import java.util.concurrent.CountDownLatch;
 
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.Protocol;
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-import com.android.server.am.BatteryStatsService;
-import com.android.server.NativeDaemonConnector.Command;
-import com.android.internal.R;
 
 /**
  * Network Service Discovery Service handles remote service discovery operation requests by
@@ -557,7 +547,7 @@
         mContentResolver = context.getContentResolver();
 
         mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
-                MDNS_TAG, 25);
+                MDNS_TAG, 25, null);
 
         mNsdStateMachine = new NsdStateMachine(TAG);
         mNsdStateMachine.start();
@@ -645,6 +635,10 @@
             mNativeDaemonConnected.countDown();
         }
 
+        public boolean onCheckHoldWakeLock(int code) {
+            return false;
+        }
+
         public boolean onEvent(int code, String raw, String[] cooked) {
             // TODO: NDC translates a message to a callback, we could enhance NDC to
             // directly interact with a state machine through messages
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index 5c7bfab..9274295 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -37,7 +37,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 
diff --git a/services/core/java/com/android/server/ShutdownActivity.java b/services/core/java/com/android/server/ShutdownActivity.java
index be65141..56172ed0 100644
--- a/services/core/java/com/android/server/ShutdownActivity.java
+++ b/services/core/java/com/android/server/ShutdownActivity.java
@@ -20,14 +20,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.IPowerManager;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Slog;
 
-import com.android.server.power.ShutdownThread;
-
 public class ShutdownActivity extends Activity {
 
     private static final String TAG = "ShutdownActivity";
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 0964767..d4c436f 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -33,7 +33,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
diff --git a/services/core/java/com/android/server/UpdateLockService.java b/services/core/java/com/android/server/UpdateLockService.java
index 0f778cd..7f33973 100644
--- a/services/core/java/com/android/server/UpdateLockService.java
+++ b/services/core/java/com/android/server/UpdateLockService.java
@@ -24,7 +24,6 @@
 import android.os.IBinder;
 import android.os.IUpdateLock;
 import android.os.RemoteException;
-import android.os.SystemClock;
 import android.os.TokenWatcher;
 import android.os.UpdateLock;
 import android.os.UserHandle;
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 28eb948..aa756a1 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -84,24 +84,27 @@
         private final long    mStartTime;
         private final long[]  mPattern;
         private final int     mRepeat;
+        private final int     mStreamHint;
         private final int     mUid;
         private final String  mPackageName;
 
-        Vibration(IBinder token, long millis, int uid, String packageName) {
-            this(token, millis, null, 0, uid, packageName);
+        Vibration(IBinder token, long millis, int streamHint, int uid, String packageName) {
+            this(token, millis, null, 0, streamHint, uid, packageName);
         }
 
-        Vibration(IBinder token, long[] pattern, int repeat, int uid, String packageName) {
-            this(token, 0, pattern, repeat, uid, packageName);
+        Vibration(IBinder token, long[] pattern, int repeat, int streamHint, int uid,
+                String packageName) {
+            this(token, 0, pattern, repeat, streamHint, uid, packageName);
         }
 
         private Vibration(IBinder token, long millis, long[] pattern,
-                int repeat, int uid, String packageName) {
+                int repeat, int streamHint, int uid, String packageName) {
             mToken = token;
             mTimeout = millis;
             mStartTime = SystemClock.uptimeMillis();
             mPattern = pattern;
             mRepeat = repeat;
+            mStreamHint = streamHint;
             mUid = uid;
             mPackageName = packageName;
         }
@@ -191,7 +194,8 @@
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
     }
 
-    public void vibrate(int uid, String packageName, long milliseconds, IBinder token) {
+    public void vibrate(int uid, String packageName, long milliseconds, int streamHint,
+            IBinder token) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
@@ -207,7 +211,7 @@
             return;
         }
 
-        Vibration vib = new Vibration(token, milliseconds, uid, packageName);
+        Vibration vib = new Vibration(token, milliseconds, streamHint, uid, packageName);
 
         final long ident = Binder.clearCallingIdentity();
         try {
@@ -233,7 +237,7 @@
     }
 
     public void vibratePattern(int uid, String packageName, long[] pattern, int repeat,
-            IBinder token) {
+            int streamHint, IBinder token) {
         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                 != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException("Requires VIBRATE permission");
@@ -258,7 +262,7 @@
                 return;
             }
 
-            Vibration vib = new Vibration(token, pattern, repeat, uid, packageName);
+            Vibration vib = new Vibration(token, pattern, repeat, streamHint, uid, packageName);
             try {
                 token.linkToDeath(vib, 0);
             } catch (RemoteException e) {
@@ -342,8 +346,12 @@
     // Lock held on mVibrations
     private void startVibrationLocked(final Vibration vib) {
         try {
-            int mode = mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
+            int mode = mAppOpsService.checkAudioOperation(AppOpsManager.OP_VIBRATE,
+                    vib.mStreamHint, vib.mUid, vib.mPackageName);
+            if (mode == AppOpsManager.MODE_ALLOWED) {
+                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);
@@ -354,7 +362,7 @@
         } catch (RemoteException e) {
         }
         if (vib.mTimeout != 0) {
-            doVibratorOn(vib.mTimeout, vib.mUid);
+            doVibratorOn(vib.mTimeout, vib.mUid, vib.mStreamHint);
             mH.postDelayed(mVibrationRunnable, vib.mTimeout);
         } else {
             // mThread better be null here. doCancelVibrate should always be
@@ -473,7 +481,7 @@
         return vibratorExists();
     }
 
-    private void doVibratorOn(long millis, int uid) {
+    private void doVibratorOn(long millis, int uid, int streamHint) {
         synchronized (mInputDeviceVibrators) {
             try {
                 mBatteryStatsService.noteVibratorOn(uid, millis);
@@ -483,7 +491,7 @@
             final int vibratorCount = mInputDeviceVibrators.size();
             if (vibratorCount != 0) {
                 for (int i = 0; i < vibratorCount; i++) {
-                    mInputDeviceVibrators.get(i).vibrate(millis);
+                    mInputDeviceVibrators.get(i).vibrate(millis, streamHint);
                 }
             } else {
                 vibratorOn(millis);
@@ -546,6 +554,7 @@
                 final int len = pattern.length;
                 final int repeat = mVibration.mRepeat;
                 final int uid = mVibration.mUid;
+                final int streamHint = mVibration.mStreamHint;
                 int index = 0;
                 long duration = 0;
 
@@ -566,7 +575,7 @@
                         // duration is saved for delay() at top of loop
                         duration = pattern[index++];
                         if (duration > 0) {
-                            VibratorService.this.doVibratorOn(duration, uid);
+                            VibratorService.this.doVibratorOn(duration, uid, streamHint);
                         }
                     } else {
                         if (repeat < 0) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index aa9849e..f587ccc 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -863,6 +863,7 @@
                         "User cannot modify accounts");
             } catch (RemoteException re) {
             }
+            return;
         }
 
         long identityToken = clearCallingIdentity();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index d66c5a7..033b967 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -28,6 +28,7 @@
 import android.os.Looper;
 import android.os.SystemProperties;
 import android.util.ArrayMap;
+import com.android.internal.app.ProcessMap;
 import com.android.internal.app.ProcessStats;
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.internal.os.TransferPipe;
@@ -596,12 +597,7 @@
                 break;
             }
         }
-        if (anyForeground != proc.foregroundServices) {
-            proc.foregroundServices = anyForeground;
-            if (oomAdj) {
-                mAm.updateOomAdjLocked();
-            }
-        }
+        mAm.updateProcessForegroundLocked(proc, anyForeground, oomAdj);
     }
 
     private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
@@ -671,8 +667,7 @@
             // what they are, so we can report this elsewhere for
             // others to know why certain services are running.
             try {
-                clientIntent = (PendingIntent)service.getParcelableExtra(
-                        Intent.EXTRA_CLIENT_INTENT);
+                clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
             } catch (RuntimeException e) {
             }
             if (clientIntent != null) {
@@ -686,6 +681,11 @@
             }
         }
 
+        if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+            mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                    "BIND_TREAT_LIKE_ACTIVITY");
+        }
+
         final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
 
         ServiceLookupResult res =
@@ -759,8 +759,12 @@
             }
 
             if (s.app != null) {
+                if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+                    s.app.treatLikeActivity = true;
+                }
                 // This could have made the service more important.
-                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
+                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
+                        || s.app.treatLikeActivity, b.client);
                 mAm.updateOomAdjLocked(s.app);
             }
 
@@ -862,6 +866,12 @@
 
                 if (r.binding.service.app != null) {
                     // This could have made the service less important.
+                    if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+                        r.binding.service.app.treatLikeActivity = true;
+                        mAm.updateLruProcessLocked(r.binding.service.app,
+                                r.binding.service.app.hasClientActivities
+                                || r.binding.service.app.treatLikeActivity, null);
+                    }
                     mAm.updateOomAdjLocked(r.binding.service.app);
                 }
             }
@@ -2077,10 +2087,12 @@
 
             // Sanity check: if the service listed for the app is not one
             // we actually are maintaining, just let it drop.
-            if (smap.mServicesByName.get(sr.name) != sr) {
-                ServiceRecord cur = smap.mServicesByName.get(sr.name);
-                Slog.wtf(TAG, "Service " + sr + " in process " + app
-                        + " not same as in map: " + cur);
+            final ServiceRecord curRec = smap.mServicesByName.get(sr.name);
+            if (curRec != sr) {
+                if (curRec != null) {
+                    Slog.wtf(TAG, "Service " + sr + " in process " + app
+                            + " not same as in map: " + curRec);
+                }
                 continue;
             }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 42e0a5b..5fa9084 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -32,6 +32,7 @@
 import android.app.IActivityContainerCallback;
 import android.appwidget.AppWidgetManager;
 import android.graphics.Rect;
+import android.os.BatteryStats;
 import android.util.ArrayMap;
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -920,11 +921,25 @@
     long mLowRamTimeSinceLastIdle = 0;
 
     /**
-     * If RAM is currently low, when that horrible situatin started.
+     * If RAM is currently low, when that horrible situation started.
      */
     long mLowRamStartTime = 0;
 
     /**
+     * For reporting to battery stats the current top application.
+     */
+    private String mCurResumedPackage = null;
+    private int mCurResumedUid = -1;
+
+    /**
+     * For reporting to battery stats the apps currently running foreground
+     * service.  The ProcessMap is package/uid tuples; each of these contain
+     * an array of the currently foreground processes.
+     */
+    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
+            = new ProcessMap<ArrayList<ProcessRecord>>();
+
+    /**
      * 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.
      */
@@ -1000,6 +1015,7 @@
     final ActivityThread mSystemThread;
 
     int mCurrentUserId = 0;
+    int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack
     private UserManagerService mUserManager;
 
     private final class AppDeathRecipient implements IBinder.DeathRecipient {
@@ -1058,7 +1074,8 @@
     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
     static final int PERSIST_URI_GRANTS_MSG = 38;
     static final int REQUEST_ALL_PSS_MSG = 39;
-    static final int UPDATE_TIME = 40;
+    static final int START_RELATED_USERS_MSG = 40;
+    static final int UPDATE_TIME = 41;
 
     static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1332,7 +1349,7 @@
                     String pkg = bundle.getString("pkg");
                     String reason = bundle.getString("reason");
                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
-                            UserHandle.USER_ALL, reason);
+                            false, UserHandle.USER_ALL, reason);
                 }
             } break;
             case FINALIZE_PENDING_INTENT_MSG: {
@@ -1672,6 +1689,12 @@
                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
                 break;
             }
+            case START_RELATED_USERS_MSG: {
+                synchronized (ActivityManagerService.this) {
+                    startRelatedUsersLocked();
+                }
+                break;
+            }
             case UPDATE_TIME: {
                 synchronized (ActivityManagerService.this) {
                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
@@ -1685,7 +1708,6 @@
                         }
                     }
                 }
-
                 break;
             }
             }
@@ -2117,29 +2139,24 @@
                                 totalUTime += otherUTime;
                                 totalSTime += otherSTime;
                                 if (pr != null) {
-                                    BatteryStatsImpl.Uid.Proc ps = bstats.getProcessStatsLocked(
-                                            st.name, st.pid);
+                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
+                                    if (ps == null || !ps.isActive()) {
+                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
+                                                pr.info.uid, pr.processName);
+                                    }
                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
                                             st.rel_stime-otherSTime);
                                     ps.addSpeedStepTimes(cpuSpeedTimes);
                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
-                                } else if (st.uid >= Process.FIRST_APPLICATION_UID) {
+                                } else {
                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
-                                    if (ps == null) {
-                                        st.batteryStats = ps = bstats.getProcessStatsLocked(st.uid,
-                                                "(Unknown)");
+                                    if (ps == null || !ps.isActive()) {
+                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
+                                                bstats.mapUid(st.uid), st.name);
                                     }
                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
                                             st.rel_stime-otherSTime);
                                     ps.addSpeedStepTimes(cpuSpeedTimes);
-                                } else {
-                                    BatteryStatsImpl.Uid.Proc ps =
-                                            bstats.getProcessStatsLocked(st.name, st.pid);
-                                    if (ps != null) {
-                                        ps.addCpuTimeLocked(st.rel_utime-otherUTime,
-                                                st.rel_stime-otherSTime);
-                                        ps.addSpeedStepTimes(cpuSpeedTimes);
-                                    }
                                 }
                             }
                             bstats.finishAddingCpuLocked(perc, totalUTime,
@@ -2297,11 +2314,12 @@
 
     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
             ProcessRecord client) {
-        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
+        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
+                || app.treatLikeActivity;
         final boolean hasService = false; // not impl yet. app.services.size() > 0;
         if (!activityChange && hasActivity) {
-            // The process has activties, so we are only going to allow activity-based
-            // adjustments move it.  It should be kept in the front of the list with other
+            // The process has activities, so we are only allowing activity-based adjustments
+            // to move it.  It should be kept in the front of the list with other
             // processes that have activities, and we don't want those to change their
             // order except due to activity operations.
             return;
@@ -2788,6 +2806,11 @@
                 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
                         ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
             }
+            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
+                    app.processName, app.info.uid);
+            if (app.isolated) {
+                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
+            }
         } catch (RuntimeException e) {
             // XXX do better error recovery.
             app.setPid(0);
@@ -3297,20 +3320,35 @@
             return;
         }
         // Remove any existing entries that are the same kind of task.
+        final Intent intent = task.intent;
+        final boolean document = intent != null && intent.isDocument();
         for (int i=0; i<N; i++) {
             TaskRecord tr = mRecentTasks.get(i);
-            if (task.userId == tr.userId
-                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
-                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
-                tr.disposeThumbnail();
-                mRecentTasks.remove(i);
-                i--;
-                N--;
-                if (task.intent == null) {
-                    // If the new recent task we are adding is not fully
-                    // specified, then replace it with the existing recent task.
-                    task = tr;
+            if (task != tr) {
+                if (task.userId != tr.userId) {
+                    continue;
                 }
+                final Intent trIntent = tr.intent;
+                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
+                    (intent == null || !intent.filterEquals(trIntent))) {
+                    continue;
+                }
+                if (document || trIntent != null && trIntent.isDocument()) {
+                    // Document tasks do not match other tasks.
+                    continue;
+                }
+            }
+
+            // Either task and tr are the same or, their affinities match or their intents match
+            // and neither of them is a document.
+            tr.disposeThumbnail();
+            mRecentTasks.remove(i);
+            i--;
+            N--;
+            if (task.intent == null) {
+                // If the new recent task we are adding is not fully
+                // specified, then replace it with the existing recent task.
+                task = tr;
             }
         }
         if (N >= MAX_RECENT_TASKS) {
@@ -4460,7 +4498,7 @@
 
     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
-                false, true, false, UserHandle.getUserId(uid), reason);
+                false, true, false, false, UserHandle.getUserId(uid), reason);
         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
                 Uri.fromParts("package", packageName, null));
         if (!mProcessesReady) {
@@ -4476,7 +4514,7 @@
     }
 
     private void forceStopUserLocked(int userId, String reason) {
-        forceStopPackageLocked(null, -1, false, false, true, false, userId, reason);
+        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                 | Intent.FLAG_RECEIVER_FOREGROUND);
@@ -4561,7 +4599,7 @@
 
     private final boolean forceStopPackageLocked(String name, int appId,
             boolean callerWillRestart, boolean purgeCache, boolean doit,
-            boolean evenPersistent, int userId, String reason) {
+            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
         int i;
         int N;
 
@@ -4653,7 +4691,7 @@
         // Remove transient permissions granted from/to this package/user
         removeUriPermissionsForPackageLocked(name, userId, false);
 
-        if (name == null) {
+        if (name == null || uninstalling) {
             // Remove pending intents.  For now we only do this when force
             // stopping users, because we have some problems when doing this
             // for packages -- app widgets are not currently cleaned up for
@@ -4743,6 +4781,11 @@
                 mPidsSelfLocked.remove(pid);
                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             }
+            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
+                    app.processName, app.info.uid);
+            if (app.isolated) {
+                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+            }
             killUnneededProcessLocked(app, reason);
             handleAppDiedLocked(app, true, allowRestart);
             removeLruProcessLocked(app);
@@ -4783,6 +4826,11 @@
                         mHeavyWeightProcess.userId, 0));
                 mHeavyWeightProcess = null;
             }
+            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
+                    app.processName, app.info.uid);
+            if (app.isolated) {
+                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+            }
             // Take care of any launching providers waiting for this process.
             checkAppInLaunchingProvidersLocked(app, true);
             // Take care of any services that are waiting for the process.
@@ -4867,7 +4915,7 @@
         app.curAdj = app.setAdj = -100;
         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
         app.forcingToForeground = null;
-        app.foregroundServices = false;
+        updateProcessForegroundLocked(app, false, false);
         app.hasShownUi = false;
         app.debugging = false;
         app.cached = false;
@@ -5098,7 +5146,7 @@
                 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, false, 0,
                                     "finished booting")) {
                                 setResultCode(Activity.RESULT_OK);
                                 return;
@@ -5156,10 +5204,11 @@
                                 userId);
                     }
                 }
+                scheduleStartRelatedUsersLocked();
             }
         }
     }
-    
+
     final void ensureBootCompleted() {
         boolean booting;
         boolean enableScreen;
@@ -5169,7 +5218,7 @@
             enableScreen = !mBooted;
             mBooted = true;
         }
-        
+
         if (booting) {
             finishBooting();
         }
@@ -5539,6 +5588,38 @@
     }
 
     @Override
+    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
+        if (!(pendingResult instanceof PendingIntentRecord)) {
+            return null;
+        }
+        try {
+            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
+            Intent intent = res.key.requestIntent;
+            if (intent != null) {
+                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
+                        || res.lastTagPrefix.equals(prefix))) {
+                    return res.lastTag;
+                }
+                res.lastTagPrefix = prefix;
+                StringBuilder sb = new StringBuilder(128);
+                if (prefix != null) {
+                    sb.append(prefix);
+                }
+                if (intent.getAction() != null) {
+                    sb.append(intent.getAction());
+                } else if (intent.getComponent() != null) {
+                    intent.getComponent().appendShortString(sb);
+                } else {
+                    sb.append("?");
+                }
+                return res.lastTag = sb.toString();
+            }
+        } catch (ClassCastException e) {
+        }
+        return null;
+    }
+
+    @Override
     public void setProcessLimit(int max) {
         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
                 "setProcessLimit()");
@@ -5570,7 +5651,7 @@
                     return;
                 }
                 pr.forcingToForeground = null;
-                pr.foregroundServices = false;
+                updateProcessForegroundLocked(pr, false, false);
             }
             updateOomAdjLocked();
         }
@@ -6739,7 +6820,7 @@
             }
         }
 
-        if (pending == null && receiver != null) {
+        if (pending.pendingRecords.isEmpty() && receiver != null) {
             // In this case all thumbnails were available and the client
             // is being asked to be told when the remaining ones come in...
             // which is unusually, since the top-most currently running
@@ -6776,10 +6857,19 @@
             ArrayList<ActivityManager.RecentTaskInfo> res
                     = new ArrayList<ActivityManager.RecentTaskInfo>(
                             maxNum < N ? maxNum : N);
+
+            final Set<Integer> includedUsers;
+            if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) {
+                includedUsers = getRelatedUsersLocked(userId);
+            } else {
+                includedUsers = new HashSet<Integer>();
+            }
+            includedUsers.add(Integer.valueOf(userId));
             for (int i=0; i<N && maxNum > 0; i++) {
                 TaskRecord tr = mRecentTasks.get(i);
-                // Only add calling user's recent tasks
-                if (tr.userId != userId) continue;
+                // Only add calling user or related users recent tasks
+                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
+
                 // Return the entry if desired by the caller.  We always return
                 // the first entry, because callers always expect this to be the
                 // foreground app.  We may filter others if the caller has
@@ -6803,6 +6893,22 @@
                     rti.origActivity = tr.origActivity;
                     rti.description = tr.lastDescription;
                     rti.stackId = tr.stack.mStackId;
+                    rti.userId = tr.userId;
+
+                    final ArrayList<ActivityRecord> activities = tr.mActivities;
+                    int numSet = 0;
+                    for (int activityNdx = activities.size() - 1; activityNdx >= 0 && numSet < 2;
+                            --activityNdx) {
+                        final ActivityRecord r = activities.get(activityNdx);
+                        if (rti.activityLabel == null && r.recentsLabel != null) {
+                            rti.activityLabel = r.recentsLabel;
+                            ++numSet;
+                        }
+                        if (rti.activityIcon == null && r.recentsIcon != null) {
+                            rti.activityIcon = r.recentsIcon;
+                            ++numSet;
+                        }
+                    }
 
                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
                         // Check whether this activity is currently available.
@@ -6822,7 +6928,7 @@
                             // Will never happen.
                         }
                     }
-                    
+
                     res.add(rti);
                     maxNum--;
                 }
@@ -6869,6 +6975,26 @@
     }
 
     @Override
+    public void setRecentsLabel(IBinder token, CharSequence recentsLabel) {
+        synchronized (this) {
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r != null) {
+                r.recentsLabel = recentsLabel.toString();
+            }
+        }
+    }
+
+    @Override
+    public void setRecentsIcon(IBinder token, Bitmap recentsIcon) {
+        synchronized (this) {
+            ActivityRecord r = ActivityRecord.isInStackLocked(token);
+            if (r != null) {
+                r.recentsIcon = recentsIcon;
+            }
+        }
+    }
+
+    @Override
     public boolean removeSubTask(int taskId, int subTaskIndex) {
         synchronized (this) {
             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
@@ -6982,11 +7108,11 @@
      * TODO: Add mController hook
      */
     @Override
-    public void moveTaskToFront(int task, int flags, Bundle options) {
+    public void moveTaskToFront(int taskId, int flags, Bundle options) {
         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
                 "moveTaskToFront()");
 
-        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
+        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
         synchronized(this) {
             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
                     Binder.getCallingUid(), "Task to front")) {
@@ -6995,6 +7121,14 @@
             }
             final long origId = Binder.clearCallingIdentity();
             try {
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                if (task == null) {
+                    return;
+                }
+                if (mStackSupervisor.isLockTaskModeViolation(task)) {
+                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+                    return;
+                }
                 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
             } finally {
                 Binder.restoreCallingIdentity(origId);
@@ -7180,12 +7314,109 @@
     }
 
     @Override
+    public boolean isInHomeStack(int taskId) {
+        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                "getStackInfo()");
+        long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                TaskRecord tr = recentTaskForIdLocked(taskId);
+                if (tr != null) {
+                    return tr.stack.isHomeStack();
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+        return false;
+    }
+
+    @Override
     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
         synchronized(this) {
             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
         }
     }
 
+    private boolean isLockTaskAuthorized(ComponentName name) {
+//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
+//                "startLockTaskMode()");
+//        DevicePolicyManager dpm = (DevicePolicyManager)
+//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+//        return dpm != null && dpm.isLockTaskPermitted(name);
+        return true;
+    }
+
+    private void startLockTaskMode(TaskRecord task) {
+        if (!isLockTaskAuthorized(task.intent.getComponent())) {
+            return;
+        }
+        long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                // Since we lost lock on task, make sure it is still there.
+                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
+                if (task != null) {
+                    mStackSupervisor.setLockTaskModeLocked(task);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void startLockTaskMode(int taskId) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            final TaskRecord task;
+            synchronized (this) {
+                task = mStackSupervisor.anyTaskForIdLocked(taskId);
+            }
+            if (task != null) {
+                startLockTaskMode(task);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void startLockTaskMode(IBinder token) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            final TaskRecord task;
+            synchronized (this) {
+                final ActivityRecord r = ActivityRecord.forToken(token);
+                if (r == null) {
+                    return;
+                }
+                task = r.task;
+            }
+            if (task != null) {
+                startLockTaskMode(task);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void stopLockTaskMode() {
+//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
+//                "stopLockTaskMode()");
+        synchronized (this) {
+            mStackSupervisor.setLockTaskModeLocked(null);
+        }
+    }
+
+    @Override
+    public boolean isInLockTaskMode() {
+        synchronized (this) {
+            return mStackSupervisor.isInLockTaskMode();
+        }
+    }
+
     // =========================================================
     // THUMBNAILS
     // =========================================================
@@ -7756,22 +7987,27 @@
      */
     public void removeContentProvider(IBinder connection, boolean stable) {
         enforceNotIsolatedCaller("removeContentProvider");
-        synchronized (this) {
-            ContentProviderConnection conn;
-            try {
-                conn = (ContentProviderConnection)connection;
-            } catch (ClassCastException e) {
-                String msg ="removeContentProvider: " + connection
-                        + " not a ContentProviderConnection";
-                Slog.w(TAG, msg);
-                throw new IllegalArgumentException(msg);
+        long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                ContentProviderConnection conn;
+                try {
+                    conn = (ContentProviderConnection)connection;
+                } catch (ClassCastException e) {
+                    String msg ="removeContentProvider: " + connection
+                            + " not a ContentProviderConnection";
+                    Slog.w(TAG, msg);
+                    throw new IllegalArgumentException(msg);
+                }
+                if (conn == null) {
+                    throw new NullPointerException("connection is null");
+                }
+                if (decProviderCountLocked(conn, null, null, stable)) {
+                    updateOomAdjLocked();
+                }
             }
-            if (conn == null) {
-                throw new NullPointerException("connection is null");
-            }
-            if (decProviderCountLocked(conn, null, null, stable)) {
-                updateOomAdjLocked();
-            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
     }
 
@@ -8378,7 +8614,7 @@
                 mDebugTransient = !persistent;
                 if (packageName != null) {
                     forceStopPackageLocked(packageName, -1, false, false, true, true,
-                            UserHandle.USER_ALL, "set debug app");
+                            false, UserHandle.USER_ALL, "set debug app");
                 }
             }
         } finally {
@@ -8746,7 +8982,7 @@
                 Context.WINDOW_SERVICE)).addView(v, lp);
     }
 
-    public void noteWakeupAlarm(IIntentSender sender) {
+    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
         if (!(sender instanceof PendingIntentRecord)) {
             return;
         }
@@ -8758,7 +8994,8 @@
                 int MY_UID = Binder.getCallingUid();
                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
                 BatteryStatsImpl.Uid.Pkg pkg =
-                    stats.getPackageStatsLocked(uid, rec.key.packageName);
+                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
+                            sourcePkg != null ? sourcePkg : rec.key.packageName);
                 pkg.incWakeupsLocked();
             }
         }
@@ -12134,7 +12371,25 @@
             if (!brief) {
                 if (!isCompact) {
                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
-                    pw.println(" kB");
+                    pw.print(" kB (status ");
+                    switch (mLastMemoryLevel) {
+                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
+                            pw.println("normal)");
+                            break;
+                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
+                            pw.println("moderate)");
+                            break;
+                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
+                            pw.println("low)");
+                            break;
+                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
+                            pw.println("critical)");
+                            break;
+                        default:
+                            pw.print(mLastMemoryLevel);
+                            pw.println(")");
+                            break;
+                    }
                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
                             pw.print(cachedPss); pw.print(" cached pss + ");
@@ -12349,9 +12604,10 @@
         app.unlinkDeathRecipient();
         app.makeInactive(mProcessStats);
         app.forcingToForeground = null;
-        app.foregroundServices = false;
+        updateProcessForegroundLocked(app, false, false);
         app.foregroundActivities = false;
         app.hasShownUi = false;
+        app.treatLikeActivity = false;
         app.hasAboveClient = false;
         app.hasClientActivities = false;
 
@@ -12479,10 +12735,16 @@
             startProcessLocked(app, "restart", app.processName);
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
+            boolean removed;
             synchronized (mPidsSelfLocked) {
                 mPidsSelfLocked.remove(app.pid);
                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
             }
+            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
+                    app.processName, app.info.uid);
+            if (app.isolated) {
+                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+            }
             app.setPid(0);
         }
     }
@@ -13309,7 +13571,7 @@
                         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, false, userId,
                                         "storage unmount");
                             }
                             sendPackageBroadcastLocked(
@@ -13321,10 +13583,13 @@
                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
                             boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
                                     intent.getAction());
+                            boolean fullUninstall = removed &&
+                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
                                 forceStopPackageLocked(ssp, UserHandle.getAppId(
                                         intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
-                                        false, userId, removed ? "pkg removed" : "pkg changed");
+                                        false, fullUninstall, userId,
+                                        removed ? "pkg removed" : "pkg changed");
                             }
                             if (removed) {
                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
@@ -13811,7 +14076,7 @@
 
             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, false, userId,
                     "start instr");
             ProcessRecord app = addAppLocked(ai, false);
             app.instrumentationClass = className;
@@ -13879,7 +14144,7 @@
         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, false, app.userId,
                 "finished inst");
     }
 
@@ -14635,6 +14900,9 @@
                             app.adjTarget = s.name;
                         }
                     }
+                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+                        app.treatLikeActivity = true;
+                    }
                     final ActivityRecord a = cr.activity;
                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
@@ -14767,10 +15035,17 @@
             }
         }
 
-        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
-            // This is a cached process, but with client activities.  Mark it so.
-            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
-            app.adjType = "cch-client-act";
+        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
+            if (app.hasClientActivities) {
+                // This is a cached process, but with client activities.  Mark it so.
+                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
+                app.adjType = "cch-client-act";
+            } else if (app.treatLikeActivity) {
+                // This is a cached process, but somebody wants us to treat it like it has
+                // an activity, okay!
+                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+                app.adjType = "cch-as-act";
+            }
         }
 
         if (adj == ProcessList.SERVICE_ADJ) {
@@ -15305,8 +15580,66 @@
                 reportingProcessState, now);
     }
 
+    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
+            boolean oomAdj) {
+        if (isForeground != proc.foregroundServices) {
+            proc.foregroundServices = isForeground;
+            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
+                    proc.info.uid);
+            if (isForeground) {
+                if (curProcs == null) {
+                    curProcs = new ArrayList<ProcessRecord>();
+                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
+                }
+                if (!curProcs.contains(proc)) {
+                    curProcs.add(proc);
+                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
+                            proc.info.packageName, proc.info.uid);
+                }
+            } else {
+                if (curProcs != null) {
+                    if (curProcs.remove(proc)) {
+                        mBatteryStatsService.noteEvent(
+                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
+                                proc.info.packageName, proc.info.uid);
+                        if (curProcs.size() <= 0) {
+                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
+                        }
+                    }
+                }
+            }
+            if (oomAdj) {
+                updateOomAdjLocked();
+            }
+        }
+    }
+
     private final ActivityRecord resumedAppLocked() {
-        return mStackSupervisor.resumedAppLocked();
+        ActivityRecord act = mStackSupervisor.resumedAppLocked();
+        String pkg;
+        int uid;
+        if (act != null && !act.sleeping) {
+            pkg = act.packageName;
+            uid = act.info.applicationInfo.uid;
+        } else {
+            pkg = null;
+            uid = -1;
+        }
+        // Has the UID or resumed package name changed?
+        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
+                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
+            if (mCurResumedPackage != null) {
+                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
+                        mCurResumedPackage, mCurResumedUid);
+            }
+            mCurResumedPackage = pkg;
+            mCurResumedUid = uid;
+            if (mCurResumedPackage != null) {
+                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
+                        mCurResumedPackage, mCurResumedUid);
+            }
+        }
+        return act;
     }
 
     final boolean updateOomAdjLocked(ProcessRecord app) {
@@ -15965,8 +16298,43 @@
 
     // Multi-user methods
 
+    /**
+     * Start user, if its not already running, but don't bring it to foreground.
+     */
+    @Override
+    public boolean startUserInBackground(final int userId) {
+        return startUser(userId, /* foreground */ false);
+    }
+
+    /**
+     * Refreshes the list of users related to the current user when either a
+     * user switch happens or when a new related user is started in the
+     * background.
+     */
+    private void updateRelatedUserIdsLocked() {
+        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
+        int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null
+        for (int i = 0; i < relatedUserIds.length; i++) {
+            relatedUserIds[i] = relatedUsers.get(i).id;
+        }
+        mRelatedUserIds = relatedUserIds;
+    }
+
+    private Set getRelatedUsersLocked(int userId) {
+        Set userIds = new HashSet<Integer>();
+        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId);
+        for (UserInfo user : relatedUsers) {
+            userIds.add(Integer.valueOf(user.id));
+        }
+        return userIds;
+    }
+
     @Override
     public boolean switchUser(final int userId) {
+        return startUser(userId, /* foregound */ true);
+    }
+
+    private boolean startUser(final int userId, boolean foreground) {
         if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
                 != PackageManager.PERMISSION_GRANTED) {
             String msg = "Permission Denial: switchUser() from pid="
@@ -15977,6 +16345,8 @@
             throw new SecurityException(msg);
         }
 
+        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
+
         final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
@@ -15985,14 +16355,18 @@
                     return true;
                 }
 
+                mStackSupervisor.setLockTaskModeLocked(null);
+
                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
                 if (userInfo == null) {
                     Slog.w(TAG, "No user info for user #" + userId);
                     return false;
                 }
 
-                mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
-                        R.anim.screen_user_enter);
+                if (foreground) {
+                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
+                            R.anim.screen_user_enter);
+                }
 
                 boolean needStart = false;
 
@@ -16004,16 +16378,24 @@
                     needStart = true;
                 }
 
-                mCurrentUserId = userId;
                 final Integer userIdInt = Integer.valueOf(userId);
                 mUserLru.remove(userIdInt);
                 mUserLru.add(userIdInt);
 
-                mWindowManager.setCurrentUser(userId);
-
-                // Once the internal notion of the active user has switched, we lock the device
-                // with the option to show the user switcher on the keyguard.
-                mWindowManager.lockNow(null);
+                if (foreground) {
+                    mCurrentUserId = userId;
+                    updateRelatedUserIdsLocked();
+                    mWindowManager.setCurrentUser(userId, mRelatedUserIds);
+                    // Once the internal notion of the active user has switched, we lock the device
+                    // with the option to show the user switcher on the keyguard.
+                    mWindowManager.lockNow(null);
+                } else {
+                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
+                    updateRelatedUserIdsLocked();
+                    mWindowManager.updateRelatedUserIds(mRelatedUserIds);
+                    mUserLru.remove(currentUserIdInt);
+                    mUserLru.add(currentUserIdInt);
+                }
 
                 final UserStartedState uss = mStartedUsers.get(userId);
 
@@ -16034,12 +16416,15 @@
                     needStart = true;
                 }
 
-                mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
-                mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
-                mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
-                        oldUserId, userId, uss));
-                mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
-                        oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
+                if (foreground) {
+                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
+                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
+                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
+                            oldUserId, userId, uss));
+                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
+                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
+                }
+
                 if (needStart) {
                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
@@ -16070,16 +16455,18 @@
                     }
                 }
 
-                boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
-                if (homeInFront) {
-                    startHomeActivityLocked(userId);
-                } else {
-                    mStackSupervisor.resumeTopActivitiesLocked();
+                if (foreground) {
+                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
+                    if (homeInFront) {
+                        startHomeActivityLocked(userId);
+                    } else {
+                        mStackSupervisor.resumeTopActivitiesLocked();
+                    }
+                    EventLogTags.writeAmSwitchUser(userId);
+                    getUserManagerLocked().userForeground(userId);
+                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
                 }
 
-                EventLogTags.writeAmSwitchUser(userId);
-                getUserManagerLocked().userForeground(userId);
-                sendUserSwitchBroadcastsLocked(oldUserId, userId);
                 if (needStart) {
                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
@@ -16225,6 +16612,32 @@
         }
     }
 
+    void scheduleStartRelatedUsersLocked() {
+        if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) {
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG),
+                    DateUtils.SECOND_IN_MILLIS);
+        }
+    }
+
+    void startRelatedUsersLocked() {
+        if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked");
+        List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId);
+        List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size());
+        for (UserInfo relatedUser : relatedUsers) {
+            if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) {
+                toStart.add(relatedUser);
+            }
+        }
+        final int n = toStart.size();
+        int i = 0;
+        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
+            startUserInBackground(toStart.get(i).id);
+        }
+        if (i < n) {
+            Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS");
+        }
+    }
+
     void finishUserSwitch(UserStartedState uss) {
         synchronized (this) {
             if (uss.mState == UserStartedState.STATE_BOOTING
@@ -16239,6 +16652,9 @@
                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
                         true, false, MY_PID, Process.SYSTEM_UID, userId);
             }
+
+            startRelatedUsersLocked();
+
             int num = mUserLru.size();
             int i = 0;
             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
@@ -16290,6 +16706,7 @@
     }
 
     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
+        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
         if (mCurrentUserId == userId) {
             return ActivityManager.USER_OP_IS_CURRENT;
         }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index a27288a..77f5c59 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -145,8 +145,12 @@
 
     private boolean inHistory;  // are we in the history stack?
     final ActivityStackSupervisor mStackSupervisor;
+    boolean mStartingWindowShown = false;
     ActivityContainer mInitialActivityContainer;
 
+    String recentsLabel;
+    Bitmap recentsIcon;
+
     void dump(PrintWriter pw, String prefix) {
         final long now = SystemClock.uptimeMillis();
         pw.print(prefix); pw.print("packageName="); pw.print(packageName);
@@ -597,7 +601,7 @@
             int requestCode, int resultCode,
             Intent resultData) {
         ActivityResult r = new ActivityResult(from, resultWho,
-        		requestCode, resultCode, resultData);
+                requestCode, resultCode, resultData);
         if (results == null) {
             results = new ArrayList<ResultInfo>();
         }
@@ -684,7 +688,8 @@
     }
 
     void applyOptionsLocked() {
-        if (pendingOptions != null) {
+        if (pendingOptions != null
+                && pendingOptions.getAnimationType() != ActivityOptions.ANIM_SCENE_TRANSITION) {
             final int animationType = pendingOptions.getAnimationType();
             switch (animationType) {
                 case ActivityOptions.ANIM_CUSTOM:
@@ -727,6 +732,10 @@
         }
     }
 
+    ActivityOptions getOptionsForTargetActivityLocked() {
+        return pendingOptions != null ? pendingOptions.forTargetActivity() : null;
+    }
+
     void clearOptionsLocked() {
         if (pendingOptions != null) {
             pendingOptions.abort();
diff --git a/services/core/java/com/android/server/am/ActivityResult.java b/services/core/java/com/android/server/am/ActivityResult.java
index 6d5bdeb..395918e 100644
--- a/services/core/java/com/android/server/am/ActivityResult.java
+++ b/services/core/java/com/android/server/am/ActivityResult.java
@@ -18,7 +18,6 @@
 
 import android.app.ResultInfo;
 import android.content.Intent;
-import android.os.Bundle;
 
 /**
  * Pending result information to send back to an activity.
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 68ef815..3db3a26 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -69,6 +69,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.util.EventLog;
@@ -121,8 +122,7 @@
     // convertToTranslucent().
     static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
 
-    static final boolean SCREENSHOT_FORCE_565 = ActivityManager
-            .isLowRamDeviceStatic() ? true : false;
+    static final boolean SCREENSHOT_FORCE_565 = ActivityManager.isLowRamDeviceStatic();
 
     enum ActivityState {
         INITIALIZING,
@@ -340,8 +340,19 @@
         mCurrentUser = mService.mCurrentUserId;
     }
 
-    boolean okToShow(ActivityRecord r) {
-        return r.userId == mCurrentUser
+    /**
+     * Checks whether the userid is either the current user or a related user.
+     */
+    private boolean isRelatedToOrCurrentUserLocked(int userId) {
+        if (mCurrentUser == userId) return true;
+        for (int i = 0; i < mService.mRelatedUserIds.length; i++) {
+            if (mService.mRelatedUserIds[i] == userId) return true;
+        }
+        return false;
+    }
+
+    boolean okToShowLocked(ActivityRecord r) {
+        return isRelatedToOrCurrentUserLocked(r.userId)
                 || (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0;
     }
 
@@ -361,7 +372,7 @@
             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)) {
+                if (!r.finishing && !r.delayedResume && r != notTop && okToShowLocked(r)) {
                     return r;
                 }
             }
@@ -388,7 +399,7 @@
             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)) {
+                if (!r.finishing && (token != r.appToken) && okToShowLocked(r)) {
                     return r;
                 }
             }
@@ -401,8 +412,9 @@
         // 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);
+            final int topActivityNdx = activities.size() - 1;
+            if (topActivityNdx >= 0) {
+                return activities.get(topActivityNdx);
             }
         }
         return null;
@@ -480,6 +492,9 @@
             cls = new ComponentName(info.packageName, info.targetActivity);
         }
         final int userId = UserHandle.getUserId(info.applicationInfo.uid);
+        boolean isDocument = intent != null & intent.isDocument();
+        // If documentData is non-null then it must match the existing task data.
+        Uri documentData = isDocument ? intent.getData() : null;
 
         if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this);
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -496,23 +511,39 @@
                 continue;
             }
 
+            final Intent taskIntent = task.intent;
+            final Intent affinityIntent = task.affinityIntent;
+            final boolean taskIsDocument;
+            final Uri taskDocumentData;
+            if (taskIntent != null && taskIntent.isDocument()) {
+                taskIsDocument = true;
+                taskDocumentData = taskIntent.getData();
+            } else if (affinityIntent != null && affinityIntent.isDocument()) {
+                taskIsDocument = true;
+                taskDocumentData = affinityIntent.getData();
+            } else {
+                taskIsDocument = false;
+                taskDocumentData = null;
+            }
+
             if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls="
-                    + r.task.intent.getComponent().flattenToShortString()
+                    + taskIntent.getComponent().flattenToShortString()
                     + "/aff=" + r.task.affinity + " to new cls="
                     + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
-            if (task.affinity != null) {
-                if (task.affinity.equals(info.taskAffinity)) {
+            if (!isDocument && !taskIsDocument && task.affinity != null) {
+                if (task.affinity.equals(target.taskAffinity)) {
                     if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!");
                     return r;
                 }
-            } else if (task.intent != null && task.intent.getComponent().equals(cls)) {
+            } else if (taskIntent != null && taskIntent.getComponent().equals(cls) &&
+                    Objects.equals(documentData, taskDocumentData)) {
                 if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
                 //dump();
                 if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
                         + r.intent);
                 return r;
-            } else if (task.affinityIntent != null
-                    && task.affinityIntent.getComponent().equals(cls)) {
+            } else if (affinityIntent != null && affinityIntent.getComponent().equals(cls) &&
+                    Objects.equals(documentData, taskDocumentData)) {
                 if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
                 //dump();
                 if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
@@ -540,7 +571,7 @@
 
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
             TaskRecord task = mTaskHistory.get(taskNdx);
-            if (task.userId != mCurrentUser) {
+            if (!isRelatedToOrCurrentUserLocked(task.userId)) {
                 return null;
             }
             final ArrayList<ActivityRecord> activities = task.mActivities;
@@ -571,7 +602,7 @@
         int index = mTaskHistory.size();
         for (int i = 0; i < index; ) {
             TaskRecord task = mTaskHistory.get(i);
-            if (task.userId == userId) {
+            if (isRelatedToOrCurrentUserLocked(task.userId)) {
                 if (DEBUG_TASKS) Slog.d(TAG, "switchUserLocked: stack=" + getStackId() +
                         " moving " + task + " to top");
                 mTaskHistory.remove(i);
@@ -702,10 +733,17 @@
         int w = mThumbnailWidth;
         int h = mThumbnailHeight;
         if (w < 0) {
-            mThumbnailWidth = w =
-                res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
-            mThumbnailHeight = h =
-                res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
+            if (SystemProperties.getBoolean("persist.recents.use_alternate", false)) {
+                mThumbnailWidth = w =
+                   res.getDimensionPixelSize(com.android.internal.R.dimen.recents_thumbnail_width);
+                mThumbnailHeight = h =
+                   res.getDimensionPixelSize(com.android.internal.R.dimen.recents_thumbnail_height);
+            } else {
+                mThumbnailWidth = w =
+                    res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
+                mThumbnailHeight = h =
+                    res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
+            }
         }
 
         if (w > 0) {
@@ -1246,6 +1284,32 @@
         }
     }
 
+    /** If any activities below the top running one are in the INITIALIZING state and they have a
+     * starting window displayed then remove that starting window. It is possible that the activity
+     * in this state will never resumed in which case that starting window will be orphaned. */
+    void cancelInitializingActivities() {
+        final ActivityRecord topActivity = topRunningActivityLocked(null);
+        boolean aboveTop = 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 (aboveTop) {
+                    if (r == topActivity) {
+                        aboveTop = false;
+                    }
+                    continue;
+                }
+
+                if (r.state == ActivityState.INITIALIZING && r.mStartingWindowShown) {
+                    if (DEBUG_VISBILITY) Slog.w(TAG, "Found orphaned starting window " + r);
+                    r.mStartingWindowShown = false;
+                    mWindowManager.removeAppStartingWindow(r.appToken);
+                }
+            }
+        }
+    }
+
     /**
      * Ensure that the top activity in the stack is resumed.
      *
@@ -1269,6 +1333,8 @@
             return false;
         }
 
+        cancelInitializingActivities();
+
         // Find the first activity that is not finishing.
         ActivityRecord next = topRunningActivityLocked(null);
 
@@ -1514,7 +1580,13 @@
                 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_ACTIVITY_OPEN, false);
             }
         }
+
+        Bundle resumeAnimOptions = null;
         if (anim) {
+            ActivityOptions opts = next.getOptionsForTargetActivityLocked();
+            if (opts != null) {
+                resumeAnimOptions = opts.toBundle();
+            }
             next.applyOptionsLocked();
         } else {
             next.clearOptionsLocked();
@@ -1606,8 +1678,9 @@
                 mService.showAskCompatModeDialogLocked(next);
                 next.app.pendingUiClean = true;
                 next.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
+                next.clearOptionsLocked();
                 next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
-                        mService.isNextTransitionForward());
+                        mService.isNextTransitionForward(), resumeAnimOptions);
 
                 mStackSupervisor.checkReadyForSleepLocked();
 
@@ -1692,10 +1765,10 @@
         mTaskHistory.remove(task);
         // Now put task at top.
         int stackNdx = mTaskHistory.size();
-        if (task.userId != mCurrentUser) {
+        if (!isRelatedToOrCurrentUserLocked(task.userId)) {
             // Put non-current user tasks below current user tasks.
             while (--stackNdx >= 0) {
-                if (mTaskHistory.get(stackNdx).userId != mCurrentUser) {
+                if (!isRelatedToOrCurrentUserLocked(mTaskHistory.get(stackNdx).userId)) {
                     break;
                 }
             }
@@ -1804,7 +1877,7 @@
                 // If the caller has requested that the target task be
                 // reset, then do so.
                 if ((r.intent.getFlags()
-                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
+                        & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                     resetTaskIfNeededLocked(r, r);
                     doShow = topRunningNonDelayedActivityLocked(null) == r;
                 }
@@ -1832,6 +1905,7 @@
                                 r.info.applicationInfo), r.nonLocalizedLabel,
                         r.labelRes, r.icon, r.logo, r.windowFlags,
                         prev != null ? prev.appToken : null, showStartingIcon);
+                r.mStartingWindowShown = true;
             }
         } else {
             // If this is the first activity, don't do any fancy animations,
@@ -1952,14 +2026,7 @@
                             + " out to new task " + target.task);
                 }
 
-                if (clearWhenTaskReset) {
-                    // This is the start of a new sub-task.
-                    if (target.thumbHolder == null) {
-                        target.thumbHolder = new ThumbnailHolder();
-                    }
-                } else {
-                    target.thumbHolder = newThumbHolder;
-                }
+                target.thumbHolder = newThumbHolder;
 
                 final int targetTaskId = targetTask.taskId;
                 mWindowManager.setAppGroupId(target.appToken, targetTaskId);
@@ -2422,14 +2489,15 @@
         }
 
         r.makeFinishing();
+        final TaskRecord task = r.task;
         EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
                 r.userId, System.identityHashCode(r),
-                r.task.taskId, r.shortComponentName, reason);
-        final ArrayList<ActivityRecord> activities = r.task.mActivities;
+                task.taskId, r.shortComponentName, reason);
+        final ArrayList<ActivityRecord> activities = task.mActivities;
         final int index = activities.indexOf(r);
         if (index < (activities.size() - 1)) {
-            r.task.setFrontOfTask();
-            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+            task.setFrontOfTask();
+            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
                 // If the caller asked that this activity (and all above it)
                 // be cleared when the task is reset, don't lose that information,
                 // but propagate it up to the next activity.
@@ -2468,6 +2536,9 @@
                 startPausingLocked(false, false);
             }
 
+            if (endTask) {
+                mStackSupervisor.endLockTaskModeIfTaskEnding(task);
+            }
         } else if (r.state != ActivityState.PAUSING) {
             // If the activity is PAUSING, we will complete the finish once
             // it is done pausing; else we can just directly finish it here.
@@ -3032,23 +3103,6 @@
         }
     }
 
-    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.mOnTopOfHome = 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);
 
@@ -3106,7 +3160,15 @@
      * @return Returns true if the move completed, false if not.
      */
     final boolean moveTaskToBackLocked(int taskId, ActivityRecord reason) {
-        Slog.i(TAG, "moveTaskToBack: " + taskId);
+        final TaskRecord tr = taskForIdLocked(taskId);
+        if (tr == null) {
+            Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
+            return false;
+        }
+
+        Slog.i(TAG, "moveTaskToBack: " + tr);
+
+        mStackSupervisor.endLockTaskModeIfTaskEnding(tr);
 
         // 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
@@ -3134,11 +3196,6 @@
         if (DEBUG_TRANSITION) Slog.v(TAG,
                 "Prepare to back transition: task=" + taskId);
 
-        final TaskRecord tr = taskForIdLocked(taskId);
-        if (tr == null) {
-            return false;
-        }
-
         mTaskHistory.remove(tr);
         mTaskHistory.add(0, tr);
 
@@ -3622,6 +3679,7 @@
     }
 
     void removeTask(TaskRecord task) {
+        mStackSupervisor.endLockTaskModeIfTaskEnding(task);
         mWindowManager.removeTask(task.taskId);
         final ActivityRecord r = mResumedActivity;
         if (r != null && r.task == task) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index bf93c5a..47b4d0a 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 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;
@@ -231,6 +232,10 @@
 
     InputManagerInternal mInputManagerInternal;
 
+    /** If non-null then the task specified remains in front and no other tasks may be started
+     * until the task exits or #stopLockTaskMode() is called. */
+    private TaskRecord mLockTaskModeTask;
+
     public ActivityStackSupervisor(ActivityManagerService service) {
         mService = service;
         PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
@@ -523,7 +528,7 @@
     }
 
     void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) {
-		// TODO: Put all stacks in supervisor and iterate through them instead.
+        // TODO: Put all stacks in supervisor and iterate through them instead.
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
@@ -1022,13 +1027,16 @@
                     }
                 }
             }
+
             app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
+            Bundle options = (r.pendingOptions == null) ? null : r.pendingOptions.toBundle();
+            r.clearOptionsLocked();
             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);
+                    profileAutoStop, options);
 
             if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
                 // This may be a heavy-weight process!  Note that the package
@@ -1438,14 +1446,20 @@
             }
         }
 
+        final boolean newDocument = intent.isDocument();
         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) {
+            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 (newDocument) {
+            if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
+                Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
+                r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+            }
         } 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
@@ -1468,7 +1482,7 @@
                 // so we don't want to blindly throw it in to that task.  Instead we will take
                 // the NEW_TASK flow and try to find a task for it. But save the task information
                 // so it can be used when creating the new task.
-                if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                     Slog.w(TAG, "startActivity called from finishing " + sourceRecord
                             + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -1484,7 +1498,7 @@
             sourceStack = null;
         }
 
-        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+        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
@@ -1501,8 +1515,8 @@
         boolean movedHome = false;
         TaskRecord reuseTask = null;
         ActivityStack targetStack;
-        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
-                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
+        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
@@ -1517,6 +1531,10 @@
                         ? findTaskLocked(r)
                         : findActivityLocked(intent, r.info);
                 if (intentActivity != null) {
+                    if (isLockTaskModeViolation(intentActivity.task)) {
+                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+                    }
                     if (r.task == null) {
                         r.task = intentActivity.task;
                     }
@@ -1687,7 +1705,7 @@
             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
+                        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,
@@ -1727,6 +1745,10 @@
         // Should this be considered a new task?
         if (r.resultTo == null && !addingToTask
                 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+            if (isLockTaskModeViolation(reuseTask)) {
+                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+            }
             targetStack = adjustStackFocus(r);
             targetStack.moveToFront();
             if (reuseTask == null) {
@@ -1751,8 +1773,13 @@
             }
         } else if (sourceRecord != null) {
             TaskRecord sourceTask = sourceRecord.task;
+            if (isLockTaskModeViolation(sourceTask)) {
+                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+            }
             targetStack = sourceTask.stack;
             targetStack.moveToFront();
+            mWindowManager.moveTaskToTop(sourceTask.taskId);
             if (!addingToTask &&
                     (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
                 // In this case, we are adding the activity to an existing
@@ -1808,6 +1835,7 @@
             r.setTask(prev != null ? prev.task
                     : targetStack.createTaskRecord(getNextTaskId(), r.info, intent, true),
                     null, true);
+            mWindowManager.moveTaskToTop(r.task.taskId);
             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                     + " in new guessed " + r.task);
         }
@@ -2110,17 +2138,18 @@
         }
     }
 
-    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
-        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
-                    if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
-                            + stacks.get(stackNdx));
-                    return;
-                }
-            }
+    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
+        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+            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.mOnTopOfHome = true;
+        }
+        task.stack.moveTaskToFrontLocked(task, null, options);
+        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
+                + task.stack);
     }
 
     ActivityStack getStack(int stackId) {
@@ -2300,6 +2329,7 @@
             }
         }
         checkReadyForSleepLocked();
+        setLockTaskModeLocked(null);
     }
 
     boolean shutdownLocked(int timeout) {
@@ -2481,7 +2511,10 @@
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = stacks.get(stackNdx);
                 stack.switchUserLocked(userId);
-                mWindowManager.moveTaskToTop(stack.topTask().taskId);
+                TaskRecord task = stack.topTask();
+                if (task != null) {
+                    mWindowManager.moveTaskToTop(task.taskId);
+                }
             }
         }
 
@@ -2492,7 +2525,10 @@
         final boolean homeInFront = stack.isHomeStack();
         if (stack.isOnHomeDisplay()) {
             moveHomeStack(homeInFront);
-            mWindowManager.moveTaskToTop(stack.topTask().taskId);
+            TaskRecord task = stack.topTask();
+            if (task != null) {
+                mWindowManager.moveTaskToTop(task.taskId);
+            }
         } else {
             // Stack was moved to another display while user was swapped out.
             resumeHomeActivity(null);
@@ -2878,6 +2914,35 @@
         return list;
     }
 
+    void setLockTaskModeLocked(TaskRecord task) {
+        if (task == null) {
+            // Take out of lock task mode.
+            mLockTaskModeTask = null;
+            return;
+        }
+        if (isLockTaskModeViolation(task)) {
+            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
+            return;
+        }
+        mLockTaskModeTask = task;
+        findTaskToMoveToFrontLocked(task, 0, null);
+        resumeTopActivitiesLocked();
+    }
+
+    boolean isLockTaskModeViolation(TaskRecord task) {
+        return mLockTaskModeTask != null && mLockTaskModeTask != task;
+    }
+
+    void endLockTaskModeIfTaskEnding(TaskRecord task) {
+        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
+            mLockTaskModeTask = null;
+        }
+    }
+
+    boolean isInLockTaskMode() {
+        return mLockTaskModeTask != null;
+    }
+
     private final class ActivityStackSupervisorHandler extends Handler {
 
         public ActivityStackSupervisorHandler(Looper looper) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index ff06513..0ddb827 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -29,6 +29,7 @@
 import android.os.Parcel;
 import android.os.Process;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.telephony.SignalStrength;
@@ -48,6 +49,8 @@
  * battery life.
  */
 public final class BatteryStatsService extends IBatteryStats.Stub {
+    static final String TAG = "BatteryStatsService";
+
     static IBatteryStats sService;
     
     final BatteryStatsImpl mStats;
@@ -66,7 +69,8 @@
         mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_radioScanningTimeout)
                 * 1000L);
-    }
+        (new WakeupReasonThread()).start();
+     }
     
     public void shutdown() {
         Slog.w("BatteryStats", "Writing battery stats before shutdown...");
@@ -105,24 +109,60 @@
         return data;
     }
     
-    public void noteStartWakelock(int uid, int pid, String name, int type) {
+    public void addIsolatedUid(int isolatedUid, int appUid) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStartWakeLocked(uid, pid, name, type);
+            mStats.addIsolatedUidLocked(isolatedUid, appUid);
+        }
+    }
+
+    public void removeIsolatedUid(int isolatedUid, int appUid) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.removeIsolatedUidLocked(isolatedUid, appUid);
+        }
+    }
+
+    public void noteEvent(int code, String name, int uid) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteEventLocked(code, name, uid);
+        }
+    }
+
+    public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
+            boolean unimportantForLogging) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging,
+                    SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
         }
     }
 
     public void noteStopWakelock(int uid, int pid, String name, int type) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStopWakeLocked(uid, pid, name, type);
+            mStats.noteStopWakeLocked(uid, pid, name, type, SystemClock.elapsedRealtime(),
+                    SystemClock.uptimeMillis());
         }
     }
 
-    public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, int type) {
+    public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
+            String historyName, int type, boolean unimportantForLogging) {
         enforceCallingPermission();
         synchronized (mStats) {
-            mStats.noteStartWakeFromSourceLocked(ws, pid, name, type);
+            mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
+                    type, unimportantForLogging);
+        }
+    }
+
+    public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name, int type,
+            WorkSource newWs, int newPid, String newName,
+            String newHistoryName, int newType, boolean newUnimportantForLogging) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, type,
+                    newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
         }
     }
 
@@ -207,7 +247,14 @@
             mStats.noteUserActivityLocked(uid, event);
         }
     }
-    
+
+    public void noteDataConnectionActive(int type, boolean active, long timestampNs) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteDataConnectionActive(type, active, timestampNs);
+        }
+    }
+
     public void notePhoneOn() {
         enforceCallingPermission();
         synchronized (mStats) {
@@ -307,6 +354,13 @@
         }
     }
 
+    public void noteWifiState(int wifiState, String accessPoint) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteWifiStateLocked(wifiState, accessPoint);
+        }
+    }
+
     public void noteBluetoothOn() {
         enforceCallingPermission();
         BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -350,6 +404,13 @@
         }
     }
     
+    public void noteBluetoothState(int bluetoothState) {
+        enforceCallingPermission();
+        synchronized (mStats) {
+            mStats.noteBluetoothStateLocked(bluetoothState);
+        }
+    }
+
     public void noteFullWifiLockAcquired(int uid) {
         enforceCallingPermission();
         synchronized (mStats) {
@@ -493,12 +554,48 @@
         mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
                 Binder.getCallingPid(), Binder.getCallingUid(), null);
     }
-    
+
+    final class WakeupReasonThread extends Thread {
+        final int[] mIrqs = new int[32];
+        final String[] mReasons = new String[32];
+
+        WakeupReasonThread() {
+            super("BatteryStats_wakeupReason");
+        }
+
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
+
+            try {
+                int num;
+                while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) {
+                    synchronized (mStats) {
+                        if (num > 0) {
+                            for (int i=0; i<num; i++) {
+                                mStats.noteWakeupReasonLocked(mReasons[i]);
+                            }
+                        } else {
+                            mStats.noteWakeupReasonLocked("unknown");
+                        }
+                    }
+                }
+            } catch (RuntimeException e) {
+                Slog.e(TAG, "Failure reading wakeup reasons", e);
+            }
+        }
+    }
+
+    private static native int nativeWaitWakeup(int[] outIrqs, String[] outReasons);
+
     private void dumpHelp(PrintWriter pw) {
         pw.println("Battery stats (batterystats) dump options:");
-        pw.println("  [--checkin] [-c] [--unplugged] [--reset] [--write] [-h] [<package.name>]");
+        pw.println("  [--checkin] [--history] [--history-start] [--unplugged] [--charged] [-c]");
+        pw.println("  [--reset] [--write] [-h] [<package.name>]");
         pw.println("  --checkin: format output for a checkin report.");
+        pw.println("  --history: show only history data.");
+        pw.println("  --history-start <num>: show only history data starting at given time offset.");
         pw.println("  --unplugged: only output data since last unplugged.");
+        pw.println("  --charged: only output data since last charged.");
         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.");
@@ -515,23 +612,37 @@
             return;
         }
 
+        int flags = 0;
         boolean isCheckin = false;
-        boolean includeHistory = false;
-        boolean isUnpluggedOnly = false;
         boolean noOutput = false;
+        long historyStart = -1;
         int reqUid = -1;
         if (args != null) {
-            for (String arg : args) {
+            for (int i=0; i<args.length; i++) {
+                String arg = args[i];
                 if ("--checkin".equals(arg)) {
                     isCheckin = true;
+                } else if ("--history".equals(arg)) {
+                    flags |= BatteryStats.DUMP_HISTORY_ONLY;
+                } else if ("--history-start".equals(arg)) {
+                    flags |= BatteryStats.DUMP_HISTORY_ONLY;
+                    i++;
+                    if (i >= args.length) {
+                        pw.println("Missing time argument for --history-since");
+                        dumpHelp(pw);
+                        return;
+                    }
+                    historyStart = Long.parseLong(args[i]);
                 } else if ("-c".equals(arg)) {
                     isCheckin = true;
-                    includeHistory = true;
+                    flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
                 } else if ("--unplugged".equals(arg)) {
-                    isUnpluggedOnly = true;
+                    flags |= BatteryStats.DUMP_UNPLUGGED_ONLY;
+                } else if ("--charged".equals(arg)) {
+                    flags |= BatteryStats.DUMP_CHARGED_ONLY;
                 } else if ("--reset".equals(arg)) {
                     synchronized (mStats) {
-                        mStats.resetAllStatsLocked();
+                        mStats.resetAllStatsCmdLocked();
                         pw.println("Battery stats reset.");
                         noOutput = true;
                     }
@@ -545,7 +656,7 @@
                     dumpHelp(pw);
                     return;
                 } else if ("-a".equals(arg)) {
-                    // fall through
+                    flags |= BatteryStats.DUMP_VERBOSE;
                 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
                     pw.println("Unknown option: " + arg);
                     dumpHelp(pw);
@@ -569,11 +680,11 @@
         if (isCheckin) {
             List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
             synchronized (mStats) {
-                mStats.dumpCheckinLocked(pw, apps, isUnpluggedOnly, includeHistory);
+                mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
             }
         } else {
             synchronized (mStats) {
-                mStats.dumpLocked(pw, isUnpluggedOnly, reqUid);
+                mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index aef9e5c..b15fa5d 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -27,7 +27,6 @@
 import android.content.IIntentReceiver;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.Bundle;
diff --git a/services/core/java/com/android/server/am/ContentProviderRecord.java b/services/core/java/com/android/server/am/ContentProviderRecord.java
index 646b7d2..ff22764 100644
--- a/services/core/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/core/java/com/android/server/am/ContentProviderRecord.java
@@ -31,7 +31,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.HashSet;
 
 final class ContentProviderRecord {
     final ActivityManagerService service;
diff --git a/services/core/java/com/android/server/am/IntentBindRecord.java b/services/core/java/com/android/server/am/IntentBindRecord.java
index 21cf266..ba6010a 100644
--- a/services/core/java/com/android/server/am/IntentBindRecord.java
+++ b/services/core/java/com/android/server/am/IntentBindRecord.java
@@ -22,8 +22,6 @@
 import android.util.ArrayMap;
 
 import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Iterator;
 
 /**
  * A particular Intent that has been bound to a Service.
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 00fa216..98999e9 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -41,6 +41,8 @@
     boolean canceled = false;
 
     String stringName;
+    String lastTagPrefix;
+    String lastTag;
     
     final static class Key {
         final int type;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index f5920c8..755a23722 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -16,7 +16,6 @@
 
 package com.android.server.am;
 
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 217a8d61..d04a6b2 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -59,6 +59,7 @@
                                 // 'persistent' is true (in which case we
                                 // are in the process of launching the app)
     ProcessStats.ProcessState baseProcessTracker;
+    BatteryStatsImpl.Uid.Proc curProcBatteryStats;
     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
@@ -94,6 +95,7 @@
     boolean hasShownUi;         // Has UI been shown in this process since it was started?
     boolean pendingUiClean;     // Want to clean up resources from showing UI?
     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
+    boolean treatLikeActivity;  // Bound using BIND_TREAT_LIKE_ACTIVITY
     boolean bad;                // True if disabled in the bad process list
     boolean killedByAm;         // True when proc has been killed by activity manager, not for RAM
     boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
@@ -250,10 +252,11 @@
                 pw.print(" lastStateTime=");
                 TimeUtils.formatDuration(lastStateTime, now, pw);
                 pw.println();
-        if (hasShownUi || pendingUiClean || hasAboveClient) {
+        if (hasShownUi || pendingUiClean || hasAboveClient || treatLikeActivity) {
             pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
                     pw.print(" pendingUiClean="); pw.print(pendingUiClean);
-                    pw.print(" hasAboveClient="); pw.println(hasAboveClient);
+                    pw.print(" hasAboveClient="); pw.print(hasAboveClient);
+                    pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
         }
         if (setIsForeground || foregroundServices || forcingToForeground != null) {
             pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
@@ -391,14 +394,15 @@
                 origBase.makeInactive();
             }
             baseProcessTracker = tracker.getProcessStateLocked(info.packageName, info.uid,
-                    processName);
+                    info.versionCode, 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);
+                ps = tracker.getProcessStateLocked(pkgList.keyAt(i), info.uid,
+                        info.versionCode, processName);
                 if (ps != baseProcessTracker) {
                     ps.makeActive();
                 }
@@ -571,7 +575,7 @@
         if (!pkgList.containsKey(pkg)) {
             if (baseProcessTracker != null) {
                 ProcessStats.ProcessState state = tracker.getProcessStateLocked(
-                        pkg, info.uid, processName);
+                        pkg, info.uid, info.versionCode, processName);
                 pkgList.put(pkg, state);
                 if (state != baseProcessTracker) {
                     state.makeActive();
@@ -618,7 +622,7 @@
                 }
                 pkgList.clear();
                 ProcessStats.ProcessState ps = tracker.getProcessStateLocked(
-                        info.packageName, info.uid, processName);
+                        info.packageName, info.uid, info.versionCode, processName);
                 pkgList.put(info.packageName, ps);
                 if (ps != baseProcessTracker) {
                     ps.makeActive();
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index e05fcda..14f3ef9 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -16,8 +16,6 @@
 
 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;
@@ -25,7 +23,6 @@
 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;
@@ -111,13 +108,14 @@
     }
 
     public ProcessStats.ProcessState getProcessStateLocked(String packageName,
-            int uid, String processName) {
-        return mProcessStats.getProcessStateLocked(packageName, uid, processName);
+            int uid, int versionCode, String processName) {
+        return mProcessStats.getProcessStateLocked(packageName, uid, versionCode, processName);
     }
 
     public ProcessStats.ServiceState getServiceStateLocked(String packageName, int uid,
-            String processName, String className) {
-        return mProcessStats.getServiceStateLocked(packageName, uid, processName, className);
+            int versionCode, String processName, String className) {
+        return mProcessStats.getServiceStateLocked(packageName, uid, versionCode, processName,
+                className);
     }
 
     public boolean isMemFactorLowered() {
@@ -137,25 +135,29 @@
             }
             mProcessStats.mMemFactor = memFactor;
             mProcessStats.mStartTime = now;
-            ArrayMap<String, SparseArray<ProcessStats.PackageState>> pmap
+            final ArrayMap<String, SparseArray<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);
+            for (int ipkg=pmap.size()-1; ipkg>=0; ipkg--) {
+                final SparseArray<SparseArray<ProcessStats.PackageState>> uids = pmap.valueAt(ipkg);
+                for (int iuid=uids.size()-1; iuid>=0; iuid--) {
+                    final SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iuid);
+                    for (int iver=vers.size()-1; iver>=0; iver--) {
+                        final ProcessStats.PackageState pkg = vers.valueAt(iver);
+                        final ArrayMap<String, ProcessStats.ServiceState> services = pkg.mServices;
+                        for (int isvc=services.size()-1; isvc>=0; isvc--) {
+                            final ProcessStats.ServiceState service = services.valueAt(isvc);
+                            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);
+                                }
                             }
-                            if (service.mBoundState != ProcessStats.STATE_NOTHING) {
-                                service.setBound(true, memFactor, now);
-                            }
-                            if (service.mExecState != ProcessStats.STATE_NOTHING) {
-                                service.setExecuting(true, memFactor, now);
-                            }
+
                         }
                     }
                 }
@@ -294,25 +296,32 @@
                             Slog.w(TAG, "  Uid " + uids.keyAt(iu) + ": " + uids.valueAt(iu));
                         }
                     }
-                    ArrayMap<String, SparseArray<ProcessStats.PackageState>> pkgMap
+                    ArrayMap<String, SparseArray<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);
+                        SparseArray<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));
+                            SparseArray<ProcessStats.PackageState> vers = uids.valueAt(iu);
+                            final int NVERS = vers.size();
+                            for (int iv=0; iv<NVERS; iv++) {
+                                Slog.w(TAG, "    Vers: " + vers.keyAt(iv));
+                                ProcessStats.PackageState pkgState = vers.valueAt(iv);
+                                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));
+
+                                }
                             }
                         }
                     }
diff --git a/services/core/java/com/android/server/am/ReceiverList.java b/services/core/java/com/android/server/am/ReceiverList.java
index fa8c1df..6ade736 100644
--- a/services/core/java/com/android/server/am/ReceiverList.java
+++ b/services/core/java/com/android/server/am/ReceiverList.java
@@ -17,11 +17,8 @@
 package com.android.server.am;
 
 import android.content.IIntentReceiver;
-import android.content.Intent;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
 
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index cb04835..363a9b7 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -329,7 +329,8 @@
         }
         if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
             tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
-                    serviceInfo.applicationInfo.uid, serviceInfo.processName, serviceInfo.name);
+                    serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode,
+                    serviceInfo.processName, serviceInfo.name);
             tracker.applyNewOwner(this);
         }
         return tracker;
@@ -346,7 +347,8 @@
         if (restartTracker == null) {
             if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
                 restartTracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
-                        serviceInfo.applicationInfo.uid, serviceInfo.processName, serviceInfo.name);
+                        serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode,
+                        serviceInfo.processName, serviceInfo.name);
             }
             if (restartTracker == null) {
                 return;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 9740812..3a43521 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -153,7 +153,7 @@
     ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
         for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
             ActivityRecord r = mActivities.get(activityNdx);
-            if (!r.finishing && r != notTop && stack.okToShow(r)) {
+            if (!r.finishing && r != notTop && stack.okToShowLocked(r)) {
                 return r;
             }
         }
diff --git a/services/core/java/com/android/server/am/UsageStatsService.java b/services/core/java/com/android/server/am/UsageStatsService.java
index 09cb344..587f949 100644
--- a/services/core/java/com/android/server/am/UsageStatsService.java
+++ b/services/core/java/com/android/server/am/UsageStatsService.java
@@ -20,7 +20,6 @@
 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;
 import android.os.IBinder;
@@ -54,7 +53,6 @@
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 6aa596d..f47d66d 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -31,7 +31,6 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.IBinder;
@@ -40,7 +39,6 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index 7786fe6..8815d0f 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -24,16 +24,13 @@
 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.Handler;
 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;
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index adf1dfc..b233943 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -28,7 +28,6 @@
 import android.hardware.usb.UsbManager;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
-import android.net.INetworkManagementEventObserver;
 import android.net.INetworkStatsService;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
@@ -52,7 +51,6 @@
 import com.android.internal.util.StateMachine;
 import com.android.server.IoThread;
 import com.android.server.net.BaseNetworkObserver;
-import com.google.android.collect.Lists;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -472,6 +470,7 @@
         mTetheredNotification.defaults &= ~Notification.DEFAULT_SOUND;
         mTetheredNotification.flags = Notification.FLAG_ONGOING_EVENT;
         mTetheredNotification.tickerText = title;
+        mTetheredNotification.visibility = Notification.VISIBILITY_PUBLIC;
         mTetheredNotification.setLatestEventInfo(mContext, title, message, pi);
 
         notificationManager.notifyAsUser(null, mTetheredNotification.icon,
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 376414b..cb1dfe4 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -29,7 +29,6 @@
 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;
@@ -64,14 +63,12 @@
 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;
 import com.android.internal.net.VpnProfile;
-import com.android.internal.util.Preconditions;
 import com.android.server.ConnectivityService.VpnCallback;
 import com.android.server.net.BaseNetworkObserver;
 
@@ -80,10 +77,8 @@
 import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.Inet4Address;
-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;
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 023bf2b..c7d2871 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -19,11 +19,13 @@
 import android.Manifest;
 import android.accounts.Account;
 import android.app.ActivityManager;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IContentService;
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
+import android.content.pm.PackageManager;
 import android.content.SyncAdapterType;
 import android.content.SyncInfo;
 import android.content.SyncRequest;
@@ -41,7 +43,6 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseIntArray;
 
@@ -315,7 +316,6 @@
         }
     }
 
-    @Override
     public void requestSync(Account account, String authority, Bundle extras) {
         ContentResolver.validateSyncExtrasBundle(extras);
         int userId = UserHandle.getCallingUserId();
@@ -345,46 +345,56 @@
      * Depending on the request, we enqueue to suit in the SyncManager.
      * @param request The request object. Validation of this object is done by its builder.
      */
-    @Override
     public void sync(SyncRequest request) {
-        Bundle extras = request.getBundle();
-        long flextime = request.getSyncFlexTime();
-        long runAtTime = request.getSyncRunTime();
         int userId = UserHandle.getCallingUserId();
-        int uId = Binder.getCallingUid();
-
+        int callerUid = 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 */);
-                    }
+            if (syncManager == null) {
+                return;
+            }
+
+            Bundle extras = request.getBundle();
+            long flextime = request.getSyncFlexTime();
+            long runAtTime = request.getSyncRunTime();
+            if (request.isPeriodic()) {
+                mContext.enforceCallingOrSelfPermission(
+                        Manifest.permission.WRITE_SYNC_SETTINGS,
+                        "no permission to write the sync settings");
+                SyncStorageEngine.EndPoint info;
+                if (!request.hasAuthority()) {
+                    // Extra permissions checking for sync service.
+                    verifySignatureForPackage(callerUid,
+                            request.getService().getPackageName(), "sync");
+                    info = new SyncStorageEngine.EndPoint(request.getService(), userId);
                 } else {
-                    Log.w(TAG, "Unrecognised sync parameters, doing nothing.");
+                    info = new SyncStorageEngine.EndPoint(
+                            request.getAccount(), request.getProvider(), userId);
+                }
+                if (runAtTime < 60) {
+                    Slog.w(TAG, "Requested poll frequency of " + runAtTime
+                            + " seconds being rounded up to 60 seconds.");
+                    runAtTime = 60;
+                }
+                // Schedule periodic sync.
+                getSyncManager().getSyncStorageEngine()
+                    .updateOrAddPeriodicSync(info, runAtTime, flextime, extras);
+            } else {
+                long beforeRuntimeMillis = (flextime) * 1000;
+                long runtimeMillis = runAtTime * 1000;
+                if (request.hasAuthority()) {
+                syncManager.scheduleSync(
+                        request.getAccount(), userId, callerUid, request.getProvider(), extras,
+                        beforeRuntimeMillis, runtimeMillis,
+                        false /* onlyThoseWithUnknownSyncableState */);
+                } else {
+                    syncManager.scheduleSync(
+                            request.getService(), userId, callerUid, extras,
+                            beforeRuntimeMillis,
+                            runtimeMillis); // Empty function.
                 }
             }
         } finally {
@@ -395,11 +405,14 @@
     /**
      * 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
+     *
+     * @param account filter the pending and active syncs to cancel using this account, or null.
+     * @param authority filter the pending and active syncs to cancel using this authority, or
+     * null.
+     * @param cname cancel syncs running on this service, or null for provider/account.
      */
     @Override
-    public void cancelSync(Account account, String authority) {
+    public void cancelSync(Account account, String authority, ComponentName cname) {
         if (authority != null && authority.length() == 0) {
             throw new IllegalArgumentException("Authority must be non-empty");
         }
@@ -411,14 +424,54 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.clearScheduledSyncOperations(account, userId, authority);
-                syncManager.cancelActiveSync(account, userId, authority);
+                SyncStorageEngine.EndPoint info;
+                if (cname == null) {
+                    info = new SyncStorageEngine.EndPoint(account, authority, userId);
+                } else {
+                    info = new SyncStorageEngine.EndPoint(cname, userId);
+                }
+                syncManager.clearScheduledSyncOperations(info);
+                syncManager.cancelActiveSync(info, null /* all syncs for this adapter */);
             }
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
+    public void cancelRequest(SyncRequest request) {
+        SyncManager syncManager = getSyncManager();
+        if (syncManager == null) return;
+        int userId = UserHandle.getCallingUserId();
+        int callerUid = Binder.getCallingUid();
+
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncStorageEngine.EndPoint info;
+            Bundle extras = new Bundle(request.getBundle());
+            if (request.hasAuthority()) {
+                Account account = request.getAccount();
+                String provider = request.getProvider();
+                info = new SyncStorageEngine.EndPoint(account, provider, userId);
+            } else {
+                // Only allowed to manipulate syncs for a service which you own.
+                ComponentName service = request.getService();
+                verifySignatureForPackage(callerUid, service.getPackageName(), "cancel");
+                info = new SyncStorageEngine.EndPoint(service, userId);
+            }
+            if (request.isPeriodic()) {
+                // Remove periodic sync.
+                mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                        "no permission to write the sync settings");
+                getSyncManager().getSyncStorageEngine().removePeriodicSync(info, extras);
+            }
+            // Cancel active syncs and clear pending syncs from the queue.
+            syncManager.cancelScheduledSyncOperation(info, extras);
+            syncManager.cancelActiveSync(info, extras);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
     /**
      * Get information about the SyncAdapters that are known to the system.
      * @return an array of SyncAdapters that have registered with the system
@@ -447,8 +500,8 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getSyncAutomatically(
-                        account, userId, providerName);
+                return syncManager.getSyncStorageEngine()
+                        .getSyncAutomatically(account, userId, providerName);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -469,8 +522,8 @@
         try {
             SyncManager syncManager = getSyncManager();
             if (syncManager != null) {
-                syncManager.getSyncStorageEngine().setSyncAutomatically(
-                        account, userId, providerName, sync);
+                syncManager.getSyncStorageEngine()
+                .setSyncAutomatically(account, userId, providerName, sync);
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -496,21 +549,22 @@
                     + " seconds being rounded up to 60 seconds.");
             pollFrequency = 60;
         }
+        long defaultFlex = SyncStorageEngine.calculateDefaultFlexTime(pollFrequency);
 
         long identityToken = clearCallingIdentity();
         try {
-            // Add default flex time to this sync.
-            PeriodicSync syncToAdd =
-                    new PeriodicSync(account, authority, extras,
-                            pollFrequency,
-                            SyncStorageEngine.calculateDefaultFlexTime(pollFrequency));
-            getSyncManager().getSyncStorageEngine().addPeriodicSync(syncToAdd, userId);
+            SyncStorageEngine.EndPoint info =
+                    new SyncStorageEngine.EndPoint(account, authority, userId);
+            getSyncManager().getSyncStorageEngine()
+                .updateOrAddPeriodicSync(info,
+                        pollFrequency,
+                        defaultFlex,
+                        extras);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    @Override
     public void removePeriodicSync(Account account, String authority, Bundle extras) {
         if (account == null) {
             throw new IllegalArgumentException("Account must not be null");
@@ -524,24 +578,18 @@
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
-            PeriodicSync syncToRemove = new PeriodicSync(account, authority, extras,
-                    0 /* Not read for removal */, 0 /* Not read for removal */);
-            getSyncManager().getSyncStorageEngine().removePeriodicSync(syncToRemove, userId);
+            getSyncManager().getSyncStorageEngine()
+                .removePeriodicSync(
+                        new SyncStorageEngine.EndPoint(account, authority, userId),
+                        extras);
         } finally {
             restoreCallingIdentity(identityToken);
         }
     }
 
-    /**
-     * TODO: Implement.
-     * @param request Sync to remove.
-     */
-    public void removeSync(SyncRequest request) {
 
-    }
-
-    @Override
-    public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName) {
+    public List<PeriodicSync> getPeriodicSyncs(Account account, String providerName,
+            ComponentName cname) {
         if (account == null) {
             throw new IllegalArgumentException("Account must not be null");
         }
@@ -551,11 +599,20 @@
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
                 "no permission to read the sync settings");
 
+        int callerUid = Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
         try {
-            return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
-                    account, userId, providerName);
+            if (cname == null) {
+                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
+                        new SyncStorageEngine.EndPoint(account, providerName, userId));
+            } else if (account == null && providerName == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "getPeriodicSyncs");
+                return getSyncManager().getSyncStorageEngine().getPeriodicSyncs(
+                        new SyncStorageEngine.EndPoint(cname, userId));
+            } else {
+                throw new IllegalArgumentException("Invalid authority specified");
+            }
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -579,7 +636,6 @@
         return -1;
     }
 
-    @Override
     public void setIsSyncable(Account account, String providerName, int syncable) {
         if (TextUtils.isEmpty(providerName)) {
             throw new IllegalArgumentException("Authority must not be empty");
@@ -600,6 +656,45 @@
         }
     }
 
+    public void setServiceActive(ComponentName cname, boolean active) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                "no permission to write the sync settings");
+        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(),
+                "setServiceActive");
+
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                syncManager.getSyncStorageEngine().setIsTargetServiceActive(
+                        cname, userId, active);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    public boolean isServiceActive(ComponentName cname) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
+                "no permission to read the sync settings");
+        verifySignatureForPackage(Binder.getCallingUid(), cname.getPackageName(),
+                "isServiceActive");
+
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine()
+                        .getIsTargetServiceActive(cname, userId);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return false;
+    }
+
     @Override
     public boolean getMasterSyncAutomatically() {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
@@ -635,17 +730,24 @@
         }
     }
 
-    public boolean isSyncActive(Account account, String authority) {
+    public boolean isSyncActive(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
         int userId = UserHandle.getCallingUserId();
-
+        int callingUid = Binder.getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
+            if (syncManager == null) {
+                return false;
+            }
+            if (cname == null) {
                 return syncManager.getSyncStorageEngine().isSyncActive(
-                        account, userId, authority);
+                        new SyncStorageEngine.EndPoint(account, authority, userId));
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callingUid, cname.getPackageName(), "isSyncActive");
+                return syncManager.getSyncStorageEngine().isSyncActive(
+                        new SyncStorageEngine.EndPoint(cname, userId));
             }
         } finally {
             restoreCallingIdentity(identityToken);
@@ -666,7 +768,7 @@
         }
     }
 
-    public SyncStatusInfo getSyncStatus(Account account, String authority) {
+    public SyncStatusInfo getSyncStatus(Account account, String authority, ComponentName cname) {
         if (TextUtils.isEmpty(authority)) {
             throw new IllegalArgumentException("Authority must not be empty");
         }
@@ -674,34 +776,52 @@
                 "no permission to read the sync stats");
 
         int userId = UserHandle.getCallingUserId();
+        int callerUid = Binder.getCallingUid();
         long identityToken = clearCallingIdentity();
         try {
             SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().getStatusByAccountAndAuthority(
-                        account, userId, authority);
+            if (syncManager == null) {
+                return null;
             }
+            SyncStorageEngine.EndPoint info;
+            if (cname == null) {
+                info = new SyncStorageEngine.EndPoint(account, authority, userId);
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "getSyncStatus");
+                info = new SyncStorageEngine.EndPoint(cname, userId);
+            } else {
+                throw new IllegalArgumentException("Must call sync status with valid authority");
+            }
+            return syncManager.getSyncStorageEngine().getStatusByAuthority(info);
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return null;
     }
 
-    public boolean isSyncPending(Account account, String authority) {
+    public boolean isSyncPending(Account account, String authority, ComponentName cname) {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
                 "no permission to read the sync stats");
 
+        int callerUid = Binder.getCallingUid();
         int userId = UserHandle.getCallingUserId();
         long identityToken = clearCallingIdentity();
+        SyncManager syncManager = getSyncManager();
+        if (syncManager == null) return false;
+
         try {
-            SyncManager syncManager = getSyncManager();
-            if (syncManager != null) {
-                return syncManager.getSyncStorageEngine().isSyncPending(account, userId, authority);
+            SyncStorageEngine.EndPoint info;
+            if (cname == null) {
+                info = new SyncStorageEngine.EndPoint(account, authority, userId);
+            } else if (account == null && authority == null) {
+                verifySignatureForPackage(callerUid, cname.getPackageName(), "isSyncPending");
+                info = new SyncStorageEngine.EndPoint(cname, userId);
+            } else {
+                throw new IllegalArgumentException("Invalid authority specified");
             }
+            return syncManager.getSyncStorageEngine().isSyncPending(info);
         } finally {
             restoreCallingIdentity(identityToken);
         }
-        return false;
     }
 
     public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
@@ -735,6 +855,30 @@
     }
 
     /**
+     * Helper to verify that the provided package name shares the same cert as the caller.
+     * @param callerUid uid of the calling process.
+     * @param packageName package to verify against package of calling application.
+     * @param tag a tag to use when throwing an exception if the signatures don't
+     * match. Cannot be null.
+     * @return true if the calling application and the provided package are signed with the same
+     * certificate.
+     */
+    private boolean verifySignatureForPackage(int callerUid, String packageName, String tag) {
+        PackageManager pm = mContext.getPackageManager();
+        try {
+            int serviceUid = pm.getApplicationInfo(packageName, 0).uid;
+            if (pm.checkSignatures(callerUid, serviceUid) == PackageManager.SIGNATURE_MATCH) {
+                return true;
+            } else {
+                throw new SecurityException(tag + ": Caller certificate does not match that for - "
+                        + packageName);
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalArgumentException(tag + ": " + packageName + " package not found.");
+        }
+    }
+
+    /**
      * Hide this class since it is not part of api,
      * but current unittest framework requires it to be public
      * @hide
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 71d8d99..026fd296 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -31,6 +31,7 @@
 import android.content.Context;
 import android.content.ISyncAdapter;
 import android.content.ISyncContext;
+import android.content.ISyncServiceAdapter;
 import android.content.ISyncStatusObserver;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -52,6 +53,7 @@
 import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.os.BatteryStats;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -59,6 +61,7 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
@@ -74,6 +77,7 @@
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.accounts.AccountManagerService;
@@ -85,10 +89,8 @@
 
 import java.io.FileDescriptor;
 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;
@@ -99,7 +101,6 @@
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
 
 /**
  * @hide
@@ -153,7 +154,7 @@
 
     private static final int INITIALIZATION_UNBIND_DELAY_MS = 5000;
 
-    private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*";
+    private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/";
     private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm";
     private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock";
 
@@ -174,6 +175,7 @@
 
     private final NotificationManager mNotificationMgr;
     private AlarmManager mAlarmService = null;
+    private final IBatteryStats mBatteryStats;
 
     private SyncStorageEngine mSyncStorageEngine;
 
@@ -202,8 +204,9 @@
                             Log.v(TAG, "Internal storage is low.");
                         }
                         mStorageIsLow = true;
-                        cancelActiveSync(null /* any account */, UserHandle.USER_ALL,
-                                null /* any authority */);
+                        cancelActiveSync(
+                                SyncStorageEngine.EndPoint.USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL,
+                                null /* any sync */);
                     } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, "Internal storage is ok.");
@@ -221,19 +224,6 @@
         }
     };
 
-    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 */, 0 /* delay */,
-                        false /* onlyThoseWithUnknownSyncableState */);
-            }
-        }
-    };
-
     private BroadcastReceiver mAccountsUpdatedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -278,16 +268,16 @@
             doDatabaseCleanup();
         }
 
+        AccountAndUser[] accounts = mRunningAccounts;
         for (ActiveSyncContext currentSyncContext : mActiveSyncContexts) {
-            if (!containsAccountAndUser(mRunningAccounts,
-                    currentSyncContext.mSyncOperation.account,
-                    currentSyncContext.mSyncOperation.userId)) {
+            if (!containsAccountAndUser(accounts,
+                    currentSyncContext.mSyncOperation.target.account,
+                    currentSyncContext.mSyncOperation.target.userId)) {
                 Log.d(TAG, "canceling sync since the account is no longer running");
                 sendSyncFinishedOrCanceledMessage(currentSyncContext,
                         null /* no result since this is a cancel */);
             }
         }
-
         // we must do this since we don't bother scheduling alarms when
         // the accounts are not set yet
         sendCheckAlarmsMessage();
@@ -316,9 +306,7 @@
                     if (Log.isLoggable(TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Reconnection detected: clearing all backoffs");
                     }
-                    synchronized(mSyncQueue) {
-                        mSyncStorageEngine.clearAllBackoffsLocked(mSyncQueue);
-                    }
+                    mSyncStorageEngine.clearAllBackoffs(mSyncQueue);
                 }
                 sendCheckAlarmsMessage();
             }
@@ -384,12 +372,17 @@
         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 /* no delay */,
-                    0 /* no delay */,
-                    false);
+            public void onSyncRequest(SyncStorageEngine.EndPoint info, int reason, Bundle extras) {
+                if (info.target_provider) {
+                    scheduleSync(info.account, info.userId, reason, info.provider, extras,
+                        0 /* no flex */,
+                        0 /* run immediately */,
+                        false);
+                } else if (info.target_service) {
+                    scheduleSync(info.service, info.userId, reason, extras,
+                            0 /* no flex */,
+                            0 /* run immediately */);
+                }
             }
         });
 
@@ -421,9 +414,6 @@
             context.registerReceiver(mBootCompletedReceiver, intentFilter);
         }
 
-        intentFilter = new IntentFilter(ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
-        context.registerReceiver(mBackgroundDataSettingChanged, intentFilter);
-
         intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
         intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
         context.registerReceiver(mStorageIntentReceiver, intentFilter);
@@ -449,6 +439,8 @@
         }
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
+                BatteryStats.SERVICE_NAME));
 
         // This WakeLock is used to ensure that we stay awake between the time that we receive
         // a sync alarm notification and when we finish processing it. We need to do this
@@ -538,11 +530,78 @@
 
     private void ensureAlarmService() {
         if (mAlarmService == null) {
-            mAlarmService = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
+            mAlarmService = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         }
     }
 
     /**
+     * Initiate a sync using the new anonymous service API.
+     * @param cname SyncService component bound to in order to perform the sync. 
+     * @param userId the id of the user whose accounts are to be synced. If userId is USER_ALL,
+     *          then all users' accounts are considered.
+     * @param uid Linux uid of the application that is performing the sync. 
+     * @param extras a Map of SyncAdapter-specific information to control
+     *          syncs of a specific provider. Cannot be null.
+     * @param beforeRunTimeMillis milliseconds before <code>runtimeMillis</code> that this sync may
+     * be run.
+     * @param runtimeMillis milliseconds from now by which this sync must be run.
+     */
+    public void scheduleSync(ComponentName cname, int userId, int uid, Bundle extras,
+            long beforeRunTimeMillis, long runtimeMillis) {
+        boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+        if (isLoggable) {
+            Log.d(TAG, "one off sync for: " + cname + " " + extras.toString());
+        }
+
+        Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
+        if (expedited) {
+            runtimeMillis = -1; // this means schedule at the front of the queue
+        }
+
+        final boolean ignoreSettings =
+                extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
+        int source = SyncStorageEngine.SOURCE_SERVICE;
+        boolean isEnabled = mSyncStorageEngine.getIsTargetServiceActive(cname, userId);
+        // Only schedule this sync if
+        //   - we've explicitly been told to ignore settings.
+        //   - global sync is enabled for this user.
+        boolean syncAllowed =
+                ignoreSettings
+                || mSyncStorageEngine.getMasterSyncAutomatically(userId);
+        if (!syncAllowed) {
+            if (isLoggable) {
+                Log.d(TAG, "scheduleSync: sync of " + cname + " not allowed, dropping request.");
+            }
+            return;
+        }
+        if (!isEnabled) {
+            if (isLoggable) {
+                Log.d(TAG, "scheduleSync: " + cname + " is not enabled, dropping request");
+            }
+            return;
+        }
+        SyncStorageEngine.EndPoint info = new SyncStorageEngine.EndPoint(cname, userId);
+        Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+        long delayUntil = mSyncStorageEngine.getDelayUntilTime(info);
+        final long backoffTime = backoff != null ? backoff.first : 0;
+        if (isLoggable) {
+                Log.v(TAG, "schedule Sync:"
+                        + ", delay until " + delayUntil
+                        + ", run by " + runtimeMillis
+                        + ", flex " + beforeRunTimeMillis
+                        + ", source " + source
+                        + ", sync service " + cname
+                        + ", extras " + extras);
+        }
+        scheduleSyncOperation(
+                new SyncOperation(cname, userId, uid, source, extras,
+                        runtimeMillis /* runtime */,
+                        beforeRunTimeMillis /* flextime */,
+                        backoffTime,
+                        delayUntil));
+    }
+
+    /**
      * Initiate a sync. This can start a sync for all providers
      * (pass null to url, set onlyTicklable to false), only those
      * providers that are marked as ticklable (pass null to url,
@@ -588,9 +647,6 @@
             long runtimeMillis, boolean onlyThoseWithUnkownSyncableState) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
-        final boolean backgroundDataUsageAllowed = !mBootCompleted ||
-                getConnectivityManager().getBackgroundDataSetting();
-
         if (extras == null) {
             extras = new Bundle();
         }
@@ -607,8 +663,6 @@
         if (requestedAccount != null && userId != UserHandle.USER_ALL) {
             accounts = new AccountAndUser[] { new AccountAndUser(requestedAccount, userId) };
         } else {
-            // if the accounts aren't configured yet then we can't support an account-less
-            // sync request
             accounts = mRunningAccounts;
             if (accounts.length == 0) {
                 if (isLoggable) {
@@ -683,12 +737,10 @@
                     continue;
                 }
 
-                // always allow if the isSyncable state is unknown
                 boolean syncAllowed =
-                        (isSyncable < 0)
+                        (isSyncable < 0) // always allow if the isSyncable state is unknown
                         || ignoreSettings
-                        || (backgroundDataUsageAllowed
-                                && mSyncStorageEngine.getMasterSyncAutomatically(account.userId)
+                        || (mSyncStorageEngine.getMasterSyncAutomatically(account.userId)
                                 && mSyncStorageEngine.getSyncAutomatically(account.account,
                                         account.userId, authority));
                 if (!syncAllowed) {
@@ -698,11 +750,12 @@
                     }
                     continue;
                 }
-
-                Pair<Long, Long> backoff = mSyncStorageEngine
-                        .getBackoff(account.account, account.userId, authority);
-                long delayUntil = mSyncStorageEngine.getDelayUntilTime(account.account,
-                        account.userId, authority);
+                SyncStorageEngine.EndPoint info =
+                        new SyncStorageEngine.EndPoint(
+                                account.account, authority, account.userId);
+                Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+                long delayUntil =
+                        mSyncStorageEngine.getDelayUntilTime(info);
                 final long backoffTime = backoff != null ? backoff.first : 0;
                 if (isSyncable < 0) {
                     // Initialisation sync.
@@ -712,6 +765,7 @@
                         Log.v(TAG, "schedule initialisation Sync:"
                                 + ", delay until " + delayUntil
                                 + ", run by " + 0
+                                + ", flex " + 0
                                 + ", source " + source
                                 + ", account " + account
                                 + ", authority " + authority
@@ -787,13 +841,12 @@
         mSyncHandler.sendMessage(msg);
     }
 
-    private void sendCancelSyncsMessage(final Account account, final int userId,
-            final String authority) {
+    private void sendCancelSyncsMessage(final SyncStorageEngine.EndPoint info, Bundle extras) {
         if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CANCEL");
         Message msg = mSyncHandler.obtainMessage();
         msg.what = SyncHandler.MESSAGE_CANCEL;
-        msg.obj = Pair.create(account, authority);
-        msg.arg1 = userId;
+        msg.setData(extras);
+        msg.obj = info;
         mSyncHandler.sendMessage(msg);
     }
 
@@ -816,10 +869,11 @@
     }
 
     private void clearBackoffSetting(SyncOperation op) {
-        mSyncStorageEngine.setBackoff(op.account, op.userId, op.authority,
-                SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
+        mSyncStorageEngine.setBackoff(op.target,
+                SyncStorageEngine.NOT_IN_BACKOFF_MODE,
+                SyncStorageEngine.NOT_IN_BACKOFF_MODE);
         synchronized (mSyncQueue) {
-            mSyncQueue.onBackoffChanged(op.account, op.userId, op.authority, 0);
+            mSyncQueue.onBackoffChanged(op.target, 0);
         }
     }
 
@@ -829,7 +883,7 @@
         final long now = SystemClock.elapsedRealtime();
 
         final Pair<Long, Long> previousSettings =
-                mSyncStorageEngine.getBackoff(op.account, op.userId, op.authority);
+                mSyncStorageEngine.getBackoff(op.target);
         long newDelayInMs = -1;
         if (previousSettings != null) {
             // don't increase backoff before current backoff is expired. This will happen for op's
@@ -860,14 +914,12 @@
 
         final long backoff = now + newDelayInMs;
 
-        mSyncStorageEngine.setBackoff(op.account, op.userId, op.authority,
-                backoff, newDelayInMs);
-
+        mSyncStorageEngine.setBackoff(op.target, backoff, newDelayInMs);
         op.backoff = backoff;
         op.updateEffectiveRunTime();
 
         synchronized (mSyncQueue) {
-            mSyncQueue.onBackoffChanged(op.account, op.userId, op.authority, backoff);
+            mSyncQueue.onBackoffChanged(op.target, backoff);
         }
     }
 
@@ -880,20 +932,20 @@
         } else {
             newDelayUntilTime = 0;
         }
-        mSyncStorageEngine
-                .setDelayUntilTime(op.account, op.userId, op.authority, newDelayUntilTime);
+        mSyncStorageEngine.setDelayUntilTime(op.target, newDelayUntilTime);
         synchronized (mSyncQueue) {
-            mSyncQueue.onDelayUntilTimeChanged(op.account, op.authority, newDelayUntilTime);
+            mSyncQueue.onDelayUntilTimeChanged(op.target, newDelayUntilTime);
         }
     }
 
     /**
-     * Cancel the active sync if it matches the authority and account.
-     * @param account limit the cancelations to syncs with this account, if non-null
-     * @param authority limit the cancelations to syncs with this authority, if non-null
+     * Cancel the active sync if it matches the target.
+     * @param info object containing info about which syncs to cancel. The target can
+     * have null account/provider info to specify all accounts/providers.
+     * @param extras if non-null, specifies the exact sync to remove.
      */
-    public void cancelActiveSync(Account account, int userId, String authority) {
-        sendCancelSyncsMessage(account, userId, authority);
+    public void cancelActiveSync(SyncStorageEngine.EndPoint info, Bundle extras) {
+        sendCancelSyncsMessage(info, extras);
     }
 
     /**
@@ -922,24 +974,40 @@
 
     /**
      * Remove scheduled sync operations.
-     * @param account limit the removals to operations with this account, if non-null
-     * @param authority limit the removals to operations with this authority, if non-null
+     * @param info limit the removals to operations that match this target. The target can
+     * have null account/provider info to specify all accounts/providers.
      */
-    public void clearScheduledSyncOperations(Account account, int userId, String authority) {
+    public void clearScheduledSyncOperations(SyncStorageEngine.EndPoint info) {
         synchronized (mSyncQueue) {
-            mSyncQueue.remove(account, userId, authority);
+            mSyncQueue.remove(info, null /* all operations */);
         }
-        mSyncStorageEngine.setBackoff(account, userId, authority,
+        mSyncStorageEngine.setBackoff(info,
                 SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
     }
 
+    /**
+     * Remove a specified sync, if it exists.
+     * @param info Authority for which the sync is to be removed.
+     * @param extras extras bundle to uniquely identify sync.
+     */
+    public void cancelScheduledSyncOperation(SyncStorageEngine.EndPoint info, Bundle extras) {
+        synchronized (mSyncQueue) {
+            mSyncQueue.remove(info, extras);
+        }
+        // Reset the back-off if there are no more syncs pending.
+        if (!mSyncStorageEngine.isSyncPending(info)) {
+            mSyncStorageEngine.setBackoff(info,
+                    SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
+        }
+    }
+
     void maybeRescheduleSync(SyncResult syncResult, SyncOperation operation) {
         boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG);
         if (isLoggable) {
             Log.d(TAG, "encountered error(s) during the sync: " + syncResult + ", " + operation);
         }
 
-        operation = new SyncOperation(operation);
+        operation = new SyncOperation(operation, 0L /* newRunTimeFromNow */);
 
         // The SYNC_EXTRAS_IGNORE_BACKOFF only applies to the first attempt to sync a given
         // request. Retries of the request will always honor the backoff, so clear the
@@ -948,25 +1016,29 @@
             operation.extras.remove(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF);
         }
 
-        // If this sync aborted because the internal sync loop retried too many times then
-        //   don't reschedule. Otherwise we risk getting into a retry loop.
-        // If the operation succeeded to some extent then retry immediately.
-        // If this was a two-way sync then retry soft errors with an exponential backoff.
-        // If this was an upward sync then schedule a two-way sync immediately.
-        // Otherwise do not reschedule.
         if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY, false)) {
-            Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified "
-                    + operation);
+            if (isLoggable) {
+                Log.d(TAG, "not retrying sync operation because SYNC_EXTRAS_DO_NOT_RETRY was specified "
+                        + operation);
+            }
         } else if (operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false)
                 && !syncResult.syncAlreadyInProgress) {
+            // If this was an upward sync then schedule a two-way sync immediately.
             operation.extras.remove(ContentResolver.SYNC_EXTRAS_UPLOAD);
-            Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
-                    + "encountered an error: " + operation);
+            if (isLoggable) {
+                Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
+                        + "encountered an error: " + operation);
+            }
             scheduleSyncOperation(operation);
         } else if (syncResult.tooManyRetries) {
-            Log.d(TAG, "not retrying sync operation because it retried too many times: "
-                    + operation);
+            // If this sync aborted because the internal sync loop retried too many times then
+            //   don't reschedule. Otherwise we risk getting into a retry loop.
+            if (isLoggable) {
+                Log.d(TAG, "not retrying sync operation because it retried too many times: "
+                        + operation);
+            }
         } else if (syncResult.madeSomeProgress()) {
+            // If the operation succeeded to some extent then retry immediately.
             if (isLoggable) {
                 Log.d(TAG, "retrying sync operation because even though it had an error "
                         + "it achieved some success");
@@ -979,19 +1051,18 @@
             }
             scheduleSyncOperation(
                 new SyncOperation(
-                    operation.account, operation.userId,
-                    operation.reason,
-                    operation.syncSource,
-                    operation.authority, operation.extras,
-                    DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000, operation.flexTime,
-                    operation.backoff, operation.delayUntil, operation.allowParallelSyncs));
+                        operation,
+                        DELAY_RETRY_SYNC_IN_PROGRESS_IN_SECONDS * 1000 /* newRunTimeFromNow */)
+                );
         } else if (syncResult.hasSoftError()) {
+            // If this was a two-way sync then retry soft errors with an exponential backoff.
             if (isLoggable) {
                 Log.d(TAG, "retrying sync operation because it encountered a soft error: "
                         + operation);
             }
             scheduleSyncOperation(operation);
         } else {
+            // Otherwise do not reschedule.
             Log.d(TAG, "not retrying sync operation because the error is a hard error: "
                     + operation);
         }
@@ -1024,9 +1095,12 @@
         updateRunningAccounts();
 
         cancelActiveSync(
-                null /* any account */,
-                userId,
-                null /* any authority */);
+                new SyncStorageEngine.EndPoint(
+                        null /* any account */,
+                        null /* any authority */,
+                        userId),
+                        null /* any sync. */
+                );
     }
 
     private void onUserRemoved(int userId) {
@@ -1035,7 +1109,7 @@
         // Clean up the storage engine database
         mSyncStorageEngine.doDatabaseCleanup(new Account[0], userId);
         synchronized (mSyncQueue) {
-            mSyncQueue.removeUser(userId);
+            mSyncQueue.removeUserLocked(userId);
         }
     }
 
@@ -1047,6 +1121,7 @@
         final SyncOperation mSyncOperation;
         final long mHistoryRowId;
         ISyncAdapter mSyncAdapter;
+        ISyncServiceAdapter mSyncServiceAdapter;
         final long mStartTime;
         long mTimeoutStartTime;
         boolean mBound;
@@ -1054,6 +1129,7 @@
         final int mSyncAdapterUid;
         SyncInfo mSyncInfo;
         boolean mIsLinkedToDeath = false;
+        String mEventName;
 
         /**
          * Create an ActiveSyncContext for an impending sync and grab the wakelock for that
@@ -1072,10 +1148,10 @@
             mSyncOperation = syncOperation;
             mHistoryRowId = historyRowId;
             mSyncAdapter = null;
+            mSyncServiceAdapter = null;
             mStartTime = SystemClock.elapsedRealtime();
             mTimeoutStartTime = mStartTime;
-            mSyncWakeLock = mSyncHandler.getSyncWakeLock(
-                    mSyncOperation.account, mSyncOperation.authority);
+            mSyncWakeLock = mSyncHandler.getSyncWakeLock(mSyncOperation);
             mSyncWakeLock.setWorkSource(new WorkSource(syncAdapterUid));
             mSyncWakeLock.acquire();
         }
@@ -1102,7 +1178,7 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             Message msg = mSyncHandler.obtainMessage();
             msg.what = SyncHandler.MESSAGE_SERVICE_CONNECTED;
-            msg.obj = new ServiceConnectionData(this, ISyncAdapter.Stub.asInterface(service));
+            msg.obj = new ServiceConnectionData(this, service);
             mSyncHandler.sendMessage(msg);
         }
 
@@ -1113,13 +1189,13 @@
             mSyncHandler.sendMessage(msg);
         }
 
-        boolean bindToSyncAdapter(RegisteredServicesCache.ServiceInfo info, int userId) {
+        boolean bindToSyncAdapter(ComponentName serviceComponent, int userId) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.d(TAG, "bindToSyncAdapter: " + info.componentName + ", connection " + this);
+                Log.d(TAG, "bindToSyncAdapter: " + serviceComponent + ", connection " + this);
             }
             Intent intent = new Intent();
             intent.setAction("android.content.SyncAdapter");
-            intent.setComponent(info.componentName);
+            intent.setComponent(serviceComponent);
             intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
                     com.android.internal.R.string.sync_binding_label);
             intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser(
@@ -1129,9 +1205,16 @@
             final boolean bindResult = mContext.bindServiceAsUser(intent, this,
                     Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND
                     | Context.BIND_ALLOW_OOM_MANAGEMENT,
-                    new UserHandle(mSyncOperation.userId));
+                    new UserHandle(mSyncOperation.target.userId));
             if (!bindResult) {
                 mBound = false;
+            } else {
+                try {
+                    mEventName = mSyncOperation.wakeLockName();
+                    mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_SYNC_START,
+                            mEventName, mSyncAdapterUid);
+                } catch (RemoteException e) {
+                }
             }
             return bindResult;
         }
@@ -1147,12 +1230,16 @@
             if (mBound) {
                 mBound = false;
                 mContext.unbindService(this);
+                try {
+                    mBatteryStats.noteEvent(BatteryStats.HistoryItem.EVENT_SYNC_FINISH,
+                            mEventName, mSyncAdapterUid);
+                } catch (RemoteException e) {
+                }
             }
             mSyncWakeLock.release();
             mSyncWakeLock.setWorkSource(null);
         }
 
-        @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
             toString(sb);
@@ -1291,11 +1378,13 @@
                 int row = table.getNumRows();
                 Pair<AuthorityInfo, SyncStatusInfo> syncAuthoritySyncStatus = 
                         mSyncStorageEngine.getCopyOfAuthorityWithSyncStatus(
-                                account.account, account.userId, syncAdapterType.type.authority);
+                                new SyncStorageEngine.EndPoint(
+                                        account.account,
+                                        syncAdapterType.type.authority,
+                                        account.userId));
                 SyncStorageEngine.AuthorityInfo settings = syncAuthoritySyncStatus.first;
                 SyncStatusInfo status = syncAuthoritySyncStatus.second;
-
-                String authority = settings.authority;
+                String authority = settings.target.provider;
                 if (authority.length() > 50) {
                     authority = authority.substring(authority.length() - 50);
                 }
@@ -1416,14 +1505,25 @@
             int maxAuthority = 0;
             int maxAccount = 0;
             for (SyncStorageEngine.SyncHistoryItem item : items) {
-                SyncStorageEngine.AuthorityInfo authority
+                SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.target.target_provider) {
+                        authorityName = authorityInfo.target.provider;
+                        accountKey = authorityInfo.target.account.name + "/"
+                                + authorityInfo.target.account.type
+                                + " u" + authorityInfo.target.userId;
+                    } else if (authorityInfo.target.target_service) {
+                        authorityName = authorityInfo.target.service.getPackageName() + "/"
+                                + authorityInfo.target.service.getClassName()
+                                + " u" + authorityInfo.target.userId;
+                        accountKey = "no account";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1544,14 +1644,25 @@
             final PackageManager pm = mContext.getPackageManager();
             for (int i = 0; i < N; i++) {
                 SyncStorageEngine.SyncHistoryItem item = items.get(i);
-                SyncStorageEngine.AuthorityInfo authority
+                SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.target.target_provider) {
+                        authorityName = authorityInfo.target.provider;
+                        accountKey = authorityInfo.target.account.name + "/"
+                                + authorityInfo.target.account.type
+                                + " u" + authorityInfo.target.userId;
+                    } else if (authorityInfo.target.target_service) {
+                        authorityName = authorityInfo.target.service.getPackageName() + "/"
+                                + authorityInfo.target.service.getClassName()
+                                + " u" + authorityInfo.target.userId;
+                        accountKey = "none";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1610,14 +1721,25 @@
                 if (extras == null || extras.size() == 0) {
                     continue;
                 }
-                final SyncStorageEngine.AuthorityInfo authority
+                final SyncStorageEngine.AuthorityInfo authorityInfo
                         = mSyncStorageEngine.getAuthority(item.authorityId);
                 final String authorityName;
                 final String accountKey;
-                if (authority != null) {
-                    authorityName = authority.authority;
-                    accountKey = authority.account.name + "/" + authority.account.type
-                            + " u" + authority.userId;
+                if (authorityInfo != null) {
+                    if (authorityInfo.target.target_provider) {
+                        authorityName = authorityInfo.target.provider;
+                        accountKey = authorityInfo.target.account.name + "/"
+                                + authorityInfo.target.account.type
+                                + " u" + authorityInfo.target.userId;
+                    } else if (authorityInfo.target.target_service) {
+                        authorityName = authorityInfo.target.service.getPackageName() + "/"
+                                + authorityInfo.target.service.getClassName()
+                                + " u" + authorityInfo.target.userId;
+                        accountKey = "none";
+                    } else {
+                        authorityName = "Unknown";
+                        accountKey = "Unknown";
+                    }
                 } else {
                     authorityName = "Unknown";
                     accountKey = "Unknown";
@@ -1761,10 +1883,11 @@
 
     class ServiceConnectionData {
         public final ActiveSyncContext activeSyncContext;
-        public final ISyncAdapter syncAdapter;
-        ServiceConnectionData(ActiveSyncContext activeSyncContext, ISyncAdapter syncAdapter) {
+        public final IBinder adapter;
+
+        ServiceConnectionData(ActiveSyncContext activeSyncContext, IBinder adapter) {
             this.activeSyncContext = activeSyncContext;
-            this.syncAdapter = syncAdapter;
+            this.adapter = adapter;
         }
     }
 
@@ -1784,11 +1907,11 @@
         public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo();
         private Long mAlarmScheduleTime = null;
         public final SyncTimeTracker mSyncTimeTracker = new SyncTimeTracker();
-        private final HashMap<Pair<Account, String>, PowerManager.WakeLock> mWakeLocks =
-                Maps.newHashMap();
+        private final HashMap<String, PowerManager.WakeLock> mWakeLocks = Maps.newHashMap();
+
         private List<Message> mBootQueue = new ArrayList<Message>();
 
-        public void onBootCompleted() {
+      public void onBootCompleted() {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "Boot completed, clearing boot queue.");
             }
@@ -1803,12 +1926,11 @@
             }
         }
 
-        private PowerManager.WakeLock getSyncWakeLock(Account account, String authority) {
-            final Pair<Account, String> wakeLockKey = Pair.create(account, authority);
+        private PowerManager.WakeLock getSyncWakeLock(SyncOperation operation) {
+            final String wakeLockKey = operation.wakeLockName();
             PowerManager.WakeLock wakeLock = mWakeLocks.get(wakeLockKey);
             if (wakeLock == null) {
-                final String name = SYNC_WAKE_LOCK_PREFIX + "/" + authority + "/" + account.type
-                        + "/" + account.name;
+                final String name = SYNC_WAKE_LOCK_PREFIX + wakeLockKey;
                 wakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name);
                 wakeLock.setReferenceCounted(false);
                 mWakeLocks.put(wakeLockKey, wakeLock);
@@ -1861,7 +1983,6 @@
             super(looper);
         }
 
-        @Override
         public void handleMessage(Message msg) {
             if (tryEnqueueMessageUntilReadyToRun(msg)) {
                 return;
@@ -1881,12 +2002,13 @@
                 earliestFuturePollTime = scheduleReadyPeriodicSyncs();
                 switch (msg.what) {
                     case SyncHandler.MESSAGE_CANCEL: {
-                        Pair<Account, String> payload = (Pair<Account, String>) msg.obj;
+                        SyncStorageEngine.EndPoint payload = (SyncStorageEngine.EndPoint) msg.obj;
+                        Bundle extras = msg.peekData();
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CANCEL: "
-                                    + payload.first + ", " + payload.second);
+                                    + payload + " bundle: " + extras);
                         }
-                        cancelActiveSyncLocked(payload.first, msg.arg1, payload.second);
+                        cancelActiveSyncLocked(payload, extras);
                         nextPendingSyncTime = maybeStartNextSyncLocked();
                         break;
                     }
@@ -1895,35 +2017,38 @@
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_FINISHED");
                         }
-                        SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload)msg.obj;
+                        SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload) msg.obj;
                         if (!isSyncStillActive(payload.activeSyncContext)) {
                             Log.d(TAG, "handleSyncHandlerMessage: dropping since the "
                                     + "sync is no longer active: "
                                     + payload.activeSyncContext);
                             break;
                         }
-                        runSyncFinishedOrCanceledLocked(payload.syncResult, payload.activeSyncContext);
+                        runSyncFinishedOrCanceledLocked(payload.syncResult,
+                                payload.activeSyncContext);
 
                         // since a sync just finished check if it is time to start a new sync
                         nextPendingSyncTime = maybeStartNextSyncLocked();
                         break;
 
                     case SyncHandler.MESSAGE_SERVICE_CONNECTED: {
-                        ServiceConnectionData msgData = (ServiceConnectionData)msg.obj;
+                        ServiceConnectionData msgData = (ServiceConnectionData) msg.obj;
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_CONNECTED: "
                                     + msgData.activeSyncContext);
                         }
                         // check that this isn't an old message
                         if (isSyncStillActive(msgData.activeSyncContext)) {
-                            runBoundToSyncAdapter(msgData.activeSyncContext, msgData.syncAdapter);
+                            runBoundToAdapter(
+                                    msgData.activeSyncContext,
+                                    msgData.adapter);
                         }
                         break;
                     }
 
                     case SyncHandler.MESSAGE_SERVICE_DISCONNECTED: {
                         final ActiveSyncContext currentSyncContext =
-                                ((ServiceConnectionData)msg.obj).activeSyncContext;
+                                ((ServiceConnectionData) msg.obj).activeSyncContext;
                         if (Log.isLoggable(TAG, Log.VERBOSE)) {
                             Log.d(TAG, "handleSyncHandlerMessage: MESSAGE_SERVICE_DISCONNECTED: "
                                     + currentSyncContext);
@@ -1932,12 +2057,15 @@
                         if (isSyncStillActive(currentSyncContext)) {
                             // cancel the sync if we have a syncadapter, which means one is
                             // outstanding
-                            if (currentSyncContext.mSyncAdapter != null) {
-                                try {
+                            try {
+                                if (currentSyncContext.mSyncAdapter != null) {
                                     currentSyncContext.mSyncAdapter.cancelSync(currentSyncContext);
-                                } catch (RemoteException e) {
-                                    // we don't need to retry this in this case
+                                } else if (currentSyncContext.mSyncServiceAdapter != null) {
+                                    currentSyncContext.mSyncServiceAdapter
+                                        .cancelSync(currentSyncContext);
                                 }
+                            } catch (RemoteException e) {
+                                // We don't need to retry this in this case.
                             }
 
                             // pretend that the sync failed with an IOException,
@@ -1982,9 +2110,46 @@
             }
         }
 
+        private boolean isDispatchable(SyncStorageEngine.EndPoint target) {
+            final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+            if (target.target_provider) {
+                // skip the sync if the account of this operation no longer exists
+                AccountAndUser[] accounts = mRunningAccounts;
+                if (!containsAccountAndUser(
+                        accounts, target.account, target.userId)) {
+                    return false;
+                }
+                if (!mSyncStorageEngine.getMasterSyncAutomatically(target.userId)
+                        || !mSyncStorageEngine.getSyncAutomatically(
+                                target.account,
+                                target.userId,
+                                target.provider)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Not scheduling periodic operation: sync turned off.");
+                    }
+                    return false;
+                }
+                if (getIsSyncable(target.account, target.userId, target.provider)
+                        == 0) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Not scheduling periodic operation: isSyncable == 0.");
+                    }
+                    return false;
+                }
+            } else if (target.target_service) {
+                if (mSyncStorageEngine.getIsTargetServiceActive(target.service, target.userId)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "   Not scheduling periodic operation: isEnabled == 0.");
+                    }
+                    return false;
+                }
+            }
+            return true;
+        }
+
         /**
          * Turn any periodic sync operations that are ready to run into pending sync operations.
-         * @return the desired start time of the earliest future  periodic sync operation,
+         * @return the desired start time of the earliest future periodic sync operation,
          * in milliseconds since boot
          */
         private long scheduleReadyPeriodicSyncs() {
@@ -1992,14 +2157,7 @@
             if (isLoggable) {
                 Log.v(TAG, "scheduleReadyPeriodicSyncs");
             }
-            final boolean backgroundDataUsageAllowed =
-                    getConnectivityManager().getBackgroundDataSetting();
             long earliestFuturePollTime = Long.MAX_VALUE;
-            if (!backgroundDataUsageAllowed) {
-                return earliestFuturePollTime;
-            }
-
-            AccountAndUser[] accounts = mRunningAccounts;
 
             final long nowAbsolute = System.currentTimeMillis();
             final long shiftedNowAbsolute = (0 < nowAbsolute - mSyncRandomOffsetMillis)
@@ -2010,40 +2168,31 @@
             for (Pair<AuthorityInfo, SyncStatusInfo> info : infos) {
                 final AuthorityInfo authorityInfo = info.first;
                 final SyncStatusInfo status = info.second;
-                if (TextUtils.isEmpty(authorityInfo.authority)) {
-                    Log.e(TAG, "Got an empty provider string. Skipping: " + authorityInfo);
-                    continue;
-                }
-                // skip the sync if the account of this operation no longer exists
-                if (!containsAccountAndUser(
-                        accounts, authorityInfo.account, authorityInfo.userId)) {
+
+                if (TextUtils.isEmpty(authorityInfo.target.provider)) {
+                    Log.e(TAG, "Got an empty provider string. Skipping: "
+                        + authorityInfo.target.provider);
                     continue;
                 }
 
-                if (!mSyncStorageEngine.getMasterSyncAutomatically(authorityInfo.userId)
-                        || !mSyncStorageEngine.getSyncAutomatically(
-                                authorityInfo.account, authorityInfo.userId,
-                                authorityInfo.authority)) {
-                    continue;
-                }
-
-                if (getIsSyncable(
-                        authorityInfo.account, authorityInfo.userId, authorityInfo.authority)
-                        == 0) {
+                if (!isDispatchable(authorityInfo.target)) {
                     continue;
                 }
 
                 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;
+                    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.
                     final long lastPollTimeAbsolute = status.getPeriodicSyncTime(i);
+                    final long shiftedLastPollTimeAbsolute =
+                            (0 < lastPollTimeAbsolute - mSyncRandomOffsetMillis) ?
+                                    (lastPollTimeAbsolute - mSyncRandomOffsetMillis) : 0;
                     long remainingMillis
                         = periodInMillis - (shiftedNowAbsolute % periodInMillis);
                     long timeSinceLastRunMillis
@@ -2054,12 +2203,13 @@
                     boolean runEarly = remainingMillis <= flexInMillis
                             && timeSinceLastRunMillis > periodInMillis - flexInMillis;
                     if (isLoggable) {
-                        Log.v(TAG, "sync: " + i + " for " + authorityInfo.authority + "."
+                        Log.v(TAG, "sync: " + i + " for " + authorityInfo.target + "."
                         + " period: " + (periodInMillis)
                         + " flex: " + (flexInMillis)
                         + " remaining: " + (remainingMillis)
                         + " time_since_last: " + timeSinceLastRunMillis
                         + " last poll absol: " + lastPollTimeAbsolute
+                        + " last poll shifed: " + shiftedLastPollTimeAbsolute
                         + " shifted now: " + shiftedNowAbsolute
                         + " run_early: " + runEarly);
                     }
@@ -2073,41 +2223,49 @@
                      * 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 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 (runEarly // Case 4
-                            || remainingMillis == periodInMillis // Case 1
+                    if (remainingMillis == periodInMillis // Case 1
                             || lastPollTimeAbsolute > nowAbsolute // Case 2
-                            || timeSinceLastRunMillis >= periodInMillis) { // Case 3
+                            || timeSinceLastRunMillis >= periodInMillis // Case 3
+                            || runEarly) { // Case 4
                         // Sync now
-                        
-                        final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
-                                authorityInfo.account, authorityInfo.userId,
-                                authorityInfo.authority);
-                        final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-                        syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                                SyncAdapterType.newKey(
-                                        authorityInfo.authority, authorityInfo.account.type),
-                                authorityInfo.userId);
-                        if (syncAdapterInfo == null) {
-                            continue;
-                        }
+                        SyncStorageEngine.EndPoint target = authorityInfo.target;
+                        final Pair<Long, Long> backoff =
+                                mSyncStorageEngine.getBackoff(target);
                         mSyncStorageEngine.setPeriodicSyncTime(authorityInfo.ident,
                                 authorityInfo.periodicSyncs.get(i), nowAbsolute);
-                        scheduleSyncOperation(
-                                new SyncOperation(authorityInfo.account, authorityInfo.userId,
-                                        SyncOperation.REASON_PERIODIC,
-                                        SyncStorageEngine.SOURCE_PERIODIC,
-                                        authorityInfo.authority, extras,
-                                        0 /* runtime */, 0 /* flex */,
-                                                backoff != null ? backoff.first : 0,
-                                        mSyncStorageEngine.getDelayUntilTime(
-                                                authorityInfo.account, authorityInfo.userId,
-                                                authorityInfo.authority),
-                                        syncAdapterInfo.type.allowParallelSyncs()));
-                        
+
+                        if (target.target_provider) {
+                            final RegisteredServicesCache.ServiceInfo<SyncAdapterType>
+                                syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                                    SyncAdapterType.newKey(
+                                            target.provider, target.account.type),
+                                    target.userId);
+                            if (syncAdapterInfo == null) {
+                                continue;
+                            }
+                            scheduleSyncOperation(
+                                    new SyncOperation(target.account, target.userId,
+                                            SyncOperation.REASON_PERIODIC,
+                                            SyncStorageEngine.SOURCE_PERIODIC,
+                                            target.provider, extras,
+                                            0 /* runtime */, 0 /* flex */,
+                                            backoff != null ? backoff.first : 0,
+                                            mSyncStorageEngine.getDelayUntilTime(target),
+                                            syncAdapterInfo.type.allowParallelSyncs()));
+                        } else if (target.target_service) {
+                            scheduleSyncOperation(
+                                    new SyncOperation(target.service, target.userId,
+                                            SyncOperation.REASON_PERIODIC,
+                                            SyncStorageEngine.SOURCE_PERIODIC,
+                                            extras,
+                                            0 /* runtime */,
+                                            0 /* flex */,
+                                            backoff != null ? backoff.first : 0,
+                                            mSyncStorageEngine.getDelayUntilTime(target)));
+                        }
                     }
                     // Compute when this periodic sync should next run.
                     long nextPollTimeAbsolute;
@@ -2154,8 +2312,7 @@
 
             // If the accounts aren't known yet then we aren't ready to run. We will be kicked
             // when the account lookup request does complete.
-            AccountAndUser[] accounts = mRunningAccounts;
-            if (accounts == INITIAL_ACCOUNTS_ARRAY) {
+            if (mRunningAccounts == INITIAL_ACCOUNTS_ARRAY) {
                 if (isLoggable) {
                     Log.v(TAG, "maybeStartNextSync: accounts not known, skipping");
                 }
@@ -2165,9 +2322,6 @@
             // Otherwise consume SyncOperations from the head of the SyncQueue until one is
             // found that is runnable (not disabled, etc). If that one is ready to run then
             // start it, otherwise just get out.
-            final boolean backgroundDataUsageAllowed =
-                    getConnectivityManager().getBackgroundDataSetting();
-
             final long now = SystemClock.elapsedRealtime();
 
             // will be set to the next time that a sync should be considered for running
@@ -2189,40 +2343,23 @@
                 while (operationIterator.hasNext()) {
                     final SyncOperation op = operationIterator.next();
 
-                    // 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.
-                    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 is not running, drop the request.
-                    if (!activityManager.isUserRunning(op.userId)) {
-                        final UserInfo userInfo = mUserManager.getUserInfo(op.userId);
+                    // If the user is not running, skip the request.
+                    if (!activityManager.isUserRunning(op.target.userId)) {
+                        final UserInfo userInfo = mUserManager.getUserInfo(op.target.userId);
                         if (userInfo == null) {
-                            removedUsers.add(op.userId);
+                            removedUsers.add(op.target.userId);
                         }
                         if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: user not running.");
+                            Log.v(TAG, "    Dropping all sync operations for + "
+                                    + op.target.userId + ": user not running.");
                         }
                         continue;
                     }
-
+                    if (!isOperationValidLocked(op)) {
+                        operationIterator.remove();
+                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
+                        continue;
+                    }
                     // If the next run time is in the future, even given the flexible scheduling,
                     // return the time.
                     if (op.effectiveRunTime - op.flexTime > now) {
@@ -2230,51 +2367,16 @@
                             nextReadyToRunTime = op.effectiveRunTime;
                         }
                         if (isLoggable) {
-                            Log.v(TAG, "    Dropping sync operation: Sync too far in future.");
+                            Log.v(TAG, "    Not running sync operation: Sync too far in future."
+                                    + "effective: " + op.effectiveRunTime + " flex: " + op.flexTime
+                                    + " now: " + now);
                         }
                         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);
-
-                    // only proceed if network is connected for requesting UID
-                    final boolean uidNetworkConnected;
-                    if (syncAdapterInfo != null) {
-                        final NetworkInfo networkInfo = getConnectivityManager()
-                                .getActiveNetworkInfoForUid(syncAdapterInfo.uid);
-                        uidNetworkConnected = networkInfo != null && networkInfo.isConnected();
-                    } else {
-                        uidNetworkConnected = false;
-                    }
-
-                    // skip the sync if it isn't manual, and auto sync or
-                    // background data usage is disabled or network is
-                    // disconnected for the target UID.
-                    if (!op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
-                            && (syncableState > 0)
-                            && (!mSyncStorageEngine.getMasterSyncAutomatically(op.userId)
-                                || !backgroundDataUsageAllowed
-                                || !uidNetworkConnected
-                                || !mSyncStorageEngine.getSyncAutomatically(
-                                       op.account, op.userId, op.authority))) {
-                        operationIterator.remove();
-                        mSyncStorageEngine.deleteFromPending(op.pendingOperation);
-                        continue;
-                    }
-
+                    // Add this sync to be run.
                     operations.add(op);
                 }
+
                 for (Integer user : removedUsers) {
                     // if it's still removed
                     if (mUserManager.getUserInfo(user) == null) {
@@ -2316,13 +2418,9 @@
                             }
                         }
                     }
-                    if (activeOp.account.type.equals(candidate.account.type)
-                            && activeOp.authority.equals(candidate.authority)
-                            && activeOp.userId == candidate.userId
-                            && (!activeOp.allowParallelSyncs
-                                || activeOp.account.name.equals(candidate.account.name))) {
+                    if (activeOp.isConflict(candidate)) {
                         conflict = activeSyncContext;
-                        // don't break out since we want to do a full count of the varieties
+                        // don't break out since we want to do a full count of the varieties.
                     } else {
                         if (candidateIsInitialization == activeOp.isInitialization()
                                 && activeSyncContext.mStartTime + MAX_TIME_PER_SYNC < now) {
@@ -2352,7 +2450,7 @@
                             Log.v(TAG, "canceling and rescheduling sync since an initialization "
                                     + "takes higher priority, " + conflict);
                         }
-                    } else if (candidate.expedited && !conflict.mSyncOperation.expedited
+                    } else if (candidate.isExpedited() && !conflict.mSyncOperation.isExpedited()
                             && (candidateIsInitialization
                                 == conflict.mSyncOperation.isInitialization())) {
                         toReschedule = conflict;
@@ -2372,8 +2470,8 @@
                     // is null. Reschedule the active sync and start the candidate.
                     toReschedule = oldestNonExpeditedRegular;
                     if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to run, "
-                                + oldestNonExpeditedRegular);
+                        Log.v(TAG, "canceling and rescheduling sync since an expedited is ready to"
+                                + " run, " + oldestNonExpeditedRegular);
                     }
                 } else if (longRunning != null
                         && (candidateIsInitialization
@@ -2402,7 +2500,114 @@
             }
 
             return nextReadyToRunTime;
-     }
+        }
+
+        /**
+         * Determine if a sync is no longer valid and should be dropped from the sync queue and its
+         * pending op deleted.
+         * @param op operation for which the sync is to be scheduled.
+         */
+        private boolean isOperationValidLocked(SyncOperation op) {
+            final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
+            int targetUid;
+            int state;
+            final SyncStorageEngine.EndPoint target = op.target;
+            boolean syncEnabled = mSyncStorageEngine.getMasterSyncAutomatically(target.userId);
+            if (target.target_provider) {
+                // Drop the sync if the account of this operation no longer exists.
+                AccountAndUser[] accounts = mRunningAccounts;
+                if (!containsAccountAndUser(accounts, target.account, target.userId)) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: account doesn't exist.");
+                    }
+                    return false;
+                }
+                // Drop this sync request if it isn't syncable.
+                state = getIsSyncable(target.account, target.userId, target.provider);
+                if (state == 0) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: isSyncable == 0.");
+                    }
+                    return false;
+                }
+                syncEnabled = syncEnabled && mSyncStorageEngine.getSyncAutomatically(
+                        target.account, target.userId, target.provider);
+
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+                syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                        SyncAdapterType.newKey(
+                                target.provider, target.account.type), target.userId);
+                if (syncAdapterInfo != null) {
+                    targetUid = syncAdapterInfo.uid;
+                } else {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: No sync adapter registered"
+                                + "for: " + target);
+                    }
+                    return false;
+                }
+            } else if (target.target_service) {
+                state = mSyncStorageEngine.getIsTargetServiceActive(target.service, target.userId)
+                            ? 1 : 0;
+                if (state == 0) {
+                    // TODO: Change this to not drop disabled syncs - keep them in the pending queue.
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: isActive == 0.");
+                    }
+                    return false;
+                }
+                try {
+                    targetUid = mContext.getPackageManager()
+                            .getServiceInfo(target.service, 0)
+                            .applicationInfo
+                            .uid;
+                } catch (PackageManager.NameNotFoundException e) {
+                    if (isLoggable) {
+                        Log.v(TAG, "    Dropping sync operation: No service registered for: "
+                                + target.service);
+                    }
+                    return false;
+                }
+            } else {
+                Log.e(TAG, "Unknown target for Sync Op: " + target);
+                return false;
+            }
+
+            // We ignore system settings that specify the sync is invalid if:
+            // 1) It's manual - we try it anyway. When/if it fails it will be rescheduled.
+            //      or
+            // 2) it's an initialisation sync - we just need to connect to it.
+            final boolean ignoreSystemConfiguration =
+                    op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
+                    || (state < 0);
+
+            // Sync not enabled.
+            if (!syncEnabled && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: disallowed by settings/network.");
+                }
+                return false;
+            }
+            // Network down.
+            final NetworkInfo networkInfo = getConnectivityManager()
+                    .getActiveNetworkInfoForUid(targetUid);
+            final boolean uidNetworkConnected = networkInfo != null && networkInfo.isConnected();
+            if (!uidNetworkConnected && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: disallowed by settings/network.");
+                }
+                return false;
+            }
+            // Metered network.
+            if (op.isNotAllowedOnMetered() && getConnectivityManager().isActiveNetworkMetered()
+                    && !ignoreSystemConfiguration) {
+                if (isLoggable) {
+                    Log.v(TAG, "    Dropping sync operation: not allowed on metered network.");
+                }
+                return false;
+            }
+            return true;
+        }
 
         private boolean dispatchSyncOperation(SyncOperation op) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -2412,27 +2617,48 @@
                     Log.v(TAG, syncContext.toString());
                 }
             }
-
-            // connect to the sync adapter
-            SyncAdapterType syncAdapterType = SyncAdapterType.newKey(op.authority, op.account.type);
-            final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
-            syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, op.userId);
-            if (syncAdapterInfo == null) {
-                Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
-                        + ", removing settings for it");
-                mSyncStorageEngine.removeAuthority(op.account, op.userId, op.authority);
-                return false;
+            // Connect to the sync adapter.
+            int targetUid;
+            ComponentName targetComponent;
+            final SyncStorageEngine.EndPoint info = op.target;
+            if (info.target_provider) {
+                SyncAdapterType syncAdapterType =
+                        SyncAdapterType.newKey(info.provider, info.account.type);
+                final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+                syncAdapterInfo = mSyncAdapters.getServiceInfo(syncAdapterType, info.userId);
+                if (syncAdapterInfo == null) {
+                    Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
+                            + ", removing settings for it");
+                    mSyncStorageEngine.removeAuthority(info);
+                    return false;
+                }
+                targetUid = syncAdapterInfo.uid;
+                targetComponent = syncAdapterInfo.componentName;
+            } else {
+                // TODO: Store the uid of the service as part of the authority info in order to
+                // avoid this call?
+                try {
+                    targetUid = mContext.getPackageManager()
+                            .getServiceInfo(info.service, 0)
+                            .applicationInfo
+                            .uid;
+                    targetComponent = info.service;
+                } catch(PackageManager.NameNotFoundException e) {
+                    Log.d(TAG, "Can't find a service for " + info.service
+                            + ", removing settings for it");
+                    mSyncStorageEngine.removeAuthority(info);
+                    return false;
+                }
             }
-
             ActiveSyncContext activeSyncContext =
-                    new ActiveSyncContext(op, insertStartSyncEvent(op), syncAdapterInfo.uid);
+                    new ActiveSyncContext(op, insertStartSyncEvent(op), targetUid);
             activeSyncContext.mSyncInfo = mSyncStorageEngine.addActiveSync(activeSyncContext);
             mActiveSyncContexts.add(activeSyncContext);
             if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "dispatchSyncOperation: starting " + activeSyncContext);
             }
-            if (!activeSyncContext.bindToSyncAdapter(syncAdapterInfo, op.userId)) {
-                Log.e(TAG, "Bind attempt failed to " + syncAdapterInfo);
+            if (!activeSyncContext.bindToSyncAdapter(targetComponent, info.userId)) {
+                Log.e(TAG, "Bind attempt failed - target: " + targetComponent);
                 closeActiveSyncContext(activeSyncContext);
                 return false;
             }
@@ -2440,47 +2666,54 @@
             return true;
         }
 
-        private void runBoundToSyncAdapter(final ActiveSyncContext activeSyncContext,
-              ISyncAdapter syncAdapter) {
-            activeSyncContext.mSyncAdapter = syncAdapter;
+        private void runBoundToAdapter(final ActiveSyncContext activeSyncContext,
+                IBinder syncAdapter) {
             final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
             try {
                 activeSyncContext.mIsLinkedToDeath = true;
-                syncAdapter.asBinder().linkToDeath(activeSyncContext, 0);
+                syncAdapter.linkToDeath(activeSyncContext, 0);
 
-                syncAdapter.startSync(activeSyncContext, syncOperation.authority,
-                        syncOperation.account, syncOperation.extras);
+                if (syncOperation.target.target_provider) {
+                    activeSyncContext.mSyncAdapter = ISyncAdapter.Stub.asInterface(syncAdapter);
+                    activeSyncContext.mSyncAdapter
+                        .startSync(activeSyncContext, syncOperation.target.provider,
+                                syncOperation.target.account, syncOperation.extras);
+                } else if (syncOperation.target.target_service) {
+                    activeSyncContext.mSyncServiceAdapter =
+                            ISyncServiceAdapter.Stub.asInterface(syncAdapter);
+                    activeSyncContext.mSyncServiceAdapter
+                        .startSync(activeSyncContext, syncOperation.extras);
+                }
             } catch (RemoteException remoteExc) {
                 Log.d(TAG, "maybeStartNextSync: caught a RemoteException, rescheduling", remoteExc);
                 closeActiveSyncContext(activeSyncContext);
                 increaseBackoffSetting(syncOperation);
-                scheduleSyncOperation(new SyncOperation(syncOperation));
+                scheduleSyncOperation(
+                        new SyncOperation(syncOperation, 0L /* newRunTimeFromNow */));
             } catch (RuntimeException exc) {
                 closeActiveSyncContext(activeSyncContext);
                 Log.e(TAG, "Caught RuntimeException while starting the sync " + syncOperation, exc);
             }
         }
 
-        private void cancelActiveSyncLocked(Account account, int userId, String authority) {
+        /**
+         * Cancel the sync for the provided target that matches the given bundle.
+         * @param info can have null fields to indicate all the active syncs for that field.
+         */
+        private void cancelActiveSyncLocked(SyncStorageEngine.EndPoint info, Bundle extras) {
             ArrayList<ActiveSyncContext> activeSyncs =
                     new ArrayList<ActiveSyncContext>(mActiveSyncContexts);
             for (ActiveSyncContext activeSyncContext : activeSyncs) {
                 if (activeSyncContext != null) {
-                    // if an account was specified then only cancel the sync if it matches
-                    if (account != null) {
-                        if (!account.equals(activeSyncContext.mSyncOperation.account)) {
-                            continue;
-                        }
+                    final SyncStorageEngine.EndPoint opInfo =
+                            activeSyncContext.mSyncOperation.target;
+                    if (!opInfo.matchesSpec(info)) {
+                        continue;
                     }
-                    // if an authority was specified then only cancel the sync if it matches
-                    if (authority != null) {
-                        if (!authority.equals(activeSyncContext.mSyncOperation.authority)) {
-                            continue;
-                        }
-                    }
-                    // check if the userid matches
-                    if (userId != UserHandle.USER_ALL
-                            && userId != activeSyncContext.mSyncOperation.userId) {
+                    if (extras != null &&
+                            !syncExtrasEquals(activeSyncContext.mSyncOperation.extras,
+                                    extras,
+                                    false /* no config settings */)) {
                         continue;
                     }
                     runSyncFinishedOrCanceledLocked(null /* no result since this is a cancel */,
@@ -2493,16 +2726,20 @@
                 ActiveSyncContext activeSyncContext) {
             boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
+            final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
+            final SyncStorageEngine.EndPoint info = syncOperation.target;
+
             if (activeSyncContext.mIsLinkedToDeath) {
-                activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+                if (info.target_provider) {
+                    activeSyncContext.mSyncAdapter.asBinder().unlinkToDeath(activeSyncContext, 0);
+                } else {
+                    activeSyncContext.mSyncServiceAdapter.asBinder()
+                        .unlinkToDeath(activeSyncContext, 0);
+                }
                 activeSyncContext.mIsLinkedToDeath = false;
             }
             closeActiveSyncContext(activeSyncContext);
-
-            final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
-
             final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime;
-
             String historyMessage;
             int downstreamActivity;
             int upstreamActivity;
@@ -2544,6 +2781,12 @@
                     } catch (RemoteException e) {
                         // we don't need to retry this in this case
                     }
+                } else if (activeSyncContext.mSyncServiceAdapter != null) {
+                    try {
+                        activeSyncContext.mSyncServiceAdapter.cancelSync(activeSyncContext);
+                    } catch (RemoteException e) {
+                        // we don't need to retry this in this case
+                    }
                 }
                 historyMessage = SyncStorageEngine.MESG_CANCELED;
                 downstreamActivity = 0;
@@ -2553,24 +2796,35 @@
             stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
                     upstreamActivity, downstreamActivity, elapsedTime);
 
-            if (syncResult != null && syncResult.tooManyDeletions) {
-                installHandleTooManyDeletesNotification(syncOperation.account,
-                        syncOperation.authority, syncResult.stats.numDeletes,
-                        syncOperation.userId);
+            // Check for full-resync and schedule it after closing off the last sync.
+            if (info.target_provider) {
+                if (syncResult != null && syncResult.tooManyDeletions) {
+                    installHandleTooManyDeletesNotification(info.account,
+                            info.provider, syncResult.stats.numDeletes,
+                            info.userId);
+                } else {
+                    mNotificationMgr.cancelAsUser(null,
+                            info.account.hashCode() ^ info.provider.hashCode(),
+                            new UserHandle(info.userId));
+                }
+                if (syncResult != null && syncResult.fullSyncRequested) {
+                    scheduleSyncOperation(
+                            new SyncOperation(info.account, info.userId,
+                                syncOperation.reason,
+                                syncOperation.syncSource, info.provider, new Bundle(),
+                                0 /* delay */, 0 /* flex */,
+                                syncOperation.backoff, syncOperation.delayUntil,
+                                syncOperation.allowParallelSyncs));
+                }
             } else {
-                mNotificationMgr.cancelAsUser(null,
-                        syncOperation.account.hashCode() ^ syncOperation.authority.hashCode(),
-                        new UserHandle(syncOperation.userId));
-            }
-
-            if (syncResult != null && syncResult.fullSyncRequested) {
-                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));
+                if (syncResult != null && syncResult.fullSyncRequested) {
+                    scheduleSyncOperation(
+                            new SyncOperation(info.service, info.userId,
+                                syncOperation.reason,
+                                syncOperation.syncSource, new Bundle(),
+                                0 /* delay */, 0 /* flex */,
+                                syncOperation.backoff, syncOperation.delayUntil));
+                }
             }
             // no need to schedule an alarm, as that will be done by our caller.
         }
@@ -2579,7 +2833,7 @@
             activeSyncContext.close();
             mActiveSyncContexts.remove(activeSyncContext);
             mSyncStorageEngine.removeActiveSync(activeSyncContext.mSyncInfo,
-                    activeSyncContext.mSyncOperation.userId);
+                    activeSyncContext.mSyncOperation.target.userId);
         }
 
         /**
@@ -2842,26 +3096,16 @@
         }
 
         public long insertStartSyncEvent(SyncOperation syncOperation) {
-            final int source = syncOperation.syncSource;
             final long now = System.currentTimeMillis();
-
-            EventLog.writeEvent(2720, syncOperation.authority,
-                                SyncStorageEngine.EVENT_START, source,
-                                syncOperation.account.name.hashCode());
-
-            return mSyncStorageEngine.insertStartSyncEvent(
-                    syncOperation.account, syncOperation.userId, syncOperation.reason,
-                    syncOperation.authority,
-                    now, source, syncOperation.isInitialization(), syncOperation.extras
-            );
+            EventLog.writeEvent(2720,
+                    syncOperation.toEventLog(SyncStorageEngine.EVENT_START));
+            return mSyncStorageEngine.insertStartSyncEvent(syncOperation, now);
         }
 
         public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage,
                 int upstreamActivity, int downstreamActivity, long elapsedTime) {
-            EventLog.writeEvent(2720, syncOperation.authority,
-                                SyncStorageEngine.EVENT_STOP, syncOperation.syncSource,
-                                syncOperation.account.name.hashCode());
-
+            EventLog.writeEvent(2720,
+                    syncOperation.toEventLog(SyncStorageEngine.EVENT_STOP));
             mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime,
                     resultMessage, downstreamActivity, upstreamActivity);
         }
@@ -2876,6 +3120,83 @@
         return false;
     }
 
+    /**
+     * Sync extra comparison function.
+     * @param b1 bundle to compare
+     * @param b2 other bundle to compare
+     * @param includeSyncSettings if false, ignore system settings in bundle.
+     */
+    public static boolean syncExtrasEquals(Bundle b1, Bundle b2, boolean includeSyncSettings) {
+        if (b1 == b2) {
+            return true;
+        }
+        // Exit early if we can.
+        if (includeSyncSettings && b1.size() != b2.size()) {
+            return false;
+        }
+        Bundle bigger = b1.size() > b2.size() ? b1 : b2;
+        Bundle smaller = b1.size() > b2.size() ? b2 : b1;
+        for (String key : bigger.keySet()) {
+            if (!includeSyncSettings && isSyncSetting(key)) {
+                continue;
+            }
+            if (!smaller.containsKey(key)) {
+                return false;
+            }
+            if (!bigger.get(key).equals(smaller.get(key))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * TODO: Get rid of this when we separate sync settings extras from dev specified extras.
+     * @return true if the provided key is used by the SyncManager in scheduling the sync.
+     */
+    private static boolean isSyncSetting(String key) {
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPEDITED)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DO_NOT_RETRY)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_MANUAL)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_UPLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_UPLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_EXPECTED_DOWNLOAD)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_PRIORITY)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED)) {
+            return true;
+        }
+        if (key.equals(ContentResolver.SYNC_EXTRAS_INITIALIZE)) {
+            return true;
+        }
+        return false;
+    }
+
     static class PrintTable {
         private ArrayList<Object[]> mTable = Lists.newArrayList();
         private final int mCols;
@@ -2913,6 +3234,7 @@
                 totalLength += maxLength;
                 formats[col] = String.format("%%-%ds", maxLength);
             }
+            formats[mCols - 1] = "%s";
             printRow(out, formats, mTable.get(0));
             totalLength += (mCols - 1) * 2;
             for (int i = 0; i < totalLength; ++i) {
diff --git a/services/core/java/com/android/server/content/SyncOperation.java b/services/core/java/com/android/server/content/SyncOperation.java
index 48567478..9a4abce 100644
--- a/services/core/java/com/android/server/content/SyncOperation.java
+++ b/services/core/java/com/android/server/content/SyncOperation.java
@@ -20,10 +20,9 @@
 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;
+import android.util.Log;
 
 /**
  * Value type that represents a sync operation.
@@ -32,10 +31,13 @@
  * {@hide}
  */
 public class SyncOperation implements Comparable {
+    public static final String TAG = "SyncManager";
+
     public static final int REASON_BACKGROUND_DATA_SETTINGS_CHANGED = -1;
     public static final int REASON_ACCOUNTS_UPDATED = -2;
     public static final int REASON_SERVICE_CHANGED = -3;
     public static final int REASON_PERIODIC = -4;
+    /** Sync started because it has just been set to isSyncable. */
     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;
@@ -54,24 +56,27 @@
             "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 static final int SYNC_TARGET_UNKNOWN = 0;
+    public static final int SYNC_TARGET_ADAPTER = 1;
+    public static final int SYNC_TARGET_SERVICE = 2;
+
+    /** Identifying info for the target for this operation. */
+    public final SyncStorageEngine.EndPoint target;
+    /** Why this sync was kicked off. {@link #REASON_NAMES} */
     public final int reason;
-    public int syncSource;
+    /** Where this sync was initiated. */
+    public final int syncSource;
     public final boolean allowParallelSyncs;
-    public Bundle extras;
     public final String key;
-    public boolean expedited;
+    /** Internal boolean to avoid reading a bundle everytime we want to compare operations. */
+    private final boolean expedited;
+    public Bundle extras;
+    /** Bare-bones version of this operation that is persisted across reboots. */
     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;
+    public long backoff;
     /** Specified by the adapter to delay subsequent sync operations. */
     public long delayUntil;
     /**
@@ -79,36 +84,71 @@
      * Depends on max(backoff, latestRunTime, and delayUntil).
      */
     public long effectiveRunTime;
-    /** Amount of time before {@link effectiveRunTime} from which this sync can run. */
+    /** 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,
+    /** Descriptive string key for this operation */
+    public String wakeLockName;
+
+    public SyncOperation(Account account, int userId, int reason, int source, String provider,
             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(new SyncStorageEngine.EndPoint(account, provider, userId),
+                reason, source, extras, runTimeFromNow, flexTime, backoff, delayUntil,
+                allowParallelSyncs);
+    }
+
+    public SyncOperation(ComponentName service, int userId, int reason, int source,
+            Bundle extras, long runTimeFromNow, long flexTime, long backoff,
+            long delayUntil) {
+        this(new SyncStorageEngine.EndPoint(service, userId), reason, source, extras,
+                runTimeFromNow, flexTime, backoff, delayUntil, true /* allowParallelSyncs */);
+    }
+
+    private SyncOperation(SyncStorageEngine.EndPoint info, int reason, int source, Bundle extras,
+            long runTimeFromNow, long flexTime, long backoff, long delayUntil,
+            boolean allowParallelSyncs) {
+        this.target = info;
         this.reason = reason;
         this.syncSource = source;
-        this.allowParallelSyncs = allowParallelSyncs;
         this.extras = new Bundle(extras);
         cleanBundle(this.extras);
         this.delayUntil = delayUntil;
         this.backoff = backoff;
+        this.allowParallelSyncs = allowParallelSyncs;
         final long now = SystemClock.elapsedRealtime();
-        // Checks the extras bundle. Must occur after we set the internal bundle.
-        if (runTimeFromNow < 0 || isExpedited()) {
+        // Set expedited based on runTimeFromNow. The SyncManager specifies whether the op is
+        // expedited (Not done solely based on bundle).
+        if (runTimeFromNow < 0) {
             this.expedited = true;
+            // Sanity check: Will always be true.
+            if (!this.extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false)) {
+                this.extras.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+            }
             this.latestRunTime = now;
             this.flexTime = 0;
         } else {
             this.expedited = false;
+            this.extras.remove(ContentResolver.SYNC_EXTRAS_EXPEDITED);
             this.latestRunTime = now + runTimeFromNow;
             this.flexTime = flexTime;
         }
         updateEffectiveRunTime();
-        this.key = toKey();
+        this.key = toKey(info, this.extras);
+    }
+
+    /** Used to reschedule a sync at a new point in time. */
+    public SyncOperation(SyncOperation other, long newRunTimeFromNow) {
+        this(other.target, other.reason, other.syncSource, new Bundle(other.extras),
+                newRunTimeFromNow,
+                0L /* In back-off so no flex */,
+                other.backoff,
+                other.delayUntil,
+                other.allowParallelSyncs);
+    }
+
+    public boolean matchesAuthority(SyncOperation other) {
+        return this.target.matchesSpec(other.target);
     }
 
     /**
@@ -126,10 +166,6 @@
         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) {
@@ -138,22 +174,24 @@
         }
     }
 
-    /** 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.extras = new Bundle(other.extras);
-        this.expedited = other.expedited;
-        this.latestRunTime = SystemClock.elapsedRealtime();
-        this.flexTime = 0L;
-        this.backoff = other.backoff;
-        this.allowParallelSyncs = other.allowParallelSyncs;
-        this.updateEffectiveRunTime();
-        this.key = toKey();
+    /**
+     * Determine whether if this sync operation is running, the provided operation would conflict
+     * with it.
+     * Parallel syncs allow multiple accounts to be synced at the same time. 
+     */
+    public boolean isConflict(SyncOperation toRun) {
+        final SyncStorageEngine.EndPoint other = toRun.target;
+        if (target.target_provider) {
+            return target.account.type.equals(other.account.type)
+                    && target.provider.equals(other.provider)
+                    && target.userId == other.userId
+                    && (!allowParallelSyncs
+                            || target.account.name.equals(other.account.name));
+        } else {
+            // Ops that target a service default to allow parallel syncs, which is handled by the
+            // service returning SYNC_IN_PROGRESS if they don't.
+            return target.service.equals(other.service) && !allowParallelSyncs;
+        }
     }
 
     @Override
@@ -162,18 +200,26 @@
     }
 
     public String dump(PackageManager pm, boolean useOneLine) {
-        StringBuilder sb = new StringBuilder()
-                .append(account.name)
+        StringBuilder sb = new StringBuilder();
+        if (target.target_provider) {
+            sb.append(target.account.name)
                 .append(" u")
-                .append(userId).append(" (")
-                .append(account.type)
+                .append(target.userId).append(" (")
+                .append(target.account.type)
                 .append(")")
                 .append(", ")
-                .append(authority)
-                .append(", ")
-                .append(SyncStorageEngine.SOURCES[syncSource])
-                .append(", latestRunTime ")
-                .append(latestRunTime);
+                .append(target.provider)
+                .append(", ");
+        } else if (target.target_service) {
+            sb.append(target.service.getPackageName())
+                .append(" u")
+                .append(target.userId).append(" (")
+                .append(target.service.getClassName()).append(")")
+                .append(", ");
+        }
+        sb.append(SyncStorageEngine.SOURCES[syncSource])
+            .append(", currentRunTime ")
+            .append(effectiveRunTime);
         if (expedited) {
             sb.append(", EXPEDITED");
         }
@@ -211,44 +257,51 @@
         }
     }
 
-    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) || expedited;
+        return expedited;
     }
 
     public boolean ignoreBackoff() {
         return extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, false);
     }
 
+    public boolean isNotAllowedOnMetered() {
+        return extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISALLOW_METERED, false);
+    }
+
     /** Changed in V3. */
-    private String toKey() {
+    public static String toKey(SyncStorageEngine.EndPoint info, Bundle extras) {
         StringBuilder sb = new StringBuilder();
-        if (service == null) {
-            sb.append("authority: ").append(authority);
-            sb.append(" account {name=" + account.name + ", user=" + userId + ", type=" + account.type
+        if (info.target_provider) {
+            sb.append("provider: ").append(info.provider);
+            sb.append(" account {name=" + info.account.name
+                    + ", user="
+                    + info.userId
+                    + ", type="
+                    + info.account.type
                     + "}");
-        } else {
+        } else if (info.target_service) {
             sb.append("service {package=" )
-                .append(service.getPackageName())
+                .append(info.service.getPackageName())
                 .append(" user=")
-                .append(userId)
+                .append(info.userId)
                 .append(", class=")
-                .append(service.getClassName())
+                .append(info.service.getClassName())
                 .append("}");
+        } else {
+            Log.v(TAG, "Converting SyncOperaton to key, invalid target: " + info.toString());
+            return "";
         }
         sb.append(" extras: ");
         extrasToStringBuilder(extras, sb);
         return sb.toString();
     }
 
-    public static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
+    private static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
         sb.append("[");
         for (String key : bundle.keySet()) {
             sb.append(key).append("=").append(bundle.get(key)).append(" ");
@@ -256,6 +309,23 @@
         sb.append("]");
     }
 
+    public String wakeLockName() {
+        if (wakeLockName != null) {
+            return wakeLockName;
+        }
+        if (target.target_provider) {
+            return (wakeLockName = target.provider
+                    + "/" + target.account.type
+                    + "/" + target.account.name);
+        } else if (target.target_service) {
+            return (wakeLockName = target.service.getPackageName()
+                    + "/" + target.service.getClassName());
+        } else {
+            Log.wtf(TAG, "Invalid target getting wakelock name for operation - " + key);
+            return null;
+        }
+    }
+
     /**
      * 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
@@ -291,4 +361,21 @@
             return 0;
         }
     }
+
+    // TODO: Test this to make sure that casting to object doesn't lose the type info for EventLog.
+    public Object[] toEventLog(int event) {
+        Object[] logArray = new Object[4];
+        logArray[1] = event;
+        logArray[2] = syncSource;
+        if (target.target_provider) {
+            logArray[0] = target.provider;
+            logArray[3] = target.account.name.hashCode();
+        } else if (target.target_service) {
+            logArray[0] = target.service.getPackageName();
+            logArray[3] = target.service.hashCode();
+        } else {
+            Log.wtf(TAG, "sync op with invalid target: " + key);
+        }
+        return logArray;
+    }
 }
diff --git a/services/core/java/com/android/server/content/SyncQueue.java b/services/core/java/com/android/server/content/SyncQueue.java
index 6f3fe6e..587de1c 100644
--- a/services/core/java/com/android/server/content/SyncQueue.java
+++ b/services/core/java/com/android/server/content/SyncQueue.java
@@ -16,12 +16,11 @@
 
 package com.android.server.content;
 
-import android.accounts.Account;
 import android.content.pm.PackageManager;
-import android.content.pm.RegisteredServicesCache;
 import android.content.SyncAdapterType;
 import android.content.SyncAdaptersCache;
 import android.content.pm.RegisteredServicesCache.ServiceInfo;
+import android.os.Bundle;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
 import android.util.Log;
@@ -60,25 +59,49 @@
 
     public void addPendingOperations(int userId) {
         for (SyncStorageEngine.PendingOperation op : mSyncStorageEngine.getPendingOperations()) {
-            if (op.userId != userId) continue;
+            final SyncStorageEngine.EndPoint info = op.target;
+            if (info.userId != userId) continue;
 
-            final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(
-                    op.account, op.userId, op.authority);
-            final ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(
-                    SyncAdapterType.newKey(op.authority, op.account.type), op.userId);
-            if (syncAdapterInfo == null) {
-                Log.w(TAG, "Missing sync adapter info for authority " + op.authority + ", userId "
-                        + op.userId);
-                continue;
+            final Pair<Long, Long> backoff = mSyncStorageEngine.getBackoff(info);
+            SyncOperation operationToAdd;
+            if (info.target_provider) {
+                final ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(
+                        SyncAdapterType.newKey(info.provider, info.account.type), info.userId);
+                if (syncAdapterInfo == null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "Missing sync adapter info for authority " + op.target);
+                    }
+                    continue;
+                }
+                operationToAdd = new SyncOperation(
+                        info.account, info.userId, op.reason, op.syncSource, info.provider,
+                        op.extras,
+                        op.expedited ? -1 : 0 /* delay */,
+                        0 /* flex */,
+                        backoff != null ? backoff.first : 0L,
+                        mSyncStorageEngine.getDelayUntilTime(info),
+                        syncAdapterInfo.type.allowParallelSyncs());
+                operationToAdd.pendingOperation = op;
+                add(operationToAdd, op);
+            } else if (info.target_service) {
+                try {
+                    mPackageManager.getServiceInfo(info.service, 0);
+                } catch (PackageManager.NameNotFoundException e) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.w(TAG, "Missing sync service for authority " + op.target);
+                    }
+                    continue;
+                }
+                operationToAdd = new SyncOperation(
+                        info.service, info.userId, op.reason, op.syncSource,
+                        op.extras,
+                        op.expedited ? -1 : 0 /* delay */,
+                        0 /* flex */,
+                        backoff != null ? backoff.first : 0,
+                        mSyncStorageEngine.getDelayUntilTime(info));
+                operationToAdd.pendingOperation = op;
+                add(operationToAdd, op);
             }
-            SyncOperation syncOperation = new SyncOperation(
-                    op.account, op.userId, op.reason, op.syncSource, op.authority, op.extras,
-                    0 /* delay */, 0 /* flex */, backoff != null ? backoff.first : 0,
-                    mSyncStorageEngine.getDelayUntilTime(op.account, op.userId, op.authority),
-                    syncAdapterInfo.type.allowParallelSyncs());
-            syncOperation.expedited = op.expedited;
-            syncOperation.pendingOperation = op;
-            add(syncOperation, op);
         }
     }
 
@@ -104,7 +127,6 @@
         if (existingOperation != null) {
             boolean changed = false;
             if (operation.compareTo(existingOperation) <= 0 ) {
-                existingOperation.expedited = operation.expedited;
                 long newRunTime =
                         Math.min(existingOperation.latestRunTime, operation.latestRunTime);
                 // Take smaller runtime.
@@ -119,12 +141,8 @@
         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,
-                    operation.authority, operation.extras, operation.expedited);
-            pop = mSyncStorageEngine.insertIntoPending(pop);
+            pop = mSyncStorageEngine.insertIntoPending(operation);
             if (pop == null) {
                 throw new IllegalStateException("error adding pending sync operation "
                         + operation);
@@ -136,17 +154,16 @@
         return true;
     }
 
-    public void removeUser(int userId) {
+    public void removeUserLocked(int userId) {
         ArrayList<SyncOperation> opsToRemove = new ArrayList<SyncOperation>();
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.userId == userId) {
+            if (op.target.userId == userId) {
                 opsToRemove.add(op);
             }
         }
-
-        for (SyncOperation op : opsToRemove) {
-            remove(op);
-        }
+            for (SyncOperation op : opsToRemove) {
+                remove(op);
+            }
     }
 
     /**
@@ -154,8 +171,15 @@
      * @param operation the operation to remove
      */
     public void remove(SyncOperation operation) {
+        boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
         SyncOperation operationToRemove = mOperationsMap.remove(operation.key);
+        if (isLoggable) {
+            Log.v(TAG, "Attempting to remove: " + operation.key);
+        }
         if (operationToRemove == null) {
+            if (isLoggable) {
+                Log.v(TAG, "Could not find: " + operation.key);
+            }
             return;
         }
         if (!mSyncStorageEngine.deleteFromPending(operationToRemove.pendingOperation)) {
@@ -164,41 +188,58 @@
         }
     }
 
-    public void onBackoffChanged(Account account, int userId, String providerName, long backoff) {
-        // for each op that matches the account and provider update its
+    /** Reset backoffs for all operations in the queue. */
+    public void clearBackoffs() {
+        for (SyncOperation op : mOperationsMap.values()) {
+            op.backoff = 0L;
+            op.updateEffectiveRunTime();
+        }
+    }
+
+    public void onBackoffChanged(SyncStorageEngine.EndPoint target, long backoff) {
+        // For each op that matches the target of the changed op, update its
         // backoff and effectiveStartTime
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.account.equals(account) && op.authority.equals(providerName)
-                    && op.userId == userId) {
+            if (op.target.matchesSpec(target)) {
                 op.backoff = backoff;
                 op.updateEffectiveRunTime();
             }
         }
     }
 
-    public void onDelayUntilTimeChanged(Account account, String providerName, long delayUntil) {
-        // for each op that matches the account and provider update its
-        // delayUntilTime and effectiveStartTime
+    public void onDelayUntilTimeChanged(SyncStorageEngine.EndPoint target, long delayUntil) {
+        // for each op that matches the target info of the provided op, change the delay time.
         for (SyncOperation op : mOperationsMap.values()) {
-            if (op.account.equals(account) && op.authority.equals(providerName)) {
+            if (op.target.matchesSpec(target)) {
                 op.delayUntil = delayUntil;
                 op.updateEffectiveRunTime();
             }
         }
     }
 
-    public void remove(Account account, int userId, String authority) {
+    /**
+     * Remove all of the SyncOperations associated with a given target.
+     *
+     * @param info target object provided here can have null Account/provider. This is the case
+     * where you want to remove all ops associated with a provider (null Account) or all ops
+     * associated with an account (null provider).
+     * @param extras option bundle to include to further specify which operation to remove. If this
+     * bundle contains sync settings flags, they are ignored.
+     */
+    public void remove(final SyncStorageEngine.EndPoint info, Bundle extras) {
         Iterator<Map.Entry<String, SyncOperation>> entries = mOperationsMap.entrySet().iterator();
         while (entries.hasNext()) {
             Map.Entry<String, SyncOperation> entry = entries.next();
             SyncOperation syncOperation = entry.getValue();
-            if (account != null && !syncOperation.account.equals(account)) {
+            final SyncStorageEngine.EndPoint opInfo = syncOperation.target;
+            if (!opInfo.matchesSpec(info)) {
                 continue;
             }
-            if (authority != null && !syncOperation.authority.equals(authority)) {
-                continue;
-            }
-            if (userId != syncOperation.userId) {
+            if (extras != null
+                    && !SyncManager.syncExtrasEquals(
+                        syncOperation.extras,
+                        extras,
+                        false /* no config flags*/)) {
                 continue;
             }
             entries.remove();
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index 124bc60..3a2e4db 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -24,6 +24,7 @@
 import android.content.ISyncStatusObserver;
 import android.content.PeriodicSync;
 import android.content.SyncInfo;
+import android.content.SyncRequest;
 import android.content.SyncStatusInfo;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
@@ -36,10 +37,12 @@
 import android.os.Parcel;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Pair;
 import android.util.SparseArray;
+import android.util.ArrayMap;
 import android.util.Xml;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -71,7 +74,6 @@
 public class SyncStorageEngine extends Handler {
 
     private static final String TAG = "SyncManager";
-    private static final boolean DEBUG = false;
     private static final String TAG_FILE = "SyncManagerFile";
 
     private static final String XML_ATTR_NEXT_AUTHORITY_ID = "nextAuthorityId";
@@ -108,10 +110,7 @@
 
     /** Enum value for a local-initiated sync. */
     public static final int SOURCE_LOCAL = 1;
-    /**
-     * Enum value for a poll-based sync (e.g., upon connection to
-     * network)
-     */
+    /** Enum value for a poll-based sync (e.g., upon connection to network) */
     public static final int SOURCE_POLL = 2;
 
     /** Enum value for a user-initiated sync. */
@@ -119,6 +118,9 @@
 
     /** Enum value for a periodic sync. */
     public static final int SOURCE_PERIODIC = 4;
+    
+    /** Enum value for a sync started for a service. */
+    public static final int SOURCE_SERVICE = 5;
 
     public static final long NOT_IN_BACKOFF_MODE = -1;
 
@@ -128,7 +130,8 @@
                                              "LOCAL",
                                              "POLL",
                                              "USER",
-                                             "PERIODIC" };
+                                             "PERIODIC",
+                                             "SERVICE"};
 
     // The MESG column will contain one of these or one of the Error types.
     public static final String MESG_SUCCESS = "success";
@@ -156,41 +159,54 @@
     }
 
     public static class PendingOperation {
-        final Account account;
-        final int userId;
+        final EndPoint target;
         final int reason;
         final int syncSource;
-        final String authority;
         final Bundle extras;        // note: read-only.
-        final ComponentName serviceName;
         final boolean expedited;
 
-        int authorityId;
+        final int authorityId;
+        // No longer used.
+        // Keep around for sake up updating from pending.bin to pending.xml
         byte[] flatExtras;
 
-        PendingOperation(Account account, int userId, int reason, int source,
-                String authority, Bundle extras, boolean expedited) {
-            this.account = account;
-            this.userId = userId;
+        PendingOperation(AuthorityInfo authority, int reason, int source,
+                 Bundle extras, boolean expedited) {
+            this.target = authority.target;
             this.syncSource = source;
             this.reason = reason;
-            this.authority = authority;
             this.extras = extras != null ? new Bundle(extras) : extras;
             this.expedited = expedited;
-            this.authorityId = -1;
-            this.serviceName = null;
+            this.authorityId = authority.ident;
         }
 
         PendingOperation(PendingOperation other) {
-            this.account = other.account;
-            this.userId = other.userId;
             this.reason = other.reason;
             this.syncSource = other.syncSource;
-            this.authority = other.authority;
+            this.target = other.target;
             this.extras = other.extras;
             this.authorityId = other.authorityId;
             this.expedited = other.expedited;
-            this.serviceName = other.serviceName;
+        }
+
+        /**
+         * Considered equal if they target the same sync adapter (A
+         * {@link android.content.SyncService}
+         * is considered an adapter), for the same userId.
+         * @param other PendingOperation to compare.
+         * @return true if the two pending ops are the same.
+         */
+        public boolean equals(PendingOperation other) {
+            return target.matchesSpec(other.target);
+        }
+
+        public String toString() {
+            return "service=" + target.service
+                        + " user=" + target.userId
+                        + " auth=" + target
+                        + " account=" + target.account
+                        + " src=" + syncSource
+                        + " extras=" + extras;
         }
     }
 
@@ -204,17 +220,96 @@
         }
     }
 
-    public static class AuthorityInfo {
+    /**  Bare bones representation of a sync target. */
+    public static class EndPoint {
+        public final static EndPoint USER_ALL_PROVIDER_ALL_ACCOUNTS_ALL =
+                new EndPoint(null, null, UserHandle.USER_ALL);
         final ComponentName service;
         final Account account;
         final int userId;
-        final String authority;
+        final String provider;
+        final boolean target_service;
+        final boolean target_provider;
+
+        public EndPoint(ComponentName service, int userId) {
+            this.service = service;
+            this.userId = userId;
+            this.account = null;
+            this.provider = null;
+            this.target_service = true;
+            this.target_provider = false;
+        }
+
+        public EndPoint(Account account, String provider, int userId) {
+            this.account = account;
+            this.provider = provider;
+            this.userId = userId;
+            this.service = null;
+            this.target_service = false;
+            this.target_provider = true;
+        }
+
+        /**
+         * An Endpoint for a sync matches if it targets the same sync adapter for the same user.
+         *
+         * @param spec the Endpoint to match. If the spec has null fields, they indicate a wildcard
+         * and match any. 
+         */
+        public boolean matchesSpec(EndPoint spec) {
+            if (userId != spec.userId
+                    && userId != UserHandle.USER_ALL
+                    && spec.userId != UserHandle.USER_ALL) {
+                return false;
+            }
+            if (target_service && spec.target_service) {
+                return service.equals(spec.service);
+            } else if (target_provider && spec.target_provider) {
+                boolean accountsMatch;
+                if (spec.account == null) {
+                    accountsMatch = true;
+                } else {
+                    accountsMatch = account.equals(spec.account);
+                }
+                boolean providersMatch;
+                if (spec.provider == null) {
+                    providersMatch = true;
+                } else {
+                    providersMatch = provider.equals(spec.provider);
+                }
+                return accountsMatch && providersMatch;
+            }
+            return false;
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            if (target_provider) {
+                sb.append(account == null ? "ALL ACCS" : account.name)
+                    .append("/")
+                    .append(provider == null ? "ALL PDRS" : provider);
+            } else if (target_service) {
+                sb.append(service.getPackageName() + "/")
+                  .append(service.getClassName());
+            } else {
+                sb.append("invalid target");
+            }
+            sb.append(":u" + userId);
+            return sb.toString();
+        }
+    }
+
+    public static class AuthorityInfo {
+        final EndPoint target;
         final int ident;
         boolean enabled;
         int syncable;
+        /** Time at which this sync will run, taking into account backoff. */
         long backoffTime;
+        /** Amount of delay due to backoff. */
         long backoffDelay;
+        /** Time offset to add to any requests coming to this target. */
         long delayUntil;
+
         final ArrayList<PeriodicSync> periodicSyncs;
 
         /**
@@ -224,10 +319,7 @@
          * @param toCopy AuthorityInfo to be copied.
          */
         AuthorityInfo(AuthorityInfo toCopy) {
-            account = toCopy.account;
-            userId = toCopy.userId;
-            authority = toCopy.authority;
-            service = toCopy.service;
+            target = toCopy.target;
             ident = toCopy.ident;
             enabled = toCopy.enabled;
             syncable = toCopy.syncable;
@@ -241,56 +333,40 @@
             }
         }
 
-        /**
-         * 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
+        AuthorityInfo(EndPoint info, int id) {
+            target = info;
+            ident = id;
+            enabled = info.target_provider ?
+                    SYNC_ENABLED_DEFAULT : true;
+            // Service is active by default,
+            if (info.target_service) {
+                this.syncable = 1;
+            }
             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)));
+            defaultInitialisation();
         }
 
-        /**
-         * 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;
+        private void defaultInitialisation() {
             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)));
+            PeriodicSync defaultSync;
+            // Old version is one sync a day. Empty bundle gets replaced by any addPeriodicSync()
+            // call.
+            if (target.target_provider) {
+                defaultSync =
+                        new PeriodicSync(target.account, target.provider,
+                            new Bundle(),
+                            DEFAULT_POLL_FREQUENCY_SECONDS,
+                            calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS));
+                periodicSyncs.add(defaultSync);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return target + ", enabled=" + enabled + ", syncable=" + syncable + ", backoff="
+                    + backoffTime + ", delay=" + delayUntil;
         }
     }
 
@@ -322,16 +398,9 @@
     }
 
     interface OnSyncRequestListener {
-        /**
-         * Called when a sync is needed on an account(s) due to some change in state.
-         * @param account
-         * @param userId
-         * @param reason
-         * @param authority
-         * @param extras
-         */
-        public void onSyncRequest(Account account, int userId, int reason, String authority,
-                Bundle extras);
+
+        /** Called when a sync is needed on an account(s) due to some change in state. */
+        public void onSyncRequest(EndPoint info, int reason, Bundle extras);
     }
 
     // Primary list of all syncable authorities.  Also our global lock.
@@ -356,9 +425,9 @@
     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>>();
+    /** Reverse mapping for component name -> <userid -> target id>. */
+    private final ArrayMap<ComponentName, SparseArray<AuthorityInfo>> mServices =
+            new ArrayMap<ComponentName, SparseArray<AuthorityInfo>>();
 
     private int mNextAuthorityId = 0;
 
@@ -501,7 +570,7 @@
      * @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}.
+     * 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) {
@@ -535,7 +604,7 @@
             mChangeListeners.finishBroadcast();
         }
 
-        if (DEBUG) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "reportChange " + which + " to: " + reports);
         }
 
@@ -555,7 +624,8 @@
     public boolean getSyncAutomatically(Account account, int userId, String providerName) {
         synchronized (mAuthorities) {
             if (account != null) {
-                AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(account, providerName, userId),
                         "getSyncAutomatically");
                 return authority != null && authority.enabled;
             }
@@ -563,10 +633,9 @@
             int i = mAuthorities.size();
             while (i > 0) {
                 i--;
-                AuthorityInfo authority = mAuthorities.valueAt(i);
-                if (authority.authority.equals(providerName)
-                        && authority.userId == userId
-                        && authority.enabled) {
+                AuthorityInfo authorityInfo = mAuthorities.valueAt(i);
+                if (authorityInfo.target.matchesSpec(new EndPoint(account, providerName, userId))
+                        && authorityInfo.enabled) {
                     return true;
                 }
             }
@@ -576,15 +645,18 @@
 
     public void setSyncAutomatically(Account account, int userId, String providerName,
             boolean sync) {
-        if (DEBUG) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.d(TAG, "setSyncAutomatically: " + /* account + */" provider " + providerName
                     + ", user " + userId + " -> " + sync);
         }
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getOrCreateAuthorityLocked(account, userId, providerName, -1,
-                    false);
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(
+                            new EndPoint(account, providerName, userId),
+                            -1 /* ident */,
+                            false);
             if (authority.enabled == sync) {
-                if (DEBUG) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.d(TAG, "setSyncAutomatically: already set to " + sync + ", doing nothing");
                 }
                 return;
@@ -603,8 +675,9 @@
     public int getIsSyncable(Account account, int userId, String providerName) {
         synchronized (mAuthorities) {
             if (account != null) {
-                AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                        "getIsSyncable");
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(account, providerName, userId),
+                        "get authority syncable");
                 if (authority == null) {
                     return -1;
                 }
@@ -614,9 +687,10 @@
             int i = mAuthorities.size();
             while (i > 0) {
                 i--;
-                AuthorityInfo authority = mAuthorities.valueAt(i);
-                if (authority.authority.equals(providerName)) {
-                    return authority.syncable;
+                AuthorityInfo authorityInfo = mAuthorities.valueAt(i);
+                if (authorityInfo.target != null
+                        && authorityInfo.target.provider.equals(providerName)) {
+                    return authorityInfo.syncable;
                 }
             }
             return -1;
@@ -624,119 +698,178 @@
     }
 
     public void setIsSyncable(Account account, int userId, String providerName, int syncable) {
-        if (syncable > 1) {
-            syncable = 1;
-        } else if (syncable < -1) {
-            syncable = -1;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "setIsSyncable: " + account + ", provider " + providerName
-                    + ", user " + userId + " -> " + syncable);
-        }
+        setSyncableStateForEndPoint(new EndPoint(account, providerName, userId), syncable);
+    }
+
+    public boolean getIsTargetServiceActive(ComponentName cname, int userId) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority =
-                    getOrCreateAuthorityLocked(account, userId, providerName, -1, false);
-            if (authority.syncable == syncable) {
-                if (DEBUG) {
+            if (cname != null) {
+                AuthorityInfo authority = getAuthorityLocked(
+                        new EndPoint(cname, userId),
+                        "get service active");
+                if (authority == null) {
+                    return false;
+                }
+                return (authority.syncable == 1);
+            }
+            return false;
+        }
+    }
+
+    public void setIsTargetServiceActive(ComponentName cname, int userId, boolean active) {
+        setSyncableStateForEndPoint(new EndPoint(cname, userId), active ? 1 : 0);
+    }
+
+    /**
+     * An enabled sync service and a syncable provider's adapter both get resolved to the same
+     * persisted variable - namely the "syncable" attribute for an AuthorityInfo in accounts.xml.
+     * @param target target to set value for.
+     * @param syncable 0 indicates unsyncable, <0 unknown, >0 is active/syncable.
+     */
+    private void setSyncableStateForEndPoint(EndPoint target, int syncable) {
+        AuthorityInfo aInfo;
+        synchronized (mAuthorities) {
+            aInfo = getOrCreateAuthorityLocked(target, -1, false);
+            if (syncable > 1) {
+                syncable = 1;
+            } else if (syncable < -1) {
+                syncable = -1;
+            }
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.d(TAG, "setIsSyncable: " + aInfo.toString() + " -> " + syncable);
+            }
+            if (aInfo.syncable == syncable) {
+                if (Log.isLoggable(TAG, Log.VERBOSE)) {
                     Log.d(TAG, "setIsSyncable: already set to " + syncable + ", doing nothing");
                 }
                 return;
             }
-            authority.syncable = syncable;
+            aInfo.syncable = syncable;
             writeAccountInfoLocked();
         }
-
         if (syncable > 0) {
-            requestSync(account, userId, SyncOperation.REASON_IS_SYNCABLE,  providerName,
-                    new Bundle());
+            requestSync(aInfo, SyncOperation.REASON_IS_SYNCABLE, new Bundle());
         }
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public Pair<Long, Long> getBackoff(Account account, int userId, String providerName) {
+    public Pair<Long, Long> getBackoff(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getBackoff");
-            if (authority == null || authority.backoffTime < 0) {
-                return null;
+            AuthorityInfo authority = getAuthorityLocked(info, "getBackoff");
+            if (authority != null) {
+                return Pair.create(authority.backoffTime, authority.backoffDelay);
             }
-            return Pair.create(authority.backoffTime, authority.backoffDelay);
+            return null;
         }
     }
 
-    public void setBackoff(Account account, int userId, String providerName,
-            long nextSyncTime, long nextDelay) {
-        if (DEBUG) {
-            Log.v(TAG, "setBackoff: " + account + ", provider " + providerName
-                    + ", user " + userId
+    /**
+     * Update the backoff for the given endpoint. The endpoint may be for a provider/account and
+     * the account or provider info be null, which signifies all accounts or providers.
+     */
+    public void setBackoff(EndPoint info, long nextSyncTime, long nextDelay) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "setBackoff: " + info
                     + " -> nextSyncTime " + nextSyncTime + ", nextDelay " + nextDelay);
         }
-        boolean changed = false;
+        boolean changed;
         synchronized (mAuthorities) {
-            if (account == null || providerName == null) {
-                for (AccountInfo accountInfo : mAccounts.values()) {
-                    if (account != null && !account.equals(accountInfo.accountAndUser.account)
-                            && userId != accountInfo.accountAndUser.userId) {
-                        continue;
-                    }
-                    for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
-                        if (providerName != null
-                                && !providerName.equals(authorityInfo.authority)) {
-                            continue;
-                        }
-                        if (authorityInfo.backoffTime != nextSyncTime
-                                || authorityInfo.backoffDelay != nextDelay) {
-                            authorityInfo.backoffTime = nextSyncTime;
-                            authorityInfo.backoffDelay = nextDelay;
-                            changed = true;
-                        }
-                    }
-                }
+            if (info.target_provider
+                    && (info.account == null || info.provider == null)) {
+                // Do more work for a provider sync if the provided info has specified all
+                // accounts/providers. 
+                changed = setBackoffLocked(
+                        info.account /* may be null */,
+                        info.userId,
+                        info.provider /* may be null */,
+                        nextSyncTime, nextDelay);
             } else {
-                AuthorityInfo authority =
-                        getOrCreateAuthorityLocked(account, userId, providerName, -1 /* ident */,
-                                true);
-                if (authority.backoffTime == nextSyncTime && authority.backoffDelay == nextDelay) {
-                    return;
+                AuthorityInfo authorityInfo =
+                        getOrCreateAuthorityLocked(info, -1 /* ident */, true);
+                if (authorityInfo.backoffTime == nextSyncTime
+                        && authorityInfo.backoffDelay == nextDelay) {
+                    changed = false;
+                } else {
+                    authorityInfo.backoffTime = nextSyncTime;
+                    authorityInfo.backoffDelay = nextDelay;
+                    changed = true;
                 }
-                authority.backoffTime = nextSyncTime;
-                authority.backoffDelay = nextDelay;
-                changed = true;
             }
         }
-
         if (changed) {
             reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
         }
     }
 
     /**
-     * Callers of this function need to hold a lock for syncQueue object passed in. Bear in mind
-     * this function grabs the lock for {@link #mAuthorities}
-     * @param syncQueue queue containing pending sync operations.
+     * Either set backoff for a specific authority, or set backoff for all the
+     * accounts on a specific adapter/all adapters.
+     *
+     * @param account account for which to set backoff. Null to specify all accounts.
+     * @param userId id of the user making this request.
+     * @param providerName provider for which to set backoff. Null to specify all providers.
+     * @return true if a change occured.
      */
-    public void clearAllBackoffsLocked(SyncQueue syncQueue) {
+    private boolean setBackoffLocked(Account account, int userId, String providerName,
+            long nextSyncTime, long nextDelay) {
+        boolean changed = false;
+        for (AccountInfo accountInfo : mAccounts.values()) {
+            if (account != null && !account.equals(accountInfo.accountAndUser.account)
+                    && userId != accountInfo.accountAndUser.userId) {
+                continue;
+            }
+            for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+                if (providerName != null
+                        && !providerName.equals(authorityInfo.target.provider)) {
+                    continue;
+                }
+                if (authorityInfo.backoffTime != nextSyncTime
+                        || authorityInfo.backoffDelay != nextDelay) {
+                    authorityInfo.backoffTime = nextSyncTime;
+                    authorityInfo.backoffDelay = nextDelay;
+                    changed = true;
+                }
+            }
+        }
+        return changed;
+    }
+
+    public void clearAllBackoffs(SyncQueue syncQueue) {
         boolean changed = false;
         synchronized (mAuthorities) {
-            for (AccountInfo accountInfo : mAccounts.values()) {
-                for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
-                    if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
-                            || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
-                        if (DEBUG) {
-                            Log.v(TAG, "clearAllBackoffs:"
-                                    + " authority:" + authorityInfo.authority
-                                    + " account:" + accountInfo.accountAndUser.account.name
-                                    + " user:" + accountInfo.accountAndUser.userId
-                                    + " backoffTime was: " + authorityInfo.backoffTime
-                                    + " backoffDelay was: " + authorityInfo.backoffDelay);
+            synchronized (syncQueue) {
+                // Clear backoff for all sync adapters.
+                for (AccountInfo accountInfo : mAccounts.values()) {
+                    for (AuthorityInfo authorityInfo : accountInfo.authorities.values()) {
+                        if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+                                || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                                Log.v(TAG, "clearAllBackoffs:"
+                                        + " authority:" + authorityInfo.target
+                                        + " account:" + accountInfo.accountAndUser.account.name
+                                        + " user:" + accountInfo.accountAndUser.userId
+                                        + " backoffTime was: " + authorityInfo.backoffTime
+                                        + " backoffDelay was: " + authorityInfo.backoffDelay);
+                            }
+                            authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+                            authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+                            changed = true;
                         }
-                        authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
-                        authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
-                        syncQueue.onBackoffChanged(accountInfo.accountAndUser.account,
-                                accountInfo.accountAndUser.userId, authorityInfo.authority, 0);
-                        changed = true;
                     }
                 }
+                // Clear backoff for all sync services.
+                for (ComponentName service : mServices.keySet()) {
+                    SparseArray<AuthorityInfo> aInfos = mServices.get(service);
+                    for (int i = 0; i < aInfos.size(); i++) {
+                        AuthorityInfo authorityInfo = aInfos.valueAt(i);
+                        if (authorityInfo.backoffTime != NOT_IN_BACKOFF_MODE
+                                || authorityInfo.backoffDelay != NOT_IN_BACKOFF_MODE) {
+                            authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
+                            authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+                        }
+                    }
+                }
+                syncQueue.clearBackoffs();
             }
         }
 
@@ -745,28 +878,9 @@
         }
     }
 
-    public void setDelayUntilTime(Account account, int userId, String providerName,
-            long delayUntil) {
-        if (DEBUG) {
-            Log.v(TAG, "setDelayUntil: " + account + ", provider " + providerName
-                    + ", user " + userId + " -> delayUntil " + delayUntil);
-        }
+    public long getDelayUntilTime(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getOrCreateAuthorityLocked(
-                    account, userId, providerName, -1 /* ident */, true);
-            if (authority.delayUntil == delayUntil) {
-                return;
-            }
-            authority.delayUntil = delayUntil;
-        }
-
-        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
-    }
-
-    public long getDelayUntilTime(Account account, int userId, String providerName) {
-        synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getDelayUntil");
+            AuthorityInfo authority = getAuthorityLocked(info, "getDelayUntil");
             if (authority == null) {
                 return 0;
             }
@@ -774,113 +888,147 @@
         }
     }
 
-    private void updateOrRemovePeriodicSync(PeriodicSync toUpdate, int userId, boolean add) {
-        if (DEBUG) {
-            Log.v(TAG, "addOrRemovePeriodicSync: " + toUpdate.account + ", user " + userId
-                    + ", provider " + toUpdate.authority
-                    + " -> period " + toUpdate.period + ", extras " + toUpdate.extras);
+    public void setDelayUntilTime(EndPoint info, long delayUntil) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "setDelayUntil: " + info
+                    + " -> delayUntil " + delayUntil);
         }
         synchronized (mAuthorities) {
-            if (toUpdate.period <= 0 && add) {
-                Log.e(TAG, "period < 0, should never happen in updateOrRemovePeriodicSync: add-"
-                        + add);
+            AuthorityInfo authority = getOrCreateAuthorityLocked(info, -1, true);
+            if (authority.delayUntil == delayUntil) {
+                return;
             }
-            if (toUpdate.extras == null) {
-                Log.e(TAG, "null extras, should never happen in updateOrRemovePeriodicSync: add-"
-                        + add);
+            authority.delayUntil = delayUntil;
+        }
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
+    }
+
+    public void updateOrAddPeriodicSync(EndPoint info, long period, long flextime, Bundle extras) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "addPeriodicSync: " + info
+                    + " -> period " + period + ", flex " + flextime + ", extras "
+                    + extras.toString());
+        }
+        synchronized (mAuthorities) {
+            if (period <= 0) {
+                Log.e(TAG, "period < 0, should never happen in updateOrAddPeriodicSync");
+            }
+            if (extras == null) {
+                Log.e(TAG, "null extras, should never happen in updateOrAddPeriodicSync:");
             }
             try {
-                AuthorityInfo authority =
-                        getOrCreateAuthorityLocked(toUpdate.account, userId, toUpdate.authority,
-                                -1, false);
-                if (add) {
-                    // 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++) {
-                        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, 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 (!alreadyPresent) {
-                        authority.periodicSyncs.add(new PeriodicSync(toUpdate));
-                        SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
-                        status.setPeriodicSyncTime(authority.periodicSyncs.size() - 1, 0L);
-                    }
+                PeriodicSync toUpdate;
+                if (info.target_provider) {
+                    toUpdate = new PeriodicSync(info.account,
+                            info.provider,
+                            extras,
+                            period,
+                            flextime);
                 } else {
-                    // Remove any periodic syncs that match the authority and extras.
-                    SyncStatusInfo status = mSyncStatus.get(authority.ident);
-                    boolean changed = false;
-                    Iterator<PeriodicSync> iterator = authority.periodicSyncs.iterator();
-                    int i = 0;
-                    while (iterator.hasNext()) {
-                        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
-                            // 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++;
+                    toUpdate = new PeriodicSync(info.service,
+                            extras,
+                            period,
+                            flextime);
+                }
+                AuthorityInfo authority =
+                        getOrCreateAuthorityLocked(info, -1, false);
+                // 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++) {
+                    PeriodicSync syncInfo = authority.periodicSyncs.get(i);
+                    if (SyncManager.syncExtrasEquals(syncInfo.extras,
+                            extras,
+                            true /* includeSyncSettings*/)) {
+                        if (period == syncInfo.period &&
+                                flextime == syncInfo.flexTime) {
+                            // Absolutely the same.
+                            return;
                         }
+                        authority.periodicSyncs.set(i, toUpdate);
+                        alreadyPresent = true;
+                        break;
                     }
-                    if (!changed) {
-                        return;
-                    }
+                }
+                // 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(toUpdate);
+                    SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
+                    // A new periodic sync is initialised as already having been run.
+                    status.setPeriodicSyncTime(
+                            authority.periodicSyncs.size() - 1,
+                            System.currentTimeMillis());
                 }
             } finally {
                 writeAccountInfoLocked();
                 writeStatusLocked();
             }
         }
-
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void addPeriodicSync(PeriodicSync toAdd, int userId) {
-        updateOrRemovePeriodicSync(toAdd, userId, true /* add */);
+    public void removePeriodicSync(EndPoint info, Bundle extras) {
+        synchronized(mAuthorities) {
+            try {
+                AuthorityInfo authority =
+                        getOrCreateAuthorityLocked(info, -1, false);
+                // Remove any periodic syncs that match the target and extras.
+                SyncStatusInfo status = mSyncStatus.get(authority.ident);
+                boolean changed = false;
+                Iterator<PeriodicSync> iterator = authority.periodicSyncs.iterator();
+                int i = 0;
+                while (iterator.hasNext()) {
+                    PeriodicSync syncInfo = iterator.next();
+                    if (SyncManager.syncExtrasEquals(syncInfo.extras,
+                            extras,
+                            true /* includeSyncSettings */)) {
+                        iterator.remove();
+                        changed = true;
+                        // 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++;
+                    }
+                }
+                if (!changed) {
+                    return;
+                }
+            } finally {
+                writeAccountInfoLocked();
+                writeStatusLocked();
+            }
+        }
+        reportChange(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
     }
 
-    public void removePeriodicSync(PeriodicSync toRemove, int userId) {
-        updateOrRemovePeriodicSync(toRemove, userId, false /* remove */);
-    }
-
-    public List<PeriodicSync> getPeriodicSyncs(Account account, int userId, String providerName) {
-        ArrayList<PeriodicSync> syncs = new ArrayList<PeriodicSync>();
+    /**
+     * @return list of periodic syncs for a target. Never null. If no such syncs exist, returns an
+     * empty list.
+     */
+    public List<PeriodicSync> getPeriodicSyncs(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authority = getAuthorityLocked(account, userId, providerName,
-                    "getPeriodicSyncs");
-            if (authority != null) {
-                for (PeriodicSync item : authority.periodicSyncs) {
+            AuthorityInfo authorityInfo = getAuthorityLocked(info, "getPeriodicSyncs");
+            ArrayList<PeriodicSync> syncs = new ArrayList<PeriodicSync>();
+            if (authorityInfo != null) {
+                for (PeriodicSync item : authorityInfo.periodicSyncs) {
                     // Copy and send out. Necessary for thread-safety although it's parceled.
                     syncs.add(new PeriodicSync(item));
                 }
             }
+            return syncs;
         }
-        return syncs;
     }
 
     public void setMasterSyncAutomatically(boolean flag, int userId) {
         synchronized (mAuthorities) {
             Boolean auto = mMasterSyncAutomatically.get(userId);
-            if (auto != null && (boolean) auto == flag) {
+            if (auto != null && auto.equals(flag)) {
                 return;
             }
             mMasterSyncAutomatically.put(userId, flag);
@@ -901,12 +1049,6 @@
         }
     }
 
-    public void removeAuthority(Account account, int userId, String authority) {
-        synchronized (mAuthorities) {
-            removeAuthorityLocked(account, userId, authority, true /* doWrite */);
-        }
-    }
-
     public AuthorityInfo getAuthority(int authorityId) {
         synchronized (mAuthorities) {
             return mAuthorities.get(authorityId);
@@ -914,72 +1056,60 @@
     }
 
     /**
-     * Returns true if there is currently a sync operation for the given
-     * account or authority actively being processed.
+     * Returns true if there is currently a sync operation being actively processed for the given
+     * target.
      */
-    public boolean isSyncActive(Account account, int userId, String authority) {
+    public boolean isSyncActive(EndPoint info) {
         synchronized (mAuthorities) {
-            for (SyncInfo syncInfo : getCurrentSyncs(userId)) {
+            for (SyncInfo syncInfo : getCurrentSyncs(info.userId)) {
                 AuthorityInfo ainfo = getAuthority(syncInfo.authorityId);
-                if (ainfo != null && ainfo.account.equals(account)
-                        && ainfo.authority.equals(authority)
-                        && ainfo.userId == userId) {
+                if (ainfo != null && ainfo.target.matchesSpec(info)) {
                     return true;
                 }
             }
         }
-
         return false;
     }
 
-    public PendingOperation insertIntoPending(PendingOperation op) {
+    public PendingOperation insertIntoPending(SyncOperation op) {
+        PendingOperation pop;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "insertIntoPending: account=" + op.account
-                        + " user=" + op.userId
-                        + " auth=" + op.authority
-                        + " src=" + op.syncSource
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "insertIntoPending: authority=" + op.target
                         + " extras=" + op.extras);
             }
-
-            AuthorityInfo authority = getOrCreateAuthorityLocked(op.account, op.userId,
-                    op.authority,
-                    -1 /* desired identifier */,
-                    true /* write accounts to storage */);
+            final EndPoint info = op.target;
+            AuthorityInfo authority =
+                    getOrCreateAuthorityLocked(info,
+                            -1 /* desired identifier */,
+                            true /* write accounts to storage */);
             if (authority == null) {
                 return null;
             }
 
-            op = new PendingOperation(op);
-            op.authorityId = authority.ident;
-            mPendingOperations.add(op);
-            appendPendingOperationLocked(op);
+            pop = new PendingOperation(authority, op.reason, op.syncSource, op.extras,
+                    op.isExpedited());
+            mPendingOperations.add(pop);
+            appendPendingOperationLocked(pop);
 
             SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
             status.pending = true;
         }
-
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_PENDING);
-        return op;
+        return pop;
     }
 
     /**
      * 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
+     * authorities. If there are no more pending syncs for the same target,
+     * update the SyncStatusInfo for that target.
+     * @param op Pending op to delete.
      */
     public boolean deleteFromPending(PendingOperation op) {
         boolean res = false;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "deleteFromPending: account=" + op.account
-                    + " user=" + op.userId
-                    + " auth=" + op.authority
-                    + " src=" + op.syncSource
-                    + " extras=" + op.extras);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "deleteFromPending: account=" + op.toString());
             }
             if (mPendingOperations.remove(op)) {
                 if (mPendingOperations.size() == 0
@@ -989,30 +1119,27 @@
                 } else {
                     mNumPendingFinished++;
                 }
-
-                AuthorityInfo authority = getAuthorityLocked(op.account, op.userId, op.authority,
-                        "deleteFromPending");
+                AuthorityInfo authority = getAuthorityLocked(op.target, "deleteFromPending");
                 if (authority != null) {
-                    if (DEBUG) Log.v(TAG, "removing - " + authority.toString());
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "removing - " + authority.toString());
+                    }
                     final int N = mPendingOperations.size();
                     boolean morePending = false;
-                    for (int i=0; i<N; i++) {
+                    for (int i = 0; i < N; i++) {
                         PendingOperation cur = mPendingOperations.get(i);
-                        if (cur.account.equals(op.account)
-                                && cur.authority.equals(op.authority)
-                                && cur.userId == op.userId) {
+                        if (cur.equals(op)) {
                             morePending = true;
                             break;
                         }
                     }
 
                     if (!morePending) {
-                        if (DEBUG) Log.v(TAG, "no more pending!");
+                        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "no more pending!");
                         SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
                         status.pending = false;
                     }
                 }
-
                 res = true;
             }
         }
@@ -1047,7 +1174,9 @@
      */
     public void doDatabaseCleanup(Account[] accounts, int userId) {
         synchronized (mAuthorities) {
-            if (DEBUG) Log.v(TAG, "Updating for new accounts...");
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "Updating for new accounts...");
+            }
             SparseArray<AuthorityInfo> removing = new SparseArray<AuthorityInfo>();
             Iterator<AccountInfo> accIt = mAccounts.values().iterator();
             while (accIt.hasNext()) {
@@ -1055,7 +1184,7 @@
                 if (!ArrayUtils.contains(accounts, acc.accountAndUser.account)
                         && acc.accountAndUser.userId == userId) {
                     // This account no longer exists...
-                    if (DEBUG) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
                         Log.v(TAG, "Account removed: " + acc.accountAndUser);
                     }
                     for (AuthorityInfo auth : acc.authorities.values()) {
@@ -1102,25 +1231,25 @@
     public SyncInfo addActiveSync(SyncManager.ActiveSyncContext activeSyncContext) {
         final SyncInfo syncInfo;
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "setActiveSync: account="
-                    + activeSyncContext.mSyncOperation.account
-                    + " auth=" + activeSyncContext.mSyncOperation.authority
+                    + " auth=" + activeSyncContext.mSyncOperation.target
                     + " src=" + activeSyncContext.mSyncOperation.syncSource
                     + " extras=" + activeSyncContext.mSyncOperation.extras);
             }
-            AuthorityInfo authority = getOrCreateAuthorityLocked(
-                    activeSyncContext.mSyncOperation.account,
-                    activeSyncContext.mSyncOperation.userId,
-                    activeSyncContext.mSyncOperation.authority,
-                    -1 /* assign a new identifier if creating a new authority */,
+            final EndPoint info = activeSyncContext.mSyncOperation.target;
+            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(
+                    info,
+                    -1 /* assign a new identifier if creating a new target */,
                     true /* write to storage if this results in a change */);
-            syncInfo = new SyncInfo(authority.ident,
-                    authority.account, authority.authority,
+            syncInfo = new SyncInfo(
+                    authorityInfo.ident,
+                    authorityInfo.target.account,
+                    authorityInfo.target.provider,
+                    authorityInfo.target.service,
                     activeSyncContext.mStartTime);
-            getCurrentSyncs(authority.userId).add(syncInfo);
+            getCurrentSyncs(authorityInfo.target.userId).add(syncInfo);
         }
-
         reportActiveChange();
         return syncInfo;
     }
@@ -1130,10 +1259,11 @@
      */
     public void removeActiveSync(SyncInfo syncInfo, int userId) {
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "removeActiveSync: account=" + syncInfo.account
                         + " user=" + userId
-                        + " auth=" + syncInfo.authority);
+                        + " auth=" + syncInfo.authority
+                        + " service=" + syncInfo.service);
             }
             getCurrentSyncs(userId).remove(syncInfo);
         }
@@ -1149,37 +1279,34 @@
     }
 
     /**
-     * Note that sync has started for the given account and authority.
+     * Note that sync has started for the given operation.
      */
-    public long insertStartSyncEvent(Account accountName, int userId, int reason,
-            String authorityName, long now, int source, boolean initialization, Bundle extras) {
+    public long insertStartSyncEvent(SyncOperation op, long now) {
         long id;
         synchronized (mAuthorities) {
-            if (DEBUG) {
-                Log.v(TAG, "insertStartSyncEvent: account=" + accountName + "user=" + userId
-                    + " auth=" + authorityName + " source=" + source);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                Log.v(TAG, "insertStartSyncEvent: " + op);
             }
-            AuthorityInfo authority = getAuthorityLocked(accountName, userId, authorityName,
-                    "insertStartSyncEvent");
+            AuthorityInfo authority = getAuthorityLocked(op.target, "insertStartSyncEvent");
             if (authority == null) {
                 return -1;
             }
             SyncHistoryItem item = new SyncHistoryItem();
-            item.initialization = initialization;
+            item.initialization = op.isInitialization();
             item.authorityId = authority.ident;
             item.historyId = mNextHistoryId++;
             if (mNextHistoryId < 0) mNextHistoryId = 0;
             item.eventTime = now;
-            item.source = source;
-            item.reason = reason;
-            item.extras = extras;
+            item.source = op.syncSource;
+            item.reason = op.reason;
+            item.extras = op.extras;
             item.event = EVENT_START;
             mSyncHistory.add(0, item);
             while (mSyncHistory.size() > MAX_HISTORY) {
                 mSyncHistory.remove(mSyncHistory.size()-1);
             }
             id = item.historyId;
-            if (DEBUG) Log.v(TAG, "returning historyId " + id);
+            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "returning historyId " + id);
         }
 
         reportChange(ContentResolver.SYNC_OBSERVER_TYPE_STATUS);
@@ -1189,7 +1316,7 @@
     public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
             long downstreamActivity, long upstreamActivity) {
         synchronized (mAuthorities) {
-            if (DEBUG) {
+            if (Log.isLoggable(TAG, Log.VERBOSE)) {
                 Log.v(TAG, "stopSyncEvent: historyId=" + historyId);
             }
             SyncHistoryItem item = null;
@@ -1346,13 +1473,12 @@
     }
 
     /**
-     * Return a copy of the specified authority with the corresponding sync status
+     * Return a copy of the specified target with the corresponding sync status
      */
-    public Pair<AuthorityInfo, SyncStatusInfo> getCopyOfAuthorityWithSyncStatus(
-            Account account, int userId, String authority) {
+    public Pair<AuthorityInfo, SyncStatusInfo> getCopyOfAuthorityWithSyncStatus(EndPoint info) {
         synchronized (mAuthorities) {
-            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(account, userId, authority,
-                    -1 /* assign a new identifier if creating a new authority */,
+            AuthorityInfo authorityInfo = getOrCreateAuthorityLocked(info,
+                    -1 /* assign a new identifier if creating a new target */,
                     true /* write to storage if this results in a change */);
             return createCopyPairOfAuthorityWithSyncStatusLocked(authorityInfo);
         }
@@ -1373,26 +1499,24 @@
     }
 
     /**
-     * Returns the status that matches the authority and account.
+     * Returns the status that matches the target.
      *
-     * @param account the account we want to check
-     * @param authority the authority whose row should be selected
-     * @return the SyncStatusInfo for the authority or null if none found.
+     * @param info the endpoint target we are querying status info for.
+     * @return the SyncStatusInfo for the endpoint.
      */
-    public SyncStatusInfo getStatusByAccountAndAuthority(Account account, int userId,
-            String authority) {
-        if (account == null || authority == null) {
-          return null;
+    public SyncStatusInfo getStatusByAuthority(EndPoint info) {
+        if (info.target_provider && (info.account == null || info.provider == null)) {
+            return null;
+        } else if (info.target_service && info.service == null) {
+            return null;
         }
         synchronized (mAuthorities) {
             final int N = mSyncStatus.size();
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 SyncStatusInfo cur = mSyncStatus.valueAt(i);
                 AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
-
-                if (ainfo != null && ainfo.authority.equals(authority)
-                        && ainfo.userId == userId
-                        && account.equals(ainfo.account)) {
+                if (ainfo != null
+                        && ainfo.target.matchesSpec(info)) {
                   return cur;
                 }
             }
@@ -1400,25 +1524,20 @@
         }
     }
 
-    /**
-     * Return true if the pending status is true of any matching authorities.
-     */
-    public boolean isSyncPending(Account account, int userId, String authority) {
+    /** Return true if the pending status is true of any matching authorities. */
+    public boolean isSyncPending(EndPoint info) {
         synchronized (mAuthorities) {
             final int N = mSyncStatus.size();
-            for (int i=0; i<N; i++) {
+            for (int i = 0; i < N; i++) {
                 SyncStatusInfo cur = mSyncStatus.valueAt(i);
                 AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
                 if (ainfo == null) {
                     continue;
                 }
-                if (userId != ainfo.userId) {
+                if (!ainfo.target.matchesSpec(info)) {
                     continue;
                 }
-                if (account != null && !ainfo.account.equals(account)) {
-                    continue;
-                }
-                if (ainfo.authority.equals(authority) && cur.pending) {
+                if (cur.pending) {
                     return true;
                 }
             }
@@ -1474,128 +1593,133 @@
     }
 
     /**
-     * Retrieve an authority, returning null if one does not exist.
+     * Retrieve a target's full info, returning null if one does not exist.
      *
-     * @param accountName The name of the account for the authority.
-     * @param authorityName The name of the authority itself.
+     * @param info info of the target to look up.
      * @param tag If non-null, this will be used in a log message if the
-     * requested authority does not exist.
+     * requested target does not exist.
      */
-    private AuthorityInfo getAuthorityLocked(Account accountName, int userId, String authorityName,
-            String tag) {
-        AccountAndUser au = new AccountAndUser(accountName, userId);
-        AccountInfo accountInfo = mAccounts.get(au);
-        if (accountInfo == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + ": unknown account " + au);
-                }
+    private AuthorityInfo getAuthorityLocked(EndPoint info, String tag) {
+        if (info.target_service) {
+            SparseArray<AuthorityInfo> aInfo = mServices.get(info.service);
+            AuthorityInfo authority = null;
+            if (aInfo != null) {
+                authority = aInfo.get(info.userId);
             }
+            if (authority == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + " No authority info found for " + info.service + " for"
+                                + " user " + info.userId);
+                    }
+                }
+                return null;
+            }
+            return authority;
+        } else if (info.target_provider){
+            AccountAndUser au = new AccountAndUser(info.account, info.userId);
+            AccountInfo accountInfo = mAccounts.get(au);
+            if (accountInfo == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + ": unknown account " + au);
+                    }
+                }
+                return null;
+            }
+            AuthorityInfo authority = accountInfo.authorities.get(info.provider);
+            if (authority == null) {
+                if (tag != null) {
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, tag + ": unknown provider " + info.provider);
+                    }
+                }
+                return null;
+            }
+            return authority;
+        } else {
+            Log.e(TAG, tag + " Authority : " + info + ", invalid target");
             return null;
         }
-        AuthorityInfo authority = accountInfo.authorities.get(authorityName);
-        if (authority == null) {
-            if (tag != null) {
-                if (DEBUG) {
-                    Log.v(TAG, tag + ": unknown authority " + authorityName);
-                }
-            }
-            return null;
-        }
-
-        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 info info identifying target.
+     * @param ident unique identifier for target. -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
+     * @return the authority that corresponds to the provided sync target, 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;
+    private AuthorityInfo getOrCreateAuthorityLocked(EndPoint info, int ident, boolean doWrite) {
+        AuthorityInfo authority = null;
+        if (info.target_service) {
+            SparseArray<AuthorityInfo> aInfo = mServices.get(info.service);
+            if (aInfo == null) {
+                aInfo = new SparseArray<AuthorityInfo>();
+                mServices.put(info.service, aInfo);
             }
-            if (DEBUG) {
-                Log.v(TAG, "created a new AuthorityInfo for " + cname.getPackageName()
-                        + ", " + cname.getClassName()
-                        + ", user: " + userId);
+            authority = aInfo.get(info.userId);
+            if (authority == null) {
+                authority = createAuthorityLocked(info, ident, doWrite);
+                aInfo.put(info.userId, authority);
             }
-            authority = new AuthorityInfo(cname, userId, ident);
-            aInfo.put(userId, authority);
-            mAuthorities.put(ident, authority);
-            if (doWrite) {
-                writeAccountInfoLocked();
+        } else if (info.target_provider) {
+            AccountAndUser au = new AccountAndUser(info.account, info.userId);
+            AccountInfo account = mAccounts.get(au);
+            if (account == null) {
+                account = new AccountInfo(au);
+                mAccounts.put(au, account);
+            }
+            authority = account.authorities.get(info.provider);
+            if (authority == null) {
+                authority = createAuthorityLocked(info, ident, doWrite);
+                account.authorities.put(info.provider, authority);
             }
         }
         return authority;
     }
 
-    private AuthorityInfo getOrCreateAuthorityLocked(Account accountName, int userId,
-            String authorityName, int ident, boolean doWrite) {
-        AccountAndUser au = new AccountAndUser(accountName, userId);
-        AccountInfo account = mAccounts.get(au);
-        if (account == null) {
-            account = new AccountInfo(au);
-            mAccounts.put(au, account);
+    private AuthorityInfo createAuthorityLocked(EndPoint info, int ident, boolean doWrite) {
+        AuthorityInfo authority;
+        if (ident < 0) {
+            ident = mNextAuthorityId;
+            mNextAuthorityId++;
+            doWrite = true;
         }
-        AuthorityInfo authority = account.authorities.get(authorityName);
-        if (authority == null) {
-            if (ident < 0) {
-                ident = mNextAuthorityId;
-                mNextAuthorityId++;
-                doWrite = true;
-            }
-            if (DEBUG) {
-                Log.v(TAG, "created a new AuthorityInfo for " + accountName
-                        + ", user " + userId
-                        + ", provider " + authorityName);
-            }
-            authority = new AuthorityInfo(accountName, userId, authorityName, ident);
-            account.authorities.put(authorityName, authority);
-            mAuthorities.put(ident, authority);
-            if (doWrite) {
-                writeAccountInfoLocked();
-            }
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "created a new AuthorityInfo for " + info);
         }
-
+        authority = new AuthorityInfo(info, ident);
+        mAuthorities.put(ident, authority);
+        if (doWrite) {
+            writeAccountInfoLocked();
+        }
         return authority;
     }
 
+    public void removeAuthority(EndPoint info) {
+        synchronized (mAuthorities) {
+            if (info.target_provider) {
+                removeAuthorityLocked(info.account, info.userId, info.provider, true /* doWrite */);
+            } else {
+                SparseArray<AuthorityInfo> aInfos = mServices.get(info.service);
+                if (aInfos != null) {
+                    AuthorityInfo authorityInfo = aInfos.get(info.userId);
+                    if (authorityInfo != null) {
+                        mAuthorities.remove(authorityInfo.ident);
+                        aInfos.delete(info.userId);
+                        writeAccountInfoLocked();
+                    }
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Remove an authority associated with a provider. Needs to be a standalone function for
+     * backward compatibility.
+     */
     private void removeAuthorityLocked(Account account, int userId, String authorityName,
             boolean doWrite) {
         AccountInfo accountInfo = mAccounts.get(new AccountAndUser(account, userId));
@@ -1612,10 +1736,9 @@
 
     /**
      * Updates (in a synchronized way) the periodic sync time of the specified
-     * authority id and target periodic sync
+     * target id and target periodic sync
      */
-    public void setPeriodicSyncTime(
-            int authorityId, PeriodicSync targetPeriodicSync, long when) {
+    public void setPeriodicSyncTime(int authorityId, PeriodicSync targetPeriodicSync, long when) {
         boolean found = false;
         final AuthorityInfo authorityInfo;
         synchronized (mAuthorities) {
@@ -1631,7 +1754,7 @@
         }
         if (!found) {
             Log.w(TAG, "Ignoring setPeriodicSyncTime request for a sync that does not exist. " +
-                    "Authority: " + authorityInfo.authority);
+                    "Authority: " + authorityInfo.target);
         }
     }
 
@@ -1692,7 +1815,7 @@
         try {
             fis = mAccountInfoFile.openRead();
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+                Log.v(TAG_FILE, "Reading " + mAccountInfoFile.getBaseFile());
             }
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(fis, null);
@@ -1806,10 +1929,14 @@
 
         ArrayList<AuthorityInfo> authoritiesToRemove = new ArrayList<AuthorityInfo>();
         final int N = mAuthorities.size();
-        for (int i=0; i<N; i++) {
+        for (int i = 0; i < N; i++) {
             AuthorityInfo authority = mAuthorities.valueAt(i);
+            // skip this authority if it doesn't target a provider
+            if (authority.target.target_service) {
+                continue;
+            }
             // skip this authority if it isn't one of the renamed ones
-            final String newAuthorityName = sAuthorityRenames.get(authority.authority);
+            final String newAuthorityName = sAuthorityRenames.get(authority.target.provider);
             if (newAuthorityName == null) {
                 continue;
             }
@@ -1825,20 +1952,26 @@
             }
 
             // if we already have a record of this new authority then don't copy over the settings
-            if (getAuthorityLocked(authority.account, authority.userId, newAuthorityName, "cleanup")
-                    != null) {
+            EndPoint newInfo =
+                    new EndPoint(authority.target.account,
+                            newAuthorityName,
+                            authority.target.userId);
+            if (getAuthorityLocked(newInfo, "cleanup") != null) {
                 continue;
             }
 
-            AuthorityInfo newAuthority = getOrCreateAuthorityLocked(authority.account,
-                    authority.userId, newAuthorityName, -1 /* ident */, false /* doWrite */);
+            AuthorityInfo newAuthority =
+                    getOrCreateAuthorityLocked(newInfo, -1 /* ident */, false /* doWrite */);
             newAuthority.enabled = true;
             writeNeeded = true;
         }
 
         for (AuthorityInfo authorityInfo : authoritiesToRemove) {
-            removeAuthorityLocked(authorityInfo.account, authorityInfo.userId,
-                    authorityInfo.authority, false /* doWrite */);
+            removeAuthorityLocked(
+                    authorityInfo.target.account,
+                    authorityInfo.target.userId,
+                    authorityInfo.target.provider,
+                    false /* doWrite */);
             writeNeeded = true;
         }
 
@@ -1880,30 +2013,37 @@
             String packageName = parser.getAttributeValue(null, "package");
             String className = parser.getAttributeValue(null, "class");
             int userId = user == null ? 0 : Integer.parseInt(user);
-            if (accountType == null) {
+            if (accountType == null && packageName == null) {
                 accountType = "com.google";
                 syncable = "unknown";
             }
             authority = mAuthorities.get(id);
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG, "Adding authority: account="
-                        + accountName + " auth=" + authorityName
+                Log.v(TAG_FILE, "Adding authority:"
+                        + " account=" + accountName
+                        + " accountType=" + accountType
+                        + " auth=" + authorityName
+                        + " package=" + packageName
+                        + " class=" + className
                         + " user=" + userId
                         + " enabled=" + enabled
                         + " syncable=" + syncable);
             }
             if (authority == null) {
                 if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                    Log.v(TAG, "Creating entry");
+                    Log.v(TAG_FILE, "Creating authority entry");
                 }
-                if (accountName != null && accountType != null) {
-                    authority = getOrCreateAuthorityLocked(
-                            new Account(accountName, accountType), userId, authorityName, id,
-                                false);
+                EndPoint info;
+                if (accountName != null && authorityName != null) {
+                    info = new EndPoint(
+                            new Account(accountName, accountType),
+                            authorityName, userId);
                 } else {
-                    authority = getOrCreateAuthorityLocked(
-                            new ComponentName(packageName, className), userId, id, false);
+                    info = new EndPoint(
+                            new ComponentName(packageName, className),
+                            userId);
                 }
+                authority = getOrCreateAuthorityLocked(info, 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 periodic sync.
@@ -1934,7 +2074,7 @@
     /**
      * Parse a periodic sync from accounts.xml. Sets the bundle to be empty.
      */
-    private PeriodicSync parsePeriodicSync(XmlPullParser parser, AuthorityInfo authority) {
+    private PeriodicSync parsePeriodicSync(XmlPullParser parser, AuthorityInfo authorityInfo) {
         Bundle extras = new Bundle(); // Gets filled in later.
         String periodValue = parser.getAttributeValue(null, "period");
         String flexValue = parser.getAttributeValue(null, "flex");
@@ -1952,17 +2092,31 @@
         try {
             flextime = Long.parseLong(flexValue);
         } catch (NumberFormatException e) {
-            Log.e(TAG, "Error formatting value parsed for periodic sync flex: " + flexValue);
             flextime = calculateDefaultFlexTime(period);
+            Log.e(TAG, "Error formatting value parsed for periodic sync flex: " + flexValue
+                    + ", using default: "
+                    + flextime);
         } 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,
+        PeriodicSync periodicSync;
+        if (authorityInfo.target.target_provider) {
+            periodicSync =
+                new PeriodicSync(authorityInfo.target.account,
+                        authorityInfo.target.provider,
+                        extras,
                         period, flextime);
-        authority.periodicSyncs.add(periodicSync);
+        } else {
+            periodicSync =
+                    new PeriodicSync(
+                            authorityInfo.target.service,
+                            extras,
+                            period,
+                            flextime);
+        }
+        authorityInfo.periodicSyncs.add(periodicSync);
         return periodicSync;
     }
 
@@ -2000,7 +2154,7 @@
      */
     private void writeAccountInfoLocked() {
         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-            Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+            Log.v(TAG_FILE, "Writing new " + mAccountInfoFile.getBaseFile());
         }
         FileOutputStream fos = null;
 
@@ -2030,17 +2184,18 @@
             final int N = mAuthorities.size();
             for (int i = 0; i < N; i++) {
                 AuthorityInfo authority = mAuthorities.valueAt(i);
+                EndPoint info = authority.target;
                 out.startTag(null, "authority");
                 out.attribute(null, "id", Integer.toString(authority.ident));
-                out.attribute(null, XML_ATTR_USER, Integer.toString(authority.userId));
+                out.attribute(null, XML_ATTR_USER, Integer.toString(info.userId));
                 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);
+                if (info.service == null) {
+                    out.attribute(null, "account", info.account.name);
+                    out.attribute(null, "type", info.account.type);
+                    out.attribute(null, "authority", info.provider);
                 } else {
-                    out.attribute(null, "package", authority.service.getPackageName());
-                    out.attribute(null, "class", authority.service.getClassName());
+                    out.attribute(null, "package", info.service.getPackageName());
+                    out.attribute(null, "class", info.service.getClassName());
                 }
                 if (authority.syncable < 0) {
                     out.attribute(null, "syncable", "unknown");
@@ -2100,7 +2255,7 @@
 
             // Copy in all of the status information, as well as accounts.
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG, "Reading legacy sync accounts db");
+                Log.v(TAG_FILE, "Reading legacy sync accounts db");
             }
             SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
             qb.setTables("stats, status");
@@ -2134,9 +2289,13 @@
                     accountType = "com.google";
                 }
                 String authorityName = c.getString(c.getColumnIndex("authority"));
-                AuthorityInfo authority = this.getOrCreateAuthorityLocked(
-                        new Account(accountName, accountType), 0 /* legacy is single-user */,
-                        authorityName, -1, false);
+                AuthorityInfo authority =
+                        this.getOrCreateAuthorityLocked(
+                                new EndPoint(new Account(accountName, accountType),
+                                        authorityName,
+                                        0 /* legacy is single-user */)
+                                , -1,
+                                false);
                 if (authority != null) {
                     int i = mSyncStatus.size();
                     boolean found = false;
@@ -2188,7 +2347,7 @@
                     while (i > 0) {
                         i--;
                         AuthorityInfo authority = mAuthorities.valueAt(i);
-                        if (authority.authority.equals(provider)) {
+                        if (authority.target.provider.equals(provider)) {
                             authority.enabled = value == null || Boolean.parseBoolean(value);
                             authority.syncable = 1;
                         }
@@ -2212,7 +2371,7 @@
      */
     private void readStatusLocked() {
         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-            Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+            Log.v(TAG_FILE, "Reading " + mStatusFile.getBaseFile());
         }
         try {
             byte[] data = mStatusFile.readFully();
@@ -2226,8 +2385,7 @@
                     if (mAuthorities.indexOfKey(status.authorityId) >= 0) {
                         status.pending = false;
                         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                            Log.v(TAG, "Adding status for id "
-                                    + status.authorityId);
+                            Log.v(TAG_FILE, "Adding status for id " + status.authorityId);
                         }
                         mSyncStatus.put(status.authorityId, status);
                     }
@@ -2247,7 +2405,7 @@
      */
     private void writeStatusLocked() {
         if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-            Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+            Log.v(TAG_FILE, "Writing new " + mStatusFile.getBaseFile());
         }
 
         // The file is being written, so we don't need to have a scheduled
@@ -2290,6 +2448,9 @@
         }
         try {
             fis = mPendingFile.openRead();
+            if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
+                Log.v(TAG_FILE, "Reading " + mPendingFile.getBaseFile());
+            }
             XmlPullParser parser;
             parser = Xml.newPullParser();
             parser.setInput(fis, null);
@@ -2301,12 +2462,11 @@
             }
             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();
+                        String tagName = parser.getName();
                         if (parser.getDepth() == 1 && "op".equals(tagName)) {
                             // Verify version.
                             String versionString =
@@ -2331,18 +2491,16 @@
                             }
                             if (authority != null) {
                                 pop = new PendingOperation(
-                                        authority.account, authority.userId, reason,
-                                        syncSource, authority.authority, new Bundle(),
-                                        expedited);
+                                        authority, reason, syncSource, 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
+                                            + pop.target
                                             + " src=" + pop.syncSource
                                             + " reason=" + pop.reason
                                             + " expedited=" + pop.expedited);
-                                }
+                                    }
                             } else {
                                 // Skip non-existent authority.
                                 pop = null;
@@ -2377,11 +2535,40 @@
         }
     }
 
+    static private byte[] flattenBundle(Bundle bundle) {
+        byte[] flatData = null;
+        Parcel parcel = Parcel.obtain();
+        try {
+            bundle.writeToParcel(parcel, 0);
+            flatData = parcel.marshall();
+        } finally {
+            parcel.recycle();
+        }
+        return flatData;
+    }
+
+    static private Bundle unflattenBundle(byte[] flatData) {
+        Bundle bundle;
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.unmarshall(flatData, 0, flatData.length);
+            parcel.setDataPosition(0);
+            bundle = parcel.readBundle();
+        } catch (RuntimeException e) {
+            // A RuntimeException is thrown if we were unable to parse the parcel.
+            // Create an empty parcel in this case.
+            bundle = new Bundle();
+        } finally {
+            parcel.recycle();
+        }
+        return bundle;
+    }
+
+    private static final String XML_ATTR_VERSION = "version";
     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.
@@ -2391,14 +2578,14 @@
         FileOutputStream fos = null;
         try {
             if (N == 0) {
-                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                    Log.v(TAG_FILE, "Truncating " + mPendingFile.getBaseFile());
+                if (Log.isLoggable(TAG_FILE, Log.VERBOSE)){
+                    Log.v(TAG, "Truncating " + mPendingFile.getBaseFile());
                 }
                 mPendingFile.truncate();
                 return;
             }
             if (Log.isLoggable(TAG_FILE, Log.VERBOSE)) {
-                Log.v(TAG_FILE, "Writing new " + mPendingFile.getBaseFile());
+                Log.v(TAG, "Writing new " + mPendingFile.getBaseFile());
             }
             fos = mPendingFile.startWrite();
             XmlSerializer out = new FastXmlSerializer();
@@ -2407,9 +2594,9 @@
             for (int i = 0; i < N; i++) {
                 PendingOperation pop = mPendingOperations.get(i);
                 writePendingOperationLocked(pop, out);
-            }
-            out.endDocument();
-            mPendingFile.finishWrite(fos);
+             }
+             out.endDocument();
+             mPendingFile.finishWrite(fos);
         } catch (java.io.IOException e1) {
             Log.w(TAG, "Error writing pending operations", e1);
             if (fos != null) {
@@ -2469,35 +2656,6 @@
         }
     }
 
-    static private byte[] flattenBundle(Bundle bundle) {
-        byte[] flatData = null;
-        Parcel parcel = Parcel.obtain();
-        try {
-            bundle.writeToParcel(parcel, 0);
-            flatData = parcel.marshall();
-        } finally {
-            parcel.recycle();
-        }
-        return flatData;
-    }
-
-    static private Bundle unflattenBundle(byte[] flatData) {
-        Bundle bundle;
-        Parcel parcel = Parcel.obtain();
-        try {
-            parcel.unmarshall(flatData, 0, flatData.length);
-            parcel.setDataPosition(0);
-            bundle = parcel.readBundle();
-        } catch (RuntimeException e) {
-            // A RuntimeException is thrown if we were unable to parse the parcel.
-            // Create an empty parcel in this case.
-            bundle = new Bundle();
-        } finally {
-            parcel.recycle();
-        }
-        return bundle;
-    }
-
     private void extrasToXml(XmlSerializer out, Bundle extras) throws java.io.IOException {
         for (String key : extras.keySet()) {
             out.startTag(null, "extra");
@@ -2530,6 +2688,24 @@
         }
     }
 
+    private void requestSync(AuthorityInfo authorityInfo, int reason, Bundle extras) {
+        if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID
+                && mSyncRequestListener != null) {
+            mSyncRequestListener.onSyncRequest(authorityInfo.target, reason, extras);
+        } else {
+            SyncRequest.Builder req =
+                    new SyncRequest.Builder()
+                            .syncOnce()
+                            .setExtras(extras);
+            if (authorityInfo.target.target_provider) {
+                req.setSyncAdapter(authorityInfo.target.account, authorityInfo.target.provider);
+            } else {
+                req.setSyncAdapter(authorityInfo.target.service);
+            }
+            ContentResolver.requestSync(req.build());
+        }
+    }
+
     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
@@ -2538,7 +2714,10 @@
         // which will know which userId to apply based on the Binder id.
         if (android.os.Process.myUid() == android.os.Process.SYSTEM_UID
                 && mSyncRequestListener != null) {
-            mSyncRequestListener.onSyncRequest(account, userId, reason, authority, extras);
+            mSyncRequestListener.onSyncRequest(
+                new EndPoint(account, authority, userId),
+                reason,
+                extras);
         } else {
             ContentResolver.requestSync(account, authority, extras);
         }
@@ -2634,10 +2813,8 @@
     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)
+            sb.append("(info: " + pop.target.toString())
+                .append(", extras: " + pop.extras)
                 .append(")\n");
         }
     }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index cb8f3e2..02be477 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -26,7 +26,6 @@
 import android.view.DisplayEventReceiver;
 import android.view.Surface;
 import android.view.SurfaceControl;
-import android.view.SurfaceControl.PhysicalDisplayInfo;
 
 import java.io.PrintWriter;
 
@@ -166,6 +165,12 @@
                     if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
                         mInfo.rotation = Surface.ROTATION_270;
                     }
+
+                    // For demonstration purposes, allow rotation of the external display
+                    // to follow the built-in display.
+                    if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) {
+                        mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                    }
                 }
             }
             return mInfo;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 7e357c0..c26c438 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -258,8 +258,7 @@
         // The orientation specifies how the physical coordinate system of the display
         // is rotated when the contents of the logical display are rendered.
         int orientation = Surface.ROTATION_0;
-        if (device == mPrimaryDisplayDevice
-                && (displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
+        if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
             orientation = displayInfo.rotation;
         }
 
diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java
index eb7a383..62114cd 100644
--- a/services/core/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/core/java/com/android/server/firewall/IntentFirewall.java
@@ -95,6 +95,7 @@
 
                 CategoryFilter.FACTORY,
                 SenderFilter.FACTORY,
+                SenderPackageFilter.FACTORY,
                 SenderPermissionFilter.FACTORY,
                 PortFilter.FACTORY
         };
diff --git a/services/core/java/com/android/server/firewall/SenderPackageFilter.java b/services/core/java/com/android/server/firewall/SenderPackageFilter.java
new file mode 100644
index 0000000..ec9b5de
--- /dev/null
+++ b/services/core/java/com/android/server/firewall/SenderPackageFilter.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.firewall;
+
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.IPackageManager;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+public class SenderPackageFilter implements Filter {
+    private static final String ATTR_NAME = "name";
+
+    public final String mPackageName;
+
+    public SenderPackageFilter(String packageName) {
+        mPackageName = packageName;
+    }
+
+    @Override
+    public boolean matches(IntentFirewall ifw, ComponentName resolvedComponent, Intent intent,
+            int callerUid, int callerPid, String resolvedType, int receivingUid) {
+        IPackageManager pm = AppGlobals.getPackageManager();
+
+        int packageUid = -1;
+        try {
+            packageUid = pm.getPackageUid(mPackageName, UserHandle.USER_OWNER);
+        } catch (RemoteException ex) {
+            // handled below
+        }
+
+        if (packageUid == -1)  {
+            return false;
+        }
+
+        return UserHandle.isSameApp(packageUid, callerUid);
+    }
+
+    public static final FilterFactory FACTORY = new FilterFactory("sender-package") {
+        @Override
+        public Filter newFilter(XmlPullParser parser)
+                throws IOException, XmlPullParserException {
+            String packageName = parser.getAttributeValue(null, ATTR_NAME);
+
+            if (packageName == null) {
+                throw new XmlPullParserException(
+                    "A package name must be specified.", parser, null);
+            }
+
+            return new SenderPackageFilter(packageName);
+        }
+    };
+}
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index e49382e..316bd57 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -52,6 +52,7 @@
 import android.hardware.input.InputManager;
 import android.hardware.input.InputManagerInternal;
 import android.hardware.input.KeyboardLayout;
+import android.hardware.input.TouchCalibration;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
@@ -76,6 +77,7 @@
 import android.view.InputEvent;
 import android.view.KeyEvent;
 import android.view.PointerIcon;
+import android.view.Surface;
 import android.view.ViewConfiguration;
 import android.view.WindowManagerPolicy;
 import android.widget.Toast;
@@ -183,6 +185,7 @@
             InputChannel fromChannel, InputChannel toChannel);
     private static native void nativeSetPointerSpeed(long ptr, int speed);
     private static native void nativeSetShowTouches(long ptr, boolean enabled);
+    private static native void nativeReloadCalibration(long ptr);
     private static native void nativeVibrate(long ptr, int deviceId, long[] pattern,
             int repeat, int token);
     private static native void nativeCancelVibrate(long ptr, int deviceId, int token);
@@ -700,6 +703,47 @@
         mTempFullKeyboards.clear();
     }
 
+    @Override // Binder call & native callback
+    public TouchCalibration getTouchCalibrationForInputDevice(String inputDeviceDescriptor,
+            int surfaceRotation) {
+        if (inputDeviceDescriptor == null) {
+            throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+        }
+
+        synchronized (mDataStore) {
+            return mDataStore.getTouchCalibration(inputDeviceDescriptor, surfaceRotation);
+        }
+    }
+
+    @Override // Binder call
+    public void setTouchCalibrationForInputDevice(String inputDeviceDescriptor, int surfaceRotation,
+            TouchCalibration calibration) {
+        if (!checkCallingPermission(android.Manifest.permission.SET_INPUT_CALIBRATION,
+                "setTouchCalibrationForInputDevice()")) {
+            throw new SecurityException("Requires SET_INPUT_CALIBRATION permission");
+        }
+        if (inputDeviceDescriptor == null) {
+            throw new IllegalArgumentException("inputDeviceDescriptor must not be null");
+        }
+        if (calibration == null) {
+            throw new IllegalArgumentException("calibration must not be null");
+        }
+        if (surfaceRotation < Surface.ROTATION_0 || surfaceRotation > Surface.ROTATION_270) {
+            throw new IllegalArgumentException("surfaceRotation value out of bounds");
+        }
+
+        synchronized (mDataStore) {
+            try {
+                if (mDataStore.setTouchCalibration(inputDeviceDescriptor, surfaceRotation,
+                        calibration)) {
+                    nativeReloadCalibration(mPtr);
+                }
+            } finally {
+                mDataStore.saveIfNeeded();
+            }
+        }
+    }
+
     // Must be called on handler.
     private void showMissingKeyboardLayoutNotification() {
         if (!mKeyboardLayoutNotificationShown) {
diff --git a/services/core/java/com/android/server/input/PersistentDataStore.java b/services/core/java/com/android/server/input/PersistentDataStore.java
index 71de776..92fa813 100644
--- a/services/core/java/com/android/server/input/PersistentDataStore.java
+++ b/services/core/java/com/android/server/input/PersistentDataStore.java
@@ -24,6 +24,8 @@
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
+import android.view.Surface;
+import android.hardware.input.TouchCalibration;
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.Xml;
@@ -82,6 +84,30 @@
         }
     }
 
+    public TouchCalibration getTouchCalibration(String inputDeviceDescriptor, int surfaceRotation) {
+        InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, false);
+        if (state == null) {
+            return TouchCalibration.IDENTITY;
+        }
+
+        TouchCalibration cal = state.getTouchCalibration(surfaceRotation);
+        if (cal == null) {
+            return TouchCalibration.IDENTITY;
+        }
+        return cal;
+    }
+
+    public boolean setTouchCalibration(String inputDeviceDescriptor, int surfaceRotation, TouchCalibration calibration) {
+        InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, true);
+
+        if (state.setTouchCalibration(surfaceRotation, calibration)) {
+            setDirty();
+            return true;
+        }
+
+        return false;
+    }
+
     public String getCurrentKeyboardLayout(String inputDeviceDescriptor) {
         InputDeviceState state = getInputDeviceState(inputDeviceDescriptor, false);
         return state != null ? state.getCurrentKeyboardLayout() : null;
@@ -275,9 +301,35 @@
     }
 
     private static final class InputDeviceState {
+        private static final String[] CALIBRATION_NAME = { "x_scale",
+                "x_ymix", "x_offset", "y_xmix", "y_scale", "y_offset" };
+
+        private TouchCalibration[] mTouchCalibration = new TouchCalibration[4];
         private String mCurrentKeyboardLayout;
         private ArrayList<String> mKeyboardLayouts = new ArrayList<String>();
 
+        public TouchCalibration getTouchCalibration(int surfaceRotation) {
+            try {
+                return mTouchCalibration[surfaceRotation];
+            } catch (ArrayIndexOutOfBoundsException ex) {
+                Slog.w(InputManagerService.TAG, "Cannot get touch calibration.", ex);
+                return null;
+            }
+        }
+
+        public boolean setTouchCalibration(int surfaceRotation, TouchCalibration calibration) {
+            try {
+                if (!calibration.equals(mTouchCalibration[surfaceRotation])) {
+                    mTouchCalibration[surfaceRotation] = calibration;
+                    return true;
+                }
+                return false;
+            } catch (ArrayIndexOutOfBoundsException ex) {
+                Slog.w(InputManagerService.TAG, "Cannot set touch calibration.", ex);
+                return false;
+            }
+        }
+
         public String getCurrentKeyboardLayout() {
             return mCurrentKeyboardLayout;
         }
@@ -389,6 +441,52 @@
                         }
                         mCurrentKeyboardLayout = descriptor;
                     }
+                } else if (parser.getName().equals("calibration")) {
+                    String format = parser.getAttributeValue(null, "format");
+                    String rotation = parser.getAttributeValue(null, "rotation");
+                    int r = -1;
+
+                    if (format == null) {
+                        throw new XmlPullParserException(
+                                "Missing format attribute on calibration.");
+                    }
+                    if (!format.equals("affine")) {
+                        throw new XmlPullParserException(
+                                "Unsupported format for calibration.");
+                    }
+                    if (rotation != null) {
+                        try {
+                            r = stringToSurfaceRotation(rotation);
+                        } catch (IllegalArgumentException e) {
+                            throw new XmlPullParserException(
+                                    "Unsupported rotation for calibration.");
+                        }
+                    }
+
+                    float[] matrix = TouchCalibration.IDENTITY.getAffineTransform();
+                    int depth = parser.getDepth();
+                    while (XmlUtils.nextElementWithin(parser, depth)) {
+                        String tag = parser.getName().toLowerCase();
+                        String value = parser.nextText();
+
+                        for (int i = 0; i < matrix.length && i < CALIBRATION_NAME.length; i++) {
+                            if (tag.equals(CALIBRATION_NAME[i])) {
+                                matrix[i] = Float.parseFloat(value);
+                                break;
+                            }
+                        }
+                    }
+
+                    if (r == -1) {
+                        // Assume calibration applies to all rotations
+                        for (r = 0; r < mTouchCalibration.length; r++) {
+                            mTouchCalibration[r] = new TouchCalibration(matrix[0],
+                                matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
+                        }
+                    } else {
+                        mTouchCalibration[r] = new TouchCalibration(matrix[0],
+                            matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
+                    }
                 }
             }
 
@@ -411,6 +509,49 @@
                 }
                 serializer.endTag(null, "keyboard-layout");
             }
+
+            for (int i = 0; i < mTouchCalibration.length; i++) {
+                if (mTouchCalibration[i] != null) {
+                    String rotation = surfaceRotationToString(i);
+                    float[] transform = mTouchCalibration[i].getAffineTransform();
+
+                    serializer.startTag(null, "calibration");
+                    serializer.attribute(null, "format", "affine");
+                    serializer.attribute(null, "rotation", rotation);
+                    for (int j = 0; j < transform.length && j < CALIBRATION_NAME.length; j++) {
+                        serializer.startTag(null, CALIBRATION_NAME[j]);
+                        serializer.text(Float.toString(transform[j]));
+                        serializer.endTag(null, CALIBRATION_NAME[j]);
+                    }
+                    serializer.endTag(null, "calibration");
+                }
+            }
+        }
+
+        private static String surfaceRotationToString(int surfaceRotation) {
+            switch (surfaceRotation) {
+                case Surface.ROTATION_0:   return "0";
+                case Surface.ROTATION_90:  return "90";
+                case Surface.ROTATION_180: return "180";
+                case Surface.ROTATION_270: return "270";
+            }
+            throw new IllegalArgumentException("Unsupported surface rotation value" + surfaceRotation);
+        }
+
+        private static int stringToSurfaceRotation(String s) {
+            if ("0".equals(s)) {
+                return Surface.ROTATION_0;
+            }
+            if ("90".equals(s)) {
+                return Surface.ROTATION_90;
+            }
+            if ("180".equals(s)) {
+                return Surface.ROTATION_180;
+            }
+            if ("270".equals(s)) {
+                return Surface.ROTATION_270;
+            }
+            throw new IllegalArgumentException("Unsupported surface rotation string '" + s + "'");
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/location/ComprehensiveCountryDetector.java b/services/core/java/com/android/server/location/ComprehensiveCountryDetector.java
index 354858b..6117a9b 100644
--- a/services/core/java/com/android/server/location/ComprehensiveCountryDetector.java
+++ b/services/core/java/com/android/server/location/ComprehensiveCountryDetector.java
@@ -26,7 +26,6 @@
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.Log;
 import android.util.Slog;
 
 import java.util.Locale;
diff --git a/services/core/java/com/android/server/location/GeocoderProxy.java b/services/core/java/com/android/server/location/GeocoderProxy.java
index 5d4a770..422b94b 100644
--- a/services/core/java/com/android/server/location/GeocoderProxy.java
+++ b/services/core/java/com/android/server/location/GeocoderProxy.java
@@ -22,7 +22,6 @@
 import android.location.IGeocodeProvider;
 import android.os.Handler;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.server.ServiceWatcher;
diff --git a/services/core/java/com/android/server/location/GeofenceProxy.java b/services/core/java/com/android/server/location/GeofenceProxy.java
index bbc1f47..b886eef 100644
--- a/services/core/java/com/android/server/location/GeofenceProxy.java
+++ b/services/core/java/com/android/server/location/GeofenceProxy.java
@@ -32,8 +32,6 @@
 import android.util.Log;
 import com.android.server.ServiceWatcher;
 
-import java.util.List;
-
 /**
  * @hide
  */
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index 9c76c19..c6cf68f 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -791,6 +791,7 @@
     private void handleDisable() {
         if (DEBUG) Log.d(TAG, "handleDisable");
 
+        updateClientUids(new WorkSource());
         stopNavigating();
         mAlarmManager.cancel(mWakeupIntent);
         mAlarmManager.cancel(mTimeoutIntent);
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index e420073..9dedb35 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -25,7 +25,6 @@
 import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
 import org.apache.http.StatusLine;
-import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.conn.params.ConnRouteParams;
diff --git a/services/core/java/com/android/server/location/LocationFudger.java b/services/core/java/com/android/server/location/LocationFudger.java
index 2a68743..ae71fe3 100644
--- a/services/core/java/com/android/server/location/LocationFudger.java
+++ b/services/core/java/com/android/server/location/LocationFudger.java
@@ -22,10 +22,7 @@
 import android.content.Context;
 import android.database.ContentObserver;
 import android.location.Location;
-import android.location.LocationManager;
-import android.os.Bundle;
 import android.os.Handler;
-import android.os.Parcelable;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.util.Log;
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 14db862..5eb06ed 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -18,7 +18,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.List;
 
 import android.content.Context;
 import android.location.LocationProvider;
diff --git a/services/core/java/com/android/server/location/LocationRequestStatistics.java b/services/core/java/com/android/server/location/LocationRequestStatistics.java
new file mode 100644
index 0000000..85231bb
--- /dev/null
+++ b/services/core/java/com/android/server/location/LocationRequestStatistics.java
@@ -0,0 +1,205 @@
+package com.android.server.location;
+
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * Holds statistics for location requests (active requests by provider).
+ *
+ * <p>Must be externally synchronized.
+ */
+public class LocationRequestStatistics {
+    private static final String TAG = "LocationStats";
+
+    // Maps package name nad provider to location request statistics.
+    public final HashMap<PackageProviderKey, PackageStatistics> statistics
+            = new HashMap<PackageProviderKey, PackageStatistics>();
+
+    /**
+     * Signals that a package has started requesting locations.
+     *
+     * @param packageName Name of package that has requested locations.
+     * @param providerName Name of provider that is requested (e.g. "gps").
+     * @param intervalMs The interval that is requested in ms.
+     */
+    public void startRequesting(String packageName, String providerName, long intervalMs) {
+        PackageProviderKey key = new PackageProviderKey(packageName, providerName);
+        PackageStatistics stats = statistics.get(key);
+        if (stats == null) {
+            stats = new PackageStatistics();
+            statistics.put(key, stats);
+        }
+        stats.startRequesting(intervalMs);
+    }
+
+    /**
+     * Signals that a package has stopped requesting locations.
+     *
+     * @param packageName Name of package that has stopped requesting locations.
+     * @param providerName Provider that is no longer being requested.
+     */
+    public void stopRequesting(String packageName, String providerName) {
+        PackageProviderKey key = new PackageProviderKey(packageName, providerName);
+        PackageStatistics stats = statistics.get(key);
+        if (stats != null) {
+            stats.stopRequesting();
+        } else {
+            // This shouldn't be a possible code path.
+            Log.e(TAG, "Couldn't find package statistics when removing location request.");
+        }
+    }
+
+    /**
+     * A key that holds both package and provider names.
+     */
+    public static class PackageProviderKey {
+        /**
+         * Name of package requesting location.
+         */
+        public final String packageName;
+        /**
+         * Name of provider being requested (e.g. "gps").
+         */
+        public final String providerName;
+
+        public PackageProviderKey(String packageName, String providerName) {
+            this.packageName = packageName;
+            this.providerName = providerName;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof PackageProviderKey)) {
+                return false;
+            }
+
+            PackageProviderKey otherKey = (PackageProviderKey) other;
+            return packageName.equals(otherKey.packageName)
+                    && providerName.equals(otherKey.providerName);
+        }
+
+        @Override
+        public int hashCode() {
+            return packageName.hashCode() + 31 * providerName.hashCode();
+        }
+    }
+
+    /**
+     * Usage statistics for a package/provider pair.
+     */
+    public static class PackageStatistics {
+        // Time when this package first requested location.
+        private final long mInitialElapsedTimeMs;
+        // Number of active location requests this package currently has.
+        private int mNumActiveRequests;
+        // Time when this package most recently went from not requesting location to requesting.
+        private long mLastActivitationElapsedTimeMs;
+        // The fastest interval this package has ever requested.
+        private long mFastestIntervalMs;
+        // The slowest interval this package has ever requested.
+        private long mSlowestIntervalMs;
+        // The total time this app has requested location (not including currently running requests).
+        private long mTotalDurationMs;
+
+        private PackageStatistics() {
+            mInitialElapsedTimeMs = SystemClock.elapsedRealtime();
+            mNumActiveRequests = 0;
+            mTotalDurationMs = 0;
+            mFastestIntervalMs = Long.MAX_VALUE;
+            mSlowestIntervalMs = 0;
+        }
+
+        private void startRequesting(long intervalMs) {
+            if (mNumActiveRequests == 0) {
+                mLastActivitationElapsedTimeMs = SystemClock.elapsedRealtime();
+            }
+
+            if (intervalMs < mFastestIntervalMs) {
+                mFastestIntervalMs = intervalMs;
+            }
+
+            if (intervalMs > mSlowestIntervalMs) {
+                mSlowestIntervalMs = intervalMs;
+            }
+
+            mNumActiveRequests++;
+        }
+
+        private void stopRequesting() {
+            if (mNumActiveRequests <= 0) {
+                // Shouldn't be a possible code path
+                Log.e(TAG, "Reference counting corrupted in usage statistics.");
+                return;
+            }
+
+            mNumActiveRequests--;
+            if (mNumActiveRequests == 0) {
+                long lastDurationMs
+                        = SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs;
+                mTotalDurationMs += lastDurationMs;
+            }
+        }
+
+        /**
+         * Returns the duration that this request has been active.
+         */
+        public long getDurationMs() {
+            long currentDurationMs = mTotalDurationMs;
+            if (mNumActiveRequests > 0) {
+                currentDurationMs
+                        += SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs;
+            }
+            return currentDurationMs;
+        }
+
+        /**
+         * Returns the time since the initial request in ms.
+         */
+        public long getTimeSinceFirstRequestMs() {
+            return SystemClock.elapsedRealtime() - mInitialElapsedTimeMs;
+        }
+
+        /**
+         * Returns the fastest interval that has been tracked.
+         */
+        public long getFastestIntervalMs() {
+            return mFastestIntervalMs;
+        }
+
+        /**
+         * Returns the slowest interval that has been tracked.
+         */
+        public long getSlowestIntervalMs() {
+            return mSlowestIntervalMs;
+        }
+
+        /**
+         * Returns true if a request is active for these tracked statistics.
+         */
+        public boolean isActive() {
+            return mNumActiveRequests > 0;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder s = new StringBuilder();
+            if (mFastestIntervalMs == mSlowestIntervalMs) {
+                s.append("Interval ").append(mFastestIntervalMs / 1000).append(" seconds");
+            } else {
+                s.append("Min interval ").append(mFastestIntervalMs / 1000).append(" seconds");
+                s.append(": Max interval ").append(mSlowestIntervalMs / 1000).append(" seconds");
+            }
+            s.append(": Duration requested ")
+                    .append((getDurationMs() / 1000) / 60)
+                    .append(" out of the last ")
+                    .append((getTimeSinceFirstRequestMs() / 1000) / 60)
+                    .append(" minutes");
+            if (isActive()) {
+                s.append(": Currently active");
+            }
+            return s.toString();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/location/MockProvider.java b/services/core/java/com/android/server/location/MockProvider.java
index 36c43ff..8578761 100644
--- a/services/core/java/com/android/server/location/MockProvider.java
+++ b/services/core/java/com/android/server/location/MockProvider.java
@@ -16,7 +16,6 @@
 
 package com.android.server.location;
 
-import android.location.Criteria;
 import android.location.ILocationManager;
 import android.location.Location;
 import android.location.LocationProvider;
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
new file mode 100644
index 0000000..1ff925c
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.Intent;
+import android.media.session.IMediaController;
+import android.media.session.IMediaControllerCallback;
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.media.Rating;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.Log;
+import android.util.Slog;
+import android.view.KeyEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is the system implementation of a Session. Apps will interact with the
+ * MediaSession wrapper class instead.
+ */
+public class MediaSessionRecord implements IBinder.DeathRecipient {
+    private static final String TAG = "MediaSessionImpl";
+
+    private final MessageHandler mHandler;
+
+    private final int mPid;
+    private final String mPackageName;
+    private final String mTag;
+    private final ControllerStub mController;
+    private final SessionStub mSession;
+    private final SessionCb mSessionCb;
+    private final MediaSessionService mService;
+
+    private final Object mControllerLock = new Object();
+    private final ArrayList<IMediaControllerCallback> mControllerCallbacks =
+            new ArrayList<IMediaControllerCallback>();
+    private final ArrayList<String> mInterfaces = new ArrayList<String>();
+
+    private boolean mTransportPerformerEnabled = false;
+    private Bundle mRoute;
+
+    // TransportPerformer fields
+
+    private MediaMetadata mMetadata;
+    private PlaybackState mPlaybackState;
+    private int mRatingType;
+    // End TransportPerformer fields
+
+    private boolean mIsPublished = false;
+
+    public MediaSessionRecord(int pid, String packageName, IMediaSessionCallback cb, String tag,
+            MediaSessionService service, Handler handler) {
+        mPid = pid;
+        mPackageName = packageName;
+        mTag = tag;
+        mController = new ControllerStub();
+        mSession = new SessionStub();
+        mSessionCb = new SessionCb(cb);
+        mService = service;
+        mHandler = new MessageHandler(handler.getLooper());
+    }
+
+    public IMediaSession getSessionBinder() {
+        return mSession;
+    }
+
+    public IMediaController getControllerBinder() {
+        return mController;
+    }
+
+    @Override
+    public void binderDied() {
+        mService.sessionDied(this);
+    }
+
+    public boolean isPublished() {
+        return mIsPublished;
+    }
+
+    private void onDestroy() {
+        mService.destroySession(this);
+    }
+
+    private void pushPlaybackStateUpdate() {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onPlaybackStateChanged(mPlaybackState);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushPlaybackStateUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
+    private void pushMetadataUpdate() {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onMetadataChanged(mMetadata);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushMetadataUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
+    private void pushRouteUpdate() {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onRouteChanged(mRoute);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushRouteUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
+    private void pushEvent(String event, Bundle data) {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onEvent(event, data);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushRouteUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
+    private final class SessionStub extends IMediaSession.Stub {
+
+        @Override
+        public void destroy() {
+            onDestroy();
+        }
+
+        @Override
+        public void sendEvent(String event, Bundle data) {
+            mHandler.post(MessageHandler.MSG_SEND_EVENT, event, data);
+        }
+
+        @Override
+        public IMediaController getMediaController() {
+            return mController;
+        }
+
+        @Override
+        public void setRouteState(Bundle routeState) {
+        }
+
+        @Override
+        public void setRoute(Bundle mediaRouteDescriptor) {
+            mRoute = mediaRouteDescriptor;
+            mHandler.post(MessageHandler.MSG_UPDATE_ROUTE);
+        }
+
+        @Override
+        public void publish() {
+            mIsPublished = true; // TODO push update to service
+        }
+        @Override
+        public void setTransportPerformerEnabled() {
+            mTransportPerformerEnabled = true;
+        }
+
+        @Override
+        public List<String> getSupportedInterfaces() {
+            return mInterfaces;
+        }
+
+        @Override
+        public void setMetadata(MediaMetadata metadata) {
+            mMetadata = metadata;
+            mHandler.post(MessageHandler.MSG_UPDATE_METADATA);
+        }
+
+        @Override
+        public void setPlaybackState(PlaybackState state) {
+            mPlaybackState = state;
+            mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE);
+        }
+
+        @Override
+        public void setRatingType(int type) {
+            mRatingType = type;
+        }
+    }
+
+    class SessionCb {
+        private final IMediaSessionCallback mCb;
+
+        public SessionCb(IMediaSessionCallback cb) {
+            mCb = cb;
+        }
+
+        public void sendMediaButton(KeyEvent keyEvent) {
+            Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+            mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
+            try {
+                mCb.onMediaButton(mediaButtonIntent);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in sendMediaRequest.", e);
+            }
+        }
+
+        public void sendCommand(String command, Bundle extras, ResultReceiver cb) {
+            try {
+                mCb.onCommand(command, extras, cb);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in sendCommand.", e);
+            }
+        }
+
+        public void play() {
+            try {
+                mCb.onPlay();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in play.", e);
+            }
+        }
+
+        public void pause() {
+            try {
+                mCb.onPause();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in pause.", e);
+            }
+        }
+
+        public void stop() {
+            try {
+                mCb.onStop();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in stop.", e);
+            }
+        }
+
+        public void next() {
+            try {
+                mCb.onNext();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in next.", e);
+            }
+        }
+
+        public void previous() {
+            try {
+                mCb.onPrevious();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in previous.", e);
+            }
+        }
+
+        public void fastForward() {
+            try {
+                mCb.onFastForward();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in fastForward.", e);
+            }
+        }
+
+        public void rewind() {
+            try {
+                mCb.onRewind();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in rewind.", e);
+            }
+        }
+
+        public void seekTo(long pos) {
+            try {
+                mCb.onSeekTo(pos);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in seekTo.", e);
+            }
+        }
+
+        public void rate(Rating rating) {
+            try {
+                mCb.onRate(rating);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in rate.", e);
+            }
+        }
+    }
+
+    class ControllerStub extends IMediaController.Stub {
+        @Override
+        public void sendCommand(String command, Bundle extras, ResultReceiver cb)
+                throws RemoteException {
+            mSessionCb.sendCommand(command, extras, cb);
+        }
+
+        @Override
+        public void sendMediaButton(KeyEvent mediaButtonIntent) {
+            mSessionCb.sendMediaButton(mediaButtonIntent);
+        }
+
+        @Override
+        public void registerCallbackListener(IMediaControllerCallback cb) {
+            synchronized (mControllerLock) {
+                if (!mControllerCallbacks.contains(cb)) {
+                    mControllerCallbacks.add(cb);
+                }
+            }
+        }
+
+        @Override
+        public void unregisterCallbackListener(IMediaControllerCallback cb)
+                throws RemoteException {
+            synchronized (mControllerLock) {
+                mControllerCallbacks.remove(cb);
+            }
+        }
+
+        @Override
+        public void play() throws RemoteException {
+            mSessionCb.play();
+        }
+
+        @Override
+        public void pause() throws RemoteException {
+            mSessionCb.pause();
+        }
+
+        @Override
+        public void stop() throws RemoteException {
+            mSessionCb.stop();
+        }
+
+        @Override
+        public void next() throws RemoteException {
+            mSessionCb.next();
+        }
+
+        @Override
+        public void previous() throws RemoteException {
+            mSessionCb.previous();
+        }
+
+        @Override
+        public void fastForward() throws RemoteException {
+            mSessionCb.fastForward();
+        }
+
+        @Override
+        public void rewind() throws RemoteException {
+            mSessionCb.rewind();
+        }
+
+        @Override
+        public void seekTo(long pos) throws RemoteException {
+            mSessionCb.seekTo(pos);
+        }
+
+        @Override
+        public void rate(Rating rating) throws RemoteException {
+            mSessionCb.rate(rating);
+        }
+
+
+        @Override
+        public MediaMetadata getMetadata() {
+            return mMetadata;
+        }
+
+        @Override
+        public PlaybackState getPlaybackState() {
+            return mPlaybackState;
+        }
+
+        @Override
+        public int getRatingType() {
+            return mRatingType;
+        }
+
+        @Override
+        public boolean isTransportControlEnabled() throws RemoteException {
+            return mTransportPerformerEnabled;
+        }
+    }
+
+    private class MessageHandler extends Handler {
+        private static final int MSG_UPDATE_METADATA = 1;
+        private static final int MSG_UPDATE_PLAYBACK_STATE = 2;
+        private static final int MSG_UPDATE_ROUTE = 3;
+        private static final int MSG_SEND_EVENT = 4;
+
+        public MessageHandler(Looper looper) {
+            super(looper);
+        }
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_METADATA:
+                    pushMetadataUpdate();
+                    break;
+                case MSG_UPDATE_PLAYBACK_STATE:
+                    pushPlaybackStateUpdate();
+                    break;
+                case MSG_UPDATE_ROUTE:
+                    pushRouteUpdate();
+                    break;
+                case MSG_SEND_EVENT:
+                    pushEvent((String) msg.obj, msg.getData());
+                    break;
+            }
+        }
+
+        public void post(int what) {
+            post(what, null);
+        }
+
+        public void post(int what, Object obj) {
+            obtainMessage(what, obj).sendToTarget();
+        }
+
+        public void post(int what, Object obj, Bundle data) {
+            Message msg = obtainMessage(what, obj);
+            msg.setData(data);
+            msg.sendToTarget();
+        }
+    }
+
+}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
new file mode 100644
index 0000000..8fe6055
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.Context;
+import android.media.session.IMediaSession;
+import android.media.session.IMediaSessionCallback;
+import android.media.session.IMediaSessionManager;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.server.SystemService;
+
+import java.util.ArrayList;
+
+/**
+ * System implementation of MediaSessionManager
+ */
+public class MediaSessionService extends SystemService {
+    private static final String TAG = "MediaSessionService";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final SessionManagerImpl mSessionManagerImpl;
+
+    private final ArrayList<MediaSessionRecord> mSessions
+            = new ArrayList<MediaSessionRecord>();
+    private final Object mLock = new Object();
+    // TODO do we want a separate thread for handling mediasession messages?
+    private final Handler mHandler = new Handler();
+
+    public MediaSessionService(Context context) {
+        super(context);
+        mSessionManagerImpl = new SessionManagerImpl();
+    }
+
+    @Override
+    public void onStart() {
+        publishBinderService(Context.MEDIA_SESSION_SERVICE, mSessionManagerImpl);
+    }
+
+    void sessionDied(MediaSessionRecord session) {
+        synchronized (mSessions) {
+            destroySessionLocked(session);
+        }
+    }
+
+    void destroySession(MediaSessionRecord session) {
+        synchronized (mSessions) {
+            destroySessionLocked(session);
+        }
+    }
+
+    private void destroySessionLocked(MediaSessionRecord session) {
+        mSessions.remove(session);
+    }
+
+    private void enforcePackageName(String packageName, int uid) {
+        if (TextUtils.isEmpty(packageName)) {
+            throw new IllegalArgumentException("packageName may not be empty");
+        }
+        String[] packages = getContext().getPackageManager().getPackagesForUid(uid);
+        final int packageCount = packages.length;
+        for (int i = 0; i < packageCount; i++) {
+            if (packageName.equals(packages[i])) {
+                return;
+            }
+        }
+        throw new IllegalArgumentException("packageName is not owned by the calling process");
+    }
+
+    private MediaSessionRecord createSessionInternal(int pid, String packageName,
+            IMediaSessionCallback cb, String tag) {
+        synchronized (mLock) {
+            return createSessionLocked(pid, packageName, cb, tag);
+        }
+    }
+
+    private MediaSessionRecord createSessionLocked(int pid, String packageName,
+            IMediaSessionCallback cb, String tag) {
+        final MediaSessionRecord session = new MediaSessionRecord(pid, packageName, cb, tag, this,
+                mHandler);
+        try {
+            cb.asBinder().linkToDeath(session, 0);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Media Session owner died prematurely.", e);
+        }
+        synchronized (mSessions) {
+            mSessions.add(session);
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Created session for package " + packageName + " with tag " + tag);
+        }
+        return session;
+    }
+
+    class SessionManagerImpl extends IMediaSessionManager.Stub {
+        @Override
+        public IMediaSession createSession(String packageName, IMediaSessionCallback cb, String tag)
+                throws RemoteException {
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                enforcePackageName(packageName, uid);
+                if (cb == null) {
+                    throw new IllegalArgumentException("Controller callback cannot be null");
+                }
+                return createSessionInternal(pid, packageName, cb, tag).getSessionBinder();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
+
+}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 5d6adc2..271e9e9 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -464,21 +464,21 @@
             private NetworkStatsCollection mUidTagComplete;
 
             private NetworkStatsCollection getUidComplete() {
-                if (mUidComplete == null) {
-                    synchronized (mStatsLock) {
+                synchronized (mStatsLock) {
+                    if (mUidComplete == null) {
                         mUidComplete = mUidRecorder.getOrLoadCompleteLocked();
                     }
+                    return mUidComplete;
                 }
-                return mUidComplete;
             }
 
             private NetworkStatsCollection getUidTagComplete() {
-                if (mUidTagComplete == null) {
-                    synchronized (mStatsLock) {
+                synchronized (mStatsLock) {
+                    if (mUidTagComplete == null) {
                         mUidTagComplete = mUidTagRecorder.getOrLoadCompleteLocked();
                     }
+                    return mUidTagComplete;
                 }
-                return mUidTagComplete;
             }
 
             @Override
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index df2aaca..4c8dcc3 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -16,12 +16,18 @@
 
 package com.android.server.notification;
 
+import android.os.IBinder;
+
 public interface NotificationDelegate {
     void onSetDisabled(int status);
-    void onClearAll();
-    void onNotificationClick(String pkg, String tag, int id);
-    void onNotificationClear(String pkg, String tag, int id);
-    void onNotificationError(String pkg, String tag, int id,
-            int uid, int initialPid, String message);
+    void onClearAll(int callingUid, int callingPid, int userId);
+    void onNotificationClick(int callingUid, int callingPid,
+            String pkg, String tag, int id, int userId);
+    void onNotificationClear(int callingUid, int callingPid,
+            String pkg, String tag, int id, int userId);
+    void onNotificationError(int callingUid, int callingPid,
+            String pkg, String tag, int id,
+            int uid, int initialPid, String message, int userId);
     void onPanelRevealed();
+    boolean allowDisable(int what, IBinder token, String pkg);
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index bd4442e..7c2de8b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -43,6 +43,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
@@ -56,6 +57,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.service.notification.INotificationListener;
@@ -67,6 +69,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.Xml;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -154,7 +157,7 @@
     private long[] mFallbackVibrationPattern;
     boolean mSystemReady;
 
-    int mDisabledNotifications;
+    private boolean mDisableNotificationAlerts;
     NotificationRecord mSoundNotification;
     NotificationRecord mVibrateNotification;
 
@@ -202,6 +205,34 @@
 
     final ArrayList<NotificationScorer> mScorers = new ArrayList<NotificationScorer>();
 
+    private int mZenMode;
+    // temporary, until we update apps to provide metadata
+    private static final Set<String> CALL_PACKAGES = new HashSet<String>(Arrays.asList(
+            "com.google.android.dialer",
+            "com.android.phone"
+            ));
+    private static final Set<String> ALARM_PACKAGES = new HashSet<String>(Arrays.asList(
+            "com.google.android.deskclock"
+            ));
+    private static final String EXTRA_INTERCEPT = "android.intercept";
+
+    // Users related to the current user.
+    final protected SparseArray<UserInfo> mRelatedUsers = new SparseArray<UserInfo>();
+
+    private static final int MY_UID = Process.myUid();
+    private static final int MY_PID = Process.myPid();
+    private static final int REASON_DELEGATE_CLICK = 1;
+    private static final int REASON_DELEGATE_CANCEL = 2;
+    private static final int REASON_DELEGATE_CANCEL_ALL = 3;
+    private static final int REASON_DELEGATE_ERROR = 4;
+    private static final int REASON_PACKAGE_CHANGED = 5;
+    private static final int REASON_USER_STOPPED = 6;
+    private static final int REASON_PACKAGE_BANNED = 7;
+    private static final int REASON_NOMAN_CANCEL = 8;
+    private static final int REASON_NOMAN_CANCEL_ALL = 9;
+    private static final int REASON_LISTENER_CANCEL = 10;
+    private static final int REASON_LISTENER_CANCEL_ALL = 11;
+
     private class NotificationListenerInfo implements IBinder.DeathRecipient {
         INotificationListener listener;
         ComponentName component;
@@ -870,8 +901,8 @@
         @Override
         public void onSetDisabled(int status) {
             synchronized (mNotificationList) {
-                mDisabledNotifications = status;
-                if ((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0) {
+                mDisableNotificationAlerts = (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
+                if (mDisableNotificationAlerts) {
                     // cancel whatever's going on
                     long identity = Binder.clearCallingIdentity();
                     try {
@@ -895,28 +926,23 @@
         }
 
         @Override
-        public void onClearAll() {
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelAll(ActivityManager.getCurrentUser());
+        public void onClearAll(int callingUid, int callingPid, int userId) {
+            cancelAll(callingUid, callingPid, userId, REASON_DELEGATE_CANCEL_ALL, null);
         }
 
         @Override
-        public void onNotificationClick(String pkg, String tag, int id) {
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelNotification(pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
-                    Notification.FLAG_FOREGROUND_SERVICE, false,
-                    ActivityManager.getCurrentUser());
+        public void onNotificationClick(int callingUid, int callingPid,
+                String pkg, String tag, int id, int userId) {
+            cancelNotification(callingUid, callingPid, pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
+                    Notification.FLAG_FOREGROUND_SERVICE, false, userId, REASON_DELEGATE_CLICK, null);
         }
 
         @Override
-        public void onNotificationClear(String pkg, String tag, int id) {
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelNotification(pkg, tag, id, 0,
-                Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
-                true, ActivityManager.getCurrentUser());
+        public void onNotificationClear(int callingUid, int callingPid,
+                String pkg, String tag, int id, int userId) {
+            cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
+                    Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+                    true, userId, REASON_DELEGATE_CANCEL, null);
         }
 
         @Override
@@ -953,13 +979,12 @@
         }
 
         @Override
-        public void onNotificationError(String pkg, String tag, int id,
-                int uid, int initialPid, String message) {
+        public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id,
+                int uid, int initialPid, String message, int userId) {
             Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
                     + "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelNotification(pkg, tag, id, 0, 0, false, UserHandle.getUserId(uid));
+            cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
+                    REASON_DELEGATE_ERROR, null);
             long ident = Binder.clearCallingIdentity();
             try {
                 ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg,
@@ -969,6 +994,14 @@
             }
             Binder.restoreCallingIdentity(ident);
         }
+
+        @Override
+        public boolean allowDisable(int what, IBinder token, String pkg) {
+            if (isCall(pkg, null)) {
+                return mZenMode == Settings.Global.ZEN_MODE_OFF;
+            }
+            return true;
+        }
     };
 
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -1028,8 +1061,8 @@
                 if (pkgList != null && (pkgList.length > 0)) {
                     for (String pkgName : pkgList) {
                         if (cancelNotifications) {
-                            cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart,
-                                    UserHandle.USER_ALL);
+                            cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, 0, 0, !queryRestart,
+                                    UserHandle.USER_ALL, REASON_PACKAGE_CHANGED, null);
                         }
                         if (mEnabledListenerPackageNames.contains(pkgName)) {
                             anyListenersInvolved = true;
@@ -1053,13 +1086,14 @@
             } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                 mScreenOn = false;
             } else if (action.equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
-                mInCall = (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
-                        TelephonyManager.EXTRA_STATE_OFFHOOK));
+                mInCall = TelephonyManager.EXTRA_STATE_OFFHOOK
+                        .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
                 updateNotificationPulse();
             } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (userHandle >= 0) {
-                    cancelAllNotificationsInt(null, 0, 0, true, userHandle);
+                    cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle,
+                            REASON_USER_STOPPED, null);
                 }
             } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                 // turn off LED when user passes through lock screen
@@ -1067,6 +1101,9 @@
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                 // reload per-user settings
                 mSettingsObserver.update(null);
+                updateRelatedUserCache(context);
+            } else if (action.equals(Intent.ACTION_USER_ADDED)) {
+                updateRelatedUserCache(context);
             }
         }
     };
@@ -1078,6 +1115,9 @@
         private final Uri ENABLED_NOTIFICATION_LISTENERS_URI
                 = Settings.Secure.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
 
+        private final Uri ZEN_MODE
+                = Settings.Global.getUriFor(Settings.Global.ZEN_MODE);
+
         SettingsObserver(Handler handler) {
             super(handler);
         }
@@ -1088,6 +1128,8 @@
                     false, this, UserHandle.USER_ALL);
             resolver.registerContentObserver(ENABLED_NOTIFICATION_LISTENERS_URI,
                     false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(ZEN_MODE,
+                    false, this);
             update(null);
         }
 
@@ -1108,6 +1150,9 @@
             if (uri == null || ENABLED_NOTIFICATION_LISTENERS_URI.equals(uri)) {
                 rebindListenerServices();
             }
+            if (ZEN_MODE.equals(uri)) {
+                updateZenMode();
+            }
         }
     }
 
@@ -1171,8 +1216,9 @@
         // flag at least once and we'll go back to 0 after that.
         if (0 == Settings.Global.getInt(getContext().getContentResolver(),
                     Settings.Global.DEVICE_PROVISIONED, 0)) {
-            mDisabledNotifications = StatusBarManager.DISABLE_NOTIFICATION_ALERTS;
+            mDisableNotificationAlerts = true;
         }
+        updateZenMode();
 
         // register for various Intents
         IntentFilter filter = new IntentFilter();
@@ -1182,6 +1228,7 @@
         filter.addAction(Intent.ACTION_USER_PRESENT);
         filter.addAction(Intent.ACTION_USER_STOPPED);
         filter.addAction(Intent.ACTION_USER_SWITCHED);
+        filter.addAction(Intent.ACTION_USER_ADDED);
         getContext().registerReceiver(mIntentReceiver, filter);
         IntentFilter pkgFilter = new IntentFilter();
         pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -1263,7 +1310,8 @@
 
         // Now, cancel any outstanding notifications that are part of a just-disabled app
         if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) {
-            cancelAllNotificationsInt(pkg, 0, 0, true, UserHandle.getUserId(uid));
+            cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true, UserHandle.getUserId(uid),
+                    REASON_PACKAGE_BANNED, null);
         }
     }
 
@@ -1379,9 +1427,10 @@
             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                     Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
             // Don't allow client applications to cancel foreground service notis.
-            cancelNotification(pkg, tag, id, 0,
+            cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
                     Binder.getCallingUid() == Process.SYSTEM_UID
-                    ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId);
+                    ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId, REASON_NOMAN_CANCEL,
+                    null);
         }
 
         @Override
@@ -1393,7 +1442,9 @@
 
             // Calling from user space, don't allow the canceling of actively
             // running foreground services.
-            cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId);
+            cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
+                    pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId,
+                    REASON_NOMAN_CANCEL_ALL, null);
         }
 
         @Override
@@ -1502,9 +1553,12 @@
         @Override
         public void cancelAllNotificationsFromListener(INotificationListener token) {
             NotificationListenerInfo info = checkListenerToken(token);
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
             long identity = Binder.clearCallingIdentity();
             try {
-                cancelAll(info.userid);
+                cancelAll(callingUid, callingPid, info.userid,
+                        REASON_LISTENER_CANCEL_ALL, info);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -1521,12 +1575,14 @@
         public void cancelNotificationFromListener(INotificationListener token, String pkg,
                 String tag, int id) {
             NotificationListenerInfo info = checkListenerToken(token);
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
             long identity = Binder.clearCallingIdentity();
             try {
-                cancelNotification(pkg, tag, id, 0,
+                cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
                         Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
                         true,
-                        info.userid);
+                        info.userid, REASON_LISTENER_CANCEL, info);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -1623,8 +1679,8 @@
 
             pw.println("  mSoundNotification=" + mSoundNotification);
             pw.println("  mVibrateNotification=" + mVibrateNotification);
-            pw.println("  mDisabledNotifications=0x"
-                    + Integer.toHexString(mDisabledNotifications));
+            pw.println("  mDisableNotificationAlerts=" + mDisableNotificationAlerts);
+            pw.println("  mZenMode=" + Settings.Global.zenModeToString(mZenMode));
             pw.println("  mSystemReady=" + mSystemReady);
             pw.println("  mArchive=" + mArchive.toString());
             Iterator<StatusBarNotification> iter = mArchive.descendingIterator();
@@ -1690,8 +1746,8 @@
         //     behalf of the download manager without affecting other apps.
         if (!pkg.equals("com.android.providers.downloads")
                 || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
-            EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, userId,
-                    notification.toString());
+            EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
+                    pkg, id, tag, userId, notification.toString());
         }
 
         if (pkg == null || notification == null) {
@@ -1768,9 +1824,13 @@
                     return;
                 }
 
-                // Should this notification make noise, vibe, or use the LED?
-                final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD);
+                // Is this notification intercepted by zen mode?
+                final boolean intercept = shouldIntercept(pkg, notification);
+                notification.extras.putBoolean(EXTRA_INTERCEPT, intercept);
 
+                // Should this notification make noise, vibe, or use the LED?
+                final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD) && !intercept;
+                if (DBG) Slog.v(TAG, "canInterrupt=" + canInterrupt + " intercept=" + intercept);
                 synchronized (mNotificationList) {
                     final StatusBarNotification n = new StatusBarNotification(
                             pkg, id, tag, callingUid, callingPid, score, notification, user);
@@ -1852,8 +1912,7 @@
                     }
 
                     // If we're not supposed to beep, vibrate, etc. then don't.
-                    if (((mDisabledNotifications
-                            & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
+                    if (!mDisableNotificationAlerts
                             && (!(old != null
                                 && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
                             && (r.getUserId() == UserHandle.USER_ALL ||
@@ -1861,7 +1920,7 @@
                             && canInterrupt
                             && mSystemReady
                             && mAudioManager != null) {
-
+                        if (DBG) Slog.v(TAG, "Interrupting!");
                         // sound
 
                         // should we use the default notification sound? (indicated either by
@@ -1906,6 +1965,8 @@
                                     final IRingtonePlayer player =
                                             mAudioManager.getRingtonePlayer();
                                     if (player != null) {
+                                        if (DBG) Slog.v(TAG, "Playing sound " + soundUri
+                                                + " on stream " + audioStreamType);
                                         player.playAsync(soundUri, user, looping, audioStreamType);
                                     }
                                 } catch (RemoteException e) {
@@ -1945,7 +2006,7 @@
                                         useDefaultVibrate ? mDefaultVibrationPattern
                                             : mFallbackVibrationPattern,
                                         ((notification.flags & Notification.FLAG_INSISTENT) != 0)
-                                                ? 0: -1);
+                                                ? 0: -1, notification.audioStreamType);
                                 } finally {
                                     Binder.restoreCallingIdentity(identity);
                                 }
@@ -1955,7 +2016,7 @@
                                 mVibrator.vibrate(r.sbn.getUid(), r.sbn.getBasePkg(),
                                         notification.vibrate,
                                     ((notification.flags & Notification.FLAG_INSISTENT) != 0)
-                                            ? 0: -1);
+                                            ? 0: -1, notification.audioStreamType);
                             }
                         }
                     }
@@ -2237,9 +2298,10 @@
      * Cancels a notification ONLY if it has all of the {@code mustHaveFlags}
      * and none of the {@code mustNotHaveFlags}.
      */
-    void cancelNotification(final String pkg, final String tag, final int id,
+    void cancelNotification(final int callingUid, final int callingPid,
+            final String pkg, final String tag, final int id,
             final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete,
-            final int userId) {
+            final int userId, final int reason, final NotificationListenerInfo listener) {
         // 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
@@ -2247,8 +2309,9 @@
         mHandler.post(new Runnable() {
             @Override
             public void run() {
-                EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId,
-                        mustHaveFlags, mustNotHaveFlags);
+                EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, id, tag, userId,
+                        mustHaveFlags, mustNotHaveFlags, reason,
+                        listener == null ? null : listener.component.toShortString());
 
                 synchronized (mNotificationList) {
                     int index = indexOfNotificationLocked(pkg, tag, id, userId);
@@ -2287,13 +2350,27 @@
     }
 
     /**
+     * Determine whether the userId applies to the notification in question, either because
+     * they match exactly, or one of them is USER_ALL (which is treated as a wildcard) or
+     * because it matches a related user.
+     */
+    private boolean notificationMatchesUserIdOrRelated(NotificationRecord r, int userId) {
+        synchronized (mRelatedUsers) {
+            return notificationMatchesUserId(r, userId)
+                    || mRelatedUsers.get(r.getUserId()) != null;
+        }
+    }
+
+    /**
      * Cancels all notifications from a given package that have all of the
      * {@code mustHaveFlags}.
      */
-    boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
-            int mustNotHaveFlags, boolean doit, int userId) {
-        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, userId,
-                mustHaveFlags, mustNotHaveFlags);
+    boolean cancelAllNotificationsInt(int callingUid, int callingPid, String pkg, int mustHaveFlags,
+            int mustNotHaveFlags, boolean doit, int userId, int reason,
+            NotificationListenerInfo listener) {
+        EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
+                pkg, userId, mustHaveFlags, mustNotHaveFlags, reason,
+                listener == null ? null : listener.component.toShortString());
 
         synchronized (mNotificationList) {
             final int N = mNotificationList.size();
@@ -2368,13 +2445,17 @@
         }
     }
 
-    void cancelAll(int userId) {
+    void cancelAll(int callingUid, int callingPid, int userId, int reason,
+            NotificationListenerInfo listener) {
+        EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
+                null, userId, 0, 0, reason,
+                listener == null ? null : listener.component.toShortString());
         synchronized (mNotificationList) {
             final int N = mNotificationList.size();
             for (int i=N-1; i>=0; i--) {
                 NotificationRecord r = mNotificationList.get(i);
 
-                if (!notificationMatchesUserId(r, userId)) {
+                if (!notificationMatchesUserIdOrRelated(r, userId)) {
                     continue;
                 }
 
@@ -2453,4 +2534,71 @@
             updateLightsLocked();
         }
     }
+
+    private void updateZenMode() {
+        final int mode = Settings.Global.getInt(getContext().getContentResolver(),
+                Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+        if (mode != mZenMode) {
+            Slog.d(TAG, String.format("updateZenMode: %s -> %s",
+                    Settings.Global.zenModeToString(mZenMode),
+                    Settings.Global.zenModeToString(mode)));
+        }
+        mZenMode = mode;
+
+        final String[] exceptionPackages = null; // none (for now)
+
+        // call restrictions
+        final boolean muteCalls = mZenMode != Settings.Global.ZEN_MODE_OFF;
+        mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, AudioManager.STREAM_RING,
+                muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+                exceptionPackages);
+        mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, AudioManager.STREAM_RING,
+                muteCalls ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+                exceptionPackages);
+
+        // alarm restrictions
+        final boolean muteAlarms = mZenMode == Settings.Global.ZEN_MODE_FULL;
+        mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, AudioManager.STREAM_ALARM,
+                muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+                exceptionPackages);
+        mAppOps.setRestriction(AppOpsManager.OP_PLAY_AUDIO, AudioManager.STREAM_ALARM,
+                muteAlarms ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+                exceptionPackages);
+
+        // restrict vibrations with no hints
+        mAppOps.setRestriction(AppOpsManager.OP_VIBRATE, AudioManager.USE_DEFAULT_STREAM_TYPE,
+                (muteAlarms || muteCalls) ? AppOpsManager.MODE_IGNORED : AppOpsManager.MODE_ALLOWED,
+                exceptionPackages);
+    }
+
+    private void updateRelatedUserCache(Context context) {
+        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        int currentUserId = ActivityManager.getCurrentUser();
+        if (userManager != null) {
+            List<UserInfo> relatedUsers = userManager.getRelatedUsers(currentUserId);
+            synchronized (mRelatedUsers) {
+                mRelatedUsers.clear();
+                for (UserInfo related : relatedUsers) {
+                    mRelatedUsers.put(related.id, related);
+                }
+            }
+        }
+    }
+
+    private boolean isCall(String pkg, Notification n) {
+        return CALL_PACKAGES.contains(pkg);
+    }
+
+    private boolean isAlarm(String pkg, Notification n) {
+        return ALARM_PACKAGES.contains(pkg);
+    }
+
+    private boolean shouldIntercept(String pkg, Notification n) {
+        if (mZenMode == Settings.Global.ZEN_MODE_LIMITED) {
+            return !isAlarm(pkg, n);
+        } else if (mZenMode == Settings.Global.ZEN_MODE_FULL) {
+            return true;
+        }
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/KeySetManager.java b/services/core/java/com/android/server/pm/KeySetManager.java
index 66dc1d1..1056cd0 100644
--- a/services/core/java/com/android/server/pm/KeySetManager.java
+++ b/services/core/java/com/android/server/pm/KeySetManager.java
@@ -20,13 +20,11 @@
 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;
diff --git a/services/core/java/com/android/server/pm/PackageKeySetData.java b/services/core/java/com/android/server/pm/PackageKeySetData.java
index cb60621..ebded28 100644
--- a/services/core/java/com/android/server/pm/PackageKeySetData.java
+++ b/services/core/java/com/android/server/pm/PackageKeySetData.java
@@ -18,9 +18,7 @@
 
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
 
 public class PackageKeySetData {
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 40ef5eb..a01c586 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -200,6 +200,9 @@
 
     private static final boolean GET_CERTIFICATES = true;
 
+    // Cap the size of permission trees that 3rd party apps can define
+    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
+
     private static final int REMOVE_EVENTS =
         FileObserver.CLOSE_WRITE | FileObserver.DELETE | FileObserver.MOVED_FROM;
     private static final int ADD_EVENTS =
@@ -302,12 +305,15 @@
     // This is the object monitoring the privileged system app dir.
     final FileObserver mPrivilegedInstallObserver;
 
-    // This is the object monitoring the system app dir.
+    // This is the object monitoring the vendor app dir.
     final FileObserver mVendorInstallObserver;
 
     // This is the object monitoring the vendor overlay package dir.
     final FileObserver mVendorOverlayInstallObserver;
 
+    // This is the object monitoring the OEM app dir.
+    final FileObserver mOemInstallObserver;
+
     // This is the object monitoring mAppInstallDir.
     final FileObserver mAppInstallObserver;
 
@@ -1157,7 +1163,12 @@
             sUserManager = new UserManagerService(context, this,
                     mInstallLock, mPackages);
 
-            readPermissions();
+            // Read permissions and features from system
+            readPermissions(Environment.buildPath(
+                    Environment.getRootDirectory(), "etc", "permissions"), false);
+            // Only read features from OEM
+            readPermissions(Environment.buildPath(
+                    Environment.getOemDirectory(), "etc", "permissions"), true);
 
             mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
 
@@ -1343,6 +1354,14 @@
             scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM
                     | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
 
+            // Collect all OEM packages.
+            File oemAppDir = new File(Environment.getOemDirectory(), "app");
+            mOemInstallObserver = new AppDirObserver(
+                    oemAppDir.getPath(), OBSERVER_EVENTS, true, false);
+            mOemInstallObserver.startWatching();
+            scanDirLI(oemAppDir, PackageParser.PARSE_IS_SYSTEM
+                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
+
             if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
             mInstaller.moveFiles();
 
@@ -1588,9 +1607,8 @@
         mSettings.removePackageLPw(ps.name);
     }
 
-    void readPermissions() {
+    void readPermissions(File libraryDir, boolean onlyFeatures) {
         // Read permissions from .../etc/permission directory.
-        File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
             Slog.w(TAG, "No directory " + libraryDir + ", skipping");
             return;
@@ -1616,16 +1634,16 @@
                 continue;
             }
 
-            readPermissionsFromXml(f);
+            readPermissionsFromXml(f, onlyFeatures);
         }
 
         // Read permissions from .../etc/permissions/platform.xml last so it will take precedence
         final File permFile = new File(Environment.getRootDirectory(),
                 "etc/permissions/platform.xml");
-        readPermissionsFromXml(permFile);
+        readPermissionsFromXml(permFile, onlyFeatures);
     }
 
-    private void readPermissionsFromXml(File permFile) {
+    private void readPermissionsFromXml(File permFile, boolean onlyFeatures) {
         FileReader permReader = null;
         try {
             permReader = new FileReader(permFile);
@@ -1647,7 +1665,7 @@
                 }
 
                 String name = parser.getName();
-                if ("group".equals(name)) {
+                if ("group".equals(name) && !onlyFeatures) {
                     String gidStr = parser.getAttributeValue(null, "gid");
                     if (gidStr != null) {
                         int gid = Process.getGidForName(gidStr);
@@ -1659,7 +1677,7 @@
 
                     XmlUtils.skipCurrentTag(parser);
                     continue;
-                } else if ("permission".equals(name)) {
+                } else if ("permission".equals(name) && !onlyFeatures) {
                     String perm = parser.getAttributeValue(null, "name");
                     if (perm == null) {
                         Slog.w(TAG, "<permission> without name at "
@@ -1670,7 +1688,7 @@
                     perm = perm.intern();
                     readPermission(parser, perm);
 
-                } else if ("assign-permission".equals(name)) {
+                } else if ("assign-permission".equals(name) && !onlyFeatures) {
                     String perm = parser.getAttributeValue(null, "name");
                     if (perm == null) {
                         Slog.w(TAG, "<assign-permission> without name at "
@@ -1702,7 +1720,7 @@
                     perms.add(perm);
                     XmlUtils.skipCurrentTag(parser);
 
-                } else if ("library".equals(name)) {
+                } else if ("library".equals(name) && !onlyFeatures) {
                     String lname = parser.getAttributeValue(null, "name");
                     String lfile = parser.getAttributeValue(null, "file");
                     if (lname == null) {
@@ -2342,7 +2360,35 @@
         //if (pi1.descriptionRes != pi2.descriptionRes) return false;
         return true;
     }
-    
+
+    int permissionInfoFootprint(PermissionInfo info) {
+        int size = info.name.length();
+        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
+        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
+        return size;
+    }
+
+    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
+        int size = 0;
+        for (BasePermission perm : mSettings.mPermissions.values()) {
+            if (perm.uid == tree.uid) {
+                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
+            }
+        }
+        return size;
+    }
+
+    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
+        // We calculate the max size of permissions defined by this uid and throw
+        // if that plus the size of 'info' would exceed our stated maximum.
+        if (tree.uid != Process.SYSTEM_UID) {
+            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
+            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
+                throw new SecurityException("Permission tree size cap exceeded");
+            }
+        }
+    }
+
     boolean addPermissionLocked(PermissionInfo info, boolean async) {
         if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
             throw new SecurityException("Label must be specified in permission");
@@ -2353,6 +2399,7 @@
         boolean changed = true;
         int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
         if (added) {
+            enforcePermissionCapLocked(info, tree);
             bp = new BasePermission(info.name, tree.sourcePackage,
                     BasePermission.TYPE_DYNAMIC);
         } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
@@ -2784,6 +2831,63 @@
         return null;
     }
 
+    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
+            int flags, List<ResolveInfo> query, boolean debug, int userId) {
+        final int N = query.size();
+        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
+                .get(userId);
+        // Get the list of persistent preferred activities that handle the intent
+        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
+        List<PersistentPreferredActivity> pprefs = ppir != null
+                ? ppir.queryIntent(intent, resolvedType,
+                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
+                : null;
+        if (pprefs != null && pprefs.size() > 0) {
+            final int M = pprefs.size();
+            for (int i=0; i<M; i++) {
+                final PersistentPreferredActivity ppa = pprefs.get(i);
+                if (DEBUG_PREFERRED || debug) {
+                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
+                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
+                            + "\n  component=" + ppa.mComponent);
+                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
+                }
+                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
+                        flags | PackageManager.GET_DISABLED_COMPONENTS, userId);
+                if (DEBUG_PREFERRED || debug) {
+                    Slog.v(TAG, "Found persistent preferred activity:");
+                    if (ai != null) {
+                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
+                    } else {
+                        Slog.v(TAG, "  null");
+                    }
+                }
+                if (ai == null) {
+                    // This previously registered persistent preferred activity
+                    // component is no longer known. Ignore it and do NOT remove it.
+                    continue;
+                }
+                for (int j=0; j<N; j++) {
+                    final ResolveInfo ri = query.get(j);
+                    if (!ri.activityInfo.applicationInfo.packageName
+                            .equals(ai.applicationInfo.packageName)) {
+                        continue;
+                    }
+                    if (!ri.activityInfo.name.equals(ai.name)) {
+                        continue;
+                    }
+                    //  Found a persistent preference that can handle the intent.
+                    if (DEBUG_PREFERRED || debug) {
+                        Slog.v(TAG, "Returning persistent preferred activity: " +
+                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
+                    }
+                    return ri;
+                }
+            }
+        }
+        return null;
+    }
+
     ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
             List<ResolveInfo> query, int priority, boolean always,
             boolean removeMatches, boolean debug, int userId) {
@@ -2794,6 +2898,16 @@
                 intent = intent.getSelector();
             }
             if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
+
+            // Try to find a matching persistent preferred activity.
+            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
+                    debug, userId);
+
+            // If a persistent preferred activity matched, use it.
+            if (pri != null) {
+                return pri;
+            }
+
             PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
             // Get the list of preferred activities that handle the intent
             if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
@@ -5121,8 +5235,9 @@
                             // discard the previous declaration and consider the system's to be
                             // canonical.
                             if (isSystemApp(p.owner)) {
-                                Slog.i(TAG, "New decl " + p.owner + " of permission  "
-                                        + p.info.name + " is system");
+                                String msg = "New decl " + p.owner + " of permission  "
+                                        + p.info.name + " is system";
+                                reportSettingsProblem(Log.WARN, msg);
                                 bp.sourcePackage = null;
                             }
                         }
@@ -6245,6 +6360,11 @@
         }
 
         public final void addProvider(PackageParser.Provider p) {
+            if (mProviders.containsKey(p.getComponentName())) {
+                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
+                return;
+            }
+
             mProviders.put(p.getComponentName(), p);
             if (DEBUG_SHOW_INFO) {
                 Log.v(TAG, "  "
@@ -10346,6 +10466,71 @@
     }
 
     @Override
+    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
+            int userId) {
+        int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException(
+                    "addPersistentPreferredActivity can only be run by the system");
+        }
+        if (filter.countActions() == 0) {
+            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
+            return;
+        }
+        synchronized (mPackages) {
+            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
+                    " :");
+            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
+            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
+                    new PersistentPreferredActivity(filter, activity));
+            mSettings.writePackageRestrictionsLPr(userId);
+        }
+    }
+
+    @Override
+    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
+        int callingUid = Binder.getCallingUid();
+        if (callingUid != Process.SYSTEM_UID) {
+            throw new SecurityException(
+                    "clearPackagePersistentPreferredActivities can only be run by the system");
+        }
+        ArrayList<PersistentPreferredActivity> removed = null;
+        boolean changed = false;
+        synchronized (mPackages) {
+            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
+                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
+                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
+                        .valueAt(i);
+                if (userId != thisUserId) {
+                    continue;
+                }
+                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
+                while (it.hasNext()) {
+                    PersistentPreferredActivity ppa = it.next();
+                    // Mark entry for removal only if it matches the package name.
+                    if (ppa.mComponent.getPackageName().equals(packageName)) {
+                        if (removed == null) {
+                            removed = new ArrayList<PersistentPreferredActivity>();
+                        }
+                        removed.add(ppa);
+                    }
+                }
+                if (removed != null) {
+                    for (int j=0; j<removed.size(); j++) {
+                        PersistentPreferredActivity ppa = removed.get(j);
+                        ppir.removeFilter(ppa);
+                    }
+                    changed = true;
+                }
+            }
+
+            if (changed) {
+                mSettings.writePackageRestrictionsLPr(userId);
+            }
+        }
+    }
+
+    @Override
     public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(Intent.CATEGORY_HOME);
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 7747c8f..2a5698b9 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -20,14 +20,11 @@
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
 
-import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageUserState;
-import android.content.pm.UserInfo;
 import android.util.SparseArray;
 
 import java.io.File;
 import java.util.HashSet;
-import java.util.List;
 
 /**
  * Settings base class for pending and resolved classes.
diff --git a/services/core/java/com/android/server/pm/PersistentPreferredActivity.java b/services/core/java/com/android/server/pm/PersistentPreferredActivity.java
new file mode 100644
index 0000000..4284a6d
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PersistentPreferredActivity.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.content.ComponentName;
+import android.content.IntentFilter;
+import android.util.Log;
+
+import java.io.IOException;
+
+class PersistentPreferredActivity extends IntentFilter {
+    private static final String ATTR_NAME = "name"; // component name
+    private static final String ATTR_FILTER = "filter"; // filter
+
+    private static final String TAG = "PersistentPreferredActivity";
+
+    private static final boolean DEBUG_FILTERS = false;
+
+    final ComponentName mComponent;
+
+    PersistentPreferredActivity(IntentFilter filter, ComponentName activity) {
+        super(filter);
+        mComponent = activity;
+    }
+
+    PersistentPreferredActivity(XmlPullParser parser) throws XmlPullParserException, IOException {
+        String shortComponent = parser.getAttributeValue(null, ATTR_NAME);
+        mComponent = ComponentName.unflattenFromString(shortComponent);
+        if (mComponent == null) {
+            PackageManagerService.reportSettingsProblem(Log.WARN,
+                    "Error in package manager settings <hard-preferred-activity>: " +
+                            "Bad activity name " + shortComponent +
+                            " at " + parser.getPositionDescription());
+        }
+        int outerDepth = parser.getDepth();
+        String tagName = parser.getName();
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+            tagName = parser.getName();
+            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+                continue;
+            } else if (type == XmlPullParser.START_TAG) {
+                if (tagName.equals(ATTR_FILTER)) {
+                    break;
+                } else {
+                    PackageManagerService.reportSettingsProblem(Log.WARN,
+                            "Unknown element under <hard-preferred-activity>: " + tagName +
+                            " at " + parser.getPositionDescription());
+                    XmlUtils.skipCurrentTag(parser);
+                }
+            }
+        }
+        if (tagName.equals(ATTR_FILTER)) {
+            readFromXml(parser);
+        } else {
+            PackageManagerService.reportSettingsProblem(Log.WARN,
+                    "Missing element under <hard-preferred-activity>: filter at " +
+                    parser.getPositionDescription());
+            XmlUtils.skipCurrentTag(parser);
+        }
+    }
+
+    public void writeToXml(XmlSerializer serializer) throws IOException {
+        serializer.attribute(null, ATTR_NAME, mComponent.flattenToShortString());
+        serializer.startTag(null, ATTR_FILTER);
+            super.writeToXml(serializer);
+        serializer.endTag(null, ATTR_FILTER);
+    }
+
+    @Override
+    public String toString() {
+        return "PersistentPreferredActivity{0x" + Integer.toHexString(System.identityHashCode(this))
+                + " " + mComponent.flattenToShortString() + "}";
+    }
+}
diff --git a/services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java b/services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java
new file mode 100644
index 0000000..9c8a9bd
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import java.io.PrintWriter;
+
+import com.android.server.IntentResolver;
+
+public class PersistentPreferredIntentResolver
+        extends IntentResolver<PersistentPreferredActivity, PersistentPreferredActivity> {
+    @Override
+    protected PersistentPreferredActivity[] newArray(int size) {
+        return new PersistentPreferredActivity[size];
+    }
+
+    @Override
+    protected boolean isPackageForFilter(String packageName, PersistentPreferredActivity filter) {
+        return packageName.equals(filter.mComponent.getPackageName());
+    }
+}
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index af7153f..d70c725 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -28,7 +28,6 @@
 import libcore.io.IoUtils;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileReader;
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8f18b23..9236bde 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -45,7 +45,6 @@
 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;
@@ -60,7 +59,6 @@
 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;
@@ -71,7 +69,6 @@
 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;
@@ -144,6 +141,11 @@
     final SparseArray<PreferredIntentResolver> mPreferredActivities =
             new SparseArray<PreferredIntentResolver>();
 
+    // The persistent preferred activities of the user's profile/device owner
+    // associated with particular intent filters.
+    final SparseArray<PersistentPreferredIntentResolver> mPersistentPreferredActivities =
+            new SparseArray<PersistentPreferredIntentResolver>();
+
     final HashMap<String, SharedUserSetting> mSharedUsers =
             new HashMap<String, SharedUserSetting>();
     private final ArrayList<Object> mUserIds = new ArrayList<Object>();
@@ -779,6 +781,15 @@
         return pir;
     }
 
+    PersistentPreferredIntentResolver editPersistentPreferredActivitiesLPw(int userId) {
+        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
+        if (ppir == null) {
+            ppir = new PersistentPreferredIntentResolver();
+            mPersistentPreferredActivities.put(userId, ppir);
+        }
+        return ppir;
+    }
+
     private File getUserPackagesStateFile(int userId) {
         return new File(Environment.getUserSystemDirectory(userId), "package-restrictions.xml");
     }
@@ -838,6 +849,27 @@
         }
     }
 
+    private void readPersistentPreferredActivitiesLPw(XmlPullParser parser, int userId)
+            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;
+            }
+            String tagName = parser.getName();
+            if (tagName.equals(TAG_ITEM)) {
+                PersistentPreferredActivity ppa = new PersistentPreferredActivity(parser);
+                editPersistentPreferredActivitiesLPw(userId).addFilter(ppa);
+            } else {
+                PackageManagerService.reportSettingsProblem(Log.WARN,
+                        "Unknown element under <hard-preferred-activities>: " + parser.getName());
+                XmlUtils.skipCurrentTag(parser);
+            }
+        }
+    }
+
     void readPackageRestrictionsLPr(int userId) {
         if (DEBUG_MU) {
             Log.i(TAG, "Reading package restrictions for user=" + userId);
@@ -964,6 +996,8 @@
                             enabledCaller, enabledComponents, disabledComponents);
                 } else if (tagName.equals("preferred-activities")) {
                     readPreferredActivitiesLPw(parser, userId);
+                } else if (tagName.equals("hard-preferred-activities")) {
+                    readPersistentPreferredActivitiesLPw(parser, userId);
                 } else {
                     Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
                           + parser.getName());
@@ -1027,6 +1061,20 @@
         serializer.endTag(null, "preferred-activities");
     }
 
+    void writePersistentPreferredActivitiesLPr(XmlSerializer serializer, int userId)
+            throws IllegalArgumentException, IllegalStateException, IOException {
+        serializer.startTag(null, "hard-preferred-activities");
+        PersistentPreferredIntentResolver ppir = mPersistentPreferredActivities.get(userId);
+        if (ppir != null) {
+            for (final PersistentPreferredActivity ppa : ppir.filterSet()) {
+                serializer.startTag(null, TAG_ITEM);
+                ppa.writeToXml(serializer);
+                serializer.endTag(null, TAG_ITEM);
+            }
+        }
+        serializer.endTag(null, "hard-preferred-activities");
+    }
+
     void writePackageRestrictionsLPr(int userId) {
         if (DEBUG_MU) {
             Log.i(TAG, "Writing package restrictions for user=" + userId);
@@ -1123,6 +1171,8 @@
 
             writePreferredActivitiesLPr(serializer, userId, true);
 
+            writePersistentPreferredActivitiesLPr(serializer, userId);
+
             serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
 
             serializer.endDocument();
@@ -1724,6 +1774,10 @@
                     // Upgrading from old single-user implementation;
                     // these are the preferred activities for user 0.
                     readPreferredActivitiesLPw(parser, 0);
+                } else if (tagName.equals("hard-preferred-activities")) {
+                    // TODO: check whether this is okay! as it is very
+                    // similar to how preferred-activities are treated
+                    readPersistentPreferredActivitiesLPw(parser, 0);
                 } else if (tagName.equals("updated-package")) {
                     readDisabledSysPackageLPw(parser);
                 } else if (tagName.equals("cleaning-package")) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index c33134a..7f55464 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -92,6 +92,7 @@
     private static final String ATTR_NEXT_SERIAL_NO = "nextSerialNumber";
     private static final String ATTR_PARTIAL = "partial";
     private static final String ATTR_USER_VERSION = "version";
+    private static final String ATTR_RELATED_GROUP_ID = "relatedGroupId";
     private static final String TAG_USERS = "users";
     private static final String TAG_USER = "user";
     private static final String TAG_RESTRICTIONS = "restrictions";
@@ -233,9 +234,7 @@
     }
 
     void systemReady() {
-        final Context context = ActivityThread.systemMain().getSystemContext();
-        mUserPackageMonitor.register(context,
-                null, UserHandle.ALL, false);
+        mUserPackageMonitor.register(mContext, null, UserHandle.ALL, false);
         userForeground(UserHandle.USER_OWNER);
     }
 
@@ -258,6 +257,29 @@
     }
 
     @Override
+    public List<UserInfo> getRelatedUsers(int userId) {
+        checkManageUsersPermission("query users");
+        synchronized (mPackagesLock) {
+            UserInfo user = getUserInfoLocked(userId);
+            ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
+            for (int i = 0; i < mUsers.size(); i++) {
+                UserInfo ui = mUsers.valueAt(i);
+                if (!areRelatedUsers(user, ui)) {
+                    continue;
+                }
+                users.add(ui);
+            }
+            return users;
+        }
+    }
+
+    private boolean areRelatedUsers(UserInfo user1, UserInfo user2) {
+        return user1.relatedGroupId != UserInfo.NO_RELATED_GROUP_ID &&
+                user1.relatedGroupId == user2.relatedGroupId &&
+                user1.id != user2.id;
+    }
+
+    @Override
     public UserInfo getUserInfo(int userId) {
         checkManageUsersPermission("query user");
         synchronized (mPackagesLock) {
@@ -433,7 +455,7 @@
 
     /**
      * Enforces that only the system UID or root's UID or apps that have the
-     * {@link android.Manifest.permission.MANAGE_USERS MANAGE_USERS}
+     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
      * permission can make certain calls to the UserManager.
      *
      * @param message used as message if SecurityException is thrown
@@ -662,6 +684,10 @@
             if (userInfo.partial) {
                 serializer.attribute(null, ATTR_PARTIAL, "true");
             }
+            if (userInfo.relatedGroupId != UserInfo.NO_RELATED_GROUP_ID) {
+                serializer.attribute(null, ATTR_RELATED_GROUP_ID,
+                        Integer.toString(userInfo.relatedGroupId));
+            }
 
             serializer.startTag(null, TAG_NAME);
             serializer.text(userInfo.name);
@@ -745,6 +771,7 @@
         long salt = 0L;
         String pinHash = null;
         int failedAttempts = 0;
+        int relatedGroupId = UserInfo.NO_RELATED_GROUP_ID;
         long lastAttemptTime = 0L;
         boolean partial = false;
         Bundle restrictions = new Bundle();
@@ -782,6 +809,8 @@
                 pinHash = parser.getAttributeValue(null, ATTR_PIN_HASH);
                 failedAttempts = readIntAttribute(parser, ATTR_FAILED_ATTEMPTS, 0);
                 lastAttemptTime = readLongAttribute(parser, ATTR_LAST_RETRY_MS, 0L);
+                relatedGroupId = readIntAttribute(parser, ATTR_RELATED_GROUP_ID,
+                        UserInfo.NO_RELATED_GROUP_ID);
                 String valueString = parser.getAttributeValue(null, ATTR_PARTIAL);
                 if ("true".equals(valueString)) {
                     partial = true;
@@ -820,6 +849,7 @@
             userInfo.creationTime = creationTime;
             userInfo.lastLoggedInTime = lastLoggedInTime;
             userInfo.partial = partial;
+            userInfo.relatedGroupId = relatedGroupId;
             mUserRestrictions.append(id, restrictions);
             if (salt != 0L) {
                 RestrictionsPinState pinState = mRestrictionsPinStates.get(id);
@@ -934,15 +964,44 @@
         }
     }
 
+    private int getNextRelatedGroupIdLocked() {
+        int maxGroupId = UserInfo.NO_RELATED_GROUP_ID;
+        for (int i = 0; i < mUsers.size(); i++) {
+            UserInfo ui = mUsers.valueAt(i);
+            if (maxGroupId < ui.relatedGroupId) {
+                maxGroupId = ui.relatedGroupId;
+            }
+        }
+        return maxGroupId + 1;
+    }
+
+    @Override
+    public UserInfo createRelatedUser(String name, int flags, int relatedUserId) {
+        checkManageUsersPermission("Only the system can create users");
+        if (relatedUserId != UserHandle.USER_OWNER) {
+            Slog.w(LOG_TAG, "Only user owner can have related users");
+            return null;
+        }
+        return createUserInternal(name, flags, relatedUserId);
+    }
+
     @Override
     public UserInfo createUser(String name, int flags) {
         checkManageUsersPermission("Only the system can create users");
+        return createUserInternal(name, flags, UserHandle.USER_NULL);
+    }
 
+    private UserInfo createUserInternal(String name, int flags, int relatedUserId) {
         final long ident = Binder.clearCallingIdentity();
-        final UserInfo userInfo;
+        UserInfo userInfo = null;
         try {
             synchronized (mInstallLock) {
                 synchronized (mPackagesLock) {
+                    UserInfo relatedUser = null;
+                    if (relatedUserId != UserHandle.USER_NULL) {
+                        relatedUser = getUserInfoLocked(relatedUserId);
+                        if (relatedUser == null) return null;
+                    }
                     if (isUserLimitReachedLocked()) return null;
                     int userId = getNextAvailableIdLocked();
                     userInfo = new UserInfo(userId, name, null, flags);
@@ -954,6 +1013,13 @@
                     Environment.getUserSystemDirectory(userInfo.id).mkdirs();
                     mUsers.put(userId, userInfo);
                     writeUserListLocked();
+                    if (relatedUser != null) {
+                        if (relatedUser.relatedGroupId == UserInfo.NO_RELATED_GROUP_ID) {
+                            relatedUser.relatedGroupId = getNextRelatedGroupIdLocked();
+                        }
+                        userInfo.relatedGroupId = relatedUser.relatedGroupId;
+                        writeUserLocked(relatedUser);
+                    }
                     writeUserLocked(userInfo);
                     mPm.createNewUserLILPw(userId, userPath);
                     userInfo.partial = false;
@@ -978,7 +1044,7 @@
     /**
      * Removes a user and all data directories created for that user. This method should be called
      * after the user's processes have been terminated.
-     * @param id the user's id
+     * @param userHandle the user's id
      */
     public boolean removeUser(int userHandle) {
         checkManageUsersPermission("Only the system can remove users");
diff --git a/services/core/java/com/android/server/power/AutomaticBrightnessController.java b/services/core/java/com/android/server/power/AutomaticBrightnessController.java
new file mode 100644
index 0000000..807262a
--- /dev/null
+++ b/services/core/java/com/android/server/power/AutomaticBrightnessController.java
@@ -0,0 +1,686 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.power;
+
+import com.android.server.twilight.TwilightListener;
+import com.android.server.twilight.TwilightManager;
+import com.android.server.twilight.TwilightState;
+
+import android.content.res.Resources;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.text.format.DateUtils;
+import android.util.MathUtils;
+import android.util.Spline;
+import android.util.Slog;
+import android.util.TimeUtils;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+
+class AutomaticBrightnessController {
+    private static final String TAG = "AutomaticBrightnessController";
+
+    private static final boolean DEBUG = false;
+    private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
+
+    // If true, enables the use of the screen auto-brightness adjustment setting.
+    private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT =
+            PowerManager.useScreenAutoBrightnessAdjustmentFeature();
+
+    // The maximum range of gamma adjustment possible using the screen
+    // auto-brightness adjustment setting.
+    private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
+
+    // Light sensor event rate in milliseconds.
+    private static final int LIGHT_SENSOR_RATE_MILLIS = 1000;
+
+    // Period of time in which to consider light samples in milliseconds.
+    private static final int AMBIENT_LIGHT_HORIZON = 10000;
+
+    // Stability requirements in milliseconds for accepting a new brightness level.  This is used
+    // for debouncing the light sensor.  Different constants are used to debounce the light sensor
+    // when adapting to brighter or darker environments.  This parameter controls how quickly
+    // brightness changes occur in response to an observed change in light level that exceeds the
+    // hysteresis threshold.
+    private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000;
+    private static final long DARKENING_LIGHT_DEBOUNCE = 8000;
+
+    // Hysteresis constraints for brightening or darkening.
+    // The recent lux must have changed by at least this fraction relative to the
+    // current ambient lux before a change will be considered.
+    private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
+    private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;
+
+    // The intercept used for the weighting calculation. This is used in order to keep all possible
+    // weighting values positive.
+    private static final int WEIGHTING_INTERCEPT = AMBIENT_LIGHT_HORIZON;
+
+    // How long the current sensor reading is assumed to be valid beyond the current time.
+    // This provides a bit of prediction, as well as ensures that the weight for the last sample is
+    // non-zero, which in turn ensures that the total weight is non-zero.
+    private static final long AMBIENT_LIGHT_PREDICTION_TIME_MILLIS = 100;
+
+    // If true, enables the use of the current time as an auto-brightness adjustment.
+    // The basic idea here is to expand the dynamic range of auto-brightness
+    // when it is especially dark outside.  The light sensor tends to perform
+    // poorly at low light levels so we compensate for it by making an
+    // assumption about the environment.
+    private static final boolean USE_TWILIGHT_ADJUSTMENT =
+            PowerManager.useTwilightAdjustmentFeature();
+
+    // Specifies the maximum magnitude of the time of day adjustment.
+    private static final float TWILIGHT_ADJUSTMENT_MAX_GAMMA = 1.5f;
+
+    // The amount of time after or before sunrise over which to start adjusting
+    // the gamma.  We want the change to happen gradually so that it is below the
+    // threshold of perceptibility and so that the adjustment has maximum effect
+    // well after dusk.
+    private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 2;
+
+    private static final int MSG_UPDATE_AMBIENT_LUX = 1;
+
+    // Callbacks for requesting updates to the the display's power state
+    private final Callbacks mCallbacks;
+
+    // The sensor manager.
+    private final SensorManager mSensorManager;
+
+    // The light sensor, or null if not available or needed.
+    private final Sensor mLightSensor;
+
+    // The twilight service.
+    private final TwilightManager mTwilight;
+
+    // The auto-brightness spline adjustment.
+    // The brightness values have been scaled to a range of 0..1.
+    private final Spline mScreenAutoBrightnessSpline;
+
+    // The minimum and maximum screen brightnesses.
+    private final int mScreenBrightnessRangeMinimum;
+    private final int mScreenBrightnessRangeMaximum;
+
+    // Amount of time to delay auto-brightness after screen on while waiting for
+    // the light sensor to warm-up in milliseconds.
+    // May be 0 if no warm-up is required.
+    private int mLightSensorWarmUpTimeConfig;
+
+    // Set to true if the light sensor is enabled.
+    private boolean mLightSensorEnabled;
+
+    // The time when the light sensor was enabled.
+    private long mLightSensorEnableTime;
+
+    // The currently accepted nominal ambient light level.
+    private float mAmbientLux;
+
+    // True if mAmbientLux holds a valid value.
+    private boolean mAmbientLuxValid;
+
+    // The ambient light level threshold at which to brighten or darken the screen.
+    private float mBrighteningLuxThreshold;
+    private float mDarkeningLuxThreshold;
+
+    // The most recent light sample.
+    private float mLastObservedLux;
+
+    // The time of the most light recent sample.
+    private long mLastObservedLuxTime;
+
+    // The number of light samples collected since the light sensor was enabled.
+    private int mRecentLightSamples;
+
+    // A ring buffer containing all of the recent ambient light sensor readings.
+    private AmbientLightRingBuffer mAmbientLightRingBuffer;
+
+    // The handler
+    private AutomaticBrightnessHandler mHandler;
+
+    // The screen brightness level that has been chosen by the auto-brightness
+    // algorithm.  The actual brightness should ramp towards this value.
+    // We preserve this value even when we stop using the light sensor so
+    // that we can quickly revert to the previous auto-brightness level
+    // while the light sensor warms up.
+    // Use -1 if there is no current auto-brightness value available.
+    private int mScreenAutoBrightness = -1;
+
+    // The screen auto-brightness adjustment factor in the range -1 (dimmer) to 1 (brighter)
+    private float mScreenAutoBrightnessAdjustment = 0.0f;
+
+    // The last screen auto-brightness gamma.  (For printing in dump() only.)
+    private float mLastScreenAutoBrightnessGamma = 1.0f;
+
+    public AutomaticBrightnessController(Callbacks callbacks, Looper looper,
+            TwilightManager twilight, SensorManager sensorManager, Spline autoBrightnessSpline,
+            int lightSensorWarmUpTime, int brightnessMin, int brightnessMax) {
+        mCallbacks = callbacks;
+        mTwilight = twilight;
+        mSensorManager = sensorManager;
+        mScreenAutoBrightnessSpline = autoBrightnessSpline;
+        mScreenBrightnessRangeMinimum = brightnessMin;
+        mScreenBrightnessRangeMaximum = brightnessMax;
+        mLightSensorWarmUpTimeConfig = lightSensorWarmUpTime;
+
+        mHandler = new AutomaticBrightnessHandler(looper);
+        mAmbientLightRingBuffer = new AmbientLightRingBuffer();
+
+        if (!DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
+            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+        }
+
+        if (USE_TWILIGHT_ADJUSTMENT) {
+            mTwilight.registerListener(mTwilightListener, mHandler);
+        }
+    }
+
+    public int getAutomaticScreenBrightness() {
+        return mScreenAutoBrightness;
+    }
+
+    public void updatePowerState(DisplayPowerRequest request) {
+        if (setScreenAutoBrightnessAdjustment(request.screenAutoBrightnessAdjustment)
+                || setLightSensorEnabled(request.wantLightSensorEnabled())) {
+            updateAutoBrightness(false /*sendUpdate*/);
+        }
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println();
+        pw.println("Automatic Brightness Controller Configuration:");
+        pw.println("  mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
+        pw.println("  mScreenBrightnessRangeMinimum=" + mScreenBrightnessRangeMinimum);
+        pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
+        pw.println("  mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
+
+        pw.println();
+        pw.println("Automatic Brightness Controller State:");
+        pw.println("  mLightSensor=" + mLightSensor);
+        pw.println("  mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
+        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
+        pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
+        pw.println("  mAmbientLux=" + mAmbientLux);
+        pw.println("  mBrighteningLuxThreshold=" + mBrighteningLuxThreshold);
+        pw.println("  mDarkeningLuxThreshold=" + mDarkeningLuxThreshold);
+        pw.println("  mLastObservedLux=" + mLastObservedLux);
+        pw.println("  mLastObservedLuxTime=" + TimeUtils.formatUptime(mLastObservedLuxTime));
+        pw.println("  mRecentLightSamples=" + mRecentLightSamples);
+        pw.println("  mAmbientLightRingBuffer=" + mAmbientLightRingBuffer);
+        pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
+        pw.println("  mScreenAutoBrightnessAdjustment=" + mScreenAutoBrightnessAdjustment);
+        pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
+    }
+
+    private boolean setLightSensorEnabled(boolean enable) {
+        if (enable) {
+            if (!mLightSensorEnabled) {
+                mLightSensorEnabled = true;
+                mLightSensorEnableTime = SystemClock.uptimeMillis();
+                mSensorManager.registerListener(mLightSensorListener, mLightSensor,
+                        LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
+                return true;
+            }
+        } else {
+            if (mLightSensorEnabled) {
+                mLightSensorEnabled = false;
+                mAmbientLuxValid = false;
+                mRecentLightSamples = 0;
+                mAmbientLightRingBuffer.clear();
+                mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
+                mSensorManager.unregisterListener(mLightSensorListener);
+            }
+        }
+        return false;
+    }
+
+    private void handleLightSensorEvent(long time, float lux) {
+        mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
+
+        applyLightSensorMeasurement(time, lux);
+        updateAmbientLux(time);
+    }
+
+    private void applyLightSensorMeasurement(long time, float lux) {
+        mRecentLightSamples++;
+        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
+        mAmbientLightRingBuffer.push(time, lux);
+
+        // Remember this sample value.
+        mLastObservedLux = lux;
+        mLastObservedLuxTime = time;
+    }
+
+    private boolean setScreenAutoBrightnessAdjustment(float adjustment) {
+        if (adjustment != mScreenAutoBrightnessAdjustment) {
+            mScreenAutoBrightnessAdjustment = adjustment;
+            return true;
+        }
+        return false;
+    }
+
+    private void setAmbientLux(float lux) {
+        mAmbientLux = lux;
+        mBrighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS);
+        mDarkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS);
+    }
+
+    private float calculateAmbientLux(long now) {
+        final int N = mAmbientLightRingBuffer.size();
+        if (N == 0) {
+            Slog.e(TAG, "calculateAmbientLux: No ambient light readings available");
+            return -1;
+        }
+        float sum = 0;
+        float totalWeight = 0;
+        long endTime = AMBIENT_LIGHT_PREDICTION_TIME_MILLIS;
+        for (int i = N - 1; i >= 0; i--) {
+            long startTime = (mAmbientLightRingBuffer.getTime(i) - now);
+            float weight = calculateWeight(startTime, endTime);
+            float lux = mAmbientLightRingBuffer.getLux(i);
+            if (DEBUG) {
+                Slog.d(TAG, "calculateAmbientLux: [" +
+                        (startTime) + ", " +
+                        (endTime) + "]: lux=" + lux + ", weight=" + weight);
+            }
+            totalWeight += weight;
+            sum += mAmbientLightRingBuffer.getLux(i) * weight;
+            endTime = startTime;
+        }
+        if (DEBUG) {
+            Slog.d(TAG, "calculateAmbientLux: totalWeight=" + totalWeight +
+                    ", newAmbientLux=" + (sum / totalWeight));
+        }
+        return sum / totalWeight;
+    }
+
+    private static float calculateWeight(long startDelta, long endDelta) {
+        return weightIntegral(endDelta) - weightIntegral(startDelta);
+    }
+
+    // Evaluates the integral of y = x + WEIGHTING_INTERCEPT. This is always positive for the
+    // horizon we're looking at and provides a non-linear weighting for light samples.
+    private static float weightIntegral(long x) {
+        return x * (x * 0.5f + WEIGHTING_INTERCEPT);
+    }
+
+    private long nextAmbientLightBrighteningTransition(long time) {
+        final int N = mAmbientLightRingBuffer.size();
+        long earliestValidTime = time;
+        for (int i = N - 1; i >= 0; i--) {
+            if (mAmbientLightRingBuffer.getLux(i) <= mBrighteningLuxThreshold) {
+                break;
+            }
+            earliestValidTime = mAmbientLightRingBuffer.getTime(i);
+        }
+        return earliestValidTime + BRIGHTENING_LIGHT_DEBOUNCE;
+    }
+
+    private long nextAmbientLightDarkeningTransition(long time) {
+        final int N = mAmbientLightRingBuffer.size();
+        long earliestValidTime = time;
+        for (int i = N - 1; i >= 0; i--) {
+            if (mAmbientLightRingBuffer.getLux(i) >= mDarkeningLuxThreshold) {
+                break;
+            }
+            earliestValidTime = mAmbientLightRingBuffer.getTime(i);
+        }
+        return earliestValidTime + DARKENING_LIGHT_DEBOUNCE;
+    }
+
+    private void updateAmbientLux() {
+        long time = SystemClock.uptimeMillis();
+        mAmbientLightRingBuffer.prune(time - AMBIENT_LIGHT_HORIZON);
+        updateAmbientLux(time);
+    }
+
+    private void updateAmbientLux(long time) {
+        // If the light sensor was just turned on then immediately update our initial
+        // estimate of the current ambient light level.
+        if (!mAmbientLuxValid) {
+            final long timeWhenSensorWarmedUp =
+                mLightSensorWarmUpTimeConfig + mLightSensorEnableTime;
+            if (time < timeWhenSensorWarmedUp) {
+                if (DEBUG) {
+                    Slog.d(TAG, "updateAmbientLux: Sensor not  ready yet: "
+                            + "time=" + time
+                            + ", timeWhenSensorWarmedUp=" + timeWhenSensorWarmedUp);
+                }
+                mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX,
+                        timeWhenSensorWarmedUp);
+                return;
+            }
+            setAmbientLux(calculateAmbientLux(time));
+            mAmbientLuxValid = true;
+            if (DEBUG) {
+                Slog.d(TAG, "updateAmbientLux: Initializing: "
+                        + "mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
+                        + ", mAmbientLux=" + mAmbientLux);
+            }
+            updateAutoBrightness(true);
+        }
+
+        long nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
+        long nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
+        float ambientLux = calculateAmbientLux(time);
+
+        if (ambientLux >= mBrighteningLuxThreshold && nextBrightenTransition <= time
+                || ambientLux <= mDarkeningLuxThreshold && nextDarkenTransition <= time) {
+            setAmbientLux(ambientLux);
+            if (DEBUG) {
+                Slog.d(TAG, "updateAmbientLux: "
+                        + ((ambientLux > mAmbientLux) ? "Brightened" : "Darkened") + ": "
+                        + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
+                        + ", mAmbientLightRingBuffer=" + mAmbientLightRingBuffer
+                        + ", mAmbientLux=" + mAmbientLux);
+            }
+            updateAutoBrightness(true);
+            nextBrightenTransition = nextAmbientLightBrighteningTransition(time);
+            nextDarkenTransition = nextAmbientLightDarkeningTransition(time);
+        }
+        long nextTransitionTime = Math.min(nextDarkenTransition, nextBrightenTransition);
+        // If one of the transitions is ready to occur, but the total weighted ambient lux doesn't
+        // exceed the necessary threshold, then it's possible we'll get a transition time prior to
+        // now. Rather than continually checking to see whether the weighted lux exceeds the
+        // threshold, schedule an update for when we'd normally expect another light sample, which
+        // should be enough time to decide whether we should actually transition to the new
+        // weighted ambient lux or not.
+        nextTransitionTime =
+                nextTransitionTime > time ? nextTransitionTime : time + LIGHT_SENSOR_RATE_MILLIS;
+        if (DEBUG) {
+            Slog.d(TAG, "updateAmbientLux: Scheduling ambient lux update for "
+                    + nextTransitionTime + TimeUtils.formatUptime(nextTransitionTime));
+        }
+        mHandler.sendEmptyMessageAtTime(MSG_UPDATE_AMBIENT_LUX, nextTransitionTime);
+    }
+
+    private void updateAutoBrightness(boolean sendUpdate) {
+        if (!mAmbientLuxValid) {
+            return;
+        }
+
+        float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
+        float gamma = 1.0f;
+
+        if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
+                && mScreenAutoBrightnessAdjustment != 0.0f) {
+            final float adjGamma = MathUtils.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
+                    Math.min(1.0f, Math.max(-1.0f, -mScreenAutoBrightnessAdjustment)));
+            gamma *= adjGamma;
+            if (DEBUG) {
+                Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
+            }
+        }
+
+        if (USE_TWILIGHT_ADJUSTMENT) {
+            TwilightState state = mTwilight.getCurrentState();
+            if (state != null && state.isNight()) {
+                final long now = System.currentTimeMillis();
+                final float earlyGamma =
+                        getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
+                final float lateGamma =
+                        getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
+                gamma *= earlyGamma * lateGamma;
+                if (DEBUG) {
+                    Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
+                            + ", lateGamma=" + lateGamma);
+                }
+            }
+        }
+
+        if (gamma != 1.0f) {
+            final float in = value;
+            value = MathUtils.pow(value, gamma);
+            if (DEBUG) {
+                Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
+                        + ", in=" + in + ", out=" + value);
+            }
+        }
+
+        int newScreenAutoBrightness =
+            clampScreenBrightness(Math.round(value * PowerManager.BRIGHTNESS_ON));
+        if (mScreenAutoBrightness != newScreenAutoBrightness) {
+            if (DEBUG) {
+                Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
+                        + mScreenAutoBrightness + ", newScreenAutoBrightness="
+                        + newScreenAutoBrightness);
+            }
+
+            mScreenAutoBrightness = newScreenAutoBrightness;
+            mLastScreenAutoBrightnessGamma = gamma;
+            if (sendUpdate) {
+                mCallbacks.updateBrightness();
+            }
+        }
+    }
+
+    private int clampScreenBrightness(int value) {
+        return MathUtils.constrain(value,
+                mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
+    }
+
+    private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
+        if (lastSunset < 0 || nextSunrise < 0
+                || now < lastSunset || now > nextSunrise) {
+            return 1.0f;
+        }
+
+        if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
+            return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
+                    (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
+        }
+
+        if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
+            return MathUtils.lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
+                    (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
+        }
+
+        return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
+    }
+
+    private final class AutomaticBrightnessHandler extends Handler {
+        public AutomaticBrightnessHandler(Looper looper) {
+            super(looper, null, true /*async*/);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_AMBIENT_LUX:
+                    updateAmbientLux();
+                    break;
+            }
+        }
+    }
+
+    private final SensorEventListener mLightSensorListener = new SensorEventListener() {
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            if (mLightSensorEnabled) {
+                final long time = SystemClock.uptimeMillis();
+                final float lux = event.values[0];
+                handleLightSensorEvent(time, lux);
+            }
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // Not used.
+        }
+    };
+
+    private final TwilightListener mTwilightListener = new TwilightListener() {
+        @Override
+        public void onTwilightStateChanged() {
+            updateAutoBrightness(true /*sendUpdate*/);
+        }
+    };
+
+    /** Callbacks to request updates to the display's power state. */
+    interface Callbacks {
+        void updateBrightness();
+    }
+
+    private static final class AmbientLightRingBuffer{
+        // Proportional extra capacity of the buffer beyond the expected number of light samples
+        // in the horizon
+        private static final float BUFFER_SLACK = 1.5f;
+        private static final int DEFAULT_CAPACITY =
+            (int) Math.ceil(AMBIENT_LIGHT_HORIZON * BUFFER_SLACK / LIGHT_SENSOR_RATE_MILLIS);
+        private float[] mRingLux;
+        private long[] mRingTime;
+        private int mCapacity;
+
+        // The first valid element and the next open slot.
+        // Note that if mCount is zero then there are no valid elements.
+        private int mStart;
+        private int mEnd;
+        private int mCount;
+
+        public AmbientLightRingBuffer() {
+            this(DEFAULT_CAPACITY);
+        }
+
+        public AmbientLightRingBuffer(int initialCapacity) {
+            mCapacity = initialCapacity;
+            mRingLux = new float[mCapacity];
+            mRingTime = new long[mCapacity];
+        }
+
+        public float getLux(int index) {
+            return mRingLux[offsetOf(index)];
+        }
+
+        public long getTime(int index) {
+            return mRingTime[offsetOf(index)];
+        }
+
+        public void push(long time, float lux) {
+            int next = mEnd;
+            if (mCount == mCapacity) {
+                int newSize = mCapacity * 2;
+
+                float[] newRingLux = new float[newSize];
+                long[] newRingTime = new long[newSize];
+                int length = mCapacity - mStart;
+                System.arraycopy(mRingLux, mStart, newRingLux, 0, length);
+                System.arraycopy(mRingTime, mStart, newRingTime, 0, length);
+                if (mStart != 0) {
+                    System.arraycopy(mRingLux, 0, newRingLux, length, mStart);
+                    System.arraycopy(mRingTime, 0, newRingTime, length, mStart);
+                }
+                mRingLux = newRingLux;
+                mRingTime = newRingTime;
+
+                next = mCapacity;
+                mCapacity = newSize;
+                mStart = 0;
+            }
+            mRingTime[next] = time;
+            mRingLux[next] = lux;
+            mEnd = next + 1;
+            if (mEnd == mCapacity) {
+                mEnd = 0;
+            }
+            mCount++;
+        }
+
+        public void prune(long horizon) {
+            if (mCount == 0) {
+                return;
+            }
+
+            while (mCount > 1) {
+                int next = mStart + 1;
+                if (next >= mCapacity) {
+                    next -= mCapacity;
+                }
+                if (mRingTime[next] > horizon) {
+                    // Some light sensors only produce data upon a change in the ambient light
+                    // levels, so we need to consider the previous measurement as the ambient light
+                    // level for all points in time up until we receive a new measurement. Thus, we
+                    // always want to keep the youngest element that would be removed from the
+                    // buffer and just set its measurement time to the horizon time since at that
+                    // point it is the ambient light level, and to remove it would be to drop a
+                    // valid data point within our horizon.
+                    break;
+                }
+                mStart = next;
+                mCount -= 1;
+            }
+
+            if (mRingTime[mStart] < horizon) {
+                mRingTime[mStart] = horizon;
+            }
+        }
+
+        public int size() {
+            return mCount;
+        }
+
+        public boolean isEmpty() {
+            return mCount == 0;
+        }
+
+        public void clear() {
+            mStart = 0;
+            mEnd = 0;
+            mCount = 0;
+        }
+
+        @Override
+        public String toString() {
+            final int length = mCapacity - mStart;
+            float[] lux = new float[mCount];
+            long[] time = new long[mCount];
+
+            if (mCount <= length) {
+                System.arraycopy(mRingLux, mStart, lux, 0, mCount);
+                System.arraycopy(mRingTime, mStart, time, 0, mCount);
+            } else {
+                System.arraycopy(mRingLux, mStart, lux, 0, length);
+                System.arraycopy(mRingLux, 0, lux, length, mCount - length);
+
+                System.arraycopy(mRingTime, mStart, time, 0, length);
+                System.arraycopy(mRingTime, 0, time, length, mCount - length);
+            }
+            return "AmbientLightRingBuffer{mCapacity=" + mCapacity
+                + ", mStart=" + mStart
+                + ", mEnd=" + mEnd
+                + ", mCount=" + mCount
+                + ", mRingLux=" + Arrays.toString(lux)
+                + ", mRingTime=" + Arrays.toString(time)
+                + "}";
+        }
+
+        private int offsetOf(int index) {
+            if (index >= mCount || index < 0) {
+                throw new ArrayIndexOutOfBoundsException(index);
+            }
+            index += mStart;
+            if (index >= mCapacity) {
+                index -= mCapacity;
+            }
+            return index;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/power/DisplayPowerController.java b/services/core/java/com/android/server/power/DisplayPowerController.java
index e83f734..6d3702a 100644
--- a/services/core/java/com/android/server/power/DisplayPowerController.java
+++ b/services/core/java/com/android/server/power/DisplayPowerController.java
@@ -35,7 +35,7 @@
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.text.format.DateUtils;
-import android.util.FloatMath;
+import android.util.MathUtils;
 import android.util.Slog;
 import android.util.Spline;
 import android.util.TimeUtils;
@@ -64,12 +64,11 @@
  * For debugging, you can make the electron beam and brightness animations run
  * slower by changing the "animator duration scale" option in Development Settings.
  */
-final class DisplayPowerController {
+final class DisplayPowerController implements AutomaticBrightnessController.Callbacks {
     private static final String TAG = "DisplayPowerController";
 
     private static boolean DEBUG = false;
     private static final boolean DEBUG_PRETEND_PROXIMITY_SENSOR_ABSENT = false;
-    private static final boolean DEBUG_PRETEND_LIGHT_SENSOR_ABSENT = false;
 
     // If true, uses the electron beam on animation.
     // We might want to turn this off if we cannot get a guarantee that the screen
@@ -77,13 +76,6 @@
     // screen state returns.  Playing the animation can also be somewhat slow.
     private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false;
 
-    // If true, enables the use of the screen auto-brightness adjustment setting.
-    private static final boolean USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT =
-            PowerManager.useScreenAutoBrightnessAdjustmentFeature();
-
-    // The maximum range of gamma adjustment possible using the screen
-    // auto-brightness adjustment setting.
-    private static final float SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA = 3.0f;
 
     // The minimum reduction in brightness when dimmed.
     private static final int SCREEN_DIM_MINIMUM_REDUCTION = 10;
@@ -110,7 +102,6 @@
 
     private static final int MSG_UPDATE_POWER_STATE = 1;
     private static final int MSG_PROXIMITY_SENSOR_DEBOUNCED = 2;
-    private static final int MSG_LIGHT_SENSOR_DEBOUNCED = 3;
 
     private static final int PROXIMITY_UNKNOWN = -1;
     private static final int PROXIMITY_NEGATIVE = 0;
@@ -123,41 +114,10 @@
     // Trigger proximity if distance is less than 5 cm.
     private static final float TYPICAL_PROXIMITY_THRESHOLD = 5.0f;
 
-    // Light sensor event rate in milliseconds.
-    private static final int LIGHT_SENSOR_RATE_MILLIS = 1000;
-
-    // A rate for generating synthetic light sensor events in the case where the light
-    // sensor hasn't reported any new data in a while and we need it to update the
-    // debounce filter.  We only synthesize light sensor measurements when needed.
-    private static final int SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS =
-            LIGHT_SENSOR_RATE_MILLIS * 2;
-
     // Brightness animation ramp rate in brightness units per second.
     private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
     private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40;
 
-    // IIR filter time constants in milliseconds for computing two moving averages of
-    // the light samples.  One is a long-term average and the other is a short-term average.
-    // We can use these filters to assess trends in ambient brightness.
-    // The short term average gives us a filtered but relatively low latency measurement.
-    // The long term average informs us about the overall trend.
-    private static final long SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 1000;
-    private static final long LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT = 5000;
-
-    // Stability requirements in milliseconds for accepting a new brightness
-    // level.  This is used for debouncing the light sensor.  Different constants
-    // are used to debounce the light sensor when adapting to brighter or darker environments.
-    // This parameter controls how quickly brightness changes occur in response to
-    // an observed change in light level that exceeds the hysteresis threshold.
-    private static final long BRIGHTENING_LIGHT_DEBOUNCE = 4000;
-    private static final long DARKENING_LIGHT_DEBOUNCE = 8000;
-
-    // Hysteresis constraints for brightening or darkening.
-    // The recent lux must have changed by at least this fraction relative to the
-    // current ambient lux before a change will be considered.
-    private static final float BRIGHTENING_LIGHT_HYSTERESIS = 0.10f;
-    private static final float DARKENING_LIGHT_HYSTERESIS = 0.20f;
-
     private final Object mLock = new Object();
 
     // Notifier for sending asynchronous notifications.
@@ -181,18 +141,12 @@
     // The lights service.
     private final LightsManager mLights;
 
-    // The twilight service.
-    private final TwilightManager mTwilight;
-
     // The sensor manager.
     private final SensorManager mSensorManager;
 
     // The proximity sensor, or null if not available or needed.
     private Sensor mProximitySensor;
 
-    // The light sensor, or null if not available or needed.
-    private Sensor mLightSensor;
-
     // The doze screen brightness.
     private final int mScreenBrightnessDozeConfig;
 
@@ -208,15 +162,6 @@
     // True if auto-brightness should be used.
     private boolean mUseSoftwareAutoBrightnessConfig;
 
-    // The auto-brightness spline adjustment.
-    // The brightness values have been scaled to a range of 0..1.
-    private Spline mScreenAutoBrightnessSpline;
-
-    // Amount of time to delay auto-brightness after screen on while waiting for
-    // the light sensor to warm-up in milliseconds.
-    // May be 0 if no warm-up is required.
-    private int mLightSensorWarmUpTimeConfig;
-
     // True if we should fade the screen while turning it off, false if we should play
     // a stylish electron beam animation instead.
     private boolean mElectronBeamFadesConfig;
@@ -286,67 +231,18 @@
     // The elapsed real time when the screen on was blocked.
     private long mScreenOnBlockStartRealTime;
 
-    // Set to true if the light sensor is enabled.
-    private boolean mLightSensorEnabled;
-
-    // The time when the light sensor was enabled.
-    private long mLightSensorEnableTime;
-
-    // The currently accepted nominal ambient light level.
-    private float mAmbientLux;
-
-    // True if mAmbientLux holds a valid value.
-    private boolean mAmbientLuxValid;
-
-    // The ambient light level threshold at which to brighten or darken the screen.
-    private float mBrighteningLuxThreshold;
-    private float mDarkeningLuxThreshold;
-
-    // The most recent light sample.
-    private float mLastObservedLux;
-
-    // The time of the most light recent sample.
-    private long mLastObservedLuxTime;
-
-    // The number of light samples collected since the light sensor was enabled.
-    private int mRecentLightSamples;
-
-    // The long-term and short-term filtered light measurements.
-    private float mRecentShortTermAverageLux;
-    private float mRecentLongTermAverageLux;
-
-    // The direction in which the average lux is moving relative to the current ambient lux.
-    //    0 if not changing or within hysteresis threshold.
-    //    1 if brightening beyond hysteresis threshold.
-    //   -1 if darkening beyond hysteresis threshold.
-    private int mDebounceLuxDirection;
-
-    // The time when the average lux last changed direction.
-    private long mDebounceLuxTime;
-
-    // The screen brightness level that has been chosen by the auto-brightness
-    // algorithm.  The actual brightness should ramp towards this value.
-    // We preserve this value even when we stop using the light sensor so
-    // that we can quickly revert to the previous auto-brightness level
-    // while the light sensor warms up.
-    // Use -1 if there is no current auto-brightness value available.
-    private int mScreenAutoBrightness = -1;
-
-    // The last screen auto-brightness gamma.  (For printing in dump() only.)
-    private float mLastScreenAutoBrightnessGamma = 1.0f;
-
     // True if the screen auto-brightness value is actually being used to
     // set the display brightness.
     private boolean mUsingScreenAutoBrightness;
 
+    // The controller for the automatic brightness level.
+    private AutomaticBrightnessController mAutomaticBrightnessController;
+
     // Animators.
     private ObjectAnimator mElectronBeamOnAnimator;
     private ObjectAnimator mElectronBeamOffAnimator;
     private RampAnimator<DisplayPowerState> mScreenBrightnessRampAnimator;
 
-    // Twilight changed.  We might recalculate auto-brightness values.
-    private boolean mTwilightChanged;
-
     /**
      * Creates the display power controller.
      */
@@ -362,7 +258,6 @@
         mCallbackHandler = callbackHandler;
 
         mLights = lights;
-        mTwilight = twilight;
         mSensorManager = sensorManager;
 
         final Resources resources = context.getResources();
@@ -373,9 +268,11 @@
         mScreenBrightnessDimConfig = clampAbsoluteBrightness(resources.getInteger(
                 com.android.internal.R.integer.config_screenBrightnessDim));
 
-        int screenBrightnessMinimum = Math.min(resources.getInteger(
+        int screenBrightnessRangeMinimum = clampAbsoluteBrightness(Math.min(resources.getInteger(
                 com.android.internal.R.integer.config_screenBrightnessSettingMinimum),
-                mScreenBrightnessDimConfig);
+                mScreenBrightnessDimConfig));
+
+        mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
 
         mUseSoftwareAutoBrightnessConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_automatic_brightness_available);
@@ -384,9 +281,11 @@
                     com.android.internal.R.array.config_autoBrightnessLevels);
             int[] screenBrightness = resources.getIntArray(
                     com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);
+            int lightSensorWarmUpTimeConfig = resources.getInteger(
+                    com.android.internal.R.integer.config_lightSensorWarmupTime);
 
-            mScreenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
-            if (mScreenAutoBrightnessSpline == null) {
+            Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);
+            if (screenAutoBrightnessSpline == null) {
                 Slog.e(TAG, "Error in config.xml.  config_autoBrightnessLcdBacklightValues "
                         + "(size " + screenBrightness.length + ") "
                         + "must be monotic and have exactly one more entry than "
@@ -395,17 +294,17 @@
                         + "Auto-brightness will be disabled.");
                 mUseSoftwareAutoBrightnessConfig = false;
             } else {
-                if (screenBrightness[0] < screenBrightnessMinimum) {
-                    screenBrightnessMinimum = screenBrightness[0];
+                if (screenBrightness[0] < screenBrightnessRangeMinimum) {
+                    screenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightness[0]);
                 }
+                mAutomaticBrightnessController = new AutomaticBrightnessController(this, looper,
+                        twilight, sensorManager, screenAutoBrightnessSpline,
+                        lightSensorWarmUpTimeConfig, screenBrightnessRangeMinimum,
+                        mScreenBrightnessRangeMaximum);
             }
-
-            mLightSensorWarmUpTimeConfig = resources.getInteger(
-                    com.android.internal.R.integer.config_lightSensorWarmupTime);
         }
 
-        mScreenBrightnessRangeMinimum = clampAbsoluteBrightness(screenBrightnessMinimum);
-        mScreenBrightnessRangeMaximum = PowerManager.BRIGHTNESS_ON;
+        mScreenBrightnessRangeMinimum = screenBrightnessRangeMinimum;
 
         mElectronBeamFadesConfig = resources.getBoolean(
                 com.android.internal.R.bool.config_animateScreenLights);
@@ -418,39 +317,6 @@
             }
         }
 
-        if (mUseSoftwareAutoBrightnessConfig
-                && !DEBUG_PRETEND_LIGHT_SENSOR_ABSENT) {
-            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
-        }
-
-        if (mUseSoftwareAutoBrightnessConfig && USE_TWILIGHT_ADJUSTMENT) {
-            mTwilight.registerListener(mTwilightListener, mHandler);
-        }
-    }
-
-    private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
-        try {
-            final int n = brightness.length;
-            float[] x = new float[n];
-            float[] y = new float[n];
-            y[0] = normalizeAbsoluteBrightness(brightness[0]);
-            for (int i = 1; i < n; i++) {
-                x[i] = lux[i - 1];
-                y[i] = normalizeAbsoluteBrightness(brightness[i]);
-            }
-
-            Spline spline = Spline.createMonotoneCubicSpline(x, y);
-            if (DEBUG) {
-                Slog.d(TAG, "Auto-brightness spline: " + spline);
-                for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
-                    Slog.d(TAG, String.format("  %7.1f: %7.1f", v, spline.interpolate(v)));
-                }
-            }
-            return spline;
-        } catch (IllegalArgumentException ex) {
-            Slog.e(TAG, "Could not create auto-brightness spline.", ex);
-            return null;
-        }
     }
 
     /**
@@ -542,6 +408,14 @@
 
         mScreenBrightnessRampAnimator = new RampAnimator<DisplayPowerState>(
                 mPowerState, DisplayPowerState.SCREEN_BRIGHTNESS);
+
+        // Initialize screen on state.
+        if (mPowerState.isScreenOn()) {
+            mNotifier.onScreenOn();
+        } else {
+            mNotifier.onScreenOff();
+        }
+        mNotifier.onScreenBrightness(mPowerState.getScreenBrightness());
     }
 
     private final Animator.AnimatorListener mAnimatorListener = new Animator.AnimatorListener() {
@@ -564,9 +438,7 @@
         // Update the power state request.
         final boolean mustNotify;
         boolean mustInitialize = false;
-        boolean updateAutoBrightness = mTwilightChanged;
         boolean wasDimOrDoze = false;
-        mTwilightChanged = false;
 
         synchronized (mLock) {
             mPendingUpdatePowerStateLocked = false;
@@ -581,10 +453,6 @@
                 mPendingRequestChangedLocked = false;
                 mustInitialize = true;
             } else if (mPendingRequestChangedLocked) {
-                if (mPowerRequest.screenAutoBrightnessAdjustment
-                        != mPendingRequestLocked.screenAutoBrightnessAdjustment) {
-                    updateAutoBrightness = true;
-                }
                 wasDimOrDoze = (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DIM
                         || mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_DOZE);
                 mPowerRequest.copyFrom(mPendingRequestLocked);
@@ -631,18 +499,19 @@
         }
 
         // Turn on the light sensor if needed.
-        if (mLightSensor != null) {
-            setLightSensorEnabled(mPowerRequest.wantLightSensorEnabled(),
-                    updateAutoBrightness);
+        if (mAutomaticBrightnessController != null) {
+            mAutomaticBrightnessController.updatePowerState(mPowerRequest);
         }
 
         // Set the screen brightness.
         if (mPowerRequest.wantScreenOnAny()) {
             int target;
             boolean slow;
-            if (mScreenAutoBrightness >= 0 && mLightSensorEnabled) {
+            int screenAutoBrightness = mAutomaticBrightnessController != null ?
+                    mAutomaticBrightnessController.getAutomaticScreenBrightness() : -1;
+            if (screenAutoBrightness >= 0 && mPowerRequest.useAutoBrightness) {
                 // Use current auto-brightness value.
-                target = mScreenAutoBrightness;
+                target = screenAutoBrightness;
                 slow = mUsingScreenAutoBrightness;
                 mUsingScreenAutoBrightness = true;
             } else {
@@ -756,6 +625,11 @@
         }
     }
 
+    @Override
+    public void updateBrightness() {
+        sendUpdatePowerState();
+    }
+
     private void blockScreenOn() {
         if (!mScreenOnWasBlocked) {
             mScreenOnWasBlocked = true;
@@ -788,25 +662,8 @@
     }
 
     private int clampScreenBrightness(int value) {
-        return clamp(value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
-    }
-
-    private static int clampAbsoluteBrightness(int value) {
-        return clamp(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
-    }
-
-    private static int clamp(int value, int min, int max) {
-        if (value <= min) {
-            return min;
-        }
-        if (value >= max) {
-            return max;
-        }
-        return value;
-    }
-
-    private static float normalizeAbsoluteBrightness(int value) {
-        return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
+        return MathUtils.constrain(
+                value, mScreenBrightnessRangeMinimum, mScreenBrightnessRangeMaximum);
     }
 
     private void animateScreenBrightness(int target, int rate) {
@@ -907,270 +764,6 @@
         mPendingProximityDebounceTime = debounceTime;
     }
 
-    private void setLightSensorEnabled(boolean enable, boolean updateAutoBrightness) {
-        if (enable) {
-            if (!mLightSensorEnabled) {
-                updateAutoBrightness = true;
-                mLightSensorEnabled = true;
-                mLightSensorEnableTime = SystemClock.uptimeMillis();
-                mSensorManager.registerListener(mLightSensorListener, mLightSensor,
-                        LIGHT_SENSOR_RATE_MILLIS * 1000, mHandler);
-            }
-        } else {
-            if (mLightSensorEnabled) {
-                mLightSensorEnabled = false;
-                mAmbientLuxValid = false;
-                mRecentLightSamples = 0;
-                mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
-                mSensorManager.unregisterListener(mLightSensorListener);
-            }
-        }
-        if (updateAutoBrightness) {
-            updateAutoBrightness(false);
-        }
-    }
-
-    private void handleLightSensorEvent(long time, float lux) {
-        mHandler.removeMessages(MSG_LIGHT_SENSOR_DEBOUNCED);
-
-        applyLightSensorMeasurement(time, lux);
-        updateAmbientLux(time);
-    }
-
-    private void applyLightSensorMeasurement(long time, float lux) {
-        // Update our filters.
-        mRecentLightSamples += 1;
-        if (mRecentLightSamples == 1) {
-            mRecentShortTermAverageLux = lux;
-            mRecentLongTermAverageLux = lux;
-        } else {
-            final long timeDelta = time - mLastObservedLuxTime;
-            mRecentShortTermAverageLux += (lux - mRecentShortTermAverageLux)
-                    * timeDelta / (SHORT_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
-            mRecentLongTermAverageLux += (lux - mRecentLongTermAverageLux)
-                    * timeDelta / (LONG_TERM_AVERAGE_LIGHT_TIME_CONSTANT + timeDelta);
-        }
-
-        // Remember this sample value.
-        mLastObservedLux = lux;
-        mLastObservedLuxTime = time;
-    }
-
-    private void setAmbientLux(float lux) {
-        mAmbientLux = lux;
-        mBrighteningLuxThreshold = mAmbientLux * (1.0f + BRIGHTENING_LIGHT_HYSTERESIS);
-        mDarkeningLuxThreshold = mAmbientLux * (1.0f - DARKENING_LIGHT_HYSTERESIS);
-    }
-
-    private void updateAmbientLux(long time) {
-        // If the light sensor was just turned on then immediately update our initial
-        // estimate of the current ambient light level.
-        if (!mAmbientLuxValid) {
-            final long timeWhenSensorWarmedUp =
-                mLightSensorWarmUpTimeConfig + mLightSensorEnableTime;
-            if (time < timeWhenSensorWarmedUp) {
-                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED,
-                        timeWhenSensorWarmedUp);
-                return;
-            }
-            setAmbientLux(mRecentShortTermAverageLux);
-            mAmbientLuxValid = true;
-            mDebounceLuxDirection = 0;
-            mDebounceLuxTime = time;
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Initializing: "
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-            updateAutoBrightness(true);
-        } else if (mRecentShortTermAverageLux > mBrighteningLuxThreshold
-                && mRecentLongTermAverageLux > mBrighteningLuxThreshold) {
-            // The ambient environment appears to be brightening.
-            if (mDebounceLuxDirection <= 0) {
-                mDebounceLuxDirection = 1;
-                mDebounceLuxTime = time;
-                if (DEBUG) {
-                    Slog.d(TAG, "updateAmbientLux: Possibly brightened, waiting for "
-                            + BRIGHTENING_LIGHT_DEBOUNCE + " ms: "
-                            + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
-                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                            + ", mAmbientLux=" + mAmbientLux);
-                }
-            }
-            long debounceTime = mDebounceLuxTime + BRIGHTENING_LIGHT_DEBOUNCE;
-            if (time < debounceTime) {
-                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
-                return;
-            }
-            setAmbientLux(mRecentShortTermAverageLux);
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Brightened: "
-                        + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-            updateAutoBrightness(true);
-        } else if (mRecentShortTermAverageLux < mDarkeningLuxThreshold
-                && mRecentLongTermAverageLux < mDarkeningLuxThreshold) {
-            // The ambient environment appears to be darkening.
-            if (mDebounceLuxDirection >= 0) {
-                mDebounceLuxDirection = -1;
-                mDebounceLuxTime = time;
-                if (DEBUG) {
-                    Slog.d(TAG, "updateAmbientLux: Possibly darkened, waiting for "
-                            + DARKENING_LIGHT_DEBOUNCE + " ms: "
-                            + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
-                            + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                            + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                            + ", mAmbientLux=" + mAmbientLux);
-                }
-            }
-            long debounceTime = mDebounceLuxTime + DARKENING_LIGHT_DEBOUNCE;
-            if (time < debounceTime) {
-                mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED, debounceTime);
-                return;
-            }
-            // Be conservative about reducing the brightness, only reduce it a little bit
-            // at a time to avoid having to bump it up again soon.
-            setAmbientLux(Math.max(mRecentShortTermAverageLux, mRecentLongTermAverageLux));
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Darkened: "
-                        + "mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-            updateAutoBrightness(true);
-        } else if (mDebounceLuxDirection != 0) {
-            // No change or change is within the hysteresis thresholds.
-            mDebounceLuxDirection = 0;
-            mDebounceLuxTime = time;
-            if (DEBUG) {
-                Slog.d(TAG, "updateAmbientLux: Canceled debounce: "
-                        + "mBrighteningLuxThreshold=" + mBrighteningLuxThreshold
-                        + ", mDarkeningLuxThreshold=" + mDarkeningLuxThreshold
-                        + ", mRecentShortTermAverageLux=" + mRecentShortTermAverageLux
-                        + ", mRecentLongTermAverageLux=" + mRecentLongTermAverageLux
-                        + ", mAmbientLux=" + mAmbientLux);
-            }
-        }
-
-        // Now that we've done all of that, we haven't yet posted a debounce
-        // message. So consider the case where current lux is beyond the
-        // threshold. It's possible that the light sensor may not report values
-        // if the light level does not change, so we need to occasionally
-        // synthesize sensor readings in order to make sure the brightness is
-        // adjusted accordingly. Note these thresholds may have changed since
-        // we entered the function because we called setAmbientLux and
-        // updateAutoBrightness along the way.
-        if (mLastObservedLux > mBrighteningLuxThreshold
-                || mLastObservedLux < mDarkeningLuxThreshold) {
-            mHandler.sendEmptyMessageAtTime(MSG_LIGHT_SENSOR_DEBOUNCED,
-                    time + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS);
-        }
-    }
-
-    private void debounceLightSensor() {
-        if (mLightSensorEnabled) {
-            long time = SystemClock.uptimeMillis();
-            if (time >= mLastObservedLuxTime + SYNTHETIC_LIGHT_SENSOR_RATE_MILLIS) {
-                if (DEBUG) {
-                    Slog.d(TAG, "debounceLightSensor: Synthesizing light sensor measurement "
-                            + "after " + (time - mLastObservedLuxTime) + " ms.");
-                }
-                applyLightSensorMeasurement(time, mLastObservedLux);
-            }
-            updateAmbientLux(time);
-        }
-    }
-
-    private void updateAutoBrightness(boolean sendUpdate) {
-        if (!mAmbientLuxValid) {
-            return;
-        }
-
-        float value = mScreenAutoBrightnessSpline.interpolate(mAmbientLux);
-        float gamma = 1.0f;
-
-        if (USE_SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT
-                && mPowerRequest.screenAutoBrightnessAdjustment != 0.0f) {
-            final float adjGamma = FloatMath.pow(SCREEN_AUTO_BRIGHTNESS_ADJUSTMENT_MAX_GAMMA,
-                    Math.min(1.0f, Math.max(-1.0f,
-                            -mPowerRequest.screenAutoBrightnessAdjustment)));
-            gamma *= adjGamma;
-            if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: adjGamma=" + adjGamma);
-            }
-        }
-
-        if (USE_TWILIGHT_ADJUSTMENT) {
-            TwilightState state = mTwilight.getCurrentState();
-            if (state != null && state.isNight()) {
-                final long now = System.currentTimeMillis();
-                final float earlyGamma =
-                        getTwilightGamma(now, state.getYesterdaySunset(), state.getTodaySunrise());
-                final float lateGamma =
-                        getTwilightGamma(now, state.getTodaySunset(), state.getTomorrowSunrise());
-                gamma *= earlyGamma * lateGamma;
-                if (DEBUG) {
-                    Slog.d(TAG, "updateAutoBrightness: earlyGamma=" + earlyGamma
-                            + ", lateGamma=" + lateGamma);
-                }
-            }
-        }
-
-        if (gamma != 1.0f) {
-            final float in = value;
-            value = FloatMath.pow(value, gamma);
-            if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: gamma=" + gamma
-                        + ", in=" + in + ", out=" + value);
-            }
-        }
-
-        int newScreenAutoBrightness = clampScreenBrightness(
-                Math.round(value * PowerManager.BRIGHTNESS_ON));
-        if (mScreenAutoBrightness != newScreenAutoBrightness) {
-            if (DEBUG) {
-                Slog.d(TAG, "updateAutoBrightness: mScreenAutoBrightness="
-                        + mScreenAutoBrightness + ", newScreenAutoBrightness="
-                        + newScreenAutoBrightness);
-            }
-
-            mScreenAutoBrightness = newScreenAutoBrightness;
-            mLastScreenAutoBrightnessGamma = gamma;
-            if (sendUpdate) {
-                sendUpdatePowerState();
-            }
-        }
-    }
-
-    private static float getTwilightGamma(long now, long lastSunset, long nextSunrise) {
-        if (lastSunset < 0 || nextSunrise < 0
-                || now < lastSunset || now > nextSunrise) {
-            return 1.0f;
-        }
-
-        if (now < lastSunset + TWILIGHT_ADJUSTMENT_TIME) {
-            return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
-                    (float)(now - lastSunset) / TWILIGHT_ADJUSTMENT_TIME);
-        }
-
-        if (now > nextSunrise - TWILIGHT_ADJUSTMENT_TIME) {
-            return lerp(1.0f, TWILIGHT_ADJUSTMENT_MAX_GAMMA,
-                    (float)(nextSunrise - now) / TWILIGHT_ADJUSTMENT_TIME);
-        }
-
-        return TWILIGHT_ADJUSTMENT_MAX_GAMMA;
-    }
-
-    private static float lerp(float x, float y, float alpha) {
-        return x + (y - x) * alpha;
-    }
-
     private void sendOnStateChangedWithWakelock() {
         mDisplaySuspendBlocker.acquire();
         mCallbackHandler.post(mOnStateChangedRunnable);
@@ -1230,8 +823,6 @@
         pw.println("  mScreenBrightnessRangeMaximum=" + mScreenBrightnessRangeMaximum);
         pw.println("  mUseSoftwareAutoBrightnessConfig="
                 + mUseSoftwareAutoBrightnessConfig);
-        pw.println("  mScreenAutoBrightnessSpline=" + mScreenAutoBrightnessSpline);
-        pw.println("  mLightSensorWarmUpTimeConfig=" + mLightSensorWarmUpTimeConfig);
 
         mHandler.runWithScissors(new Runnable() {
             @Override
@@ -1255,25 +846,7 @@
         pw.println("  mPendingProximityDebounceTime="
                 + TimeUtils.formatUptime(mPendingProximityDebounceTime));
         pw.println("  mScreenOffBecauseOfProximity=" + mScreenOffBecauseOfProximity);
-
-        pw.println("  mLightSensor=" + mLightSensor);
-        pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
-        pw.println("  mLightSensorEnableTime="
-                + TimeUtils.formatUptime(mLightSensorEnableTime));
-        pw.println("  mAmbientLux=" + mAmbientLux);
-        pw.println("  mAmbientLuxValid=" + mAmbientLuxValid);
-        pw.println("  mLastObservedLux=" + mLastObservedLux);
-        pw.println("  mLastObservedLuxTime="
-                + TimeUtils.formatUptime(mLastObservedLuxTime));
-        pw.println("  mRecentLightSamples=" + mRecentLightSamples);
-        pw.println("  mRecentShortTermAverageLux=" + mRecentShortTermAverageLux);
-        pw.println("  mRecentLongTermAverageLux=" + mRecentLongTermAverageLux);
-        pw.println("  mDebounceLuxDirection=" + mDebounceLuxDirection);
-        pw.println("  mDebounceLuxTime=" + TimeUtils.formatUptime(mDebounceLuxTime));
-        pw.println("  mScreenAutoBrightness=" + mScreenAutoBrightness);
         pw.println("  mUsingScreenAutoBrightness=" + mUsingScreenAutoBrightness);
-        pw.println("  mLastScreenAutoBrightnessGamma=" + mLastScreenAutoBrightnessGamma);
-        pw.println("  mTwilight.getCurrentState()=" + mTwilight.getCurrentState());
 
         if (mElectronBeamOnAnimator != null) {
             pw.println("  mElectronBeamOnAnimator.isStarted()=" +
@@ -1287,6 +860,11 @@
         if (mPowerState != null) {
             mPowerState.dump(pw);
         }
+
+        if (mAutomaticBrightnessController != null) {
+            mAutomaticBrightnessController.dump(pw);
+        }
+
     }
 
     private static String proximityToString(int state) {
@@ -1302,6 +880,39 @@
         }
     }
 
+    private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {
+        try {
+            final int n = brightness.length;
+            float[] x = new float[n];
+            float[] y = new float[n];
+            y[0] = normalizeAbsoluteBrightness(brightness[0]);
+            for (int i = 1; i < n; i++) {
+                x[i] = lux[i - 1];
+                y[i] = normalizeAbsoluteBrightness(brightness[i]);
+            }
+
+            Spline spline = Spline.createMonotoneCubicSpline(x, y);
+            if (DEBUG) {
+                Slog.d(TAG, "Auto-brightness spline: " + spline);
+                for (float v = 1f; v < lux[lux.length - 1] * 1.25f; v *= 1.25f) {
+                    Slog.d(TAG, String.format("  %7.1f: %7.1f", v, spline.interpolate(v)));
+                }
+            }
+            return spline;
+        } catch (IllegalArgumentException ex) {
+            Slog.e(TAG, "Could not create auto-brightness spline.", ex);
+            return null;
+        }
+    }
+
+    private static float normalizeAbsoluteBrightness(int value) {
+        return (float)clampAbsoluteBrightness(value) / PowerManager.BRIGHTNESS_ON;
+    }
+
+    private static int clampAbsoluteBrightness(int value) {
+        return MathUtils.constrain(value, PowerManager.BRIGHTNESS_OFF, PowerManager.BRIGHTNESS_ON);
+    }
+
     /**
      * Asynchronous callbacks from the power controller to the power manager service.
      */
@@ -1326,10 +937,6 @@
                 case MSG_PROXIMITY_SENSOR_DEBOUNCED:
                     debounceProximitySensor();
                     break;
-
-                case MSG_LIGHT_SENSOR_DEBOUNCED:
-                    debounceLightSensor();
-                    break;
             }
         }
     }
@@ -1350,28 +957,4 @@
             // Not used.
         }
     };
-
-    private final SensorEventListener mLightSensorListener = new SensorEventListener() {
-        @Override
-        public void onSensorChanged(SensorEvent event) {
-            if (mLightSensorEnabled) {
-                final long time = SystemClock.uptimeMillis();
-                final float lux = event.values[0];
-                handleLightSensorEvent(time, lux);
-            }
-        }
-
-        @Override
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-            // Not used.
-        }
-    };
-
-    private final TwilightListener mTwilightListener = new TwilightListener() {
-        @Override
-        public void onTwilightStateChanged() {
-            mTwilightChanged = true;
-            updatePowerState();
-        }
-    };
 }
diff --git a/services/core/java/com/android/server/power/DisplayPowerRequest.java b/services/core/java/com/android/server/power/DisplayPowerRequest.java
index 6061a40..c5e46cb 100644
--- a/services/core/java/com/android/server/power/DisplayPowerRequest.java
+++ b/services/core/java/com/android/server/power/DisplayPowerRequest.java
@@ -132,4 +132,13 @@
                 + ", useAutoBrightness=" + useAutoBrightness
                 + ", blockScreenOn=" + blockScreenOn;
     }
+
+    public static boolean wantScreenOn(int state) {
+        switch(state) {
+            case SCREEN_STATE_DIM:
+            case SCREEN_STATE_BRIGHT:
+                return true;
+        }
+        return false;
+    }
 }
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 264e2e9..81af636 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -34,6 +34,7 @@
 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.UserHandle;
@@ -129,7 +130,7 @@
      * Called when a wake lock is acquired.
      */
     public void onWakeLockAcquired(int flags, String tag, String packageName,
-            int ownerUid, int ownerPid, WorkSource workSource) {
+            int ownerUid, int ownerPid, WorkSource workSource, String historyTag) {
         if (DEBUG) {
             Slog.d(TAG, "onWakeLockAcquired: flags=" + flags + ", tag=\"" + tag
                     + "\", packageName=" + packageName
@@ -139,10 +140,14 @@
 
         try {
             final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+            boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
+                    && ownerUid == Process.SYSTEM_UID;
             if (workSource != null) {
-                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, monitorType);
+                mBatteryStats.noteStartWakelockFromSource(workSource, ownerPid, tag, historyTag,
+                        monitorType, unimportantForLogging);
             } else {
-                mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, monitorType);
+                mBatteryStats.noteStartWakelock(ownerUid, ownerPid, tag, historyTag,
+                        monitorType, unimportantForLogging);
                 // XXX need to deal with disabled operations.
                 mAppOps.startOperation(AppOpsManager.getToken(mAppOps),
                         AppOpsManager.OP_WAKE_LOCK, ownerUid, packageName);
@@ -153,6 +158,39 @@
     }
 
     /**
+     * Called when a wake lock is changing.
+     */
+    public void onWakeLockChanging(int flags, String tag, String packageName,
+            int ownerUid, int ownerPid, WorkSource workSource, String historyTag,
+            int newFlags, String newTag, String newPackageName, int newOwnerUid,
+            int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
+
+        if (workSource != null && newWorkSource != null) {
+            final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+            final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
+            boolean unimportantForLogging = (newFlags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
+                    && newOwnerUid == Process.SYSTEM_UID;
+            if (DEBUG) {
+                Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
+                        + "\", packageName=" + newPackageName
+                        + ", ownerUid=" + newOwnerUid + ", ownerPid=" + newOwnerPid
+                        + ", workSource=" + newWorkSource);
+            }
+            try {
+                mBatteryStats.noteChangeWakelockFromSource(workSource, ownerPid, tag, monitorType,
+                        newWorkSource, newOwnerPid, newTag, newHistoryTag,
+                        newMonitorType, unimportantForLogging);
+            } catch (RemoteException ex) {
+                // Ignore
+            }
+        } else {
+            onWakeLockReleased(flags, tag, packageName, ownerUid, ownerPid, workSource);
+            onWakeLockAcquired(newFlags, newTag, newPackageName, newOwnerUid, newOwnerPid,
+                    newWorkSource, newHistoryTag);
+        }
+    }
+
+    /**
      * Called when a wake lock is released.
      */
     public void onWakeLockReleased(int flags, String tag, String packageName,
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index c251af1..a388318 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -632,7 +632,7 @@
     }
 
     private void acquireWakeLockInternal(IBinder lock, int flags, String tag, String packageName,
-            WorkSource ws, int uid, int pid) {
+            WorkSource ws, String historyTag, int uid, int pid) {
         synchronized (mLock) {
             if (DEBUG_SPEW) {
                 Slog.d(TAG, "acquireWakeLockInternal: lock=" + Objects.hashCode(lock)
@@ -646,12 +646,12 @@
                 wakeLock = mWakeLocks.get(index);
                 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, packageName, ws, uid, pid);
-                    notifyWakeLockAcquiredLocked(wakeLock);
+                    notifyWakeLockChangingLocked(wakeLock, flags, tag, packageName,
+                            uid, pid, ws, historyTag);
+                    wakeLock.updateProperties(flags, tag, packageName, ws, historyTag, uid, pid);
                 }
             } else {
-                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, uid, pid);
+                wakeLock = new WakeLock(lock, flags, tag, packageName, ws, historyTag, uid, pid);
                 try {
                     lock.linkToDeath(wakeLock, 0);
                 } catch (RemoteException ex) {
@@ -747,7 +747,7 @@
         }
     }
 
-    private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws) {
+    private void updateWakeLockWorkSourceInternal(IBinder lock, WorkSource ws, String historyTag) {
         synchronized (mLock) {
             int index = findWakeLockIndexLocked(lock);
             if (index < 0) {
@@ -765,9 +765,11 @@
             }
 
             if (!wakeLock.hasSameWorkSource(ws)) {
-                notifyWakeLockReleasedLocked(wakeLock);
+                notifyWakeLockChangingLocked(wakeLock, wakeLock.mFlags, wakeLock.mTag,
+                        wakeLock.mPackageName, wakeLock.mOwnerUid, wakeLock.mOwnerPid,
+                        ws, historyTag);
+                wakeLock.mHistoryTag = historyTag;
                 wakeLock.updateWorkSource(ws);
-                notifyWakeLockAcquiredLocked(wakeLock);
             }
         }
     }
@@ -786,7 +788,17 @@
         if (mSystemReady) {
             wakeLock.mNotifiedAcquired = true;
             mNotifier.onWakeLockAcquired(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
-                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource);
+                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
+                    wakeLock.mHistoryTag);
+        }
+    }
+
+    private void notifyWakeLockChangingLocked(WakeLock wakeLock, int flags, String tag,
+            String packageName, int uid, int pid, WorkSource ws, String historyTag) {
+        if (mSystemReady && wakeLock.mNotifiedAcquired) {
+            mNotifier.onWakeLockChanging(wakeLock.mFlags, wakeLock.mTag, wakeLock.mPackageName,
+                    wakeLock.mOwnerUid, wakeLock.mOwnerPid, wakeLock.mWorkSource,
+                    wakeLock.mHistoryTag, flags, tag, packageName, uid, pid, ws, historyTag);
         }
     }
 
@@ -1990,9 +2002,10 @@
     }
 
     /**
-     * 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.
+     * Low-level function to reboot the device. On success, this
+     * function doesn't return. If more than 20 seconds passes from
+     * the time a reboot is requested (120 seconds for reboot to
+     * recovery), this method returns.
      *
      * @param reason code to pass to the kernel (e.g. "recovery"), or null.
      */
@@ -2000,9 +2013,24 @@
         if (reason == null) {
             reason = "";
         }
-        SystemProperties.set("sys.powerctl", "reboot," + reason);
+        long duration;
+        if (reason.equals(PowerManager.REBOOT_RECOVERY)) {
+            // If we are rebooting to go into recovery, instead of
+            // setting sys.powerctl directly we'll start the
+            // pre-recovery service which will do some preparation for
+            // recovery and then reboot for us.
+            //
+            // This preparation can take more than 20 seconds if
+            // there's a very large update package, so lengthen the
+            // timeout.
+            SystemProperties.set("ctl.start", "pre-recovery");
+            duration = 120 * 1000L;
+        } else {
+            SystemProperties.set("sys.powerctl", "reboot," + reason);
+            duration = 20 * 1000L;
+        }
         try {
-            Thread.sleep(20000);
+            Thread.sleep(duration);
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
         }
@@ -2267,17 +2295,19 @@
         public String mTag;
         public final String mPackageName;
         public WorkSource mWorkSource;
+        public String mHistoryTag;
         public final int mOwnerUid;
         public final int mOwnerPid;
         public boolean mNotifiedAcquired;
 
         public WakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource workSource, int ownerUid, int ownerPid) {
+                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
             mLock = lock;
             mFlags = flags;
             mTag = tag;
             mPackageName = packageName;
             mWorkSource = copyWorkSource(workSource);
+            mHistoryTag = historyTag;
             mOwnerUid = ownerUid;
             mOwnerPid = ownerPid;
         }
@@ -2297,7 +2327,7 @@
         }
 
         public void updateProperties(int flags, String tag, String packageName,
-                WorkSource workSource, int ownerUid, int ownerPid) {
+                WorkSource workSource, String historyTag, int ownerUid, int ownerPid) {
             if (!mPackageName.equals(packageName)) {
                 throw new IllegalStateException("Existing wake lock package name changed: "
                         + mPackageName + " to " + packageName);
@@ -2313,6 +2343,7 @@
             mFlags = flags;
             mTag = tag;
             updateWorkSource(workSource);
+            mHistoryTag = historyTag;
         }
 
         public boolean hasSameWorkSource(WorkSource workSource) {
@@ -2510,12 +2541,12 @@
         @Override // Binder call
         public void acquireWakeLockWithUid(IBinder lock, int flags, String tag,
                 String packageName, int uid) {
-            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid));
+            acquireWakeLock(lock, flags, tag, packageName, new WorkSource(uid), null);
         }
 
         @Override // Binder call
         public void acquireWakeLock(IBinder lock, int flags, String tag, String packageName,
-                WorkSource ws) {
+                WorkSource ws, String historyTag) {
             if (lock == null) {
                 throw new IllegalArgumentException("lock must not be null");
             }
@@ -2536,7 +2567,7 @@
             final int pid = Binder.getCallingPid();
             final long ident = Binder.clearCallingIdentity();
             try {
-                acquireWakeLockInternal(lock, flags, tag, packageName, ws, uid, pid);
+                acquireWakeLockInternal(lock, flags, tag, packageName, ws, historyTag, uid, pid);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2570,11 +2601,11 @@
                     ws.add(uids[i]);
                 }
             }
-            updateWakeLockWorkSource(lock, ws);
+            updateWakeLockWorkSource(lock, ws, null);
         }
 
         @Override // Binder call
-        public void updateWakeLockWorkSource(IBinder lock, WorkSource ws) {
+        public void updateWakeLockWorkSource(IBinder lock, WorkSource ws, String historyTag) {
             if (lock == null) {
                 throw new IllegalArgumentException("lock must not be null");
             }
@@ -2589,7 +2620,7 @@
 
             final long ident = Binder.clearCallingIdentity();
             try {
-                updateWakeLockWorkSourceInternal(lock, ws);
+                updateWakeLockWorkSourceInternal(lock, ws, historyTag);
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
@@ -2710,6 +2741,9 @@
         @Override // Binder call
         public void reboot(boolean confirm, String reason, boolean wait) {
             mContext.enforceCallingOrSelfPermission(android.Manifest.permission.REBOOT, null);
+            if (PowerManager.REBOOT_RECOVERY.equals(reason)) {
+                mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+            }
 
             final long ident = Binder.clearCallingIdentity();
             try {
diff --git a/services/core/java/com/android/server/power/ShutdownThread.java b/services/core/java/com/android/server/power/ShutdownThread.java
index 88a27f5..8fed79f 100644
--- a/services/core/java/com/android/server/power/ShutdownThread.java
+++ b/services/core/java/com/android/server/power/ShutdownThread.java
@@ -24,6 +24,7 @@
 import android.app.ProgressDialog;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.IBluetoothManager;
+import android.media.AudioManager;
 import android.nfc.NfcAdapter;
 import android.nfc.INfcAdapter;
 import android.content.BroadcastReceiver;
@@ -498,7 +499,7 @@
             // vibrate before shutting down
             Vibrator vibrator = new SystemVibrator();
             try {
-                vibrator.vibrate(SHUTDOWN_VIBRATE_MS);
+                vibrator.vibrate(SHUTDOWN_VIBRATE_MS, AudioManager.STREAM_SYSTEM);
             } catch (Exception e) {
                 // Failure to vibrate shouldn't interrupt shutdown.  Just log it.
                 Log.w(TAG, "Failed to vibrate during shutdown.", e);
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index b5d81d1..486477a 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.search;
 
 import android.app.ActivityManager;
-import android.app.ActivityManagerNative;
 import android.app.AppGlobals;
 import android.app.ISearchManager;
 import android.app.SearchManager;
@@ -39,7 +38,6 @@
 import android.os.UserManager;
 import android.provider.Settings;
 import android.util.Log;
-import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.content.PackageMonitor;
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 2ae467e..4ce02c1 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -23,9 +23,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.util.Slog;
@@ -207,6 +205,10 @@
 
     @Override
     public void disable(int what, IBinder token, String pkg) {
+        if (!mNotificationDelegate.allowDisable(what, token, pkg)) {
+            if (SPEW) Slog.d(TAG, "Blocking disable request from " + pkg);
+            return;
+        }
         disableInternal(mCurrentUserId, what, token, pkg);
     }
 
@@ -533,11 +535,13 @@
     }
 
     @Override
-    public void onNotificationClick(String pkg, String tag, int id) {
+    public void onNotificationClick(String pkg, String tag, int id, int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
-            mNotificationDelegate.onNotificationClick(pkg, tag, id);
+            mNotificationDelegate.onNotificationClick(callingUid, callingPid, pkg, tag, id, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -545,34 +549,41 @@
 
     @Override
     public void onNotificationError(String pkg, String tag, int id,
-            int uid, int initialPid, String message) {
+            int uid, int initialPid, String message, int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
             // WARNING: this will call back into us to do the remove.  Don't hold any locks.
-            mNotificationDelegate.onNotificationError(pkg, tag, id, uid, initialPid, message);
+            mNotificationDelegate.onNotificationError(callingUid, callingPid,
+                    pkg, tag, id, uid, initialPid, message, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public void onNotificationClear(String pkg, String tag, int id) {
+    public void onNotificationClear(String pkg, String tag, int id, int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
-            mNotificationDelegate.onNotificationClear(pkg, tag, id);
+            mNotificationDelegate.onNotificationClear(callingUid, callingPid, pkg, tag, id, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public void onClearAllNotifications() {
+    public void onClearAllNotifications(int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
-            mNotificationDelegate.onClearAll();
+            mNotificationDelegate.onClearAll(callingUid, callingPid, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -676,26 +687,4 @@
             }
         }
     }
-
-    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)) {
-                collapsePanels();
-            }
-            /*
-            else if (Telephony.Intents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
-                updateNetworkName(intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_SPN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_SPN),
-                        intent.getBooleanExtra(Telephony.Intents.EXTRA_SHOW_PLMN, false),
-                        intent.getStringExtra(Telephony.Intents.EXTRA_PLMN));
-            }
-            else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
-                updateResources();
-            }
-            */
-        }
-    };
-
 }
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index 43a99e0..260e97a 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -454,6 +454,7 @@
         notification.tickerText = title;
         notification.flags |= Notification.FLAG_NO_CLEAR;
         notification.setLatestEventInfo(context, title, details, intent);
+        notification.visibility = Notification.VISIBILITY_PUBLIC;
         mNotificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification,
                 UserHandle.ALL);
         context.sendStickyBroadcastAsUser(mStorageLowIntent, UserHandle.ALL);
diff --git a/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
index 9601e9a..1a68fb3 100644
--- a/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/ConfigUpdateInstallReceiver.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.provider.Settings;
-import android.os.FileUtils;
 import android.util.Base64;
 import android.util.EventLog;
 import android.util.Slog;
@@ -30,18 +29,15 @@
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.IOException;
-import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.Signature;
-import java.security.SignatureException;
 
 import libcore.io.IoUtils;
 
diff --git a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
index e430814..fdc604f 100644
--- a/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/SELinuxPolicyInstallReceiver.java
@@ -18,8 +18,6 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.os.FileUtils;
-import android.os.SELinux;
 import android.os.SystemProperties;
 import android.provider.Settings;
 import android.util.Base64;
diff --git a/services/core/java/com/android/server/updates/TZInfoInstallReceiver.java b/services/core/java/com/android/server/updates/TZInfoInstallReceiver.java
index 83adbdb..2fe68f8 100644
--- a/services/core/java/com/android/server/updates/TZInfoInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/TZInfoInstallReceiver.java
@@ -17,7 +17,6 @@
 package com.android.server.updates;
 
 import android.util.Base64;
-import android.util.Slog;
 
 import java.io.IOException;
 
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 97ea52c..87953fe 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -230,7 +230,6 @@
         public void onServiceConnected(ComponentName name, IBinder service) {
             synchronized (mLock) {
                 if (mWallpaper.connection == this) {
-                    mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
                     mService = IWallpaperService.Stub.asInterface(service);
                     attachServiceLocked(this, mWallpaper);
                     // XXX should probably do saveSettingsLocked() later
@@ -250,11 +249,21 @@
                 if (mWallpaper.connection == this) {
                     Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
                     if (!mWallpaper.wallpaperUpdating
-                            && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
-                                > SystemClock.uptimeMillis()
                             && mWallpaper.userId == mCurrentUserId) {
-                        Slog.w(TAG, "Reverting to built-in wallpaper!");
-                        clearWallpaperLocked(true, mWallpaper.userId, null);
+                        // There is a race condition which causes
+                        // {@link #mWallpaper.wallpaperUpdating} to be false even if it is
+                        // currently updating since the broadcast notifying us is async.
+                        // This race is overcome by the general rule that we only reset the
+                        // wallpaper if its service was shut down twice
+                        // during {@link #MIN_WALLPAPER_CRASH_TIME} millis.
+                        if (mWallpaper.lastDiedTime != 0
+                                && mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME
+                                    > SystemClock.uptimeMillis()) {
+                            Slog.w(TAG, "Reverting to built-in wallpaper!");
+                            clearWallpaperLocked(true, mWallpaper.userId, null);
+                        } else {
+                            mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
+                        }
                     }
                 }
             }
@@ -938,7 +947,6 @@
             }
             wallpaper.wallpaperComponent = componentName;
             wallpaper.connection = newConn;
-            wallpaper.lastDiedTime = SystemClock.uptimeMillis();
             newConn.mReply = reply;
             try {
                 if (wallpaper.userId == mCurrentUserId) {
diff --git a/services/core/java/com/android/server/wifi/README.txt b/services/core/java/com/android/server/wifi/README.txt
deleted file mode 100644
index 39e14751..0000000
--- a/services/core/java/com/android/server/wifi/README.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-WifiService: Implements the IWifiManager 3rd party API. The API and the device state information (screen on/off, battery state, sleep policy) go as input into the WifiController which tracks high level states as to whether STA or AP mode is operational and controls the WifiStateMachine to handle bringup and shut down.
-
-WifiController: Acts as a controller to the WifiStateMachine based on various inputs (API and device state). Runs on the same thread created in WifiService.
-
-WifiSettingsStore: Tracks the various settings (wifi toggle, airplane toggle, tethering toggle, scan mode toggle) and provides API to figure if wifi should be turned on or off.
-
-WifiTrafficPoller: Polls traffic on wifi and notifies apps listening on it.
-
-WifiNotificationController: Controls whether the open network notification is displayed or not based on the scan results.
-
-WifiStateMachine: Tracks the various states on STA and AP connectivity and handles bring up and shut down.
-
-
-Feature description:
-
-Scan-only mode with Wi-Fi turned off:
- - Setup wizard opts user into allowing scanning for improved location. We show no further dialogs in setup wizard since the user has just opted into the feature. This is the reason WifiService listens to DEVICE_PROVISIONED setting.
- - Once the user has his device provisioned, turning off Wi-Fi from settings or from a third party app will show up a dialog reminding the user that scan mode will be on even though Wi-Fi is being turned off. The user has the choice to turn this notification off.
- - In the scan mode, the device continues to allow scanning from any app with Wi-Fi turned off. This is done by disabling all networks and allowing only scans to be passed.
diff --git a/services/core/java/com/android/server/wifi/WifiController.java b/services/core/java/com/android/server/wifi/WifiController.java
deleted file mode 100644
index bdb0a5e..0000000
--- a/services/core/java/com/android/server/wifi/WifiController.java
+++ /dev/null
@@ -1,761 +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.server.wifi;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiManager;
-import static android.net.wifi.WifiManager.WIFI_MODE_FULL;
-import static android.net.wifi.WifiManager.WIFI_MODE_FULL_HIGH_PERF;
-import static android.net.wifi.WifiManager.WIFI_MODE_SCAN_ONLY;
-import android.net.wifi.WifiStateMachine;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.os.WorkSource;
-import android.provider.Settings;
-import android.util.Slog;
-
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.server.wifi.WifiService.LockList;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-class WifiController extends StateMachine {
-    private static final String TAG = "WifiController";
-    private static final boolean DBG = false;
-    private Context mContext;
-    private boolean mScreenOff;
-    private boolean mDeviceIdle;
-    private int mPluggedType;
-    private int mStayAwakeConditions;
-    private long mIdleMillis;
-    private int mSleepPolicy;
-    private boolean mFirstUserSignOnSeen = false;
-
-    private AlarmManager mAlarmManager;
-    private PendingIntent mIdleIntent;
-    private static final int IDLE_REQUEST = 0;
-
-    /**
-     * See {@link Settings.Global#WIFI_IDLE_MS}. This is the default value if a
-     * Settings.Global value is not present. This timeout value is chosen as
-     * the approximate point at which the battery drain caused by Wi-Fi
-     * being enabled but not active exceeds the battery drain caused by
-     * re-establishing a connection to the mobile data network.
-     */
-    private static final long DEFAULT_IDLE_MS = 15 * 60 * 1000; /* 15 minutes */
-
-    /**
-     * See {@link Settings.Global#WIFI_REENABLE_DELAY_MS}.  This is the default value if a
-     * Settings.Global value is not present.  This is the minimum time after wifi is disabled
-     * we'll act on an enable.  Enable requests received before this delay will be deferred.
-     */
-    private static final long DEFAULT_REENABLE_DELAY_MS = 500;
-
-    // finding that delayed messages can sometimes be delivered earlier than expected
-    // probably rounding errors..  add a margin to prevent problems
-    private static final long DEFER_MARGIN_MS = 5;
-
-    NetworkInfo mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, "WIFI", "");
-
-    private static final String ACTION_DEVICE_IDLE =
-            "com.android.server.WifiManager.action.DEVICE_IDLE";
-
-    /* References to values tracked in WifiService */
-    final WifiStateMachine mWifiStateMachine;
-    final WifiSettingsStore mSettingsStore;
-    final LockList mLocks;
-
-    /**
-     * Temporary for computing UIDS that are responsible for starting WIFI.
-     * Protected by mWifiStateTracker lock.
-     */
-    private final WorkSource mTmpWorkSource = new WorkSource();
-
-    private long mReEnableDelayMillis;
-
-    private static final int BASE = Protocol.BASE_WIFI_CONTROLLER;
-
-    static final int CMD_EMERGENCY_MODE_CHANGED     = BASE + 1;
-    static final int CMD_SCREEN_ON                  = BASE + 2;
-    static final int CMD_SCREEN_OFF                 = BASE + 3;
-    static final int CMD_BATTERY_CHANGED            = BASE + 4;
-    static final int CMD_DEVICE_IDLE                = BASE + 5;
-    static final int CMD_LOCKS_CHANGED              = BASE + 6;
-    static final int CMD_SCAN_ALWAYS_MODE_CHANGED   = BASE + 7;
-    static final int CMD_WIFI_TOGGLED               = BASE + 8;
-    static final int CMD_AIRPLANE_TOGGLED           = BASE + 9;
-    static final int CMD_SET_AP                     = BASE + 10;
-    static final int CMD_DEFERRED_TOGGLE            = BASE + 11;
-    static final int CMD_USER_PRESENT               = BASE + 12;
-
-    private DefaultState mDefaultState = new DefaultState();
-    private StaEnabledState mStaEnabledState = new StaEnabledState();
-    private ApStaDisabledState mApStaDisabledState = new ApStaDisabledState();
-    private StaDisabledWithScanState mStaDisabledWithScanState = new StaDisabledWithScanState();
-    private ApEnabledState mApEnabledState = new ApEnabledState();
-    private DeviceActiveState mDeviceActiveState = new DeviceActiveState();
-    private DeviceInactiveState mDeviceInactiveState = new DeviceInactiveState();
-    private ScanOnlyLockHeldState mScanOnlyLockHeldState = new ScanOnlyLockHeldState();
-    private FullLockHeldState mFullLockHeldState = new FullLockHeldState();
-    private FullHighPerfLockHeldState mFullHighPerfLockHeldState = new FullHighPerfLockHeldState();
-    private NoLockHeldState mNoLockHeldState = new NoLockHeldState();
-    private EcmState mEcmState = new EcmState();
-
-    WifiController(Context context, WifiService service, Looper looper) {
-        super(TAG, looper);
-        mContext = context;
-        mWifiStateMachine = service.mWifiStateMachine;
-        mSettingsStore = service.mSettingsStore;
-        mLocks = service.mLocks;
-
-        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
-        Intent idleIntent = new Intent(ACTION_DEVICE_IDLE, null);
-        mIdleIntent = PendingIntent.getBroadcast(mContext, IDLE_REQUEST, idleIntent, 0);
-
-        addState(mDefaultState);
-            addState(mApStaDisabledState, mDefaultState);
-            addState(mStaEnabledState, mDefaultState);
-                addState(mDeviceActiveState, mStaEnabledState);
-                addState(mDeviceInactiveState, mStaEnabledState);
-                    addState(mScanOnlyLockHeldState, mDeviceInactiveState);
-                    addState(mFullLockHeldState, mDeviceInactiveState);
-                    addState(mFullHighPerfLockHeldState, mDeviceInactiveState);
-                    addState(mNoLockHeldState, mDeviceInactiveState);
-            addState(mStaDisabledWithScanState, mDefaultState);
-            addState(mApEnabledState, mDefaultState);
-            addState(mEcmState, mDefaultState);
-
-        boolean isAirplaneModeOn = mSettingsStore.isAirplaneModeOn();
-        boolean isWifiEnabled = mSettingsStore.isWifiToggleEnabled();
-        boolean isScanningAlwaysAvailable = mSettingsStore.isScanAlwaysAvailable();
-
-        log("isAirplaneModeOn = " + isAirplaneModeOn +
-                ", isWifiEnabled = " + isWifiEnabled +
-                ", isScanningAvailable = " + isScanningAlwaysAvailable);
-
-        if (isWifiEnabled && isScanningAlwaysAvailable) {
-            setInitialState(mStaDisabledWithScanState);
-        } else {
-            setInitialState(mApStaDisabledState);
-        }
-
-        setLogRecSize(100);
-        setLogOnlyTransitions(false);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ACTION_DEVICE_IDLE);
-        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        String action = intent.getAction();
-                        if (action.equals(ACTION_DEVICE_IDLE)) {
-                            sendMessage(CMD_DEVICE_IDLE);
-                        } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                            mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
-                                    WifiManager.EXTRA_NETWORK_INFO);
-                        }
-                    }
-                },
-                new IntentFilter(filter));
-
-        initializeAndRegisterForSettingsChange(looper);
-    }
-
-    private void initializeAndRegisterForSettingsChange(Looper looper) {
-        Handler handler = new Handler(looper);
-        readStayAwakeConditions();
-        registerForStayAwakeModeChange(handler);
-        readWifiIdleTime();
-        registerForWifiIdleTimeChange(handler);
-        readWifiSleepPolicy();
-        registerForWifiSleepPolicyChange(handler);
-        readWifiReEnableDelay();
-    }
-
-    private void readStayAwakeConditions() {
-        mStayAwakeConditions = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
-    }
-
-    private void readWifiIdleTime() {
-        mIdleMillis = Settings.Global.getLong(mContext.getContentResolver(),
-                Settings.Global.WIFI_IDLE_MS, DEFAULT_IDLE_MS);
-    }
-
-    private void readWifiSleepPolicy() {
-        mSleepPolicy = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_SLEEP_POLICY,
-                Settings.Global.WIFI_SLEEP_POLICY_NEVER);
-    }
-
-    private void readWifiReEnableDelay() {
-        mReEnableDelayMillis = Settings.Global.getLong(mContext.getContentResolver(),
-                Settings.Global.WIFI_REENABLE_DELAY_MS, DEFAULT_REENABLE_DELAY_MS);
-    }
-
-    /**
-     * Observes settings changes to scan always mode.
-     */
-    private void registerForStayAwakeModeChange(Handler handler) {
-        ContentObserver contentObserver = new ContentObserver(handler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                readStayAwakeConditions();
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.STAY_ON_WHILE_PLUGGED_IN),
-                false, contentObserver);
-    }
-
-    /**
-     * Observes settings changes to scan always mode.
-     */
-    private void registerForWifiIdleTimeChange(Handler handler) {
-        ContentObserver contentObserver = new ContentObserver(handler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                readWifiIdleTime();
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.WIFI_IDLE_MS),
-                false, contentObserver);
-    }
-
-    /**
-     * Observes changes to wifi sleep policy
-     */
-    private void registerForWifiSleepPolicyChange(Handler handler) {
-        ContentObserver contentObserver = new ContentObserver(handler) {
-            @Override
-            public void onChange(boolean selfChange) {
-                readWifiSleepPolicy();
-            }
-        };
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.WIFI_SLEEP_POLICY),
-                false, contentObserver);
-    }
-
-    /**
-     * Determines whether the Wi-Fi chipset should stay awake or be put to
-     * sleep. Looks at the setting for the sleep policy and the current
-     * conditions.
-     *
-     * @see #shouldDeviceStayAwake(int)
-     */
-    private boolean shouldWifiStayAwake(int pluggedType) {
-        if (mSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER) {
-            // Never sleep
-            return true;
-        } else if ((mSleepPolicy == Settings.Global.WIFI_SLEEP_POLICY_NEVER_WHILE_PLUGGED) &&
-                (pluggedType != 0)) {
-            // Never sleep while plugged, and we're plugged
-            return true;
-        } else {
-            // Default
-            return shouldDeviceStayAwake(pluggedType);
-        }
-    }
-
-    /**
-     * Determine whether the bit value corresponding to {@code pluggedType} is set in
-     * the bit string mStayAwakeConditions. This determines whether the device should
-     * stay awake based on the current plugged type.
-     *
-     * @param pluggedType the type of plug (USB, AC, or none) for which the check is
-     * being made
-     * @return {@code true} if {@code pluggedType} indicates that the device is
-     * supposed to stay awake, {@code false} otherwise.
-     */
-    private boolean shouldDeviceStayAwake(int pluggedType) {
-        return (mStayAwakeConditions & pluggedType) != 0;
-    }
-
-    private void updateBatteryWorkSource() {
-        mTmpWorkSource.clear();
-        if (mDeviceIdle) {
-            mLocks.updateWorkSource(mTmpWorkSource);
-        }
-        mWifiStateMachine.updateBatteryWorkSource(mTmpWorkSource);
-    }
-
-    class DefaultState extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_SCREEN_ON:
-                    mAlarmManager.cancel(mIdleIntent);
-                    mScreenOff = false;
-                    mDeviceIdle = false;
-                    updateBatteryWorkSource();
-                    break;
-                case CMD_SCREEN_OFF:
-                    mScreenOff = true;
-                    /*
-                    * Set a timer to put Wi-Fi to sleep, but only if the screen is off
-                    * AND the "stay on while plugged in" setting doesn't match the
-                    * current power conditions (i.e, not plugged in, plugged in to USB,
-                    * or plugged in to AC).
-                    */
-                    if (!shouldWifiStayAwake(mPluggedType)) {
-                        //Delayed shutdown if wifi is connected
-                        if (mNetworkInfo.getDetailedState() ==
-                                NetworkInfo.DetailedState.CONNECTED) {
-                            if (DBG) Slog.d(TAG, "set idle timer: " + mIdleMillis + " ms");
-                            mAlarmManager.set(AlarmManager.RTC_WAKEUP,
-                                    System.currentTimeMillis() + mIdleMillis, mIdleIntent);
-                        } else {
-                            sendMessage(CMD_DEVICE_IDLE);
-                        }
-                    }
-                    break;
-                case CMD_DEVICE_IDLE:
-                    mDeviceIdle = true;
-                    updateBatteryWorkSource();
-                    break;
-                case CMD_BATTERY_CHANGED:
-                    /*
-                    * Set a timer to put Wi-Fi to sleep, but only if the screen is off
-                    * AND we are transitioning from a state in which the device was supposed
-                    * to stay awake to a state in which it is not supposed to stay awake.
-                    * If "stay awake" state is not changing, we do nothing, to avoid resetting
-                    * the already-set timer.
-                    */
-                    int pluggedType = msg.arg1;
-                    if (DBG) Slog.d(TAG, "battery changed pluggedType: " + pluggedType);
-                    if (mScreenOff && shouldWifiStayAwake(mPluggedType) &&
-                            !shouldWifiStayAwake(pluggedType)) {
-                        long triggerTime = System.currentTimeMillis() + mIdleMillis;
-                        if (DBG) Slog.d(TAG, "set idle timer for " + mIdleMillis + "ms");
-                        mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
-                    }
-
-                    mPluggedType = pluggedType;
-                    break;
-                case CMD_SET_AP:
-                case CMD_SCAN_ALWAYS_MODE_CHANGED:
-                case CMD_LOCKS_CHANGED:
-                case CMD_WIFI_TOGGLED:
-                case CMD_AIRPLANE_TOGGLED:
-                case CMD_EMERGENCY_MODE_CHANGED:
-                    break;
-                case CMD_USER_PRESENT:
-                    mFirstUserSignOnSeen = true;
-                    break;
-                case CMD_DEFERRED_TOGGLE:
-                    log("DEFERRED_TOGGLE ignored due to state change");
-                    break;
-                default:
-                    throw new RuntimeException("WifiController.handleMessage " + msg.what);
-            }
-            return HANDLED;
-        }
-
-    }
-
-    class ApStaDisabledState extends State {
-        private int mDeferredEnableSerialNumber = 0;
-        private boolean mHaveDeferredEnable = false;
-        private long mDisabledTimestamp;
-
-        @Override
-        public void enter() {
-            mWifiStateMachine.setSupplicantRunning(false);
-            // Supplicant can't restart right away, so not the time we switched off
-            mDisabledTimestamp = SystemClock.elapsedRealtime();
-            mDeferredEnableSerialNumber++;
-            mHaveDeferredEnable = false;
-        }
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_WIFI_TOGGLED:
-                case CMD_AIRPLANE_TOGGLED:
-                    if (mSettingsStore.isWifiToggleEnabled()) {
-                        if (doDeferEnable(msg)) {
-                            if (mHaveDeferredEnable) {
-                                //  have 2 toggles now, inc serial number an ignore both
-                                mDeferredEnableSerialNumber++;
-                            }
-                            mHaveDeferredEnable = !mHaveDeferredEnable;
-                            break;
-                        }
-                        if (mDeviceIdle == false) {
-                            transitionTo(mDeviceActiveState);
-                        } else {
-                            checkLocksAndTransitionWhenDeviceIdle();
-                        }
-                    }
-                    break;
-                case CMD_SCAN_ALWAYS_MODE_CHANGED:
-                    if (mSettingsStore.isScanAlwaysAvailable()) {
-                        transitionTo(mStaDisabledWithScanState);
-                    }
-                    break;
-                case CMD_SET_AP:
-                    if (msg.arg1 == 1) {
-                        mWifiStateMachine.setHostApRunning((WifiConfiguration) msg.obj,
-                                true);
-                        transitionTo(mApEnabledState);
-                    }
-                    break;
-                case CMD_DEFERRED_TOGGLE:
-                    if (msg.arg1 != mDeferredEnableSerialNumber) {
-                        log("DEFERRED_TOGGLE ignored due to serial mismatch");
-                        break;
-                    }
-                    log("DEFERRED_TOGGLE handled");
-                    sendMessage((Message)(msg.obj));
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        private boolean doDeferEnable(Message msg) {
-            long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp;
-            if (delaySoFar >= mReEnableDelayMillis) {
-                return false;
-            }
-
-            log("WifiController msg " + msg + " deferred for " +
-                    (mReEnableDelayMillis - delaySoFar) + "ms");
-
-            // need to defer this action.
-            Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE);
-            deferredMsg.obj = Message.obtain(msg);
-            deferredMsg.arg1 = ++mDeferredEnableSerialNumber;
-            sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar + DEFER_MARGIN_MS);
-            return true;
-        }
-
-    }
-
-    class StaEnabledState extends State {
-        @Override
-        public void enter() {
-            mWifiStateMachine.setSupplicantRunning(true);
-        }
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_WIFI_TOGGLED:
-                    if (! mSettingsStore.isWifiToggleEnabled()) {
-                        if (mSettingsStore.isScanAlwaysAvailable()) {
-                            transitionTo(mStaDisabledWithScanState);
-                        } else {
-                            transitionTo(mApStaDisabledState);
-                        }
-                    }
-                    break;
-                case CMD_AIRPLANE_TOGGLED:
-                    /* When wi-fi is turned off due to airplane,
-                    * disable entirely (including scan)
-                    */
-                    if (! mSettingsStore.isWifiToggleEnabled()) {
-                        transitionTo(mApStaDisabledState);
-                    }
-                    break;
-                case CMD_EMERGENCY_MODE_CHANGED:
-                    if (msg.arg1 == 1) {
-                        transitionTo(mEcmState);
-                        break;
-                    }
-                default:
-                    return NOT_HANDLED;
-
-            }
-            return HANDLED;
-        }
-    }
-
-    class StaDisabledWithScanState extends State {
-        private int mDeferredEnableSerialNumber = 0;
-        private boolean mHaveDeferredEnable = false;
-        private long mDisabledTimestamp;
-
-        @Override
-        public void enter() {
-            mWifiStateMachine.setSupplicantRunning(true);
-            mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_WITH_WIFI_OFF_MODE);
-            mWifiStateMachine.setDriverStart(true);
-            // Supplicant can't restart right away, so not the time we switched off
-            mDisabledTimestamp = SystemClock.elapsedRealtime();
-            mDeferredEnableSerialNumber++;
-            mHaveDeferredEnable = false;
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_WIFI_TOGGLED:
-                    if (mSettingsStore.isWifiToggleEnabled()) {
-                        if (doDeferEnable(msg)) {
-                            if (mHaveDeferredEnable) {
-                                // have 2 toggles now, inc serial number and ignore both
-                                mDeferredEnableSerialNumber++;
-                            }
-                            mHaveDeferredEnable = !mHaveDeferredEnable;
-                            break;
-                        }
-                        if (mDeviceIdle == false) {
-                            transitionTo(mDeviceActiveState);
-                        } else {
-                            checkLocksAndTransitionWhenDeviceIdle();
-                        }
-                    }
-                    break;
-                case CMD_AIRPLANE_TOGGLED:
-                    if (mSettingsStore.isAirplaneModeOn() &&
-                            ! mSettingsStore.isWifiToggleEnabled()) {
-                        transitionTo(mApStaDisabledState);
-                    }
-                case CMD_SCAN_ALWAYS_MODE_CHANGED:
-                    if (! mSettingsStore.isScanAlwaysAvailable()) {
-                        transitionTo(mApStaDisabledState);
-                    }
-                    break;
-                case CMD_SET_AP:
-                    // Before starting tethering, turn off supplicant for scan mode
-                    if (msg.arg1 == 1) {
-                        deferMessage(msg);
-                        transitionTo(mApStaDisabledState);
-                    }
-                    break;
-                case CMD_DEFERRED_TOGGLE:
-                    if (msg.arg1 != mDeferredEnableSerialNumber) {
-                        log("DEFERRED_TOGGLE ignored due to serial mismatch");
-                        break;
-                    }
-                    logd("DEFERRED_TOGGLE handled");
-                    sendMessage((Message)(msg.obj));
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        private boolean doDeferEnable(Message msg) {
-            long delaySoFar = SystemClock.elapsedRealtime() - mDisabledTimestamp;
-            if (delaySoFar >= mReEnableDelayMillis) {
-                return false;
-            }
-
-            log("WifiController msg " + msg + " deferred for " +
-                    (mReEnableDelayMillis - delaySoFar) + "ms");
-
-            // need to defer this action.
-            Message deferredMsg = obtainMessage(CMD_DEFERRED_TOGGLE);
-            deferredMsg.obj = Message.obtain(msg);
-            deferredMsg.arg1 = ++mDeferredEnableSerialNumber;
-            sendMessageDelayed(deferredMsg, mReEnableDelayMillis - delaySoFar + DEFER_MARGIN_MS);
-            return true;
-        }
-
-    }
-
-    class ApEnabledState extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_AIRPLANE_TOGGLED:
-                    if (mSettingsStore.isAirplaneModeOn()) {
-                        mWifiStateMachine.setHostApRunning(null, false);
-                        transitionTo(mApStaDisabledState);
-                    }
-                    break;
-                case CMD_SET_AP:
-                    if (msg.arg1 == 0) {
-                        mWifiStateMachine.setHostApRunning(null, false);
-                        transitionTo(mApStaDisabledState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class EcmState extends State {
-        @Override
-        public void enter() {
-            mWifiStateMachine.setSupplicantRunning(false);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            if (msg.what == CMD_EMERGENCY_MODE_CHANGED && msg.arg1 == 0) {
-                if (mSettingsStore.isWifiToggleEnabled()) {
-                    if (mDeviceIdle == false) {
-                        transitionTo(mDeviceActiveState);
-                    } else {
-                        checkLocksAndTransitionWhenDeviceIdle();
-                    }
-                } else if (mSettingsStore.isScanAlwaysAvailable()) {
-                    transitionTo(mStaDisabledWithScanState);
-                } else {
-                    transitionTo(mApStaDisabledState);
-                }
-                return HANDLED;
-            } else {
-                return NOT_HANDLED;
-            }
-        }
-    }
-
-    /* Parent: StaEnabledState */
-    class DeviceActiveState extends State {
-        @Override
-        public void enter() {
-            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
-            mWifiStateMachine.setDriverStart(true);
-            mWifiStateMachine.setHighPerfModeEnabled(false);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            if (msg.what == CMD_DEVICE_IDLE) {
-                checkLocksAndTransitionWhenDeviceIdle();
-                // We let default state handle the rest of work
-            } else if (msg.what == CMD_USER_PRESENT) {
-                // TLS networks can't connect until user unlocks keystore. KeyStore
-                // unlocks when the user punches PIN after the reboot. So use this
-                // trigger to get those networks connected.
-                if (mFirstUserSignOnSeen == false) {
-                    mWifiStateMachine.reloadTlsNetworksAndReconnect();
-                }
-                mFirstUserSignOnSeen = true;
-                return HANDLED;
-            }
-            return NOT_HANDLED;
-        }
-    }
-
-    /* Parent: StaEnabledState */
-    class DeviceInactiveState extends State {
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_LOCKS_CHANGED:
-                    checkLocksAndTransitionWhenDeviceIdle();
-                    updateBatteryWorkSource();
-                    return HANDLED;
-                case CMD_SCREEN_ON:
-                    transitionTo(mDeviceActiveState);
-                    // More work in default state
-                    return NOT_HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a scan only lock. */
-    class ScanOnlyLockHeldState extends State {
-        @Override
-        public void enter() {
-            mWifiStateMachine.setOperationalMode(WifiStateMachine.SCAN_ONLY_MODE);
-            mWifiStateMachine.setDriverStart(true);
-        }
-    }
-
-    /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a full lock. */
-    class FullLockHeldState extends State {
-        @Override
-        public void enter() {
-            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
-            mWifiStateMachine.setDriverStart(true);
-            mWifiStateMachine.setHighPerfModeEnabled(false);
-        }
-    }
-
-    /* Parent: DeviceInactiveState. Device is inactive, but an app is holding a high perf lock. */
-    class FullHighPerfLockHeldState extends State {
-        @Override
-        public void enter() {
-            mWifiStateMachine.setOperationalMode(WifiStateMachine.CONNECT_MODE);
-            mWifiStateMachine.setDriverStart(true);
-            mWifiStateMachine.setHighPerfModeEnabled(true);
-        }
-    }
-
-    /* Parent: DeviceInactiveState. Device is inactive and no app is holding a wifi lock. */
-    class NoLockHeldState extends State {
-        @Override
-        public void enter() {
-            mWifiStateMachine.setDriverStart(false);
-        }
-    }
-
-    private void checkLocksAndTransitionWhenDeviceIdle() {
-        if (mLocks.hasLocks()) {
-            switch (mLocks.getStrongestLockMode()) {
-                case WIFI_MODE_FULL:
-                    transitionTo(mFullLockHeldState);
-                    break;
-                case WIFI_MODE_FULL_HIGH_PERF:
-                    transitionTo(mFullHighPerfLockHeldState);
-                    break;
-                case WIFI_MODE_SCAN_ONLY:
-                    transitionTo(mScanOnlyLockHeldState);
-                    break;
-                default:
-                    loge("Illegal lock " + mLocks.getStrongestLockMode());
-            }
-        } else {
-            if (mSettingsStore.isScanAlwaysAvailable()) {
-                transitionTo(mScanOnlyLockHeldState);
-            } else {
-                transitionTo(mNoLockHeldState);
-            }
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
-
-        pw.println("mScreenOff " + mScreenOff);
-        pw.println("mDeviceIdle " + mDeviceIdle);
-        pw.println("mPluggedType " + mPluggedType);
-        pw.println("mIdleMillis " + mIdleMillis);
-        pw.println("mSleepPolicy " + mSleepPolicy);
-    }
-}
diff --git a/services/core/java/com/android/server/wifi/WifiNotificationController.java b/services/core/java/com/android/server/wifi/WifiNotificationController.java
deleted file mode 100644
index a9206e0..0000000
--- a/services/core/java/com/android/server/wifi/WifiNotificationController.java
+++ /dev/null
@@ -1,297 +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.server.wifi;
-
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.TaskStackBuilder;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.NetworkInfo;
-import android.net.wifi.ScanResult;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiStateMachine;
-import android.os.Handler;
-import android.os.Message;
-import android.os.UserHandle;
-import android.provider.Settings;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.List;
-
-/* Takes care of handling the "open wi-fi network available" notification @hide */
-final class WifiNotificationController {
-    /**
-     * The icon to show in the 'available networks' notification. This will also
-     * be the ID of the Notification given to the NotificationManager.
-     */
-    private static final int ICON_NETWORKS_AVAILABLE =
-            com.android.internal.R.drawable.stat_notify_wifi_in_range;
-    /**
-     * When a notification is shown, we wait this amount before possibly showing it again.
-     */
-    private final long NOTIFICATION_REPEAT_DELAY_MS;
-    /**
-     * Whether the user has set the setting to show the 'available networks' notification.
-     */
-    private boolean mNotificationEnabled;
-    /**
-     * Observes the user setting to keep {@link #mNotificationEnabled} in sync.
-     */
-    private NotificationEnabledSettingObserver mNotificationEnabledSettingObserver;
-    /**
-     * The {@link System#currentTimeMillis()} must be at least this value for us
-     * to show the notification again.
-     */
-    private long mNotificationRepeatTime;
-    /**
-     * The Notification object given to the NotificationManager.
-     */
-    private Notification mNotification;
-    /**
-     * Whether the notification is being shown, as set by us. That is, if the
-     * user cancels the notification, we will not receive the callback so this
-     * will still be true. We only guarantee if this is false, then the
-     * notification is not showing.
-     */
-    private boolean mNotificationShown;
-    /**
-     * The number of continuous scans that must occur before consider the
-     * supplicant in a scanning state. This allows supplicant to associate with
-     * remembered networks that are in the scan results.
-     */
-    private static final int NUM_SCANS_BEFORE_ACTUALLY_SCANNING = 3;
-    /**
-     * The number of scans since the last network state change. When this
-     * exceeds {@link #NUM_SCANS_BEFORE_ACTUALLY_SCANNING}, we consider the
-     * supplicant to actually be scanning. When the network state changes to
-     * something other than scanning, we reset this to 0.
-     */
-    private int mNumScansSinceNetworkStateChange;
-
-    private final Context mContext;
-    private final WifiStateMachine mWifiStateMachine;
-    private NetworkInfo mNetworkInfo;
-    private volatile int mWifiState;
-
-    WifiNotificationController(Context context, WifiStateMachine wsm) {
-        mContext = context;
-        mWifiStateMachine = wsm;
-        mWifiState = WifiManager.WIFI_STATE_UNKNOWN;
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        filter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        if (intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                            mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
-                                    WifiManager.WIFI_STATE_UNKNOWN);
-                            resetNotification();
-                        } else if (intent.getAction().equals(
-                                WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                            mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
-                                    WifiManager.EXTRA_NETWORK_INFO);
-                            // reset & clear notification on a network connect & disconnect
-                            switch(mNetworkInfo.getDetailedState()) {
-                                case CONNECTED:
-                                case DISCONNECTED:
-                                case CAPTIVE_PORTAL_CHECK:
-                                    resetNotification();
-                                    break;
-                            }
-                        } else if (intent.getAction().equals(
-                                WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
-                            checkAndSetNotification(mNetworkInfo,
-                                    mWifiStateMachine.syncGetScanResultsList());
-                        }
-                    }
-                }, filter);
-
-        // Setting is in seconds
-        NOTIFICATION_REPEAT_DELAY_MS = Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY, 900) * 1000l;
-        mNotificationEnabledSettingObserver = new NotificationEnabledSettingObserver(new Handler());
-        mNotificationEnabledSettingObserver.register();
-    }
-
-    private synchronized void checkAndSetNotification(NetworkInfo networkInfo,
-            List<ScanResult> scanResults) {
-        // TODO: unregister broadcast so we do not have to check here
-        // If we shouldn't place a notification on available networks, then
-        // don't bother doing any of the following
-        if (!mNotificationEnabled) return;
-        if (networkInfo == null) return;
-        if (mWifiState != WifiManager.WIFI_STATE_ENABLED) return;
-
-        NetworkInfo.State state = networkInfo.getState();
-        if ((state == NetworkInfo.State.DISCONNECTED)
-                || (state == NetworkInfo.State.UNKNOWN)) {
-            if (scanResults != null) {
-                int numOpenNetworks = 0;
-                for (int i = scanResults.size() - 1; i >= 0; i--) {
-                    ScanResult scanResult = scanResults.get(i);
-
-                    //A capability of [ESS] represents an open access point
-                    //that is available for an STA to connect
-                    if (scanResult.capabilities != null &&
-                            scanResult.capabilities.equals("[ESS]")) {
-                        numOpenNetworks++;
-                    }
-                }
-
-                if (numOpenNetworks > 0) {
-                    if (++mNumScansSinceNetworkStateChange >= NUM_SCANS_BEFORE_ACTUALLY_SCANNING) {
-                        /*
-                         * We've scanned continuously at least
-                         * NUM_SCANS_BEFORE_NOTIFICATION times. The user
-                         * probably does not have a remembered network in range,
-                         * since otherwise supplicant would have tried to
-                         * associate and thus resetting this counter.
-                         */
-                        setNotificationVisible(true, numOpenNetworks, false, 0);
-                    }
-                    return;
-                }
-            }
-        }
-
-        // No open networks in range, remove the notification
-        setNotificationVisible(false, 0, false, 0);
-    }
-
-    /**
-     * Clears variables related to tracking whether a notification has been
-     * shown recently and clears the current notification.
-     */
-    private synchronized void resetNotification() {
-        mNotificationRepeatTime = 0;
-        mNumScansSinceNetworkStateChange = 0;
-        setNotificationVisible(false, 0, false, 0);
-    }
-
-    /**
-     * Display or don't display a notification that there are open Wi-Fi networks.
-     * @param visible {@code true} if notification should be visible, {@code false} otherwise
-     * @param numNetworks the number networks seen
-     * @param force {@code true} to force notification to be shown/not-shown,
-     * even if it is already shown/not-shown.
-     * @param delay time in milliseconds after which the notification should be made
-     * visible or invisible.
-     */
-    private void setNotificationVisible(boolean visible, int numNetworks, boolean force,
-            int delay) {
-
-        // Since we use auto cancel on the notification, when the
-        // mNetworksAvailableNotificationShown is true, the notification may
-        // have actually been canceled.  However, when it is false we know
-        // for sure that it is not being shown (it will not be shown any other
-        // place than here)
-
-        // If it should be hidden and it is already hidden, then noop
-        if (!visible && !mNotificationShown && !force) {
-            return;
-        }
-
-        NotificationManager notificationManager = (NotificationManager) mContext
-                .getSystemService(Context.NOTIFICATION_SERVICE);
-
-        Message message;
-        if (visible) {
-
-            // Not enough time has passed to show the notification again
-            if (System.currentTimeMillis() < mNotificationRepeatTime) {
-                return;
-            }
-
-            if (mNotification == null) {
-                // Cache the Notification object.
-                mNotification = new Notification();
-                mNotification.when = 0;
-                mNotification.icon = ICON_NETWORKS_AVAILABLE;
-                mNotification.flags = Notification.FLAG_AUTO_CANCEL;
-                mNotification.contentIntent = TaskStackBuilder.create(mContext)
-                        .addNextIntentWithParentStack(
-                                new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK))
-                        .getPendingIntent(0, 0, null, UserHandle.CURRENT);
-            }
-
-            CharSequence title = mContext.getResources().getQuantityText(
-                    com.android.internal.R.plurals.wifi_available, numNetworks);
-            CharSequence details = mContext.getResources().getQuantityText(
-                    com.android.internal.R.plurals.wifi_available_detailed, numNetworks);
-            mNotification.tickerText = title;
-            mNotification.setLatestEventInfo(mContext, title, details, mNotification.contentIntent);
-
-            mNotificationRepeatTime = System.currentTimeMillis() + NOTIFICATION_REPEAT_DELAY_MS;
-
-            notificationManager.notifyAsUser(null, ICON_NETWORKS_AVAILABLE, mNotification,
-                    UserHandle.ALL);
-        } else {
-            notificationManager.cancelAsUser(null, ICON_NETWORKS_AVAILABLE, UserHandle.ALL);
-        }
-
-        mNotificationShown = visible;
-    }
-
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("mNotificationEnabled " + mNotificationEnabled);
-        pw.println("mNotificationRepeatTime " + mNotificationRepeatTime);
-        pw.println("mNotificationShown " + mNotificationShown);
-        pw.println("mNumScansSinceNetworkStateChange " + mNumScansSinceNetworkStateChange);
-    }
-
-    private class NotificationEnabledSettingObserver extends ContentObserver {
-        public NotificationEnabledSettingObserver(Handler handler) {
-            super(handler);
-        }
-
-        public void register() {
-            ContentResolver cr = mContext.getContentResolver();
-            cr.registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON), true, this);
-            synchronized (WifiNotificationController.this) {
-                mNotificationEnabled = getValue();
-            }
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            super.onChange(selfChange);
-
-            synchronized (WifiNotificationController.this) {
-                mNotificationEnabled = getValue();
-                resetNotification();
-            }
-        }
-
-        private boolean getValue() {
-            return Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1) == 1;
-        }
-    }
-
-}
diff --git a/services/core/java/com/android/server/wifi/WifiService.java b/services/core/java/com/android/server/wifi/WifiService.java
deleted file mode 100644
index aecf9ae..0000000
--- a/services/core/java/com/android/server/wifi/WifiService.java
+++ /dev/null
@@ -1,1599 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wifi;
-
-import android.app.ActivityManager;
-import android.app.AppOpsManager;
-import android.bluetooth.BluetoothAdapter;
-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.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.WifiConfiguration.ProxySettings;
-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;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.INetworkManagementService;
-import android.os.Message;
-import android.os.RemoteException;
-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;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.AsyncChannel;
-import com.android.server.am.BatteryStatsService;
-import static com.android.server.wifi.WifiController.CMD_AIRPLANE_TOGGLED;
-import static com.android.server.wifi.WifiController.CMD_BATTERY_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_EMERGENCY_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_LOCKS_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_SCAN_ALWAYS_MODE_CHANGED;
-import static com.android.server.wifi.WifiController.CMD_SCREEN_OFF;
-import static com.android.server.wifi.WifiController.CMD_SCREEN_ON;
-import static com.android.server.wifi.WifiController.CMD_SET_AP;
-import static com.android.server.wifi.WifiController.CMD_USER_PRESENT;
-import static com.android.server.wifi.WifiController.CMD_WIFI_TOGGLED;
-/**
- * WifiService handles remote WiFi operation requests by implementing
- * the IWifiManager interface.
- *
- * @hide
- */
-public final class WifiService extends IWifiManager.Stub {
-    private static final String TAG = "WifiService";
-    private static final boolean DBG = false;
-
-    final WifiStateMachine mWifiStateMachine;
-
-    private final Context mContext;
-
-    final LockList mLocks = new LockList();
-    // some wifi lock statistics
-    private int mFullHighPerfLocksAcquired;
-    private int mFullHighPerfLocksReleased;
-    private int mFullLocksAcquired;
-    private int mFullLocksReleased;
-    private int mScanLocksAcquired;
-    private int mScanLocksReleased;
-
-    private final List<Multicaster> mMulticasters =
-            new ArrayList<Multicaster>();
-    private int mMulticastEnabled;
-    private int mMulticastDisabled;
-
-    private final IBatteryStats mBatteryStats;
-    private final AppOpsManager mAppOps;
-
-    private String mInterfaceName;
-
-    /* Tracks the open wi-fi network notification */
-    private WifiNotificationController mNotificationController;
-    /* Polls traffic stats and notifies clients */
-    private WifiTrafficPoller mTrafficPoller;
-    /* Tracks the persisted states for wi-fi & airplane mode */
-    final WifiSettingsStore mSettingsStore;
-
-    final boolean mBatchedScanSupported;
-
-    /**
-     * Asynchronous channel to WifiStateMachine
-     */
-    private AsyncChannel mWifiStateMachineChannel;
-
-    /**
-     * Handles client connections
-     */
-    private class ClientHandler extends Handler {
-
-        ClientHandler(android.os.Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
-                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
-                        // We track the clients by the Messenger
-                        // since it is expected to be always available
-                        mTrafficPoller.addClient(msg.replyTo);
-                    } else {
-                        Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
-                    }
-                    break;
-                }
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
-                    if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
-                        if (DBG) Slog.d(TAG, "Send failed, client connection lost");
-                    } else {
-                        if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
-                    }
-                    mTrafficPoller.removeClient(msg.replyTo);
-                    break;
-                }
-                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
-                    AsyncChannel ac = new AsyncChannel();
-                    ac.connect(mContext, this, msg.replyTo);
-                    break;
-                }
-                /* Client commands are forwarded to state machine */
-                case WifiManager.CONNECT_NETWORK:
-                case WifiManager.SAVE_NETWORK: {
-                    WifiConfiguration config = (WifiConfiguration) msg.obj;
-                    int networkId = msg.arg1;
-                    if (config != null && config.isValid()) {
-                        // This is restricted because there is no UI for the user to
-                        // monitor/control PAC.
-                        if (config.proxySettings != ProxySettings.PAC) {
-                            if (DBG) Slog.d(TAG, "Connect with config" + config);
-                            mWifiStateMachine.sendMessage(Message.obtain(msg));
-                        } else {
-                            Slog.e(TAG,  "ClientHandler.handleMessage cannot process msg with PAC");
-                            if (msg.what == WifiManager.CONNECT_NETWORK) {
-                                replyFailed(msg, WifiManager.CONNECT_NETWORK_FAILED);
-                            } else {
-                                replyFailed(msg, WifiManager.SAVE_NETWORK_FAILED);
-                            }
-                        }
-                    } else if (config == null
-                            && networkId != WifiConfiguration.INVALID_NETWORK_ID) {
-                        if (DBG) Slog.d(TAG, "Connect with networkId" + networkId);
-                        mWifiStateMachine.sendMessage(Message.obtain(msg));
-                    } else {
-                        Slog.e(TAG, "ClientHandler.handleMessage ignoring invalid 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:
-                case WifiManager.DISABLE_NETWORK:
-                case WifiManager.RSSI_PKTCNT_FETCH: {
-                    mWifiStateMachine.sendMessage(Message.obtain(msg));
-                    break;
-                }
-                default: {
-                    Slog.d(TAG, "ClientHandler.handleMessage ignoring msg=" + msg);
-                    break;
-                }
-            }
-        }
-
-        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;
-
-    /**
-     * Handles interaction with WifiStateMachine
-     */
-    private class WifiStateMachineHandler extends Handler {
-        private AsyncChannel mWsmChannel;
-
-        WifiStateMachineHandler(android.os.Looper looper) {
-            super(looper);
-            mWsmChannel = new AsyncChannel();
-            mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
-                    if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        mWifiStateMachineChannel = mWsmChannel;
-                    } else {
-                        Slog.e(TAG, "WifiStateMachine connection failure, error=" + msg.arg1);
-                        mWifiStateMachineChannel = null;
-                    }
-                    break;
-                }
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
-                    Slog.e(TAG, "WifiStateMachine channel lost, msg.arg1 =" + msg.arg1);
-                    mWifiStateMachineChannel = null;
-                    //Re-establish connection to state machine
-                    mWsmChannel.connect(mContext, this, mWifiStateMachine.getHandler());
-                    break;
-                }
-                default: {
-                    Slog.d(TAG, "WifiStateMachineHandler.handleMessage ignoring msg=" + msg);
-                    break;
-                }
-            }
-        }
-    }
-    WifiStateMachineHandler mWifiStateMachineHandler;
-
-    private WifiWatchdogStateMachine mWifiWatchdogStateMachine;
-
-    public WifiService(Context context) {
-        mContext = context;
-
-        mInterfaceName =  SystemProperties.get("wifi.interface", "wlan0");
-
-        mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);
-        mWifiStateMachine.enableRssiPolling(true);
-        mBatteryStats = BatteryStatsService.getService();
-        mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
-
-        mNotificationController = new WifiNotificationController(mContext, mWifiStateMachine);
-        mTrafficPoller = new WifiTrafficPoller(mContext, mInterfaceName);
-        mSettingsStore = new WifiSettingsStore(mContext);
-
-        HandlerThread wifiThread = new HandlerThread("WifiService");
-        wifiThread.start();
-        mClientHandler = new ClientHandler(wifiThread.getLooper());
-        mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());
-        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() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        if (mSettingsStore.handleAirplaneModeToggled()) {
-                            mWifiController.sendMessage(CMD_AIRPLANE_TOGGLED);
-                        }
-                    }
-                },
-                new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED));
-
-        // Adding optimizations of only receiving broadcasts when wifi is enabled
-        // can result in race conditions when apps toggle wifi in the background
-        // without active user involvement. Always receive broadcasts.
-        registerForBroadcasts();
-    }
-
-    private WifiController mWifiController;
-
-    /**
-     * Check if Wi-Fi needs to be enabled and start
-     * if needed
-     *
-     * This function is used only at boot time
-     */
-    public void checkAndStartWifi() {
-        /* Check if wi-fi needs to be enabled */
-        boolean wifiEnabled = mSettingsStore.isWifiToggleEnabled();
-        Slog.i(TAG, "WifiService starting up with Wi-Fi " +
-                (wifiEnabled ? "enabled" : "disabled"));
-
-        // If we are already disabled (could be due to airplane mode), avoid changing persist
-        // state here
-        if (wifiEnabled) setWifiEnabled(wifiEnabled);
-
-        mWifiWatchdogStateMachine = WifiWatchdogStateMachine.
-               makeWifiWatchdogStateMachine(mContext);
-
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#pingSupplicant()}
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     */
-    public boolean pingSupplicant() {
-        enforceAccessPermission();
-        if (mWifiStateMachineChannel != null) {
-            return mWifiStateMachine.syncPingSupplicant(mWifiStateMachineChannel);
-        } else {
-            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
-            return false;
-        }
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#startScan()}
-     *
-     * <p>If workSource is null, all blame is given to the calling uid.
-     */
-    public void startScan(WorkSource workSource) {
-        enforceChangePermission();
-        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 {
-        final BatchedScanSettings settings;
-        final int uid;
-        final int pid;
-        final WorkSource workSource;
-
-        BatchedScanRequest(BatchedScanSettings settings, IBinder binder, WorkSource ws) {
-            super(0, null, binder, null);
-            this.settings = settings;
-            this.uid = getCallingUid();
-            this.pid = getCallingPid();
-            workSource = ws;
-        }
-        public void binderDied() {
-            stopBatchedScan(settings, uid, pid);
-        }
-        public String toString() {
-            return "BatchedScanRequest{settings=" + settings + ", binder=" + mBinder + "}";
-        }
-
-        public boolean isSameApp(int uid, int pid) {
-            return (this.uid == uid && this.pid == pid);
-        }
-    }
-
-    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,
-            WorkSource workSource) {
-        enforceChangePermission();
-        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();
-        }
-        if (mBatchedScanSupported == false) return false;
-        requested = new BatchedScanSettings(requested);
-        if (requested.isInvalid()) return false;
-        BatchedScanRequest r = new BatchedScanRequest(requested, binder, workSource);
-        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) {
-        enforceChangePermission();
-        if (mBatchedScanSupported == false) return;
-        stopBatchedScan(settings, getCallingUid(), getCallingPid());
-    }
-
-    private void stopBatchedScan(BatchedScanSettings settings, int uid, int pid) {
-        ArrayList<BatchedScanRequest> found = new ArrayList<BatchedScanRequest>();
-        synchronized(mBatchedScanners) {
-            for (BatchedScanRequest r : mBatchedScanners) {
-                if (r.isSameApp(uid, pid) && (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();
-        WorkSource responsibleWorkSource = null;
-        int responsibleUid = 0;
-        double responsibleCsph = 0; // Channel Scans Per Hour
-
-        if (mBatchedScanners.size() == 0) {
-            mWifiStateMachine.setBatchedScanSettings(null, 0, 0, null);
-            return;
-        }
-        for (BatchedScanRequest r : mBatchedScanners) {
-            BatchedScanSettings s = r.settings;
-
-            // evaluate responsibility
-            int currentChannelCount;
-            int currentScanInterval;
-            double currentCsph;
-
-            if (s.channelSet == null || s.channelSet.isEmpty()) {
-                // all channels - 11 B and 9 A channels roughly.
-                currentChannelCount = 9 + 11;
-            } else {
-                currentChannelCount = s.channelSet.size();
-                // these are rough est - no real need to correct for reg-domain;
-                if (s.channelSet.contains("A")) currentChannelCount += (9 - 1);
-                if (s.channelSet.contains("B")) currentChannelCount += (11 - 1);
-
-            }
-            if (s.scanIntervalSec == BatchedScanSettings.UNSPECIFIED) {
-                currentScanInterval = BatchedScanSettings.DEFAULT_INTERVAL_SEC;
-            } else {
-                currentScanInterval = s.scanIntervalSec;
-            }
-            currentCsph = 60 * 60 * currentChannelCount / currentScanInterval;
-
-            if (currentCsph > responsibleCsph) {
-                responsibleUid = r.uid;
-                responsibleWorkSource = r.workSource;
-                responsibleCsph = currentCsph;
-            }
-
-            if (s.maxScansPerBatch != BatchedScanSettings.UNSPECIFIED &&
-                    s.maxScansPerBatch < setting.maxScansPerBatch) {
-                setting.maxScansPerBatch = s.maxScansPerBatch;
-            }
-            if (s.maxApPerScan != BatchedScanSettings.UNSPECIFIED &&
-                    (setting.maxApPerScan == BatchedScanSettings.UNSPECIFIED ||
-                    s.maxApPerScan > setting.maxApPerScan)) {
-                setting.maxApPerScan = s.maxApPerScan;
-            }
-            if (s.scanIntervalSec != BatchedScanSettings.UNSPECIFIED &&
-                    s.scanIntervalSec < setting.scanIntervalSec) {
-                setting.scanIntervalSec = s.scanIntervalSec;
-            }
-            if (s.maxApForDistance != BatchedScanSettings.UNSPECIFIED &&
-                    (setting.maxApForDistance == BatchedScanSettings.UNSPECIFIED ||
-                    s.maxApForDistance > setting.maxApForDistance)) {
-                setting.maxApForDistance = s.maxApForDistance;
-            }
-            if (s.channelSet != null && s.channelSet.size() != 0) {
-                if (setting.channelSet == null || setting.channelSet.size() != 0) {
-                    if (setting.channelSet == null) setting.channelSet = new ArrayList<String>();
-                    for (String i : s.channelSet) {
-                        if (setting.channelSet.contains(i) == false) setting.channelSet.add(i);
-                    }
-                } // else, ignore the constraint - we already use all channels
-            } else {
-                if (setting.channelSet == null || setting.channelSet.size() != 0) {
-                    setting.channelSet = new ArrayList<String>();
-                }
-            }
-        }
-
-        setting.constrain();
-        mWifiStateMachine.setBatchedScanSettings(setting, responsibleUid, (int)responsibleCsph,
-                responsibleWorkSource);
-    }
-
-    private void enforceAccessPermission() {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
-                                                "WifiService");
-    }
-
-    private void enforceChangePermission() {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
-                                                "WifiService");
-
-    }
-
-    private void enforceWorkSourcePermission() {
-        mContext.enforceCallingPermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
-                                                "WifiService");
-
-    }
-
-    private void enforceMulticastChangePermission() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE,
-                "WifiService");
-    }
-
-    private void enforceConnectivityInternalPermission() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CONNECTIVITY_INTERNAL,
-                "ConnectivityService");
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
-     * @param enable {@code true} to enable, {@code false} to disable.
-     * @return {@code true} if the enable/disable operation was
-     *         started or is already in the queue.
-     */
-    public synchronized boolean setWifiEnabled(boolean enable) {
-        enforceChangePermission();
-        Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-        if (DBG) {
-            Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
-        }
-
-        /*
-        * Caller might not have WRITE_SECURE_SETTINGS,
-        * only CHANGE_WIFI_STATE is enforced
-        */
-
-        long ident = Binder.clearCallingIdentity();
-        try {
-            if (! mSettingsStore.handleWifiToggled(enable)) {
-                // Nothing to do if wifi cannot be toggled
-                return true;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-
-        mWifiController.sendMessage(CMD_WIFI_TOGGLED);
-        return true;
-    }
-
-    /**
-     * see {@link WifiManager#getWifiState()}
-     * @return One of {@link WifiManager#WIFI_STATE_DISABLED},
-     *         {@link WifiManager#WIFI_STATE_DISABLING},
-     *         {@link WifiManager#WIFI_STATE_ENABLED},
-     *         {@link WifiManager#WIFI_STATE_ENABLING},
-     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
-     */
-    public int getWifiEnabledState() {
-        enforceAccessPermission();
-        return mWifiStateMachine.syncGetWifiState();
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#setWifiApEnabled(WifiConfiguration, boolean)}
-     * @param wifiConfig SSID, security and channel details as
-     *        part of WifiConfiguration
-     * @param enabled true to enable and false to disable
-     */
-    public void setWifiApEnabled(WifiConfiguration wifiConfig, boolean enabled) {
-        enforceChangePermission();
-        // null wifiConfig is a meaningful input for CMD_SET_AP
-        if (wifiConfig == null || wifiConfig.isValid()) {
-            mWifiController.obtainMessage(CMD_SET_AP, enabled ? 1 : 0, 0, wifiConfig).sendToTarget();
-        } else {
-            Slog.e(TAG, "Invalid WifiConfiguration");
-        }
-    }
-
-    /**
-     * see {@link WifiManager#getWifiApState()}
-     * @return One of {@link WifiManager#WIFI_AP_STATE_DISABLED},
-     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
-     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
-     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
-     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
-     */
-    public int getWifiApEnabledState() {
-        enforceAccessPermission();
-        return mWifiStateMachine.syncGetWifiApState();
-    }
-
-    /**
-     * see {@link WifiManager#getWifiApConfiguration()}
-     * @return soft access point configuration
-     */
-    public WifiConfiguration getWifiApConfiguration() {
-        enforceAccessPermission();
-        return mWifiStateMachine.syncGetWifiApConfiguration();
-    }
-
-    /**
-     * see {@link WifiManager#setWifiApConfiguration(WifiConfiguration)}
-     * @param wifiConfig WifiConfiguration details for soft access point
-     */
-    public void setWifiApConfiguration(WifiConfiguration wifiConfig) {
-        enforceChangePermission();
-        if (wifiConfig == null)
-            return;
-        if (wifiConfig.isValid()) {
-            mWifiStateMachine.setWifiApConfiguration(wifiConfig);
-        } else {
-            Slog.e(TAG, "Invalid WifiConfiguration");
-        }
-    }
-
-    /**
-     * @param enable {@code true} to enable, {@code false} to disable.
-     * @return {@code true} if the enable/disable operation was
-     *         started or is already in the queue.
-     */
-    public boolean isScanAlwaysAvailable() {
-        enforceAccessPermission();
-        return mSettingsStore.isScanAlwaysAvailable();
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#disconnect()}
-     */
-    public void disconnect() {
-        enforceChangePermission();
-        mWifiStateMachine.disconnectCommand();
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#reconnect()}
-     */
-    public void reconnect() {
-        enforceChangePermission();
-        mWifiStateMachine.reconnectCommand();
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#reassociate()}
-     */
-    public void reassociate() {
-        enforceChangePermission();
-        mWifiStateMachine.reassociateCommand();
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#getConfiguredNetworks()}
-     * @return the list of configured networks
-     */
-    public List<WifiConfiguration> getConfiguredNetworks() {
-        enforceAccessPermission();
-        if (mWifiStateMachineChannel != null) {
-            return mWifiStateMachine.syncGetConfiguredNetworks(mWifiStateMachineChannel);
-        } else {
-            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
-            return null;
-        }
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#addOrUpdateNetwork(WifiConfiguration)}
-     * @return the supplicant-assigned identifier for the new or updated
-     * network if the operation succeeds, or {@code -1} if it fails
-     */
-    public int addOrUpdateNetwork(WifiConfiguration config) {
-        enforceChangePermission();
-        if (config.proxySettings == ProxySettings.PAC) {
-            enforceConnectivityInternalPermission();
-        }
-        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, "bad network configuration");
-            return -1;
-        }
-    }
-
-     /**
-     * See {@link android.net.wifi.WifiManager#removeNetwork(int)}
-     * @param netId the integer that identifies the network configuration
-     * to the supplicant
-     * @return {@code true} if the operation succeeded
-     */
-    public boolean removeNetwork(int netId) {
-        enforceChangePermission();
-        if (mWifiStateMachineChannel != null) {
-            return mWifiStateMachine.syncRemoveNetwork(mWifiStateMachineChannel, netId);
-        } else {
-            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
-            return false;
-        }
-    }
-
-    /**
-     * See {@link android.net.wifi.WifiManager#enableNetwork(int, boolean)}
-     * @param netId the integer that identifies the network configuration
-     * to the supplicant
-     * @param disableOthers if true, disable all other networks.
-     * @return {@code true} if the operation succeeded
-     */
-    public boolean enableNetwork(int netId, boolean disableOthers) {
-        enforceChangePermission();
-        if (mWifiStateMachineChannel != null) {
-            return mWifiStateMachine.syncEnableNetwork(mWifiStateMachineChannel, netId,
-                    disableOthers);
-        } else {
-            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
-            return false;
-        }
-    }
-
-    /**
-     * See {@link android.net.wifi.WifiManager#disableNetwork(int)}
-     * @param netId the integer that identifies the network configuration
-     * to the supplicant
-     * @return {@code true} if the operation succeeded
-     */
-    public boolean disableNetwork(int netId) {
-        enforceChangePermission();
-        if (mWifiStateMachineChannel != null) {
-            return mWifiStateMachine.syncDisableNetwork(mWifiStateMachineChannel, netId);
-        } else {
-            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
-            return false;
-        }
-    }
-
-    /**
-     * See {@link android.net.wifi.WifiManager#getConnectionInfo()}
-     * @return the Wi-Fi information, contained in {@link WifiInfo}.
-     */
-    public WifiInfo getConnectionInfo() {
-        enforceAccessPermission();
-        /*
-         * Make sure we have the latest information, by sending
-         * a status request to the supplicant.
-         */
-        return mWifiStateMachine.syncRequestConnectionInfo();
-    }
-
-    /**
-     * Return the results of the most recent access point scan, in the form of
-     * a list of {@link ScanResult} objects.
-     * @return the list of results
-     */
-    public List<ScanResult> getScanResults(String callingPackage) {
-        enforceAccessPermission();
-        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<ScanResult>();
-            }
-            int currentUser = ActivityManager.getCurrentUser();
-            if (userId != currentUser) {
-                return new ArrayList<ScanResult>();
-            } else {
-                return mWifiStateMachine.syncGetScanResultsList();
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    /**
-     * Tell the supplicant to persist the current list of configured networks.
-     * @return {@code true} if the operation succeeded
-     *
-     * TODO: deprecate this
-     */
-    public boolean saveConfiguration() {
-        boolean result = true;
-        enforceChangePermission();
-        if (mWifiStateMachineChannel != null) {
-            return mWifiStateMachine.syncSaveConfig(mWifiStateMachineChannel);
-        } else {
-            Slog.e(TAG, "mWifiStateMachineChannel is not initialized");
-            return false;
-        }
-    }
-
-    /**
-     * Set the country code
-     * @param countryCode ISO 3166 country code.
-     * @param persist {@code true} if the setting should be remembered.
-     *
-     * The persist behavior exists so that wifi can fall back to the last
-     * persisted country code on a restart, when the locale information is
-     * not available from telephony.
-     */
-    public void setCountryCode(String countryCode, boolean persist) {
-        Slog.i(TAG, "WifiService trying to set country code to " + countryCode +
-                " with persist set to " + persist);
-        enforceConnectivityInternalPermission();
-        final long token = Binder.clearCallingIdentity();
-        try {
-            mWifiStateMachine.setCountryCode(countryCode, persist);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    /**
-     * Set the operational frequency band
-     * @param band One of
-     *     {@link WifiManager#WIFI_FREQUENCY_BAND_AUTO},
-     *     {@link WifiManager#WIFI_FREQUENCY_BAND_5GHZ},
-     *     {@link WifiManager#WIFI_FREQUENCY_BAND_2GHZ},
-     * @param persist {@code true} if the setting should be remembered.
-     *
-     */
-    public void setFrequencyBand(int band, boolean persist) {
-        enforceChangePermission();
-        if (!isDualBandSupported()) return;
-        Slog.i(TAG, "WifiService trying to set frequency band to " + band +
-                " with persist set to " + persist);
-        final long token = Binder.clearCallingIdentity();
-        try {
-            mWifiStateMachine.setFrequencyBand(band, persist);
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-
-    /**
-     * Get the operational frequency band
-     */
-    public int getFrequencyBand() {
-        enforceAccessPermission();
-        return mWifiStateMachine.getFrequencyBand();
-    }
-
-    public boolean isDualBandSupported() {
-        //TODO: Should move towards adding a driver API that checks at runtime
-        return mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_wifi_dual_band_support);
-    }
-
-    /**
-     * Return the DHCP-assigned addresses from the last successful DHCP request,
-     * if any.
-     * @return the DHCP information
-     * @deprecated
-     */
-    public DhcpInfo getDhcpInfo() {
-        enforceAccessPermission();
-        DhcpResults dhcpResults = mWifiStateMachine.syncGetDhcpResults();
-        if (dhcpResults.linkProperties == null) return null;
-
-        DhcpInfo info = new DhcpInfo();
-        for (LinkAddress la : dhcpResults.linkProperties.getLinkAddresses()) {
-            InetAddress addr = la.getAddress();
-            if (addr instanceof Inet4Address) {
-                info.ipAddress = NetworkUtils.inetAddressToInt((Inet4Address)addr);
-                break;
-            }
-        }
-        for (RouteInfo r : dhcpResults.linkProperties.getRoutes()) {
-            if (r.isDefaultRoute()) {
-                InetAddress gateway = r.getGateway();
-                if (gateway instanceof Inet4Address) {
-                    info.gateway = NetworkUtils.inetAddressToInt((Inet4Address)gateway);
-                }
-            } else if (r.hasGateway() == false) {
-                LinkAddress dest = r.getDestination();
-                if (dest.getAddress() instanceof Inet4Address) {
-                    info.netmask = NetworkUtils.prefixLengthToNetmaskInt(
-                            dest.getNetworkPrefixLength());
-                }
-            }
-        }
-        int dnsFound = 0;
-        for (InetAddress dns : dhcpResults.linkProperties.getDnses()) {
-            if (dns instanceof Inet4Address) {
-                if (dnsFound == 0) {
-                    info.dns1 = NetworkUtils.inetAddressToInt((Inet4Address)dns);
-                } else {
-                    info.dns2 = NetworkUtils.inetAddressToInt((Inet4Address)dns);
-                }
-                if (++dnsFound > 1) break;
-            }
-        }
-        InetAddress serverAddress = dhcpResults.serverAddress;
-        if (serverAddress instanceof Inet4Address) {
-            info.serverAddress = NetworkUtils.inetAddressToInt((Inet4Address)serverAddress);
-        }
-        info.leaseDuration = dhcpResults.leaseDuration;
-
-        return info;
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#startWifi}
-     *
-     */
-    public void startWifi() {
-        enforceConnectivityInternalPermission();
-        /* TODO: may be add permissions for access only to connectivity service
-         * TODO: if a start issued, keep wifi alive until a stop issued irrespective
-         * of WifiLock & device idle status unless wifi enabled status is toggled
-         */
-
-        mWifiStateMachine.setDriverStart(true);
-        mWifiStateMachine.reconnectCommand();
-    }
-
-    public void captivePortalCheckComplete() {
-        enforceConnectivityInternalPermission();
-        mWifiStateMachine.captivePortalCheckComplete();
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#stopWifi}
-     *
-     */
-    public void stopWifi() {
-        enforceConnectivityInternalPermission();
-        /*
-         * TODO: if a stop is issued, wifi is brought up only by startWifi
-         * unless wifi enabled status is toggled
-         */
-        mWifiStateMachine.setDriverStart(false);
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#addToBlacklist}
-     *
-     */
-    public void addToBlacklist(String bssid) {
-        enforceChangePermission();
-
-        mWifiStateMachine.addToBlacklist(bssid);
-    }
-
-    /**
-     * see {@link android.net.wifi.WifiManager#clearBlacklist}
-     *
-     */
-    public void clearBlacklist() {
-        enforceChangePermission();
-
-        mWifiStateMachine.clearBlacklist();
-    }
-
-    /**
-     * 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
-     */
-    public Messenger getWifiServiceMessenger() {
-        enforceAccessPermission();
-        enforceChangePermission();
-        return new Messenger(mClientHandler);
-    }
-
-    /** Get a reference to WifiStateMachine handler for AsyncChannel communication */
-    public Messenger getWifiStateMachineMessenger() {
-        enforceAccessPermission();
-        enforceChangePermission();
-        return mWifiStateMachine.getMessenger();
-    }
-
-    /**
-     * Get the IP and proxy configuration file
-     */
-    public String getConfigFile() {
-        enforceAccessPermission();
-        return mWifiStateMachine.getConfigFile();
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (action.equals(Intent.ACTION_SCREEN_ON)) {
-                mWifiController.sendMessage(CMD_SCREEN_ON);
-            } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
-                mWifiController.sendMessage(CMD_USER_PRESENT);
-            } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
-                mWifiController.sendMessage(CMD_SCREEN_OFF);
-            } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
-                int pluggedType = intent.getIntExtra("plugged", 0);
-                mWifiController.sendMessage(CMD_BATTERY_CHANGED, pluggedType, 0, null);
-            } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
-                int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE,
-                        BluetoothAdapter.STATE_DISCONNECTED);
-                mWifiStateMachine.sendBluetoothAdapterStateChange(state);
-            } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) {
-                boolean emergencyMode = intent.getBooleanExtra("phoneinECMState", false);
-                mWifiController.sendMessage(CMD_EMERGENCY_MODE_CHANGED, emergencyMode ? 1 : 0, 0);
-            }
-        }
-    };
-
-    /**
-     * Observes settings changes to scan always mode.
-     */
-    private void registerForScanModeChange() {
-        ContentObserver contentObserver = new ContentObserver(null) {
-            @Override
-            public void onChange(boolean selfChange) {
-                mSettingsStore.handleWifiScanAlwaysAvailableToggled();
-                mWifiController.sendMessage(CMD_SCAN_ALWAYS_MODE_CHANGED);
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE),
-                false, contentObserver);
-    }
-
-    private void registerForBroadcasts() {
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
-        intentFilter.addAction(Intent.ACTION_USER_PRESENT);
-        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
-        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
-        intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
-        intentFilter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED);
-        mContext.registerReceiver(mReceiver, intentFilter);
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump WifiService from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-            return;
-        }
-        pw.println("Wi-Fi is " + mWifiStateMachine.syncGetWifiStateByName());
-        pw.println("Stay-awake conditions: " +
-                Settings.Global.getInt(mContext.getContentResolver(),
-                                       Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0));
-        pw.println("mMulticastEnabled " + mMulticastEnabled);
-        pw.println("mMulticastDisabled " + mMulticastDisabled);
-        mWifiController.dump(fd, pw, args);
-        mSettingsStore.dump(fd, pw, args);
-        mNotificationController.dump(fd, pw, args);
-        mTrafficPoller.dump(fd, pw, args);
-
-        pw.println("Latest scan results:");
-        List<ScanResult> scanResults = mWifiStateMachine.syncGetScanResultsList();
-        if (scanResults != null && scanResults.size() != 0) {
-            pw.println("  BSSID              Frequency   RSSI  Flags             SSID");
-            for (ScanResult r : scanResults) {
-                pw.printf("  %17s  %9d  %5d  %-16s  %s%n",
-                                         r.BSSID,
-                                         r.frequency,
-                                         r.level,
-                                         r.capabilities,
-                                         r.SSID == null ? "" : r.SSID);
-            }
-        }
-        pw.println();
-        pw.println("Locks acquired: " + mFullLocksAcquired + " full, " +
-                mFullHighPerfLocksAcquired + " full high perf, " +
-                mScanLocksAcquired + " scan");
-        pw.println("Locks released: " + mFullLocksReleased + " full, " +
-                mFullHighPerfLocksReleased + " full high perf, " +
-                mScanLocksReleased + " scan");
-        pw.println();
-        pw.println("Locks held:");
-        mLocks.dump(pw);
-
-        mWifiWatchdogStateMachine.dump(fd, pw, args);
-        pw.println();
-        mWifiStateMachine.dump(fd, pw, args);
-        pw.println();
-    }
-
-    private class WifiLock extends DeathRecipient {
-        WifiLock(int lockMode, String tag, IBinder binder, WorkSource ws) {
-            super(lockMode, tag, binder, ws);
-        }
-
-        public void binderDied() {
-            synchronized (mLocks) {
-                releaseWifiLockLocked(mBinder);
-            }
-        }
-
-        public String toString() {
-            return "WifiLock{" + mTag + " type=" + mMode + " binder=" + mBinder + "}";
-        }
-    }
-
-    class LockList {
-        private List<WifiLock> mList;
-
-        private LockList() {
-            mList = new ArrayList<WifiLock>();
-        }
-
-        synchronized boolean hasLocks() {
-            return !mList.isEmpty();
-        }
-
-        synchronized int getStrongestLockMode() {
-            if (mList.isEmpty()) {
-                return WifiManager.WIFI_MODE_FULL;
-            }
-
-            if (mFullHighPerfLocksAcquired > mFullHighPerfLocksReleased) {
-                return WifiManager.WIFI_MODE_FULL_HIGH_PERF;
-            }
-
-            if (mFullLocksAcquired > mFullLocksReleased) {
-                return WifiManager.WIFI_MODE_FULL;
-            }
-
-            return WifiManager.WIFI_MODE_SCAN_ONLY;
-        }
-
-        synchronized void updateWorkSource(WorkSource ws) {
-            for (int i = 0; i < mLocks.mList.size(); i++) {
-                ws.add(mLocks.mList.get(i).mWorkSource);
-            }
-        }
-
-        private void addLock(WifiLock lock) {
-            if (findLockByBinder(lock.mBinder) < 0) {
-                mList.add(lock);
-            }
-        }
-
-        private WifiLock removeLock(IBinder binder) {
-            int index = findLockByBinder(binder);
-            if (index >= 0) {
-                WifiLock ret = mList.remove(index);
-                ret.unlinkDeathRecipient();
-                return ret;
-            } else {
-                return null;
-            }
-        }
-
-        private int findLockByBinder(IBinder binder) {
-            int size = mList.size();
-            for (int i = size - 1; i >= 0; i--) {
-                if (mList.get(i).mBinder == binder)
-                    return i;
-            }
-            return -1;
-        }
-
-        private void dump(PrintWriter pw) {
-            for (WifiLock l : mList) {
-                pw.print("    ");
-                pw.println(l);
-            }
-        }
-    }
-
-    void enforceWakeSourcePermission(int uid, int pid) {
-        if (uid == android.os.Process.myUid()) {
-            return;
-        }
-        mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
-                pid, uid, null);
-    }
-
-    public boolean acquireWifiLock(IBinder binder, int lockMode, String tag, WorkSource ws) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
-        if (lockMode != WifiManager.WIFI_MODE_FULL &&
-                lockMode != WifiManager.WIFI_MODE_SCAN_ONLY &&
-                lockMode != WifiManager.WIFI_MODE_FULL_HIGH_PERF) {
-            Slog.e(TAG, "Illegal argument, lockMode= " + lockMode);
-            if (DBG) throw new IllegalArgumentException("lockMode=" + lockMode);
-            return false;
-        }
-        if (ws != null && ws.size() == 0) {
-            ws = null;
-        }
-        if (ws != null) {
-            enforceWakeSourcePermission(Binder.getCallingUid(), Binder.getCallingPid());
-        }
-        if (ws == null) {
-            ws = new WorkSource(Binder.getCallingUid());
-        }
-        WifiLock wifiLock = new WifiLock(lockMode, tag, binder, ws);
-        synchronized (mLocks) {
-            return acquireWifiLockLocked(wifiLock);
-        }
-    }
-
-    private void noteAcquireWifiLock(WifiLock wifiLock) throws RemoteException {
-        switch(wifiLock.mMode) {
-            case WifiManager.WIFI_MODE_FULL:
-            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
-            case WifiManager.WIFI_MODE_SCAN_ONLY:
-                mBatteryStats.noteFullWifiLockAcquiredFromSource(wifiLock.mWorkSource);
-                break;
-        }
-    }
-
-    private void noteReleaseWifiLock(WifiLock wifiLock) throws RemoteException {
-        switch(wifiLock.mMode) {
-            case WifiManager.WIFI_MODE_FULL:
-            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
-            case WifiManager.WIFI_MODE_SCAN_ONLY:
-                mBatteryStats.noteFullWifiLockReleasedFromSource(wifiLock.mWorkSource);
-                break;
-        }
-    }
-
-    private boolean acquireWifiLockLocked(WifiLock wifiLock) {
-        if (DBG) Slog.d(TAG, "acquireWifiLockLocked: " + wifiLock);
-
-        mLocks.addLock(wifiLock);
-
-        long ident = Binder.clearCallingIdentity();
-        try {
-            noteAcquireWifiLock(wifiLock);
-            switch(wifiLock.mMode) {
-            case WifiManager.WIFI_MODE_FULL:
-                ++mFullLocksAcquired;
-                break;
-            case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
-                ++mFullHighPerfLocksAcquired;
-                break;
-
-            case WifiManager.WIFI_MODE_SCAN_ONLY:
-                ++mScanLocksAcquired;
-                break;
-            }
-            mWifiController.sendMessage(CMD_LOCKS_CHANGED);
-            return true;
-        } catch (RemoteException e) {
-            return false;
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    public void updateWifiLockWorkSource(IBinder lock, WorkSource ws) {
-        int uid = Binder.getCallingUid();
-        int pid = Binder.getCallingPid();
-        if (ws != null && ws.size() == 0) {
-            ws = null;
-        }
-        if (ws != null) {
-            enforceWakeSourcePermission(uid, pid);
-        }
-        long ident = Binder.clearCallingIdentity();
-        try {
-            synchronized (mLocks) {
-                int index = mLocks.findLockByBinder(lock);
-                if (index < 0) {
-                    throw new IllegalArgumentException("Wifi lock not active");
-                }
-                WifiLock wl = mLocks.mList.get(index);
-                noteReleaseWifiLock(wl);
-                wl.mWorkSource = ws != null ? new WorkSource(ws) : new WorkSource(uid);
-                noteAcquireWifiLock(wl);
-            }
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    public boolean releaseWifiLock(IBinder lock) {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WAKE_LOCK, null);
-        synchronized (mLocks) {
-            return releaseWifiLockLocked(lock);
-        }
-    }
-
-    private boolean releaseWifiLockLocked(IBinder lock) {
-        boolean hadLock;
-
-        WifiLock wifiLock = mLocks.removeLock(lock);
-
-        if (DBG) Slog.d(TAG, "releaseWifiLockLocked: " + wifiLock);
-
-        hadLock = (wifiLock != null);
-
-        long ident = Binder.clearCallingIdentity();
-        try {
-            if (hadLock) {
-                noteReleaseWifiLock(wifiLock);
-                switch(wifiLock.mMode) {
-                    case WifiManager.WIFI_MODE_FULL:
-                        ++mFullLocksReleased;
-                        break;
-                    case WifiManager.WIFI_MODE_FULL_HIGH_PERF:
-                        ++mFullHighPerfLocksReleased;
-                        break;
-                    case WifiManager.WIFI_MODE_SCAN_ONLY:
-                        ++mScanLocksReleased;
-                        break;
-                }
-                mWifiController.sendMessage(CMD_LOCKS_CHANGED);
-            }
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-
-        return hadLock;
-    }
-
-    private abstract class DeathRecipient
-            implements IBinder.DeathRecipient {
-        String mTag;
-        int mMode;
-        IBinder mBinder;
-        WorkSource mWorkSource;
-
-        DeathRecipient(int mode, String tag, IBinder binder, WorkSource ws) {
-            super();
-            mTag = tag;
-            mMode = mode;
-            mBinder = binder;
-            mWorkSource = ws;
-            try {
-                mBinder.linkToDeath(this, 0);
-            } catch (RemoteException e) {
-                binderDied();
-            }
-        }
-
-        void unlinkDeathRecipient() {
-            mBinder.unlinkToDeath(this, 0);
-        }
-    }
-
-    private class Multicaster extends DeathRecipient {
-        Multicaster(String tag, IBinder binder) {
-            super(Binder.getCallingUid(), tag, binder, null);
-        }
-
-        public void binderDied() {
-            Slog.e(TAG, "Multicaster binderDied");
-            synchronized (mMulticasters) {
-                int i = mMulticasters.indexOf(this);
-                if (i != -1) {
-                    removeMulticasterLocked(i, mMode);
-                }
-            }
-        }
-
-        public String toString() {
-            return "Multicaster{" + mTag + " binder=" + mBinder + "}";
-        }
-
-        public int getUid() {
-            return mMode;
-        }
-    }
-
-    public void initializeMulticastFiltering() {
-        enforceMulticastChangePermission();
-
-        synchronized (mMulticasters) {
-            // if anybody had requested filters be off, leave off
-            if (mMulticasters.size() != 0) {
-                return;
-            } else {
-                mWifiStateMachine.startFilteringMulticastV4Packets();
-            }
-        }
-    }
-
-    public void acquireMulticastLock(IBinder binder, String tag) {
-        enforceMulticastChangePermission();
-
-        synchronized (mMulticasters) {
-            mMulticastEnabled++;
-            mMulticasters.add(new Multicaster(tag, binder));
-            // Note that we could call stopFilteringMulticastV4Packets only when
-            // our new size == 1 (first call), but this function won't
-            // be called often and by making the stopPacket call each
-            // time we're less fragile and self-healing.
-            mWifiStateMachine.stopFilteringMulticastV4Packets();
-        }
-
-        int uid = Binder.getCallingUid();
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.noteWifiMulticastEnabled(uid);
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    public void releaseMulticastLock() {
-        enforceMulticastChangePermission();
-
-        int uid = Binder.getCallingUid();
-        synchronized (mMulticasters) {
-            mMulticastDisabled++;
-            int size = mMulticasters.size();
-            for (int i = size - 1; i >= 0; i--) {
-                Multicaster m = mMulticasters.get(i);
-                if ((m != null) && (m.getUid() == uid)) {
-                    removeMulticasterLocked(i, uid);
-                }
-            }
-        }
-    }
-
-    private void removeMulticasterLocked(int i, int uid)
-    {
-        Multicaster removed = mMulticasters.remove(i);
-
-        if (removed != null) {
-            removed.unlinkDeathRecipient();
-        }
-        if (mMulticasters.size() == 0) {
-            mWifiStateMachine.startFilteringMulticastV4Packets();
-        }
-
-        final long ident = Binder.clearCallingIdentity();
-        try {
-            mBatteryStats.noteWifiMulticastDisabled(uid);
-        } catch (RemoteException e) {
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-    }
-
-    public boolean isMulticastEnabled() {
-        enforceAccessPermission();
-
-        synchronized (mMulticasters) {
-            return (mMulticasters.size() > 0);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/wifi/WifiSettingsStore.java b/services/core/java/com/android/server/wifi/WifiSettingsStore.java
deleted file mode 100644
index 3ff8061..0000000
--- a/services/core/java/com/android/server/wifi/WifiSettingsStore.java
+++ /dev/null
@@ -1,197 +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.server.wifi;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/* Tracks persisted settings for Wi-Fi and airplane mode interaction */
-final class WifiSettingsStore {
-    /* Values tracked in Settings.Global.WIFI_ON */
-    private static final int WIFI_DISABLED                      = 0;
-    private static final int WIFI_ENABLED                       = 1;
-    /* Wifi enabled while in airplane mode */
-    private static final int WIFI_ENABLED_AIRPLANE_OVERRIDE     = 2;
-    /* Wifi disabled due to airplane mode on */
-    private static final int WIFI_DISABLED_AIRPLANE_ON          = 3;
-
-    /* Persisted state that tracks the wifi & airplane interaction from settings */
-    private int mPersistWifiState = WIFI_DISABLED;
-    /* Tracks current airplane mode state */
-    private boolean mAirplaneModeOn = false;
-
-    /* Tracks the setting of scan being available even when wi-fi is turned off
-     */
-    private boolean mScanAlwaysAvailable;
-
-    private final Context mContext;
-
-    /* Tracks if we have checked the saved wi-fi state after boot */
-    private boolean mCheckSavedStateAtBoot = false;
-
-    WifiSettingsStore(Context context) {
-        mContext = context;
-        mAirplaneModeOn = getPersistedAirplaneModeOn();
-        mPersistWifiState = getPersistedWifiState();
-        mScanAlwaysAvailable = getPersistedScanAlwaysAvailable();
-    }
-
-    synchronized boolean isWifiToggleEnabled() {
-        if (!mCheckSavedStateAtBoot) {
-            mCheckSavedStateAtBoot = true;
-            if (testAndClearWifiSavedState()) return true;
-        }
-
-        if (mAirplaneModeOn) {
-            return mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE;
-        } else {
-            return mPersistWifiState != WIFI_DISABLED;
-        }
-    }
-
-    /**
-     * Returns true if airplane mode is currently on.
-     * @return {@code true} if airplane mode is on.
-     */
-    synchronized boolean isAirplaneModeOn() {
-       return mAirplaneModeOn;
-    }
-
-    synchronized boolean isScanAlwaysAvailable() {
-        return mScanAlwaysAvailable;
-    }
-
-    synchronized boolean handleWifiToggled(boolean wifiEnabled) {
-        // Can Wi-Fi be toggled in airplane mode ?
-        if (mAirplaneModeOn && !isAirplaneToggleable()) {
-            return false;
-        }
-
-        if (wifiEnabled) {
-            if (mAirplaneModeOn) {
-                persistWifiState(WIFI_ENABLED_AIRPLANE_OVERRIDE);
-            } else {
-                persistWifiState(WIFI_ENABLED);
-            }
-        } else {
-            // When wifi state is disabled, we do not care
-            // if airplane mode is on or not. The scenario of
-            // wifi being disabled due to airplane mode being turned on
-            // is handled handleAirplaneModeToggled()
-            persistWifiState(WIFI_DISABLED);
-        }
-        return true;
-    }
-
-    synchronized boolean handleAirplaneModeToggled() {
-        // Is Wi-Fi sensitive to airplane mode changes ?
-        if (!isAirplaneSensitive()) {
-            return false;
-        }
-
-        mAirplaneModeOn = getPersistedAirplaneModeOn();
-        if (mAirplaneModeOn) {
-            // Wifi disabled due to airplane on
-            if (mPersistWifiState == WIFI_ENABLED) {
-                persistWifiState(WIFI_DISABLED_AIRPLANE_ON);
-            }
-        } else {
-            /* On airplane mode disable, restore wifi state if necessary */
-            if (testAndClearWifiSavedState() ||
-                    mPersistWifiState == WIFI_ENABLED_AIRPLANE_OVERRIDE) {
-                persistWifiState(WIFI_ENABLED);
-            }
-        }
-        return true;
-    }
-
-    synchronized void handleWifiScanAlwaysAvailableToggled() {
-        mScanAlwaysAvailable = getPersistedScanAlwaysAvailable();
-    }
-
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("mPersistWifiState " + mPersistWifiState);
-        pw.println("mAirplaneModeOn " + mAirplaneModeOn);
-    }
-
-    private void persistWifiState(int state) {
-        final ContentResolver cr = mContext.getContentResolver();
-        mPersistWifiState = state;
-        Settings.Global.putInt(cr, Settings.Global.WIFI_ON, state);
-    }
-
-    /* Does Wi-Fi need to be disabled when airplane mode is on ? */
-    private boolean isAirplaneSensitive() {
-        String airplaneModeRadios = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_RADIOS);
-        return airplaneModeRadios == null
-                || airplaneModeRadios.contains(Settings.Global.RADIO_WIFI);
-    }
-
-    /* Is Wi-Fi allowed to be re-enabled while airplane mode is on ? */
-    private boolean isAirplaneToggleable() {
-        String toggleableRadios = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
-        return toggleableRadios != null
-                && toggleableRadios.contains(Settings.Global.RADIO_WIFI);
-    }
-
-     /* After a reboot, we restore wi-fi to be on if it was turned off temporarily for tethering.
-      * The settings app tracks the saved state, but the framework has to check it at boot to
-      * make sure the wi-fi is turned on in case it was turned off for the purpose of tethering.
-      *
-      * Note that this is not part of the regular WIFI_ON setting because this only needs to
-      * be controlled through the settings app and not the Wi-Fi public API.
-      */
-    private boolean testAndClearWifiSavedState() {
-        final ContentResolver cr = mContext.getContentResolver();
-        int wifiSavedState = 0;
-        try {
-            wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE);
-            if(wifiSavedState == 1)
-                Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
-        } catch (Settings.SettingNotFoundException e) {
-            ;
-        }
-        return (wifiSavedState == 1);
-    }
-
-    private int getPersistedWifiState() {
-        final ContentResolver cr = mContext.getContentResolver();
-        try {
-            return Settings.Global.getInt(cr, Settings.Global.WIFI_ON);
-        } catch (Settings.SettingNotFoundException e) {
-            Settings.Global.putInt(cr, Settings.Global.WIFI_ON, WIFI_DISABLED);
-            return WIFI_DISABLED;
-        }
-    }
-
-    private boolean getPersistedAirplaneModeOn() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
-    }
-
-    private boolean getPersistedScanAlwaysAvailable() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
-                0) == 1;
-    }
-}
diff --git a/services/core/java/com/android/server/wifi/WifiTrafficPoller.java b/services/core/java/com/android/server/wifi/WifiTrafficPoller.java
deleted file mode 100644
index b498550..0000000
--- a/services/core/java/com/android/server/wifi/WifiTrafficPoller.java
+++ /dev/null
@@ -1,191 +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.server.wifi;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.NetworkInfo;
-import static android.net.NetworkInfo.DetailedState.CONNECTED;
-import android.net.TrafficStats;
-import android.net.wifi.WifiManager;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-import android.os.Handler;
-import android.os.Message;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import com.android.internal.util.AsyncChannel;
-
-/* Polls for traffic stats and notifies the clients */
-final class WifiTrafficPoller {
-    /**
-     * Interval in milliseconds between polling for traffic
-     * statistics
-     */
-    private static final int POLL_TRAFFIC_STATS_INTERVAL_MSECS = 1000;
-
-    private static final int ENABLE_TRAFFIC_STATS_POLL  = 1;
-    private static final int TRAFFIC_STATS_POLL         = 2;
-    private static final int ADD_CLIENT                 = 3;
-    private static final int REMOVE_CLIENT              = 4;
-
-    private boolean mEnableTrafficStatsPoll = false;
-    private int mTrafficStatsPollToken = 0;
-    private long mTxPkts;
-    private long mRxPkts;
-    /* Tracks last reported data activity */
-    private int mDataActivity;
-
-    private final List<Messenger> mClients = new ArrayList<Messenger>();
-    // err on the side of updating at boot since screen on broadcast may be missed
-    // the first time
-    private AtomicBoolean mScreenOn = new AtomicBoolean(true);
-    private final TrafficHandler mTrafficHandler;
-    private NetworkInfo mNetworkInfo;
-    private final String mInterface;
-
-    WifiTrafficPoller(Context context, String iface) {
-        mInterface = iface;
-        mTrafficHandler = new TrafficHandler();
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        filter.addAction(Intent.ACTION_SCREEN_OFF);
-        filter.addAction(Intent.ACTION_SCREEN_ON);
-
-        context.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        if (intent.getAction().equals(
-                                WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                            mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
-                                    WifiManager.EXTRA_NETWORK_INFO);
-                        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
-                            mScreenOn.set(false);
-                        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
-                            mScreenOn.set(true);
-                        }
-                        evaluateTrafficStatsPolling();
-                    }
-                }, filter);
-    }
-
-    void addClient(Messenger client) {
-        Message.obtain(mTrafficHandler, ADD_CLIENT, client).sendToTarget();
-    }
-
-    void removeClient(Messenger client) {
-        Message.obtain(mTrafficHandler, REMOVE_CLIENT, client).sendToTarget();
-    }
-
-
-    private class TrafficHandler extends Handler {
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case ENABLE_TRAFFIC_STATS_POLL:
-                    mEnableTrafficStatsPoll = (msg.arg1 == 1);
-                    mTrafficStatsPollToken++;
-                    if (mEnableTrafficStatsPoll) {
-                        notifyOnDataActivity();
-                        sendMessageDelayed(Message.obtain(this, TRAFFIC_STATS_POLL,
-                                mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
-                    }
-                    break;
-                case TRAFFIC_STATS_POLL:
-                    if (msg.arg1 == mTrafficStatsPollToken) {
-                        notifyOnDataActivity();
-                        sendMessageDelayed(Message.obtain(this, TRAFFIC_STATS_POLL,
-                                mTrafficStatsPollToken, 0), POLL_TRAFFIC_STATS_INTERVAL_MSECS);
-                    }
-                    break;
-                case ADD_CLIENT:
-                    mClients.add((Messenger) msg.obj);
-                    break;
-                case REMOVE_CLIENT:
-                    mClients.remove(msg.obj);
-                    break;
-            }
-
-        }
-    }
-
-    private void evaluateTrafficStatsPolling() {
-        Message msg;
-        if (mNetworkInfo == null) return;
-        if (mNetworkInfo.getDetailedState() == CONNECTED && mScreenOn.get()) {
-            msg = Message.obtain(mTrafficHandler,
-                    ENABLE_TRAFFIC_STATS_POLL, 1, 0);
-        } else {
-            msg = Message.obtain(mTrafficHandler,
-                    ENABLE_TRAFFIC_STATS_POLL, 0, 0);
-        }
-        msg.sendToTarget();
-    }
-
-    private void notifyOnDataActivity() {
-        long sent, received;
-        long preTxPkts = mTxPkts, preRxPkts = mRxPkts;
-        int dataActivity = WifiManager.DATA_ACTIVITY_NONE;
-
-        mTxPkts = TrafficStats.getTxPackets(mInterface);
-        mRxPkts = TrafficStats.getRxPackets(mInterface);
-
-        if (preTxPkts > 0 || preRxPkts > 0) {
-            sent = mTxPkts - preTxPkts;
-            received = mRxPkts - preRxPkts;
-            if (sent > 0) {
-                dataActivity |= WifiManager.DATA_ACTIVITY_OUT;
-            }
-            if (received > 0) {
-                dataActivity |= WifiManager.DATA_ACTIVITY_IN;
-            }
-
-            if (dataActivity != mDataActivity && mScreenOn.get()) {
-                mDataActivity = dataActivity;
-                for (Messenger client : mClients) {
-                    Message msg = Message.obtain();
-                    msg.what = WifiManager.DATA_ACTIVITY_NOTIFICATION;
-                    msg.arg1 = mDataActivity;
-                    try {
-                        client.send(msg);
-                    } catch (RemoteException e) {
-                        // Failed to reach, skip
-                        // Client removal is handled in WifiService
-                    }
-                }
-            }
-        }
-    }
-
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("mEnableTrafficStatsPoll " + mEnableTrafficStatsPoll);
-        pw.println("mTrafficStatsPollToken " + mTrafficStatsPollToken);
-        pw.println("mTxPkts " + mTxPkts);
-        pw.println("mRxPkts " + mRxPkts);
-        pw.println("mDataActivity " + mDataActivity);
-    }
-
-}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
new file mode 100644
index 0000000..35b7f99
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -0,0 +1,1173 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.Service;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.ArraySet;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.MagnificationSpec;
+import android.view.Surface;
+import android.view.Surface.OutOfResourcesException;
+import android.view.SurfaceControl;
+import android.view.WindowInfo;
+import android.view.WindowManager;
+import android.view.WindowManagerInternal.MagnificationCallbacks;
+import android.view.WindowManagerInternal.WindowsForAccessibilityCallback;
+import android.view.WindowManagerPolicy;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import com.android.internal.R;
+import com.android.internal.os.SomeArgs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class contains the accessibility related logic of the window manger.
+ */
+final class AccessibilityController {
+
+    private final WindowManagerService mWindowManagerService;
+
+    private static final float[] sTempFloats = new float[9];
+
+    public AccessibilityController(WindowManagerService service) {
+        mWindowManagerService = service;
+    }
+
+    private DisplayMagnifier mDisplayMagnifier;
+
+    private WindowsForAccessibilityObserver mWindowsForAccessibilityObserver;
+
+    public void setMagnificationCallbacksLocked(MagnificationCallbacks callbacks) {
+        if (callbacks != null) {
+            if (mDisplayMagnifier != null) {
+                throw new IllegalStateException("Magnification callbacks already set!");
+            }
+            mDisplayMagnifier = new DisplayMagnifier(mWindowManagerService, callbacks);
+        } else {
+            if  (mDisplayMagnifier == null) {
+                throw new IllegalStateException("Magnification callbacks already cleared!");
+            }
+            mDisplayMagnifier.destroyLocked();
+            mDisplayMagnifier = null;
+        }
+    }
+
+    public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) {
+        if (callback != null) {
+            if (mWindowsForAccessibilityObserver != null) {
+                throw new IllegalStateException(
+                        "Windows for accessibility callback already set!");
+            }
+            mWindowsForAccessibilityObserver = new WindowsForAccessibilityObserver(
+                    mWindowManagerService, callback);
+        } else {
+            if (mWindowsForAccessibilityObserver == null) {
+                throw new IllegalStateException(
+                        "Windows for accessibility callback already cleared!");
+            }
+            mWindowsForAccessibilityObserver = null;
+        }
+    }
+
+    public void setMagnificationSpecLocked(MagnificationSpec spec) {
+        if (mDisplayMagnifier != null) {
+            mDisplayMagnifier.setMagnificationSpecLocked(spec);
+        }
+        if (mWindowsForAccessibilityObserver != null) {
+            mWindowsForAccessibilityObserver.computeChangedWindows();
+        }
+    }
+
+    public void onRectangleOnScreenRequestedLocked(Rect rectangle, boolean immediate) {
+        if (mDisplayMagnifier != null) {
+            mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle, immediate);
+        }
+        // Not relevant for the window observer.
+    }
+
+    public void onWindowLayersChangedLocked() {
+        if (mDisplayMagnifier != null) {
+            mDisplayMagnifier.onWindowLayersChangedLocked();
+        }
+        if (mWindowsForAccessibilityObserver != null) {
+            mWindowsForAccessibilityObserver.computeChangedWindows();
+        }
+    }
+
+    public void onRotationChangedLocked(DisplayContent displayContent, int rotation) {
+        if (mDisplayMagnifier != null) {
+            mDisplayMagnifier.onRotationChangedLocked(displayContent, rotation);
+        }
+        if (mWindowsForAccessibilityObserver != null) {
+            mWindowsForAccessibilityObserver.computeChangedWindows();
+        }
+    }
+
+    public void onAppWindowTransitionLocked(WindowState windowState, int transition) {
+        if (mDisplayMagnifier != null) {
+            mDisplayMagnifier.onAppWindowTransitionLocked(windowState, transition);
+        }
+        // Not relevant for the window observer.
+    }
+
+    public void onWindowTransitionLocked(WindowState windowState, int transition) {
+        if (mDisplayMagnifier != null) {
+            mDisplayMagnifier.onWindowTransitionLocked(windowState, transition);
+        }
+        if (mWindowsForAccessibilityObserver != null) {
+            mWindowsForAccessibilityObserver.computeChangedWindows();
+        }
+    }
+
+    public void onWindowFocusChangedLocked() {
+        // Not relevant for the display magnifier.
+
+        if (mWindowsForAccessibilityObserver != null) {
+            mWindowsForAccessibilityObserver.computeChangedWindows();
+        }
+    }
+
+    /** NOTE: This has to be called within a surface transaction. */
+    public void drawMagnifiedRegionBorderIfNeededLocked() {
+        if (mDisplayMagnifier != null) {
+            mDisplayMagnifier.drawMagnifiedRegionBorderIfNeededLocked();
+        }
+        // Not relevant for the window observer.
+    }
+
+    public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) {
+        if (mDisplayMagnifier != null) {
+            return mDisplayMagnifier.getMagnificationSpecForWindowLocked(windowState);
+        }
+        return null;
+    }
+
+    public boolean hasCallbacksLocked() {
+        return (mDisplayMagnifier != null
+                || mWindowsForAccessibilityObserver != null);
+    }
+
+    private static void populateTransformationMatrixLocked(WindowState windowState,
+            Matrix outMatrix) {
+        sTempFloats[Matrix.MSCALE_X] = windowState.mWinAnimator.mDsDx;
+        sTempFloats[Matrix.MSKEW_Y] = windowState.mWinAnimator.mDtDx;
+        sTempFloats[Matrix.MSKEW_X] = windowState.mWinAnimator.mDsDy;
+        sTempFloats[Matrix.MSCALE_Y] = windowState.mWinAnimator.mDtDy;
+        sTempFloats[Matrix.MTRANS_X] = windowState.mShownFrame.left;
+        sTempFloats[Matrix.MTRANS_Y] = windowState.mShownFrame.top;
+        sTempFloats[Matrix.MPERSP_0] = 0;
+        sTempFloats[Matrix.MPERSP_1] = 0;
+        sTempFloats[Matrix.MPERSP_2] = 1;
+        outMatrix.setValues(sTempFloats);
+    }
+
+    /**
+     * This class encapsulates the functionality related to display magnification.
+     */
+    private static final class DisplayMagnifier {
+
+        private static final String LOG_TAG = "DisplayMagnifier";
+
+        private static final boolean DEBUG_WINDOW_TRANSITIONS = false;
+        private static final boolean DEBUG_ROTATION = false;
+        private static final boolean DEBUG_LAYERS = false;
+        private static final boolean DEBUG_RECTANGLE_REQUESTED = false;
+        private static final boolean DEBUG_VIEWPORT_WINDOW = false;
+
+        private final Rect mTempRect1 = new Rect();
+        private final Rect mTempRect2 = new Rect();
+
+        private final Region mTempRegion1 = new Region();
+        private final Region mTempRegion2 = new Region();
+        private final Region mTempRegion3 = new Region();
+        private final Region mTempRegion4 = new Region();
+
+        private final Context mContext;
+        private final WindowManagerService mWindowManagerService;
+        private final MagnifiedViewport mMagnifedViewport;
+        private final Handler mHandler;
+
+        private final MagnificationCallbacks mCallbacks;
+
+        private final long mLongAnimationDuration;
+
+        public DisplayMagnifier(WindowManagerService windowManagerService,
+                MagnificationCallbacks callbacks) {
+            mContext = windowManagerService.mContext;
+            mWindowManagerService = windowManagerService;
+            mCallbacks = callbacks;
+            mHandler = new MyHandler(mWindowManagerService.mH.getLooper());
+            mMagnifedViewport = new MagnifiedViewport();
+            mLongAnimationDuration = mContext.getResources().getInteger(
+                    com.android.internal.R.integer.config_longAnimTime);
+        }
+
+        public void setMagnificationSpecLocked(MagnificationSpec spec) {
+            mMagnifedViewport.updateMagnificationSpecLocked(spec);
+            mMagnifedViewport.recomputeBoundsLocked();
+            mWindowManagerService.scheduleAnimationLocked();
+        }
+
+        public void onRectangleOnScreenRequestedLocked(Rect rectangle, boolean immediate) {
+            if (DEBUG_RECTANGLE_REQUESTED) {
+                Slog.i(LOG_TAG, "Rectangle on screen requested: " + rectangle);
+            }
+            if (!mMagnifedViewport.isMagnifyingLocked()) {
+                return;
+            }
+            Rect magnifiedRegionBounds = mTempRect2;
+            mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked(magnifiedRegionBounds);
+            if (magnifiedRegionBounds.contains(rectangle)) {
+                return;
+            }
+            SomeArgs args = SomeArgs.obtain();
+            args.argi1 = rectangle.left;
+            args.argi2 = rectangle.top;
+            args.argi3 = rectangle.right;
+            args.argi4 = rectangle.bottom;
+            mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED,
+                    args).sendToTarget();
+        }
+
+        public void onWindowLayersChangedLocked() {
+            if (DEBUG_LAYERS) {
+                Slog.i(LOG_TAG, "Layers changed.");
+            }
+            mMagnifedViewport.recomputeBoundsLocked();
+            mWindowManagerService.scheduleAnimationLocked();
+        }
+
+        public void onRotationChangedLocked(DisplayContent displayContent, int rotation) {
+            if (DEBUG_ROTATION) {
+                Slog.i(LOG_TAG, "Rotaton: " + Surface.rotationToString(rotation)
+                        + " displayId: " + displayContent.getDisplayId());
+            }
+            mMagnifedViewport.onRotationChangedLocked();
+            mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_ROTATION_CHANGED);
+        }
+
+        public void onAppWindowTransitionLocked(WindowState windowState, int transition) {
+            if (DEBUG_WINDOW_TRANSITIONS) {
+                Slog.i(LOG_TAG, "Window transition: "
+                        + AppTransition.appTransitionToString(transition)
+                        + " displayId: " + windowState.getDisplayId());
+            }
+            final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
+            if (magnifying) {
+                switch (transition) {
+                    case AppTransition.TRANSIT_ACTIVITY_OPEN:
+                    case AppTransition.TRANSIT_TASK_OPEN:
+                    case AppTransition.TRANSIT_TASK_TO_FRONT:
+                    case AppTransition.TRANSIT_WALLPAPER_OPEN:
+                    case AppTransition.TRANSIT_WALLPAPER_CLOSE:
+                    case AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN: {
+                        mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_USER_CONTEXT_CHANGED);
+                    }
+                }
+            }
+        }
+
+        public void onWindowTransitionLocked(WindowState windowState, int transition) {
+            if (DEBUG_WINDOW_TRANSITIONS) {
+                Slog.i(LOG_TAG, "Window transition: "
+                        + AppTransition.appTransitionToString(transition)
+                        + " displayId: " + windowState.getDisplayId());
+            }
+            final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
+            final int type = windowState.mAttrs.type;
+            switch (transition) {
+                case WindowManagerPolicy.TRANSIT_ENTER:
+                case WindowManagerPolicy.TRANSIT_SHOW: {
+                    if (!magnifying) {
+                        break;
+                    }
+                    switch (type) {
+                        case WindowManager.LayoutParams.TYPE_APPLICATION:
+                        case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
+                        case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
+                        case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
+                        case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG:
+                        case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
+                        case WindowManager.LayoutParams.TYPE_PHONE:
+                        case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
+                        case WindowManager.LayoutParams.TYPE_TOAST:
+                        case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
+                        case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
+                        case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
+                        case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
+                        case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
+                        case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
+                        case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
+                        case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY: {
+                            Rect magnifiedRegionBounds = mTempRect2;
+                            mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked(
+                                    magnifiedRegionBounds);
+                            Rect touchableRegionBounds = mTempRect1;
+                            windowState.getTouchableRegion(mTempRegion1);
+                            mTempRegion1.getBounds(touchableRegionBounds);
+                            if (!magnifiedRegionBounds.intersect(touchableRegionBounds)) {
+                                mCallbacks.onRectangleOnScreenRequested(
+                                        touchableRegionBounds.left,
+                                        touchableRegionBounds.top,
+                                        touchableRegionBounds.right,
+                                        touchableRegionBounds.bottom);
+                            }
+                        } break;
+                    } break;
+                }
+            }
+        }
+
+        public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) {
+            MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked();
+            if (spec != null && !spec.isNop()) {
+                WindowManagerPolicy policy = mWindowManagerService.mPolicy;
+                final int windowType = windowState.mAttrs.type;
+                if (!policy.isTopLevelWindow(windowType) && windowState.mAttachedWindow != null
+                        && !policy.canMagnifyWindow(windowType)) {
+                    return null;
+                }
+                if (!policy.canMagnifyWindow(windowState.mAttrs.type)) {
+                    return null;
+                }
+            }
+            return spec;
+        }
+
+        public void destroyLocked() {
+            mMagnifedViewport.destroyWindow();
+        }
+
+        /** NOTE: This has to be called within a surface transaction. */
+        public void drawMagnifiedRegionBorderIfNeededLocked() {
+            mMagnifedViewport.drawWindowIfNeededLocked();
+        }
+
+        private final class MagnifiedViewport {
+
+            private static final int DEFAUTLT_BORDER_WIDTH_DIP = 5;
+
+            private final SparseArray<WindowState> mTempWindowStates =
+                    new SparseArray<WindowState>();
+
+            private final RectF mTempRectF = new RectF();
+
+            private final Point mTempPoint = new Point();
+
+            private final Matrix mTempMatrix = new Matrix();
+
+            private final Region mMagnifiedBounds = new Region();
+            private final Region mOldMagnifiedBounds = new Region();
+
+            private final MagnificationSpec mMagnificationSpec = MagnificationSpec.obtain();
+
+            private final WindowManager mWindowManager;
+
+            private final int mBorderWidth;
+            private final int mHalfBorderWidth;
+
+            private final ViewportWindow mWindow;
+
+            private boolean mFullRedrawNeeded;
+
+            public MagnifiedViewport() {
+                mWindowManager = (WindowManager) mContext.getSystemService(Service.WINDOW_SERVICE);
+                mBorderWidth = (int) TypedValue.applyDimension(
+                        TypedValue.COMPLEX_UNIT_DIP, DEFAUTLT_BORDER_WIDTH_DIP,
+                                mContext.getResources().getDisplayMetrics());
+                mHalfBorderWidth = (int) (mBorderWidth + 0.5) / 2;
+                mWindow = new ViewportWindow(mContext);
+                recomputeBoundsLocked();
+            }
+
+            public void updateMagnificationSpecLocked(MagnificationSpec spec) {
+                if (spec != null) {
+                    mMagnificationSpec.initialize(spec.scale, spec.offsetX, spec.offsetY);
+                } else {
+                    mMagnificationSpec.clear();
+                }
+                // If this message is pending we are in a rotation animation and do not want
+                // to show the border. We will do so when the pending message is handled.
+                if (!mHandler.hasMessages(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)) {
+                    setMagnifiedRegionBorderShownLocked(isMagnifyingLocked(), true);
+                }
+            }
+
+            public void recomputeBoundsLocked() {
+                mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
+                final int screenWidth = mTempPoint.x;
+                final int screenHeight = mTempPoint.y;
+
+                Region magnifiedBounds = mMagnifiedBounds;
+                magnifiedBounds.set(0, 0, 0, 0);
+
+                Region availableBounds = mTempRegion1;
+                availableBounds.set(0, 0, screenWidth, screenHeight);
+
+                Region nonMagnifiedBounds = mTempRegion4;
+                nonMagnifiedBounds.set(0,  0,  0,  0);
+
+                SparseArray<WindowState> visibleWindows = mTempWindowStates;
+                visibleWindows.clear();
+                populateWindowsOnScreenLocked(visibleWindows);
+
+                final int visibleWindowCount = visibleWindows.size();
+                for (int i = visibleWindowCount - 1; i >= 0; i--) {
+                    WindowState windowState = visibleWindows.valueAt(i);
+                    if (windowState.mAttrs.type == WindowManager
+                            .LayoutParams.TYPE_MAGNIFICATION_OVERLAY) {
+                        continue;
+                    }
+
+                    Region windowBounds = mTempRegion2;
+                    Matrix matrix = mTempMatrix;
+                    populateTransformationMatrixLocked(windowState, matrix);
+                    RectF windowFrame = mTempRectF;
+
+                    if (mWindowManagerService.mPolicy.canMagnifyWindow(windowState.mAttrs.type)) {
+                        windowFrame.set(windowState.mFrame);
+                        windowFrame.offset(-windowFrame.left, -windowFrame.top);
+                        matrix.mapRect(windowFrame);
+                        windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
+                                (int) windowFrame.right, (int) windowFrame.bottom);
+                        magnifiedBounds.op(windowBounds, Region.Op.UNION);
+                        magnifiedBounds.op(availableBounds, Region.Op.INTERSECT);
+                    } else {
+                        Region touchableRegion = mTempRegion3;
+                        windowState.getTouchableRegion(touchableRegion);
+                        Rect touchableFrame = mTempRect1;
+                        touchableRegion.getBounds(touchableFrame);
+                        windowFrame.set(touchableFrame);
+                        windowFrame.offset(-windowState.mFrame.left, -windowState.mFrame.top);
+                        matrix.mapRect(windowFrame);
+                        windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
+                                (int) windowFrame.right, (int) windowFrame.bottom);
+                        nonMagnifiedBounds.op(windowBounds, Region.Op.UNION);
+                        windowBounds.op(magnifiedBounds, Region.Op.DIFFERENCE);
+                        availableBounds.op(windowBounds, Region.Op.DIFFERENCE);
+                    }
+
+                    Region accountedBounds = mTempRegion2;
+                    accountedBounds.set(magnifiedBounds);
+                    accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION);
+                    accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT);
+
+                    if (accountedBounds.isRect()) {
+                        Rect accountedFrame = mTempRect1;
+                        accountedBounds.getBounds(accountedFrame);
+                        if (accountedFrame.width() == screenWidth
+                                && accountedFrame.height() == screenHeight) {
+                            break;
+                        }
+                    }
+                }
+
+                visibleWindows.clear();
+
+                magnifiedBounds.op(mHalfBorderWidth, mHalfBorderWidth,
+                        screenWidth - mHalfBorderWidth, screenHeight - mHalfBorderWidth,
+                        Region.Op.INTERSECT);
+
+                if (!mOldMagnifiedBounds.equals(magnifiedBounds)) {
+                    Region bounds = Region.obtain();
+                    bounds.set(magnifiedBounds);
+                    mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED,
+                            bounds).sendToTarget();
+
+                    mWindow.setBounds(magnifiedBounds);
+                    Rect dirtyRect = mTempRect1;
+                    if (mFullRedrawNeeded) {
+                        mFullRedrawNeeded = false;
+                        dirtyRect.set(mHalfBorderWidth, mHalfBorderWidth,
+                                screenWidth - mHalfBorderWidth, screenHeight - mHalfBorderWidth);
+                        mWindow.invalidate(dirtyRect);
+                    } else {
+                        Region dirtyRegion = mTempRegion3;
+                        dirtyRegion.set(magnifiedBounds);
+                        dirtyRegion.op(mOldMagnifiedBounds, Region.Op.UNION);
+                        dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT);
+                        dirtyRegion.getBounds(dirtyRect);
+                        mWindow.invalidate(dirtyRect);
+                    }
+
+                    mOldMagnifiedBounds.set(magnifiedBounds);
+                }
+            }
+
+            public void onRotationChangedLocked() {
+                // If we are magnifying, hide the magnified border window immediately so
+                // the user does not see strange artifacts during rotation. The screenshot
+                // used for rotation has already the border. After the rotation is complete
+                // we will show the border.
+                if (isMagnifyingLocked()) {
+                    setMagnifiedRegionBorderShownLocked(false, false);
+                    final long delay = (long) (mLongAnimationDuration
+                            * mWindowManagerService.mWindowAnimationScale);
+                    Message message = mHandler.obtainMessage(
+                            MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED);
+                    mHandler.sendMessageDelayed(message, delay);
+                }
+                recomputeBoundsLocked();
+                mWindow.updateSize();
+            }
+
+            public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) {
+                if (shown) {
+                    mFullRedrawNeeded = true;
+                    mOldMagnifiedBounds.set(0,  0,  0,  0);
+                }
+                mWindow.setShown(shown, animate);
+            }
+
+            public void getMagnifiedFrameInContentCoordsLocked(Rect rect) {
+                MagnificationSpec spec = mMagnificationSpec;
+                mMagnifiedBounds.getBounds(rect);
+                rect.offset((int) -spec.offsetX, (int) -spec.offsetY);
+                rect.scale(1.0f / spec.scale);
+            }
+
+            public boolean isMagnifyingLocked() {
+                return mMagnificationSpec.scale > 1.0f;
+            }
+
+            public MagnificationSpec getMagnificationSpecLocked() {
+                return mMagnificationSpec;
+            }
+
+            /** NOTE: This has to be called within a surface transaction. */
+            public void drawWindowIfNeededLocked() {
+                recomputeBoundsLocked();
+                mWindow.drawIfNeeded();
+            }
+
+            public void destroyWindow() {
+                mWindow.releaseSurface();
+            }
+
+            private void populateWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
+                DisplayContent displayContent = mWindowManagerService
+                        .getDefaultDisplayContentLocked();
+                WindowList windowList = displayContent.getWindowList();
+                final int windowCount = windowList.size();
+                for (int i = 0; i < windowCount; i++) {
+                    WindowState windowState = windowList.get(i);
+                    if ((windowState.isOnScreen() || windowState.mAttrs.type == WindowManager
+                            .LayoutParams.TYPE_UNIVERSE_BACKGROUND)
+                            && !windowState.mWinAnimator.mEnterAnimationPending) {
+                        outWindows.put(windowState.mLayer, windowState);
+                    }
+                }
+            }
+
+            private final class ViewportWindow {
+                private static final String SURFACE_TITLE = "Magnification Overlay";
+
+                private static final String PROPERTY_NAME_ALPHA = "alpha";
+
+                private static final int MIN_ALPHA = 0;
+                private static final int MAX_ALPHA = 255;
+
+                private final Region mBounds = new Region();
+                private final Rect mDirtyRect = new Rect();
+                private final Paint mPaint = new Paint();
+
+                private final ValueAnimator mShowHideFrameAnimator;
+                private final SurfaceControl mSurfaceControl;
+                private final Surface mSurface = new Surface();
+
+                private boolean mShown;
+                private int mAlpha;
+
+                private boolean mInvalidated;
+
+                public ViewportWindow(Context context) {
+                    SurfaceControl surfaceControl = null;
+                    try {
+                        mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
+                        surfaceControl = new SurfaceControl(mWindowManagerService.mFxSession,
+                                SURFACE_TITLE, mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT,
+                                SurfaceControl.HIDDEN);
+                    } catch (OutOfResourcesException oore) {
+                        /* ignore */
+                    }
+                    mSurfaceControl = surfaceControl;
+                    mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay()
+                            .getLayerStack());
+                    mSurfaceControl.setLayer(mWindowManagerService.mPolicy.windowTypeToLayerLw(
+                            WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
+                            * WindowManagerService.TYPE_LAYER_MULTIPLIER);
+                    mSurfaceControl.setPosition(0, 0);
+                    mSurface.copyFrom(mSurfaceControl);
+
+                    TypedValue typedValue = new TypedValue();
+                    context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight,
+                            typedValue, true);
+                    final int borderColor = context.getResources().getColor(typedValue.resourceId);
+
+                    mPaint.setStyle(Paint.Style.STROKE);
+                    mPaint.setStrokeWidth(mBorderWidth);
+                    mPaint.setColor(borderColor);
+
+                    Interpolator interpolator = new DecelerateInterpolator(2.5f);
+                    final long longAnimationDuration = context.getResources().getInteger(
+                            com.android.internal.R.integer.config_longAnimTime);
+
+                    mShowHideFrameAnimator = ObjectAnimator.ofInt(this, PROPERTY_NAME_ALPHA,
+                            MIN_ALPHA, MAX_ALPHA);
+                    mShowHideFrameAnimator.setInterpolator(interpolator);
+                    mShowHideFrameAnimator.setDuration(longAnimationDuration);
+                    mInvalidated = true;
+                }
+
+                public void setShown(boolean shown, boolean animate) {
+                    synchronized (mWindowManagerService.mWindowMap) {
+                        if (mShown == shown) {
+                            return;
+                        }
+                        mShown = shown;
+                        if (animate) {
+                            if (mShowHideFrameAnimator.isRunning()) {
+                                mShowHideFrameAnimator.reverse();
+                            } else {
+                                if (shown) {
+                                    mShowHideFrameAnimator.start();
+                                } else {
+                                    mShowHideFrameAnimator.reverse();
+                                }
+                            }
+                        } else {
+                            mShowHideFrameAnimator.cancel();
+                            if (shown) {
+                                setAlpha(MAX_ALPHA);
+                            } else {
+                                setAlpha(MIN_ALPHA);
+                            }
+                        }
+                        if (DEBUG_VIEWPORT_WINDOW) {
+                            Slog.i(LOG_TAG, "ViewportWindow shown: " + mShown);
+                        }
+                    }
+                }
+
+                @SuppressWarnings("unused")
+                // Called reflectively from an animator.
+                public int getAlpha() {
+                    synchronized (mWindowManagerService.mWindowMap) {
+                        return mAlpha;
+                    }
+                }
+
+                public void setAlpha(int alpha) {
+                    synchronized (mWindowManagerService.mWindowMap) {
+                        if (mAlpha == alpha) {
+                            return;
+                        }
+                        mAlpha = alpha;
+                        invalidate(null);
+                        if (DEBUG_VIEWPORT_WINDOW) {
+                            Slog.i(LOG_TAG, "ViewportWindow set alpha: " + alpha);
+                        }
+                    }
+                }
+
+                public void setBounds(Region bounds) {
+                    synchronized (mWindowManagerService.mWindowMap) {
+                        if (mBounds.equals(bounds)) {
+                            return;
+                        }
+                        mBounds.set(bounds);
+                        invalidate(mDirtyRect);
+                        if (DEBUG_VIEWPORT_WINDOW) {
+                            Slog.i(LOG_TAG, "ViewportWindow set bounds: " + bounds);
+                        }
+                    }
+                }
+
+                public void updateSize() {
+                    synchronized (mWindowManagerService.mWindowMap) {
+                        mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
+                        mSurfaceControl.setSize(mTempPoint.x, mTempPoint.y);
+                        invalidate(mDirtyRect);
+                    }
+                }
+
+                public void invalidate(Rect dirtyRect) {
+                    if (dirtyRect != null) {
+                        mDirtyRect.set(dirtyRect);
+                    } else {
+                        mDirtyRect.setEmpty();
+                    }
+                    mInvalidated = true;
+                    mWindowManagerService.scheduleAnimationLocked();
+                }
+
+                /** NOTE: This has to be called within a surface transaction. */
+                public void drawIfNeeded() {
+                    synchronized (mWindowManagerService.mWindowMap) {
+                        if (!mInvalidated) {
+                            return;
+                        }
+                        mInvalidated = false;
+                        Canvas canvas = null;
+                        try {
+                            // Empty dirty rectangle means unspecified.
+                            if (mDirtyRect.isEmpty()) {
+                                mBounds.getBounds(mDirtyRect);
+                            }
+                            mDirtyRect.inset(- mHalfBorderWidth, - mHalfBorderWidth);
+                            canvas = mSurface.lockCanvas(mDirtyRect);
+                            if (DEBUG_VIEWPORT_WINDOW) {
+                                Slog.i(LOG_TAG, "Dirty rect: " + mDirtyRect);
+                            }
+                        } catch (IllegalArgumentException iae) {
+                            /* ignore */
+                        } catch (Surface.OutOfResourcesException oore) {
+                            /* ignore */
+                        }
+                        if (canvas == null) {
+                            return;
+                        }
+                        if (DEBUG_VIEWPORT_WINDOW) {
+                            Slog.i(LOG_TAG, "Bounds: " + mBounds);
+                        }
+                        canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
+                        mPaint.setAlpha(mAlpha);
+                        Path path = mBounds.getBoundaryPath();
+                        canvas.drawPath(path, mPaint);
+
+                        mSurface.unlockCanvasAndPost(canvas);
+
+                        if (mAlpha > 0) {
+                            mSurfaceControl.show();
+                        } else {
+                            mSurfaceControl.hide();
+                        }
+                    }
+                }
+
+                public void releaseSurface() {
+                    mSurfaceControl.release();
+                    mSurface.release();
+                }
+            }
+        }
+
+        private class MyHandler extends Handler {
+            public static final int MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED = 1;
+            public static final int MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 2;
+            public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3;
+            public static final int MESSAGE_NOTIFY_ROTATION_CHANGED = 4;
+            public static final int MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED = 5;
+
+            public MyHandler(Looper looper) {
+                super(looper);
+            }
+
+            @Override
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED: {
+                        Region bounds = (Region) message.obj;
+                        mCallbacks.onMagnifedBoundsChanged(bounds);
+                        bounds.recycle();
+                    } break;
+
+                    case MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {
+                        SomeArgs args = (SomeArgs) message.obj;
+                        final int left = args.argi1;
+                        final int top = args.argi2;
+                        final int right = args.argi3;
+                        final int bottom = args.argi4;
+                        mCallbacks.onRectangleOnScreenRequested(left, top, right, bottom);
+                        args.recycle();
+                    } break;
+
+                    case MESSAGE_NOTIFY_USER_CONTEXT_CHANGED: {
+                        mCallbacks.onUserContextChanged();
+                    } break;
+
+                    case MESSAGE_NOTIFY_ROTATION_CHANGED: {
+                        final int rotation = message.arg1;
+                        mCallbacks.onRotationChanged(rotation);
+                    } break;
+
+                    case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : {
+                        synchronized (mWindowManagerService.mWindowMap) {
+                            if (mMagnifedViewport.isMagnifyingLocked()) {
+                                mMagnifedViewport.setMagnifiedRegionBorderShownLocked(true, true);
+                                mWindowManagerService.scheduleAnimationLocked();
+                            }
+                        }
+                    } break;
+                }
+            }
+        }
+    }
+
+    /**
+     * This class encapsulates the functionality related to computing the windows
+     * reported for accessibility purposes. These windows are all windows a sighted
+     * user can see on the screen.
+     */
+    private static final class WindowsForAccessibilityObserver {
+        private static final String LOG_TAG = "WindowsForAccessibilityObserver";
+
+        private static final boolean DEBUG = false;
+
+        private final SparseArray<WindowState> mTempWindowStates =
+                new SparseArray<WindowState>();
+
+        private final List<WindowInfo> mOldWindows = new ArrayList<WindowInfo>();
+
+        private final Set<IBinder> mTempBinderSet = new ArraySet<IBinder>();
+
+        private final RectF mTempRectF = new RectF();
+
+        private final Matrix mTempMatrix = new Matrix();
+
+        private final Point mTempPoint = new Point();
+
+        private final Rect mTempRect = new Rect();
+
+        private final Region mTempRegion = new Region();
+
+        private final Region mTempRegion1 = new Region();
+
+        private final Context mContext;
+
+        private final WindowManagerService mWindowManagerService;
+
+        private final Handler mHandler;
+
+        private final WindowsForAccessibilityCallback mCallback;
+
+        public WindowsForAccessibilityObserver(WindowManagerService windowManagerService,
+                WindowsForAccessibilityCallback callback) {
+            mContext = windowManagerService.mContext;
+            mWindowManagerService = windowManagerService;
+            mCallback = callback;
+            mHandler = new MyHandler(mWindowManagerService.mH.getLooper());
+            computeChangedWindows();
+        }
+
+        public void computeChangedWindows() {
+            if (DEBUG) {
+                Slog.i(LOG_TAG, "computeChangedWindows()");
+            }
+
+            synchronized (mWindowManagerService.mWindowMap) {
+                WindowManager windowManager = (WindowManager)
+                        mContext.getSystemService(Context.WINDOW_SERVICE);
+                windowManager.getDefaultDisplay().getRealSize(mTempPoint);
+                final int screenWidth = mTempPoint.x;
+                final int screenHeight = mTempPoint.y;
+
+                Region unaccountedSpace = mTempRegion;
+                unaccountedSpace.set(0, 0, screenWidth, screenHeight);
+
+                SparseArray<WindowState> visibleWindows = mTempWindowStates;
+                populateVisibleWindowsOnScreenLocked(visibleWindows);
+
+                List<WindowInfo> windows = new ArrayList<WindowInfo>();
+
+                Set<IBinder> addedWindows = mTempBinderSet;
+                addedWindows.clear();
+
+                final int visibleWindowCount = visibleWindows.size();
+                for (int i = visibleWindowCount - 1; i >= 0; i--) {
+                    WindowState windowState = visibleWindows.valueAt(i);
+                    // Compute the window touchable frame as shown on the screen.
+
+                    // Get the touchable frame.
+                    Region touchableRegion = mTempRegion1;
+                    windowState.getTouchableRegion(touchableRegion);
+                    Rect touchableFrame = mTempRect;
+                    touchableRegion.getBounds(touchableFrame);
+
+                    // Move to origin as all transforms are captured by the matrix.
+                    RectF windowFrame = mTempRectF;
+                    windowFrame.set(touchableFrame);
+                    windowFrame.offset(-windowState.mFrame.left, -windowState.mFrame.top);
+
+                    // Map the frame to get what appears on the screen.
+                    Matrix matrix = mTempMatrix;
+                    populateTransformationMatrixLocked(windowState, matrix);
+                    matrix.mapRect(windowFrame);
+
+                    // Got the bounds.
+                    Rect boundsInScreen = mTempRect;
+                    boundsInScreen.set((int) windowFrame.left, (int) windowFrame.top,
+                            (int) windowFrame.right, (int) windowFrame.bottom);
+
+                    final int flags = windowState.mAttrs.flags;
+
+                    // If the window is not touchable, do not report it but take into account
+                    // the space it takes since the content behind it cannot be touched.
+                    if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) == 1) {
+                        unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+                                Region.Op.DIFFERENCE);
+                        continue;
+                    }
+
+                    // If the window is completely covered by other windows - ignore.
+                    if (unaccountedSpace.quickReject(boundsInScreen)) {
+                        continue;
+                    }
+
+                    // Add windows of certain types not covered by modal windows.
+                    if (isReportedWindowType(windowState.mAttrs.type)) {
+                        // Add the window to the ones to be reported.
+                        WindowInfo window = WindowInfo.obtain();
+                        window.type = windowState.mAttrs.type;
+                        window.layer = windowState.mLayer;
+                        window.token = windowState.mClient.asBinder();
+
+                        addedWindows.add(window.token);
+
+                        WindowState attachedWindow = windowState.mAttachedWindow;
+                        if (attachedWindow != null) {
+                            window.parentToken = attachedWindow.mClient.asBinder();
+                        }
+
+                        window.focused = windowState.isFocused();
+                        window.boundsInScreen.set(boundsInScreen);
+
+                        final int childCount = windowState.mChildWindows.size();
+                        if (childCount > 0) {
+                            if (window.childTokens == null) {
+                                window.childTokens = new ArrayList<IBinder>();
+                            }
+                            for (int j = 0; j < childCount; j++) {
+                                WindowState child = windowState.mChildWindows.get(j);
+                                window.childTokens.add(child.mClient.asBinder());
+                            }
+                        }
+
+                        windows.add(window);
+                    }
+
+                    // Account for the space this window takes.
+                    unaccountedSpace.op(boundsInScreen, unaccountedSpace,
+                            Region.Op.REVERSE_DIFFERENCE);
+
+                    // We figured out what is touchable for the entire screen - done.
+                    if (unaccountedSpace.isEmpty()) {
+                        break;
+                    }
+
+                    // If a window is modal, no other below can be touched - done.
+                    if ((flags & (WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)) == 0) {
+                        break;
+                    }
+                }
+
+                // Remove child/parent references to windows that were not added.
+                final int windowCount = windows.size();
+                for (int i = 0; i < windowCount; i++) {
+                    WindowInfo window = windows.get(i);
+                    if (!addedWindows.contains(window.parentToken)) {
+                        window.parentToken = null;
+                    }
+                    if (window.childTokens != null) {
+                        final int childTokenCount = window.childTokens.size();
+                        for (int j = childTokenCount - 1; j >= 0; j--) {
+                            if (!addedWindows.contains(window.childTokens.get(j))) {
+                                window.childTokens.remove(j);
+                            }
+                        }
+                        // Leave the child token list if empty.
+                    }
+                }
+
+                visibleWindows.clear();
+                addedWindows.clear();
+
+                // We computed the windows and if they changed notify the client.
+                boolean windowsChanged = false;
+                if (mOldWindows.size() != windows.size()) {
+                    // Different size means something changed.
+                    windowsChanged = true;
+                } else if (!mOldWindows.isEmpty() || !windows.isEmpty()) {
+                    // Since we always traverse windows from high to low layer
+                    // the old and new windows at the same index should be the
+                    // same, otherwise something changed.
+                    for (int i = 0; i < windowCount; i++) {
+                        WindowInfo oldWindow = mOldWindows.get(i);
+                        WindowInfo newWindow = windows.get(i);
+                        // We do not care for layer changes given the window
+                        // order does not change. This brings no new information
+                        // to the clients.
+                        if (windowChangedNoLayer(oldWindow, newWindow)) {
+                            windowsChanged = true;
+                            break;
+                        }
+                    }
+                }
+
+                if (windowsChanged) {
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "Windows changed:" + windows);
+                    }
+                    // Remember the old windows to detect changes.
+                    cacheWindows(windows);
+                    // Announce the change.
+                    mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_WINDOWS_CHANGED,
+                            windows).sendToTarget();
+                } else {
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, "No windows changed.");
+                    }
+                    // Recycle the nodes as we do not need them.
+                    clearAndRecycleWindows(windows);
+                }
+            }
+        }
+
+        private void cacheWindows(List<WindowInfo> windows) {
+            final int oldWindowCount = mOldWindows.size();
+            for (int i = oldWindowCount - 1; i >= 0; i--) {
+                mOldWindows.remove(i).recycle();
+            }
+            final int newWindowCount = windows.size();
+            for (int i = 0; i < newWindowCount; i++) {
+                WindowInfo newWindow = windows.get(i);
+                mOldWindows.add(WindowInfo.obtain(newWindow));
+            }
+        }
+
+        private boolean windowChangedNoLayer(WindowInfo oldWindow, WindowInfo newWindow) {
+            if (oldWindow == newWindow) {
+                return false;
+            }
+            if (oldWindow == null && newWindow != null) {
+                return true;
+            }
+            if (oldWindow != null && newWindow == null) {
+                return true;
+            }
+            if (oldWindow.type != newWindow.type) {
+                return true;
+            }
+            if (oldWindow.focused != newWindow.focused) {
+                return true;
+            }
+            if (oldWindow.token == null) {
+                if (newWindow.token != null) {
+                    return true;
+                }
+            } else if (!oldWindow.token.equals(newWindow.token)) {
+                return true;
+            }
+            if (oldWindow.parentToken == null) {
+                if (newWindow.parentToken != null) {
+                    return true;
+                }
+            } else if (!oldWindow.parentToken.equals(newWindow.parentToken)) {
+                return true;
+            }
+            if (!oldWindow.boundsInScreen.equals(newWindow.boundsInScreen)) {
+                return true;
+            }
+            if (oldWindow.childTokens != null && newWindow.childTokens != null
+                    && !oldWindow.childTokens.equals(newWindow.childTokens)) {
+                return true;
+            }
+            return false;
+        }
+
+        private void clearAndRecycleWindows(List<WindowInfo> windows) {
+            final int windowCount = windows.size();
+            for (int i = windowCount - 1; i >= 0; i--) {
+                windows.remove(i).recycle();
+            }
+        }
+
+        private static boolean isReportedWindowType(int windowType) {
+            return (windowType != WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
+                    && windowType != WindowManager.LayoutParams.TYPE_WALLPAPER
+                    && windowType != WindowManager.LayoutParams.TYPE_BOOT_PROGRESS
+                    && windowType != WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
+                    && windowType != WindowManager.LayoutParams.TYPE_DRAG
+                    && windowType != WindowManager.LayoutParams.TYPE_HIDDEN_NAV_CONSUMER
+                    && windowType != WindowManager.LayoutParams.TYPE_POINTER
+                    && windowType != WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND
+                    && windowType != WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY
+                    && windowType != WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
+                    && windowType != WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY
+                    && windowType != WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
+        }
+
+        private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
+            DisplayContent displayContent = mWindowManagerService
+                    .getDefaultDisplayContentLocked();
+            WindowList windowList = displayContent.getWindowList();
+            final int windowCount = windowList.size();
+            for (int i = 0; i < windowCount; i++) {
+                WindowState windowState = windowList.get(i);
+                if (windowState.isVisibleLw()) {
+                    outWindows.put(windowState.mLayer, windowState);
+                }
+            }
+        }
+
+        private class MyHandler extends Handler {
+            public static final int MESSAGE_NOTIFY_WINDOWS_CHANGED = 1;
+
+            public MyHandler(Looper looper) {
+                super(looper, null, false);
+            }
+
+            @Override
+            @SuppressWarnings("unchecked")
+            public void handleMessage(Message message) {
+                switch (message.what) {
+                    case MESSAGE_NOTIFY_WINDOWS_CHANGED: {
+                        List<WindowInfo> windows = (List<WindowInfo>) message.obj;
+                        mCallback.onWindowsForAccessibilityChanged(windows);
+                        clearAndRecycleWindows(windows);
+                    } break;
+                }
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index 756e06a..7d8b5af 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -19,18 +19,22 @@
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Point;
+import android.graphics.Rect;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IRemoteCallback;
+import android.os.SystemProperties;
 import android.util.Slog;
 import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.AnimationSet;
 import android.view.animation.AnimationUtils;
+import android.view.animation.ClipRectAnimation;
 import android.view.animation.Interpolator;
 import android.view.animation.ScaleAnimation;
 
+import android.view.animation.TranslateAnimation;
 import com.android.internal.util.DumpUtils.Dump;
 import com.android.server.AttributeCache;
 import com.android.server.wm.WindowManagerService.H;
@@ -125,6 +129,12 @@
     private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4;
     private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
 
+    // These are the possible states for the enter/exit activities during a thumbnail transition
+    private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
+    private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
+    private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
+    private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
+
     private String mNextAppTransitionPackage;
     private Bitmap mNextAppTransitionThumbnail;
     // Used for thumbnail transitions. True if we're scaling up, false if scaling down
@@ -148,10 +158,13 @@
     private final Interpolator mThumbnailFadeoutInterpolator;
 
     private int mCurrentUserId = 0;
+    private boolean mUseAlternateThumbnailAnimation;
 
     AppTransition(Context context, Handler h) {
         mContext = context;
         mH = h;
+        mUseAlternateThumbnailAnimation =
+                SystemProperties.getBoolean("persist.anim.use_alt_thumbnail", false);
         mConfigShortAnimTime = context.getResources().getInteger(
                 com.android.internal.R.integer.config_shortAnimTime);
         mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
@@ -384,80 +397,10 @@
         return a;
     }
 
-    Animation createThumbnailAnimationLocked(int transit, boolean enter, boolean thumb,
-                                    int appWidth, int appHeight) {
-        Animation a;
-        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
-        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
-        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
-        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
-        if (thumb) {
-            // Animation for zooming thumbnail from its initial size to
-            // filling the screen.
-            if (mNextAppTransitionScaleUp) {
-                float scaleW = appWidth / thumbWidth;
-                float scaleH = appHeight / thumbHeight;
-                Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
-                        computePivot(mNextAppTransitionStartX, 1 / scaleW),
-                        computePivot(mNextAppTransitionStartY, 1 / scaleH));
-                scale.setInterpolator(mDecelerateInterpolator);
-
-                Animation alpha = new AlphaAnimation(1, 0);
-                alpha.setInterpolator(mThumbnailFadeoutInterpolator);
-
-                // This AnimationSet uses the Interpolators assigned above.
-                AnimationSet set = new AnimationSet(false);
-                set.addAnimation(scale);
-                set.addAnimation(alpha);
-                a = set;
-            } else {
-                float scaleW = appWidth / thumbWidth;
-                float scaleH = appHeight / thumbHeight;
-                a = new ScaleAnimation(scaleW, 1, scaleH, 1,
-                        computePivot(mNextAppTransitionStartX, 1 / scaleW),
-                        computePivot(mNextAppTransitionStartY, 1 / scaleH));
-            }
-        } else if (enter) {
-            // Entering app zooms out from the center of the thumbnail.
-            if (mNextAppTransitionScaleUp) {
-                float scaleW = thumbWidth / appWidth;
-                float scaleH = thumbHeight / appHeight;
-                a = new ScaleAnimation(scaleW, 1, scaleH, 1,
-                        computePivot(mNextAppTransitionStartX, scaleW),
-                        computePivot(mNextAppTransitionStartY, scaleH));
-            } else {
-                // noop animation
-                a = new AlphaAnimation(1, 1);
-            }
-        } else {
-            // Exiting app
-            if (mNextAppTransitionScaleUp) {
-                if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
-                    // Fade out while bringing up selected activity. This keeps the
-                    // current activity from showing through a launching wallpaper
-                    // activity.
-                    a = new AlphaAnimation(1, 0);
-                } else {
-                    // noop animation
-                    a = new AlphaAnimation(1, 1);
-                }
-            } else {
-                float scaleW = thumbWidth / appWidth;
-                float scaleH = thumbHeight / appHeight;
-                Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
-                        computePivot(mNextAppTransitionStartX, scaleW),
-                        computePivot(mNextAppTransitionStartY, scaleH));
-
-                Animation alpha = new AlphaAnimation(1, 0);
-
-                AnimationSet set = new AnimationSet(true);
-                set.addAnimation(scale);
-                set.addAnimation(alpha);
-                set.setZAdjustment(Animation.ZORDER_TOP);
-                a = set;
-            }
-        }
-
+    /**
+     * Prepares the specified animation with a standard duration, interpolator, etc.
+     */
+    Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight, int transit) {
         // Pick the desired duration.  If this is an inter-activity transition,
         // it  is the standard duration for that.  Otherwise we use the longer
         // task transition duration.
@@ -478,9 +421,223 @@
         return a;
     }
 
+    /**
+     * Return the current thumbnail transition state.
+     */
+    int getThumbnailTransitionState(boolean enter) {
+        if (enter) {
+            if (mNextAppTransitionScaleUp) {
+                return THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
+            } else {
+                return THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN;
+            }
+        } else {
+            if (mNextAppTransitionScaleUp) {
+                return THUMBNAIL_TRANSITION_EXIT_SCALE_UP;
+            } else {
+                return THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN;
+            }
+        }
+    }
+
+    /**
+     * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
+     * when a thumbnail is specified with the activity options.
+     */
+    Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
+        Animation a;
+        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
+        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
+
+        if (mNextAppTransitionScaleUp) {
+            // Animation for the thumbnail zooming from its initial size to the full screen
+            float scaleW = appWidth / thumbWidth;
+            float scaleH = appHeight / thumbHeight;
+            Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
+                    computePivot(mNextAppTransitionStartX, 1 / scaleW),
+                    computePivot(mNextAppTransitionStartY, 1 / scaleH));
+            scale.setInterpolator(mDecelerateInterpolator);
+
+            Animation alpha = new AlphaAnimation(1, 0);
+            alpha.setInterpolator(mThumbnailFadeoutInterpolator);
+
+            // This AnimationSet uses the Interpolators assigned above.
+            AnimationSet set = new AnimationSet(false);
+            set.addAnimation(scale);
+            set.addAnimation(alpha);
+            a = set;
+        } else {
+            // Animation for the thumbnail zooming down from the full screen to its final size
+            float scaleW = appWidth / thumbWidth;
+            float scaleH = appHeight / thumbHeight;
+            a = new ScaleAnimation(scaleW, 1, scaleH, 1,
+                    computePivot(mNextAppTransitionStartX, 1 / scaleW),
+                    computePivot(mNextAppTransitionStartY, 1 / scaleH));
+        }
+
+        return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
+    }
+
+    /**
+     * This alternate animation is created when we are doing a thumbnail transition, for the
+     * activity that is leaving, and the activity that is entering.
+     */
+    Animation createAlternateThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
+                                                    int appHeight, int transit,
+                                                    Rect containingFrame, Rect contentInsets) {
+        Animation a;
+        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
+        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
+
+        switch (thumbTransitState) {
+            case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
+                // Entering app scales up with the thumbnail
+                float scale = thumbWidth / appWidth;
+                int unscaledThumbHeight = (int) (thumbHeight / scale);
+                int scaledTopDecor = (int) (scale * contentInsets.top);
+                Rect fromClipRect = new Rect(containingFrame);
+                fromClipRect.bottom = (fromClipRect.top + unscaledThumbHeight);
+                Rect toClipRect = new Rect(containingFrame);
+
+                Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
+                        computePivot(mNextAppTransitionStartX, scale),
+                        computePivot(mNextAppTransitionStartY, scale));
+                Animation alphaAnim = new AlphaAnimation(1, 1);
+                Animation clipAnim = new ClipRectAnimation(fromClipRect, toClipRect);
+                Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
+
+                AnimationSet set = new AnimationSet(true);
+                set.addAnimation(alphaAnim);
+                set.addAnimation(clipAnim);
+                set.addAnimation(scaleAnim);
+                set.addAnimation(translateAnim);
+                a = set;
+                break;
+            }
+            case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
+                // Exiting app while the thumbnail is scaling up should fade
+                if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
+                    // Fade out while bringing up selected activity. This keeps the
+                    // current activity from showing through a launching wallpaper
+                    // activity.
+                    a = new AlphaAnimation(1, 0);
+                } else {
+                    // noop animation
+                    a = new AlphaAnimation(1, 1);
+                }
+                break;
+            }
+            case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
+                // Entering the other app, it should just be visible while we scale the thumbnail
+                // down above it
+                a = new AlphaAnimation(1, 1);
+                break;
+            }
+            case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
+                // Exiting the current app, the app should scale down with the thumbnail
+                float scale = thumbWidth / appWidth;
+                int unscaledThumbHeight = (int) (thumbHeight / scale);
+                int scaledTopDecor = (int) (scale * contentInsets.top);
+                Rect fromClipRect = new Rect(containingFrame);
+                Rect toClipRect = new Rect(containingFrame);
+                toClipRect.bottom = (toClipRect.top + unscaledThumbHeight);
+
+                Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
+                        computePivot(mNextAppTransitionStartX, scale),
+                        computePivot(mNextAppTransitionStartY, scale));
+                Animation alphaAnim = new AlphaAnimation(1, 1);
+                Animation clipAnim = new ClipRectAnimation(fromClipRect, toClipRect);
+                Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
+
+                AnimationSet set = new AnimationSet(true);
+                set.addAnimation(alphaAnim);
+                set.addAnimation(clipAnim);
+                set.addAnimation(scaleAnim);
+                set.addAnimation(translateAnim);
+
+                a = set;
+                a.setZAdjustment(Animation.ZORDER_TOP);
+                break;
+            }
+            default:
+                throw new RuntimeException("Invalid thumbnail transition state");
+        }
+
+        return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
+    }
+
+    /**
+     * This animation is created when we are doing a thumbnail transition, for the activity that is
+     * leaving, and the activity that is entering.
+     */
+    Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
+                                                    int appHeight, int transit) {
+        Animation a;
+        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
+        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
+
+        switch (thumbTransitState) {
+            case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
+                // Entering app scales up with the thumbnail
+                float scaleW = thumbWidth / appWidth;
+                float scaleH = thumbHeight / appHeight;
+                a = new ScaleAnimation(scaleW, 1, scaleH, 1,
+                        computePivot(mNextAppTransitionStartX, scaleW),
+                        computePivot(mNextAppTransitionStartY, scaleH));
+                break;
+            }
+            case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
+                // Exiting app while the thumbnail is scaling up should fade or stay in place
+                if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
+                    // Fade out while bringing up selected activity. This keeps the
+                    // current activity from showing through a launching wallpaper
+                    // activity.
+                    a = new AlphaAnimation(1, 0);
+                } else {
+                    // noop animation
+                    a = new AlphaAnimation(1, 1);
+                }
+                break;
+            }
+            case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
+                // Entering the other app, it should just be visible while we scale the thumbnail
+                // down above it
+                a = new AlphaAnimation(1, 1);
+                break;
+            }
+            case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
+                // Exiting the current app, the app should scale down with the thumbnail
+                float scaleW = thumbWidth / appWidth;
+                float scaleH = thumbHeight / appHeight;
+                Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
+                        computePivot(mNextAppTransitionStartX, scaleW),
+                        computePivot(mNextAppTransitionStartY, scaleH));
+
+                Animation alpha = new AlphaAnimation(1, 0);
+
+                AnimationSet set = new AnimationSet(true);
+                set.addAnimation(scale);
+                set.addAnimation(alpha);
+                set.setZAdjustment(Animation.ZORDER_TOP);
+                a = set;
+                break;
+            }
+            default:
+                throw new RuntimeException("Invalid thumbnail transition state");
+        }
+
+        return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
+    }
+
 
     Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
-                            int appWidth, int appHeight) {
+                            int appWidth, int appHeight, Rect containingFrame, Rect contentInsets) {
         Animation a;
         if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
             a = loadAnimation(mNextAppTransitionPackage, enter ?
@@ -501,7 +658,14 @@
                 mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
             mNextAppTransitionScaleUp =
                     (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
-            a = createThumbnailAnimationLocked(transit, enter, false, appWidth, appHeight);
+            if (mUseAlternateThumbnailAnimation) {
+                a = createAlternateThumbnailEnterExitAnimationLocked(
+                        getThumbnailTransitionState(enter), appWidth, appHeight, transit,
+                        containingFrame, contentInsets);
+            } else {
+                a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
+                        appWidth, appHeight, transit);
+            }
             if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
                 String animName = mNextAppTransitionScaleUp ?
                         "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
diff --git a/services/core/java/com/android/server/wm/DisplayMagnifier.java b/services/core/java/com/android/server/wm/DisplayMagnifier.java
deleted file mode 100644
index 382d7b4..0000000
--- a/services/core/java/com/android/server/wm/DisplayMagnifier.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.wm;
-
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.app.Service;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.PixelFormat;
-import android.graphics.Point;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.Region;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.util.Pools.SimplePool;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.TypedValue;
-import android.view.IMagnificationCallbacks;
-import android.view.MagnificationSpec;
-import android.view.Surface;
-import android.view.Surface.OutOfResourcesException;
-import android.view.SurfaceControl;
-import android.view.WindowManager;
-import android.view.WindowManagerPolicy;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-
-import com.android.internal.R;
-import com.android.internal.os.SomeArgs;
-
-/**
- * This class is a part of the window manager and encapsulates the
- * functionality related to display magnification.
- */
-final class DisplayMagnifier {
-    private static final String LOG_TAG = DisplayMagnifier.class.getSimpleName();
-
-    private static final boolean DEBUG_WINDOW_TRANSITIONS = false;
-    private static final boolean DEBUG_ROTATION = false;
-    private static final boolean DEBUG_LAYERS = false;
-    private static final boolean DEBUG_RECTANGLE_REQUESTED = false;
-    private static final boolean DEBUG_VIEWPORT_WINDOW = false;
-
-    private final Rect mTempRect1 = new Rect();
-    private final Rect mTempRect2 = new Rect();
-
-    private final Region mTempRegion1 = new Region();
-    private final Region mTempRegion2 = new Region();
-    private final Region mTempRegion3 = new Region();
-    private final Region mTempRegion4 = new Region();
-
-    private final Context mContext;
-    private final WindowManagerService mWindowManagerService;
-    private final MagnifiedViewport mMagnifedViewport;
-    private final Handler mHandler;
-
-    private final IMagnificationCallbacks mCallbacks;
-
-    private final long mLongAnimationDuration;
-
-    public DisplayMagnifier(WindowManagerService windowManagerService,
-            IMagnificationCallbacks callbacks) {
-        mContext = windowManagerService.mContext;
-        mWindowManagerService = windowManagerService;
-        mCallbacks = callbacks;
-        mHandler = new MyHandler(mWindowManagerService.mH.getLooper());
-        mMagnifedViewport = new MagnifiedViewport();
-        mLongAnimationDuration = mContext.getResources().getInteger(
-                com.android.internal.R.integer.config_longAnimTime);
-    }
-
-    public void setMagnificationSpecLocked(MagnificationSpec spec) {
-        mMagnifedViewport.updateMagnificationSpecLocked(spec);
-        mMagnifedViewport.recomputeBoundsLocked();
-        mWindowManagerService.scheduleAnimationLocked();
-    }
-
-    public void onRectangleOnScreenRequestedLocked(Rect rectangle, boolean immediate) {
-        if (DEBUG_RECTANGLE_REQUESTED) {
-            Slog.i(LOG_TAG, "Rectangle on screen requested: " + rectangle);
-        }
-        if (!mMagnifedViewport.isMagnifyingLocked()) {
-            return;
-        }
-        Rect magnifiedRegionBounds = mTempRect2;
-        mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked(magnifiedRegionBounds);
-        if (magnifiedRegionBounds.contains(rectangle)) {
-            return;
-        }
-        SomeArgs args = SomeArgs.obtain();
-        args.argi1 = rectangle.left;
-        args.argi2 = rectangle.top;
-        args.argi3 = rectangle.right;
-        args.argi4 = rectangle.bottom;
-        mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED,
-                args).sendToTarget();
-    }
-
-    public void onWindowLayersChangedLocked() {
-        if (DEBUG_LAYERS) {
-            Slog.i(LOG_TAG, "Layers changed.");
-        }
-        mMagnifedViewport.recomputeBoundsLocked();
-        mWindowManagerService.scheduleAnimationLocked();
-    }
-
-    public void onRotationChangedLocked(DisplayContent displayContent, int rotation) {
-        if (DEBUG_ROTATION) {
-            Slog.i(LOG_TAG, "Rotaton: " + Surface.rotationToString(rotation)
-                    + " displayId: " + displayContent.getDisplayId());
-        }
-        mMagnifedViewport.onRotationChangedLocked();
-        mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_ROTATION_CHANGED);
-    }
-
-    public void onAppWindowTransitionLocked(WindowState windowState, int transition) {
-        if (DEBUG_WINDOW_TRANSITIONS) {
-            Slog.i(LOG_TAG, "Window transition: "
-                    + AppTransition.appTransitionToString(transition)
-                    + " displayId: " + windowState.getDisplayId());
-        }
-        final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
-        if (magnifying) {
-            switch (transition) {
-                case AppTransition.TRANSIT_ACTIVITY_OPEN:
-                case AppTransition.TRANSIT_TASK_OPEN:
-                case AppTransition.TRANSIT_TASK_TO_FRONT:
-                case AppTransition.TRANSIT_WALLPAPER_OPEN:
-                case AppTransition.TRANSIT_WALLPAPER_CLOSE:
-                case AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN: {
-                    mHandler.sendEmptyMessage(MyHandler.MESSAGE_NOTIFY_USER_CONTEXT_CHANGED);
-                }
-            }
-        }
-    }
-
-    public void onWindowTransitionLocked(WindowState windowState, int transition) {
-        if (DEBUG_WINDOW_TRANSITIONS) {
-            Slog.i(LOG_TAG, "Window transition: "
-                    + AppTransition.appTransitionToString(transition)
-                    + " displayId: " + windowState.getDisplayId());
-        }
-        final boolean magnifying = mMagnifedViewport.isMagnifyingLocked();
-        final int type = windowState.mAttrs.type;
-        switch (transition) {
-            case WindowManagerPolicy.TRANSIT_ENTER:
-            case WindowManagerPolicy.TRANSIT_SHOW: {
-                if (!magnifying) {
-                    break;
-                }
-                switch (type) {
-                    case WindowManager.LayoutParams.TYPE_APPLICATION:
-                    case WindowManager.LayoutParams.TYPE_APPLICATION_PANEL:
-                    case WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA:
-                    case WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL:
-                    case WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG:
-                    case WindowManager.LayoutParams.TYPE_SEARCH_BAR:
-                    case WindowManager.LayoutParams.TYPE_PHONE:
-                    case WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
-                    case WindowManager.LayoutParams.TYPE_TOAST:
-                    case WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY:
-                    case WindowManager.LayoutParams.TYPE_PRIORITY_PHONE:
-                    case WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG:
-                    case WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG:
-                    case WindowManager.LayoutParams.TYPE_SYSTEM_ERROR:
-                    case WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY:
-                    case WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL:
-                    case WindowManager.LayoutParams.TYPE_RECENTS_OVERLAY: {
-                        Rect magnifiedRegionBounds = mTempRect2;
-                        mMagnifedViewport.getMagnifiedFrameInContentCoordsLocked(
-                                magnifiedRegionBounds);
-                        Rect touchableRegionBounds = mTempRect1;
-                        windowState.getTouchableRegion(mTempRegion1);
-                        mTempRegion1.getBounds(touchableRegionBounds);
-                        if (!magnifiedRegionBounds.intersect(touchableRegionBounds)) {
-                            try {
-                                mCallbacks.onRectangleOnScreenRequested(
-                                        touchableRegionBounds.left,
-                                        touchableRegionBounds.top,
-                                        touchableRegionBounds.right,
-                                        touchableRegionBounds.bottom);
-                            } catch (RemoteException re) {
-                                /* ignore */
-                            }
-                        }
-                    } break;
-                } break;
-            }
-        }
-    }
-
-    public MagnificationSpec getMagnificationSpecForWindowLocked(WindowState windowState) {
-        MagnificationSpec spec = mMagnifedViewport.getMagnificationSpecLocked();
-        if (spec != null && !spec.isNop()) {
-            WindowManagerPolicy policy = mWindowManagerService.mPolicy;
-            final int windowType = windowState.mAttrs.type;
-            if (!policy.isTopLevelWindow(windowType) && windowState.mAttachedWindow != null
-                    && !policy.canMagnifyWindow(windowType)) {
-                return null;
-            }
-            if (!policy.canMagnifyWindow(windowState.mAttrs.type)) {
-                return null;
-            }
-        }
-        return spec;
-    }
-
-    public void destroyLocked() {
-        mMagnifedViewport.destroyWindow();
-    }
-
-    /** NOTE: This has to be called within a surface transaction. */
-    public void drawMagnifiedRegionBorderIfNeededLocked() {
-        mMagnifedViewport.drawWindowIfNeededLocked();
-    }
-
-    private final class MagnifiedViewport {
-
-        private static final int DEFAUTLT_BORDER_WIDTH_DIP = 5;
-
-        private final SparseArray<WindowStateInfo> mTempWindowStateInfos =
-                new SparseArray<WindowStateInfo>();
-
-        private final float[] mTempFloats = new float[9];
-
-        private final RectF mTempRectF = new RectF();
-
-        private final Point mTempPoint = new Point();
-
-        private final Matrix mTempMatrix = new Matrix();
-
-        private final Region mMagnifiedBounds = new Region();
-        private final Region mOldMagnifiedBounds = new Region();
-
-        private final MagnificationSpec mMagnificationSpec = MagnificationSpec.obtain();
-
-        private final WindowManager mWindowManager;
-
-        private final int mBorderWidth;
-        private final int mHalfBorderWidth;
-
-        private final ViewportWindow mWindow;
-
-        private boolean mFullRedrawNeeded;
-
-        public MagnifiedViewport() {
-            mWindowManager = (WindowManager) mContext.getSystemService(Service.WINDOW_SERVICE);
-            mBorderWidth = (int) TypedValue.applyDimension(
-                    TypedValue.COMPLEX_UNIT_DIP, DEFAUTLT_BORDER_WIDTH_DIP,
-                            mContext.getResources().getDisplayMetrics());
-            mHalfBorderWidth = (int) (mBorderWidth + 0.5) / 2;
-            mWindow = new ViewportWindow(mContext);
-            recomputeBoundsLocked();
-        }
-
-        public void updateMagnificationSpecLocked(MagnificationSpec spec) {
-            if (spec != null) {
-                mMagnificationSpec.initialize(spec.scale, spec.offsetX, spec.offsetY);
-            } else {
-                mMagnificationSpec.clear();
-            }
-            // If this message is pending we are in a rotation animation and do not want
-            // to show the border. We will do so when the pending message is handled.
-            if (!mHandler.hasMessages(MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED)) {
-                setMagnifiedRegionBorderShownLocked(isMagnifyingLocked(), true);
-            }
-        }
-
-        public void recomputeBoundsLocked() {
-            mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
-            final int screenWidth = mTempPoint.x;
-            final int screenHeight = mTempPoint.y;
-
-            Region magnifiedBounds = mMagnifiedBounds;
-            magnifiedBounds.set(0, 0, 0, 0);
-
-            Region availableBounds = mTempRegion1;
-            availableBounds.set(0, 0, screenWidth, screenHeight);
-
-            Region nonMagnifiedBounds = mTempRegion4;
-            nonMagnifiedBounds.set(0,  0,  0,  0);
-
-            SparseArray<WindowStateInfo> visibleWindows = mTempWindowStateInfos;
-            visibleWindows.clear();
-            getWindowsOnScreenLocked(visibleWindows);
-
-            final int visibleWindowCount = visibleWindows.size();
-            for (int i = visibleWindowCount - 1; i >= 0; i--) {
-                WindowStateInfo info = visibleWindows.valueAt(i);
-                if (info.mWindowState.mAttrs.type == WindowManager
-                        .LayoutParams.TYPE_MAGNIFICATION_OVERLAY) {
-                    continue;
-                }
-
-                Region windowBounds = mTempRegion2;
-                Matrix matrix = mTempMatrix;
-                populateTransformationMatrix(info.mWindowState, matrix);
-                RectF windowFrame = mTempRectF;
-
-                if (mWindowManagerService.mPolicy.canMagnifyWindow(info.mWindowState.mAttrs.type)) {
-                    windowFrame.set(info.mWindowState.mFrame);
-                    windowFrame.offset(-windowFrame.left, -windowFrame.top);
-                    matrix.mapRect(windowFrame);
-                    windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
-                            (int) windowFrame.right, (int) windowFrame.bottom);
-                    magnifiedBounds.op(windowBounds, Region.Op.UNION);
-                    magnifiedBounds.op(availableBounds, Region.Op.INTERSECT);
-                } else {
-                    windowFrame.set(info.mTouchableRegion);
-                    windowFrame.offset(-info.mWindowState.mFrame.left,
-                            -info.mWindowState.mFrame.top);
-                    matrix.mapRect(windowFrame);
-                    windowBounds.set((int) windowFrame.left, (int) windowFrame.top,
-                            (int) windowFrame.right, (int) windowFrame.bottom);
-                    nonMagnifiedBounds.op(windowBounds, Region.Op.UNION);
-                    windowBounds.op(magnifiedBounds, Region.Op.DIFFERENCE);
-                    availableBounds.op(windowBounds, Region.Op.DIFFERENCE);
-                }
-
-                Region accountedBounds = mTempRegion2;
-                accountedBounds.set(magnifiedBounds);
-                accountedBounds.op(nonMagnifiedBounds, Region.Op.UNION);
-                accountedBounds.op(0, 0, screenWidth, screenHeight, Region.Op.INTERSECT);
-
-                if (accountedBounds.isRect()) {
-                    Rect accountedFrame = mTempRect1;
-                    accountedBounds.getBounds(accountedFrame);
-                    if (accountedFrame.width() == screenWidth
-                            && accountedFrame.height() == screenHeight) {
-                        break;
-                    }
-                }
-            }
-
-            for (int i = visibleWindowCount - 1; i >= 0; i--) {
-                WindowStateInfo info = visibleWindows.valueAt(i);
-                info.recycle();
-                visibleWindows.removeAt(i);
-            }
-
-            magnifiedBounds.op(mHalfBorderWidth, mHalfBorderWidth,
-                    screenWidth - mHalfBorderWidth, screenHeight - mHalfBorderWidth,
-                    Region.Op.INTERSECT);
-
-            if (!mOldMagnifiedBounds.equals(magnifiedBounds)) {
-                Region bounds = Region.obtain();
-                bounds.set(magnifiedBounds);
-                mHandler.obtainMessage(MyHandler.MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED,
-                        bounds).sendToTarget();
-
-                mWindow.setBounds(magnifiedBounds);
-                Rect dirtyRect = mTempRect1;
-                if (mFullRedrawNeeded) {
-                    mFullRedrawNeeded = false;
-                    dirtyRect.set(mHalfBorderWidth, mHalfBorderWidth,
-                            screenWidth - mHalfBorderWidth, screenHeight - mHalfBorderWidth);
-                    mWindow.invalidate(dirtyRect);
-                } else {
-                    Region dirtyRegion = mTempRegion3;
-                    dirtyRegion.set(magnifiedBounds);
-                    dirtyRegion.op(mOldMagnifiedBounds, Region.Op.UNION);
-                    dirtyRegion.op(nonMagnifiedBounds, Region.Op.INTERSECT);
-                    dirtyRegion.getBounds(dirtyRect);
-                    mWindow.invalidate(dirtyRect);
-                }
-
-                mOldMagnifiedBounds.set(magnifiedBounds);
-            }
-        }
-
-        private void populateTransformationMatrix(WindowState windowState, Matrix outMatrix) {
-            mTempFloats[Matrix.MSCALE_X] = windowState.mWinAnimator.mDsDx;
-            mTempFloats[Matrix.MSKEW_Y] = windowState.mWinAnimator.mDtDx;
-            mTempFloats[Matrix.MSKEW_X] = windowState.mWinAnimator.mDsDy;
-            mTempFloats[Matrix.MSCALE_Y] = windowState.mWinAnimator.mDtDy;
-            mTempFloats[Matrix.MTRANS_X] = windowState.mShownFrame.left;
-            mTempFloats[Matrix.MTRANS_Y] = windowState.mShownFrame.top;
-            mTempFloats[Matrix.MPERSP_0] = 0;
-            mTempFloats[Matrix.MPERSP_1] = 0;
-            mTempFloats[Matrix.MPERSP_2] = 1;
-            outMatrix.setValues(mTempFloats);
-        }
-
-        private void getWindowsOnScreenLocked(SparseArray<WindowStateInfo> outWindowStates) {
-            DisplayContent displayContent = mWindowManagerService.getDefaultDisplayContentLocked();
-            WindowList windowList = displayContent.getWindowList();
-            final int windowCount = windowList.size();
-            for (int i = 0; i < windowCount; i++) {
-                WindowState windowState = windowList.get(i);
-                if ((windowState.isOnScreen() || windowState.mAttrs.type == WindowManager
-                        .LayoutParams.TYPE_UNIVERSE_BACKGROUND)
-                        && !windowState.mWinAnimator.mEnterAnimationPending) {
-                    outWindowStates.put(windowState.mLayer, WindowStateInfo.obtain(windowState));
-                }
-            }
-        }
-
-        public void onRotationChangedLocked() {
-            // If we are magnifying, hide the magnified border window immediately so
-            // the user does not see strange artifacts during rotation. The screenshot
-            // used for rotation has already the border. After the rotation is complete
-            // we will show the border.
-            if (isMagnifyingLocked()) {
-                setMagnifiedRegionBorderShownLocked(false, false);
-                final long delay = (long) (mLongAnimationDuration
-                        * mWindowManagerService.mWindowAnimationScale);
-                Message message = mHandler.obtainMessage(
-                        MyHandler.MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED);
-                mHandler.sendMessageDelayed(message, delay);
-            }
-            recomputeBoundsLocked();
-            mWindow.updateSize();
-        }
-
-        public void setMagnifiedRegionBorderShownLocked(boolean shown, boolean animate) {
-            if (shown) {
-                mFullRedrawNeeded = true;
-                mOldMagnifiedBounds.set(0,  0,  0,  0);
-            }
-            mWindow.setShown(shown, animate);
-        }
-
-        public void getMagnifiedFrameInContentCoordsLocked(Rect rect) {
-            MagnificationSpec spec = mMagnificationSpec;
-            mMagnifiedBounds.getBounds(rect);
-            rect.offset((int) -spec.offsetX, (int) -spec.offsetY);
-            rect.scale(1.0f / spec.scale);
-        }
-
-        public boolean isMagnifyingLocked() {
-            return mMagnificationSpec.scale > 1.0f;
-        }
-
-        public MagnificationSpec getMagnificationSpecLocked() {
-            return mMagnificationSpec;
-        }
-
-        /** NOTE: This has to be called within a surface transaction. */
-        public void drawWindowIfNeededLocked() {
-            recomputeBoundsLocked();
-            mWindow.drawIfNeeded();
-        }
-
-        public void destroyWindow() {
-            mWindow.releaseSurface();
-        }
-
-        private final class ViewportWindow {
-            private static final String SURFACE_TITLE = "Magnification Overlay";
-
-            private static final String PROPERTY_NAME_ALPHA = "alpha";
-
-            private static final int MIN_ALPHA = 0;
-            private static final int MAX_ALPHA = 255;
-
-            private final Region mBounds = new Region();
-            private final Rect mDirtyRect = new Rect();
-            private final Paint mPaint = new Paint();
-
-            private final ValueAnimator mShowHideFrameAnimator;
-            private final SurfaceControl mSurfaceControl;
-            private final Surface mSurface = new Surface();
-
-            private boolean mShown;
-            private int mAlpha;
-
-            private boolean mInvalidated;
-
-            public ViewportWindow(Context context) {
-                SurfaceControl surfaceControl = null;
-                try {
-                    mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
-                    surfaceControl = new SurfaceControl(mWindowManagerService.mFxSession, SURFACE_TITLE,
-                            mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-                } catch (OutOfResourcesException oore) {
-                    /* ignore */
-                }
-                mSurfaceControl = surfaceControl;
-                mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay().getLayerStack());
-                mSurfaceControl.setLayer(mWindowManagerService.mPolicy.windowTypeToLayerLw(
-                        WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY)
-                        * WindowManagerService.TYPE_LAYER_MULTIPLIER);
-                mSurfaceControl.setPosition(0, 0);
-                mSurface.copyFrom(mSurfaceControl);
-
-                TypedValue typedValue = new TypedValue();
-                context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight,
-                        typedValue, true);
-                final int borderColor = context.getResources().getColor(typedValue.resourceId);
-
-                mPaint.setStyle(Paint.Style.STROKE);
-                mPaint.setStrokeWidth(mBorderWidth);
-                mPaint.setColor(borderColor);
-
-                Interpolator interpolator = new DecelerateInterpolator(2.5f);
-                final long longAnimationDuration = context.getResources().getInteger(
-                        com.android.internal.R.integer.config_longAnimTime);
-
-                mShowHideFrameAnimator = ObjectAnimator.ofInt(this, PROPERTY_NAME_ALPHA,
-                        MIN_ALPHA, MAX_ALPHA);
-                mShowHideFrameAnimator.setInterpolator(interpolator);
-                mShowHideFrameAnimator.setDuration(longAnimationDuration);
-                mInvalidated = true;
-            }
-
-            public void setShown(boolean shown, boolean animate) {
-                synchronized (mWindowManagerService.mWindowMap) {
-                    if (mShown == shown) {
-                        return;
-                    }
-                    mShown = shown;
-                    if (animate) {
-                        if (mShowHideFrameAnimator.isRunning()) {
-                            mShowHideFrameAnimator.reverse();
-                        } else {
-                            if (shown) {
-                                mShowHideFrameAnimator.start();
-                            } else {
-                                mShowHideFrameAnimator.reverse();
-                            }
-                        }
-                    } else {
-                        mShowHideFrameAnimator.cancel();
-                        if (shown) {
-                            setAlpha(MAX_ALPHA);
-                        } else {
-                            setAlpha(MIN_ALPHA);
-                        }
-                    }
-                    if (DEBUG_VIEWPORT_WINDOW) {
-                        Slog.i(LOG_TAG, "ViewportWindow shown: " + mShown);
-                    }
-                }
-            }
-
-            @SuppressWarnings("unused")
-            // Called reflectively from an animator.
-            public int getAlpha() {
-                synchronized (mWindowManagerService.mWindowMap) {
-                    return mAlpha;
-                }
-            }
-
-            public void setAlpha(int alpha) {
-                synchronized (mWindowManagerService.mWindowMap) {
-                    if (mAlpha == alpha) {
-                        return;
-                    }
-                    mAlpha = alpha;
-                    invalidate(null);
-                    if (DEBUG_VIEWPORT_WINDOW) {
-                        Slog.i(LOG_TAG, "ViewportWindow set alpha: " + alpha);
-                    }
-                }
-            }
-
-            public void setBounds(Region bounds) {
-                synchronized (mWindowManagerService.mWindowMap) {
-                    if (mBounds.equals(bounds)) {
-                        return;
-                    }
-                    mBounds.set(bounds);
-                    invalidate(mDirtyRect);
-                    if (DEBUG_VIEWPORT_WINDOW) {
-                        Slog.i(LOG_TAG, "ViewportWindow set bounds: " + bounds);
-                    }
-                }
-            }
-
-            public void updateSize() {
-                synchronized (mWindowManagerService.mWindowMap) {
-                    mWindowManager.getDefaultDisplay().getRealSize(mTempPoint);
-                    mSurfaceControl.setSize(mTempPoint.x, mTempPoint.y);
-                    invalidate(mDirtyRect);
-                }
-            }
-
-            public void invalidate(Rect dirtyRect) {
-                if (dirtyRect != null) {
-                    mDirtyRect.set(dirtyRect);
-                } else {
-                    mDirtyRect.setEmpty();
-                }
-                mInvalidated = true;
-                mWindowManagerService.scheduleAnimationLocked();
-            }
-
-            /** NOTE: This has to be called within a surface transaction. */
-            public void drawIfNeeded() {
-                synchronized (mWindowManagerService.mWindowMap) {
-                    if (!mInvalidated) {
-                        return;
-                    }
-                    mInvalidated = false;
-                    Canvas canvas = null;
-                    try {
-                        // Empty dirty rectangle means unspecified.
-                        if (mDirtyRect.isEmpty()) {
-                            mBounds.getBounds(mDirtyRect);
-                        }
-                        mDirtyRect.inset(- mHalfBorderWidth, - mHalfBorderWidth);
-                        canvas = mSurface.lockCanvas(mDirtyRect);
-                        if (DEBUG_VIEWPORT_WINDOW) {
-                            Slog.i(LOG_TAG, "Dirty rect: " + mDirtyRect);
-                        }
-                    } catch (IllegalArgumentException iae) {
-                        /* ignore */
-                    } catch (Surface.OutOfResourcesException oore) {
-                        /* ignore */
-                    }
-                    if (canvas == null) {
-                        return;
-                    }
-                    if (DEBUG_VIEWPORT_WINDOW) {
-                        Slog.i(LOG_TAG, "Bounds: " + mBounds);
-                    }
-                    canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
-                    mPaint.setAlpha(mAlpha);
-                    Path path = mBounds.getBoundaryPath();
-                    canvas.drawPath(path, mPaint);
-
-                    mSurface.unlockCanvasAndPost(canvas);
-
-                    if (mAlpha > 0) {
-                        mSurfaceControl.show();
-                    } else {
-                        mSurfaceControl.hide();
-                    }
-                }
-            }
-
-            public void releaseSurface() {
-                mSurfaceControl.release();
-                mSurface.release();
-            }
-        }
-    }
-
-    private static final class WindowStateInfo {
-        private static final int MAX_POOL_SIZE = 30;
-
-        private static final SimplePool<WindowStateInfo> sPool =
-                new SimplePool<WindowStateInfo>(MAX_POOL_SIZE);
-
-        private static final Region mTempRegion = new Region();
-
-        public WindowState mWindowState;
-        public final Rect mTouchableRegion = new Rect();
-
-        public static WindowStateInfo obtain(WindowState windowState) {
-            WindowStateInfo info = sPool.acquire();
-            if (info == null) {
-                info = new WindowStateInfo();
-            }
-            info.mWindowState = windowState;
-            windowState.getTouchableRegion(mTempRegion);
-            mTempRegion.getBounds(info.mTouchableRegion);
-            return info;
-        }
-
-        public void recycle() {
-            mWindowState = null;
-            mTouchableRegion.setEmpty();
-            sPool.release(this);
-        }
-    }
-
-    private class MyHandler extends Handler {
-        public static final int MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED = 1;
-        public static final int MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 2;
-        public static final int MESSAGE_NOTIFY_USER_CONTEXT_CHANGED = 3;
-        public static final int MESSAGE_NOTIFY_ROTATION_CHANGED = 4;
-        public static final int MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED = 5;
-
-        public MyHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message message) {
-            switch (message.what) {
-                case MESSAGE_NOTIFY_MAGNIFIED_BOUNDS_CHANGED: {
-                    Region bounds = (Region) message.obj;
-                    try {
-                        mCallbacks.onMagnifedBoundsChanged(bounds);
-                    } catch (RemoteException re) {
-                        /* ignore */
-                    } finally {
-                        bounds.recycle();
-                    }
-                } break;
-                case MESSAGE_NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: {
-                    SomeArgs args = (SomeArgs) message.obj;
-                    final int left = args.argi1;
-                    final int top = args.argi2;
-                    final int right = args.argi3;
-                    final int bottom = args.argi4;
-                    try {
-                        mCallbacks.onRectangleOnScreenRequested(left, top, right, bottom);
-                    } catch (RemoteException re) {
-                        /* ignore */
-                    } finally {
-                        args.recycle();
-                    }
-                } break;
-                case MESSAGE_NOTIFY_USER_CONTEXT_CHANGED: {
-                    try {
-                        mCallbacks.onUserContextChanged();
-                    } catch (RemoteException re) {
-                        /* ignore */
-                    }
-                } break;
-                case MESSAGE_NOTIFY_ROTATION_CHANGED: {
-                    final int rotation = message.arg1;
-                    try {
-                        mCallbacks.onRotationChanged(rotation);
-                    } catch (RemoteException re) {
-                        /* ignore */
-                    }
-                } break;
-                case MESSAGE_SHOW_MAGNIFIED_REGION_BOUNDS_IF_NEEDED : {
-                    synchronized (mWindowManagerService.mWindowMap) {
-                        if (mMagnifedViewport.isMagnifyingLocked()) {
-                            mMagnifedViewport.setMagnifiedRegionBorderShownLocked(true, true);
-                            mWindowManagerService.scheduleAnimationLocked();
-                        }
-                    }
-                } break;
-            }
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index a737939..edc7c93 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -33,7 +33,6 @@
 import android.view.Display;
 import android.view.DragEvent;
 import android.view.InputChannel;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.WindowManager;
diff --git a/services/core/java/com/android/server/wm/FakeWindowImpl.java b/services/core/java/com/android/server/wm/FakeWindowImpl.java
index 5a3471b..c18ea01 100644
--- a/services/core/java/com/android/server/wm/FakeWindowImpl.java
+++ b/services/core/java/com/android/server/wm/FakeWindowImpl.java
@@ -21,11 +21,9 @@
 
 import android.os.Looper;
 import android.os.Process;
-import android.util.Slog;
 import android.view.Display;
 import android.view.InputChannel;
 import android.view.InputEventReceiver;
-import android.view.InputQueue;
 import android.view.WindowManagerPolicy;
 
 public final class FakeWindowImpl implements WindowManagerPolicy.FakeWindow {
diff --git a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
index 859df51..c1420a8 100644
--- a/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
+++ b/services/core/java/com/android/server/wm/KeyguardDisableHandler.java
@@ -24,7 +24,6 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.TokenWatcher;
-import android.os.UserHandle;
 import android.util.Log;
 import android.util.Pair;
 import android.view.WindowManagerPolicy;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 0c68258..266527d 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -529,8 +529,9 @@
                 mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers();
 
                 //TODO (multidisplay): Magnification is supported only for the default display.
-                if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {
-                    mService.mDisplayMagnifier.drawMagnifiedRegionBorderIfNeededLocked();
+                if (mService.mAccessibilityController != null
+                        && displayId == Display.DEFAULT_DISPLAY) {
+                    mService.mAccessibilityController.drawMagnifiedRegionBorderIfNeededLocked();
                 }
             }
 
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index da546d9..0558b5a 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -19,7 +19,6 @@
 import static android.view.WindowManager.LayoutParams.*;
 
 import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-
 import android.app.AppOpsManager;
 import android.util.ArraySet;
 import android.util.TimeUtils;
@@ -104,7 +103,6 @@
 import android.view.Gravity;
 import android.view.IApplicationToken;
 import android.view.IInputFilter;
-import android.view.IMagnificationCallbacks;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
 import android.view.IWindow;
@@ -257,9 +255,6 @@
     /** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
     static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
 
-    /** Amount of time (in milliseconds) to delay before declaring a starting window leaked. */
-    static final int STARTING_WINDOW_TIMEOUT_DURATION = 10000;
-
     /**
      * If true, the window manager will do its own custom freezing and general
      * management of the screen during rotation.
@@ -305,8 +300,16 @@
         }
     };
 
-    // Current user when multi-user is enabled. Don't show windows of non-current user.
+    /**
+     * Current user when multi-user is enabled. Don't show windows of
+     * non-current user. Also see mRelatedUserIds.
+     */
     int mCurrentUserId;
+    /**
+     * Users related to the current user. These are also allowed to show windows
+     * on the current user.
+     */
+    int[] mRelatedUserIds = new int[0];
 
     final Context mContext;
 
@@ -414,7 +417,7 @@
 
     IInputMethodManager mInputMethodManager;
 
-    DisplayMagnifier mDisplayMagnifier;
+    AccessibilityController mAccessibilityController;
 
     final SurfaceSession mFxSession;
     Watermark mWatermark;
@@ -443,10 +446,10 @@
     boolean mAltOrientation = false;
     class RotationWatcher {
         IRotationWatcher watcher;
-        IBinder.DeathRecipient dr;
+        IBinder.DeathRecipient deathRecipient;
         RotationWatcher(IRotationWatcher w, IBinder.DeathRecipient d) {
             watcher = w;
-            dr = d;
+            deathRecipient = d;
         }
     }
     ArrayList<RotationWatcher> mRotationWatchers = new ArrayList<RotationWatcher>();
@@ -2291,8 +2294,6 @@
                 token.appWindowToken.startingWindow = win;
                 if (DEBUG_STARTING_WINDOW) Slog.v (TAG, "addWindow: " + token.appWindowToken
                         + " startingWindow=" + win);
-                Message m = mH.obtainMessage(H.REMOVE_STARTING_TIMEOUT, token.appWindowToken);
-                mH.sendMessageDelayed(m, STARTING_WINDOW_TIMEOUT_DURATION);
             }
 
             boolean imMayMove = true;
@@ -2395,7 +2396,6 @@
     public void removeWindowLocked(Session session, WindowState win) {
         if (win.mAttrs.type == TYPE_APPLICATION_STARTING) {
             if (DEBUG_STARTING_WINDOW) Slog.d(TAG, "Starting window removed " + win);
-            removeStartingWindowTimeout(win.mAppToken);
         }
 
         if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win==mCurrentFocus) Slog.v(
@@ -2438,9 +2438,9 @@
                     win.mExiting = true;
                 }
                 //TODO (multidisplay): Magnification is supported only for the default display.
-                if (mDisplayMagnifier != null
+                if (mAccessibilityController != null
                         && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
-                    mDisplayMagnifier.onWindowTransitionLocked(win, transit);
+                    mAccessibilityController.onWindowTransitionLocked(win, transit);
                 }
             }
             if (win.mExiting || win.mWinAnimator.isAnimating()) {
@@ -2540,7 +2540,6 @@
         if (atoken != null) {
             if (atoken.startingWindow == win) {
                 if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Nulling startingWindow " + win);
-                removeStartingWindowTimeout(atoken);
                 atoken.startingWindow = null;
             } else if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
                 // If this is the last window and we had requested a starting
@@ -2759,11 +2758,12 @@
 
     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle, boolean immediate) {
         synchronized (mWindowMap) {
-            if (mDisplayMagnifier != null) {
+            if (mAccessibilityController != null) {
                 WindowState window = mWindowMap.get(token);
                 //TODO (multidisplay): Magnification is supported only for the default display.
                 if (window != null && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
-                    mDisplayMagnifier.onRectangleOnScreenRequestedLocked(rectangle, immediate);
+                    mAccessibilityController.onRectangleOnScreenRequestedLocked(rectangle,
+                            immediate);
                 }
             }
         }
@@ -2998,9 +2998,9 @@
                             winAnimator.destroySurfaceLocked();
                         }
                         //TODO (multidisplay): Magnification is supported only for the default
-                        if (mDisplayMagnifier != null
+                        if (mAccessibilityController != null
                                 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
-                            mDisplayMagnifier.onWindowTransitionLocked(win, transit);
+                            mAccessibilityController.onWindowTransitionLocked(win, transit);
                         }
                     }
                 }
@@ -3143,86 +3143,6 @@
         }
     }
 
-    @Override
-    public void getWindowFrame(IBinder token, Rect outBounds) {
-        if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
-                "getWindowInfo()")) {
-            throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
-        }
-        synchronized (mWindowMap) {
-            WindowState windowState = mWindowMap.get(token);
-            if (windowState != null) {
-                outBounds.set(windowState.mFrame);
-            } else {
-                outBounds.setEmpty();
-            }
-        }
-    }
-
-    @Override
-    public void setMagnificationSpec(MagnificationSpec spec) {
-        if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
-                "setMagnificationSpec()")) {
-            throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
-        }
-        synchronized (mWindowMap) {
-            if (mDisplayMagnifier != null) {
-                mDisplayMagnifier.setMagnificationSpecLocked(spec);
-            } else {
-                throw new IllegalStateException("Magnification callbacks not set!");
-            }
-        }
-        if (Binder.getCallingPid() != android.os.Process.myPid()) {
-            spec.recycle();
-        }
-    }
-
-    @Override
-    public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
-        if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
-                "getCompatibleMagnificationSpecForWindow()")) {
-            throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
-        }
-        synchronized (mWindowMap) {
-            WindowState windowState = mWindowMap.get(windowToken);
-            if (windowState == null) {
-                return null;
-            }
-            MagnificationSpec spec = null;
-            if (mDisplayMagnifier != null) {
-                spec = mDisplayMagnifier.getMagnificationSpecForWindowLocked(windowState);
-            }
-            if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
-                return null;
-            }
-            spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
-            spec.scale *= windowState.mGlobalScale;
-            return spec;
-        }
-    }
-
-    @Override
-    public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
-        if (!checkCallingPermission(android.Manifest.permission.MAGNIFY_DISPLAY,
-                "setMagnificationCallbacks()")) {
-            throw new SecurityException("Requires MAGNIFY_DISPLAY permission.");
-        }
-        synchronized (mWindowMap) {
-            if (mDisplayMagnifier == null) {
-                mDisplayMagnifier = new DisplayMagnifier(this, callbacks);
-            } else {
-                if (callbacks == null) {
-                    if (mDisplayMagnifier != null) {
-                        mDisplayMagnifier.destroyLocked();
-                        mDisplayMagnifier = null;
-                    }
-                } else {
-                    throw new IllegalStateException("Magnification callbacks already set!");
-                }
-            }
-        }
-    }
-
     private boolean applyAnimationLocked(AppWindowToken atoken,
             WindowManager.LayoutParams lp, int transit, boolean enter) {
         // Only apply an animation if the display isn't frozen.  If it is
@@ -3235,7 +3155,22 @@
             final int height = displayInfo.appHeight;
             if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken="
                     + atoken);
-            Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height);
+
+            // Determine the visible rect to calculate the thumbnail clip
+            WindowState win = atoken.findMainWindow();
+            Rect containingFrame = new Rect(0, 0, width, height);
+            Rect contentInsets = new Rect();
+            if (win != null) {
+                if (win.mContainingFrame != null) {
+                    containingFrame.set(win.mContainingFrame);
+                }
+                if (win.mContentInsets != null) {
+                    contentInsets.set(win.mContentInsets);
+                }
+            }
+
+            Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height,
+                    containingFrame, contentInsets);
             if (a != null) {
                 if (DEBUG_ANIM) {
                     RuntimeException e = null;
@@ -3402,8 +3337,8 @@
                             win.mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT,
                                     false);
                             //TODO (multidisplay): Magnification is supported only for the default
-                            if (mDisplayMagnifier != null && win.isDefaultDisplay()) {
-                                mDisplayMagnifier.onWindowTransitionLocked(win,
+                            if (mAccessibilityController != null && win.isDefaultDisplay()) {
+                                mAccessibilityController.onWindowTransitionLocked(win,
                                         WindowManagerPolicy.TRANSIT_EXIT);
                             }
                             changed = true;
@@ -3888,22 +3823,22 @@
                     + " " + mAppTransition
                     + " alwaysKeepCurrent=" + alwaysKeepCurrent
                     + " Callers=" + Debug.getCallers(3));
-            if (okToDisplay()) {
-                if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
+            if (!mAppTransition.isTransitionSet() || mAppTransition.isTransitionNone()) {
+                mAppTransition.setAppTransition(transit);
+            } else if (!alwaysKeepCurrent) {
+                if (transit == AppTransition.TRANSIT_TASK_OPEN
+                        && mAppTransition.isTransitionEqual(
+                                AppTransition.TRANSIT_TASK_CLOSE)) {
+                    // Opening a new task always supersedes a close for the anim.
                     mAppTransition.setAppTransition(transit);
-                } else if (!alwaysKeepCurrent) {
-                    if (transit == AppTransition.TRANSIT_TASK_OPEN
-                            && mAppTransition.isTransitionEqual(
-                                    AppTransition.TRANSIT_TASK_CLOSE)) {
-                        // Opening a new task always supersedes a close for the anim.
-                        mAppTransition.setAppTransition(transit);
-                    } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
-                            && mAppTransition.isTransitionEqual(
-                                AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
-                        // Opening a new activity always supersedes a close for the anim.
-                        mAppTransition.setAppTransition(transit);
-                    }
+                } else if (transit == AppTransition.TRANSIT_ACTIVITY_OPEN
+                        && mAppTransition.isTransitionEqual(
+                            AppTransition.TRANSIT_ACTIVITY_CLOSE)) {
+                    // Opening a new activity always supersedes a close for the anim.
+                    mAppTransition.setAppTransition(transit);
                 }
+            }
+            if (okToDisplay()) {
                 mAppTransition.prepare();
                 mStartingIconInTransition = false;
                 mSkipAppTransitionAnimation = false;
@@ -4035,7 +3970,6 @@
                         if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
                             Slog.v(TAG, "Removing starting window: " + startingWindow);
                         }
-                        removeStartingWindowTimeout(ttoken);
                         startingWindow.getWindowList().remove(startingWindow);
                         mWindowsChanged = true;
                         if (DEBUG_ADD_REMOVE) Slog.v(TAG,
@@ -4182,6 +4116,15 @@
         }
     }
 
+    public void removeAppStartingWindow(IBinder token) {
+        synchronized (mWindowMap) {
+            AppWindowToken wtoken = mTokenMap.get(token).appWindowToken;
+            if (wtoken.startingWindow != null) {
+                scheduleRemoveStartingWindow(wtoken);
+            }
+        }
+    }
+
     @Override
     public void setAppWillBeHidden(IBinder token) {
         if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
@@ -4251,9 +4194,9 @@
                 }
                 WindowState window = wtoken.findMainWindow();
                 //TODO (multidisplay): Magnification is supported only for the default display.
-                if (window != null && mDisplayMagnifier != null
+                if (window != null && mAccessibilityController != null
                         && window.getDisplayId() == Display.DEFAULT_DISPLAY) {
-                    mDisplayMagnifier.onAppWindowTransitionLocked(window, transit);
+                    mAccessibilityController.onAppWindowTransitionLocked(window, transit);
                 }
                 changed = true;
             }
@@ -4273,9 +4216,9 @@
                             win.mWinAnimator.applyAnimationLocked(
                                     WindowManagerPolicy.TRANSIT_ENTER, true);
                             //TODO (multidisplay): Magnification is supported only for the default
-                            if (mDisplayMagnifier != null
+                            if (mAccessibilityController != null
                                     && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
-                                mDisplayMagnifier.onWindowTransitionLocked(win,
+                                mAccessibilityController.onWindowTransitionLocked(win,
                                         WindowManagerPolicy.TRANSIT_ENTER);
                             }
                         }
@@ -4290,9 +4233,9 @@
                         win.mWinAnimator.applyAnimationLocked(
                                 WindowManagerPolicy.TRANSIT_EXIT, false);
                         //TODO (multidisplay): Magnification is supported only for the default
-                        if (mDisplayMagnifier != null
+                        if (mAccessibilityController != null
                                 && win.getDisplayId() == Display.DEFAULT_DISPLAY) {
-                            mDisplayMagnifier.onWindowTransitionLocked(win,
+                            mAccessibilityController.onWindowTransitionLocked(win,
                                     WindowManagerPolicy.TRANSIT_EXIT);
                         }
                     }
@@ -4629,21 +4572,11 @@
         scheduleRemoveStartingWindow(startingToken);
     }
 
-    void removeStartingWindowTimeout(AppWindowToken wtoken) {
-        if (wtoken != null) {
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
-                    ": Remove starting window timeout " + wtoken + (wtoken != null ?
-                    " startingWindow=" + wtoken.startingWindow : ""));
-            mH.removeMessages(H.REMOVE_STARTING_TIMEOUT, wtoken);
-        }
-    }
-
     void scheduleRemoveStartingWindow(AppWindowToken wtoken) {
         if (wtoken != null && wtoken.startingWindow != null) {
             if (DEBUG_STARTING_WINDOW) Slog.v(TAG, Debug.getCallers(1) +
                     ": Schedule remove starting " + wtoken + (wtoken != null ?
                     " startingWindow=" + wtoken.startingWindow : ""));
-            removeStartingWindowTimeout(wtoken);
             Message m = mH.obtainMessage(H.REMOVE_STARTING, wtoken);
             mH.sendMessage(m);
         }
@@ -5280,23 +5213,16 @@
         ShutdownThread.rebootSafeMode(mContext, confirm);
     }
 
-    @Override
-    public void setInputFilter(IInputFilter filter) {
-        if (!checkCallingPermission(android.Manifest.permission.FILTER_EVENTS, "setInputFilter()")) {
-            throw new SecurityException("Requires FILTER_EVENTS permission");
-        }
-        mInputManager.setInputFilter(filter);
-    }
-
-    @Override
-    public void setTouchExplorationEnabled(boolean enabled) {
-        mPolicy.setTouchExplorationEnabled(enabled);
-    }
-
-    public void setCurrentUser(final int newUserId) {
+    public void updateRelatedUserIds(final int[] relatedUserIds) {
         synchronized (mWindowMap) {
-            int oldUserId = mCurrentUserId;
+            mRelatedUserIds = relatedUserIds;
+        }
+    }
+
+    public void setCurrentUser(final int newUserId, final int[] relatedUserIds) {
+        synchronized (mWindowMap) {
             mCurrentUserId = newUserId;
+            mRelatedUserIds = relatedUserIds;
             mAppTransition.setCurrentUser(newUserId);
             mPolicy.setCurrentUserLw(newUserId);
 
@@ -5311,6 +5237,15 @@
         }
     }
 
+    /* Called by WindowState */
+    boolean isRelatedToOrCurrentUserLocked(int userId) {
+        if (userId == mCurrentUserId) return true;
+        for (int i = 0; i < mRelatedUserIds.length; i++) {
+            if (mRelatedUserIds[i] == userId) return true;
+        }
+        return false;
+    }
+
     public void enableScreenAfterBoot() {
         synchronized(mWindowMap) {
             if (DEBUG_BOOT) {
@@ -5789,7 +5724,11 @@
                                 + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
                     }
                 }
-                rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
+                // TODO: Replace 'false' in the following line with a variable that indicates
+                // whether the screenshot should use the identity transformation matrix
+                // (e.g., enable it when taking a screenshot for recents, since we might be in
+                // the middle of the rotation animation, but don't want a rotated recent image).
+                rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer, false);
             }
         } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
         if (retryCount > MAX_SCREENSHOT_RETRIES)  Slog.i(TAG, "Screenshot max retries " +
@@ -6089,9 +6028,9 @@
         }
 
         //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mDisplayMagnifier != null
+        if (mAccessibilityController != null
                 && displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
-            mDisplayMagnifier.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
+            mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
         }
 
         return true;
@@ -6117,8 +6056,9 @@
                     for (int i=0; i<mRotationWatchers.size(); i++) {
                         if (watcherBinder == mRotationWatchers.get(i).watcher.asBinder()) {
                             RotationWatcher removed = mRotationWatchers.remove(i);
-                            if (removed != null) {
-                                removed.watcher.asBinder().unlinkToDeath(this, 0);
+                            IBinder binder = removed.watcher.asBinder();
+                            if (binder != null) {
+                                binder.unlinkToDeath(this, 0);
                             }
                             i--;
                         }
@@ -6147,10 +6087,11 @@
                 RotationWatcher rotationWatcher = mRotationWatchers.get(i);
                 if (watcherBinder == rotationWatcher.watcher.asBinder()) {
                     RotationWatcher removed = mRotationWatchers.remove(i);
-                    if (removed != null) {
-                        removed.watcher.asBinder().unlinkToDeath(removed.dr, 0);
-                        i--;
+                    IBinder binder = removed.watcher.asBinder();
+                    if (binder != null) {
+                        binder.unlinkToDeath(removed.deathRecipient, 0);
                     }
+                    i--;
                 }
             }
         }
@@ -6996,21 +6937,6 @@
         }
     }
 
-    @Override
-    public IBinder getFocusedWindowToken() {
-        if (!checkCallingPermission(android.Manifest.permission.RETRIEVE_WINDOW_INFO,
-                "getFocusedWindowToken()")) {
-            throw new SecurityException("Requires RETRIEVE_WINDOW_INFO permission.");
-        }
-        synchronized (mWindowMap) {
-            WindowState windowState = getFocusedWindowLocked();
-            if (windowState != null) {
-                return windowState.mClient.asBinder();
-            }
-            return null;
-        }
-    }
-
     private WindowState getFocusedWindow() {
         synchronized (mWindowMap) {
             return getFocusedWindowLocked();
@@ -7267,7 +7193,6 @@
                                             "Aborted starting " + wtoken
                                             + ": removed=" + wtoken.removed
                                             + " startingData=" + wtoken.startingData);
-                                    removeStartingWindowTimeout(wtoken);
                                     wtoken.startingWindow = null;
                                     wtoken.startingData = null;
                                     abort = true;
@@ -7292,11 +7217,6 @@
                     }
                 } break;
 
-                case REMOVE_STARTING_TIMEOUT: {
-                    final AppWindowToken wtoken = (AppWindowToken)msg.obj;
-                    Slog.e(TAG, "Starting window " + wtoken + " timed out");
-                    // Fall through.
-                }
                 case REMOVE_STARTING: {
                     final AppWindowToken wtoken = (AppWindowToken)msg.obj;
                     IBinder token = null;
@@ -8196,9 +8116,9 @@
         }
 
         //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mDisplayMagnifier != null && anyLayerChanged
+        if (mAccessibilityController != null && anyLayerChanged
                 && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
-            mDisplayMagnifier.onWindowLayersChangedLocked();
+            mAccessibilityController.onWindowLayersChangedLocked();
         }
     }
 
@@ -8703,11 +8623,13 @@
                 wtoken.deferClearAllDrawn = false;
             }
 
+            boolean useAlternateThumbnailAnimation =
+                            SystemProperties.getBoolean("persist.anim.use_alt_thumbnail", false);
             AppWindowAnimator appAnimator =
                     topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
             Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
-            if (nextAppTransitionThumbnail != null && appAnimator != null
-                    && appAnimator.animation != null) {
+            if (!useAlternateThumbnailAnimation && nextAppTransitionThumbnail != null
+                    && appAnimator != null && appAnimator.animation != null) {
                 // This thumbnail animation is very special, we need to have
                 // an extra surface with the thumbnail included with the animation.
                 Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
@@ -8731,8 +8653,8 @@
                     drawSurface.release();
                     appAnimator.thumbnailLayer = topOpeningLayer;
                     DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
-                    Animation anim = mAppTransition.createThumbnailAnimationLocked(
-                            transit, true, true, displayInfo.appWidth, displayInfo.appHeight);
+                    Animation anim = mAppTransition.createThumbnailScaleAnimationLocked(
+                            displayInfo.appWidth, displayInfo.appHeight, transit);
                     appAnimator.thumbnailAnimation = anim;
                     anim.restrictDuration(MAX_ANIMATION_DURATION);
                     anim.scaleCurrentDuration(mTransitionAnimationScale);
@@ -9419,7 +9341,7 @@
                     mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
             for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
                 AppWindowToken token = exitingAppTokens.get(i);
-                if (!token.hasVisible && !mClosingApps.contains(token)) {
+                if (!token.hasVisible && !mClosingApps.contains(token) && !token.mDeferRemoval) {
                     // 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
@@ -9831,6 +9753,11 @@
             final WindowState oldFocus = mCurrentFocus;
             mCurrentFocus = newFocus;
             mLosingFocus.remove(newFocus);
+
+            if (mAccessibilityController != null) {
+                mAccessibilityController.onWindowFocusChangedLocked();
+            }
+
             int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
 
             if (imWindowChanged && oldFocus != mInputMethodWindow) {
@@ -10258,6 +10185,12 @@
         }
     }
 
+    public int getInputMethodWindowVisibleHeight() {
+        synchronized (mWindowMap) {
+            return mPolicy.getInputMethodWindowVisibleHeightLw();
+        }
+    }
+
     @Override
     public boolean hasNavigationBar() {
         return mPolicy.hasNavigationBar();
@@ -10950,5 +10883,100 @@
         public void requestTraversalFromDisplayManager() {
             requestTraversal();
         }
+
+        @Override
+        public void setMagnificationSpec(MagnificationSpec spec) {
+            synchronized (mWindowMap) {
+                if (mAccessibilityController != null) {
+                    mAccessibilityController.setMagnificationSpecLocked(spec);
+                } else {
+                    throw new IllegalStateException("Magnification callbacks not set!");
+                }
+            }
+            if (Binder.getCallingPid() != android.os.Process.myPid()) {
+                spec.recycle();
+            }
+        }
+
+        @Override
+        public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
+            synchronized (mWindowMap) {
+                WindowState windowState = mWindowMap.get(windowToken);
+                if (windowState == null) {
+                    return null;
+                }
+                MagnificationSpec spec = null;
+                if (mAccessibilityController != null) {
+                    spec = mAccessibilityController.getMagnificationSpecForWindowLocked(windowState);
+                }
+                if ((spec == null || spec.isNop()) && windowState.mGlobalScale == 1.0f) {
+                    return null;
+                }
+                spec = (spec == null) ? MagnificationSpec.obtain() : MagnificationSpec.obtain(spec);
+                spec.scale *= windowState.mGlobalScale;
+                return spec;
+            }
+        }
+
+        @Override
+        public void setMagnificationCallbacks(MagnificationCallbacks callbacks) {
+            synchronized (mWindowMap) {
+                if (mAccessibilityController == null) {
+                    mAccessibilityController = new AccessibilityController(
+                            WindowManagerService.this);
+                }
+                mAccessibilityController.setMagnificationCallbacksLocked(callbacks);
+                if (!mAccessibilityController.hasCallbacksLocked()) {
+                     mAccessibilityController = null;
+                }
+            }
+        }
+
+        @Override
+        public void setWindowsForAccessibilityCallback(WindowsForAccessibilityCallback callback) {
+            synchronized (mWindowMap) {
+                if (mAccessibilityController == null) {
+                    mAccessibilityController = new AccessibilityController(
+                            WindowManagerService.this);
+                }
+                mAccessibilityController.setWindowsForAccessibilityCallback(callback);
+                if (!mAccessibilityController.hasCallbacksLocked()) {
+                     mAccessibilityController = null;
+                }
+            }
+        }
+
+        @Override
+        public void setInputFilter(IInputFilter filter) {
+            mInputManager.setInputFilter(filter);
+        }
+
+        @Override
+        public IBinder getFocusedWindowToken() {
+            synchronized (mWindowMap) {
+                WindowState windowState = getFocusedWindowLocked();
+                if (windowState != null) {
+                    return windowState.mClient.asBinder();
+                }
+                return null;
+            }
+        }
+
+        @Override
+        public boolean isKeyguardLocked() {
+            return isKeyguardLocked();
+        }
+
+        @Override
+        public void getWindowFrame(IBinder token, Rect outBounds) {
+            synchronized (mWindowMap) {
+                WindowState windowState = mWindowMap.get(token);
+                if (windowState != null) {
+                    outBounds.set(windowState.mFrame);
+                } else {
+                    outBounds.setEmpty();
+                }
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 9f3415e..2c0e99e 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -375,17 +375,19 @@
                 mAttachedWindow.mChildWindows.add(this);
             } else {
                 for (int i = 0; i < children_size; i++) {
-                    WindowState child = mAttachedWindow.mChildWindows.get(i);
-                    if (mSubLayer < child.mSubLayer) {
+                    WindowState child = (WindowState)mAttachedWindow.mChildWindows.get(i);
+                    if (this.mSubLayer < child.mSubLayer) {
                         mAttachedWindow.mChildWindows.add(i, this);
                         break;
-                    } else if (mSubLayer > child.mSubLayer) {
+                    } else if (this.mSubLayer > child.mSubLayer) {
                         continue;
                     }
 
-                    if (mBaseLayer <= child.mBaseLayer) {
+                    if (this.mBaseLayer <= child.mBaseLayer) {
                         mAttachedWindow.mChildWindows.add(i, this);
                         break;
+                    } else {
+                        continue;
                     }
                 }
                 if (children_size == mAttachedWindow.mChildWindows.size()) {
@@ -1247,7 +1249,7 @@
         }
 
         return win.mShowToOwnerOnly
-                && UserHandle.getUserId(win.mOwnerUid) != mService.mCurrentUserId;
+                && !mService.isRelatedToOrCurrentUserLocked(UserHandle.getUserId(win.mOwnerUid));
     }
 
     private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 93f6d22..6b3c368 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -113,6 +113,11 @@
     float mAlpha = 0;
     float mLastAlpha = 0;
 
+    boolean mHasClipRect;
+    Rect mClipRect = new Rect();
+    Rect mTmpClipRect = new Rect();
+    Rect mLastClipRect = new Rect();
+
     // Used to save animation distances between the time they are calculated and when they are
     // used.
     int mAnimDw;
@@ -951,9 +956,10 @@
             if (screenAnimation) {
                 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
             }
+
             //TODO (multidisplay): Magnification is supported only for the default display.
-            if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {
-                MagnificationSpec spec = mService.mDisplayMagnifier
+            if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
+                MagnificationSpec spec = mService.mAccessibilityController
                         .getMagnificationSpecForWindowLocked(mWin);
                 if (spec != null && !spec.isNop()) {
                     tmpMatrix.postScale(spec.scale, spec.scale);
@@ -985,6 +991,7 @@
             // transforming since it is more important to have that
             // animation be smooth.
             mShownAlpha = mAlpha;
+            mHasClipRect = false;
             if (!mService.mLimitedAlphaCompositing
                     || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
                     || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
@@ -998,6 +1005,10 @@
                 }
                 if (appTransformation != null) {
                     mShownAlpha *= appTransformation.getAlpha();
+                    if (appTransformation.hasClipRect()) {
+                        mClipRect.set(appTransformation.getClipRect());
+                        mHasClipRect = true;
+                    }
                 }
                 if (mAnimator.mUniverseBackground != null) {
                     mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
@@ -1032,8 +1043,8 @@
                 && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer);
         MagnificationSpec spec = null;
         //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) {
-            spec = mService.mDisplayMagnifier.getMagnificationSpecForWindowLocked(mWin);
+        if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
+            spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
         }
         if (applyUniverseTransformation || spec != null) {
             final Rect frame = mWin.mFrame;
@@ -1149,15 +1160,32 @@
             applyDecorRect(w.mDecorFrame);
         }
 
-        if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
-            w.mLastSystemDecorRect.set(w.mSystemDecorRect);
+        // By default, the clip rect is the system decor rect
+        Rect clipRect = w.mSystemDecorRect;
+        if (mHasClipRect) {
+
+            // If we have an animated clip rect, intersect it with the system decor rect
+            // NOTE: We are adding a temporary workaround due to the status bar not always reporting
+            // the correct system decor rect.  In such cases, we take into account the specified
+            // content insets as well.
+            int offsetTop = Math.max(w.mSystemDecorRect.top, w.mContentInsets.top);
+            mTmpClipRect.set(w.mSystemDecorRect);
+            mTmpClipRect.offset(0, -offsetTop);
+            mTmpClipRect.intersect(mClipRect);
+            mTmpClipRect.offset(0, offsetTop);
+            clipRect = mTmpClipRect;
+
+        }
+
+        if (!clipRect.equals(mLastClipRect)) {
+            mLastClipRect.set(clipRect);
             try {
                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
-                        "CROP " + w.mSystemDecorRect.toShortString(), null);
-                mSurfaceControl.setWindowCrop(w.mSystemDecorRect);
+                        "CROP " + clipRect.toShortString(), null);
+                mSurfaceControl.setWindowCrop(clipRect);
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Error setting crop surface of " + w
-                        + " crop=" + w.mSystemDecorRect.toShortString(), e);
+                        + " crop=" + clipRect.toShortString(), e);
                 if (!recoveringMemory) {
                     mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
                 }
@@ -1302,8 +1330,8 @@
                     mSurfaceLayer = mAnimLayer;
                     mSurfaceControl.setLayer(mAnimLayer);
                     mSurfaceControl.setMatrix(
-                        mDsDx*w.mHScale, mDtDx*w.mVScale,
-                        mDsDy*w.mHScale, mDtDy*w.mVScale);
+                            mDsDx * w.mHScale, mDtDx * w.mVScale,
+                            mDsDy * w.mHScale, mDtDy * w.mVScale);
 
                     if (mLastHidden && mDrawState == HAS_DRAWN) {
                         if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
@@ -1565,9 +1593,9 @@
         }
         applyAnimationLocked(transit, true);
         //TODO (multidisplay): Magnification is supported only for the default display.
-        if (mService.mDisplayMagnifier != null
+        if (mService.mAccessibilityController != null
                 && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
-            mService.mDisplayMagnifier.onWindowTransitionLocked(mWin, transit);
+            mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
         }
     }
 
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 0843e94..1b3887c 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -2,8 +2,11 @@
 # files
 LOCAL_REL_DIR := core/jni
 
+LOCAL_CFLAGS += -Wno-unused-parameter
+
 LOCAL_SRC_FILES += \
     $(LOCAL_REL_DIR)/com_android_server_AlarmManagerService.cpp \
+    $(LOCAL_REL_DIR)/com_android_server_am_BatteryStatsService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_AssetAtlasService.cpp \
     $(LOCAL_REL_DIR)/com_android_server_connectivity_Vpn.cpp \
     $(LOCAL_REL_DIR)/com_android_server_ConsumerIrService.cpp \
@@ -31,7 +34,6 @@
     frameworks/base/libs \
     frameworks/base/core/jni \
     frameworks/native/services \
-    external/skia/include/core \
     libcore/include \
     libcore/include/libsuspend \
 	$(call include-path-for, libhardware)/hardware \
@@ -49,6 +51,7 @@
     libutils \
     libui \
     libinput \
+    libinputflinger \
     libinputservice \
     libsensorservice \
     libskia \
diff --git a/services/core/jni/com_android_server_UsbHostManager.cpp b/services/core/jni/com_android_server_UsbHostManager.cpp
index fc6de60..bc866d3 100644
--- a/services/core/jni/com_android_server_UsbHostManager.cpp
+++ b/services/core/jni/com_android_server_UsbHostManager.cpp
@@ -41,7 +41,11 @@
     jmethodID mConstructor;
 } gParcelFileDescriptorOffsets;
 
-static jmethodID method_usbDeviceAdded;
+static jmethodID method_beginUsbDeviceAdded;
+static jmethodID method_addUsbConfiguration;
+static jmethodID method_addUsbInterface;
+static jmethodID method_addUsbEndpoint;
+static jmethodID method_endUsbDeviceAdded;
 static jmethodID method_usbDeviceRemoved;
 
 static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
@@ -68,64 +72,69 @@
     Vector<int> endpointValues;
     const usb_device_descriptor* deviceDesc = usb_device_get_device_descriptor(device);
 
-    uint16_t vendorId = usb_device_get_vendor_id(device);
-    uint16_t productId = usb_device_get_product_id(device);
-    uint8_t deviceClass = deviceDesc->bDeviceClass;
-    uint8_t deviceSubClass = deviceDesc->bDeviceSubClass;
-    uint8_t protocol = deviceDesc->bDeviceProtocol;
     char *manufacturer = usb_device_get_manufacturer_name(device);
     char *product = usb_device_get_product_name(device);
     char *serial = usb_device_get_serial(device);
 
-    usb_descriptor_iter_init(device, &iter);
-
-    while ((desc = usb_descriptor_iter_next(&iter)) != NULL) {
-        if (desc->bDescriptorType == USB_DT_INTERFACE) {
-            struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc;
-
-            // push class, subclass, protocol and number of endpoints into interfaceValues vector
-            interfaceValues.add(interface->bInterfaceNumber);
-            interfaceValues.add(interface->bInterfaceClass);
-            interfaceValues.add(interface->bInterfaceSubClass);
-            interfaceValues.add(interface->bInterfaceProtocol);
-            interfaceValues.add(interface->bNumEndpoints);
-        } else if (desc->bDescriptorType == USB_DT_ENDPOINT) {
-            struct usb_endpoint_descriptor *endpoint = (struct usb_endpoint_descriptor *)desc;
-
-            // push address, attributes, max packet size and interval into endpointValues vector
-            endpointValues.add(endpoint->bEndpointAddress);
-            endpointValues.add(endpoint->bmAttributes);
-            endpointValues.add(__le16_to_cpu(endpoint->wMaxPacketSize));
-            endpointValues.add(endpoint->bInterval);
-        }
-    }
-
-    usb_device_close(device);
-
-    // handle generic device notification
-    int length = interfaceValues.size();
-    jintArray interfaceArray = env->NewIntArray(length);
-    env->SetIntArrayRegion(interfaceArray, 0, length, interfaceValues.array());
-
-    length = endpointValues.size();
-    jintArray endpointArray = env->NewIntArray(length);
-    env->SetIntArrayRegion(endpointArray, 0, length, endpointValues.array());
-
     jstring deviceName = env->NewStringUTF(devname);
     jstring manufacturerName = env->NewStringUTF(manufacturer);
     jstring productName = env->NewStringUTF(product);
     jstring serialNumber = env->NewStringUTF(serial);
-    env->CallVoidMethod(thiz, method_usbDeviceAdded,
-            deviceName, vendorId, productId, deviceClass,
-            deviceSubClass, protocol, manufacturerName,
-            productName, serialNumber, interfaceArray, endpointArray);
 
-    env->DeleteLocalRef(interfaceArray);
-    env->DeleteLocalRef(endpointArray);
+    jboolean result = env->CallBooleanMethod(thiz, method_beginUsbDeviceAdded,
+            deviceName, usb_device_get_vendor_id(device), usb_device_get_product_id(device),
+            deviceDesc->bDeviceClass, deviceDesc->bDeviceSubClass, deviceDesc->bDeviceProtocol,
+            manufacturerName, productName, serialNumber);
+
     env->DeleteLocalRef(serialNumber);
     env->DeleteLocalRef(productName);
     env->DeleteLocalRef(manufacturerName);
     env->DeleteLocalRef(deviceName);
+    free(manufacturer);
+    free(product);
+    free(serial);
+
+    if (!result) goto fail;
+
+    usb_descriptor_iter_init(device, &iter);
+
+    while ((desc = usb_descriptor_iter_next(&iter)) != NULL) {
+        if (desc->bDescriptorType == USB_DT_CONFIG) {
+            struct usb_config_descriptor *config = (struct usb_config_descriptor *)desc;
+            char *name = usb_device_get_string(device, config->iConfiguration);
+            jstring configName = env->NewStringUTF(name);
+
+            env->CallVoidMethod(thiz, method_addUsbConfiguration,
+                    config->bConfigurationValue, configName, config->bmAttributes,
+                    config->bMaxPower);
+
+            env->DeleteLocalRef(configName);
+            free(name);
+        } else if (desc->bDescriptorType == USB_DT_INTERFACE) {
+            struct usb_interface_descriptor *interface = (struct usb_interface_descriptor *)desc;
+            char *name = usb_device_get_string(device, interface->iInterface);
+            jstring interfaceName = env->NewStringUTF(name);
+
+            env->CallVoidMethod(thiz, method_addUsbInterface,
+                    interface->bInterfaceNumber, interfaceName, interface->bAlternateSetting,
+                    interface->bInterfaceClass, interface->bInterfaceSubClass,
+                    interface->bInterfaceProtocol);
+
+            env->DeleteLocalRef(interfaceName);
+            free(name);
+        } else if (desc->bDescriptorType == USB_DT_ENDPOINT) {
+            struct usb_endpoint_descriptor *endpoint = (struct usb_endpoint_descriptor *)desc;
+
+            env->CallVoidMethod(thiz, method_addUsbEndpoint,
+                    endpoint->bEndpointAddress, endpoint->bmAttributes,
+                    __le16_to_cpu(endpoint->wMaxPacketSize), endpoint->bInterval);
+        }
+    }
+
+    env->CallVoidMethod(thiz, method_endUsbDeviceAdded);
+
+fail:
+    usb_device_close(device);
     checkAndClearExceptionFromCallback(env, __FUNCTION__);
 
     return 0;
@@ -191,12 +200,36 @@
         ALOGE("Can't find com/android/server/usb/UsbHostManager");
         return -1;
     }
-    method_usbDeviceAdded = env->GetMethodID(clazz, "usbDeviceAdded", "(Ljava/lang/String;IIIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;[I[I)V");
-    if (method_usbDeviceAdded == NULL) {
-        ALOGE("Can't find usbDeviceAdded");
+    method_beginUsbDeviceAdded = env->GetMethodID(clazz, "beginUsbDeviceAdded",
+            "(Ljava/lang/String;IIIIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
+    if (method_beginUsbDeviceAdded == NULL) {
+        ALOGE("Can't find beginUsbDeviceAdded");
         return -1;
     }
-    method_usbDeviceRemoved = env->GetMethodID(clazz, "usbDeviceRemoved", "(Ljava/lang/String;)V");
+    method_addUsbConfiguration = env->GetMethodID(clazz, "addUsbConfiguration",
+            "(ILjava/lang/String;II)V");
+    if (method_addUsbConfiguration == NULL) {
+        ALOGE("Can't find addUsbConfiguration");
+        return -1;
+    }
+    method_addUsbInterface = env->GetMethodID(clazz, "addUsbInterface",
+            "(ILjava/lang/String;IIII)V");
+    if (method_addUsbInterface == NULL) {
+        ALOGE("Can't find addUsbInterface");
+        return -1;
+    }
+    method_addUsbEndpoint = env->GetMethodID(clazz, "addUsbEndpoint", "(IIII)V");
+    if (method_addUsbEndpoint == NULL) {
+        ALOGE("Can't find addUsbEndpoint");
+        return -1;
+    }
+    method_endUsbDeviceAdded = env->GetMethodID(clazz, "endUsbDeviceAdded", "()V");
+    if (method_endUsbDeviceAdded == NULL) {
+        ALOGE("Can't find endUsbDeviceAdded");
+        return -1;
+    }
+    method_usbDeviceRemoved = env->GetMethodID(clazz, "usbDeviceRemoved",
+            "(Ljava/lang/String;)V");
     if (method_usbDeviceRemoved == NULL) {
         ALOGE("Can't find usbDeviceRemoved");
         return -1;
@@ -205,7 +238,8 @@
     clazz = env->FindClass("android/os/ParcelFileDescriptor");
     LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
     gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
-    gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
+    gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>",
+            "(Ljava/io/FileDescriptor;)V");
     LOG_FATAL_IF(gParcelFileDescriptorOffsets.mConstructor == NULL,
                  "Unable to find constructor for android.os.ParcelFileDescriptor");
 
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
new file mode 100644
index 0000000..da4cc48
--- /dev/null
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BatteryStatsService"
+//#define LOG_NDEBUG 0
+
+#include <android_runtime/AndroidRuntime.h>
+#include <jni.h>
+
+#include <ScopedLocalRef.h>
+#include <ScopedPrimitiveArray.h>
+
+#include <cutils/log.h>
+#include <utils/misc.h>
+#include <utils/Log.h>
+#include <hardware/hardware.h>
+#include <suspend/autosuspend.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+namespace android
+{
+
+#define LAST_RESUME_REASON "/sys/kernel/wakeup_reasons/last_resume_reason"
+#define MAX_REASON_SIZE 512
+
+static bool wakeup_init = false;
+static sem_t wakeup_sem;
+
+static void wakeup_callback(void)
+{
+    ALOGV("In wakeup_callback");
+    int ret = sem_post(&wakeup_sem);
+    if (ret < 0) {
+        char buf[80];
+        strerror_r(errno, buf, sizeof(buf));
+        ALOGE("Error posting wakeup sem: %s\n", buf);
+    }
+}
+
+static jint nativeWaitWakeup(JNIEnv *env, jobject clazz, jintArray outIrqs,
+        jobjectArray outReasons)
+{
+    bool first_time = false;
+
+    if (outIrqs == NULL || outReasons == NULL) {
+        jniThrowException(env, "java/lang/NullPointerException", "null argument");
+        return -1;
+    }
+
+    // Register our wakeup callback if not yet done.
+    if (!wakeup_init) {
+        wakeup_init = true;
+        ALOGV("Creating semaphore...");
+        int ret = sem_init(&wakeup_sem, 0, 0);
+        if (ret < 0) {
+            char buf[80];
+            strerror_r(errno, buf, sizeof(buf));
+            ALOGE("Error creating semaphore: %s\n", buf);
+            jniThrowException(env, "java/lang/IllegalStateException", buf);
+            return -1;
+        }
+        ALOGV("Registering callback...");
+        set_wakeup_callback(&wakeup_callback);
+        // First time through, we will just drain the current wakeup reasons.
+        first_time = true;
+    } else {
+        // On following calls, we need to wait for wakeup.
+        ALOGV("Waiting for wakeup...");
+        int ret = sem_wait(&wakeup_sem);
+        if (ret < 0) {
+            char buf[80];
+            strerror_r(errno, buf, sizeof(buf));
+            ALOGE("Error waiting on semaphore: %s\n", buf);
+            // Return 0 here to let it continue looping but not return results.
+            return 0;
+        }
+    }
+
+    FILE *fp = fopen(LAST_RESUME_REASON, "r");
+    if (fp == NULL) {
+        ALOGE("Failed to open %s", LAST_RESUME_REASON);
+        return -1;
+    }
+
+    int numOut = env->GetArrayLength(outIrqs);
+    ScopedIntArrayRW irqs(env, outIrqs);
+
+    ALOGV("Reading up to %d wakeup reasons", numOut);
+
+    char mergedreason[MAX_REASON_SIZE];
+    char* mergedreasonpos = mergedreason;
+    int remainreasonlen = MAX_REASON_SIZE;
+    int firstirq = 0;
+    char reasonline[128];
+    int i = 0;
+    while (fgets(reasonline, sizeof(reasonline), fp) != NULL && i < numOut) {
+        char* pos = reasonline;
+        char* endPos;
+        // First field is the index.
+        int irq = (int)strtol(pos, &endPos, 10);
+        if (pos == endPos) {
+            // Ooops.
+            ALOGE("Bad reason line: %s", reasonline);
+            continue;
+        }
+        pos = endPos;
+        // Skip whitespace; rest of the buffer is the reason string.
+        while (*pos == ' ') {
+            pos++;
+        }
+        // Chop newline at end.
+        char* endpos = pos;
+        while (*endpos != 0) {
+            if (*endpos == '\n') {
+                *endpos = 0;
+                break;
+            }
+            endpos++;
+        }
+        // For now we are not separating out the first irq.
+        // This is because in practice there are always multiple
+        // lines of wakeup reasons, so it is better to just treat
+        // them all together as a single string.
+        if (false && i == 0) {
+            firstirq = irq;
+        } else {
+            int len = snprintf(mergedreasonpos, remainreasonlen,
+                    i == 0 ? "%d" : ":%d", irq);
+            if (len >= 0 && len < remainreasonlen) {
+                mergedreasonpos += len;
+                remainreasonlen -= len;
+            }
+        }
+        int len = snprintf(mergedreasonpos, remainreasonlen, ":%s", pos);
+        if (len >= 0 && len < remainreasonlen) {
+            mergedreasonpos += len;
+            remainreasonlen -= len;
+        }
+        // For now it is better to combine all of these in to one entry in the
+        // battery history.  In the future, it might be nice to figure out a way
+        // to efficiently store multiple lines as a single entry in the history.
+        //irqs[i] = irq;
+        //ScopedLocalRef<jstring> reasonString(env, env->NewStringUTF(pos));
+        //env->SetObjectArrayElement(outReasons, i, reasonString.get());
+        //ALOGV("Wakeup reason #%d: irw %d reason %s", i, irq, pos);
+        i++;
+    }
+
+    ALOGV("Got %d reasons", i);
+    if (first_time) {
+        i = 0;
+    }
+    if (i > 0) {
+        irqs[0] = firstirq;
+        *mergedreasonpos = 0;
+        ScopedLocalRef<jstring> reasonString(env, env->NewStringUTF(mergedreason));
+        env->SetObjectArrayElement(outReasons, 0, reasonString.get());
+        i = 1;
+    }
+
+    if (fclose(fp) != 0) {
+        ALOGE("Failed to close %s", LAST_RESUME_REASON);
+        return -1;
+    }
+
+    return first_time ? 0 : i;
+}
+
+static JNINativeMethod method_table[] = {
+    { "nativeWaitWakeup", "([I[Ljava/lang/String;)I", (void*)nativeWaitWakeup },
+};
+
+int register_android_server_BatteryStatsService(JNIEnv *env)
+{
+    return jniRegisterNativeMethods(env, "com/android/server/am/BatteryStatsService",
+            method_table, NELEM(method_table));
+}
+
+};
diff --git a/services/core/jni/com_android_server_input_InputApplicationHandle.h b/services/core/jni/com_android_server_input_InputApplicationHandle.h
index 89d48c6..62c8570 100644
--- a/services/core/jni/com_android_server_input_InputApplicationHandle.h
+++ b/services/core/jni/com_android_server_input_InputApplicationHandle.h
@@ -17,7 +17,7 @@
 #ifndef _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
 #define _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
 
-#include <input/InputApplication.h>
+#include <inputflinger/InputApplication.h>
 
 #include "JNIHelp.h"
 #include "jni.h"
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 3fccf53..e1069ae 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -35,10 +35,11 @@
 #include <utils/Looper.h>
 #include <utils/threads.h>
 
-#include <input/InputManager.h>
 #include <input/PointerController.h>
 #include <input/SpriteController.h>
 
+#include <inputflinger/InputManager.h>
+
 #include <android_os_MessageQueue.h>
 #include <android_view_InputDevice.h>
 #include <android_view_KeyEvent.h>
@@ -48,6 +49,7 @@
 #include <android/graphics/GraphicsJNI.h>
 
 #include <ScopedLocalRef.h>
+#include <ScopedPrimitiveArray.h>
 #include <ScopedUtfChars.h>
 
 #include "com_android_server_power_PowerManagerService.h"
@@ -85,6 +87,7 @@
     jmethodID getPointerIcon;
     jmethodID getKeyboardLayoutOverlay;
     jmethodID getDeviceAlias;
+    jmethodID getTouchCalibrationForInputDevice;
 } gServiceClassInfo;
 
 static struct {
@@ -104,6 +107,11 @@
     jmethodID constructor;
 } gInputDeviceIdentifierInfo;
 
+static struct {
+    jclass clazz;
+    jmethodID getAffineTransform;
+} gTouchCalibrationClassInfo;
+
 
 
 // --- Global functions ---
@@ -181,6 +189,7 @@
     void setSystemUiVisibility(int32_t visibility);
     void setPointerSpeed(int32_t speed);
     void setShowTouches(bool enabled);
+    void reloadCalibration();
 
     /* --- InputReaderPolicyInterface implementation --- */
 
@@ -189,6 +198,10 @@
     virtual void notifyInputDevicesChanged(const Vector<InputDeviceInfo>& inputDevices);
     virtual sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier);
     virtual String8 getDeviceAlias(const InputDeviceIdentifier& identifier);
+    virtual TouchAffineTransformation getTouchAffineTransformation(JNIEnv *env,
+            jfloatArray matrixArr);
+    virtual TouchAffineTransformation getTouchAffineTransformation(
+            const String8& inputDeviceDescriptor, int32_t surfaceRotation);
 
     /* --- InputDispatcherPolicyInterface implementation --- */
 
@@ -740,6 +753,11 @@
             InputReaderConfiguration::CHANGE_SHOW_TOUCHES);
 }
 
+void NativeInputManager::reloadCalibration() {
+    mInputManager->getReader()->requestRefreshConfiguration(
+            InputReaderConfiguration::TOUCH_AFFINE_TRANSFORMATION);
+}
+
 bool NativeInputManager::isScreenOn() {
     return android_server_PowerManagerService_isScreenOn();
 }
@@ -748,6 +766,43 @@
     return android_server_PowerManagerService_isScreenBright();
 }
 
+TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
+        JNIEnv *env, jfloatArray matrixArr) {
+    ScopedFloatArrayRO matrix(env, matrixArr);
+    assert(matrix.size() == 6);
+
+    TouchAffineTransformation transform;
+    transform.x_scale  = matrix[0];
+    transform.x_ymix   = matrix[1];
+    transform.x_offset = matrix[2];
+    transform.y_xmix   = matrix[3];
+    transform.y_scale  = matrix[4];
+    transform.y_offset = matrix[5];
+
+    return transform;
+}
+
+TouchAffineTransformation NativeInputManager::getTouchAffineTransformation(
+        const String8& inputDeviceDescriptor, int32_t surfaceRotation) {
+    JNIEnv* env = jniEnv();
+
+    ScopedLocalRef<jstring> descriptorObj(env, env->NewStringUTF(inputDeviceDescriptor.string()));
+
+    jobject cal = env->CallObjectMethod(mServiceObj,
+            gServiceClassInfo.getTouchCalibrationForInputDevice, descriptorObj.get(),
+            surfaceRotation);
+
+    jfloatArray matrixArr = jfloatArray(env->CallObjectMethod(cal,
+            gTouchCalibrationClassInfo.getAffineTransform));
+
+    TouchAffineTransformation transform = getTouchAffineTransformation(env, matrixArr);
+
+    env->DeleteLocalRef(matrixArr);
+    env->DeleteLocalRef(cal);
+
+    return transform;
+}
+
 bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
     jobject inputEventObj;
 
@@ -1230,6 +1285,11 @@
     im->setShowTouches(enabled);
 }
 
+static void nativeReloadCalibration(JNIEnv* env, jclass clazz, jlong ptr) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+    im->reloadCalibration();
+}
+
 static void nativeVibrate(JNIEnv* env,
         jclass clazz, jlong ptr, jint deviceId, jlongArray patternObj,
         jint repeat, jint token) {
@@ -1335,6 +1395,8 @@
             (void*) nativeSetPointerSpeed },
     { "nativeSetShowTouches", "(JZ)V",
             (void*) nativeSetShowTouches },
+    { "nativeReloadCalibration", "(J)V",
+            (void*) nativeReloadCalibration },
     { "nativeVibrate", "(JI[JII)V",
             (void*) nativeVibrate },
     { "nativeCancelVibrate", "(JII)V",
@@ -1445,6 +1507,10 @@
     GET_METHOD_ID(gServiceClassInfo.getDeviceAlias, clazz,
             "getDeviceAlias", "(Ljava/lang/String;)Ljava/lang/String;");
 
+    GET_METHOD_ID(gServiceClassInfo.getTouchCalibrationForInputDevice, clazz,
+            "getTouchCalibrationForInputDevice",
+            "(Ljava/lang/String;I)Landroid/hardware/input/TouchCalibration;");
+
     // InputDevice
 
     FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
@@ -1467,6 +1533,14 @@
     GET_METHOD_ID(gInputDeviceIdentifierInfo.constructor, gInputDeviceIdentifierInfo.clazz,
             "<init>", "(Ljava/lang/String;II)V");
 
+    // TouchCalibration
+
+    FIND_CLASS(gTouchCalibrationClassInfo.clazz, "android/hardware/input/TouchCalibration");
+    gTouchCalibrationClassInfo.clazz = jclass(env->NewGlobalRef(gTouchCalibrationClassInfo.clazz));
+
+    GET_METHOD_ID(gTouchCalibrationClassInfo.getAffineTransform, gTouchCalibrationClassInfo.clazz,
+            "getAffineTransform", "()[F");
+
     return 0;
 }
 
diff --git a/services/core/jni/com_android_server_input_InputWindowHandle.cpp b/services/core/jni/com_android_server_input_InputWindowHandle.cpp
index b80183c..03bf7eb 100644
--- a/services/core/jni/com_android_server_input_InputWindowHandle.cpp
+++ b/services/core/jni/com_android_server_input_InputWindowHandle.cpp
@@ -23,6 +23,7 @@
 
 #include <android_view_InputChannel.h>
 #include <android/graphics/Region.h>
+#include <ui/Region.h>
 
 #include "com_android_server_input_InputWindowHandle.h"
 #include "com_android_server_input_InputApplicationHandle.h"
@@ -86,6 +87,8 @@
 
     if (!mInfo) {
         mInfo = new InputWindowInfo();
+    } else {
+        mInfo->touchableRegion.clear();
     }
 
     jobject inputChannelObj = env->GetObjectField(obj,
@@ -131,10 +134,11 @@
             gInputWindowHandleClassInfo.touchableRegion);
     if (regionObj) {
         SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
-        mInfo->touchableRegion.set(*region);
+        for (SkRegion::Iterator it(*region); !it.done(); it.next()) {
+            const SkIRect& rect = it.rect();
+            mInfo->addTouchableRegion(Rect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom));
+        }
         env->DeleteLocalRef(regionObj);
-    } else {
-        mInfo->touchableRegion.setEmpty();
     }
 
     mInfo->visible = env->GetBooleanField(obj,
diff --git a/services/core/jni/com_android_server_input_InputWindowHandle.h b/services/core/jni/com_android_server_input_InputWindowHandle.h
index 2cfa17d3..8d9e7d7 100644
--- a/services/core/jni/com_android_server_input_InputWindowHandle.h
+++ b/services/core/jni/com_android_server_input_InputWindowHandle.h
@@ -17,7 +17,7 @@
 #ifndef _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
 #define _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
 
-#include <input/InputWindow.h>
+#include <inputflinger/InputWindow.h>
 
 #include "JNIHelp.h"
 #include "jni.h"
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.h b/services/core/jni/com_android_server_power_PowerManagerService.h
index 0808b80..b48e546 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.h
+++ b/services/core/jni/com_android_server_power_PowerManagerService.h
@@ -20,7 +20,7 @@
 #include "JNIHelp.h"
 #include "jni.h"
 
-#include <androidfw/PowerManager.h>
+#include <powermanager/PowerManager.h>
 
 namespace android {
 
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 904966a..bf9f7f4 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -22,6 +22,7 @@
 namespace android {
 int register_android_server_AlarmManagerService(JNIEnv* env);
 int register_android_server_AssetAtlasService(JNIEnv* env);
+int register_android_server_BatteryStatsService(JNIEnv* env);
 int register_android_server_ConsumerIrService(JNIEnv *env);
 int register_android_server_InputApplicationHandle(JNIEnv* env);
 int register_android_server_InputWindowHandle(JNIEnv* env);
@@ -70,6 +71,7 @@
     register_android_server_AssetAtlasService(env);
     register_android_server_ConsumerIrService(env);
     register_android_server_dreams_McuHal(env);
+    register_android_server_BatteryStatsService(env);
     register_android_server_hdmi_HdmiCecService(env);
 
     return JNI_VERSION_1_4;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
new file mode 100644
index 0000000..1b048a1
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceOwner.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.app.AppGlobals;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Environment;
+import android.os.RemoteException;
+import android.util.AtomicFile;
+import android.util.Slog;
+import android.util.Xml;
+
+import com.android.internal.annotations.VisibleForTesting;
+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.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+
+/**
+ * Stores and restores state for the Device and Profile owners. By definition there can be
+ * only one device owner, but there may be a profile owner for each user.
+ */
+public class DeviceOwner {
+    private static final String TAG = "DevicePolicyManagerService";
+
+    private static final String DEVICE_OWNER_XML = "device_owner.xml";
+    private static final String TAG_DEVICE_OWNER = "device-owner";
+    private static final String TAG_PROFILE_OWNER = "profile-owner";
+    private static final String ATTR_NAME = "name";
+    private static final String ATTR_PACKAGE = "package";
+    private static final String ATTR_USERID = "userId";
+
+    private AtomicFile fileForWriting;
+
+    // Input/Output streams for testing.
+    private InputStream mInputStreamForTest;
+    private OutputStream mOutputStreamForTest;
+
+    // Internal state for the device owner package.
+    private String mDeviceOwnerPackageName;
+    private String mDeviceOwnerName;
+
+    // Internal state for the profile owner packages.
+    private final HashMap<Integer, String[]> mProfileOwners = new HashMap<Integer, String[]>();
+
+    // Private default constructor.
+    private DeviceOwner() {
+    }
+
+    @VisibleForTesting
+    DeviceOwner(InputStream in, OutputStream out) {
+        mInputStreamForTest = in;
+        mOutputStreamForTest = out;
+    }
+
+    /**
+     * Loads the device owner state from disk.
+     */
+    static DeviceOwner load() {
+        DeviceOwner owner = new DeviceOwner();
+        if (new File(Environment.getSystemSecureDirectory(), DEVICE_OWNER_XML).exists()) {
+            owner.readOwnerFile();
+            return owner;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Creates an instance of the device owner object with the device owner set.
+     */
+    static DeviceOwner createWithDeviceOwner(String packageName, String ownerName) {
+        DeviceOwner owner = new DeviceOwner();
+        owner.mDeviceOwnerPackageName = packageName;
+        owner.mDeviceOwnerName = ownerName;
+        return owner;
+    }
+
+    /**
+     * Creates an instance of the device owner object with the profile owner set.
+     */
+    static DeviceOwner createWithProfileOwner(String packageName, String ownerName, int userId) {
+        DeviceOwner owner = new DeviceOwner();
+        owner.mProfileOwners.put(userId, new String[] { packageName, ownerName });
+        return owner;
+    }
+
+    String getDeviceOwnerPackageName() {
+        return mDeviceOwnerPackageName;
+    }
+
+    String getDeviceOwnerName() {
+        return mDeviceOwnerName;
+    }
+
+    void setDeviceOwner(String packageName, String ownerName) {
+        mDeviceOwnerPackageName = packageName;
+        mDeviceOwnerName = ownerName;
+    }
+
+    void setProfileOwner(String packageName, String ownerName, int userId) {
+        mProfileOwners.put(userId, new String[] { packageName, ownerName });
+    }
+
+    void removeProfileOwner(int userId) {
+        mProfileOwners.remove(userId);
+    }
+
+    String getProfileOwnerPackageName(int userId) {
+        String[] profileOwner = mProfileOwners.get(userId);
+        return profileOwner != null ? profileOwner[0] : null;
+    }
+
+    String getProfileOwnerName(int userId) {
+        String[] profileOwner = mProfileOwners.get(userId);
+        return profileOwner != null ? profileOwner[1] : null;
+    }
+
+    boolean hasDeviceOwner() {
+        return mDeviceOwnerPackageName != null;
+    }
+
+    static boolean isInstalled(String packageName, PackageManager pm) {
+        try {
+            PackageInfo pi;
+            if ((pi = pm.getPackageInfo(packageName, 0)) != null) {
+                if ((pi.applicationInfo.flags) != 0) {
+                    return true;
+                }
+            }
+        } catch (NameNotFoundException nnfe) {
+            Slog.w(TAG, "Device Owner package " + packageName + " not installed.");
+        }
+        return false;
+    }
+
+    static boolean isInstalledForUser(String packageName, int userHandle) {
+        try {
+            PackageInfo pi = (AppGlobals.getPackageManager())
+                    .getPackageInfo(packageName, 0, userHandle);
+            if (pi != null && pi.applicationInfo.flags != 0) {
+                return true;
+            }
+        } catch (RemoteException re) {
+            throw new RuntimeException("Package manager has died", re);
+        }
+
+        return false;
+    }
+
+    void readOwnerFile() {
+        try {
+            InputStream input = openRead();
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(input, null);
+            int type;
+            while ((type=parser.next()) != XmlPullParser.END_DOCUMENT) {
+                if (type!=XmlPullParser.START_TAG) {
+                    continue;
+                }
+
+                String tag = parser.getName();
+                if (tag.equals(TAG_DEVICE_OWNER)) {
+                    mDeviceOwnerPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
+                    mDeviceOwnerName = parser.getAttributeValue(null, ATTR_NAME);
+                } else if (tag.equals(TAG_PROFILE_OWNER)) {
+                    String profileOwnerPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
+                    String profileOwnerName = parser.getAttributeValue(null, ATTR_NAME);
+                    int userId = Integer.parseInt(parser.getAttributeValue(null, ATTR_USERID));
+                    mProfileOwners.put(userId,
+                            new String[] { profileOwnerPackageName, profileOwnerName });
+                } else {
+                    throw new XmlPullParserException(
+                            "Unexpected tag in device owner file: " + tag);
+                }
+            }
+            input.close();
+        } catch (XmlPullParserException xppe) {
+            Slog.e(TAG, "Error parsing device-owner file\n" + xppe);
+        } catch (IOException ioe) {
+            Slog.e(TAG, "IO Exception when reading device-owner file\n" + ioe);
+        }
+    }
+
+    void writeOwnerFile() {
+        synchronized (this) {
+            writeOwnerFileLocked();
+        }
+    }
+
+    private void writeOwnerFileLocked() {
+        try {
+            OutputStream outputStream = startWrite();
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(outputStream, "utf-8");
+            out.startDocument(null, true);
+
+            // Write device owner tag
+            if (mDeviceOwnerPackageName != null) {
+                out.startTag(null, TAG_DEVICE_OWNER);
+                out.attribute(null, ATTR_PACKAGE, mDeviceOwnerPackageName);
+                if (mDeviceOwnerName != null) {
+                    out.attribute(null, ATTR_NAME, mDeviceOwnerName);
+                }
+                out.endTag(null, TAG_DEVICE_OWNER);
+            }
+
+            // Write profile owner tags
+            if (mProfileOwners.size() > 0) {
+                for (HashMap.Entry<Integer, String[]> owner : mProfileOwners.entrySet()) {
+                    out.startTag(null, TAG_PROFILE_OWNER);
+                    out.attribute(null, ATTR_PACKAGE, owner.getValue()[0]);
+                    out.attribute(null, ATTR_NAME, owner.getValue()[1]);
+                    out.attribute(null, ATTR_USERID, Integer.toString(owner.getKey()));
+                    out.endTag(null, TAG_PROFILE_OWNER);
+                }
+            }
+            out.endDocument();
+            out.flush();
+            finishWrite(outputStream);
+        } catch (IOException ioe) {
+            Slog.e(TAG, "IO Exception when writing device-owner file\n" + ioe);
+        }
+    }
+
+    private InputStream openRead() throws IOException {
+        if (mInputStreamForTest != null) {
+            return mInputStreamForTest;
+        }
+
+        return new AtomicFile(new File(Environment.getSystemSecureDirectory(),
+                DEVICE_OWNER_XML)).openRead();
+    }
+
+    private OutputStream startWrite() throws IOException {
+        if (mOutputStreamForTest != null) {
+            return mOutputStreamForTest;
+        }
+
+        fileForWriting = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
+                DEVICE_OWNER_XML));
+        return fileForWriting.startWrite();
+    }
+
+    private void finishWrite(OutputStream stream) {
+        if (fileForWriting != null) {
+            fileForWriting.finishWrite((FileOutputStream) stream);
+        }
+    }
+}
\ No newline at end of file
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 296d852..f186b2c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -27,15 +27,10 @@
 import com.android.org.conscrypt.TrustedCertificateStore;
 import com.android.server.SystemService;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.app.Activity;
 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;
@@ -51,17 +46,11 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.Signature;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.net.ProxyProperties;
-import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Binder;
-import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
@@ -81,7 +70,6 @@
 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;
@@ -89,7 +77,10 @@
 import android.util.SparseArray;
 import android.util.Xml;
 import android.view.IWindowManager;
-import android.view.WindowManagerPolicy;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -99,14 +90,11 @@
 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.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -142,6 +130,7 @@
     IWindowManager mIWindowManager;
     NotificationManager mNotificationManager;
 
+    // Stores and loads state on device and profile owners.
     private DeviceOwner mDeviceOwner;
 
     /**
@@ -631,6 +620,11 @@
                 Slog.w(LOG_TAG, "Tried to remove device policy file for user 0! Ignoring.");
                 return;
             }
+            if (mDeviceOwner != null) {
+                mDeviceOwner.removeProfileOwner(userHandle);
+                mDeviceOwner.writeOwnerFile();
+            }
+
             DevicePolicyData policy = mUserData.get(userHandle);
             if (policy != null) {
                 mUserData.remove(userHandle);
@@ -644,9 +638,7 @@
 
     void loadDeviceOwner() {
         synchronized (this) {
-            if (DeviceOwner.isRegistered()) {
-                mDeviceOwner = new DeviceOwner();
-            }
+            mDeviceOwner = DeviceOwner.load();
         }
     }
 
@@ -1323,8 +1315,7 @@
             }
             if (admin.getUid() != Binder.getCallingUid()) {
                 // If trying to remove device owner, refuse when the caller is not the owner.
-                if (mDeviceOwner != null
-                        && adminReceiver.getPackageName().equals(mDeviceOwner.getPackageName())) {
+                if (isDeviceOwner(adminReceiver.getPackageName())) {
                     return;
                 }
                 mContext.enforceCallingOrSelfPermission(
@@ -2769,14 +2760,26 @@
                     + " for device owner");
         }
         synchronized (this) {
-            if (mDeviceOwner == null && !isDeviceProvisioned()) {
-                mDeviceOwner = new DeviceOwner(packageName, ownerName);
+            if (isDeviceProvisioned()) {
+                throw new IllegalStateException(
+                        "Trying to set device owner but device is already provisioned.");
+            }
+
+            if (mDeviceOwner != null && mDeviceOwner.hasDeviceOwner()) {
+                throw new IllegalStateException(
+                        "Trying to set device owner but device owner is already set.");
+            }
+
+            if (mDeviceOwner == null) {
+                // Device owner is not set and does not exist, set it.
+                mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName);
                 mDeviceOwner.writeOwnerFile();
                 return true;
             } else {
-                throw new IllegalStateException("Trying to set device owner to " + packageName
-                        + ", owner=" + mDeviceOwner.getPackageName()
-                        + ", device_provisioned=" + isDeviceProvisioned());
+                // Device owner is not set but a profile owner exists, update Device owner state.
+                mDeviceOwner.setDeviceOwner(packageName, ownerName);
+                mDeviceOwner.writeOwnerFile();
+                return true;
             }
         }
     }
@@ -2788,7 +2791,8 @@
         }
         synchronized (this) {
             return mDeviceOwner != null
-                    && mDeviceOwner.getPackageName().equals(packageName);
+                    && mDeviceOwner.hasDeviceOwner()
+                    && mDeviceOwner.getDeviceOwnerPackageName().equals(packageName);
         }
     }
 
@@ -2799,7 +2803,7 @@
         }
         synchronized (this) {
             if (mDeviceOwner != null) {
-                return mDeviceOwner.getPackageName();
+                return mDeviceOwner.getDeviceOwnerPackageName();
             }
         }
         return null;
@@ -2813,7 +2817,75 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
         synchronized (this) {
             if (mDeviceOwner != null) {
-                return mDeviceOwner.getName();
+                return mDeviceOwner.getDeviceOwnerName();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean setProfileOwner(String packageName, String ownerName, int userHandle) {
+        if (!mHasFeature) {
+            return false;
+        }
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+
+        UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        if (um.getUserInfo(userHandle) == null) {
+            // User doesn't exist.
+            throw new IllegalArgumentException(
+                    "Attempted to set profile owner for invalid userId: " + userHandle);
+        }
+
+        if (packageName == null
+                || !DeviceOwner.isInstalledForUser(packageName, userHandle)) {
+            throw new IllegalArgumentException("Package name " + packageName
+                    + " not installed for userId:" + userHandle);
+        }
+        synchronized (this) {
+            if (isUserSetupComplete(userHandle)) {
+                throw new IllegalStateException(
+                        "Trying to set profile owner but user is already set-up.");
+            }
+            if (mDeviceOwner == null) {
+                // Device owner state does not exist, create it.
+                mDeviceOwner = DeviceOwner.createWithProfileOwner(packageName, ownerName,
+                        userHandle);
+                mDeviceOwner.writeOwnerFile();
+                return true;
+            } else {
+                // Device owner already exists, update it.
+                mDeviceOwner.setProfileOwner(packageName, ownerName, userHandle);
+                mDeviceOwner.writeOwnerFile();
+                return true;
+            }
+        }
+    }
+
+    @Override
+    public String getProfileOwner(int userHandle) {
+        if (!mHasFeature) {
+            return null;
+        }
+
+        synchronized (this) {
+            if (mDeviceOwner != null) {
+                return mDeviceOwner.getProfileOwnerPackageName(userHandle);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getProfileOwnerName(int userHandle) {
+        if (!mHasFeature) {
+            return null;
+        }
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+
+        synchronized (this) {
+            if (mDeviceOwner != null) {
+                return mDeviceOwner.getProfileOwnerName(userHandle);
             }
         }
         return null;
@@ -2824,6 +2896,11 @@
                 Settings.Global.DEVICE_PROVISIONED, 0) > 0;
     }
 
+    private boolean isUserSetupComplete(int userId) {
+        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.USER_SETUP_COMPLETE, 0, userId) > 0;
+    }
+
     private void enforceCrossUserPermission(int userHandle) {
         if (userHandle < 0) {
             throw new IllegalArgumentException("Invalid userId " + userHandle);
@@ -2889,101 +2966,64 @@
         }
     }
 
-    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;
+    private boolean isProfileOwner(String packageName, int userId) {
+        String profileOwnerPackage = getProfileOwner(userId);
+        // TODO: make public and connect with isProfileOwnerApp in DPM
+        return profileOwnerPackage != null && profileOwnerPackage.equals(packageName);
+    }
 
-        DeviceOwner() {
-            readOwnerFile();
-        }
-
-        DeviceOwner(String packageName, String ownerName) {
-            this.mPackageName = packageName;
-            this.mOwnerName = ownerName;
-        }
-
-        static boolean isRegistered() {
-            return new File(Environment.getSystemSecureDirectory(),
-                    DEVICE_OWNER_XML).exists();
-        }
-
-        String getPackageName() {
-            return mPackageName;
-        }
-
-        String getName() {
-            return mOwnerName;
-        }
-
-        static boolean isInstalled(String packageName, PackageManager pm) {
-            try {
-                PackageInfo pi;
-                if ((pi = pm.getPackageInfo(packageName, 0)) != null) {
-                    if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                        return true;
+    public void addPersistentPreferredActivity(ComponentName admin, IntentFilter filter,
+            ComponentName activity) {
+        int callingUserId = UserHandle.getCallingUserId();
+        Slog.d(LOG_TAG,"called by user " + callingUserId);
+        synchronized (this) {
+            ActiveAdmin aa = getActiveAdminUncheckedLocked(admin, callingUserId);
+            if (aa == null) {
+                throw new SecurityException("No active admin " + admin);
+            } else {
+                if (isProfileOwner(admin.getPackageName(), callingUserId)
+                        || isDeviceOwner(admin.getPackageName())) {
+                    IPackageManager pm = AppGlobals.getPackageManager();
+                    long id = Binder.clearCallingIdentity();
+                    try {
+                        pm.addPersistentPreferredActivity(filter, activity, callingUserId);
+                    } catch (RemoteException re) {
+                        // Shouldn't happen
+                    } finally {
+                        restoreCallingIdentity(id);
                     }
+                } else {
+                    throw new SecurityException("Admin " + admin +
+                            "is not device owner or profile owner" );
                 }
-            } catch (NameNotFoundException nnfe) {
-                Slog.w(LOG_TAG, "Device Owner package " + packageName + " not installed.");
-            }
-            return false;
-        }
-
-        void readOwnerFile() {
-            AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
-                    DEVICE_OWNER_XML));
-            try {
-                FileInputStream input = file.openRead();
-                XmlPullParser parser = Xml.newPullParser();
-                parser.setInput(input, null);
-                int type;
-                while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
-                        && type != XmlPullParser.START_TAG) {
-                }
-                String tag = parser.getName();
-                if (!TAG_DEVICE_OWNER.equals(tag)) {
-                    throw new XmlPullParserException(
-                            "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(LOG_TAG, "Error parsing device-owner file\n" + xppe);
-            } catch (IOException ioe) {
-                Slog.e(LOG_TAG, "IO Exception when reading device-owner file\n" + ioe);
             }
         }
+    }
 
-        void writeOwnerFile() {
-            synchronized (this) {
-                writeOwnerFileLocked();
-            }
-        }
-
-        private void writeOwnerFileLocked() {
-            AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
-                    DEVICE_OWNER_XML));
-            try {
-                FileOutputStream output = file.startWrite();
-                XmlSerializer out = new FastXmlSerializer();
-                out.setOutput(output, "utf-8");
-                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);
+    public void clearPackagePersistentPreferredActivities(ComponentName admin,
+            String packageName) {
+        int callingUserId = UserHandle.getCallingUserId();
+        Slog.d(LOG_TAG,"called by user " + callingUserId);
+        synchronized (this) {
+            ActiveAdmin aa = getActiveAdminUncheckedLocked(admin, callingUserId);
+            if (aa == null) {
+                throw new SecurityException("No active admin " + admin);
+            } else {
+                if (isProfileOwner(admin.getPackageName(), callingUserId)
+                        || isDeviceOwner(admin.getPackageName())) {
+                    IPackageManager pm = AppGlobals.getPackageManager();
+                    long id = Binder.clearCallingIdentity();
+                    try{
+                        pm.clearPackagePersistentPreferredActivities(packageName, callingUserId);
+                    } catch (RemoteException re) {
+                        // Shouldn't happen
+                    } finally {
+                        restoreCallingIdentity(id);
+                    }
+                } else {
+                    throw new SecurityException("Admin " + admin +
+                            "is not device owner or profile owner" );
                 }
-                out.endTag(null, TAG_DEVICE_OWNER);
-                out.endDocument();
-                out.flush();
-                file.finishWrite(output);
-            } catch (IOException ioe) {
-                Slog.e(LOG_TAG, "IO Exception when writing device-owner file\n" + ioe);
             }
         }
     }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index f80db48..c925669 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -29,7 +29,6 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.media.AudioService;
-import android.net.wifi.p2p.WifiP2pService;
 import android.os.Environment;
 import android.os.FactoryTest;
 import android.os.Handler;
@@ -64,6 +63,7 @@
 import com.android.server.lights.LightsManager;
 import com.android.server.lights.LightsService;
 import com.android.server.media.MediaRouterService;
+import com.android.server.media.MediaSessionService;
 import com.android.server.net.NetworkPolicyManagerService;
 import com.android.server.net.NetworkStatsService;
 import com.android.server.notification.NotificationManagerService;
@@ -79,7 +79,6 @@
 import com.android.server.twilight.TwilightService;
 import com.android.server.usb.UsbService;
 import com.android.server.wallpaper.WallpaperManagerService;
-import com.android.server.wifi.WifiService;
 import com.android.server.wm.WindowManagerService;
 
 import dalvik.system.VMRuntime;
@@ -115,6 +114,10 @@
             "com.android.server.print.PrintManagerService";
     private static final String USB_SERVICE_CLASS =
             "com.android.server.usb.UsbService$Lifecycle";
+    private static final String WIFI_SERVICE_CLASS =
+            "com.android.server.wifi.WifiService";
+    private static final String WIFI_P2P_SERVICE_CLASS =
+            "com.android.server.wifi.p2p.WifiP2pService";
     private static final String HDMI_CEC_SERVICE_CLASS =
             "com.android.server.hdmi.HdmiCecService";
 
@@ -302,8 +305,6 @@
         NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
         ConnectivityService connectivity = null;
-        WifiP2pService wifiP2p = null;
-        WifiService wifi = null;
         NsdService serviceDiscovery= null;
         IPackageManager pm = null;
         WindowManagerService wm = null;
@@ -606,18 +607,14 @@
                     reportWtf("starting NetworkPolicy Service", e);
                 }
 
-               try {
-                    Slog.i(TAG, "Wi-Fi P2pService");
-                    wifiP2p = new WifiP2pService(context);
-                    ServiceManager.addService(Context.WIFI_P2P_SERVICE, wifiP2p);
+                try {
+                    mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
                 } 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);
+                try {
+                    mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
                 } catch (Throwable e) {
                     reportWtf("starting Wi-Fi Service", e);
                 }
@@ -629,9 +626,6 @@
                     ServiceManager.addService(Context.CONNECTIVITY_SERVICE, connectivity);
                     networkStats.bindConnectivityManager(connectivity);
                     networkPolicy.bindConnectivityManager(connectivity);
-
-                    wifiP2p.connectivityServiceReady();
-                    wifi.checkAndStartWifi();
                 } catch (Throwable e) {
                     reportWtf("starting Connectivity Service", e);
                 }
@@ -891,6 +885,13 @@
             }
 
             try {
+                Slog.i(TAG, "MediaSessionService");
+                mSystemServiceManager.startService(MediaSessionService.class);
+            } catch (Throwable e) {
+                reportWtf("starting MediaSessionService", e);
+            }
+
+            try {
                 mSystemServiceManager.startService(HDMI_CEC_SERVICE_CLASS);
             } catch (Throwable e) {
                 reportWtf("starting HdmiCec Service", e);
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index c6fdbe5..f7bec6e 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -405,7 +405,6 @@
         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) {
@@ -425,39 +424,42 @@
         private void registerBoradcastReceivers() {
             PackageMonitor monitor = new PackageMonitor() {
                 @Override
-                public boolean onPackageChanged(String packageName, int uid, String[] components) {
+                public void onPackageModified(String packageName) {
                     synchronized (mLock) {
+                        boolean servicesChanged = false;
                         UserState userState = getOrCreateUserStateLocked(getChangingUserId());
-                        Iterator<ComponentName> iterator = userState.getEnabledServices()
-                                .iterator();
+                        Iterator<ComponentName> iterator = userState.getEnabledServices().iterator();
                         while (iterator.hasNext()) {
                             ComponentName componentName = iterator.next();
                             if (packageName.equals(componentName.getPackageName())) {
-                                userState.updateIfNeededLocked();
-                                return true;
+                                servicesChanged = true;
                             }
                         }
+                        if (servicesChanged) {
+                            userState.updateIfNeededLocked();
+                        }
                     }
-                    return false;
                 }
 
                 @Override
                 public void onPackageRemoved(String packageName, int uid) {
                     synchronized (mLock) {
+                        boolean servicesRemoved = false;
                         UserState userState = getOrCreateUserStateLocked(getChangingUserId());
-                        Iterator<ComponentName> iterator = userState.getEnabledServices()
-                                .iterator();
+                        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;
+                                servicesRemoved = true;
                             }
                         }
+                        if (servicesRemoved) {
+                            persistComponentNamesToSettingLocked(
+                                    Settings.Secure.ENABLED_PRINT_SERVICES,
+                                    userState.getEnabledServices(), getChangingUserId());
+                            userState.updateIfNeededLocked();
+                        }
                     }
                 }
 
diff --git a/services/print/java/com/android/server/print/UserState.java b/services/print/java/com/android/server/print/UserState.java
index f23a992..f647814 100644
--- a/services/print/java/com/android/server/print/UserState.java
+++ b/services/print/java/com/android/server/print/UserState.java
@@ -71,6 +71,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -594,6 +595,8 @@
                     .append(installedService.getSettingsActivityName()).println();
             pw.append(installedServicePrefix).append(tab).append("addPrintersActivity=")
                     .append(installedService.getAddPrintersActivityName()).println();
+            pw.append(installedServicePrefix).append(tab).append("avancedOptionsActivity=")
+                   .append(installedService.getAdvancedOptionsActivityName()).println();
         }
 
         pw.append(prefix).append(tab).append("enabled services:").println();
@@ -657,7 +660,33 @@
             tempPrintServices.add(PrintServiceInfo.create(installedService, mContext));
         }
 
-        if (!tempPrintServices.equals(mInstalledServices)) {
+        boolean someServiceChanged = false;
+
+        if (tempPrintServices.size() != mInstalledServices.size()) {
+            someServiceChanged = true;
+        } else {
+            for (PrintServiceInfo newService: tempPrintServices) {
+                final int oldServiceIndex = mInstalledServices.indexOf(newService);
+                if (oldServiceIndex < 0) {
+                    someServiceChanged = true;
+                    break;
+                }
+                // PrintServiceInfo#equals compares only the id not all members,
+                // so we are also comparing the members coming from meta-data.
+                PrintServiceInfo oldService = mInstalledServices.get(oldServiceIndex);
+                if (!TextUtils.equals(oldService.getAddPrintersActivityName(),
+                            newService.getAddPrintersActivityName())
+                        || !TextUtils.equals(oldService.getAdvancedOptionsActivityName(),
+                                newService.getAdvancedOptionsActivityName())
+                        || !TextUtils.equals(oldService.getSettingsActivityName(),
+                                newService.getSettingsActivityName())) {
+                    someServiceChanged = true;
+                    break;
+                }
+            }
+        }
+
+        if (someServiceChanged) {
             mInstalledServices.clear();
             mInstalledServices.addAll(tempPrintServices);
             return true;
@@ -761,11 +790,16 @@
     }
 
     private void onConfigurationChangedLocked() {
+        Set<ComponentName> installedComponents = new ArraySet<ComponentName>();
+
         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);
+
+            installedComponents.add(serviceName);
+
             if (mEnabledServices.contains(serviceName)) {
                 if (!mActiveServices.containsKey(serviceName)) {
                     RemotePrintService service = new RemotePrintService(
@@ -779,6 +813,18 @@
                 }
             }
         }
+
+        Iterator<Map.Entry<ComponentName, RemotePrintService>> iterator =
+                mActiveServices.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<ComponentName, RemotePrintService> entry = iterator.next();
+            ComponentName serviceName = entry.getKey();
+            RemotePrintService service = entry.getValue();
+            if (!installedComponents.contains(serviceName)) {
+                removeServiceLocked(service);
+                iterator.remove();
+            }
+        }
     }
 
     private void addServiceLocked(RemotePrintService service) {
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index 7a30d31..0d5daa5 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -141,14 +141,21 @@
         /**
          * Interface class activity.
          */
+
         sendMessage("613 IfaceClass active rmnet0");
-        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true);
+        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 0);
+
+        sendMessage("613 IfaceClass active rmnet0 1234");
+        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 1234);
 
         sendMessage("613 IfaceClass idle eth0");
-        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false);
+        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 0);
 
-        sendMessage("613 IfaceClass reallyactive rmnet0");
-        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", false);
+        sendMessage("613 IfaceClass idle eth0 1234");
+        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 1234);
+
+        sendMessage("613 IfaceClass reallyactive rmnet0 1234");
+        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", false, 1234);
 
         sendMessage("613 InterfaceClass reallyactive rmnet0");
         // Invalid group.
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 8ae3824..0f20dde 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -226,9 +226,9 @@
                 final Handler handler) {
         }
 
-		@Override
-		public void invalidateCache(int userId) {
-		}
+        @Override
+        public void invalidateCache(int userId) {
+        }
     }
 
     static public class MyMockContext extends MockContext {
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 37176d6..b0296a0 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncOperationTest.java
@@ -18,12 +18,13 @@
 
 import android.accounts.Account;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.os.Bundle;
+import android.os.SystemClock;
+import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.server.content.SyncOperation;
-
 /**
  * You can run those tests with:
  *
@@ -35,6 +36,21 @@
 
 public class SyncOperationTest extends AndroidTestCase {
 
+    Account mDummy;
+    /** Indicate an unimportant long that we're not testing. */
+    long mUnimportantLong = 0L;
+    /** Empty bundle. */
+    Bundle mEmpty;
+    /** Silly authority. */
+    String mAuthority;
+
+    @Override
+    public void setUp() {
+        mDummy = new Account("account1", "type1");
+        mEmpty = new Bundle();
+        mAuthority = "authority1";
+    }
+
     @SmallTest
     public void testToKey() {
         Account account1 = new Account("account1", "type1");
@@ -111,35 +127,64 @@
 
     @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);
+        SyncOperation op1 = new SyncOperation(mDummy, 0, 0, SyncOperation.REASON_PERIODIC,
+                "authority1", mEmpty, soon, soonFlex, mUnimportantLong, mUnimportantLong, true);
 
         // Interval disjoint from and after op1.
-        SyncOperation op2 = new SyncOperation(dummy, 0, 0, SyncOperation.REASON_PERIODIC,
-                "authority1", b1, after, afterFlex, unimportant, unimportant, true);
+        SyncOperation op2 = new SyncOperation(mDummy, 0, 0, SyncOperation.REASON_PERIODIC,
+                "authority1", mEmpty, after, afterFlex, mUnimportantLong, mUnimportantLong, 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);
+        SyncOperation op3 = new SyncOperation(mDummy, 0, 0, 0,
+                "authority1", b2, -1, soonFlex, mUnimportantLong, mUnimportantLong, 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);
+        SyncOperation op4 = new SyncOperation(mDummy, 0, 0, SyncOperation.REASON_PERIODIC,
+                "authority1", mEmpty, soon + 100, soonFlex + 100, mUnimportantLong, mUnimportantLong, true);
 
         assertTrue(op1.compareTo(op2) == -1);
         assertTrue("less than not transitive.", op2.compareTo(op1) == 1);
-        assertTrue(op1.compareTo(op3) == 1);
+        assertTrue("Expedited sync not smaller than non-expedited.", 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);
+        assertTrue("overlapping intervals not correctly compared.", op1.compareTo(op4) == -1);
+        assertTrue("equality not transitive.", op4.compareTo(op1) == 1);
+    }
+
+    @SmallTest
+    public void testCopyConstructor() {
+        long fiveSecondsFromNow = 5 * 1000L;
+        long twoSecondsFlex = 2 * 1000L;
+        long eightSeconds = 8 * 1000L;
+        long fourSeconds = 4 * 1000L;
+
+        Bundle withExpedited = new Bundle();
+        withExpedited.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
+        SyncOperation op = new SyncOperation(mDummy, 0, 0, SyncOperation.REASON_USER_START,
+                mAuthority, withExpedited, fiveSecondsFromNow, twoSecondsFlex,
+                eightSeconds /* backoff */, fourSeconds /* delayUntil */, true);
+        // Create another sync op to be rerun in 5 minutes.
+        long now = SystemClock.elapsedRealtime();
+        SyncOperation copy = new SyncOperation(op, fiveSecondsFromNow * 60);
+        // Copying an expedited sync to be re-run should not keep expedited property.
+        assertFalse("A rescheduled sync based off an expedited should not be expedited!",
+                copy.isExpedited());
+        assertFalse("A rescheduled sync based off an expedited should not have expedited=true in"
+                + "its bundle.",
+                copy.extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false));
+        assertTrue("Copied sync is not respecting new provided run-time.",
+                copy.latestRunTime == (now + fiveSecondsFromNow * 60));
+        assertTrue("A rescheduled sync should not have any flex.",
+                copy.flexTime == 0L);
+        assertTrue("A rescheduled op should honour the old op's backoff.",
+                copy.backoff == eightSeconds);
+        assertTrue("A rescheduled op should honour the old op's delayUntil param.",
+                copy.delayUntil == fourSeconds);
+
     }
 }
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 f870e4c..ae1967e 100644
--- a/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
+++ b/services/tests/servicestests/src/com/android/server/content/SyncStorageEngineTest.java
@@ -17,6 +17,7 @@
 package com.android.server.content;
 
 import android.accounts.Account;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
@@ -32,22 +33,34 @@
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.server.content.SyncStorageEngine.EndPoint;
+
 import com.android.internal.os.AtomicFile;
 
 import java.io.File;
 import java.io.FileOutputStream;
 import java.util.List;
 
+import com.android.server.content.SyncStorageEngine.EndPoint;
+
 public class SyncStorageEngineTest extends AndroidTestCase {
 
     protected Account account1;
+    protected Account account2;
+    protected ComponentName syncService1;
     protected String authority1 = "testprovider";
     protected Bundle defaultBundle;
     protected final int DEFAULT_USER = 0;
-    
+
+    /* Some default poll frequencies. */
+    final long dayPoll = (60 * 60 * 24);
+    final long dayFuzz = 60;
+    final long thousandSecs = 1000;
+    final long thousandSecsFuzz = 100;
+
     MockContentResolver mockResolver;
     SyncStorageEngine engine;
-    
+
     private File getSyncDir() {
         return new File(new File(getContext().getFilesDir(), "system"), "sync");
     }
@@ -55,6 +68,8 @@
     @Override
     public void setUp() {
         account1 = new Account("a@example.com", "example.type");
+        account2 = new Account("b@example.com", "example.type");
+        syncService1 = new ComponentName("com.example", "SyncService");
         // Default bundle.
         defaultBundle = new Bundle();
         defaultBundle.putInt("int_key", 0);
@@ -80,11 +95,13 @@
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
                 new TestContext(mockResolver, getContext()));
-
         long time0 = 1000;
-        long historyId = engine.insertStartSyncEvent(
-                account, 0, SyncOperation.REASON_PERIODIC, authority, time0,
-                SyncStorageEngine.SOURCE_LOCAL, false /* initialization */, null /* extras */);
+        SyncOperation op = new SyncOperation(account, 0,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL,
+                authority,
+                Bundle.EMPTY, time0, 0 /* flex*/, 0, 0, true);
+        long historyId = engine.insertStartSyncEvent(op, time0);
         long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
         engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0);
     }
@@ -93,28 +110,100 @@
      * 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);
+    public void testAppendPending() throws Exception {
+        SyncOperation sop = new SyncOperation(account1,
+                DEFAULT_USER,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+                0 /* runtime */, 0 /* flex */, 0 /* backoff */, 0 /* delayuntil */,
+                true /* expedited */);
+        engine.insertIntoPending(sop);
+
         // Force engine to read from disk.
         engine.clearAndReadState();
 
-        assert(engine.getPendingOperationCount() == 1);
+        assertTrue(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));
+        assertEquals(sop.target.account, popRetrieved.target.account);
+        assertEquals(sop.target.provider, popRetrieved.target.provider);
+        assertEquals(sop.target.service, popRetrieved.target.service);
+        assertEquals(sop.target.userId, popRetrieved.target.userId);
+        assertEquals(sop.reason, popRetrieved.reason);
+        assertEquals(sop.syncSource, popRetrieved.syncSource);
+        assertEquals(sop.isExpedited(), popRetrieved.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(sop.extras, popRetrieved.extras));
+    }
 
+    /**
+     * Verify {@link com.android.server.content.SyncStorageEngine#writePendingOperationsLocked()}
+     */
+    public void testWritePendingOperationsLocked() throws Exception {
+        SyncOperation sop = new SyncOperation(account1,
+                DEFAULT_USER,
+                SyncOperation.REASON_IS_SYNCABLE,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+                1000L /* runtime */, 57L /* flex */, 0 /* backoff */, 0 /* delayuntil */,
+                true /* expedited */);
+        SyncOperation sop1 = new SyncOperation(account2,
+                DEFAULT_USER,
+                SyncOperation.REASON_PERIODIC,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, defaultBundle,
+                0 /* runtime */, 0 /* flex */, 20L /* backoff */, 100L /* delayuntil */,
+                false /* expedited */);
+        SyncOperation deleted = new SyncOperation(account2,
+                DEFAULT_USER,
+                SyncOperation.REASON_SYNC_AUTO,
+                SyncStorageEngine.SOURCE_LOCAL, authority1, Bundle.EMPTY,
+                0 /* runtime */, 0 /* flex */, 20L /* backoff */, 100L /* delayuntil */,
+                false /* expedited */);
+        engine.insertIntoPending(sop);
+        engine.insertIntoPending(sop1);
+        engine.insertIntoPending(deleted);
+
+        SyncStorageEngine.PendingOperation popDeleted = engine.getPendingOperations().get(2);
+        // Free verifying, going to delete it anyway.
+        assertEquals(deleted.target.account, popDeleted.target.account);
+        assertEquals(deleted.target.provider, popDeleted.target.provider);
+        assertEquals(deleted.target.service, popDeleted.target.service);
+        assertEquals(deleted.target.userId, popDeleted.target.userId);
+        assertEquals(deleted.reason, popDeleted.reason);
+        assertEquals(deleted.syncSource, popDeleted.syncSource);
+        assertEquals(deleted.isExpedited(), popDeleted.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(deleted.extras, popDeleted.extras));
+        // Delete one to force write-all
+        engine.deleteFromPending(popDeleted);
+        assertEquals("Delete of pending op failed.", 2, engine.getPendingOperationCount());
+        // If there's dirty pending data (which there is because we deleted a pending op) this
+        // re-writes the entire file.
+        engine.writeAllState();
+
+        engine.clearAndReadState();
+
+        // Validate state read back out.
+        assertEquals("Delete of pending op failed.", 2, engine.getPendingOperationCount());
+
+        List<SyncStorageEngine.PendingOperation> pops = engine.getPendingOperations();
+
+        SyncStorageEngine.PendingOperation popRetrieved = pops.get(0);
+        assertEquals(sop.target.account, popRetrieved.target.account);
+        assertEquals(sop.target.provider, popRetrieved.target.provider);
+        assertEquals(sop.target.service, popRetrieved.target.service);
+        assertEquals(sop.target.userId, popRetrieved.target.userId);
+        assertEquals(sop.reason, popRetrieved.reason);
+        assertEquals(sop.syncSource, popRetrieved.syncSource);
+        assertEquals(sop.isExpedited(), popRetrieved.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(sop.extras, popRetrieved.extras));
+
+        popRetrieved = pops.get(1);
+        assertEquals(sop1.target.account, popRetrieved.target.account);
+        assertEquals(sop1.target.provider, popRetrieved.target.provider);
+        assertEquals(sop1.target.service, popRetrieved.target.service);
+        assertEquals(sop1.target.userId, popRetrieved.target.userId);
+        assertEquals(sop1.reason, popRetrieved.reason);
+        assertEquals(sop1.syncSource, popRetrieved.syncSource);
+        assertEquals(sop1.isExpedited(), popRetrieved.expedited);
+        assert(android.content.PeriodicSync.syncExtrasEquals(sop1.extras, popRetrieved.extras));
     }
 
     /**
@@ -134,42 +223,44 @@
         final int period2 = 1000;
 
         PeriodicSync sync1 = new PeriodicSync(account1, authority, extras1, period1);
+        EndPoint end1 = new EndPoint(account1, authority, 0);
+
         PeriodicSync sync2 = new PeriodicSync(account1, authority, extras2, period1);
         PeriodicSync sync3 = new PeriodicSync(account1, authority, extras2, period2);
         PeriodicSync sync4 = new PeriodicSync(account2, authority, extras2, period2);
 
-        
+
 
         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);
-        engine.addPeriodicSync(sync4, 0);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras1);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period1, 0, extras2);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 0), period2, 0, extras2);
+        engine.updateOrAddPeriodicSync(new EndPoint(account2, authority, 0), period2, 0, extras2);
         // add a second user
-        engine.addPeriodicSync(sync2, 1);
+        engine.updateOrAddPeriodicSync(new EndPoint(account1, authority, 1), period1, 0, extras2);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0));
 
         assertEquals(2, syncs.size());
 
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync3, syncs.get(1));
 
-        engine.removePeriodicSync(sync1, 0);
+        engine.removePeriodicSync(new EndPoint(account1, authority, 0), extras1);
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(account1, authority, 0));
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(account2, authority, 0));
         assertEquals(1, syncs.size());
         assertEquals(sync4, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(sync2.account, 1, sync2.authority);
+        syncs = engine.getPeriodicSyncs(new EndPoint(sync2.account, sync2.authority, 1));
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
     }
@@ -190,12 +281,19 @@
         final int period2 = 1000;
         final int flex1 = 10;
         final int flex2 = 100;
+        EndPoint point1 = new EndPoint(account1, authority, 0);
+        EndPoint point2 = new EndPoint(account2, authority, 0);
+        EndPoint point1User2 = new EndPoint(account1, authority, 1);
 
         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);
 
+        EndPoint target1 = new EndPoint(account1, authority, 0);
+        EndPoint target2 = new EndPoint(account2, authority, 0);
+        EndPoint target1UserB = new EndPoint(account1, authority, 1);
+
         MockContentResolver mockResolver = new MockContentResolver();
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
@@ -206,40 +304,42 @@
         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);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2);
+        // Edit existing sync and update the period and flex.
+        engine.updateOrAddPeriodicSync(target1, period2, flex2, extras2);
+        engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2);
+        // add a target for a second user.
+        engine.updateOrAddPeriodicSync(target1UserB, period1, flex1, extras2);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
 
         assertEquals(2, syncs.size());
 
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync3, syncs.get(1));
 
-        engine.removePeriodicSync(sync1, 0);
+        engine.removePeriodicSync(target1, extras1);
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync4, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(sync2.account, 1, sync2.authority);
+        syncs = engine.getPeriodicSyncs(target1UserB);
         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);
+        EndPoint target = new EndPoint(account, authority, userId);
+        engine.setIsSyncable(account, userId, authority, engine.getIsSyncable(account, userId, authority));
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target);
         for (PeriodicSync sync : syncs) {
-            engine.removePeriodicSync(sync, userId);
+            engine.removePeriodicSync(target, sync.extras);
         }
     }
 
@@ -264,16 +364,19 @@
         final int flex1 = 10;
         final int flex2 = 100;
 
+        EndPoint point1 = new EndPoint(account1, authority1, 0);
+        EndPoint point2 = new EndPoint(account1, authority2, 0);
+        EndPoint point3 = new EndPoint(account2, authority1, 0);
+
         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();
-
-        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(
-                new TestContext(mockResolver, getContext()));
+        EndPoint target1 = new EndPoint(account1, authority1, 0);
+        EndPoint target2 = new EndPoint(account1, authority2, 0);
+        EndPoint target3 = new EndPoint(account2, authority1, 0);
 
         removePeriodicSyncs(engine, account1, 0, authority1);
         removePeriodicSyncs(engine, account2, 0, authority1);
@@ -294,26 +397,26 @@
         engine.setIsSyncable(account2, 0, authority2, 0);
         engine.setSyncAutomatically(account2, 0, authority2, true);
 
-        engine.addPeriodicSync(sync1, 0);
-        engine.addPeriodicSync(sync2, 0);
-        engine.addPeriodicSync(sync3, 0);
-        engine.addPeriodicSync(sync4, 0);
-        engine.addPeriodicSync(sync5, 0);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target1, period1, flex1, extras2);
+        engine.updateOrAddPeriodicSync(target2, period1, flex1, extras1);
+        engine.updateOrAddPeriodicSync(target2, period2, flex2, extras2);
+        engine.updateOrAddPeriodicSync(target3, period1, flex1, extras1);
 
         engine.writeAllState();
         engine.clearAndReadState();
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account1, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals(2, syncs.size());
         assertEquals(sync1, syncs.get(0));
         assertEquals(sync2, syncs.get(1));
 
-        syncs = engine.getPeriodicSyncs(account1, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(2, syncs.size());
         assertEquals(sync3, syncs.get(0));
         assertEquals(sync4, syncs.get(1));
 
-        syncs = engine.getPeriodicSyncs(account2, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync5, syncs.get(0));
 
@@ -328,6 +431,50 @@
         assertEquals(0, engine.getIsSyncable(account2, 0, authority2));
     }
 
+    @SmallTest
+    public void testComponentParsing() throws Exception {
+
+        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"2\" >\n"
+                + "<authority id=\"0\" user=\"0\" package=\"" + syncService1.getPackageName() + "\""
+                + " class=\"" + syncService1.getClassName() + "\" syncable=\"true\">"
+                + "\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);
+
+        engine.clearAndReadState();
+
+        SyncStorageEngine.AuthorityInfo aInfo = engine.getAuthority(0);
+        assertNotNull(aInfo);
+
+        // Test service component read
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(
+                new SyncStorageEngine.EndPoint(syncService1, 0));
+        assertEquals(1, syncs.size());
+        assertEquals(true, engine.getIsTargetServiceActive(syncService1, 0));
+    }
+
+    @SmallTest
+    public void testComponentSettings() throws Exception {
+        EndPoint target1 = new EndPoint(syncService1, 0);
+        engine.updateOrAddPeriodicSync(target1, dayPoll, dayFuzz, Bundle.EMPTY);
+        
+        engine.setIsTargetServiceActive(target1.service, 0, true);
+        boolean active = engine.getIsTargetServiceActive(target1.service, 0);
+        assert(active);
+
+        engine.setIsTargetServiceActive(target1.service, 1, false);
+        active = engine.getIsTargetServiceActive(target1.service, 1);
+        assert(!active);
+    }
+
     @MediumTest
     /**
      * V2 introduces flex time as well as service components.
@@ -339,20 +486,20 @@
         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();
+        EndPoint target1 = new EndPoint(account, authority1, 0);
+        EndPoint target2 = new EndPoint(account, authority2, 0);
+        EndPoint target3 = new EndPoint(account, authority3, 0);
+        EndPoint target4 = new EndPoint(account, authority3, 1);
 
-        final TestContext testContext = new TestContext(mockResolver, getContext());
+        PeriodicSync sync1 = new PeriodicSync(account, authority1, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync2 = new PeriodicSync(account, authority2, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync3 = new PeriodicSync(account, authority3, Bundle.EMPTY, dayPoll, dayFuzz);
+        PeriodicSync sync1s = new PeriodicSync(account, authority1, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
+        PeriodicSync sync2s = new PeriodicSync(account, authority2, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
+        PeriodicSync sync3s = new PeriodicSync(account, authority3, Bundle.EMPTY, thousandSecs,
+                thousandSecsFuzz);
 
         byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
                 + "<accounts version=\"2\" >\n"
@@ -378,21 +525,22 @@
         fos.write(accountsFileData);
         accountInfoFile.finishWrite(fos);
 
-        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
+        engine.clearAndReadState();
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals("Got incorrect # of syncs", 1, syncs.size());
         assertEquals(sync1, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 1, authority3);
+        syncs = engine.getPeriodicSyncs(target4);
+
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
@@ -411,13 +559,13 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(0, syncs.size());
 
         accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
@@ -440,15 +588,15 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync1s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3s, syncs.get(0));
     }
@@ -460,6 +608,12 @@
         final String authority2 = "auth2";
         final String authority3 = "auth3";
         final Bundle extras = new Bundle();
+
+        EndPoint target1 = new EndPoint(account, authority1, 0);
+        EndPoint target2 = new EndPoint(account, authority2, 0);
+        EndPoint target3 = new EndPoint(account, authority3, 0);
+        EndPoint target4 = new EndPoint(account, authority3, 1);
+
         PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24));
         PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24));
         PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24));
@@ -488,19 +642,20 @@
 
         SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
 
-        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals("expected sync1: " + sync1.toString() + " == sync 2" + syncs.get(0).toString(), sync1, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
+        syncs = engine.getPeriodicSyncs(target4);
 
-        syncs = engine.getPeriodicSyncs(account, 1, authority3);
+
         assertEquals(1, syncs.size());
         assertEquals(sync3, syncs.get(0));
 
@@ -518,13 +673,13 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(0, syncs.size());
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(0, syncs.size());
 
         accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
@@ -547,15 +702,15 @@
 
         engine.clearAndReadState();
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority1);
+        syncs = engine.getPeriodicSyncs(target1);
         assertEquals(1, syncs.size());
         assertEquals(sync1s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority2);
+        syncs = engine.getPeriodicSyncs(target2);
         assertEquals(1, syncs.size());
         assertEquals(sync2s, syncs.get(0));
 
-        syncs = engine.getPeriodicSyncs(account, 0, authority3);
+        syncs = engine.getPeriodicSyncs(target3);
         assertEquals(1, syncs.size());
         assertEquals(sync3s, syncs.get(0));
     }
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DeviceOwnerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DeviceOwnerTest.java
new file mode 100644
index 0000000..f913b97
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DeviceOwnerTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.devicepolicy;
+
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+/**
+ * Tests for the DeviceOwner object that saves & loads device and policy owner information.
+ * run this test with:
+ *   make -j FrameworksServicesTests
+ *   runtest --path frameworks/base/services/tests/servicestests/ \
+ *       src/com/android/server/devicepolicy/DeviceOwnerTest.java
+ */
+public class DeviceOwnerTest extends AndroidTestCase {
+
+    private ByteArrayInputStream mInputStreamForTest;
+    private ByteArrayOutputStream mOutputStreamForTest = new ByteArrayOutputStream();
+
+    @SmallTest
+    public void testDeviceOwnerOnly() throws Exception {
+        DeviceOwner out = new DeviceOwner(null, mOutputStreamForTest);
+        out.setDeviceOwner("some.device.owner.package", "owner");
+        out.writeOwnerFile();
+
+        mInputStreamForTest = new ByteArrayInputStream(mOutputStreamForTest.toByteArray());
+        DeviceOwner in = new DeviceOwner(mInputStreamForTest, null);
+        in.readOwnerFile();
+
+        assertEquals("some.device.owner.package", in.getDeviceOwnerPackageName());
+        assertEquals("owner", in.getDeviceOwnerName());
+        assertNull(in.getProfileOwnerPackageName(1));
+    }
+
+    @SmallTest
+    public void testProfileOwnerOnly() throws Exception {
+        DeviceOwner out = new DeviceOwner(null, mOutputStreamForTest);
+        out.setProfileOwner("some.profile.owner.package", "some-company", 1);
+        out.writeOwnerFile();
+
+        mInputStreamForTest = new ByteArrayInputStream(mOutputStreamForTest.toByteArray());
+        DeviceOwner in = new DeviceOwner(mInputStreamForTest, null);
+        in.readOwnerFile();
+
+        assertNull(in.getDeviceOwnerPackageName());
+        assertNull(in.getDeviceOwnerName());
+        assertEquals("some.profile.owner.package", in.getProfileOwnerPackageName(1));
+        assertEquals("some-company", in.getProfileOwnerName(1));
+    }
+
+    @SmallTest
+    public void testDeviceAndProfileOwners() throws Exception {
+        DeviceOwner out = new DeviceOwner(null, mOutputStreamForTest);
+        out.setDeviceOwner("some.device.owner.package", "owner");
+        out.setProfileOwner("some.profile.owner.package", "some-company", 1);
+        out.setProfileOwner("some.other.profile.owner", "some-other-company", 2);
+        out.writeOwnerFile();
+
+        mInputStreamForTest = new ByteArrayInputStream(mOutputStreamForTest.toByteArray());
+
+        DeviceOwner in = new DeviceOwner(mInputStreamForTest, null);
+        in.readOwnerFile();
+
+        assertEquals("some.device.owner.package", in.getDeviceOwnerPackageName());
+        assertEquals("owner", in.getDeviceOwnerName());
+        assertEquals("some.profile.owner.package", in.getProfileOwnerPackageName(1));
+        assertEquals("some-company", in.getProfileOwnerName(1));
+        assertEquals("some.other.profile.owner", in.getProfileOwnerPackageName(2));
+        assertEquals("some-other-company", in.getProfileOwnerName(2));
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java b/services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java
new file mode 100644
index 0000000..33f604d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java
@@ -0,0 +1,175 @@
+package com.android.server.location;
+
+import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
+import com.android.server.location.LocationRequestStatistics.PackageStatistics;
+
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+
+/**
+ * Unit tests for {@link LocationRequestStatistics}.
+ */
+public class LocationRequestStatisticsTest extends AndroidTestCase {
+    private static final String PACKAGE1 = "package1";
+    private static final String PACKAGE2 = "package2";
+    private static final String PROVIDER1 = "provider1";
+    private static final String PROVIDER2 = "provider2";
+    private static final long INTERVAL1 = 5000;
+    private static final long INTERVAL2 = 100000;
+
+    private LocationRequestStatistics mStatistics;
+    private long mStartElapsedRealtimeMs;
+
+    @Override
+    public void setUp() {
+        mStatistics = new LocationRequestStatistics();
+        mStartElapsedRealtimeMs = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Tests that adding a single package works correctly.
+     */
+    public void testSinglePackage() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+
+        assertEquals(1, mStatistics.statistics.size());
+        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
+        assertEquals(PACKAGE1, key.packageName);
+        assertEquals(PROVIDER1, key.providerName);
+        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
+        verifyStatisticsTimes(stats);
+        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
+        assertEquals(INTERVAL1, stats.getSlowestIntervalMs());
+        assertTrue(stats.isActive());
+    }
+
+    /**
+     * Tests that adding a single package works correctly when it is stopped and restarted.
+     */
+    public void testSinglePackage_stopAndRestart() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+
+        assertEquals(1, mStatistics.statistics.size());
+        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
+        assertEquals(PACKAGE1, key.packageName);
+        assertEquals(PROVIDER1, key.providerName);
+        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
+        verifyStatisticsTimes(stats);
+        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
+        assertEquals(INTERVAL1, stats.getSlowestIntervalMs());
+        assertTrue(stats.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats.isActive());
+    }
+
+    /**
+     * Tests that adding a single package works correctly when multiple intervals are used.
+     */
+    public void testSinglePackage_multipleIntervals() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL2);
+
+        assertEquals(1, mStatistics.statistics.size());
+        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
+        assertEquals(PACKAGE1, key.packageName);
+        assertEquals(PROVIDER1, key.providerName);
+        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
+        verifyStatisticsTimes(stats);
+        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
+        assertTrue(stats.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertTrue(stats.isActive());
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats.isActive());
+    }
+
+    /**
+     * Tests that adding a single package works correctly when multiple providers are used.
+     */
+    public void testSinglePackage_multipleProviders() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2);
+
+        assertEquals(2, mStatistics.statistics.size());
+        PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
+        PackageStatistics stats1 = mStatistics.statistics.get(key1);
+        verifyStatisticsTimes(stats1);
+        assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
+        assertTrue(stats1.isActive());
+        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
+        PackageStatistics stats2 = mStatistics.statistics.get(key2);
+        verifyStatisticsTimes(stats2);
+        assertEquals(INTERVAL2, stats2.getSlowestIntervalMs());
+        assertEquals(INTERVAL2, stats2.getFastestIntervalMs());
+        assertTrue(stats2.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats1.isActive());
+        assertTrue(stats2.isActive());
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
+        assertFalse(stats1.isActive());
+        assertFalse(stats2.isActive());
+    }
+
+    /**
+     * Tests that adding multiple packages works correctly.
+     */
+    public void testMultiplePackages() {
+        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1);
+        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2);
+        mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1);
+
+        assertEquals(3, mStatistics.statistics.size());
+        PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
+        PackageStatistics stats1 = mStatistics.statistics.get(key1);
+        verifyStatisticsTimes(stats1);
+        assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
+        assertTrue(stats1.isActive());
+
+        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
+        PackageStatistics stats2 = mStatistics.statistics.get(key2);
+        verifyStatisticsTimes(stats2);
+        assertEquals(INTERVAL2, stats2.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats2.getFastestIntervalMs());
+        assertTrue(stats2.isActive());
+
+        PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, PROVIDER1);
+        PackageStatistics stats3 = mStatistics.statistics.get(key3);
+        verifyStatisticsTimes(stats3);
+        assertEquals(INTERVAL1, stats3.getSlowestIntervalMs());
+        assertEquals(INTERVAL1, stats3.getFastestIntervalMs());
+        assertTrue(stats3.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
+        assertFalse(stats1.isActive());
+        assertTrue(stats2.isActive());
+        assertTrue(stats3.isActive());
+
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
+        assertFalse(stats1.isActive());
+        assertTrue(stats2.isActive());
+        assertTrue(stats3.isActive());
+        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
+        assertFalse(stats2.isActive());
+
+        mStatistics.stopRequesting(PACKAGE2, PROVIDER1);
+        assertFalse(stats1.isActive());
+        assertFalse(stats2.isActive());
+        assertFalse(stats3.isActive());
+    }
+
+    private void verifyStatisticsTimes(PackageStatistics stats) {
+        long durationMs = stats.getDurationMs();
+        long timeSinceFirstRequestMs = stats.getTimeSinceFirstRequestMs();
+        long maxDeltaMs = SystemClock.elapsedRealtime() - mStartElapsedRealtimeMs;
+        assertTrue("Duration is too large", durationMs <= maxDeltaMs);
+        assertTrue("Time since first request is too large", timeSinceFirstRequestMs <= maxDeltaMs);
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 76a8d17..502ee18 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -53,6 +53,7 @@
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -297,12 +298,7 @@
     }
 
     private static boolean containsFunction(String functions, String function) {
-        int index = functions.indexOf(function);
-        if (index < 0) return false;
-        if (index > 0 && functions.charAt(index - 1) != ',') return false;
-        int charAfter = index + function.length();
-        if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
-        return true;
+        return Arrays.asList(functions.split(",")).contains(function);
     }
 
     private final class UsbHandler extends Handler {
@@ -720,6 +716,7 @@
                     PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                             intent, 0, null, UserHandle.CURRENT);
                     notification.setLatestEventInfo(mContext, title, message, pi);
+                    notification.visibility = Notification.VISIBILITY_PUBLIC;
                     mNotificationManager.notifyAsUser(null, id, notification,
                             UserHandle.ALL);
                     mUsbNotificationId = id;
@@ -755,6 +752,7 @@
                     PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                             intent, 0, null, UserHandle.CURRENT);
                     notification.setLatestEventInfo(mContext, title, message, pi);
+                    notification.visibility = Notification.VISIBILITY_PUBLIC;
                     mAdbNotificationShown = true;
                     mNotificationManager.notifyAsUser(null, id, notification,
                             UserHandle.ALL);
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index dfaad0b..7ae5460 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -17,6 +17,7 @@
 package com.android.server.usb;
 
 import android.content.Context;
+import android.hardware.usb.UsbConfiguration;
 import android.hardware.usb.UsbConstants;
 import android.hardware.usb.UsbDevice;
 import android.hardware.usb.UsbEndpoint;
@@ -30,6 +31,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashMap;
 
 /**
@@ -48,6 +50,13 @@
     private final Context mContext;
     private final Object mLock = new Object();
 
+    private UsbDevice mNewDevice;
+    private UsbConfiguration mNewConfiguration;
+    private UsbInterface mNewInterface;
+    private ArrayList<UsbConfiguration> mNewConfigurations;
+    private ArrayList<UsbInterface> mNewInterfaces;
+    private ArrayList<UsbEndpoint> mNewEndpoints;
+
     @GuardedBy("mLock")
     private UsbSettingsManager mCurrentSettings;
 
@@ -93,69 +102,103 @@
         return false;
     }
 
-    /* Called from JNI in monitorUsbHostBus() to report new USB devices */
-    private void usbDeviceAdded(String deviceName, int vendorID, int productID,
+    /* Called from JNI in monitorUsbHostBus() to report new USB devices
+       Returns true if successful, in which case the JNI code will continue adding configurations,
+       interfaces and endpoints, and finally call endUsbDeviceAdded after all descriptors
+       have been processed
+     */
+    private boolean beginUsbDeviceAdded(String deviceName, int vendorID, int productID,
             int deviceClass, int deviceSubclass, int deviceProtocol,
-            String manufacturerName, String productName, String serialNumber,
-            /* array of quintuples containing id, class, subclass, protocol
-               and number of endpoints for each interface */
-            int[] interfaceValues,
-           /* array of quadruples containing address, attributes, max packet size
-              and interval for each endpoint */
-            int[] endpointValues) {
+            String manufacturerName, String productName, String serialNumber) {
 
         if (isBlackListed(deviceName) ||
                 isBlackListed(deviceClass, deviceSubclass, deviceProtocol)) {
-            return;
+            return false;
         }
 
         synchronized (mLock) {
             if (mDevices.get(deviceName) != null) {
                 Slog.w(TAG, "device already on mDevices list: " + deviceName);
-                return;
+                return false;
             }
 
-            int numInterfaces = interfaceValues.length / 5;
-            Parcelable[] interfaces = new UsbInterface[numInterfaces];
-            try {
-                // repackage interfaceValues as an array of UsbInterface
-                int intf, endp, ival = 0, eval = 0;
-                for (intf = 0; intf < numInterfaces; intf++) {
-                    int interfaceId = interfaceValues[ival++];
-                    int interfaceClass = interfaceValues[ival++];
-                    int interfaceSubclass = interfaceValues[ival++];
-                    int interfaceProtocol = interfaceValues[ival++];
-                    int numEndpoints = interfaceValues[ival++];
-
-                    Parcelable[] endpoints = new UsbEndpoint[numEndpoints];
-                    for (endp = 0; endp < numEndpoints; endp++) {
-                        int address = endpointValues[eval++];
-                        int attributes = endpointValues[eval++];
-                        int maxPacketSize = endpointValues[eval++];
-                        int interval = endpointValues[eval++];
-                        endpoints[endp] = new UsbEndpoint(address, attributes,
-                                maxPacketSize, interval);
-                    }
-
-                    // don't allow if any interfaces are blacklisted
-                    if (isBlackListed(interfaceClass, interfaceSubclass, interfaceProtocol)) {
-                        return;
-                    }
-                    interfaces[intf] = new UsbInterface(interfaceId, interfaceClass,
-                            interfaceSubclass, interfaceProtocol, endpoints);
-                }
-            } catch (Exception e) {
-                // beware of index out of bound exceptions, which might happen if
-                // a device does not set bNumEndpoints correctly
-                Slog.e(TAG, "error parsing USB descriptors", e);
-                return;
+            if (mNewDevice != null) {
+                Slog.e(TAG, "mNewDevice is not null in endUsbDeviceAdded");
+                return false;
             }
 
-            UsbDevice device = new UsbDevice(deviceName, vendorID, productID,
+            mNewDevice = new UsbDevice(deviceName, vendorID, productID,
                     deviceClass, deviceSubclass, deviceProtocol,
-                    manufacturerName, productName, serialNumber, interfaces);
-            mDevices.put(deviceName, device);
-            getCurrentSettings().deviceAttached(device);
+                    manufacturerName, productName, serialNumber);
+
+            mNewConfigurations = new ArrayList<UsbConfiguration>();
+            mNewInterfaces = new ArrayList<UsbInterface>();
+            mNewEndpoints = new ArrayList<UsbEndpoint>();
+        }
+        return true;
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to report new USB configuration for the device
+       currently being added.  Returns true if successful, false in case of error.
+     */
+    private void addUsbConfiguration(int id, String name, int attributes, int maxPower) {
+        if (mNewConfiguration != null) {
+            mNewConfiguration.setInterfaces(
+                    mNewInterfaces.toArray(new UsbInterface[mNewInterfaces.size()]));
+            mNewInterfaces.clear();
+        }
+
+        mNewConfiguration = new UsbConfiguration(id, name, attributes, maxPower);
+        mNewConfigurations.add(mNewConfiguration);
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to report new USB interface for the device
+       currently being added.  Returns true if successful, false in case of error.
+     */
+    private void addUsbInterface(int id, String name, int altSetting,
+            int Class, int subClass, int protocol) {
+        if (mNewInterface != null) {
+            mNewInterface.setEndpoints(
+                    mNewEndpoints.toArray(new UsbEndpoint[mNewEndpoints.size()]));
+            mNewEndpoints.clear();
+        }
+
+        mNewInterface = new UsbInterface(id, altSetting, name, Class, subClass, protocol);
+        mNewInterfaces.add(mNewInterface);
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to report new USB endpoint for the device
+       currently being added.  Returns true if successful, false in case of error.
+     */
+    private void addUsbEndpoint(int address, int attributes, int maxPacketSize, int interval) {
+        mNewEndpoints.add(new UsbEndpoint(address, attributes, maxPacketSize, interval));
+    }
+
+    /* Called from JNI in monitorUsbHostBus() to finish adding a new device */
+    private void endUsbDeviceAdded() {
+        if (mNewInterface != null) {
+            mNewInterface.setEndpoints(
+                    mNewEndpoints.toArray(new UsbEndpoint[mNewEndpoints.size()]));
+        }
+        if (mNewConfiguration != null) {
+            mNewConfiguration.setInterfaces(
+                    mNewInterfaces.toArray(new UsbInterface[mNewInterfaces.size()]));
+        }
+
+        synchronized (mLock) {
+            if (mNewDevice != null) {
+                mNewDevice.setConfigurations(
+                        mNewConfigurations.toArray(new UsbConfiguration[mNewConfigurations.size()]));
+                mDevices.put(mNewDevice.getDeviceName(), mNewDevice);
+                Slog.d(TAG, "Added device " + mNewDevice);
+                getCurrentSettings().deviceAttached(mNewDevice);
+            } else {
+                Slog.e(TAG, "mNewDevice is null in endUsbDeviceAdded");
+            }
+            mNewDevice = null;
+            mNewConfigurations = null;
+            mNewInterfaces = null;
+            mNewEndpoints = null;
         }
     }
 
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index ff4857b..37b5c51 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -27,6 +27,7 @@
 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.XmlResourceParser;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbDevice;
@@ -73,6 +74,7 @@
 
     private final UserHandle mUser;
     private final AtomicFile mSettingsFile;
+    private final boolean mDisablePermissionDialogs;
 
     private final Context mContext;
     private final Context mUserContext;
@@ -510,6 +512,9 @@
                 Environment.getUserSystemDirectory(user.getIdentifier()),
                 "usb_device_manager.xml"));
 
+        mDisablePermissionDialogs = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_disableUsbPermissionDialogs);
+
         synchronized (mLock) {
             if (UserHandle.OWNER.equals(user)) {
                 upgradeSingleUserLocked();
@@ -815,6 +820,14 @@
                     (rInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                 defaultRI = rInfo;
             }
+
+            if (mDisablePermissionDialogs) {
+                // bypass dialog and launch the only matching activity
+                rInfo = matches.get(0);
+                if (rInfo.activityInfo != null) {
+                    defaultPackage = rInfo.activityInfo.packageName;
+                }
+            }
         }
 
         if (defaultRI == null && defaultPackage != null) {
@@ -970,7 +983,7 @@
     public boolean hasPermission(UsbDevice device) {
         synchronized (mLock) {
             int uid = Binder.getCallingUid();
-            if (uid == Process.SYSTEM_UID) {
+            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
                 return true;
             }
             SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());
@@ -984,7 +997,7 @@
     public boolean hasPermission(UsbAccessory accessory) {
         synchronized (mLock) {
             int uid = Binder.getCallingUid();
-            if (uid == Process.SYSTEM_UID) {
+            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
                 return true;
             }
             SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index bfa0942..b5e4eef 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -76,7 +76,7 @@
         return mRegistered;
     }
     /** @hide */
-    public void setRegisterd(boolean registered) {
+    public void setRegistered(boolean registered) {
         mRegistered = registered;
     }
 
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index 42c2aff..f9a222f 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -19,9 +19,6 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.Settings;
-
 
 import android.telephony.cdma.CdmaCellLocation;
 import android.telephony.gsm.GsmCellLocation;
diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java
index 3b470fc..9c23f78 100644
--- a/telephony/java/android/telephony/CellSignalStrength.java
+++ b/telephony/java/android/telephony/CellSignalStrength.java
@@ -16,9 +16,6 @@
 
 package android.telephony;
 
-import android.os.Parcel;
-import android.os.Parcelable;
-
 /**
  * Abstract base class for cell phone signal strength related information.
  */
diff --git a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
index 983c349..438b572 100644
--- a/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
+++ b/telephony/java/android/telephony/PhoneNumberFormattingTextWatcher.java
@@ -65,8 +65,6 @@
      *
      * @param countryCode the ISO 3166-1 two-letter country code that indicates the country/region
      * where the phone number is being entered.
-     *
-     * @hide
      */
     public PhoneNumberFormattingTextWatcher(String countryCode) {
         if (countryCode == null) throw new IllegalArgumentException();
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index e3a1aa6..c79e9bf 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1143,6 +1143,8 @@
      * @param source The phone number to format
      * @return A locally acceptable formatting of the input, or the raw input if
      *  formatting rules aren't known for the number
+     *
+     * @deprecated Use {@link #formatNumber(String phoneNumber, String defaultCountryIso)} instead
      */
     public static String formatNumber(String source) {
         SpannableStringBuilder text = new SpannableStringBuilder(source);
@@ -1159,7 +1161,8 @@
      * not begin with +[country_code]
      * @return The phone number formatted with the given formatting type.
      *
-     * @hide TODO: Should be unhidden.
+     * @hide
+     * @deprecated Use {@link #formatNumber(String phoneNumber, String defaultCountryIso)} instead
      */
     public static String formatNumber(String source, int defaultFormattingType) {
         SpannableStringBuilder text = new SpannableStringBuilder(source);
@@ -1173,6 +1176,8 @@
      * @param locale The locale of interest, usually {@link Locale#getDefault()}
      * @return The formatting type for the given locale, or FORMAT_UNKNOWN if the formatting
      * rules are not known for the given locale
+     *
+     * @deprecated Use {@link #formatNumber(String phoneNumber, String defaultCountryIso)} instead
      */
     public static int getFormatTypeForLocale(Locale locale) {
         String country = locale.getCountry();
@@ -1187,6 +1192,8 @@
      * @param text The number to be formatted, will be modified with the formatting
      * @param defaultFormattingType The default formatting rules to apply if the number does
      * not begin with +[country_code]
+     *
+     * @deprecated Use {@link #formatNumber(String phoneNumber, String defaultCountryIso)} instead
      */
     public static void formatNumber(Editable text, int defaultFormattingType) {
         int formatType = defaultFormattingType;
@@ -1233,6 +1240,8 @@
      * </code></p>
      *
      * @param text the number to be formatted, will be modified with the formatting
+     *
+     * @deprecated Use {@link #formatNumber(String phoneNumber, String defaultCountryIso)} instead
      */
     public static void formatNanpNumber(Editable text) {
         int length = text.length();
@@ -1346,6 +1355,8 @@
      *
      * @param text the number to be formatted, will be modified with
      * the formatting
+     *
+     * @deprecated Use {@link #formatNumber(String phoneNumber, String defaultCountryIso)} instead
      */
     public static void formatJapaneseNumber(Editable text) {
         JapanesePhoneNumberFormatter.format(text);
@@ -1382,8 +1393,6 @@
      *            the ISO 3166-1 two letters country code
      * @return the E.164 representation, or null if the given phone number is
      *         not valid.
-     *
-     * @hide
      */
     public static String formatNumberToE164(String phoneNumber, String defaultCountryIso) {
         PhoneNumberUtil util = PhoneNumberUtil.getInstance();
@@ -1410,8 +1419,6 @@
      *            the ISO 3166-1 two letters country code whose convention will
      *            be used if the given number doesn't have the country code.
      * @return the formatted number, or null if the given number is not valid.
-     *
-     * @hide
      */
     public static String formatNumber(String phoneNumber, String defaultCountryIso) {
         // Do not attempt to format numbers that start with a hash or star symbol.
@@ -1446,8 +1453,6 @@
      *            contains IDD.
      * @return the formatted number if the given number has been formatted,
      *            otherwise, return the given number.
-     *
-     * @hide
      */
     public static String formatNumber(
             String phoneNumber, String phoneNumberE164, String defaultCountryIso) {
@@ -1483,11 +1488,8 @@
      * the given number has keypad letters, the letters will be converted to
      * digits first.
      *
-     * @param phoneNumber
-     *            the number to be normalized.
+     * @param phoneNumber the number to be normalized.
      * @return the normalized number.
-     *
-     * @hide
      */
     public static String normalizeNumber(String phoneNumber) {
         StringBuilder sb = new StringBuilder();
@@ -1508,12 +1510,10 @@
     }
 
     /**
-     * Replace arabic/unicode digits with decimal digits.
-     * @param number
-     *            the number to be normalized.
-     * @return the replaced number.
+     * Replaces all unicode(e.g. Arabic, Persian) digits with their decimal digit equivalents.
      *
-     * @hide
+     * @param number the number to perform the replacement on.
+     * @return the replaced number.
      */
     public static String replaceUnicodeDigits(String number) {
         StringBuilder normalizedDigits = new StringBuilder(number.length());
@@ -1737,16 +1737,12 @@
     }
 
     /**
-     * Checks if a given number is an emergency number for the country that the user is in. The
-     * current country is determined using the CountryDetector.
+     * Checks if a given number is an emergency number for the country that the user is in.
      *
      * @param number the number to look up.
      * @param context the specific context which the number should be checked against
-     * @return true if the specified number is an emergency number for a local country, based on the
-     *              CountryDetector.
-     *
-     * @see android.location.CountryDetector
-     * @hide
+     * @return true if the specified number is an emergency number for the country the user
+     * is currently in.
      */
     public static boolean isLocalEmergencyNumber(String number, Context context) {
         return isLocalEmergencyNumberInternal(number,
@@ -1825,7 +1821,6 @@
      * @return true if the number is in the list of voicemail. False
      * otherwise, including if the caller does not have the permission
      * to read the VM number.
-     * @hide TODO: pending API Council approval
      */
     public static boolean isVoiceMailNumber(String number) {
         String vmNumber;
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 538548d..bb3f132 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -299,7 +299,7 @@
      * @param otaspMode is integer <code>OTASP_UNKNOWN=1<code>
      *   means the value is currently unknown and the system should wait until
      *   <code>OTASP_NEEDED=2<code> or <code>OTASP_NOT_NEEDED=3<code> is received before
-     *   making the decisision to perform OTASP or not.
+     *   making the decision to perform OTASP or not.
      *
      * @hide
      */
diff --git a/telephony/java/android/telephony/Rlog.java b/telephony/java/android/telephony/Rlog.java
index 9ac7bda..2a7f7af 100644
--- a/telephony/java/android/telephony/Rlog.java
+++ b/telephony/java/android/telephony/Rlog.java
@@ -16,13 +16,8 @@
 
 package android.telephony;
 
-import com.android.internal.os.RuntimeInit;
-
 import android.util.Log;
 
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
 /**
  * A class to log strings to the RADIO LOG.
  *
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ea22bc4..ec4d574 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -23,7 +23,6 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemProperties;
-import android.telephony.Rlog;
 
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
@@ -694,7 +693,7 @@
         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:
+        case RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA:
             return PhoneConstants.PHONE_TYPE_GSM;
 
         // Use CDMA Phone for the global mode including CDMA
@@ -1519,7 +1518,7 @@
      * At registration, and when a specified telephony state
      * changes, the telephony manager invokes the appropriate
      * callback method on the listener object and passes the
-     * current (udpated) values.
+     * current (updated) values.
      * <p>
      * To unregister a listener, pass the listener object and set the
      * events argument to
@@ -1700,4 +1699,183 @@
         return mContext.getResources().getString(
                 com.android.internal.R.string.config_mms_user_agent_profile_url);
     }
+
+    /**
+     * Opens a logical channel to the ICC card.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHO command.
+     *
+     * @param AID Application id. See ETSI 102.221 and 101.220.
+     * @return The logical channel id which is negative on error.
+     */
+    public int iccOpenLogicalChannel(String AID) {
+        try {
+          return getITelephony().iccOpenLogicalChannel(AID);
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return -1;
+    }
+
+    /**
+     * Closes a previously opened logical channel to the ICC card.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHC command.
+     *
+     * @param channel is the channel id to be closed as retruned by a successful
+     *            iccOpenLogicalChannel.
+     * @return true if the channel was closed successfully.
+     */
+    public boolean iccCloseLogicalChannel(int channel) {
+        try {
+          return getITelephony().iccCloseLogicalChannel(channel);
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return false;
+    }
+
+    /**
+     * Transmit an APDU to the ICC card over a logical channel.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CGLA command.
+     *
+     * @param channel is the channel id to be closed as returned by a successful
+     *            iccOpenLogicalChannel.
+     * @param cla Class of the APDU command.
+     * @param instruction Instruction of the APDU command.
+     * @param p1 P1 value of the APDU command.
+     * @param p2 P2 value of the APDU command.
+     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
+     *            is sent to the SIM.
+     * @param data Data to be sent with the APDU.
+     * @return The APDU response from the ICC card with the status appended at
+     *            the end. If an error occurs, an empty string is returned.
+     */
+    public String iccTransmitApduLogicalChannel(int channel, int cla,
+            int instruction, int p1, int p2, int p3, String data) {
+        try {
+          return getITelephony().iccTransmitApduLogicalChannel(channel, cla,
+                  instruction, p1, p2, p3, data);
+        } catch (RemoteException ex) {
+        } catch (NullPointerException ex) {
+        }
+        return "";
+    }
+
+    /**
+     * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @return the NV item as a String, or null on any failure.
+     * @hide
+     */
+    public String nvReadItem(int itemID) {
+        try {
+            return getITelephony().nvReadItem(itemID);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvReadItem RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvReadItem NPE", ex);
+        }
+        return "";
+    }
+
+
+    /**
+     * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @param itemValue the value to write, as a String.
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean nvWriteItem(int itemID, String itemValue) {
+        try {
+            return getITelephony().nvWriteItem(itemID, itemValue);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvWriteItem RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvWriteItem NPE", ex);
+        }
+        return false;
+    }
+
+    /**
+     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param preferredRoamingList byte array containing the new PRL.
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
+        try {
+            return getITelephony().nvWriteCdmaPrl(preferredRoamingList);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvWriteCdmaPrl RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvWriteCdmaPrl NPE", ex);
+        }
+        return false;
+    }
+
+    /**
+     * Perform the specified type of NV config reset. The radio will be taken offline
+     * and the device must be rebooted after the operation. Used for device
+     * configuration by some CDMA operators.
+     *
+     * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean nvResetConfig(int resetType) {
+        try {
+            return getITelephony().nvResetConfig(resetType);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "nvResetConfig RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "nvResetConfig NPE", ex);
+        }
+        return false;
+    }
+
+    /**
+     * Get the preferred network type.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @return the preferred network type, defined in RILConstants.java.
+     * @hide
+     */
+    public int getPreferredNetworkType() {
+        try {
+            return getITelephony().getPreferredNetworkType();
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "getPreferredNetworkType RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "getPreferredNetworkType NPE", ex);
+        }
+        return -1;
+    }
+
+    /**
+     * Set the preferred network type.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param networkType the preferred network type, defined in RILConstants.java.
+     * @return true on success; false on any failure.
+     * @hide
+     */
+    public boolean setPreferredNetworkType(int networkType) {
+        try {
+            return getITelephony().setPreferredNetworkType(networkType);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "setPreferredNetworkType NPE", ex);
+        }
+        return false;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index c63be91..74f73b5 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -24,7 +24,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.SystemProperties;
 import android.provider.ContactsContract.CommonDataKinds.SipAddress;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.PhoneLookup;
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 7bd2c84..7c338ac 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -324,5 +324,100 @@
      * Sets minimum time in milli-seconds between onCellInfoChanged
      */
     void setCellInfoListRate(int rateInMillis);
-}
 
+    /**
+     * Opens a logical channel to the ICC card.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHO command.
+     *
+     * @param AID Application id. See ETSI 102.221 and 101.220.
+     * @return The logical channel id which is set to -1 on error.
+     */
+    int iccOpenLogicalChannel(String AID);
+
+    /**
+     * Closes a previously opened logical channel to the ICC card.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CCHC command.
+     *
+     * @param channel is the channel id to be closed as retruned by a
+     *            successful iccOpenLogicalChannel.
+     * @return true if the channel was closed successfully.
+     */
+    boolean iccCloseLogicalChannel(int channel);
+
+    /**
+     * Transmit an APDU to the ICC card over a logical channel.
+     *
+     * Input parameters equivalent to TS 27.007 AT+CGLA command.
+     *
+     * @param channel is the channel id to be closed as retruned by a
+     *            successful iccOpenLogicalChannel.
+     * @param cla Class of the APDU command.
+     * @param instruction Instruction of the APDU command.
+     * @param p1 P1 value of the APDU command.
+     * @param p2 P2 value of the APDU command.
+     * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
+     *            is sent to the SIM.
+     * @param data Data to be sent with the APDU.
+     * @return The APDU response from the ICC card with the status appended at
+     *            the end. If an error occurs, an empty string is returned.
+     */
+    String iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
+            int p1, int p2, int p3, String data);
+
+    /**
+     * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @return the NV item as a String, or null on any failure.
+     */
+    String nvReadItem(int itemID);
+
+    /**
+     * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param itemID the ID of the item to read.
+     * @param itemValue the value to write, as a String.
+     * @return true on success; false on any failure.
+     */
+    boolean nvWriteItem(int itemID, String itemValue);
+
+    /**
+     * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param preferredRoamingList byte array containing the new PRL.
+     * @return true on success; false on any failure.
+     */
+    boolean nvWriteCdmaPrl(in byte[] preferredRoamingList);
+
+    /**
+     * Perform the specified type of NV config reset. The radio will be taken offline
+     * and the device must be rebooted after the operation. Used for device
+     * configuration by some CDMA operators.
+     *
+     * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset).
+     * @return true on success; false on any failure.
+     */
+    boolean nvResetConfig(int resetType);
+
+    /**
+     * Get the preferred network type.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @return the preferred network type, defined in RILConstants.java.
+     */
+    int getPreferredNetworkType();
+
+    /**
+     * Set the preferred network type.
+     * Used for device configuration by some CDMA operators.
+     *
+     * @param networkType the preferred network type, defined in RILConstants.java.
+     * @return true on success; false on any failure.
+     */
+    boolean setPreferredNetworkType(int networkType);
+}
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index 1fed417d..8c42d25 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -63,11 +63,11 @@
     public static final int LTE_ON_CDMA_FALSE = RILConstants.LTE_ON_CDMA_FALSE;
     public static final int LTE_ON_CDMA_TRUE = RILConstants.LTE_ON_CDMA_TRUE;
 
-    // Number presentation type for caller id display (From internal/Conneciton.java)
-    public static int PRESENTATION_ALLOWED = 1;    // normal
-    public static int PRESENTATION_RESTRICTED = 2; // block by user
-    public static int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
-    public static int PRESENTATION_PAYPHONE = 4;   // show pay phone info
+    // Number presentation type for caller id display (From internal/Connection.java)
+    public static final int PRESENTATION_ALLOWED = 1;    // normal
+    public static final int PRESENTATION_RESTRICTED = 2; // block by user
+    public static final int PRESENTATION_UNKNOWN = 3;    // no specified or unknown by network
+    public static final int PRESENTATION_PAYPHONE = 4;   // show pay phone info
 
 
     public static final String PHONE_NAME_KEY = "phoneName";
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 8e445d9..d338857 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -72,7 +72,7 @@
                                             AVAILABLE Application Settings menu*/
     int NETWORK_MODE_LTE_CDMA_EVDO  = 8; /* LTE, CDMA and EvDo */
     int NETWORK_MODE_LTE_GSM_WCDMA  = 9; /* LTE, GSM/WCDMA */
-    int NETWORK_MODE_LTE_CMDA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
+    int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
     int NETWORK_MODE_LTE_ONLY       = 11; /* LTE Only mode. */
     int NETWORK_MODE_LTE_WCDMA      = 12; /* LTE/WCDMA */
     int PREFERRED_NETWORK_MODE      = NETWORK_MODE_WCDMA_PREF;
@@ -114,6 +114,11 @@
     int DEACTIVATE_REASON_RADIO_OFF = 1;
     int DEACTIVATE_REASON_PDP_RESET = 2;
 
+    /* NV config radio reset types. */
+    int NV_CONFIG_RELOAD_RESET = 1;
+    int NV_CONFIG_ERASE_RESET = 2;
+    int NV_CONFIG_FACTORY_RESET = 3;
+
 /*
 cat include/telephony/ril.h | \
    egrep '^#define' | \
@@ -271,6 +276,12 @@
     int RIL_REQUEST_SIM_OPEN_CHANNEL = 115;
     int RIL_REQUEST_SIM_CLOSE_CHANNEL = 116;
     int RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL = 117;
+    int RIL_REQUEST_NV_READ_ITEM = 118;
+    int RIL_REQUEST_NV_WRITE_ITEM = 119;
+    int RIL_REQUEST_NV_WRITE_CDMA_PRL = 120;
+    int RIL_REQUEST_NV_RESET_CONFIG = 121;
+    int RIL_REQUEST_SET_RADIO_MODE = 122;
+
     int RIL_UNSOL_RESPONSE_BASE = 1000;
     int RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED = 1000;
     int RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED = 1001;
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index a7baf1c..9ad2d42 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -125,16 +125,14 @@
      * Broadcast Action: The data connection state has changed for any one of the
      * phone's mobile data connections (eg, default, MMS or GPS specific connection).
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>phoneName</em> - A string version of the phone name.</li>
-     *   <li><em>state</em> - One of <code>"CONNECTED"</code>
-     *      <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li>
-     *   <li><em>apn</em> - A string that is the APN associated with this
-     *      connection.</li>
-     *   <li><em>apnType</em> - A string array of APN types associated with
-     *      this connection.  The APN type <code>"*"</code> is a special
-     *      type that means this APN services all types.</li>
-     * </ul>
+     * <dl>
+     *   <dt>phoneName</dt><dd>A string version of the phone name.</dd>
+     *   <dt>state</dt><dd>One of {@code CONNECTED}, {@code CONNECTING},
+     *      or {@code DISCONNECTED}.</dd>
+     *   <dt>apn</dt><dd>A string that is the APN associated with this connection.</dd>
+     *   <dt>apnType</dt><dd>A string array of APN types associated with this connection.
+     *      The APN type {@code *} is a special type that means this APN services all types.</dd>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -149,16 +147,14 @@
      * Broadcast Action: Occurs when a data connection connects to a provisioning apn
      * and is broadcast by the low level data connection code.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>apn</em> - A string that is the APN associated with this
-     *      connection.</li>
-     *   <li><em>apnType</em> - A string array of APN types associated with
-     *      this connection.  The APN type <code>"*"</code> is a special
-     *      type that means this APN services all types.</li>
-     *   <li><em>linkProperties</em> - The <code>LinkProperties</code> for this APN</li>
-     *   <li><em>linkCapabilities</em> - The <code>linkCapabilities</code> for this APN</li>
-     *   <li><em>iface</em> - A string that is the name of the interface</li>
-     * </ul>
+     * <dl>
+     *   <dt>apn</dt><dd>A string that is the APN associated with this connection.</dd>
+     *   <dt>apnType</dt><dd>A string array of APN types associated with this connection.
+     *      The APN type {@code *} is a special type that means this APN services all types.</dd>
+     *   <dt>linkProperties</dt><dd>{@code LinkProperties} for this APN.</dd>
+     *   <dt>linkCapabilities</dt><dd>The {@code LinkCapabilities} for this APN.</dd>
+     *   <dt>iface</dt><dd>A string that is the name of the interface.</dd>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -172,12 +168,11 @@
     /**
      * Broadcast Action: An attempt to establish a data connection has failed.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>phoneName</em> &mdash A string version of the phone name.</li>
-     *   <li><em>state</em> &mdash; One of <code>"CONNECTED"</code>
-     *      <code>"CONNECTING"</code> or <code>"DISCONNNECTED"</code></li>
-     * <li><em>reason</em> &mdash; A string indicating the reason for the failure, if available</li>
-     * </ul>
+     * <dl>
+     *   <dt>phoneName</dt><dd>A string version of the phone name.</dd>
+     *   <dt>state</dt><dd>One of {@code CONNECTED}, {@code CONNECTING}, or {code DISCONNECTED}.</dd>
+     *   <dt>reason</dt><dd>A string indicating the reason for the failure, if available.</dd>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -192,16 +187,23 @@
     /**
      * Broadcast Action: The sim card state has changed.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>phoneName</em> - A string version of the phone name.</li>
-     *   <li><em>ss</em> - The sim state.  One of
-     *   <code>"ABSENT"</code> <code>"LOCKED"</code>
-     *   <code>"READY"</code> <code>"ISMI"</code> <code>"LOADED"</code> </li>
-     *   <li><em>reason</em> - The reason while ss is LOCKED, otherwise is null
-     *   <code>"PIN"</code> locked on PIN1
-     *   <code>"PUK"</code> locked on PUK1
-     *   <code>"NETWORK"</code> locked on Network Personalization </li>
-     * </ul>
+     * <dl>
+     *   <dt>phoneName</dt><dd>A string version of the phone name.</dd>
+     *   <dt>ss</dt><dd>The sim state. One of:
+     *     <dl>
+     *       <dt>{@code ABSENT}</dt><dd>SIM card not found</dd>
+     *       <dt>{@code LOCKED}</dt><dd>SIM card locked (see {@code reason})</dd>
+     *       <dt>{@code READY}</dt><dd>SIM card ready</dd>
+     *       <dt>{@code IMSI}</dt><dd>FIXME: what is this state?</dd>
+     *       <dt>{@code LOADED}</dt><dd>SIM card data loaded</dd>
+     *     </dl></dd>
+     *   <dt>reason</dt><dd>The reason why ss is {@code LOCKED}; null otherwise.</dd>
+     *   <dl>
+     *       <dt>{@code PIN}</dt><dd>locked on PIN1</dd>
+     *       <dt>{@code PUK}</dt><dd>locked on PUK1</dd>
+     *       <dt>{@code NETWORK}</dt><dd>locked on network personalization</dd>
+     *   </dl>
+     * </dl>
      *
      * <p class="note">
      * Requires the READ_PHONE_STATE permission.
@@ -272,31 +274,30 @@
     /**
      * 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>
+     * string of the form: {@code android.intent.category.MCCMNC_310260}
      */
     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
-     * of the form *#*#<code>#*#*. The intent will have the data URI:</p>
+     * of the form {@code *#*#<code>#*#*}. The intent will have the data URI:
      *
-     * <p><code>android_secret_code://&lt;code&gt;</code></p>
+     * {@code android_secret_code://<code>}
      */
-    public static final String SECRET_CODE_ACTION =
-            "android.provider.Telephony.SECRET_CODE";
+    public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE";
 
     /**
      * Broadcast Action: The Service Provider string(s) have been updated.  Activities or
      * services that use these strings should update their display.
      * The intent will have the following extra values:</p>
-     * <ul>
-     *   <li><em>showPlmn</em> - Boolean that indicates whether the PLMN should be shown.</li>
-     *   <li><em>plmn</em> - The operator name of the registered network, as a string.</li>
-     *   <li><em>showSpn</em> - Boolean that indicates whether the SPN should be shown.</li>
-     *   <li><em>spn</em> - The service provider name, as a string.</li>
-     * </ul>
+     *
+     * <dl>
+     *   <dt>showPlmn</dt><dd>Boolean that indicates whether the PLMN should be shown.</dd>
+     *   <dt>plmn</dt><dd>The operator name of the registered network, as a string.</dd>
+     *   <dt>showSpn</dt><dd>Boolean that indicates whether the SPN should be shown.</dd>
+     *   <dt>spn</dt><dd>The service provider name, as a string.</dd>
+     * </dl>
+     *
      * Note that <em>showPlmn</em> may indicate that <em>plmn</em> should be displayed, even
      * though the value for <em>plmn</em> is null.  This can happen, for example, if the phone
      * has not registered to a network yet.  In this case the receiver may substitute an
@@ -305,8 +306,7 @@
      * It is recommended to display <em>plmn</em> before / above <em>spn</em> if
      * both are displayed.
      *
-     * <p>Note this is a protected intent that can only be sent
-     * by the system.
+     * <p>Note: this is a protected intent that can only be sent by the system.
      */
     public static final String SPN_STRINGS_UPDATED_ACTION =
             "android.provider.Telephony.SPN_STRINGS_UPDATED";
diff --git a/test-runner/src/android/test/ActivityInstrumentationTestCase.java b/test-runner/src/android/test/ActivityInstrumentationTestCase.java
index d12ff6f..a59ee35 100644
--- a/test-runner/src/android/test/ActivityInstrumentationTestCase.java
+++ b/test-runner/src/android/test/ActivityInstrumentationTestCase.java
@@ -18,8 +18,6 @@
 
 import android.app.Activity;
 
-import java.lang.reflect.Field;
-
 /**
  * This class provides functional testing of a single activity.  The activity under test will
  * be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity())
diff --git a/test-runner/src/android/test/ApplicationTestCase.java b/test-runner/src/android/test/ApplicationTestCase.java
index ae5fa4d..f093181 100644
--- a/test-runner/src/android/test/ApplicationTestCase.java
+++ b/test-runner/src/android/test/ApplicationTestCase.java
@@ -16,8 +16,6 @@
 
 package android.test;
 
-import java.lang.reflect.Field;
-
 import android.app.Application;
 import android.app.Instrumentation;
 import android.content.Context;
diff --git a/test-runner/src/android/test/InstrumentationUtils.java b/test-runner/src/android/test/InstrumentationUtils.java
index 4c59097..1a7002a 100644
--- a/test-runner/src/android/test/InstrumentationUtils.java
+++ b/test-runner/src/android/test/InstrumentationUtils.java
@@ -16,8 +16,6 @@
 
 package android.test;
 
-import java.lang.reflect.Field;
-
 /**
  * 
  * The InstrumentationUtils class has all the utility functions needed for
diff --git a/test-runner/src/android/test/IsolatedContext.java b/test-runner/src/android/test/IsolatedContext.java
index bc00f68..f971b5d 100644
--- a/test-runner/src/android/test/IsolatedContext.java
+++ b/test-runner/src/android/test/IsolatedContext.java
@@ -39,8 +39,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeoutException;
 import java.util.List;
 
 
diff --git a/test-runner/src/android/test/LaunchPerformanceBase.java b/test-runner/src/android/test/LaunchPerformanceBase.java
index c324446..d423e62 100644
--- a/test-runner/src/android/test/LaunchPerformanceBase.java
+++ b/test-runner/src/android/test/LaunchPerformanceBase.java
@@ -19,13 +19,6 @@
 import android.app.Instrumentation;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.Debug;
-import android.os.Process;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-
-import java.util.ArrayList;
 
 
 /**
diff --git a/test-runner/src/android/test/MoreAsserts.java b/test-runner/src/android/test/MoreAsserts.java
index 83cc420..fb0faba 100644
--- a/test-runner/src/android/test/MoreAsserts.java
+++ b/test-runner/src/android/test/MoreAsserts.java
@@ -16,7 +16,6 @@
 
 package android.test;
 
-import com.google.android.collect.Lists;
 import junit.framework.Assert;
 
 import java.util.Arrays;
diff --git a/test-runner/src/android/test/ServiceTestCase.java b/test-runner/src/android/test/ServiceTestCase.java
index d8ced38..ba20c09 100644
--- a/test-runner/src/android/test/ServiceTestCase.java
+++ b/test-runner/src/android/test/ServiceTestCase.java
@@ -18,14 +18,11 @@
 
 import android.app.Application;
 import android.app.Service;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.os.IBinder;
-import android.os.RemoteException;
 import android.test.mock.MockApplication;
 
-import java.lang.reflect.Field;
 import java.util.Random;
 
 /**
@@ -263,6 +260,7 @@
         }
         if (mServiceCreated) {
             mService.onDestroy();
+            mServiceCreated = false;
         }
     }
 
diff --git a/test-runner/src/android/test/SingleLaunchActivityTestCase.java b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
index 79c554a..72c93ce 100644
--- a/test-runner/src/android/test/SingleLaunchActivityTestCase.java
+++ b/test-runner/src/android/test/SingleLaunchActivityTestCase.java
@@ -17,8 +17,6 @@
 package android.test;
 
 import android.app.Activity;
-import android.view.IWindowManager;
-import android.os.ServiceManager;
 
 /**
  * If you would like to test a single activity with an
diff --git a/test-runner/src/android/test/mock/MockCursor.java b/test-runner/src/android/test/mock/MockCursor.java
index 5b8a4f4..a37c6eb 100644
--- a/test-runner/src/android/test/mock/MockCursor.java
+++ b/test-runner/src/android/test/mock/MockCursor.java
@@ -24,8 +24,6 @@
 import android.net.Uri;
 import android.os.Bundle;
 
-import java.util.Map;
-
 /**
  * <P>
  * A mock {@link android.database.Cursor} class that isolates the test code from real
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index c1305bc..118cba4 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -40,13 +40,10 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.VerificationParams;
 import android.content.pm.VerifierDeviceIdentity;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 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;
diff --git a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
index 28f7216..8c89489 100644
--- a/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
+++ b/test-runner/src/android/test/suitebuilder/TestSuiteBuilder.java
@@ -29,8 +29,6 @@
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
 
-import java.lang.reflect.InvocationTargetException;
-import java.util.Enumeration;
 import java.util.List;
 import java.util.Set;
 import java.util.HashSet;
diff --git a/test-runner/src/junit/runner/FailureDetailView.java b/test-runner/src/junit/runner/FailureDetailView.java
index 1b8365a..c846191 100644
--- a/test-runner/src/junit/runner/FailureDetailView.java
+++ b/test-runner/src/junit/runner/FailureDetailView.java
@@ -12,7 +12,7 @@
 public interface FailureDetailView {
     // The following definition was removed for compatibility with Android
     // libraries.
-    // 	/**
+    //  /**
     //   * Returns the component used to present the TraceView
     //   */
     //  public Component getComponent();
diff --git a/test-runner/src/junit/runner/LoadingTestCollector.java b/test-runner/src/junit/runner/LoadingTestCollector.java
index 489d9d6..9101900 100644
--- a/test-runner/src/junit/runner/LoadingTestCollector.java
+++ b/test-runner/src/junit/runner/LoadingTestCollector.java
@@ -1,7 +1,6 @@
 package junit.runner;
 
 import java.lang.reflect.*;
-import junit.runner.*;
 import junit.framework.*;
 
 /**
diff --git a/test-runner/src/junit/runner/Sorter.java b/test-runner/src/junit/runner/Sorter.java
index 7731f66..8d9341d 100644
--- a/test-runner/src/junit/runner/Sorter.java
+++ b/test-runner/src/junit/runner/Sorter.java
@@ -2,8 +2,6 @@
 
 import java.util.*;
 
-import junit.runner.*;
-
 /**
  * A custom quick sort with support to customize the swap behaviour.
  * NOTICE: We can't use the the sorting support from the JDK 1.2 collection
diff --git a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
index daec845..8189fa9 100644
--- a/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
+++ b/tests/AccessoryDisplay/sink/src/com/android/accessorydisplay/sink/DisplaySinkService.java
@@ -30,6 +30,7 @@
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 
 public class DisplaySinkService extends Service implements SurfaceHolder.Callback {
@@ -150,7 +151,12 @@
             if (mSurface != null) {
                 MediaFormat format = MediaFormat.createVideoFormat(
                         "video/avc", mSurfaceWidth, mSurfaceHeight);
-                mCodec = MediaCodec.createDecoderByType("video/avc");
+                try {
+                    mCodec = MediaCodec.createDecoderByType("video/avc");
+                } catch (IOException e) {
+                    throw new RuntimeException(
+                            "failed to create video/avc decoder", e);
+                }
                 mCodec.configure(format, mSurface, null, 0);
                 mCodec.start();
                 mCodecBufferInfo = new BufferInfo();
diff --git a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
index 256f900..a4faca5 100644
--- a/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
+++ b/tests/AccessoryDisplay/source/src/com/android/accessorydisplay/source/DisplaySourceService.java
@@ -32,6 +32,7 @@
 import android.view.Display;
 import android.view.Surface;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 
 public class DisplaySourceService extends Service {
@@ -191,8 +192,13 @@
             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");
+            MediaCodec codec;
+            try {
+                codec = MediaCodec.createEncoderByType("video/avc");
+            } catch (IOException e) {
+                throw new RuntimeException(
+                        "failed to create video/avc encoder", e);
+            }
             codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
             Surface surface = codec.createInputSurface();
             codec.start();
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
index 2b5e674..ea08a6a 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeLtr.java
@@ -22,11 +22,25 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.FrameLayout;
 import android.widget.GridLayout;
-import android.widget.*;
+import android.widget.Space;
+import android.widget.TextView;
 
-import static android.text.InputType.*;
-import static android.widget.GridLayout.*;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static android.widget.GridLayout.ALIGN_BOUNDS;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.START;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.spec;
 
 public class BiDiTestGridLayoutCodeLtr extends Fragment {
 
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
index 3a03c6c..fc3a92c 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestGridLayoutCodeRtl.java
@@ -22,11 +22,25 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.FrameLayout;
 import android.widget.GridLayout;
-import android.widget.*;
+import android.widget.Space;
+import android.widget.TextView;
 
-import static android.text.InputType.*;
-import static android.widget.GridLayout.*;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
+import static android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD;
+import static android.widget.GridLayout.ALIGN_BOUNDS;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.START;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.spec;
 
 public class BiDiTestGridLayoutCodeRtl extends Fragment {
 
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
index ef885e3..ec02d34 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/GraphReader.java
@@ -117,7 +117,7 @@
         }
 
         @Override
-	public void execute(CommandStack stack) {
+        public void execute(CommandStack stack) {
             Filter filter = null;
             try {
                 filter = stack.getFactory().createFilterByClassName(mClassName,
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java
index 0219fd7..3b3de9f 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/AudioTrackDecoder.java
@@ -59,8 +59,15 @@
 
     @Override
     protected MediaCodec initMediaCodec(MediaFormat format) {
-        MediaCodec mediaCodec = MediaCodec.createDecoderByType(
-                format.getString(MediaFormat.KEY_MIME));
+        MediaCodec mediaCodec;
+        try {
+            mediaCodec = MediaCodec.createDecoderByType(
+                    format.getString(MediaFormat.KEY_MIME));
+        } catch (IOException e) {
+            throw new RuntimeException(
+                    "failed to create decoder for "
+                    + format.getString(MediaFormat.KEY_MIME), e);
+        }
         mediaCodec.configure(format, null, null, 0);
         return mediaCodec;
     }
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java
index 96f3059..a624010 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/CpuVideoTrackDecoder.java
@@ -29,6 +29,7 @@
 import androidx.media.filterfw.FrameImage2D;
 import androidx.media.filterfw.PixelUtils;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.HashSet;
@@ -214,7 +215,13 @@
             return null;
         } else {
             String bestCodec = candidateCodecs.firstEntry().getValue();
-            return MediaCodec.createByCodecName(bestCodec);
+            try {
+                return MediaCodec.createByCodecName(bestCodec);
+            } catch (IOException e) {
+                throw new RuntimeException(
+                        "failed to create codec for "
+                        + bestCodec, e);
+            }
         }
     }
 
diff --git a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java
index bbba9d8..f5eb513 100644
--- a/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java
+++ b/tests/Camera2Tests/SmartCamera/SimpleCamera/src/androidx/media/filterfw/decoder/GpuVideoTrackDecoder.java
@@ -28,6 +28,7 @@
 import androidx.media.filterfw.ImageShader;
 import androidx.media.filterfw.TextureSource;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 
 /**
@@ -86,9 +87,16 @@
 
     @Override
     protected MediaCodec initMediaCodec(MediaFormat format) {
+        MediaCodec mediaCodec;
+        try {
+            mediaCodec = MediaCodec.createDecoderByType(
+                    format.getString(MediaFormat.KEY_MIME));
+        } catch (IOException e) {
+            throw new RuntimeException(
+                    "failed to create decoder for "
+                    + format.getString(MediaFormat.KEY_MIME), e);
+        }
         Surface surface = new Surface(mSurfaceTexture);
-        MediaCodec mediaCodec = MediaCodec.createDecoderByType(
-                format.getString(MediaFormat.KEY_MIME));
         mediaCodec.configure(format, surface, null, 0);
         surface.release();
         return mediaCodec;
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
index 0b85189..8d8d9de 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/CompareActivity.java
@@ -97,7 +97,7 @@
                 Log.d(LOG_TAG, "failure to access hardware layer");
                 return;
             }
-            Method copyInto = hardwareLayer.getClass().getSuperclass()
+            Method copyInto = hardwareLayer.getClass()
                     .getDeclaredMethod("copyInto", Bitmap.class);
             if (!copyInto.isAccessible())
                 copyInto.setAccessible(true);
diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java b/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
index a08b558..c90b626 100644
--- a/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
+++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/ErrorCalculator.java
@@ -35,23 +35,24 @@
     private static final boolean LOG_TIMING = false;
     private static final boolean LOG_CALC = false;
 
-    private final RenderScript mRS;
+    private RenderScript mRS;
     private Allocation mIdealPixelsAllocation;
     private Allocation mGivenPixelsAllocation;
     private Allocation mOutputPixelsAllocation;
 
-    private final Allocation mInputRowsAllocation;
-    private final Allocation mOutputRegionsAllocation;
+    private Allocation mInputRowsAllocation;
+    private Allocation mOutputRegionsAllocation;
 
-    private final ScriptC_errorCalculator mScript;
+    private ScriptC_errorCalculator mScript;
 
-    private final int[] mOutputRowRegions;
+    private int[] mOutputRowRegions;
 
     public ErrorCalculator(Context c, Resources resources) {
         int width = resources.getDimensionPixelSize(R.dimen.layer_width);
         int height = resources.getDimensionPixelSize(R.dimen.layer_height);
         mOutputRowRegions = new int[height / REGION_SIZE];
 
+/*
         mRS = RenderScript.create(c);
         int[] rowIndices = new int[height / REGION_SIZE];
         for (int i = 0; i < rowIndices.length; i++)
@@ -67,12 +68,15 @@
         mInputRowsAllocation.copyFrom(rowIndices);
         mOutputRegionsAllocation = Allocation.createSized(mRS, Element.I32(mRS),
                 mOutputRowRegions.length, Allocation.USAGE_SCRIPT);
+*/
     }
 
 
     private static long startMillis, middleMillis;
 
     public float calcErrorRS(Bitmap ideal, Bitmap given) {
+        if (true)
+            return calcError(ideal, given);
         if (LOG_TIMING) {
             startMillis = System.currentTimeMillis();
         }
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
index 4d3a843..196a5c1 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/AbstractLayoutTest.java
@@ -24,7 +24,13 @@
 import android.view.ViewGroup;
 import android.widget.Button;
 
-import static android.view.Gravity.*;
+import static android.view.Gravity.BOTTOM;
+import static android.view.Gravity.CENTER;
+import static android.view.Gravity.FILL;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.NO_GRAVITY;
+import static android.view.Gravity.RIGHT;
+import static android.view.Gravity.TOP;
 
 public abstract class AbstractLayoutTest extends Activity {
 
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
index b1c4486..5559707 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/AlignmentTest.java
@@ -20,15 +20,25 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.view.View;
+import android.view.View.OnClickListener;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.GridLayout;
+import android.widget.GridLayout.Alignment;
+import android.widget.GridLayout.LayoutParams;
 import android.widget.TextView;
 
-import static android.widget.GridLayout.*;
+import static android.widget.GridLayout.BASELINE;
+import static android.widget.GridLayout.BOTTOM;
+import static android.widget.GridLayout.CENTER;
+import static android.widget.GridLayout.FILL;
+import static android.widget.GridLayout.LEFT;
+import static android.widget.GridLayout.RIGHT;
+import static android.widget.GridLayout.TOP;
+import static android.widget.GridLayout.spec;
 
-public class AlignmentTest  extends Activity {
+public class AlignmentTest extends Activity {
 
     public static final String[] HORIZONTAL_NAMES = {"LEFT", "center", "east", "fill"};
     public static final Alignment[] HORIZONTAL_ALIGNMENTS = {LEFT, CENTER, RIGHT, FILL};
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
index 4ce449a..8047c5f1 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/GridLayoutTest.java
@@ -21,7 +21,10 @@
 import android.view.ViewGroup;
 import android.widget.GridLayout;
 
-import static android.widget.GridLayout.*;
+import static android.widget.GridLayout.Spec;
+import static android.widget.GridLayout.UNDEFINED;
+import static android.widget.GridLayout.VERTICAL;
+import static android.widget.GridLayout.spec;
 
 public class GridLayoutTest extends AbstractLayoutTest {
     public ViewGroup create(Context context) {
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java b/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
index c7f4665..dc5b12c 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/LinearLayoutTest.java
@@ -20,9 +20,9 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
 
-import static android.widget.LinearLayout.*;
-import static android.widget.LinearLayout.LayoutParams.*;
+import static android.widget.LinearLayout.LayoutParams.WRAP_CONTENT;
 
 public class LinearLayoutTest extends AbstractLayoutTest {
     public ViewGroup create(Context context) {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 1bb0db0..c8eefe0 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -706,6 +706,15 @@
         </activity>
 
         <activity
+                android:name="ColorFiltersMutateActivity"
+                android:label="ColorFilters/Mutate Filters">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.test.hwui.TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity
                 android:name="LinesActivity"
                 android:label="Draw/Lines">
             <intent-filter>
@@ -849,5 +858,23 @@
             </intent-filter>
         </activity>
 
+        <activity
+                android:name="ProjectionActivity"
+                android:label="Reordering/Projection">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.test.hwui.TEST" />
+            </intent-filter>
+        </activity>
+
+        <activity
+                android:name="IsolationVolumeActivity"
+                android:label="Reordering/IsolationVolume">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.test.hwui.TEST" />
+            </intent-filter>
+        </activity>
+
     </application>
 </manifest>
diff --git a/tests/HwAccelerationTest/res/layout/isolation.xml b/tests/HwAccelerationTest/res/layout/isolation.xml
new file mode 100644
index 0000000..e66db19
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/isolation.xml
@@ -0,0 +1,56 @@
+<?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"
+    android:background="#f55">
+    <!-- Left and right layouts are not isolated volumes, so the text views
+         will interleave since they share an isolated z volume-->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="200dp"
+            android:layout_weight="1"
+            android:orientation="vertical">
+            <TextView style="@style/TopLeftReorderTextView"/>
+            <TextView style="@style/BottomLeftReorderTextView"/>
+        </LinearLayout>
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="200dp"
+            android:layout_weight="1"
+            android:translationY="50dp"
+            android:orientation="vertical">
+            <TextView style="@style/TopRightReorderTextView"/>
+            <TextView style="@style/BottomRightReorderTextView"/>
+        </LinearLayout>
+    </LinearLayout>
+
+    <!-- Left and right volumes are isolated by default, so no interleaving will be seen. -->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="200dp"
+            android:layout_weight="1"
+            android:orientation="vertical">
+            <TextView style="@style/TopLeftReorderTextView"/>
+            <TextView style="@style/BottomLeftReorderTextView"/>
+        </LinearLayout>
+        <LinearLayout
+            android:layout_width="0dp"
+            android:layout_height="200dp"
+            android:layout_weight="1"
+            android:translationY="50dp"
+            android:orientation="vertical">
+            <TextView style="@style/TopRightReorderTextView"/>
+            <TextView style="@style/BottomRightReorderTextView"/>
+        </LinearLayout>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/layout/projection.xml b/tests/HwAccelerationTest/res/layout/projection.xml
new file mode 100644
index 0000000..b6e4c5e
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/projection.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    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"
+    android:orientation="vertical"
+    android:background="#66ff0000"
+    tools:context="com.example.projection.ProjectionActivity"
+    tools:ignore="MergeRootFrame">
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        android:textSize="50sp"
+        android:text="TextView"/>
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        android:clipChildren="false">
+        <view class="com.android.test.hwui.ProjectionActivity$ProjectedView"
+            android:id="@+id/projection"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:textSize="50sp"
+            android:text="TextView"/>
+    </FrameLayout>
+
+    <TextView
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        android:textSize="50sp"
+        android:text="TextView"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/HwAccelerationTest/res/values/styles.xml b/tests/HwAccelerationTest/res/values/styles.xml
new file mode 100644
index 0000000..cde5d20
--- /dev/null
+++ b/tests/HwAccelerationTest/res/values/styles.xml
@@ -0,0 +1,34 @@
+<resources>
+    <style name="ReorderTextView" parent="@android:style/TextAppearance.Medium">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">100dp</item>
+        <item name="android:gravity">center</item>
+    </style>
+    <style name="LeftReorderTextView" parent="@style/ReorderTextView">
+        <item name="android:translationX">20dp</item>
+    </style>
+    <style name="RightReorderTextView" parent="@style/ReorderTextView">
+        <item name="android:translationX">-20dp</item>
+    </style>
+
+    <style name="TopLeftReorderTextView" parent="@style/LeftReorderTextView">
+        <item name="android:background">#666</item>
+        <item name="android:text">100</item>
+        <item name="android:translationZ">100dp</item>
+    </style>
+    <style name="BottomLeftReorderTextView" parent="@style/LeftReorderTextView">
+        <item name="android:background">#bbb</item>
+        <item name="android:text">300</item>
+        <item name="android:translationZ">300dp</item>
+    </style>
+    <style name="TopRightReorderTextView" parent="@style/RightReorderTextView">
+        <item name="android:background">#888</item>
+        <item name="android:text">200</item>
+        <item name="android:translationZ">200dp</item>
+    </style>
+    <style name="BottomRightReorderTextView" parent="@style/RightReorderTextView">
+        <item name="android:background">#ccc</item>
+        <item name="android:text">400</item>
+        <item name="android:translationZ">400dp</item>
+    </style>
+</resources>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
new file mode 100644
index 0000000..808b5d3
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ColorFiltersMutateActivity.java
@@ -0,0 +1,180 @@
+/*
+ * 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.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.LightingColorFilter;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ColorFiltersMutateActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        final BitmapsView view = new BitmapsView(this);
+        setContentView(view);
+    }
+
+    static class BitmapsView extends View {
+        private final Bitmap mBitmap1;
+        private final Bitmap mBitmap2;
+        private final Paint mColorMatrixPaint;
+        private final Paint mLightingPaint;
+        private final Paint mBlendPaint;
+
+        private float mSaturation = 0.0f;
+        private int mLightAdd = 0;
+        private int mLightMul = 0;
+        private int mPorterDuffColor = 0;
+
+        BitmapsView(Context c) {
+            super(c);
+
+            mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
+            mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset2);
+
+            mColorMatrixPaint = new Paint();
+            final ColorMatrix colorMatrix = new ColorMatrix();
+            colorMatrix.setSaturation(0);
+            mColorMatrixPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
+
+            mLightingPaint = new Paint();
+            mLightingPaint.setColorFilter(new LightingColorFilter(0, 0));
+
+            mBlendPaint = new Paint();
+            mBlendPaint.setColorFilter(new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_OVER));
+
+            ObjectAnimator sat = ObjectAnimator.ofFloat(this, "saturation", 1.0f);
+            sat.setDuration(1000);
+            sat.setRepeatCount(ObjectAnimator.INFINITE);
+            sat.setRepeatMode(ObjectAnimator.REVERSE);
+            sat.start();
+
+            ObjectAnimator light = ObjectAnimator.ofInt(this, "lightAdd", 0x00101030);
+            light.setEvaluator(new ArgbEvaluator());
+            light.setDuration(1000);
+            light.setRepeatCount(ObjectAnimator.INFINITE);
+            light.setRepeatMode(ObjectAnimator.REVERSE);
+            light.start();
+
+            ObjectAnimator mult = ObjectAnimator.ofInt(this, "lightMul", 0x0060ffff);
+            mult.setEvaluator(new ArgbEvaluator());
+            mult.setDuration(1000);
+            mult.setRepeatCount(ObjectAnimator.INFINITE);
+            mult.setRepeatMode(ObjectAnimator.REVERSE);
+            mult.start();
+
+            ObjectAnimator color = ObjectAnimator.ofInt(this, "porterDuffColor", 0x7f990040);
+            color.setEvaluator(new ArgbEvaluator());
+            color.setDuration(1000);
+            color.setRepeatCount(ObjectAnimator.INFINITE);
+            color.setRepeatMode(ObjectAnimator.REVERSE);
+            color.start();
+        }
+
+        public int getPorterDuffColor() {
+            return mPorterDuffColor;
+        }
+
+        public void setPorterDuffColor(int porterDuffColor) {
+            mPorterDuffColor = porterDuffColor;
+            final PorterDuffColorFilter filter =
+                    (PorterDuffColorFilter) mBlendPaint.getColorFilter();
+            filter.setColor(mPorterDuffColor);
+            invalidate();
+        }
+
+        public int getLightAdd() {
+            return mLightAdd;
+        }
+
+        public void setLightAdd(int lightAdd) {
+            mLightAdd = lightAdd;
+            final LightingColorFilter filter =
+                    (LightingColorFilter) mLightingPaint.getColorFilter();
+            filter.setColorAdd(lightAdd);
+            invalidate();
+        }
+
+        public int getLightMul() {
+            return mLightAdd;
+        }
+
+        public void setLightMul(int lightMul) {
+            mLightMul = lightMul;
+            final LightingColorFilter filter =
+                    (LightingColorFilter) mLightingPaint.getColorFilter();
+            filter.setColorMultiply(lightMul);
+            invalidate();
+        }
+
+        public void setSaturation(float saturation) {
+            mSaturation = saturation;
+            final ColorMatrixColorFilter filter =
+                    (ColorMatrixColorFilter) mColorMatrixPaint.getColorFilter();
+            final ColorMatrix m = filter.getColorMatrix();
+            m.setSaturation(saturation);
+            filter.setColorMatrix(m);
+            invalidate();
+        }
+
+        public float getSaturation() {
+            return mSaturation;
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            super.onDraw(canvas);
+
+            canvas.drawARGB(255, 255, 255, 255);
+
+            canvas.save();
+            canvas.translate(120.0f, 50.0f);
+            canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mColorMatrixPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap1.getHeight());
+            canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mLightingPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap1.getHeight());
+            canvas.drawBitmap(mBitmap1, 0.0f, 0.0f, mBlendPaint);
+            canvas.restore();
+
+            canvas.save();
+            canvas.translate(120.0f + mBitmap1.getWidth() + 120.0f, 50.0f);
+            canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mColorMatrixPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap2.getHeight());
+            canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mLightingPaint);
+
+            canvas.translate(0.0f, 50.0f + mBitmap2.getHeight());
+            canvas.drawBitmap(mBitmap2, 0.0f, 0.0f, mBlendPaint);
+            canvas.restore();
+        }
+    }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java
new file mode 100644
index 0000000..d5c93f2
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/IsolationVolumeActivity.java
@@ -0,0 +1,12 @@
+package com.android.test.hwui;
+
+import android.os.Bundle;
+import android.app.Activity;
+
+public class IsolationVolumeActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.isolation);
+    }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
new file mode 100644
index 0000000..5ba3ad9
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
@@ -0,0 +1,83 @@
+package com.android.test.hwui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Bundle;
+
+import android.app.Activity;
+import android.util.AttributeSet;
+import android.view.RenderNode;
+import android.view.View;
+import android.widget.LinearLayout;
+
+public class ProjectionActivity extends Activity {
+    /**
+     * The content from this view should be projected in between the background of the
+     * ProjecteeLayout and its children, unclipped.
+     *
+     * This view doesn't clip to its bounds (because its parent has clipChildren=false) so that
+     * when it is projected onto the ProjecteeLayout, it draws outside its view bounds.
+     */
+    public static class ProjectedView extends View {
+        private final Paint mPaint = new Paint();
+        private final RectF mRectF = new RectF();
+
+        public ProjectedView(Context context) {
+            this(context, null);
+        }
+
+        public ProjectedView(Context context, AttributeSet attrs) {
+            this(context, attrs, 0);
+        }
+
+        public ProjectedView(Context context, AttributeSet attrs, int defStyleAttr) {
+            super(context, attrs, defStyleAttr);
+
+            setOnClickListener(new OnClickListener() {
+                boolean toggle = false;
+                @Override
+                public void onClick(View v) {
+                    toggle = !toggle;
+                    setProject(toggle);
+                }
+            });
+        }
+
+        private void setProject(boolean value) {
+            RenderNode displayList = getDisplayList();
+            if (displayList != null) {
+                displayList.setProjectBackwards(value);
+            }
+            // NOTE: we can't invalidate ProjectedView for the redraw because:
+            // 1) the view won't preserve displayList properties that it doesn't know about
+            // 2) the damage rect won't be big enough
+
+            // instead, twiddle properties on the container, so that enough area of the screen is
+            // redrawn without rerecording any DisplayLists.
+            container.setTranslationX(100f);
+            container.setTranslationX(0.0f);
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            // TODO: set projection flag
+            final int w = getWidth();
+            final int h = getHeight();
+            mRectF.set(0, -h, w, 2 * h);
+            mPaint.setAntiAlias(true);
+            mPaint.setColor(0x5f00ff00);
+            canvas.drawOval(mRectF, mPaint);
+        }
+    }
+
+    static View container;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.projection);
+        container = findViewById(R.id.container);
+    }
+}
diff --git a/tests/IdleServiceTest/Android.mk b/tests/IdleServiceTest/Android.mk
new file mode 100644
index 0000000..a7879c5
--- /dev/null
+++ b/tests/IdleServiceTest/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := IdleServiceTest
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/tests/IdleServiceTest/AndroidManifest.xml b/tests/IdleServiceTest/AndroidManifest.xml
new file mode 100644
index 0000000..16d2324
--- /dev/null
+++ b/tests/IdleServiceTest/AndroidManifest.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.idleservicetest">
+
+    <application>
+        <service android:name="TestService"
+                 android:exported="true"
+                 android:enabled="true"
+                 android:permission="android.permission.BIND_IDLE_SERVICE" >
+            <intent-filter>
+                <action android:name="android.service.idle.IdleService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="CrashingTestService"
+                 android:exported="true"
+                 android:enabled="true"
+                 android:permission="android.permission.BIND_IDLE_SERVICE" >
+            <intent-filter>
+                <action android:name="android.service.idle.IdleService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="TimeoutTestService"
+                 android:exported="true"
+                 android:enabled="true"
+                 android:permission="android.permission.BIND_IDLE_SERVICE" >
+            <intent-filter>
+                <action android:name="android.service.idle.IdleService" />
+            </intent-filter>
+        </service>
+
+        <!-- UnpermissionedTestService should never run because it does
+             not require the necessary permission in its <service> block -->
+        <service android:name="UnpermissionedTestService"
+                 android:exported="true"
+                 android:enabled="true" >
+            <intent-filter>
+                <action android:name="android.service.idle.IdleService" />
+            </intent-filter>
+        </service>
+
+    </application>
+</manifest>
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java
new file mode 100644
index 0000000..022ebcf
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/CrashingTestService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.os.Handler;
+import android.util.Log;
+
+public class CrashingTestService extends IdleService {
+    static final String TAG = "CrashingTestService";
+
+    String mNull = null;
+
+    @Override
+    public boolean onIdleStart() {
+        Log.i(TAG, "Idle maintenance: onIdleStart()");
+
+        Handler h = new Handler();
+        Runnable r = new Runnable() {
+            @Override
+            public void run() {
+                Log.i(TAG, "Explicitly crashing");
+                if (mNull.equals("")) {
+                    Log.i(TAG, "won't happen");
+                }
+            }
+        };
+        Log.i(TAG, "Posting explicit crash in 15 seconds");
+        h.postDelayed(r, 15 * 1000);
+        return true;
+    }
+
+    @Override
+    public void onIdleStop() {
+        Log.i(TAG, "Idle maintenance: onIdleStop()");
+    }
+
+}
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java
new file mode 100644
index 0000000..7e9805f
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/TestService.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.os.Handler;
+import android.util.Log;
+
+public class TestService extends IdleService {
+    static final String TAG = "TestService";
+
+    @Override
+    public boolean onIdleStart() {
+        Log.i(TAG, "Idle maintenance: onIdleStart()");
+
+        Handler h = new Handler();
+        Runnable r = new Runnable() {
+            @Override
+            public void run() {
+                Log.i(TAG, "Explicitly finishing idle");
+                finishIdle();
+            }
+        };
+        Log.i(TAG, "Posting explicit finish in 15 seconds");
+        h.postDelayed(r, 15 * 1000);
+        return true;
+    }
+
+    @Override
+    public void onIdleStop() {
+        Log.i(TAG, "Idle maintenance: onIdleStop()");
+    }
+
+}
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java
new file mode 100644
index 0000000..b2ba21b
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/TimeoutTestService.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.util.Log;
+
+public class TimeoutTestService extends IdleService {
+    private static final String TAG = "TimeoutTestService";
+
+    @Override
+    public boolean onIdleStart() {
+        Log.i(TAG, "onIdleStart() but anticipating time-slice timeout");
+        return true;
+    }
+
+    @Override
+    public void onIdleStop() {
+        Log.i(TAG, "onIdleStop() so we're done");
+    }
+
+}
diff --git a/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java b/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java
new file mode 100644
index 0000000..b9fe32b
--- /dev/null
+++ b/tests/IdleServiceTest/src/com/android/idleservicetest/UnpermissionedTestService.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.idleservicetest;
+
+import android.app.maintenance.IdleService;
+import android.util.Log;
+
+// Should never be invoked because its manifest declaration does not
+// require the necessary permission.
+public class UnpermissionedTestService extends IdleService {
+    private static final String TAG = "UnpermissionedTestService";
+
+    @Override
+    public boolean onIdleStart() {
+        Log.e(TAG, "onIdleStart() for this service should never be called!");
+        return false;
+    }
+
+    @Override
+    public void onIdleStop() {
+        Log.e(TAG, "onIdleStop() for this service should never be called!");
+    }
+
+}
diff --git a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
index 25ac2f0..299e6bb 100644
--- a/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
+++ b/tests/ImfTest/src/com/android/imftest/samples/InputTypeActivity.java
@@ -81,11 +81,11 @@
         
         /* Uri Edit Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_URI, 
-        		R.string.uri_edit_text_label));
+                R.string.uri_edit_text_label));
         
         /* Email Address Edit Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS, 
-        		R.string.email_address_edit_text_label));
+                R.string.email_address_edit_text_label));
         
         /* Email Subject Text */
         mLayout.addView(buildEntryView(EditorInfo.TYPE_CLASS_TEXT|EditorInfo.TYPE_TEXT_VARIATION_EMAIL_SUBJECT, 
@@ -142,7 +142,7 @@
     private View buildEntryView(int inputType, int label) {
 
         
-    	View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
+        View view = mInflater.inflate(R.layout.sample_edit_text, mParent, false);
         
         EditText editText = (EditText) view.findViewById(R.id.data);
         editText.setInputType(inputType);
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
index a1c5fd2..2db11c5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollablePanScanTests.java
@@ -24,26 +24,26 @@
 
 public class BigEditTextActivityNonScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityNonScrollablePanScan> {
 
-	public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
-	
+    public final String TAG = "BigEditTextActivityNonScrollablePanScanTests";
+    
     public BigEditTextActivityNonScrollablePanScanTests() {
         super(BigEditTextActivityNonScrollablePanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {
-	    // Give the IME 2 seconds to appear.
-	    pause(2000);
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {
+        // Give the IME 2 seconds to appear.
+        pause(2000);
         
-	    View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
-	    View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
-	        
-	    assertNotNull(rootView);
-	    assertNotNull(servedView);
-	    
-	    destructiveCheckImeInitialState(rootView, servedView);
-	    
+        View rootView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getRootView();
+        View servedView = ((BigEditTextActivityNonScrollablePanScan) mTargetActivity).getDefaultFocusedView();
+            
+        assertNotNull(rootView);
+        assertNotNull(servedView);
+        
+        destructiveCheckImeInitialState(rootView, servedView);
+        
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
index 2e0b0eb..1050794 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityNonScrollableResizeTests.java
@@ -24,14 +24,14 @@
 
 public class BigEditTextActivityNonScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityNonScrollableResize> {
 
-	public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
-	
+    public final String TAG = "BigEditTextActivityNonScrollableResizeTests";
+    
     public BigEditTextActivityNonScrollableResizeTests() {
         super(BigEditTextActivityNonScrollableResize.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityNonScrollableResize) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
index d3eefb5..1e848b0 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollablePanScanTests.java
@@ -24,14 +24,14 @@
 
 public class BigEditTextActivityScrollablePanScanTests extends ImfBaseTestCase<BigEditTextActivityScrollablePanScan> {
 
-	public final String TAG = "BigEditTextActivityScrollablePanScanTests";
-	
+    public final String TAG = "BigEditTextActivityScrollablePanScanTests";
+    
     public BigEditTextActivityScrollablePanScanTests() {
         super(BigEditTextActivityScrollablePanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityScrollablePanScan) mTargetActivity).getRootView();
@@ -43,6 +43,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
index 5c40e6d..de607d6 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BigEditTextActivityScrollableResizeTests.java
@@ -24,15 +24,15 @@
 
 public class BigEditTextActivityScrollableResizeTests extends ImfBaseTestCase<BigEditTextActivityScrollableResize> {
 
-	public final String TAG = "BigEditTextActivityScrollableResizeTests";
-	
+    public final String TAG = "BigEditTextActivityScrollableResizeTests";
+    
     public BigEditTextActivityScrollableResizeTests() {
         super(BigEditTextActivityScrollableResize.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {       
-	    // Give the IME 2 seconds to appear.
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {       
+        // Give the IME 2 seconds to appear.
         pause(2000);
         
         View rootView = ((BigEditTextActivityScrollableResize) mTargetActivity).getRootView();
@@ -44,6 +44,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
             
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
index 9a93133..c521905 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/BottomEditTextActivityPanScanTests.java
@@ -24,14 +24,14 @@
 
 public class BottomEditTextActivityPanScanTests extends ImfBaseTestCase<BottomEditTextActivityPanScan> {
 
-	public final String TAG = "BottomEditTextActivityPanScanTests";
-	
+    public final String TAG = "BottomEditTextActivityPanScanTests";
+    
     public BottomEditTextActivityPanScanTests() {
         super(BottomEditTextActivityPanScan.class);
     }
-	
-	@LargeTest
-	public void testAppAdjustmentPanScan() {
+    
+    @LargeTest
+    public void testAppAdjustmentPanScan() {
         // Give the IME 2 seconds to appear.
         pause(2000);
         
@@ -44,6 +44,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
         
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
index ae900c3..f6f97b5 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/ButtonActivityTest.java
@@ -23,8 +23,8 @@
 
 public class ButtonActivityTest extends ImfBaseTestCase<ButtonActivity> {
 
-	final public String TAG = "ButtonActivityTest";
-	
+    final public String TAG = "ButtonActivityTest";
+    
     public ButtonActivityTest() {
         super(ButtonActivity.class);
     }
diff --git a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
index ed5b0c9..6147d3c 100644
--- a/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
+++ b/tests/ImfTest/tests/src/com/android/imftest/samples/OneEditTextActivityNotSelectedTests.java
@@ -22,21 +22,21 @@
 
 public class OneEditTextActivityNotSelectedTests extends ImfBaseTestCase<OneEditTextActivityNotSelected> {
 
-	public final String TAG = "OneEditTextActivityNotSelectedTests";
-	
+    public final String TAG = "OneEditTextActivityNotSelectedTests";
+    
     public OneEditTextActivityNotSelectedTests() {
         super(OneEditTextActivityNotSelected.class);
     }
     
-	@LargeTest
-	public void testSoftKeyboardNoAutoPop() {
-	    
-	    // Give the IME 2 seconds to appear.
-	    pause(2000);
-	    
-	    assertFalse(mImm.isAcceptingText());
-	    
-	    View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
+    @LargeTest
+    public void testSoftKeyboardNoAutoPop() {
+        
+        // Give the IME 2 seconds to appear.
+        pause(2000);
+        
+        assertFalse(mImm.isAcceptingText());
+        
+        View rootView = ((OneEditTextActivityNotSelected) mTargetActivity).getRootView();
         View servedView = ((OneEditTextActivityNotSelected) mTargetActivity).getDefaultFocusedView();
         
         assertNotNull(rootView);
@@ -45,6 +45,6 @@
         destructiveCheckImeInitialState(rootView, servedView);
         
         verifyEditTextAdjustment(servedView, rootView.getMeasuredHeight());
-	}
-	
+    }
+    
 }
diff --git a/tests/OneMedia/Android.mk b/tests/OneMedia/Android.mk
new file mode 100644
index 0000000..93b9c9a
--- /dev/null
+++ b/tests/OneMedia/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files) \
+        $(call all-Iaidl-files-under, src)
+
+LOCAL_PACKAGE_NAME := OneMedia
+LOCAL_CERTIFICATE := platform
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+        android-support-v7-appcompat \
+        android-support-v7-mediarouter
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml
new file mode 100644
index 0000000..7d6ba1d
--- /dev/null
+++ b/tests/OneMedia/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.onemedia"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk android:minSdkVersion="19"/>
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.android.onemedia.OnePlayerActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <service
+            android:name="com.android.onemedia.OnePlayerService"
+            android:exported="false"
+            android:process="com.android.onemedia.service" />
+    </application>
+
+</manifest>
diff --git a/tests/OneMedia/res/drawable-hdpi/ic_launcher.png b/tests/OneMedia/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..288b665
--- /dev/null
+++ b/tests/OneMedia/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/drawable-mdpi/ic_launcher.png b/tests/OneMedia/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6ae570b
--- /dev/null
+++ b/tests/OneMedia/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/drawable-xhdpi/ic_launcher.png b/tests/OneMedia/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..d4fb7cd
--- /dev/null
+++ b/tests/OneMedia/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/drawable-xxhdpi/ic_launcher.png b/tests/OneMedia/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..85a6081
--- /dev/null
+++ b/tests/OneMedia/res/drawable-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/OneMedia/res/layout/activity_main.xml b/tests/OneMedia/res/layout/activity_main.xml
new file mode 100644
index 0000000..168c9b8ce
--- /dev/null
+++ b/tests/OneMedia/res/layout/activity_main.xml
@@ -0,0 +1,16 @@
+<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:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context=".MainActivity" >
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/hello_world" />
+
+</RelativeLayout>
diff --git a/tests/OneMedia/res/layout/activity_one_player.xml b/tests/OneMedia/res/layout/activity_one_player.xml
new file mode 100644
index 0000000..4208355
--- /dev/null
+++ b/tests/OneMedia/res/layout/activity_one_player.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2014 Google Inc. All Rights Reserved. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center_horizontal"
+        android:orientation="vertical">
+    <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:gravity="center"
+            android:text="@string/app_name"
+            style="@style/Title" />
+    <EditText
+            android:id="@+id/content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:inputType="textUri"
+            android:hint="@string/media_content_hint"
+            android:gravity="center"
+            android:textSize="24sp" />
+    <EditText
+            android:id="@+id/next_content"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:inputType="textNoSuggestions"
+            android:hint="@string/media_next_hint"
+            android:gravity="center"
+            android:textSize="24sp" />
+    <CheckBox
+            android:id="@+id/has_video"
+            android:layout_marginRight="8dip"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/has_video" />
+    <LinearLayout
+            android:id="@+id/controls"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal" >
+        <Button
+                android:id="@+id/start_button"
+                style="@style/BottomBarButton"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/start_button" />
+        <Button
+                android:id="@+id/play_button"
+                style="@style/BottomBarButton"
+                android:layout_width="0dip"
+                android:layout_height="wrap_content"
+                android:layout_weight="1"
+                android:text="@string/play_button" />
+    </LinearLayout>
+    <TextView
+            android:id="@+id/status"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/OneMedia/res/menu/main.xml b/tests/OneMedia/res/menu/main.xml
new file mode 100644
index 0000000..c002028
--- /dev/null
+++ b/tests/OneMedia/res/menu/main.xml
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/action_settings"/>
+
+</menu>
diff --git a/tests/OneMedia/res/values/colors.xml b/tests/OneMedia/res/values/colors.xml
new file mode 100644
index 0000000..9b9dc2a
--- /dev/null
+++ b/tests/OneMedia/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+
+<resources>
+    <color name="title_color">#33B5E5</color>
+</resources>
diff --git a/tests/OneMedia/res/values/dimens.xml b/tests/OneMedia/res/values/dimens.xml
new file mode 100644
index 0000000..562edef
--- /dev/null
+++ b/tests/OneMedia/res/values/dimens.xml
@@ -0,0 +1,9 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+    <dimen name="title_size">22sp</dimen>
+    <dimen name="small_size">11sp</dimen>
+
+</resources>
diff --git a/tests/OneMedia/res/values/strings.xml b/tests/OneMedia/res/values/strings.xml
new file mode 100644
index 0000000..1b0cebb
--- /dev/null
+++ b/tests/OneMedia/res/values/strings.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">OneMedia</string>
+    <string name="action_settings">Settings</string>
+    <string name="hello_world">Test app for trying out new media components</string>
+
+    <string name="start_button">Start</string>
+    <string name="play_button">Play</string>
+    <string name="media_content_hint">Content</string>
+    <string name="media_next_hint">Next content</string>
+    <string name="has_video">Is video</string>
+    <string name="has_duration">Has duration</string>
+
+</resources>
diff --git a/tests/OneMedia/res/values/styles.xml b/tests/OneMedia/res/values/styles.xml
new file mode 100644
index 0000000..60f3139
--- /dev/null
+++ b/tests/OneMedia/res/values/styles.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<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>
+
+    <style name="Title">
+        <item name="android:textSize">@dimen/title_size</item>
+        <item name="android:textColor">@color/title_color</item>
+        <item name="android:clickable">false</item>
+        <item name="android:longClickable">false</item>
+    </style>
+
+    <style name="Text">
+        <item name="android:textSize">@dimen/small_size</item>
+        <item name="android:textColor">@color/title_color</item>
+        <item name="android:clickable">false</item>
+        <item name="android:longClickable">false</item>
+    </style>
+
+    <style name="BottomBarButton">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:paddingTop">0dip</item>
+        <item name="android:paddingLeft">0dip</item>
+        <item name="android:paddingRight">0dip</item>
+        <item name="android:paddingBottom">0dip</item>
+        <item name="android:textSize">12sp</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+</resources>
diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl
new file mode 100644
index 0000000..2b14384
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/IPlayerCallback.aidl
@@ -0,0 +1,22 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.onemedia;
+
+import android.media.session.MediaSessionToken;
+
+interface IPlayerCallback {
+    void onSessionChanged(in MediaSessionToken session);
+}
\ No newline at end of file
diff --git a/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl
new file mode 100644
index 0000000..efdbe9a
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/IPlayerService.aidl
@@ -0,0 +1,29 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.onemedia;
+
+import android.media.session.MediaSessionToken;
+import android.os.Bundle;
+
+import com.android.onemedia.IPlayerCallback;
+import com.android.onemedia.playback.IRequestCallback;
+
+interface IPlayerService {
+    MediaSessionToken getSessionToken();
+    void registerCallback(in IPlayerCallback cb);
+    void unregisterCallback(in IPlayerCallback cb);
+    void sendRequest(String action, in Bundle params, in IRequestCallback cb);
+}
\ No newline at end of file
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
new file mode 100644
index 0000000..3114ca9
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+
+import android.app.Activity;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Menu;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.android.onemedia.playback.Renderer;
+
+public class OnePlayerActivity extends Activity {
+    private static final String TAG = "OnePlayerActivity";
+
+    protected PlayerController mPlayer;
+
+    private Button mStartButton;
+    private Button mPlayButton;
+    private TextView mStatusView;
+
+    private EditText mContentText;
+    private EditText mNextContentText;
+    private CheckBox mHasVideo;
+
+    private int mPlaybackState;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_one_player);
+        mPlayer = new PlayerController(this, OnePlayerService.getServiceIntent(this));
+
+
+        mStartButton = (Button) findViewById(R.id.start_button);
+        mPlayButton = (Button) findViewById(R.id.play_button);
+        mStatusView = (TextView) findViewById(R.id.status);
+        mContentText = (EditText) findViewById(R.id.content);
+        mNextContentText = (EditText) findViewById(R.id.next_content);
+        mHasVideo = (CheckBox) findViewById(R.id.has_video);
+
+        mStartButton.setOnClickListener(mButtonListener);
+        mPlayButton.setOnClickListener(mButtonListener);
+
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Inflate the menu; this adds items to the action bar if it is present.
+        getMenuInflater().inflate(R.menu.main, menu);
+        return true;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mPlayer.onResume();
+        mPlayer.setListener(mListener);
+    }
+
+    @Override
+    public void onPause() {
+        mPlayer.setListener(null);
+        mPlayer.onPause();
+        super.onPause();
+    }
+
+    private void setControlsEnabled(boolean enabled) {
+        mStartButton.setEnabled(enabled);
+        mPlayButton.setEnabled(enabled);
+    }
+
+    private View.OnClickListener mButtonListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.play_button:
+                    Log.d(TAG, "Play button pressed, in state " + mPlaybackState);
+                    if (mPlaybackState == PlaybackState.PLAYSTATE_PAUSED
+                            || mPlaybackState == PlaybackState.PLAYSTATE_STOPPED) {
+                        mPlayer.play();
+                    } else if (mPlaybackState == PlaybackState.PLAYSTATE_PLAYING) {
+                        mPlayer.pause();
+                    }
+                    break;
+                case R.id.start_button:
+                    Log.d(TAG, "Start button pressed, in state " + mPlaybackState);
+                    mPlayer.setContent(mContentText.getText().toString());
+                    break;
+            }
+
+        }
+    };
+
+    private PlayerController.Listener mListener = new PlayerController.Listener() {
+        @Override
+        public void onPlaybackStateChange(PlaybackState state) {
+            mPlaybackState = state.getState();
+            boolean enablePlay = false;
+            StringBuilder statusBuilder = new StringBuilder();
+            switch (mPlaybackState) {
+                case PlaybackState.PLAYSTATE_PLAYING:
+                    statusBuilder.append("playing");
+                    mPlayButton.setText("Pause");
+                    enablePlay = true;
+                    break;
+                case PlaybackState.PLAYSTATE_PAUSED:
+                    statusBuilder.append("paused");
+                    mPlayButton.setText("Play");
+                    enablePlay = true;
+                    break;
+                case PlaybackState.PLAYSTATE_STOPPED:
+                    statusBuilder.append("ended");
+                    mPlayButton.setText("Play");
+                    enablePlay = true;
+                    break;
+                case PlaybackState.PLAYSTATE_ERROR:
+                    statusBuilder.append("error: ").append(state.getErrorMessage());
+                    break;
+                case PlaybackState.PLAYSTATE_BUFFERING:
+                    statusBuilder.append("buffering");
+                    break;
+                case PlaybackState.PLAYSTATE_NONE:
+                    statusBuilder.append("none");
+                    break;
+                default:
+                    statusBuilder.append(mPlaybackState);
+            }
+            statusBuilder.append(" -- At position: ").append(state.getPosition());
+            mStatusView.setText(statusBuilder.toString());
+            mPlayButton.setEnabled(enablePlay);
+        }
+
+        @Override
+        public void onConnectionStateChange(int state) {
+            if (state == PlayerController.STATE_DISCONNECTED) {
+                setControlsEnabled(false);
+            } else if (state == PlayerController.STATE_CONNECTED) {
+                setControlsEnabled(true);
+            }
+        }
+
+        @Override
+        public void onMetadataChange(MediaMetadata metadata) {
+            Log.d(TAG, "Metadata update! Title: " + metadata);
+        }
+    };
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java
new file mode 100644
index 0000000..573f7ff
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.content.Context;
+import android.content.Intent;
+
+import java.util.ArrayList;
+
+public class OnePlayerService extends PlayerService {
+    private static final String TAG = "OnePlayerService";
+
+    public static Intent getServiceIntent(Context context) {
+        return new Intent(context, OnePlayerService.class).setPackage(
+                OnePlayerService.class.getPackage().getName());
+    }
+
+    @Override
+    protected Intent onCreateServiceIntent() {
+        return getServiceIntent(this);
+    }
+
+    @Override
+    protected ArrayList<String> getAllowedPackages() {
+        ArrayList<String> allowedPackages = new ArrayList<String>();
+        allowedPackages.add("com.android.onemedia");
+        return allowedPackages;
+    }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
new file mode 100644
index 0000000..e831ec6
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
@@ -0,0 +1,209 @@
+
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.media.session.MediaController;
+import android.media.session.MediaMetadata;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
+import android.media.session.TransportController;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.util.Log;
+
+import com.android.onemedia.playback.RequestUtils;
+
+public class PlayerController {
+    private static final String TAG = "PlayerController";
+
+    public static final int STATE_DISCONNECTED = 0;
+    public static final int STATE_CONNECTED = 1;
+
+    protected MediaController mController;
+    protected IPlayerService mBinder;
+    protected TransportController mTransportControls;
+
+    private final Intent mServiceIntent;
+    private Context mContext;
+    private Listener mListener;
+    private TransportListener mTransportListener = new TransportListener();
+    private SessionCallback mControllerCb;
+    private MediaSessionManager mManager;
+    private Handler mHandler = new Handler();
+
+    private boolean mResumed;
+
+    public PlayerController(Context context, Intent serviceIntent) {
+        mContext = context;
+        if (serviceIntent == null) {
+            mServiceIntent = new Intent(mContext, PlayerService.class);
+        } else {
+            mServiceIntent = serviceIntent;
+        }
+        mControllerCb = new SessionCallback();
+        mManager = (MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
+
+        mResumed = false;
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+        Log.d(TAG, "Listener set to " + listener + " session is " + mController);
+        if (mListener != null) {
+            mHandler = new Handler();
+            mListener.onConnectionStateChange(
+                    mController == null ? STATE_DISCONNECTED : STATE_CONNECTED);
+        }
+    }
+
+    public void onResume() {
+        mResumed = true;
+        Log.d(TAG, "onResume. Binding to service with intent " + mServiceIntent.toString());
+        bindToService();
+    }
+
+    public void onPause() {
+        mResumed = false;
+        Log.d(TAG, "onPause, unbinding from service");
+        unbindFromService();
+    }
+
+    public void play() {
+        if (mTransportControls != null) {
+            mTransportControls.play();
+        }
+    }
+
+    public void pause() {
+        if (mTransportControls != null) {
+            mTransportControls.pause();
+        }
+    }
+
+    public void setContent(String source) {
+        RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
+        bob.setSource(source);
+        try {
+            mBinder.sendRequest(RequestUtils.ACTION_SET_CONTENT, bob.build(), null);
+        } catch (RemoteException e) {
+            Log.d(TAG, "setContent failed, service may have died.", e);
+        }
+    }
+
+    public void setNextContent(String source) {
+        RequestUtils.ContentBuilder bob = new RequestUtils.ContentBuilder();
+        bob.setSource(source);
+        try {
+            mBinder.sendRequest(RequestUtils.ACTION_SET_NEXT_CONTENT, bob.build(), null);
+        } catch (RemoteException e) {
+            Log.d(TAG, "setNexctContent failed, service may have died.", e);
+        }
+    }
+
+    private void unbindFromService() {
+        mContext.unbindService(mServiceConnection);
+    }
+
+    private void bindToService() {
+        mContext.bindService(mServiceIntent, mServiceConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    private ServiceConnection mServiceConnection = new ServiceConnection() {
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            if (mController != null) {
+                mController.removeCallback(mControllerCb);
+            }
+            mBinder = null;
+            mController = null;
+            mTransportControls = null;
+            Log.d(TAG, "Disconnected from PlayerService");
+
+            if (mListener != null) {
+                mListener.onConnectionStateChange(STATE_DISCONNECTED);
+            }
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            mBinder = IPlayerService.Stub.asInterface(service);
+            Log.d(TAG, "service is " + service + " binder is " + mBinder);
+            try {
+                mController = MediaController.fromToken(mBinder.getSessionToken());
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error getting session", e);
+                return;
+            }
+            mController.addCallback(mControllerCb, mHandler);
+            mTransportControls = mController.getTransportController();
+            if (mTransportControls != null) {
+                mTransportControls.addStateListener(mTransportListener);
+            }
+            Log.d(TAG, "Ready to use PlayerService");
+
+            if (mListener != null) {
+                mListener.onConnectionStateChange(STATE_CONNECTED);
+                if (mTransportControls != null) {
+                    mListener.onPlaybackStateChange(mTransportControls.getPlaybackState());
+                }
+            }
+        }
+    };
+
+    private class SessionCallback extends MediaController.Callback {
+        @Override
+        public void onRouteChanged(Bundle route) {
+            // TODO
+        }
+    }
+
+    private class TransportListener extends TransportController.TransportStateListener {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            if (state == null) {
+                return;
+            }
+            Log.d(TAG, "Received playback state change to state " + state.getState());
+            if (mListener != null) {
+                mListener.onPlaybackStateChange(state);
+            }
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            if (metadata == null) {
+                return;
+            }
+            Log.d(TAG, "Received metadata change, title is "
+                    + metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+        }
+    }
+
+    public interface Listener {
+        public void onPlaybackStateChange(PlaybackState state);
+        public void onMetadataChange(MediaMetadata metadata);
+        public void onConnectionStateChange(int state);
+    }
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerService.java b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
new file mode 100644
index 0000000..0ad6dd1
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.app.Service;
+import android.content.Intent;
+import android.media.session.MediaSessionToken;
+import android.media.session.PlaybackState;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.onemedia.playback.IRequestCallback;
+import com.android.onemedia.playback.RequestUtils;
+
+import java.util.ArrayList;
+
+public class PlayerService extends Service {
+    private static final String TAG = "PlayerService";
+
+    private PlayerBinder mBinder;
+    private PlayerSession mSession;
+    private Intent mIntent;
+    private boolean mStarted = false;
+
+    private ArrayList<IPlayerCallback> mCbs = new ArrayList<IPlayerCallback>();
+
+    @Override
+    public void onCreate() {
+        Log.d(TAG, "onCreate");
+        mIntent = onCreateServiceIntent();
+        if (mSession == null) {
+            mSession = onCreatePlayerController();
+            mSession.createSession();
+            mSession.setListener(mPlayerListener);
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (mBinder == null) {
+            mBinder = new PlayerBinder();
+        }
+        return mBinder;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.d(TAG, "onStartCommand");
+        return START_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.d(TAG, "onDestroy");
+        mSession.onDestroy();
+        mSession = null;
+    }
+
+    public void onPlaybackStarted() {
+        if (!mStarted) {
+            Log.d(TAG, "Starting self");
+            startService(onCreateServiceIntent());
+            mStarted = true;
+        }
+    }
+
+    public void onPlaybackEnded() {
+        if (mStarted) {
+            Log.d(TAG, "Stopping self");
+            stopSelf();
+            mStarted = false;
+        }
+    }
+
+    protected Intent onCreateServiceIntent() {
+        return new Intent(this, PlayerService.class).setPackage(getBasePackageName());
+    }
+
+    protected PlayerSession onCreatePlayerController() {
+        return new PlayerSession(this);
+    }
+
+    protected ArrayList<String> getAllowedPackages() {
+        return null;
+    }
+
+    private final PlayerSession.Listener mPlayerListener = new PlayerSession.Listener() {
+        @Override
+        public void onPlayStateChanged(PlaybackState state) {
+            switch (state.getState()) {
+                case PlaybackState.PLAYSTATE_PLAYING:
+                    onPlaybackStarted();
+                    break;
+                case PlaybackState.PLAYSTATE_STOPPED:
+                case PlaybackState.PLAYSTATE_ERROR:
+                    onPlaybackEnded();
+                    break;
+            }
+        }
+    };
+
+    public class PlayerBinder extends IPlayerService.Stub {
+        @Override
+        public void sendRequest(String action, Bundle params, IRequestCallback cb) {
+            if (RequestUtils.ACTION_SET_CONTENT.equals(action)) {
+                mSession.setContent(params);
+            } else if (RequestUtils.ACTION_SET_NEXT_CONTENT.equals(action)) {
+                mSession.setNextContent(params);
+            }
+        }
+
+        @Override
+        public void registerCallback(final IPlayerCallback cb) throws RemoteException {
+            if (!mCbs.contains(cb)) {
+                mCbs.add(cb);
+                cb.asBinder().linkToDeath(new IBinder.DeathRecipient() {
+                    @Override
+                    public void binderDied() {
+                        mCbs.remove(cb);
+                    }
+                }, 0);
+            }
+            try {
+                cb.onSessionChanged(getSessionToken());
+            } catch (RemoteException e) {
+                mCbs.remove(cb);
+                throw e;
+            }
+        }
+
+        @Override
+        public void unregisterCallback(IPlayerCallback cb) throws RemoteException {
+            mCbs.remove(cb);
+        }
+
+        @Override
+        public MediaSessionToken getSessionToken() throws RemoteException {
+            return mSession.getSessionToken();
+        }
+    }
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
new file mode 100644
index 0000000..a2d7897
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.onemedia;
+
+import android.content.Context;
+import android.content.Intent;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionToken;
+import android.media.session.PlaybackState;
+import android.media.session.TransportPerformer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import com.android.onemedia.playback.LocalRenderer;
+import com.android.onemedia.playback.Renderer;
+import com.android.onemedia.playback.RendererFactory;
+
+public class PlayerSession {
+    private static final String TAG = "PlayerSession";
+
+    protected MediaSession mSession;
+    protected Context mContext;
+    protected RendererFactory mRendererFactory;
+    protected LocalRenderer mRenderer;
+    protected MediaSession.Callback mCallback;
+    protected Renderer.Listener mRenderListener;
+    protected TransportPerformer mPerformer;
+
+    protected PlaybackState mPlaybackState;
+    protected Listener mListener;
+
+    public PlayerSession(Context context) {
+        mContext = context;
+        mRendererFactory = new RendererFactory();
+        mRenderer = new LocalRenderer(context, null);
+        mCallback = new ControllerCb();
+        mRenderListener = new RenderListener();
+        mPlaybackState = new PlaybackState();
+        mPlaybackState.setActions(PlaybackState.ACTION_PAUSE
+                | PlaybackState.ACTION_PLAY);
+
+        mRenderer.registerListener(mRenderListener);
+    }
+
+    public void createSession() {
+        if (mSession != null) {
+            mSession.release();
+        }
+        MediaSessionManager man = (MediaSessionManager) mContext
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
+        Log.d(TAG, "Creating session for package " + mContext.getBasePackageName());
+        mSession = man.createSession("OneMedia");
+        mSession.addCallback(mCallback);
+        mPerformer = mSession.setTransportPerformerEnabled();
+        mPerformer.addListener(new TransportListener());
+        mPerformer.setPlaybackState(mPlaybackState);
+        mSession.publish();
+    }
+
+    public void onDestroy() {
+        if (mSession != null) {
+            mSession.release();
+        }
+        if (mRenderer != null) {
+            mRenderer.unregisterListener(mRenderListener);
+            mRenderer.onDestroy();
+        }
+    }
+
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+    public MediaSessionToken getSessionToken() {
+        return mSession.getSessionToken();
+    }
+
+    public void setContent(Bundle request) {
+        mRenderer.setContent(request);
+    }
+
+    public void setNextContent(Bundle request) {
+        mRenderer.setNextContent(request);
+    }
+
+    public interface Listener {
+        public void onPlayStateChanged(PlaybackState state);
+    }
+
+    private class RenderListener implements Renderer.Listener {
+
+        @Override
+        public void onError(int type, int extra, Bundle extras, Throwable error) {
+            Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
+            mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+            if (error != null) {
+                mPlaybackState.setErrorMessage(error.getLocalizedMessage());
+            }
+            mPerformer.setPlaybackState(mPlaybackState);
+            if (mListener != null) {
+                mListener.onPlayStateChanged(mPlaybackState);
+            }
+        }
+
+        @Override
+        public void onStateChanged(int newState) {
+            if (newState != Renderer.STATE_ERROR) {
+                mPlaybackState.setErrorMessage(null);
+            }
+            switch (newState) {
+                case Renderer.STATE_ENDED:
+                case Renderer.STATE_STOPPED:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_STOPPED);
+                    break;
+                case Renderer.STATE_INIT:
+                case Renderer.STATE_PREPARING:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_BUFFERING);
+                    break;
+                case Renderer.STATE_ERROR:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+                    break;
+                case Renderer.STATE_PAUSED:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_PAUSED);
+                    break;
+                case Renderer.STATE_PLAYING:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_PLAYING);
+                    break;
+                default:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+                    mPlaybackState.setErrorMessage("unkown state");
+                    break;
+            }
+            mPlaybackState.setPosition(mRenderer.getSeekPosition());
+            mPerformer.setPlaybackState(mPlaybackState);
+            if (mListener != null) {
+                mListener.onPlayStateChanged(mPlaybackState);
+            }
+        }
+
+        @Override
+        public void onBufferingUpdate(int percent) {
+        }
+
+        @Override
+        public void onFocusLost() {
+            Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED);
+            mPlaybackState.setState(PlaybackState.PLAYSTATE_PAUSED);
+            mPlaybackState.setPosition(mRenderer.getSeekPosition());
+            mPerformer.setPlaybackState(mPlaybackState);
+            if (mListener != null) {
+                mListener.onPlayStateChanged(mPlaybackState);
+            }
+        }
+
+        @Override
+        public void onNextStarted() {
+        }
+
+    }
+
+    private class ControllerCb extends MediaSession.Callback {
+
+        @Override
+        public void onMediaButton(Intent mediaRequestIntent) {
+            if (Intent.ACTION_MEDIA_BUTTON.equals(mediaRequestIntent.getAction())) {
+                KeyEvent event = (KeyEvent) mediaRequestIntent
+                        .getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                switch (event.getKeyCode()) {
+                    case KeyEvent.KEYCODE_MEDIA_PLAY:
+                        Log.d(TAG, "play button received");
+                        mRenderer.onPlay();
+                        break;
+                    case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                        Log.d(TAG, "pause button received");
+                        mRenderer.onPause();
+                        break;
+                }
+            }
+        }
+    }
+
+    private class TransportListener extends TransportPerformer.Listener {
+        @Override
+        public void onPlay() {
+            mRenderer.onPlay();
+        }
+
+        @Override
+        public void onPause() {
+            mRenderer.onPause();
+        }
+    }
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/IRequestCallback.aidl b/tests/OneMedia/src/com/android/onemedia/playback/IRequestCallback.aidl
new file mode 100644
index 0000000..c5a30a8
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/IRequestCallback.aidl
@@ -0,0 +1,22 @@
+/* Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+
+oneway interface IRequestCallback {
+    void onResult(in Bundle result);
+}
\ No newline at end of file
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java
new file mode 100644
index 0000000..7f62f66
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java
@@ -0,0 +1,704 @@
+package com.android.onemedia.playback;
+
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.media.MediaPlayer;
+import android.media.MediaPlayer.OnBufferingUpdateListener;
+import android.media.MediaPlayer.OnCompletionListener;
+import android.media.MediaPlayer.OnErrorListener;
+import android.media.MediaPlayer.OnPreparedListener;
+import android.net.Uri;
+import android.net.http.AndroidHttpClient;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Helper class for wrapping a MediaPlayer and doing a lot of the default work
+ * to play audio. This class is not currently thread safe and all calls to it
+ * should be made on the same thread.
+ */
+public class LocalRenderer extends Renderer implements OnPreparedListener,
+        OnBufferingUpdateListener, OnCompletionListener, OnErrorListener,
+        OnAudioFocusChangeListener {
+    private static final String TAG = "MediaPlayerManager";
+    private static final boolean DEBUG = true;
+    private static long sDebugInstanceId = 0;
+
+    private static final String[] SUPPORTED_FEATURES = {
+            FEATURE_SET_CONTENT,
+            FEATURE_SET_NEXT_CONTENT,
+            FEATURE_PLAY,
+            FEATURE_PAUSE,
+            FEATURE_NEXT,
+            FEATURE_PREVIOUS,
+            FEATURE_SEEK_TO,
+            FEATURE_STOP
+    };
+
+    /**
+     * These are the states where it is valid to call play directly on the
+     * MediaPlayer.
+     */
+    private static final int CAN_PLAY = STATE_READY | STATE_PAUSED | STATE_ENDED;
+    /**
+     * These are the states where we expect the MediaPlayer to be ready in the
+     * future, so we can set a flag to start playing when it is.
+     */
+    private static final int CAN_READY_PLAY = STATE_INIT | STATE_PREPARING;
+    /**
+     * The states when it is valid to call pause on the MediaPlayer.
+     */
+    private static final int CAN_PAUSE = STATE_PLAYING;
+    /**
+     * The states where it is valid to call seek on the MediaPlayer.
+     */
+    private static final int CAN_SEEK = STATE_READY | STATE_PLAYING | STATE_PAUSED | STATE_ENDED;
+    /**
+     * The states where we expect the MediaPlayer to be ready in the future and
+     * can store a seek position to set later.
+     */
+    private static final int CAN_READY_SEEK = STATE_INIT | STATE_PREPARING;
+    /**
+     * The states where it is valid to call stop on the MediaPlayer.
+     */
+    private static final int CAN_STOP = STATE_READY | STATE_PLAYING | STATE_PAUSED | STATE_ENDED;
+    /**
+     * The states where it is valid to get the current play position and the
+     * duration from the MediaPlayer.
+     */
+    private static final int CAN_GET_POSITION = STATE_READY | STATE_PLAYING | STATE_PAUSED;
+
+
+
+    private class PlayerContent {
+        public final String source;
+        public final Map<String, String> headers;
+
+        public PlayerContent(String source, Map<String, String> headers) {
+            this.source = source;
+            this.headers = headers;
+        }
+    }
+
+    private class AsyncErrorRetriever extends AsyncTask<HttpGet, Void, Void> {
+        private final long errorId;
+        private boolean closeHttpClient;
+
+        public AsyncErrorRetriever(long errorId) {
+            this.errorId = errorId;
+            closeHttpClient = false;
+        }
+
+        public boolean cancelRequestLocked(boolean closeHttp) {
+            closeHttpClient = closeHttp;
+            return this.cancel(false);
+        }
+
+        @Override
+        protected Void doInBackground(HttpGet[] params) {
+            synchronized (mErrorLock) {
+                if (isCancelled() || mHttpClient == null) {
+                    if (mErrorRetriever == this) {
+                        mErrorRetriever = null;
+                    }
+                    return null;
+                }
+                mSafeToCloseClient = false;
+            }
+            final PlaybackError error = new PlaybackError();
+            try {
+                HttpResponse response = mHttpClient.execute(params[0]);
+                synchronized (mErrorLock) {
+                    if (mErrorId != errorId || mError == null) {
+                        // A new error has occurred, abort
+                        return null;
+                    }
+                    error.type = mError.type;
+                    error.extra = mError.extra;
+                    error.errorMessage = mError.errorMessage;
+                }
+                final int code = response.getStatusLine().getStatusCode();
+                if (code >= 300) {
+                    error.extra = code;
+                }
+                final Bundle errorExtras = new Bundle();
+                Header[] headers = response.getAllHeaders();
+                if (headers != null && headers.length > 0) {
+                    for (Header header : headers) {
+                        errorExtras.putString(header.getName(), header.getValue());
+                    }
+                    error.errorExtras = errorExtras;
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "IOException requesting from server, unable to get more exact error");
+            } finally {
+                synchronized (mErrorLock) {
+                    mSafeToCloseClient = true;
+                    if (mErrorRetriever == this) {
+                        mErrorRetriever = null;
+                    }
+                    if (isCancelled()) {
+                        if (closeHttpClient) {
+                            mHttpClient.close();
+                            mHttpClient = null;
+                        }
+                        return null;
+                    }
+                }
+            }
+            mHandler.post(new Runnable() {
+                    @Override
+                public void run() {
+                    synchronized (mErrorLock) {
+                        if (mErrorId == errorId) {
+                            setError(error.type, error.extra, error.errorExtras, null);
+                        }
+                    }
+                }
+            });
+            return null;
+        }
+    }
+
+    private int mState = STATE_INIT;
+
+    private AudioManager mAudioManager;
+    private MediaPlayer mPlayer;
+    private PlayerContent mContent;
+    private MediaPlayer mNextPlayer;
+    private PlayerContent mNextContent;
+    private SurfaceHolder mHolder;
+    private SurfaceHolder.Callback mHolderCB;
+    private Context mContext;
+
+    private Handler mHandler = new Handler();
+
+    private AndroidHttpClient mHttpClient = AndroidHttpClient.newInstance("TUQ");
+    // The ongoing error request thread if there is one. This should only be
+    // modified while mErrorLock is held.
+    private AsyncErrorRetriever mErrorRetriever;
+    // This is set to false while a server request is being made to retrieve
+    // the current error. It should only be set while mErrorLock is held.
+    private boolean mSafeToCloseClient = true;
+    private final Object mErrorLock = new Object();
+    // A tracking id for the current error. This should only be modified while
+    // mErrorLock is held.
+    private long mErrorId = 0;
+    // The current error state of this player. This is cleared when the state
+    // leaves an error state and set when it enters one. This should only be
+    // modified when mErrorLock is held.
+    private PlaybackError mError;
+
+    private boolean mPlayOnReady;
+    private int mSeekOnReady;
+    private boolean mHasAudioFocus;
+    private long mDebugId = sDebugInstanceId++;
+
+    public LocalRenderer(Context context, Bundle params) {
+        super(context, params);
+        mContext = context;
+        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+    }
+
+    @Override
+    protected void initFeatures(Bundle params) {
+        for (String feature : SUPPORTED_FEATURES) {
+            mFeatures.add(feature);
+        }
+    }
+
+    /**
+     * Call this when completely finished with the MediaPlayerManager to have it
+     * clean up. The instance may not be used again after this is called.
+     */
+    @Override
+    public void onDestroy() {
+        synchronized (mErrorLock) {
+            if (DEBUG) {
+                Log.d(TAG, "onDestroy, error retriever? " + mErrorRetriever + " safe to close? "
+                        + mSafeToCloseClient + " client? " + mHttpClient);
+            }
+            if (mErrorRetriever != null) {
+                mErrorRetriever.cancelRequestLocked(true);
+                mErrorRetriever = null;
+            }
+            // Increment the error id to ensure no errors are sent after this
+            // point.
+            mErrorId++;
+            if (mSafeToCloseClient) {
+                mHttpClient.close();
+                mHttpClient = null;
+            }
+        }
+    }
+
+    @Override
+    public void onPrepared(MediaPlayer player) {
+        if (!isCurrentPlayer(player)) {
+            return;
+        }
+        setState(STATE_READY);
+        if (DEBUG) {
+            Log.d(TAG, mDebugId + ": Finished preparing, seekOnReady is " + mSeekOnReady);
+        }
+        if (mSeekOnReady >= 0) {
+            onSeekTo(mSeekOnReady);
+            mSeekOnReady = -1;
+        }
+        if (mPlayOnReady) {
+            player.start();
+            setState(STATE_PLAYING);
+        }
+    }
+
+    @Override
+    public void onBufferingUpdate(MediaPlayer player, int percent) {
+        if (!isCurrentPlayer(player)) {
+            return;
+        }
+        pushOnBufferingUpdate(percent);
+    }
+
+    @Override
+    public void onCompletion(MediaPlayer player) {
+        if (!isCurrentPlayer(player)) {
+            return;
+        }
+        if (DEBUG) {
+            Log.d(TAG, mDebugId + ": Completed item. Have next item? " + (mNextPlayer != null));
+        }
+        if (mNextPlayer != null) {
+            if (mPlayer != null) {
+                mPlayer.release();
+            }
+            mPlayer = mNextPlayer;
+            mContent = mNextContent;
+            mNextPlayer = null;
+            mNextContent = null;
+            pushOnNextStarted();
+            return;
+        }
+        setState(STATE_ENDED);
+    }
+
+    @Override
+    public boolean onError(MediaPlayer player, int what, int extra) {
+        if (!isCurrentPlayer(player)) {
+            return false;
+        }
+        if (DEBUG) {
+            Log.d(TAG, mDebugId + ": Entered error state, what: " + what + " extra: " + extra);
+        }
+        synchronized (mErrorLock) {
+            ++mErrorId;
+            mError = new PlaybackError();
+            mError.type = what;
+            mError.extra = extra;
+        }
+
+        if (what == MediaPlayer.MEDIA_ERROR_UNKNOWN && extra == MediaPlayer.MEDIA_ERROR_IO
+                && mContent != null && mContent.source.startsWith("http")) {
+            HttpGet request = new HttpGet(mContent.source);
+            if (mContent.headers != null) {
+                for (String key : mContent.headers.keySet()) {
+                    request.addHeader(key, mContent.headers.get(key));
+                }
+            }
+            synchronized (mErrorLock) {
+                if (mErrorRetriever != null) {
+                    mErrorRetriever.cancelRequestLocked(false);
+                }
+                mErrorRetriever = new AsyncErrorRetriever(mErrorId);
+                mErrorRetriever.execute(request);
+            }
+        } else {
+            setError(what, extra, null, null);
+        }
+        return true;
+    }
+
+    @Override
+    public void onAudioFocusChange(int focusChange) {
+        // TODO figure out appropriate logic for handling focus loss at the TUQ
+        // level.
+        switch (focusChange) {
+            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+                if (mState == STATE_PLAYING) {
+                    onPause();
+                    mPlayOnReady = true;
+                }
+                mHasAudioFocus = false;
+                break;
+            case AudioManager.AUDIOFOCUS_LOSS:
+                if (mState == STATE_PLAYING) {
+                    onPause();
+                    mPlayOnReady = false;
+                }
+                pushOnFocusLost();
+                mHasAudioFocus = false;
+                break;
+            case AudioManager.AUDIOFOCUS_GAIN:
+                mHasAudioFocus = true;
+                if (mPlayOnReady) {
+                    onPlay();
+                }
+                break;
+            default:
+                Log.d(TAG, "Unknown focus change event " + focusChange);
+                break;
+        }
+    }
+
+    @Override
+    public void setContent(Bundle request) {
+        setContent(request, null);
+    }
+
+    /**
+     * Prepares the player for the given playback request. If the holder is null
+     * it is assumed this is an audio only source. If playOnReady is set to true
+     * the media will begin playing as soon as it can.
+     */
+    public void setContent(Bundle request, SurfaceHolder holder) {
+        String source = request.getString(RequestUtils.EXTRA_KEY_SOURCE);
+        Map<String, String> headers = null; // request.mHeaders;
+        boolean playOnReady = true; // request.mPlayOnReady;
+        if (DEBUG) {
+            Log.d(TAG, mDebugId + ": Settings new content. Have a player? " + (mPlayer != null)
+                    + " have a next player? " + (mNextPlayer != null));
+        }
+        cleanUpPlayer();
+        setState(STATE_PREPARING);
+        mPlayOnReady = playOnReady;
+        mSeekOnReady = -1;
+        final MediaPlayer newPlayer = new MediaPlayer();
+
+        requestAudioFocus();
+
+        mPlayer = newPlayer;
+        mContent = new PlayerContent(source, headers);
+        try {
+            if (headers != null) {
+                Uri sourceUri = Uri.parse(source);
+                newPlayer.setDataSource(mContext, sourceUri, headers);
+            } else {
+                newPlayer.setDataSource(source);
+            }
+        } catch (Exception e) {
+            setError(Listener.ERROR_LOAD_FAILED, 0, null, e);
+            return;
+        }
+        if (isHolderReady(holder, newPlayer)) {
+            preparePlayer(newPlayer, true);
+        }
+    }
+
+    @Override
+    public void setNextContent(Bundle request) {
+        String source = request.getString(RequestUtils.EXTRA_KEY_SOURCE);
+        Map<String, String> headers = null; // request.mHeaders;
+
+        // TODO support video
+
+        if (DEBUG) {
+            Log.d(TAG, mDebugId + ": Setting next content. Have player? " + (mPlayer != null)
+                    + " have next player? " + (mNextPlayer != null));
+        }
+
+        if (mPlayer == null) {
+            // The manager isn't being used to play anything, don't try to
+            // set a next.
+            return;
+        }
+        if (mNextPlayer != null) {
+            // Before setting up the new one clear out the old one and release
+            // it to ensure it doesn't play.
+            mPlayer.setNextMediaPlayer(null);
+            mNextPlayer.release();
+            mNextPlayer = null;
+            mNextContent = null;
+        }
+        if (source == null) {
+            // If there's no new content we're done
+            return;
+        }
+        final MediaPlayer newPlayer = new MediaPlayer();
+
+        try {
+            if (headers != null) {
+                Uri sourceUri = Uri.parse(source);
+                newPlayer.setDataSource(mContext, sourceUri, headers);
+            } else {
+                newPlayer.setDataSource(source);
+            }
+        } catch (Exception e) {
+            newPlayer.release();
+            // Don't return an error until we get to this item in playback
+            return;
+        }
+
+        if (preparePlayer(newPlayer, false)) {
+            mPlayer.setNextMediaPlayer(newPlayer);
+            mNextPlayer = newPlayer;
+            mNextContent = new PlayerContent(source, headers);
+        }
+    }
+
+    private void requestAudioFocus() {
+        int result = mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
+                AudioManager.AUDIOFOCUS_GAIN);
+        mHasAudioFocus = result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
+    }
+
+    /**
+     * Start the player if possible or queue it to play when ready. If the
+     * player is in a state where it will never be ready returns false.
+     *
+     * @return true if the content was started or will be started later
+     */
+    @Override
+    public boolean onPlay() {
+        MediaPlayer player = mPlayer;
+        if (player != null && mState == STATE_PLAYING) {
+            // already playing, just return
+            return true;
+        }
+        if (!mHasAudioFocus) {
+            requestAudioFocus();
+        }
+        if (player != null && canPlay()) {
+            player.start();
+            setState(STATE_PLAYING);
+        } else if (canReadyPlay()) {
+            mPlayOnReady = true;
+        } else if (!isPlaying()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Pause the player if possible or set it to not play when ready. If the
+     * player is in a state where it will never be ready returns false.
+     *
+     * @return true if the content was paused or will wait to play when ready
+     *         later
+     */
+    @Override
+    public boolean onPause() {
+        MediaPlayer player = mPlayer;
+        // If the user paused us make sure we won't start playing again until
+        // asked to
+        mPlayOnReady = false;
+        if (player != null && (mState & CAN_PAUSE) != 0) {
+            player.pause();
+            setState(STATE_PAUSED);
+        } else if (!isPaused()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Seek to a given position in the media. If the seek succeeded or will be
+     * performed when loading is complete returns true. If the position is not
+     * in range or the player will never be ready returns false.
+     *
+     * @param position The position to seek to in milliseconds
+     * @return true if playback was moved or will be moved when ready
+     */
+    @Override
+    public boolean onSeekTo(int position) {
+        MediaPlayer player = mPlayer;
+        if (player != null && (mState & CAN_SEEK) != 0) {
+            if (position < 0 || position >= getDuration()) {
+                return false;
+            } else {
+                if (mState == STATE_ENDED) {
+                    player.start();
+                    player.pause();
+                    setState(STATE_PAUSED);
+                }
+                player.seekTo(position);
+            }
+        } else if ((mState & CAN_READY_SEEK) != 0) {
+            mSeekOnReady = position;
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Stop the player. It cannot be used again until
+     * {@link #setContent(String, boolean)} is called.
+     *
+     * @return true if stopping the player succeeded
+     */
+    @Override
+    public boolean onStop() {
+        cleanUpPlayer();
+        setState(STATE_STOPPED);
+        return true;
+    }
+
+    public boolean isPlaying() {
+        return mState == STATE_PLAYING;
+    }
+
+    public boolean isPaused() {
+        return mState == STATE_PAUSED;
+    }
+
+    @Override
+    public long getSeekPosition() {
+        return ((mState & CAN_GET_POSITION) == 0) ? -1 : mPlayer.getCurrentPosition();
+    }
+
+    @Override
+    public long getDuration() {
+        return ((mState & CAN_GET_POSITION) == 0) ? -1 : mPlayer.getDuration();
+    }
+
+    private boolean canPlay() {
+        return ((mState & CAN_PLAY) != 0) && mHasAudioFocus;
+    }
+
+    private boolean canReadyPlay() {
+        return (mState & CAN_PLAY) != 0 || (mState & CAN_READY_PLAY) != 0;
+    }
+
+    /**
+     * Sends a state update if the listener exists
+     */
+    private void setState(int state) {
+        if (state == mState) {
+            return;
+        }
+        Log.d(TAG, "Entering state " + state + " from state " + mState);
+        mState = state;
+        if (state != STATE_ERROR) {
+            // Don't notify error here, it'll get sent via onError
+            pushOnStateChanged(state);
+        }
+    }
+
+    private boolean preparePlayer(final MediaPlayer player, boolean current) {
+        player.setOnPreparedListener(this);
+        player.setOnBufferingUpdateListener(this);
+        player.setOnCompletionListener(this);
+        player.setOnErrorListener(this);
+        try {
+            player.prepareAsync();
+            if (current) {
+                setState(STATE_PREPARING);
+            }
+        } catch (IllegalStateException e) {
+            if (current) {
+                setError(Listener.ERROR_PREPARE_ERROR, 0, null, e);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @param extra
+     * @param e
+     */
+    private void setError(int type, int extra, Bundle extras, Exception e) {
+        setState(STATE_ERROR);
+        pushOnError(type, extra, extras, e);
+        cleanUpPlayer();
+        return;
+    }
+
+    /**
+     * Checks if the holder is ready and either sets up a callback to wait for
+     * it or sets it directly. If
+     *
+     * @param holder
+     * @param player
+     * @return
+     */
+    private boolean isHolderReady(final SurfaceHolder holder, final MediaPlayer player) {
+        mHolder = holder;
+        if (holder != null) {
+            if (holder.getSurface() != null && holder.getSurface().isValid()) {
+                player.setDisplay(holder);
+                return true;
+            } else {
+                Log.w(TAG, "Holder not null, waiting for it to be ready");
+                // If the holder isn't ready yet add a callback to set the
+                // holder when it's ready.
+                SurfaceHolder.Callback cb = new SurfaceHolder.Callback() {
+                        @Override
+                    public void surfaceDestroyed(SurfaceHolder arg0) {
+                    }
+
+                        @Override
+                    public void surfaceCreated(SurfaceHolder arg0) {
+                        if (player.equals(mPlayer)) {
+                            player.setDisplay(arg0);
+                            preparePlayer(player, true);
+                        }
+                    }
+
+                        @Override
+                    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
+                    }
+                };
+                mHolderCB = cb;
+                holder.addCallback(cb);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private void cleanUpPlayer() {
+        if (DEBUG) {
+            Log.d(TAG, mDebugId + ": Cleaning up current player");
+        }
+        synchronized (mErrorLock) {
+            mError = null;
+            if (mErrorRetriever != null) {
+                mErrorRetriever.cancelRequestLocked(false);
+                // Don't set to null as we may need to cancel again with true if
+                // the object gets destroyed.
+            }
+        }
+        mAudioManager.abandonAudioFocus(this);
+
+        SurfaceHolder.Callback cb = mHolderCB;
+        mHolderCB = null;
+        SurfaceHolder holder = mHolder;
+        mHolder = null;
+        if (holder != null && cb != null) {
+            holder.removeCallback(cb);
+        }
+
+        MediaPlayer player = mPlayer;
+        mPlayer = null;
+        if (player != null) {
+            player.reset();
+            player.release();
+        }
+    }
+
+    private boolean isCurrentPlayer(MediaPlayer player) {
+        return player.equals(mPlayer);
+    }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java b/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java
new file mode 100644
index 0000000..f9e6794
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/MediaItem.java
@@ -0,0 +1,59 @@
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.v7.media.MediaItemMetadata;
+
+/**
+ * TODO: Insert description here. (generated by epastern)
+ */
+public class MediaItem implements Parcelable {
+    private Bundle mBundle;
+
+    public MediaItem() {
+
+    }
+
+    private MediaItem(Parcel in) {
+        mBundle = in.readBundle();
+    }
+
+    public String getTitle() {
+        return mBundle.getString(MediaItemMetadata.KEY_TITLE);
+    }
+
+    public String getArtist() {
+        return mBundle.getString(MediaItemMetadata.KEY_ALBUM_ARTIST);
+    }
+
+    /* (non-Javadoc)
+     * @see android.os.Parcelable#describeContents()
+     */
+    @Override
+    public int describeContents() {
+        // TODO(epastern): Auto-generated method stub
+        return 0;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBundle(mBundle);
+    }
+
+    public static final Parcelable.Creator<MediaItem> CREATOR
+            = new Parcelable.Creator<MediaItem>() {
+                public MediaItem createFromParcel(Parcel in) {
+                    return new MediaItem(in);
+                }
+
+                public MediaItem[] newArray(int size) {
+                    return new MediaItem[size];
+                }
+            };
+
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/PlaybackError.java b/tests/OneMedia/src/com/android/onemedia/playback/PlaybackError.java
new file mode 100644
index 0000000..72d936c
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/PlaybackError.java
@@ -0,0 +1,10 @@
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+
+public class PlaybackError {
+    public int type;
+    public int extra;
+    public String errorMessage;
+    public Bundle errorExtras;
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/Renderer.java b/tests/OneMedia/src/com/android/onemedia/playback/Renderer.java
new file mode 100644
index 0000000..2451bdf
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/Renderer.java
@@ -0,0 +1,199 @@
+package com.android.onemedia.playback;
+
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * TODO: Insert description here. (generated by epastern)
+ */
+public abstract class Renderer {
+    public static final String FEATURE_SET_CONTENT = "com.android.media.SET_CONTENT";
+    public static final String FEATURE_SET_NEXT_CONTENT = "com.android.media.SET_NEXT_CONTENT";
+    public static final String FEATURE_PLAY = "com.android.media.PLAY";
+    public static final String FEATURE_PAUSE = "com.android.media.PAUSE";
+    public static final String FEATURE_NEXT = "com.android.media.NEXT";
+    public static final String FEATURE_PREVIOUS = "com.android.media.PREVIOUS";
+    public static final String FEATURE_SEEK_TO = "com.android.media.SEEK_TO";
+    public static final String FEATURE_STOP = "com.android.media.STOP";
+    // TODO move states somewhere else
+    public static final int STATE_ERROR = 0;
+    /**
+     * The state MediaPlayerManager starts in before any action has been
+     * performed.
+     */
+    public static final int STATE_INIT = 1 << 0;
+    /**
+     * Indicates the source has been set and it is being prepared/buffered
+     * before starting playback.
+     */
+    public static final int STATE_PREPARING = 1 << 1;
+    /**
+     * The media is ready and playback can be started.
+     */
+    public static final int STATE_READY = 1 << 2;
+    /**
+     * The media is currently playing.
+     */
+    public static final int STATE_PLAYING = 1 << 3;
+    /**
+     * The media is currently paused.
+     */
+    public static final int STATE_PAUSED = 1 << 4;
+    /**
+     * The service has been stopped and cannot be started again until a new
+     * source has been set.
+     */
+    public static final int STATE_STOPPED = 1 << 5;
+    /**
+     * The playback has reached the end. It can be restarted by calling play().
+     */
+    public static final int STATE_ENDED = 1 << 6;
+
+    // TODO decide on proper way of describing features
+    protected List<String> mFeatures = new ArrayList<String>();
+    protected List<Listener> mListeners = new ArrayList<Listener>();
+
+    public Renderer(Context context, Bundle params) {
+        onCreate(params);
+        initFeatures(params);
+    }
+
+    abstract public void setContent(Bundle request);
+
+    public void onCreate(Bundle params) {
+        // Do nothing by default
+    }
+
+    public void setNextContent(Bundle request) {
+        throw new UnsupportedOperationException("setNextContent() is not supported.");
+    }
+
+    public List<String> getFeatures() {
+        return mFeatures;
+    }
+
+    public boolean onPlay() {
+        throw new UnsupportedOperationException("play is not supported.");
+    }
+
+    public boolean onPause() {
+        throw new UnsupportedOperationException("pause is not supported.");
+    }
+
+    public boolean onNext() {
+        throw new UnsupportedOperationException("next is not supported.");
+    }
+
+    public boolean onPrevious() {
+        throw new UnsupportedOperationException("previous is not supported.");
+    }
+
+    public boolean onStop() {
+        throw new UnsupportedOperationException("stop is not supported.");
+    }
+
+    public boolean onSeekTo(int time) {
+        throw new UnsupportedOperationException("seekTo is not supported.");
+    }
+
+    public long getSeekPosition() {
+        throw new UnsupportedOperationException("getSeekPosition is not supported.");
+    }
+
+    public long getDuration() {
+        throw new UnsupportedOperationException("getDuration is not supported.");
+    }
+
+    public int getPlayState() {
+        throw new UnsupportedOperationException("getPlayState is not supported.");
+    }
+
+    public void onDestroy() {
+        // Do nothing by default
+    }
+
+    public void registerListener(Listener listener) {
+        if (!mListeners.contains(listener)) {
+            mListeners.add(listener);
+        }
+    }
+
+    public void unregisterListener(Listener listener) {
+        mListeners.remove(listener);
+    }
+
+    protected void initFeatures(Bundle params) {
+        mFeatures.add(FEATURE_SET_CONTENT);
+    }
+
+    protected void pushOnError(int type, int extra, Bundle extras, Throwable error) {
+        for (Listener listener : mListeners) {
+            listener.onError(type, extra, extras, error);
+        }
+    }
+
+    protected void pushOnStateChanged(int newState) {
+        for (Listener listener : mListeners) {
+            listener.onStateChanged(newState);
+        }
+    }
+
+    protected void pushOnBufferingUpdate(int percent) {
+        for (Listener listener : mListeners) {
+            listener.onBufferingUpdate(percent);
+        }
+    }
+
+    protected void pushOnFocusLost() {
+        for (Listener listener : mListeners) {
+            listener.onFocusLost();
+        }
+    }
+
+    protected void pushOnNextStarted() {
+        for (Listener listener : mListeners) {
+            listener.onNextStarted();
+        }
+    }
+
+    public interface Listener {
+        public static final int ERROR_LOAD_FAILED = 1770;
+        public static final int ERROR_PREPARE_ERROR = 1771;
+        public static final int ERROR_PLAYBACK_FAILED = 1772;
+
+        /**
+         * When an error occurs onError will be called but not onStateChanged.
+         * The Manager will remain in the error state until
+         * {@link #setContent()} is called again.
+         */
+        public void onError(int type, int extra, Bundle extras,
+                Throwable error);
+
+        /**
+         * onStateChanged will be called whenever the state of the manager
+         * transitions except to an error state.
+         */
+        public void onStateChanged(int newState);
+
+        /**
+         * This is a passthrough of
+         * {@link MediaPlayer.OnBufferingUpdateListener}.
+         */
+        public void onBufferingUpdate(int percent);
+
+        /**
+         * Called when audio focus is lost and it is not transient or ducking.
+         */
+        public void onFocusLost();
+
+        /**
+         * Called when the next item was started playing. Only called if a next
+         * item has been set and the current item has ended.
+         */
+        public void onNextStarted();
+    }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/RendererFactory.java b/tests/OneMedia/src/com/android/onemedia/playback/RendererFactory.java
new file mode 100644
index 0000000..f333fce
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/RendererFactory.java
@@ -0,0 +1,22 @@
+package com.android.onemedia.playback;
+
+import android.content.Context;
+import android.media.MediaRouter;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * TODO: Insert description here.
+ */
+public class RendererFactory {
+    private static final String TAG = "RendererFactory";
+
+    public Renderer createRenderer(MediaRouter.RouteInfo route, Context context, Bundle params) {
+        if (route.getPlaybackType() == MediaRouter.RouteInfo.PLAYBACK_TYPE_LOCAL) {
+            return new LocalRenderer(context, params);
+        }
+        Log.e(TAG, "Unable to create renderer for route of playback type "
+                + route.getPlaybackType());
+        return null;
+    }
+}
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java b/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java
new file mode 100644
index 0000000..9b50dad
--- /dev/null
+++ b/tests/OneMedia/src/com/android/onemedia/playback/RequestUtils.java
@@ -0,0 +1,53 @@
+package com.android.onemedia.playback;
+
+import android.os.Bundle;
+import android.support.v7.media.MediaItemMetadata;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * TODO: Insert description here. (generated by epastern)
+ */
+public class RequestUtils {
+    public static final String ACTION_SET_CONTENT = "set_content";
+    public static final String ACTION_SET_NEXT_CONTENT = "set_next_content";
+
+    public static final String EXTRA_KEY_SOURCE = "source";
+    public static final String EXTRA_KEY_METADATA = "metadata";
+    public static final String EXTRA_KEY_HEADERS = "headers";
+
+    private RequestUtils() {
+    }
+
+    public static class ContentBuilder {
+        private Bundle mBundle;
+
+        public ContentBuilder() {
+            mBundle = new Bundle();
+        }
+
+        public ContentBuilder setSource(String source) {
+            mBundle.putString(EXTRA_KEY_SOURCE, source);
+            return this;
+        }
+
+        /**
+         * @see MediaItemMetadata
+         * @param metadata The metadata for this item
+         */
+        public ContentBuilder setMetadata(Bundle metadata) {
+            mBundle.putBundle(EXTRA_KEY_METADATA, metadata);
+            return this;
+        }
+
+        public ContentBuilder setHeaders(HashMap<String, String> headers) {
+            mBundle.putSerializable(EXTRA_KEY_HEADERS, headers);
+            return this;
+        }
+
+        public Bundle build() {
+            return mBundle;
+        }
+    }
+}
diff --git a/tests/RenderThreadTest/Android.mk b/tests/RenderThreadTest/Android.mk
new file mode 100644
index 0000000..bdcba2e
--- /dev/null
+++ b/tests/RenderThreadTest/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 := RenderThreadTest
+
+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/RenderThreadTest/AndroidManifest.xml b/tests/RenderThreadTest/AndroidManifest.xml
new file mode 100644
index 0000000..c76cfce
--- /dev/null
+++ b/tests/RenderThreadTest/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.renderthread"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="18"
+        android:targetSdkVersion="18" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".SubActivity"
+            android:theme="@style/AppTheme.Transparent" />
+    </application>
+
+</manifest>
diff --git a/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png b/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg
new file mode 100644
index 0000000..755232d
--- /dev/null
+++ b/tests/RenderThreadTest/res/drawable-xhdpi/starry_night_bg.jpg
Binary files differ
diff --git a/tests/RenderThreadTest/res/layout/activity_main.xml b/tests/RenderThreadTest/res/layout/activity_main.xml
new file mode 100644
index 0000000..1fd5459
--- /dev/null
+++ b/tests/RenderThreadTest/res/layout/activity_main.xml
@@ -0,0 +1,12 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity" >
+
+    <ListView android:id="@android:id/list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:divider="@null" />
+
+</FrameLayout>
diff --git a/tests/RenderThreadTest/res/layout/activity_sub.xml b/tests/RenderThreadTest/res/layout/activity_sub.xml
new file mode 100644
index 0000000..713cee4
--- /dev/null
+++ b/tests/RenderThreadTest/res/layout/activity_sub.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+
+    <View
+        android:id="@+id/bg_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/starry_night_bg" />
+
+    <LinearLayout
+        android:id="@+id/my_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical" >
+
+        <View
+            android:id="@+id/from_left"
+            android:layout_width="match_parent"
+            android:layout_height="48dip"
+            android:background="#7000FF00" />
+
+        <View
+            android:id="@+id/from_right"
+            android:layout_width="match_parent"
+            android:layout_height="0dip"
+            android:layout_margin="80dip"
+            android:layout_weight="1"
+            android:background="#90FF0000" />
+
+        <View
+            android:id="@+id/from_left"
+            android:layout_width="match_parent"
+            android:layout_height="48dip"
+            android:background="#7000FF00" />
+    </LinearLayout>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/tests/RenderThreadTest/res/layout/item_layout.xml b/tests/RenderThreadTest/res/layout/item_layout.xml
new file mode 100644
index 0000000..5bdb1ac
--- /dev/null
+++ b/tests/RenderThreadTest/res/layout/item_layout.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:textAppearance="?android:attr/textAppearanceListItemSmall"
+    android:gravity="center_vertical"
+    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
+    android:background="#33b5e5"
+/>
\ No newline at end of file
diff --git a/tests/RenderThreadTest/res/values/strings.xml b/tests/RenderThreadTest/res/values/strings.xml
new file mode 100644
index 0000000..f782e98
--- /dev/null
+++ b/tests/RenderThreadTest/res/values/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">Render Thread</string>
+    <string name="action_settings">Settings</string>
+    <string name="hello_world">Hello world!</string>
+
+</resources>
diff --git a/tests/RenderThreadTest/res/values/styles.xml b/tests/RenderThreadTest/res/values/styles.xml
new file mode 100644
index 0000000..f6b5d6a
--- /dev/null
+++ b/tests/RenderThreadTest/res/values/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="android:Theme.Holo.Light">
+    </style>
+
+    <style name="AppTheme.Transparent">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
+
+</resources>
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
new file mode 100644
index 0000000..09531fd
--- /dev/null
+++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
@@ -0,0 +1,158 @@
+
+package com.example.renderthread;
+
+import android.animation.TimeInterpolator;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.view.RenderNode;
+import android.view.HardwareRenderer;
+import android.view.ThreadedRenderer;
+import android.view.View;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MainActivity extends Activity implements OnItemClickListener {
+
+    static final int DURATION = 400;
+
+    static final String KEY_NAME = "name";
+    static final String KEY_CLASS = "clazz";
+
+    static Map<String,?> make(String name) {
+        Map<String,Object> ret = new HashMap<String,Object>();
+        ret.put(KEY_NAME, name);
+        return ret;
+    }
+
+    @SuppressWarnings("serial")
+    static final ArrayList<Map<String,?>> SAMPLES = new ArrayList<Map<String,?>>() {{
+        for (int i = 1; i < 25; i++) {
+            add(make("List Item: " + i));
+        }
+    }};
+
+    Handler mHandler = new Handler();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        HardwareRenderer.sUseRenderThread = true;
+        setContentView(R.layout.activity_main);
+        ListView lv = (ListView) findViewById(android.R.id.list);
+        lv.setDrawSelectorOnTop(true);
+        lv.setAdapter(new SimpleAdapter(this, SAMPLES,
+                R.layout.item_layout, new String[] { KEY_NAME },
+                new int[] { android.R.id.text1 }));
+        lv.setOnItemClickListener(this);
+        getActionBar().setTitle("MainActivity");
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        ListView lv = (ListView) findViewById(android.R.id.list);
+        for (int i = 0; i < lv.getChildCount(); i++) {
+            lv.getChildAt(i).animate().translationY(0).setDuration(DURATION);
+        }
+    }
+
+    private static class DisplayListAnimator {
+        private static final TimeInterpolator sDefaultInterpolator =
+                new AccelerateDecelerateInterpolator();
+
+        RenderNode mDisplayList;
+        float mFromValue;
+        float mDelta;
+        long mDuration = DURATION * 2;
+        long mStartTime;
+
+        DisplayListAnimator(View view, float translateXBy) {
+            mDelta = translateXBy;
+            mFromValue = view.getTranslationY();
+            mDisplayList = view.getDisplayList();
+        }
+
+        boolean animate(long currentTime) {
+            if (mStartTime == 0) mStartTime = currentTime;
+
+            float fraction = (float)(currentTime - mStartTime) / mDuration;
+            if (fraction > 1) {
+                return false;
+            }
+            fraction = sDefaultInterpolator.getInterpolation(fraction);
+            float translation = mFromValue + (mDelta * fraction);
+            mDisplayList.setTranslationY(translation);
+            return fraction < 1f;
+        }
+    }
+
+    private static class AnimationExecutor implements Runnable {
+        DisplayListAnimator[] mAnimations;
+        ThreadedRenderer mRenderer;
+
+        AnimationExecutor(ThreadedRenderer renderer, DisplayListAnimator[] animations) {
+            mRenderer = renderer;
+            mAnimations = animations;
+            ThreadedRenderer.postToRenderThread(this);
+        }
+
+        @Override
+        public void run() {
+            boolean hasMore = false;
+            long now = SystemClock.uptimeMillis();
+            for (DisplayListAnimator animator : mAnimations) {
+                hasMore |= animator.animate(now);
+            }
+            mRenderer.repeatLastDraw();
+            if (hasMore) {
+                ThreadedRenderer.postToRenderThread(this);
+            }
+        }
+
+    }
+
+    @Override
+    public void onItemClick(final AdapterView<?> adapterView, View clickedView,
+            int clickedPosition, long clickedId) {
+        int topPosition = adapterView.getFirstVisiblePosition();
+        int dy = adapterView.getHeight();
+        final DisplayListAnimator[] animators = new DisplayListAnimator[adapterView.getChildCount()];
+        for (int i = 0; i < adapterView.getChildCount(); i++) {
+            int pos = topPosition + i;
+            View child = adapterView.getChildAt(i);
+            float delta = (pos - clickedPosition) * 1.1f;
+            if (delta == 0) delta = -1;
+            animators[i] = new DisplayListAnimator(child, dy * delta);
+        }
+        adapterView.invalidate();
+        adapterView.post(new Runnable() {
+
+            @Override
+            public void run() {
+                new AnimationExecutor((ThreadedRenderer) adapterView.getHardwareRenderer(), animators);
+            }
+        });
+        //mHandler.postDelayed(mLaunchActivity, (long) (DURATION * .4));
+        mLaunchActivity.run();
+    }
+
+    private Runnable mLaunchActivity = new Runnable() {
+
+        @Override
+        public void run() {
+            startActivity(new Intent(MainActivity.this, SubActivity.class));
+            overridePendingTransition(0, 0);
+        }
+    };
+
+}
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.java
new file mode 100644
index 0000000..892cbae
--- /dev/null
+++ b/tests/RenderThreadTest/src/com/example/renderthread/SubActivity.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.example.renderthread;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.SystemClock;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class SubActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        long before = SystemClock.currentThreadTimeMillis();
+        setContentView(R.layout.activity_sub);
+        getActionBar().setTitle("SubActivity");
+        // Simulate being a real app!
+        while (SystemClock.currentThreadTimeMillis() - before < 100) {
+            View v = new View(this, null);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        ViewGroup container = (ViewGroup) findViewById(R.id.my_container);
+        int dx = getWindowManager().getDefaultDisplay().getWidth();
+        for (int i = 0; i < container.getChildCount(); i++) {
+            View child = container.getChildAt(i);
+            int dir = child.getId() == R.id.from_left ? 1 : -1;
+            child.setTranslationX(dx * dir);
+            child.animate().translationX(0).setDuration(MainActivity.DURATION);
+        }
+        View bg = findViewById(R.id.bg_container);
+        bg.setAlpha(0f);
+        bg.animate().alpha(1f).setDuration(MainActivity.DURATION);
+    }
+
+    @Override
+    public void onBackPressed() {
+        super.onBackPressed();
+        overridePendingTransition(0, 0);
+    }
+}
diff --git a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
index cceed16..3bd35a7 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ActivityManagerPermissionTests.java
@@ -37,7 +37,7 @@
     }
 
     @SmallTest
-	public void testREORDER_TASKS() {
+    public void testREORDER_TASKS() {
         try {
             mAm.moveTaskToFront(0, 0, null);
             fail("IActivityManager.moveTaskToFront did not throw SecurityException as"
@@ -67,7 +67,7 @@
         } catch (RemoteException e) {
             fail("Unexpected remote exception");
         }
-	}
+    }
 
     @SmallTest
     public void testCHANGE_CONFIGURATION() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
index 4dfe0fe..322b853 100644
--- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java
@@ -32,7 +32,7 @@
  */
 public class ServiceManagerPermissionTests extends TestCase {
     @SmallTest
-	public void testAddService() {
+    public void testAddService() {
         try {
             // The security in the service manager is that you can't replace
             // a service that is already published.
@@ -43,7 +43,7 @@
         } catch (SecurityException e) {
             // expected
         }
-	}
+    }
 
     @SmallTest
     public void testSetPermissionController() {
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
index 90b6abc..b12ed94 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
@@ -18,6 +18,7 @@
 
 import junit.framework.TestCase;
 
+import android.media.AudioManager;
 import android.os.Binder;
 import android.os.IVibratorService;
 import android.os.Process;
@@ -47,7 +48,8 @@
      */
     public void testVibrate() throws RemoteException {
         try {
-            mVibratorService.vibrate(Process.myUid(), null, 2000, new Binder());
+            mVibratorService.vibrate(Process.myUid(), null, 2000, AudioManager.STREAM_ALARM,
+                    new Binder());
             fail("vibrate did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
@@ -63,7 +65,8 @@
      */
     public void testVibratePattern() throws RemoteException {
         try {
-            mVibratorService.vibratePattern(Process.myUid(), null, new long[] {0}, 0, new Binder());
+            mVibratorService.vibratePattern(Process.myUid(), null, new long[] {0}, 0,
+                    AudioManager.STREAM_ALARM, new Binder());
             fail("vibratePattern did not throw SecurityException as expected");
         } catch (SecurityException e) {
             // expected
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 df32ee1..6f5788a 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -41,7 +41,7 @@
     }
 
     @SmallTest
-	public void testMANAGE_APP_TOKENS() {
+    public void testMANAGE_APP_TOKENS() {
         try {
             mWm.pauseKeyDispatching(null);
             fail("IWindowManager.pauseKeyDispatching did not throw SecurityException as"
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 5c11054..f9a2d19 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -2378,6 +2378,9 @@
                     current->setFullResPaths(mFullResPaths);
                 }
                 count = current->slurpResourceTree(bundle, String8(res));
+                if (i > 0 && count > 0) {
+                  count = current->filter(bundle);
+                }
 
                 if (count < 0) {
                     totalCount = count;
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 26b10a6..49b8b55 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -51,7 +51,7 @@
           mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),
           mUpdate(false), mExtending(false),
           mRequireLocalization(false), mPseudolocalize(false),
-          mWantUTF16(false), mValues(false),
+          mWantUTF16(false), mValues(false), mIncludeMetaData(false),
           mCompressionMethod(0), mJunkPath(false), mOutputAPKFile(NULL),
           mManifestPackageNameOverride(NULL), mInstrumentationPackageNameOverride(NULL),
           mAutoAddOverlay(false), mGenDependencies(false),
@@ -59,9 +59,10 @@
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
           mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
           mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
-          mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL), mExtraPackages(NULL),
-          mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
-          mUseCrunchCache(false), mErrorOnFailedInsert(false), mOutputTextSymbols(NULL),
+          mVersionCode(NULL), mVersionName(NULL), mReplaceVersion(false), mCustomPackage(NULL),
+          mExtraPackages(NULL), mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false),
+          mProduct(NULL), mUseCrunchCache(false), mErrorOnFailedInsert(false),
+          mErrorOnMissingConfigEntry(false), mOutputTextSymbols(NULL),
           mSingleCrunchInputFile(NULL), mSingleCrunchOutputFile(NULL),
           mArgc(0), mArgv(NULL)
         {}
@@ -98,6 +99,8 @@
     void setWantUTF16(bool val) { mWantUTF16 = val; }
     bool getValues(void) const { return mValues; }
     void setValues(bool val) { mValues = val; }
+    bool getIncludeMetaData(void) const { return mIncludeMetaData; }
+    void setIncludeMetaData(bool val) { mIncludeMetaData = val; }
     int getCompressionMethod(void) const { return mCompressionMethod; }
     void setCompressionMethod(int val) { mCompressionMethod = val; }
     bool getJunkPath(void) const { return mJunkPath; }
@@ -114,6 +117,8 @@
     void setGenDependencies(bool val) { mGenDependencies = val; }
     bool getErrorOnFailedInsert() { return mErrorOnFailedInsert; }
     void setErrorOnFailedInsert(bool val) { mErrorOnFailedInsert = val; }
+    bool getErrorOnMissingConfigEntry() { return mErrorOnMissingConfigEntry; }
+    void setErrorOnMissingConfigEntry(bool val) { mErrorOnMissingConfigEntry = val; }
 
     bool getUTF16StringsOption() {
         return mWantUTF16 || !isMinSdkAtLeast(SDK_FROYO);
@@ -161,6 +166,8 @@
     void setVersionCode(const char*  val) { mVersionCode = val; }
     const char* getVersionName() const { return mVersionName; }
     void setVersionName(const char* val) { mVersionName = val; }
+    bool getReplaceVersion() { return mReplaceVersion; }
+    void setReplaceVersion(bool val) { mReplaceVersion = val; }
     const char* getCustomPackage() const { return mCustomPackage; }
     void setCustomPackage(const char* val) { mCustomPackage = val; }
     const char* getExtraPackages() const { return mExtraPackages; }
@@ -252,6 +259,7 @@
     bool        mPseudolocalize;
     bool        mWantUTF16;
     bool        mValues;
+    bool        mIncludeMetaData;
     int         mCompressionMethod;
     bool        mJunkPath;
     const char* mOutputAPKFile;
@@ -259,7 +267,6 @@
     const char* mInstrumentationPackageNameOverride;
     bool        mAutoAddOverlay;
     bool        mGenDependencies;
-    const char* mAssetSourceDir;
     const char* mCrunchedOutputDir;
     const char* mProguardFile;
     const char* mAndroidManifestFile;
@@ -280,6 +287,7 @@
     const char* mMaxSdkVersion;
     const char* mVersionCode;
     const char* mVersionName;
+    bool        mReplaceVersion;
     const char* mCustomPackage;
     const char* mExtraPackages;
     const char* mMaxResVersion;
@@ -288,6 +296,7 @@
     const char* mProduct;
     bool        mUseCrunchCache;
     bool        mErrorOnFailedInsert;
+    bool        mErrorOnMissingConfigEntry;
     const char* mOutputTextSymbols;
     const char* mSingleCrunchInputFile;
     const char* mSingleCrunchOutputFile;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index fe8bb68..44b8340 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -25,8 +25,9 @@
  */
 int doVersion(Bundle* bundle)
 {
-    if (bundle->getFileSpecCount() != 0)
+    if (bundle->getFileSpecCount() != 0) {
         printf("(ignoring extra arguments)\n");
+    }
     printf("Android Asset Packaging Tool, v0.2\n");
 
     return 0;
@@ -46,13 +47,14 @@
     zip = new ZipFile;
     result = zip->open(fileName, ZipFile::kOpenReadOnly);
     if (result != NO_ERROR) {
-        if (result == NAME_NOT_FOUND)
+        if (result == NAME_NOT_FOUND) {
             fprintf(stderr, "ERROR: '%s' not found\n", fileName);
-        else if (result == PERMISSION_DENIED)
+        } else if (result == PERMISSION_DENIED) {
             fprintf(stderr, "ERROR: '%s' access denied\n", fileName);
-        else
+        } else {
             fprintf(stderr, "ERROR: failed opening '%s' as Zip file\n",
                 fileName);
+        }
         delete zip;
         return NULL;
     }
@@ -73,8 +75,9 @@
     int flags;
 
     flags = ZipFile::kOpenReadWrite;
-    if (okayToCreate)
+    if (okayToCreate) {
         flags |= ZipFile::kOpenCreate;
+    }
 
     zip = new ZipFile;
     result = zip->open(fileName, flags);
@@ -94,12 +97,13 @@
  */
 const char* compressionName(int method)
 {
-    if (method == ZipEntry::kCompressStored)
+    if (method == ZipEntry::kCompressStored) {
         return "Stored";
-    else if (method == ZipEntry::kCompressDeflated)
+    } else if (method == ZipEntry::kCompressDeflated) {
         return "Deflated";
-    else
+    } else {
         return "Unknown";
+    }
 }
 
 /*
@@ -107,10 +111,11 @@
  */
 int calcPercent(long uncompressedLen, long compressedLen)
 {
-    if (!uncompressedLen)
+    if (!uncompressedLen) {
         return 0;
-    else
+    } else {
         return (int) (100.0 - (compressedLen * 100.0) / uncompressedLen + 0.5);
+    }
 }
 
 /*
@@ -135,8 +140,9 @@
     zipFileName = bundle->getFileSpecEntry(0);
 
     zip = openReadOnly(zipFileName);
-    if (zip == NULL)
+    if (zip == NULL) {
         goto bail;
+    }
 
     int count, i;
 
@@ -248,7 +254,9 @@
     Res_value value;
     if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
         if (value.dataType != Res_value::TYPE_STRING) {
-            if (outError != NULL) *outError = "attribute is not a string value";
+            if (outError != NULL) {
+                *outError = "attribute is not a string value";
+            }
             return String8();
         }
     }
@@ -266,7 +274,9 @@
     Res_value value;
     if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
         if (value.dataType != Res_value::TYPE_STRING) {
-            if (outError != NULL) *outError = "attribute is not a string value";
+            if (outError != NULL) {
+                *outError = "attribute is not a string value";
+            }
             return String8();
         }
     }
@@ -286,7 +296,9 @@
     if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
         if (value.dataType < Res_value::TYPE_FIRST_INT
                 || value.dataType > Res_value::TYPE_LAST_INT) {
-            if (outError != NULL) *outError = "attribute is not an integer value";
+            if (outError != NULL) {
+                *outError = "attribute is not an integer value";
+            }
             return defValue;
         }
     }
@@ -307,7 +319,9 @@
         }
         if (value.dataType < Res_value::TYPE_FIRST_INT
                 || value.dataType > Res_value::TYPE_LAST_INT) {
-            if (outError != NULL) *outError = "attribute is not an integer value";
+            if (outError != NULL) {
+                *outError = "attribute is not an integer value";
+            }
             return defValue;
         }
     }
@@ -330,7 +344,9 @@
         }
         resTable->resolveReference(&value, 0);
         if (value.dataType != Res_value::TYPE_STRING) {
-            if (outError != NULL) *outError = "attribute is not a string value";
+            if (outError != NULL) {
+                *outError = "attribute is not a string value";
+            }
             return String8();
         }
     }
@@ -340,6 +356,49 @@
     return str ? String8(str, len) : String8();
 }
 
+static void getResolvedResourceAttribute(Res_value* value, const ResTable* resTable,
+        const ResXMLTree& tree, uint32_t attrRes, String8* outError)
+{
+    ssize_t idx = indexOfAttribute(tree, attrRes);
+    if (idx < 0) {
+        if (outError != NULL) {
+            *outError = "attribute could not be found";
+        }
+        return;
+    }
+    if (tree.getAttributeValue(idx, value) != NO_ERROR) {
+        if (value->dataType == Res_value::TYPE_REFERENCE) {
+            resTable->resolveReference(value, 0);
+        }
+        // The attribute was found and was resolved if need be.
+        return;
+    }
+    if (outError != NULL) {
+        *outError = "error getting resolved resource attribute";
+    }
+}
+
+static void printResolvedResourceAttribute(const ResTable* resTable, const ResXMLTree& tree,
+        uint32_t attrRes, String8 attrLabel, String8* outError)
+{
+    Res_value value;
+    getResolvedResourceAttribute(&value, resTable, tree, attrRes, outError);
+    if (*outError != "") {
+        *outError = "error print resolved resource attribute";
+        return;
+    }
+    if (value.dataType == Res_value::TYPE_STRING) {
+        String8 result = getResolvedAttribute(resTable, tree, attrRes, outError);
+        printf("%s='%s'", attrLabel.string(),
+                ResTable::normalizeForOutput(result.string()).string());
+    } else if (Res_value::TYPE_FIRST_INT <= value.dataType &&
+            value.dataType <= Res_value::TYPE_LAST_INT) {
+        printf("%s='%d'", attrLabel.string(), value.data);
+    } else {
+        printf("%s='0x%x'", attrLabel.string(), (int)value.data);
+    }
+}
+
 // These are attribute resource constants for the platform, as found
 // in android.R.attr
 enum {
@@ -349,6 +408,7 @@
     PERMISSION_ATTR = 0x01010006,
     RESOURCE_ATTR = 0x01010025,
     DEBUGGABLE_ATTR = 0x0101000f,
+    VALUE_ATTR = 0x01010024,
     VERSION_CODE_ATTR = 0x0101021b,
     VERSION_NAME_ATTR = 0x0101021c,
     SCREEN_ORIENTATION_ATTR = 0x0101001e,
@@ -378,7 +438,7 @@
     BANNER_ATTR = 0x10103f2,
 };
 
-const char *getComponentName(String8 &pkgName, String8 &componentName) {
+String8 getComponentName(String8 &pkgName, String8 &componentName) {
     ssize_t idx = componentName.find(".");
     String8 retStr(pkgName);
     if (idx == 0) {
@@ -387,9 +447,9 @@
         retStr += ".";
         retStr += componentName;
     } else {
-        return componentName.string();
+        return componentName;
     }
-    return retStr.string();
+    return retStr;
 }
 
 static void printCompatibleScreens(ResXMLTree& tree) {
@@ -428,6 +488,29 @@
     printf("\n");
 }
 
+static void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) {
+    printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string());
+    if (maxSdkVersion != -1) {
+         printf(" maxSdkVersion='%d'", maxSdkVersion);
+    }
+    printf("\n");
+
+    if (optional) {
+        printf("optional-permission: name='%s'",
+                ResTable::normalizeForOutput(name.string()).string());
+        if (maxSdkVersion != -1) {
+            printf(" maxSdkVersion='%d'", maxSdkVersion);
+        }
+        printf("\n");
+    }
+}
+
+static void printUsesImpliedPermission(const String8& name, const String8& reason) {
+    printf("uses-implied-permission: name='%s' reason='%s'\n",
+            ResTable::normalizeForOutput(name.string()).string(),
+            ResTable::normalizeForOutput(reason.string()).string());
+}
+
 Vector<String8> getNfcAidCategories(AssetManager& assets, String8 xmlPath, bool offHost,
         String8 *outError = NULL)
 {
@@ -635,7 +718,7 @@
                         goto bail;
                     }
                     String8 pkg = getAttribute(tree, NULL, "package", NULL);
-                    printf("package: %s\n", pkg.string());
+                    printf("package: %s\n", ResTable::normalizeForOutput(pkg.string()).string());
                 } else if (depth == 2 && tag == "permission") {
                     String8 error;
                     String8 name = getAttribute(tree, NAME_ATTR, &error);
@@ -643,7 +726,8 @@
                         fprintf(stderr, "ERROR: %s\n", error.string());
                         goto bail;
                     }
-                    printf("permission: %s\n", name.string());
+                    printf("permission: %s\n",
+                            ResTable::normalizeForOutput(name.string()).string());
                 } else if (depth == 2 && tag == "uses-permission") {
                     String8 error;
                     String8 name = getAttribute(tree, NAME_ATTR, &error);
@@ -651,11 +735,9 @@
                         fprintf(stderr, "ERROR: %s\n", error.string());
                         goto bail;
                     }
-                    printf("uses-permission: %s\n", name.string());
-                    int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
-                    if (!req) {
-                        printf("optional-permission: %s\n", name.string());
-                    }
+                    printUsesPermission(name,
+                            getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0,
+                            getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1));
                 }
             }
         } else if (strcmp("badging", option) == 0) {
@@ -668,7 +750,9 @@
             const size_t NC = configs.size();
             for (size_t i=0; i<NC; i++) {
                 int dens = configs[i].density;
-                if (dens == 0) dens = 160;
+                if (dens == 0) {
+                    dens = 160;
+                }
                 densities.add(dens);
             }
 
@@ -802,7 +886,8 @@
                             printf("supports-input: '");
                             const size_t N = supportedInput.size();
                             for (size_t i=0; i<N; i++) {
-                                printf("%s", supportedInput[i].string());
+                                printf("%s", ResTable::normalizeForOutput(
+                                        supportedInput[i].string()).string());
                                 if (i != N - 1) {
                                     printf("' '");
                                 } else {
@@ -815,25 +900,27 @@
                         withinSupportsInput = false;
                     } else if (depth < 3) {
                         if (withinActivity && isMainActivity) {
-                            const char *aName = getComponentName(pkg, activityName);
+                            String8 aName(getComponentName(pkg, activityName));
                             if (isLauncherActivity) {
                                 printf("launchable-activity:");
-                                if (aName != NULL) {
-                                    printf(" name='%s' ", aName);
+                                if (aName.length() > 0) {
+                                    printf(" name='%s' ",
+                                            ResTable::normalizeForOutput(aName.string()).string());
                                 }
                                 printf(" label='%s' icon='%s'\n",
-                                        activityLabel.string(),
-                                        activityIcon.string());
+                                        ResTable::normalizeForOutput(activityLabel.string()).string(),
+                                        ResTable::normalizeForOutput(activityIcon.string()).string());
                             }
                             if (isLeanbackLauncherActivity) {
                                 printf("leanback-launchable-activity:");
-                                if (aName != NULL) {
-                                    printf(" name='%s' ", aName);
+                                if (aName.length() > 0) {
+                                    printf(" name='%s' ",
+                                            ResTable::normalizeForOutput(aName.string()).string());
                                 }
                                 printf(" label='%s' icon='%s' banner='%s'\n",
-                                        activityLabel.string(),
-                                        activityIcon.string(),
-                                        activityBanner.string());
+                                        ResTable::normalizeForOutput(activityLabel.string()).string(),
+                                        ResTable::normalizeForOutput(activityIcon.string()).string(),
+                                        ResTable::normalizeForOutput(activityBanner.string()).string());
                             }
                         }
                         if (!hasIntentFilter) {
@@ -890,7 +977,8 @@
                         goto bail;
                     }
                     pkg = getAttribute(tree, NULL, "package", NULL);
-                    printf("package: name='%s' ", pkg.string());
+                    printf("package: name='%s' ",
+                            ResTable::normalizeForOutput(pkg.string()).string());
                     int32_t versionCode = getIntegerAttribute(tree, VERSION_CODE_ATTR, &error);
                     if (error != "") {
                         fprintf(stderr, "ERROR getting 'android:versionCode' attribute: %s\n", error.string());
@@ -906,7 +994,8 @@
                         fprintf(stderr, "ERROR getting 'android:versionName' attribute: %s\n", error.string());
                         goto bail;
                     }
-                    printf("versionName='%s'\n", versionName.string());
+                    printf("versionName='%s'\n",
+                            ResTable::normalizeForOutput(versionName.string()).string());
                 } else if (depth == 2) {
                     withinApplication = false;
                     if (tag == "application") {
@@ -921,13 +1010,14 @@
                             if (llabel != "") {
                                 if (localeStr == NULL || strlen(localeStr) == 0) {
                                     label = llabel;
-                                    printf("application-label:'%s'\n", llabel.string());
+                                    printf("application-label:'%s'\n",
+                                            ResTable::normalizeForOutput(llabel.string()).string());
                                 } else {
                                     if (label == "") {
                                         label = llabel;
                                     }
                                     printf("application-label-%s:'%s'\n", localeStr,
-                                            llabel.string());
+                                           ResTable::normalizeForOutput(llabel.string()).string());
                                 }
                             }
                         }
@@ -939,7 +1029,8 @@
                             assets.setConfiguration(tmpConfig);
                             String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
                             if (icon != "") {
-                                printf("application-icon-%d:'%s'\n", densities[i], icon.string());
+                                printf("application-icon-%d:'%s'\n", densities[i],
+                                        ResTable::normalizeForOutput(icon.string()).string());
                             }
                         }
                         assets.setConfiguration(config);
@@ -954,8 +1045,9 @@
                             fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string());
                             goto bail;
                         }
-                        printf("application: label='%s' ", label.string());
-                        printf("icon='%s'\n", icon.string());
+                        printf("application: label='%s' ",
+                                ResTable::normalizeForOutput(label.string()).string());
+                        printf("icon='%s'\n", ResTable::normalizeForOutput(icon.string()).string());
                         if (testOnly != 0) {
                             printf("testOnly='%d'\n", testOnly);
                         }
@@ -979,7 +1071,8 @@
                                 goto bail;
                             }
                             if (name == "Donut") targetSdk = 4;
-                            printf("sdkVersion:'%s'\n", name.string());
+                            printf("sdkVersion:'%s'\n",
+                                    ResTable::normalizeForOutput(name.string()).string());
                         } else if (code != -1) {
                             targetSdk = code;
                             printf("sdkVersion:'%d'\n", code);
@@ -998,7 +1091,8 @@
                                 goto bail;
                             }
                             if (name == "Donut" && targetSdk < 4) targetSdk = 4;
-                            printf("targetSdkVersion:'%s'\n", name.string());
+                            printf("targetSdkVersion:'%s'\n",
+                                    ResTable::normalizeForOutput(name.string()).string());
                         } else if (code != -1) {
                             if (targetSdk < code) {
                                 targetSdk = code;
@@ -1103,7 +1197,8 @@
                                 specScreenLandscapeFeature = true;
                             }
                             printf("uses-feature%s:'%s'\n",
-                                    req ? "" : "-not-required", name.string());
+                                    req ? "" : "-not-required",
+                                            ResTable::normalizeForOutput(name.string()).string());
                         } else {
                             int vers = getIntegerAttribute(tree,
                                     GL_ES_VERSION_ATTR, &error);
@@ -1161,12 +1256,11 @@
                             } else if (name == "android.permission.WRITE_CALL_LOG") {
                                 hasWriteCallLogPermission = true;
                             }
-                            printf("uses-permission:'%s'\n", name.string());
-                            int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
-                            if (!req) {
-                                printf("optional-permission:'%s'\n", name.string());
-                            }
-                        } else {
+
+                            printUsesPermission(name,
+                                    getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1) == 0,
+                                    getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, NULL, -1));
+                       } else {
                             fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
                                     error.string());
                             goto bail;
@@ -1174,7 +1268,8 @@
                     } else if (tag == "uses-package") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
                         if (name != "" && error == "") {
-                            printf("uses-package:'%s'\n", name.string());
+                            printf("uses-package:'%s'\n",
+                                    ResTable::normalizeForOutput(name.string()).string());
                         } else {
                             fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
                                     error.string());
@@ -1183,7 +1278,8 @@
                     } else if (tag == "original-package") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
                         if (name != "" && error == "") {
-                            printf("original-package:'%s'\n", name.string());
+                            printf("original-package:'%s'\n",
+                                    ResTable::normalizeForOutput(name.string()).string());
                         } else {
                             fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
                                     error.string());
@@ -1192,7 +1288,8 @@
                     } else if (tag == "supports-gl-texture") {
                         String8 name = getAttribute(tree, NAME_ATTR, &error);
                         if (name != "" && error == "") {
-                            printf("supports-gl-texture:'%s'\n", name.string());
+                            printf("supports-gl-texture:'%s'\n",
+                                    ResTable::normalizeForOutput(name.string()).string());
                         } else {
                             fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
                                     error.string());
@@ -1207,7 +1304,8 @@
                             String8 publicKey = getAttribute(tree, PUBLIC_KEY_ATTR, &error);
                             if (publicKey != "" && error == "") {
                                 printf("package-verifier: name='%s' publicKey='%s'\n",
-                                        name.string(), publicKey.string());
+                                        ResTable::normalizeForOutput(name.string()).string(),
+                                        ResTable::normalizeForOutput(publicKey.string()).string());
                             }
                         }
                     }
@@ -1276,7 +1374,8 @@
                             int req = getIntegerAttribute(tree,
                                     REQUIRED_ATTR, NULL, 1);
                             printf("uses-library%s:'%s'\n",
-                                    req ? "" : "-not-required", libraryName.string());
+                                    req ? "" : "-not-required", ResTable::normalizeForOutput(
+                                            libraryName.string()).string());
                         } else if (tag == "receiver") {
                             withinReceiver = true;
                             receiverName = getAttribute(tree, NAME_ATTR, &error);
@@ -1302,8 +1401,8 @@
                             serviceName = getAttribute(tree, NAME_ATTR, &error);
 
                             if (error != "") {
-                                fprintf(stderr, "ERROR getting 'android:name' attribute for"
-                                        " service: %s\n", error.string());
+                                fprintf(stderr, "ERROR getting 'android:name' attribute for "
+                                        "service:%s\n", error.string());
                                 goto bail;
                             }
 
@@ -1322,15 +1421,39 @@
                                 fprintf(stderr, "ERROR getting 'android:permission' attribute for"
                                         " service '%s': %s\n", serviceName.string(), 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;
+                        } else if (bundle->getIncludeMetaData() && tag == "meta-data") {
+                            String8 metaDataName = getAttribute(tree, NAME_ATTR, &error);
+                            if (error != "") {
+                                fprintf(stderr, "ERROR getting 'android:name' attribute for "
+                                        "meta-data:%s\n", error.string());
+                                goto bail;
+                            }
+                            printf("meta-data: name='%s' ",
+                                    ResTable::normalizeForOutput(metaDataName.string()).string());
+                            printResolvedResourceAttribute(&res, tree, VALUE_ATTR, String8("value"),
+                                    &error);
+                            if (error != "") {
+                                // Try looking for a RESOURCE_ATTR
+                                error = "";
+                                printResolvedResourceAttribute(&res, tree, RESOURCE_ATTR,
+                                        String8("resource"), &error);
+                                if (error != "") {
+                                    fprintf(stderr, "ERROR getting 'android:value' or "
+                                            "'android:resource' attribute for "
+                                            "meta-data:%s\n", error.string());
+                                    goto bail;
+                                }
+                            }
+                            printf("\n");
+                        } 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;
+                            }
                         }
                     }
                 } else if (depth == 4) {
@@ -1387,14 +1510,16 @@
                             }
                         }
                     }
-                } else if ((depth == 5) && withinIntentFilter){
+                } else if ((depth == 5) && withinIntentFilter) {
                     String8 action;
                     if (tag == "action") {
                         action = getAttribute(tree, NAME_ATTR, &error);
                         if (error != "") {
-                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n", error.string());
+                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
+                                    error.string());
                             goto bail;
                         }
+
                         if (withinActivity) {
                             if (action == "android.intent.action.MAIN") {
                                 isMainActivity = true;
@@ -1429,7 +1554,8 @@
                     if (tag == "category") {
                         String8 category = getAttribute(tree, NAME_ATTR, &error);
                         if (error != "") {
-                            fprintf(stderr, "ERROR getting 'name' attribute: %s\n", error.string());
+                            fprintf(stderr, "ERROR getting 'name' attribute: %s\n",
+                                    error.string());
                             goto bail;
                         }
                         if (withinActivity) {
@@ -1446,15 +1572,15 @@
             // Pre-1.6 implicitly granted permission compatibility logic
             if (targetSdk < 4) {
                 if (!hasWriteExternalStoragePermission) {
-                    printf("uses-permission:'android.permission.WRITE_EXTERNAL_STORAGE'\n");
-                    printf("uses-implied-permission:'android.permission.WRITE_EXTERNAL_STORAGE'," \
-                            "'targetSdkVersion < 4'\n");
+                    printUsesPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"));
+                    printUsesImpliedPermission(String8("android.permission.WRITE_EXTERNAL_STORAGE"),
+                            String8("targetSdkVersion < 4"));
                     hasWriteExternalStoragePermission = true;
                 }
                 if (!hasReadPhoneStatePermission) {
-                    printf("uses-permission:'android.permission.READ_PHONE_STATE'\n");
-                    printf("uses-implied-permission:'android.permission.READ_PHONE_STATE'," \
-                            "'targetSdkVersion < 4'\n");
+                    printUsesPermission(String8("android.permission.READ_PHONE_STATE"));
+                    printUsesImpliedPermission(String8("android.permission.READ_PHONE_STATE"),
+                            String8("targetSdkVersion < 4"));
                 }
             }
 
@@ -1463,22 +1589,22 @@
             // do this (regardless of target API version) because we can't have
             // an app with write permission but not read permission.
             if (!hasReadExternalStoragePermission && hasWriteExternalStoragePermission) {
-                printf("uses-permission:'android.permission.READ_EXTERNAL_STORAGE'\n");
-                printf("uses-implied-permission:'android.permission.READ_EXTERNAL_STORAGE'," \
-                        "'requested WRITE_EXTERNAL_STORAGE'\n");
+                printUsesPermission(String8("android.permission.READ_EXTERNAL_STORAGE"));
+                printUsesImpliedPermission(String8("android.permission.READ_EXTERNAL_STORAGE"),
+                        String8("requested WRITE_EXTERNAL_STORAGE"));
             }
 
             // Pre-JellyBean call log permission compatibility.
             if (targetSdk < 16) {
                 if (!hasReadCallLogPermission && hasReadContactsPermission) {
-                    printf("uses-permission:'android.permission.READ_CALL_LOG'\n");
-                    printf("uses-implied-permission:'android.permission.READ_CALL_LOG'," \
-                            "'targetSdkVersion < 16 and requested READ_CONTACTS'\n");
+                    printUsesPermission(String8("android.permission.READ_CALL_LOG"));
+                    printUsesImpliedPermission(String8("android.permission.READ_CALL_LOG"),
+                            String8("targetSdkVersion < 16 and requested READ_CONTACTS"));
                 }
                 if (!hasWriteCallLogPermission && hasWriteContactsPermission) {
-                    printf("uses-permission:'android.permission.WRITE_CALL_LOG'\n");
-                    printf("uses-implied-permission:'android.permission.WRITE_CALL_LOG'," \
-                            "'targetSdkVersion < 16 and requested WRITE_CONTACTS'\n");
+                    printUsesPermission(String8("android.permission.WRITE_CALL_LOG"));
+                    printUsesImpliedPermission(String8("android.permission.WRITE_CALL_LOG"),
+                            String8("targetSdkVersion < 16 and requested WRITE_CONTACTS"));
                 }
             }
 
@@ -1503,7 +1629,7 @@
                     printf("uses-implied-feature:'android.hardware.camera'," \
                             "'requested android.hardware.camera.autofocus feature'\n");
                 } else if (hasCameraPermission) {
-                    // if app wants to use camera but didn't request the feature, we infer 
+                    // if app wants to use camera but didn't request the feature, we infer
                     // that it meant to, and further that it wants autofocus
                     // (which was the 1.0 - 1.5 behavior)
                     printf("uses-feature:'android.hardware.camera'\n");
@@ -1656,7 +1782,9 @@
             if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0
                     && requiresSmallestWidthDp > 0) {
                 int compatWidth = compatibleWidthLimitDp;
-                if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp;
+                if (compatWidth <= 0) {
+                    compatWidth = requiresSmallestWidthDp;
+                }
                 if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) {
                     smallScreen = -1;
                 } else {
@@ -1701,10 +1829,18 @@
                         || compatibleWidthLimitDp > 0) ? -1 : 0;
             }
             printf("supports-screens:");
-            if (smallScreen != 0) printf(" 'small'");
-            if (normalScreen != 0) printf(" 'normal'");
-            if (largeScreen != 0) printf(" 'large'");
-            if (xlargeScreen != 0) printf(" 'xlarge'");
+            if (smallScreen != 0) {
+                printf(" 'small'");
+            }
+            if (normalScreen != 0) {
+                printf(" 'normal'");
+            }
+            if (largeScreen != 0) {
+                printf(" 'large'");
+            }
+            if (xlargeScreen != 0) {
+                printf(" 'xlarge'");
+            }
             printf("\n");
             printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false");
             if (requiresSmallestWidthDp > 0) {
@@ -1740,7 +1876,8 @@
                 if (dir->getFileCount() > 0) {
                     printf("native-code:");
                     for (size_t i=0; i<dir->getFileCount(); i++) {
-                        printf(" '%s'", dir->getFileName(i).string());
+                        printf(" '%s'", ResTable::normalizeForOutput(
+                                dir->getFileName(i).string()).string());
                     }
                     printf("\n");
                 }
@@ -1813,7 +1950,8 @@
         } else {
             if (bundle->getJunkPath()) {
                 String8 storageName = String8(fileName).getPathLeaf();
-                printf(" '%s' as '%s'...\n", fileName, storageName.string());
+                printf(" '%s' as '%s'...\n", fileName,
+                        ResTable::normalizeForOutput(storageName.string()).string());
                 result = zip->add(fileName, storageName.string(),
                                   bundle->getCompressionMethod(), NULL);
             } else {
@@ -1823,12 +1961,13 @@
         }
         if (result != NO_ERROR) {
             fprintf(stderr, "Unable to add '%s' to '%s'", bundle->getFileSpecEntry(i), zipFileName);
-            if (result == NAME_NOT_FOUND)
+            if (result == NAME_NOT_FOUND) {
                 fprintf(stderr, ": file not found\n");
-            else if (result == ALREADY_EXISTS)
+            } else if (result == ALREADY_EXISTS) {
                 fprintf(stderr, ": already exists in archive\n");
-            else
+            } else {
                 fprintf(stderr, "\n");
+            }
             goto bail;
         }
     }
@@ -2093,7 +2232,7 @@
  *
  * POSTCONDITIONS
  *  Destination directory will be updated to match the PNG files in
- *  the source directory. 
+ *  the source directory.
  */
 int doCrunch(Bundle* bundle)
 {
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index db74831..12f5b92 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -81,6 +81,12 @@
     png_bytepp allocRows;
 };
 
+static void log_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+    const char* imageName = (const char*) png_get_error_ptr(png_ptr);
+    fprintf(stderr, "%s: libpng warning: %s\n", imageName, warning_message);
+}
+
 static void read_png(const char* imageName,
                      png_structp read_ptr, png_infop read_info,
                      image_info* outImageInfo)
@@ -89,6 +95,8 @@
     int bit_depth, interlace_type, compression_type;
     int i;
 
+    png_set_error_fn(read_ptr, const_cast<char*>(imageName),
+            NULL /* use default errorfn */, log_warning);
     png_read_info(read_ptr, read_info);
 
     png_get_IHDR(read_ptr, read_info, &outImageInfo->width,
@@ -119,6 +127,8 @@
     if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
         png_set_gray_to_rgb(read_ptr);
 
+    png_set_interlace_handling(read_ptr);
+
     png_read_update_info(read_ptr, read_info);
 
     outImageInfo->rows = (png_bytepp)malloc(
@@ -931,7 +941,7 @@
                 gg = *row++;
                 bb = *row++;
                 aa = *row++;
-
+                
                 if (isGrayscale) {
                     *out++ = rr;
                 } else {
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index d1d3deb..33711fa 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -47,7 +47,7 @@
         " %s l[ist] [-v] [-a] file.{zip,jar,apk}\n"
         "   List contents of Zip-compatible archive.\n\n", gProgName);
     fprintf(stderr,
-        " %s d[ump] [--values] WHAT file.{apk} [asset [asset ...]]\n"
+        " %s d[ump] [--values] [--include-meta-data] WHAT file.{apk} [asset [asset ...]]\n"
         "   strings          Print the contents of the resource table string pool in the APK.\n"
         "   badging          Print the label and icon for the app declared in APK.\n"
         "   permissions      Print the permissions from the APK.\n"
@@ -138,6 +138,8 @@
         "   --debug-mode\n"
         "       inserts android:debuggable=\"true\" in to the application node of the\n"
         "       manifest, making the application debuggable even on production devices.\n"
+        "   --include-meta-data\n"
+        "       when used with \"dump badging\" also includes meta-data tags.\n"
         "   --min-sdk-version\n"
         "       inserts android:minSdkVersion in to manifest.  If the version is 7 or\n"
         "       higher, the default encoding for resources will be in UTF-8.\n"
@@ -151,6 +153,11 @@
         "       inserts android:versionCode in to manifest.\n"
         "   --version-name\n"
         "       inserts android:versionName in to manifest.\n"
+        "   --replace-version\n"
+        "       If --version-code and/or --version-name are specified, these\n"
+        "       values will replace any value already in the manifest. By\n"
+        "       default, nothing is changed if the manifest already defines\n"
+        "       these attributes.\n"
         "   --custom-package\n"
         "       generates R.java into a different package.\n"
         "   --extra-packages\n"
@@ -188,6 +195,8 @@
         "       with --debug-mode, --min-sdk-version, --target-sdk-version --version-code\n"
         "       and --version-name.\n"
         "       Insertion typically fails if the manifest already defines the attribute.\n"
+        "   --error-on-missing-config-entry\n"
+        "       Forces aapt to return an error if it fails to find an entry for a configuration.\n"
         "   --output-text-symbols\n"
         "       Generates a text file containing the resource symbols of the R class in the\n"
         "       specified folder.\n"
@@ -528,8 +537,12 @@
                         goto bail;
                     }
                     bundle.setVersionName(argv[0]);
+                } else if (strcmp(cp, "-replace-version") == 0) {
+                    bundle.setReplaceVersion(true);
                 } else if (strcmp(cp, "-values") == 0) {
                     bundle.setValues(true);
+                } else if (strcmp(cp, "-include-meta-data") == 0) {
+                    bundle.setIncludeMetaData(true);
                 } else if (strcmp(cp, "-custom-package") == 0) {
                     argc--;
                     argv++;
@@ -583,6 +596,8 @@
                     bundle.setAutoAddOverlay(true);
                 } else if (strcmp(cp, "-error-on-failed-insert") == 0) {
                     bundle.setErrorOnFailedInsert(true);
+                } else if (strcmp(cp, "-error-on-missing-config-entry") == 0) {
+                    bundle.setErrorOnMissingConfigEntry(true);
                 } else if (strcmp(cp, "-output-text-symbols") == 0) {
                     argc--;
                     argv++;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 4d29ff7..6d9d62e 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -470,7 +470,7 @@
                         value.data);
                 return ATTR_NOT_FOUND;
             }
-
+            
             pool = table.getTableStringBlock(strIdx);
             #if 0
             if (pool != NULL) {
@@ -676,13 +676,15 @@
 }
 
 /*
- * Inserts an attribute in a given node, only if the attribute does not
- * exist.
+ * Inserts an attribute in a given node.
  * If errorOnFailedInsert is true, and the attribute already exists, returns false.
- * Returns true otherwise, even if the attribute already exists.
+ * If replaceExisting is true, the attribute will be updated if it already exists.
+ * Returns true otherwise, even if the attribute already exists, and does not modify
+ * the existing attribute's value.
  */
 bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
-        const char* attr8, const char* value, bool errorOnFailedInsert)
+        const char* attr8, const char* value, bool errorOnFailedInsert,
+        bool replaceExisting)
 {
     if (value == NULL) {
         return true;
@@ -691,7 +693,16 @@
     const String16 ns(ns8);
     const String16 attr(attr8);
 
-    if (node->getAttribute(ns, attr) != NULL) {
+    XMLNode::attribute_entry* existingEntry = node->editAttribute(ns, attr);
+    if (existingEntry != NULL) {
+        if (replaceExisting) {
+            NOISY(printf("Info: AndroidManifest.xml already defines %s (in %s);"
+                         " overwriting existing value from manifest.\n",
+                         String8(attr).string(), String8(ns).string()));
+            existingEntry->string = String16(value);
+            return true;
+        }
+
         if (errorOnFailedInsert) {
             fprintf(stderr, "Error: AndroidManifest.xml already defines %s (in %s);"
                             " cannot insert new value %s.\n",
@@ -706,11 +717,23 @@
         // don't stop the build.
         return true;
     }
-
+    
     node->addAttribute(ns, attr, String16(value));
     return true;
 }
 
+/*
+ * Inserts an attribute in a given node, only if the attribute does not
+ * exist.
+ * If errorOnFailedInsert is true, and the attribute already exists, returns false.
+ * Returns true otherwise, even if the attribute already exists.
+ */
+bool addTagAttribute(const sp<XMLNode>& node, const char* ns8,
+        const char* attr8, const char* value, bool errorOnFailedInsert)
+{
+    return addTagAttribute(node, ns8, attr8, value, errorOnFailedInsert, false);
+}
+
 static void fullyQualifyClassName(const String8& package, sp<XMLNode> node,
         const String16& attrName) {
     XMLNode::attribute_entry* attr = node->editAttribute(
@@ -748,16 +771,17 @@
     }
 
     bool errorOnFailedInsert = bundle->getErrorOnFailedInsert();
+    bool replaceVersion = bundle->getReplaceVersion();
 
     if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionCode",
-            bundle->getVersionCode(), errorOnFailedInsert)) {
+            bundle->getVersionCode(), errorOnFailedInsert, replaceVersion)) {
         return UNKNOWN_ERROR;
     }
     if (!addTagAttribute(root, RESOURCES_ANDROID_NAMESPACE, "versionName",
-            bundle->getVersionName(), errorOnFailedInsert)) {
+            bundle->getVersionName(), errorOnFailedInsert, replaceVersion)) {
         return UNKNOWN_ERROR;
     }
-
+    
     if (bundle->getMinSdkVersion() != NULL
             || bundle->getTargetSdkVersion() != NULL
             || bundle->getMaxSdkVersion() != NULL) {
@@ -766,7 +790,7 @@
             vers = XMLNode::newElement(root->getFilename(), String16(), String16("uses-sdk"));
             root->insertChildAt(vers, 0);
         }
-
+        
         if (!addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "minSdkVersion",
                 bundle->getMinSdkVersion(), errorOnFailedInsert)) {
             return UNKNOWN_ERROR;
@@ -841,7 +865,7 @@
             }
         }
     }
-
+    
     return NO_ERROR;
 }
 
@@ -925,7 +949,7 @@
     // --------------------------------------------------------------
 
     // resType -> leafName -> group
-    KeyedVector<String8, sp<ResourceTypeSet> > *resources =
+    KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
             new KeyedVector<String8, sp<ResourceTypeSet> >;
     collect_files(assets, resources);
 
@@ -957,7 +981,7 @@
     // now go through any resource overlays and collect their files
     sp<AaptAssets> current = assets->getOverlay();
     while(current.get()) {
-        KeyedVector<String8, sp<ResourceTypeSet> > *resources =
+        KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
                 new KeyedVector<String8, sp<ResourceTypeSet> >;
         current->setResources(resources);
         collect_files(current, resources);
@@ -1060,7 +1084,7 @@
     // compile resources
     current = assets;
     while(current.get()) {
-        KeyedVector<String8, sp<ResourceTypeSet> > *resources =
+        KeyedVector<String8, sp<ResourceTypeSet> > *resources = 
                 current->getResources();
 
         ssize_t index = resources->indexOfKey(String8("values"));
@@ -1069,7 +1093,7 @@
             ssize_t res;
             while ((res=it.next()) == NO_ERROR) {
                 sp<AaptFile> file = it.getFile();
-                res = compileResourceFile(bundle, assets, file, it.getParams(),
+                res = compileResourceFile(bundle, assets, file, it.getParams(), 
                                           (current!=assets), &table);
                 if (res != NO_ERROR) {
                     hasErrors = true;
@@ -1254,7 +1278,7 @@
     if (table.validateLocalizations()) {
         hasErrors = true;
     }
-
+    
     if (hasErrors) {
         return UNKNOWN_ERROR;
     }
@@ -1287,7 +1311,7 @@
 
     ResTable finalResTable;
     sp<AaptFile> resFile;
-
+    
     if (table.hasResources()) {
         sp<AaptSymbols> symbols = assets->getSymbolsFor(String8("R"));
         err = table.addSymbols(symbols);
@@ -1319,9 +1343,10 @@
             table.writePublicDefinitions(String16(assets->getPackage()), fp);
             fclose(fp);
         }
-
+        
         // Read resources back in,
         finalResTable.add(resFile->getData(), resFile->getSize());
+        
 #if 0
         NOISY(
               printf("Generated resources:\n");
@@ -1329,7 +1354,7 @@
         )
 #endif
     }
-
+    
     // Perform a basic validation of the manifest file.  This time we
     // parse it with the comments intact, so that we can use them to
     // generate java docs...  so we are not going to write this one
@@ -1424,7 +1449,7 @@
                 ssize_t index = block.indexOfAttribute(RESOURCES_ANDROID_NAMESPACE, "name");
                 const uint16_t* id = block.getAttributeStringValue(index, &len);
                 if (id == NULL) {
-                    fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n",
+                    fprintf(stderr, "%s:%d: missing name attribute in element <%s>.\n", 
                             manifestPath.string(), block.getLineNumber(),
                             String8(block.getElementName(&len)).string());
                     hasErrors = true;
@@ -1582,7 +1607,7 @@
             return err;
         }
     }
-
+    
     return err;
 }
 
@@ -1704,7 +1729,7 @@
         NA = idents.size();
 
         bool deprecated = false;
-
+        
         String16 comment = symbols->getComment(realClassName);
         fprintf(fp, "%s/** ", indentStr);
         if (comment.size() > 0) {
@@ -1787,7 +1812,7 @@
         if (deprecated) {
             fprintf(fp, "%s@Deprecated\n", indentStr);
         }
-
+        
         fprintf(fp,
                 "%spublic static final int[] %s = {\n"
                 "%s",
@@ -1832,9 +1857,9 @@
                 //printf("%s:%s/%s: 0x%08x\n", String8(package16).string(),
                 //    String8(attr16).string(), String8(name16).string(), typeSpecFlags);
                 const bool pub = (typeSpecFlags&ResTable_typeSpec::SPEC_PUBLIC) != 0;
-
+                
                 bool deprecated = false;
-
+                
                 fprintf(fp, "%s/**\n", indentStr);
                 if (comment.size() > 0) {
                     String8 cmt(comment);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 38bf540..652998e 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -1317,9 +1317,9 @@
                         curIsFormatted = false;
                         // Untranslatable strings must only exist in the default [empty] locale
                         if (locale.size() > 0) {
-                            fprintf(stderr, "aapt: warning: string '%s' in %s marked untranslatable but exists"
-                                    " in locale '%s'\n", String8(name).string(),
-                                    bundle->getResourceSourceDirs()[0],
+                            SourcePos(in->getPrintableSource(), block.getLineNumber()).warning(
+                                    "string '%s' marked untranslatable but exists in locale '%s'\n",
+                                    String8(name).string(),
                                     locale.string());
                             // hasErrors = localHasErrors = true;
                         } else {
@@ -1330,7 +1330,10 @@
                             // having no default translation.
                         }
                     } else {
-                        outTable->addLocalization(name, locale);
+                        outTable->addLocalization(
+                                name,
+                                locale,
+                                SourcePos(in->getPrintableSource(), block.getLineNumber()));
                     }
 
                     if (formatted == false16) {
@@ -2570,9 +2573,9 @@
 
 
 void
-ResourceTable::addLocalization(const String16& name, const String8& locale)
+ResourceTable::addLocalization(const String16& name, const String8& locale, const SourcePos& src)
 {
-    mLocalizations[name].insert(locale);
+    mLocalizations[name][locale] = src;
 }
 
 
@@ -2592,21 +2595,22 @@
     const String8 defaultLocale;
 
     // For all strings...
-    for (map<String16, set<String8> >::iterator nameIter = mLocalizations.begin();
+    for (map<String16, map<String8, SourcePos> >::iterator nameIter = mLocalizations.begin();
          nameIter != mLocalizations.end();
          nameIter++) {
-        const set<String8>& configSet = nameIter->second;   // naming convenience
+        const map<String8, SourcePos>& configSrcMap = nameIter->second;
 
         // Look for strings with no default localization
-        if (configSet.count(defaultLocale) == 0) {
-            fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:",
-                    String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]);
-            for (set<String8>::const_iterator locales = configSet.begin();
-                 locales != configSet.end();
-                 locales++) {
-                fprintf(stdout, " %s", (*locales).string());
+        if (configSrcMap.count(defaultLocale) == 0) {
+            SourcePos().warning("string '%s' has no default translation.",
+                    String8(nameIter->first).string());
+            if (mBundle->getVerbose()) {
+                for (map<String8, SourcePos>::const_iterator locales = configSrcMap.begin();
+                    locales != configSrcMap.end();
+                    locales++) {
+                    locales->second.printf("locale %s found", locales->first.string());
+                }
             }
-            fprintf(stdout, "\n");
             // !!! TODO: throw an error here in some circumstances
         }
 
@@ -2616,6 +2620,8 @@
             const char* start = allConfigs;
             const char* comma;
             
+            set<String8> missingConfigs;
+            AaptLocaleValue locale;
             do {
                 String8 config;
                 comma = strchr(start, ',');
@@ -2626,27 +2632,38 @@
                     config.setTo(start);
                 }
 
+                if (!locale.initFromFilterString(config)) {
+                    continue;
+                }
+
                 // don't bother with the pseudolocale "zz_ZZ"
                 if (config != "zz_ZZ") {
-                    if (configSet.find(config) == configSet.end()) {
+                    if (configSrcMap.find(config) == configSrcMap.end()) {
                         // okay, no specific localization found.  it's possible that we are
                         // requiring a specific regional localization [e.g. de_DE] but there is an
                         // available string in the generic language localization [e.g. de];
                         // consider that string to have fulfilled the localization requirement.
                         String8 region(config.string(), 2);
-                        if (configSet.find(region) == configSet.end()) {
-                            if (configSet.count(defaultLocale) == 0) {
-                                fprintf(stdout, "aapt: warning: "
-                                        "**** string '%s' has no default or required localization "
-                                        "for '%s' in %s\n",
-                                        String8(nameIter->first).string(),
-                                        config.string(),
-                                        mBundle->getResourceSourceDirs()[0]);
-                            }
+                        if (configSrcMap.find(region) == configSrcMap.end() &&
+                                configSrcMap.count(defaultLocale) == 0) {
+                            missingConfigs.insert(config);
                         }
                     }
                 }
-           } while (comma != NULL);
+            } while (comma != NULL);
+
+            if (!missingConfigs.empty()) {
+                String8 configStr;
+                for (set<String8>::iterator iter = missingConfigs.begin();
+                     iter != missingConfigs.end();
+                     iter++) {
+                    configStr.appendFormat(" %s", iter->string());
+                }
+                SourcePos().warning("string '%s' is missing %u required localizations:%s",
+                        String8(nameIter->first).string(),
+                        (unsigned int)missingConfigs.size(),
+                        configStr.string());
+            }
         }
     }
 
@@ -2979,13 +2996,21 @@
                 tHeader->header.size = htodl(data->getSize()-typeStart);
             }
 
+            bool missing_entry = false;
+            const char* log_prefix = bundle->getErrorOnMissingConfigEntry() ?
+                    "error" : "warning";
             for (size_t i = 0; i < N; ++i) {
                 if (!validResources[i]) {
                     sp<ConfigList> c = t->getOrderedConfigs().itemAt(i);
-                    fprintf(stderr, "warning: no entries written for %s/%s\n",
+                    fprintf(stderr, "%s: no entries written for %s/%s\n", log_prefix,
                             String8(typeName).string(), String8(c->getName()).string());
+                    missing_entry = true;
                 }
             }
+            if (bundle->getErrorOnMissingConfigEntry() && missing_entry) {
+                fprintf(stderr, "Error: Missing entries, quit!\n");
+                return NOT_ENOUGH_DATA;
+            }
         }
 
         // Fill in the rest of the package information.
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index a3e0666..75005cd 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -220,7 +220,7 @@
 
     status_t assignResourceIds();
     status_t addSymbols(const sp<AaptSymbols>& outSymbols = NULL);
-    void addLocalization(const String16& name, const String8& locale);
+    void addLocalization(const String16& name, const String8& locale, const SourcePos& src);
     status_t validateLocalizations(void);
 
     status_t flatten(Bundle*, const sp<AaptFile>& dest);
@@ -551,7 +551,7 @@
     Bundle* mBundle;
     
     // key = string resource name, value = set of locales in which that name is defined
-    map<String16, set<String8> > mLocalizations;
+    map<String16, map<String8, SourcePos> > mLocalizations;
 };
 
 #endif
diff --git a/tools/aapt/SourcePos.cpp b/tools/aapt/SourcePos.cpp
index e2a921c..ae25047 100644
--- a/tools/aapt/SourcePos.cpp
+++ b/tools/aapt/SourcePos.cpp
@@ -10,17 +10,20 @@
 // =============================================================================
 struct ErrorPos
 {
+    enum Level {
+        NOTE,
+        WARNING,
+        ERROR
+    };
+
     String8 file;
     int line;
     String8 error;
-    bool fatal;
+    Level level;
 
     ErrorPos();
     ErrorPos(const ErrorPos& that);
-    ErrorPos(const String8& file, int line, const String8& error, bool fatal);
-    ~ErrorPos();
-    bool operator<(const ErrorPos& rhs) const;
-    bool operator==(const ErrorPos& rhs) const;
+    ErrorPos(const String8& file, int line, const String8& error, Level level);
     ErrorPos& operator=(const ErrorPos& rhs);
 
     void print(FILE* to) const;
@@ -29,7 +32,7 @@
 static vector<ErrorPos> g_errors;
 
 ErrorPos::ErrorPos()
-    :line(-1), fatal(false)
+    :line(-1), level(NOTE)
 {
 }
 
@@ -37,61 +40,52 @@
     :file(that.file),
      line(that.line),
      error(that.error),
-     fatal(that.fatal)
+     level(that.level)
 {
 }
 
-ErrorPos::ErrorPos(const String8& f, int l, const String8& e, bool fat)
+ErrorPos::ErrorPos(const String8& f, int l, const String8& e, Level lev)
     :file(f),
      line(l),
      error(e),
-     fatal(fat)
+     level(lev)
 {
 }
 
-ErrorPos::~ErrorPos()
-{
-}
-
-bool
-ErrorPos::operator<(const ErrorPos& rhs) const
-{
-    if (this->file < rhs.file) return true;
-    if (this->file == rhs.file) {
-        if (this->line < rhs.line) return true;
-        if (this->line == rhs.line) {
-            if (this->error < rhs.error) return true;
-        }
-    }
-    return false;
-}
-
-bool
-ErrorPos::operator==(const ErrorPos& rhs) const
-{
-    return this->file == rhs.file
-            && this->line == rhs.line
-            && this->error == rhs.error;
-}
-
 ErrorPos&
 ErrorPos::operator=(const ErrorPos& rhs)
 {
     this->file = rhs.file;
     this->line = rhs.line;
     this->error = rhs.error;
+    this->level = rhs.level;
     return *this;
 }
 
 void
 ErrorPos::print(FILE* to) const
 {
-    const char* type = fatal ? "error:" : "warning:";
+    const char* type = "";
+    switch (level) {
+    case NOTE:
+        type = "note: ";
+        break;
+    case WARNING:
+        type = "warning: ";
+        break;
+    case ERROR:
+        type = "error: ";
+        break;
+    }
     
-    if (this->line >= 0) {
-        fprintf(to, "%s:%d: %s %s\n", this->file.string(), this->line, type, this->error.string());
+    if (!this->file.isEmpty()) {
+        if (this->line >= 0) {
+            fprintf(to, "%s:%d: %s%s\n", this->file.string(), this->line, type, this->error.string());
+        } else {
+            fprintf(to, "%s: %s%s\n", this->file.string(), type, this->error.string());
+        }
     } else {
-        fprintf(to, "%s: %s %s\n", this->file.string(), type, this->error.string());
+        fprintf(to, "%s%s\n", type, this->error.string());
     }
 }
 
@@ -116,40 +110,34 @@
 {
 }
 
-int
+void
 SourcePos::error(const char* fmt, ...) const
 {
-    int retval=0;
-    char buf[1024];
     va_list ap;
     va_start(ap, fmt);
-    retval = vsnprintf(buf, sizeof(buf), fmt, ap);
+    String8 msg = String8::formatV(fmt, ap);
     va_end(ap);
-    char* p = buf + retval - 1;
-    while (p > buf && *p == '\n') {
-        *p = '\0';
-        p--;
-    }
-    g_errors.push_back(ErrorPos(this->file, this->line, String8(buf), true));
-    return retval;
+    g_errors.push_back(ErrorPos(this->file, this->line, msg, ErrorPos::ERROR));
 }
 
-int
+void
 SourcePos::warning(const char* fmt, ...) const
 {
-    int retval=0;
-    char buf[1024];
     va_list ap;
     va_start(ap, fmt);
-    retval = vsnprintf(buf, sizeof(buf), fmt, ap);
+    String8 msg = String8::formatV(fmt, ap);
     va_end(ap);
-    char* p = buf + retval - 1;
-    while (p > buf && *p == '\n') {
-        *p = '\0';
-        p--;
-    }
-    ErrorPos(this->file, this->line, String8(buf), false).print(stderr);
-    return retval;
+    ErrorPos(this->file, this->line, msg, ErrorPos::WARNING).print(stderr);
+}
+
+void
+SourcePos::printf(const char* fmt, ...) const
+{
+    va_list ap;
+    va_start(ap, fmt);
+    String8 msg = String8::formatV(fmt, ap);
+    va_end(ap);
+    ErrorPos(this->file, this->line, msg, ErrorPos::NOTE).print(stderr);
 }
 
 bool
diff --git a/tools/aapt/SourcePos.h b/tools/aapt/SourcePos.h
index 33f72a9..4ce817f 100644
--- a/tools/aapt/SourcePos.h
+++ b/tools/aapt/SourcePos.h
@@ -17,8 +17,9 @@
     SourcePos();
     ~SourcePos();
 
-    int error(const char* fmt, ...) const;
-    int warning(const char* fmt, ...) const;
+    void error(const char* fmt, ...) const;
+    void warning(const char* fmt, ...) const;
+    void printf(const char* fmt, ...) const;
 
     static bool hasErrors();
     static void printErrors(FILE* to);
diff --git a/tools/aidl/aidl.cpp b/tools/aidl/aidl.cpp
index a84d743..9c1867e 100644
--- a/tools/aidl/aidl.cpp
+++ b/tools/aidl/aidl.cpp
@@ -207,7 +207,7 @@
     p = strchr(name->data, '.');
     len = p ? p-name->data : strlen(name->data);
     expected.append(name->data, len);
-
+    
     expected += ".aidl";
 
     len = fn.length();
@@ -473,7 +473,7 @@
             err = 1;
             goto next;
         }
-
+        
         if (!(kind == INTERFACE_TYPE_BINDER ? t->CanWriteToParcel() : t->CanWriteToRpcData())) {
             fprintf(stderr, "%s:%d parameter %d: '%s %s' can't be marshalled.\n",
                         filename, m->type.type.lineno, index,
@@ -536,7 +536,7 @@
                     filename, m->name.lineno, index, arg->name.data);
             err = 1;
         }
-
+        
 next:
         index++;
         arg = arg->next;
@@ -797,7 +797,7 @@
         //printf("%s:%d:...%s...%s...%s...\n", filename.c_str(), lineno,
         //        type, packagename, classname);
         document_item_type* doc;
-
+        
         if (0 == strcmp("parcelable", type)) {
             user_data_type* parcl = (user_data_type*)malloc(
                     sizeof(user_data_type));
@@ -1104,13 +1104,13 @@
     }
 
     // write preprocessed file
-    int fd = open( options.outputFileName.c_str(),
+    int fd = open( options.outputFileName.c_str(), 
                    O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
 #ifdef HAVE_MS_C_RUNTIME
                    _S_IREAD|_S_IWRITE);
-#else
+#else    
                    S_IRUSR|S_IWUSR|S_IRGRP);
-#endif
+#endif            
     if (fd == -1) {
         fprintf(stderr, "aidl: could not open file for write: %s\n",
                 options.outputFileName.c_str());
diff --git a/tools/layoutlib/bridge/.classpath b/tools/layoutlib/bridge/.classpath
index 2e4274d..aef3efa 100644
--- a/tools/layoutlib/bridge/.classpath
+++ b/tools/layoutlib/bridge/.classpath
@@ -1,12 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry excluding="org/kxml2/io/" kind="src" path="src"/>
+	<classpathentry kind="src" path="tests/src"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar"/>
+	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/layoutlib_api/layoutlib_api-prebuilt.jar" sourcepath="/ANDROID_SRC/tools/base/layoutlib-api/src/main"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/kxml2/kxml2-2.3.0.jar" sourcepath="/ANDROID_PLAT_SRC/dalvik/libcore/xml/src/main/java"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
 	<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
index 224eac6..4603b63 100644
--- a/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/animation/PropertyValuesHolder_Delegate.java
@@ -48,6 +48,20 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static long nGetMultipleIntMethod(Class<?> targetClass, String methodName,
+            int numParams) {
+        // TODO: return the right thing.
+        return 0;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static long nGetMultipleFloatMethod(Class<?> targetClass, String methodName,
+            int numParams) {
+        // TODO: return the right thing.
+        return 0;
+    }
+
+    @LayoutlibDelegate
     /*package*/ static void nCallIntMethod(Object target, long methodID, int arg) {
         // do nothing
     }
@@ -56,4 +70,40 @@
     /*package*/ static void nCallFloatMethod(Object target, long methodID, float arg) {
         // do nothing
     }
+
+    @LayoutlibDelegate
+    /*package*/ static void nCallTwoIntMethod(Object target, long methodID, int arg1,
+            int arg2) {
+        // do nothing
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nCallFourIntMethod(Object target, long methodID, int arg1,
+            int arg2, int arg3, int arg4) {
+        // do nothing
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nCallMultipleIntMethod(Object target, long methodID,
+            int[] args) {
+        // do nothing
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nCallTwoFloatMethod(Object target, long methodID, float arg1,
+            float arg2) {
+        // do nothing
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nCallFourFloatMethod(Object target, long methodID, float arg1,
+            float arg2, float arg3, float arg4) {
+        // do nothing
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static void nCallMultipleFloatMethod(Object target, long methodID,
+            float[] args) {
+        // do nothing
+    }
 }
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
index 8794452..dd573be 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeResources.java
@@ -51,6 +51,7 @@
     private BridgeContext mContext;
     private IProjectCallback mProjectCallback;
     private boolean[] mPlatformResourceFlag = new boolean[1];
+    private TypedValue mTmpValue = new TypedValue();
 
     /**
      * Simpler wrapper around FileInputStream. This is used when the input stream represent
@@ -154,6 +155,11 @@
 
     @Override
     public Drawable getDrawable(int id) throws NotFoundException {
+        return getDrawable(id, null);
+    }
+
+    @Override
+    public Drawable getDrawable(int id, Theme theme) {
         Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
diff --git a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
index 446d139..cfe7525 100644
--- a/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/android/content/res/BridgeTypedArray.java
@@ -58,7 +58,7 @@
 
     public BridgeTypedArray(BridgeResources resources, BridgeContext context, int len,
             boolean platformFile) {
-        super(null, null, null, 0);
+        super(resources, null, null, 0);
         mBridgeResources = resources;
         mContext = context;
         mPlatformFile = platformFile;
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
new file mode 100644
index 0000000..112250d
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.res;
+
+import java.util.Locale;
+
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Delegate used to provide new implementation of a select few methods of {@link Resources}
+ *
+ * Through the layoutlib_create tool, the original  methods of Resources have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ */
+public class Resources_Delegate {
+
+    @LayoutlibDelegate
+    /*package*/ static String localeToLanguageTag(Resources res, Locale locale)  {
+        return ULocale.forLocale(locale).toLanguageTag();
+    }
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
index 89d7e23..7016136 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java
@@ -518,7 +518,8 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static void nativeSetHasAlpha(long nativeBitmap, boolean hasAlpha) {
+    /*package*/ static void nativeSetAlphaAndPremultiplied(long nativeBitmap, boolean hasAlpha,
+            boolean isPremul) {
         // get the delegate from the native int.
         Bitmap_Delegate delegate = sManager.getDelegate(nativeBitmap);
         if (delegate == null) {
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 73d274c..bb05d45 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -344,7 +344,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_saveLayer(long nativeCanvas, RectF bounds,
+    /*package*/ static int native_saveLayer(long nativeCanvas, RectF bounds,
                                                long paint, int layerFlags) {
         // get the delegate from the native int.
         Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
@@ -361,7 +361,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_saveLayer(long nativeCanvas, float l,
+    /*package*/ static int native_saveLayer(long nativeCanvas, float l,
                                                float t, float r, float b,
                                                long paint, int layerFlags) {
         // get the delegate from the native int.
@@ -380,7 +380,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_saveLayerAlpha(long nativeCanvas,
+    /*package*/ static int native_saveLayerAlpha(long nativeCanvas,
                                                     RectF bounds, int alpha,
                                                     int layerFlags) {
         // get the delegate from the native int.
@@ -393,7 +393,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_saveLayerAlpha(long nativeCanvas, float l,
+    /*package*/ static int native_saveLayerAlpha(long nativeCanvas, float l,
                                                     float t, float r, float b,
                                                     int alpha, int layerFlags) {
         // get the delegate from the native int.
@@ -975,8 +975,10 @@
     @LayoutlibDelegate
     /*package*/ static void native_drawText(long nativeCanvas,
             final char[] text, final int index, final int count,
-            final float startX, final float startY, final int flags, long paint) {
+            final float startX, final float startY, final int flags, long paint,
+            long typeface) {
 
+        // TODO: use typeface.
         draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
                 new GcSnapshot.Drawable() {
             @Override
@@ -1006,30 +1008,31 @@
 
     @LayoutlibDelegate
     /*package*/ static void native_drawText(long nativeCanvas, String text,
-            int start, int end, float x, float y, final int flags, long paint) {
+            int start, int end, float x, float y, final int flags, long paint,
+            long typeface) {
         int count = end - start;
         char[] buffer = TemporaryBuffer.obtain(count);
         TextUtils.getChars(text, start, end, buffer, 0);
 
-        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint);
+        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
     }
 
     @LayoutlibDelegate
     /*package*/ static void native_drawTextRun(long nativeCanvas, String text,
             int start, int end, int contextStart, int contextEnd,
-            float x, float y, int flags, long paint) {
+            float x, float y, int flags, long paint, long typeface) {
         int count = end - start;
         char[] buffer = TemporaryBuffer.obtain(count);
         TextUtils.getChars(text, start, end, buffer, 0);
 
-        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint);
+        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
     }
 
     @LayoutlibDelegate
     /*package*/ static void native_drawTextRun(long nativeCanvas, char[] text,
             int start, int count, int contextStart, int contextCount,
-            float x, float y, int flags, long paint) {
-        native_drawText(nativeCanvas, text, start, count, x, y, flags, paint);
+            float x, float y, int flags, long paint, long typeface) {
+        native_drawText(nativeCanvas, text, start, count, x, y, flags, paint, typeface);
     }
 
     @LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
index d6b3da1..bf03a5e 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorFilter_Delegate.java
@@ -56,7 +56,7 @@
     // ---- native methods ----
 
     @LayoutlibDelegate
-    /*package*/ static void finalizer(long native_instance, long nativeColorFilter) {
+    /*package*/ static void destroyFilter(long native_instance) {
         sManager.removeJavaReferenceFor(native_instance);
     }
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
index ca8f450..9aac2bd 100644
--- a/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/ColorMatrixColorFilter_Delegate.java
@@ -60,11 +60,5 @@
         return sManager.addNewDelegate(newDelegate);
     }
 
-    @LayoutlibDelegate
-    /*package*/ static long nColorMatrixFilter(long nativeFilter, float[] array) {
-        // pass
-        return 0;
-    }
-
     // ---- Private delegate/helper methods ----
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
index defaac3..501d55c 100644
--- a/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/LightingColorFilter_Delegate.java
@@ -60,11 +60,5 @@
         return sManager.addNewDelegate(newDelegate);
     }
 
-    @LayoutlibDelegate
-    /*package*/ static int nCreateLightingFilter(long nativeFilter, int mul, int add) {
-        // pass
-        return 0;
-    }
-
     // ---- Private delegate/helper methods ----
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index 7007b71..de2e592 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -688,7 +688,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getStyle(long native_object) {
+    /*package*/ static int native_getStyle(long native_object) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(native_object);
         if (delegate == null) {
@@ -710,7 +710,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getStrokeCap(long native_object) {
+    /*package*/ static int native_getStrokeCap(long native_object) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(native_object);
         if (delegate == null) {
@@ -732,7 +732,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getStrokeJoin(long native_object) {
+    /*package*/ static int native_getStrokeJoin(long native_object) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(native_object);
         if (delegate == null) {
@@ -889,7 +889,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getTextAlign(long native_object) {
+    /*package*/ static int native_getTextAlign(long native_object) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(native_object);
         if (delegate == null) {
@@ -922,7 +922,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getTextWidths(long native_object, char[] text, int index,
+    /*package*/ static int native_getTextWidths(long native_object, char[] text, int index,
             int count, int bidiFlags, float[] widths) {
         // get the delegate from the native int.
         Paint_Delegate delegate = sManager.getDelegate(native_object);
@@ -964,14 +964,14 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getTextWidths(long native_object, String text, int start,
+    /*package*/ static int native_getTextWidths(long native_object, String text, int start,
             int end, int bidiFlags, float[] widths) {
         return native_getTextWidths(native_object, text.toCharArray(), start, end - start,
                 bidiFlags, widths);
     }
 
     @LayoutlibDelegate
-    /* package */static long native_getTextGlyphs(long native_object, String text, int start,
+    /* package */static int native_getTextGlyphs(long native_object, String text, int start,
             int end, int contextStart, int contextEnd, int flags, char[] glyphs) {
         // FIXME
         return 0;
@@ -1012,7 +1012,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getTextRunCursor(Paint thisPaint, long native_object, char[] text,
+    /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, char[] text,
             int contextStart, int contextLength, int flags, int offset, int cursorOpt) {
         // FIXME
         Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
@@ -1021,7 +1021,7 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getTextRunCursor(Paint thisPaint, long native_object, String text,
+    /*package*/ static int native_getTextRunCursor(Paint thisPaint, long native_object, String text,
             int contextStart, int contextEnd, int flags, int offset, int cursorOpt) {
         // FIXME
         Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 6f6ef20..b235408 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -142,7 +142,14 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static long native_getFillType(long nPath) {
+    /*package*/ static boolean native_isConvex(long nPath) {
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.isConvex is not supported.", null, null);
+        return true;
+    }
+
+    @LayoutlibDelegate
+    /*package*/ static int native_getFillType(long nPath) {
         Path_Delegate pathDelegate = sManager.getDelegate(nPath);
         if (pathDelegate == null) {
             return 0;
@@ -484,6 +491,11 @@
         sManager.removeJavaReferenceFor(nPath);
     }
 
+    @LayoutlibDelegate
+    /*package*/ static float[] native_approximate(long nPath, float error) {
+        Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "Path.approximate() not supported", null);
+        return new float[0];
+    }
 
     // ---- Private helper methods ----
 
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
index 6049919..1bc3033 100644
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffColorFilter_Delegate.java
@@ -60,12 +60,5 @@
         return sManager.addNewDelegate(newDelegate);
     }
 
-    @LayoutlibDelegate
-    /*package*/ static long nCreatePorterDuffFilter(long nativeFilter, int srcColor,
-            int porterDuffMode) {
-        // pass
-        return 0;
-    }
-
     // ---- Private delegate/helper methods ----
 }
diff --git a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
index ea23649..edb7025 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Region_Delegate.java
@@ -275,21 +275,20 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static boolean nativeSetRegion(long native_dst, long native_src) {
+    /*package*/ static void nativeSetRegion(long native_dst, long native_src) {
         Region_Delegate dstRegion = sManager.getDelegate(native_dst);
         if (dstRegion == null) {
-            return true;
+            return;
         }
 
         Region_Delegate srcRegion = sManager.getDelegate(native_src);
         if (srcRegion == null) {
-            return true;
+            return;
         }
 
         dstRegion.mArea.reset();
         dstRegion.mArea.add(srcRegion.mArea);
 
-        return true;
     }
 
     @LayoutlibDelegate
diff --git a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
index 941f1ce6..cdbe200 100644
--- a/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/android/view/BridgeInflater.java
@@ -125,10 +125,11 @@
     }
 
     @Override
-    public View createViewFromTag(View parent, String name, AttributeSet attrs) {
+    public View createViewFromTag(View parent, String name, AttributeSet attrs,
+            boolean inheritContext) {
         View view = null;
         try {
-            view = super.createViewFromTag(parent, name, attrs);
+            view = super.createViewFromTag(parent, name, attrs, inheritContext);
         } catch (InflateException e) {
             // try to load the class from using the custom view loader
             try {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index dd2cbc1..743a26c 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -458,44 +458,8 @@
     }
 
     @Override
-    public IBinder getFocusedWindowToken() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public void setInputFilter(IInputFilter filter) throws RemoteException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void getWindowFrame(IBinder token, Rect outFrame) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setMagnificationCallbacks(IMagnificationCallbacks callbacks) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public void setMagnificationSpec(MagnificationSpec spec) {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
-    public MagnificationSpec getCompatibleMagnificationSpecForWindow(IBinder windowToken) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
     public boolean isRotationFrozen() throws RemoteException {
         // TODO Auto-generated method stub
         return false;
     }
-
-    @Override
-    public void setTouchExplorationEnabled(boolean enabled) {
-    }
 }
diff --git a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
index 3db3a1b..7a73fae 100644
--- a/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/LayoutInflater_Delegate.java
@@ -48,9 +48,9 @@
      * This implementation just records the merge status before calling the default implementation.
      */
     @LayoutlibDelegate
-    /*package*/ static void rInflate(LayoutInflater thisInflater,
-            XmlPullParser parser, View parent, final AttributeSet attrs,
-            boolean finishInflate) throws XmlPullParserException, IOException {
+    /* package */ static void rInflate(LayoutInflater thisInflater, XmlPullParser parser,
+            View parent, final AttributeSet attrs, boolean finishInflate, boolean inheritContext)
+            throws XmlPullParserException, IOException {
 
         if (finishInflate == false) {
             // this is a merge rInflate!
@@ -61,7 +61,7 @@
 
         // ---- START DEFAULT IMPLEMENTATION.
 
-        thisInflater.rInflate_Original(parser, parent, attrs, finishInflate);
+        thisInflater.rInflate_Original(parser, parent, attrs, finishInflate, inheritContext);
 
         // ---- END DEFAULT IMPLEMENTATION.
 
@@ -74,10 +74,8 @@
     }
 
     @LayoutlibDelegate
-    public static void parseInclude(
-            LayoutInflater thisInflater,
-            XmlPullParser parser, View parent, AttributeSet attrs)
-            throws XmlPullParserException, IOException {
+    public static void parseInclude(LayoutInflater thisInflater, XmlPullParser parser, View parent,
+            AttributeSet attrs, boolean inheritContext) throws XmlPullParserException, IOException {
 
         int type;
 
@@ -113,9 +111,11 @@
 
                     if (TAG_MERGE.equals(childName)) {
                         // Inflate all children.
-                        thisInflater.rInflate(childParser, parent, childAttrs, false);
+                        thisInflater.rInflate(childParser, parent, childAttrs, false,
+                                inheritContext);
                     } else {
-                        final View view = thisInflater.createViewFromTag(parent, childName, childAttrs);
+                        final View view = thisInflater.createViewFromTag(parent, childName,
+                                childAttrs, inheritContext);
                         final ViewGroup group = (ViewGroup) parent;
 
                         // We try to load the layout params set in the <include /> tag. If
@@ -151,7 +151,7 @@
                         }
 
                         // Inflate all children.
-                        thisInflater.rInflate(childParser, view, childAttrs, true);
+                        thisInflater.rInflate(childParser, view, childAttrs, true, true);
 
                         // Attempt to override the included layout's android:id with the
                         // one set on the <include /> tag itself.
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 01740b1..89288bf 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
@@ -135,6 +135,7 @@
         return null;
     }
 
+
     @Override
     public Uri canonicalize(String callingPkg, Uri uri) throws RemoteException {
         return null;
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 3cf5ed5..66e67db 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
@@ -209,6 +209,17 @@
     }
 
     @Override
+        public int getInputMethodWindowVisibleHeight() throws RemoteException {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+        public void notifyTextCommitted() throws RemoteException {
+        // TODO Auto-generated method stub
+    }
+
+    @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 281337c..a90632c 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, String arg2_5, WorkSource arg3)
+    public void acquireWakeLock(IBinder arg0, int arg1, String arg2, String arg2_5, WorkSource arg3, String arg4)
             throws RemoteException {
         // pass for now.
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index bcd08eb4..86797e5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -87,7 +87,7 @@
         }
     }
 
-    private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction, 
+    private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction,
             String[] pathOut, boolean tryOtherDensities) {
         // current density
         Density density = densityInOut[0];
@@ -111,10 +111,10 @@
                         return stream;
                     }
                 }
-            }
-            // couldn't find resource with direction qualifier. try without.
-            if (direction != null) {
-                return getIcon(iconName, densityInOut, null, pathOut, true);
+                // couldn't find resource with direction qualifier. try without.
+                if (direction != null) {
+                    return getIcon(iconName, densityInOut, null, pathOut, true);
+                }
             }
         }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
index 84e676e..112c267 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/NavigationBar.java
@@ -17,7 +17,6 @@
 package com.android.layoutlib.bridge.bars;
 
 import com.android.resources.Density;
-import com.android.layoutlib.bridge.Bridge;
 
 import org.xmlpull.v1.XmlPullParserException;
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
index 3692d96..1498044 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/StatusBar.java
@@ -33,7 +33,6 @@
     public StatusBar(Context context, Density density, int direction, boolean RtlEnabled)
             throws XmlPullParserException {
         // FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
-
         super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml");
 
         // FIXME: use FILL_H?
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index 998b08b..b16b4aa 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -18,6 +18,7 @@
 
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 import com.ibm.icu.text.DateTimePatternGenerator;
+import com.ibm.icu.util.Currency;
 import com.ibm.icu.util.ULocale;
 
 import java.util.Locale;
@@ -117,6 +118,11 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static int getCurrencyNumericCode(String currencyCode) {
+        return Currency.getInstance(currencyCode).getNumericCode();
+    }
+
+    @LayoutlibDelegate
     /*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
         return "";
     }
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
index d3218db..274516c 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/TestDelegates.java
@@ -121,6 +121,15 @@
                 Method delegateMethod = delegateClass.getDeclaredMethod(originalMethod.getName(),
                         parameters);
 
+                // check the return type of the methods match.
+                assertTrue(
+                        String.format("Delegate method %1$s.%2$s does not match the corresponding " +
+                                "framework method which returns %3$s",
+                                delegateClass.getName(),
+                                getMethodName(delegateMethod),
+                                originalMethod.getReturnType().getName()),
+                        delegateMethod.getReturnType() == originalMethod.getReturnType());
+
                 // check that the method has the annotation
                 assertNotNull(
                         String.format(
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 79aa642..4236038 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -125,6 +125,7 @@
         "android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
         "android.content.res.Resources$Theme#obtainStyledAttributes",
         "android.content.res.Resources$Theme#resolveAttribute",
+        "android.content.res.Resources#localeToLanguageTag",
         "android.content.res.TypedArray#getValueAt",
         "android.graphics.BitmapFactory#finishDecode",
         "android.os.Handler#sendMessageAtTime",
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index a79fba1..2ef3d5f 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -114,6 +114,7 @@
                         "android.os.*",  // for android.os.Handler
                         "android.database.ContentObserver", // for Digital clock
                         "com.android.i18n.phonenumbers.*",  // for TextView with autolink attribute
+                        "android.app.DatePickerDialog",     // b.android.com/28318
                     },
                     excludeClasses,
                     new String[] {
diff --git a/wifi/java/android/net/wifi/BatchedScanResult.java b/wifi/java/android/net/wifi/BatchedScanResult.java
index eb4e0276..7598b92 100644
--- a/wifi/java/android/net/wifi/BatchedScanResult.java
+++ b/wifi/java/android/net/wifi/BatchedScanResult.java
@@ -20,7 +20,6 @@
 import android.os.Parcel;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 
 /**
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 149bda6..84e933d 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -20,6 +20,8 @@
 import android.net.wifi.BatchedScanSettings;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
+import android.net.wifi.ScanSettings;
+import android.net.wifi.WifiChannel;
 import android.net.wifi.ScanResult;
 import android.net.DhcpInfo;
 
@@ -45,7 +47,9 @@
 
     boolean pingSupplicant();
 
-    void startScan(in WorkSource ws);
+    List<WifiChannel> getChannelList();
+
+    void startScan(in ScanSettings requested, in WorkSource ws);
 
     List<ScanResult> getScanResults(String callingPackage);
 
@@ -111,8 +115,6 @@
 
     String getConfigFile();
 
-    void captivePortalCheckComplete();
-
     void enableTdls(String remoteIPAddress, boolean enable);
 
     void enableTdlsWithMacAddress(String remoteMacAddress, boolean enable);
diff --git a/wifi/java/android/net/wifi/NetworkUpdateResult.java b/wifi/java/android/net/wifi/NetworkUpdateResult.java
deleted file mode 100644
index 234bbe1..0000000
--- a/wifi/java/android/net/wifi/NetworkUpdateResult.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
-
-class NetworkUpdateResult {
-    int netId;
-    boolean ipChanged;
-    boolean proxyChanged;
-    boolean isNewNetwork = false;
-
-    public NetworkUpdateResult(int id) {
-        netId = id;
-        ipChanged = false;
-        proxyChanged = false;
-    }
-
-    public NetworkUpdateResult(boolean ip, boolean proxy) {
-        netId = INVALID_NETWORK_ID;
-        ipChanged = ip;
-        proxyChanged = proxy;
-    }
-
-    public void setNetworkId(int id) {
-        netId = id;
-    }
-
-    public int getNetworkId() {
-        return netId;
-    }
-
-    public void setIpChanged(boolean ip) {
-        ipChanged = ip;
-    }
-
-    public boolean hasIpChanged() {
-        return ipChanged;
-    }
-
-    public void setProxyChanged(boolean proxy) {
-        proxyChanged = proxy;
-    }
-
-    public boolean hasProxyChanged() {
-        return proxyChanged;
-    }
-
-    public boolean isNewNetwork() {
-        return isNewNetwork;
-    }
-
-    public void setIsNewNetwork(boolean isNew) {
-        isNewNetwork = isNew;
-    }
-}
diff --git a/wifi/java/android/net/wifi/ScanSettings.aidl b/wifi/java/android/net/wifi/ScanSettings.aidl
new file mode 100644
index 0000000..ebd2a39
--- /dev/null
+++ b/wifi/java/android/net/wifi/ScanSettings.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+parcelable ScanSettings;
diff --git a/wifi/java/android/net/wifi/ScanSettings.java b/wifi/java/android/net/wifi/ScanSettings.java
new file mode 100644
index 0000000..094ce34
--- /dev/null
+++ b/wifi/java/android/net/wifi/ScanSettings.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Bundle of customized scan settings
+ *
+ * @see WifiManager#startCustomizedScan
+ *
+ * @hide
+ */
+public class ScanSettings implements Parcelable {
+
+    /** channel set to scan. this can be null or empty, indicating a full scan */
+    public Collection<WifiChannel> channelSet;
+
+    /** public constructor */
+    public ScanSettings() { }
+
+    /** copy constructor */
+    public ScanSettings(ScanSettings source) {
+        if (source.channelSet != null)
+            channelSet = new ArrayList<WifiChannel>(source.channelSet);
+    }
+
+    /** check for validity */
+    public boolean isValid() {
+        for (WifiChannel channel : channelSet)
+            if (!channel.isValid()) return false;
+        return true;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(channelSet == null ? 0 : channelSet.size());
+        if (channelSet != null)
+            for (WifiChannel channel : channelSet) channel.writeToParcel(out, flags);
+    }
+
+    /** implement Parcelable interface */
+    public static final Parcelable.Creator<ScanSettings> CREATOR =
+            new Parcelable.Creator<ScanSettings>() {
+        @Override
+        public ScanSettings createFromParcel(Parcel in) {
+            ScanSettings settings = new ScanSettings();
+            int size = in.readInt();
+            if (size > 0) {
+                settings.channelSet = new ArrayList<WifiChannel>(size);
+                while (size-- > 0)
+                    settings.channelSet.add(WifiChannel.CREATOR.createFromParcel(in));
+            }
+            return settings;
+        }
+
+        @Override
+        public ScanSettings[] newArray(int size) {
+            return new ScanSettings[size];
+        }
+    };
+}
diff --git a/wifi/java/android/net/wifi/StateChangeResult.java b/wifi/java/android/net/wifi/StateChangeResult.java
deleted file mode 100644
index c334b91..0000000
--- a/wifi/java/android/net/wifi/StateChangeResult.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.net.wifi;
-
-/**
- * Stores supplicant state change information passed from WifiMonitor to
- * a state machine. WifiStateMachine, SupplicantStateTracker and WpsStateMachine
- * are example state machines that handle it.
- * @hide
- */
-public class StateChangeResult {
-    StateChangeResult(int networkId, WifiSsid wifiSsid, String BSSID,
-            SupplicantState state) {
-        this.state = state;
-        this.wifiSsid= wifiSsid;
-        this.BSSID = BSSID;
-        this.networkId = networkId;
-    }
-
-    int networkId;
-    WifiSsid wifiSsid;
-    String BSSID;
-    SupplicantState state;
-}
diff --git a/wifi/java/android/net/wifi/SupplicantState.java b/wifi/java/android/net/wifi/SupplicantState.java
index 4a2037d..369d3a8 100644
--- a/wifi/java/android/net/wifi/SupplicantState.java
+++ b/wifi/java/android/net/wifi/SupplicantState.java
@@ -194,7 +194,8 @@
         }
     }
 
-    static boolean isConnecting(SupplicantState state) {
+    /** @hide */
+    public static boolean isConnecting(SupplicantState state) {
         switch(state) {
             case AUTHENTICATING:
             case ASSOCIATING:
@@ -216,7 +217,8 @@
         }
     }
 
-    static boolean isDriverActive(SupplicantState state) {
+    /** @hide */
+    public static boolean isDriverActive(SupplicantState state) {
         switch(state) {
             case DISCONNECTED:
             case DORMANT:
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
deleted file mode 100644
index e76eb17..0000000
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import android.net.wifi.StateChangeResult;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Parcelable;
-import android.os.UserHandle;
-import android.util.Log;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Tracks the state changes in supplicant and provides functionality
- * that is based on these state changes:
- * - detect a failed WPA handshake that loops indefinitely
- * - authentication failure handling
- */
-class SupplicantStateTracker extends StateMachine {
-
-    private static final String TAG = "SupplicantStateTracker";
-    private static final boolean DBG = false;
-
-    private WifiStateMachine mWifiStateMachine;
-    private WifiConfigStore mWifiConfigStore;
-    private int mAuthenticationFailuresCount = 0;
-    private int mAssociationRejectCount = 0;
-    /* Indicates authentication failure in supplicant broadcast.
-     * TODO: enhance auth failure reporting to include notification
-     * for all type of failures: EAP, WPS & WPA networks */
-    private boolean mAuthFailureInSupplicantBroadcast = false;
-
-    /* Maximum retries on a authentication failure notification */
-    private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;
-
-    /* Maximum retries on assoc rejection events */
-    private static final int MAX_RETRIES_ON_ASSOCIATION_REJECT = 16;
-
-    /* Tracks if networks have been disabled during a connection */
-    private boolean mNetworksDisabledDuringConnect = false;
-
-    private Context mContext;
-
-    private State mUninitializedState = new UninitializedState();
-    private State mDefaultState = new DefaultState();
-    private State mInactiveState = new InactiveState();
-    private State mDisconnectState = new DisconnectedState();
-    private State mScanState = new ScanState();
-    private State mHandshakeState = new HandshakeState();
-    private State mCompletedState = new CompletedState();
-    private State mDormantState = new DormantState();
-
-    public SupplicantStateTracker(Context c, WifiStateMachine wsm, WifiConfigStore wcs, Handler t) {
-        super(TAG, t.getLooper());
-
-        mContext = c;
-        mWifiStateMachine = wsm;
-        mWifiConfigStore = wcs;
-        addState(mDefaultState);
-            addState(mUninitializedState, mDefaultState);
-            addState(mInactiveState, mDefaultState);
-            addState(mDisconnectState, mDefaultState);
-            addState(mScanState, mDefaultState);
-            addState(mHandshakeState, mDefaultState);
-            addState(mCompletedState, mDefaultState);
-            addState(mDormantState, mDefaultState);
-
-        setInitialState(mUninitializedState);
-        setLogRecSize(50);
-        setLogOnlyTransitions(true);
-        //start the state machine
-        start();
-    }
-
-    private void handleNetworkConnectionFailure(int netId, int disableReason) {
-        /* If other networks disabled during connection, enable them */
-        if (mNetworksDisabledDuringConnect) {
-            mWifiConfigStore.enableAllNetworks();
-            mNetworksDisabledDuringConnect = false;
-        }
-        /* Disable failed network */
-        mWifiConfigStore.disableNetwork(netId, disableReason);
-    }
-
-    private void transitionOnSupplicantStateChange(StateChangeResult stateChangeResult) {
-        SupplicantState supState = (SupplicantState) stateChangeResult.state;
-
-        if (DBG) Log.d(TAG, "Supplicant state: " + supState.toString() + "\n");
-
-        switch (supState) {
-           case DISCONNECTED:
-                transitionTo(mDisconnectState);
-                break;
-            case INTERFACE_DISABLED:
-                //we should have received a disconnection already, do nothing
-                break;
-            case SCANNING:
-                transitionTo(mScanState);
-                break;
-            case AUTHENTICATING:
-            case ASSOCIATING:
-            case ASSOCIATED:
-            case FOUR_WAY_HANDSHAKE:
-            case GROUP_HANDSHAKE:
-                transitionTo(mHandshakeState);
-                break;
-            case COMPLETED:
-                transitionTo(mCompletedState);
-                break;
-            case DORMANT:
-                transitionTo(mDormantState);
-                break;
-            case INACTIVE:
-                transitionTo(mInactiveState);
-                break;
-            case UNINITIALIZED:
-            case INVALID:
-                transitionTo(mUninitializedState);
-                break;
-            default:
-                Log.e(TAG, "Unknown supplicant state " + supState);
-                break;
-        }
-    }
-
-    private void sendSupplicantStateChangedBroadcast(SupplicantState state, boolean failedAuth) {
-        Intent intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
-                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra(WifiManager.EXTRA_NEW_STATE, (Parcelable) state);
-        if (failedAuth) {
-            intent.putExtra(
-                WifiManager.EXTRA_SUPPLICANT_ERROR,
-                WifiManager.ERROR_AUTHENTICATING);
-        }
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    /********************************************************
-     * HSM states
-     *******************************************************/
-
-    class DefaultState extends State {
-        @Override
-         public void enter() {
-             if (DBG) Log.d(TAG, getName() + "\n");
-         }
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
-                    mAuthenticationFailuresCount++;
-                    mAuthFailureInSupplicantBroadcast = true;
-                    break;
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-                    SupplicantState state = stateChangeResult.state;
-                    sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast);
-                    mAuthFailureInSupplicantBroadcast = false;
-                    transitionOnSupplicantStateChange(stateChangeResult);
-                    break;
-                case WifiStateMachine.CMD_RESET_SUPPLICANT_STATE:
-                    transitionTo(mUninitializedState);
-                    break;
-                case WifiManager.CONNECT_NETWORK:
-                    mNetworksDisabledDuringConnect = true;
-                    mAssociationRejectCount = 0;
-                    break;
-                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
-                    mAssociationRejectCount++;
-                    break;
-                default:
-                    Log.e(TAG, "Ignoring " + message);
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-    /*
-     * This indicates that the supplicant state as seen
-     * by the framework is not initialized yet. We are
-     * in this state right after establishing a control
-     * channel connection before any supplicant events
-     * or after we have lost the control channel
-     * connection to the supplicant
-     */
-    class UninitializedState extends State {
-        @Override
-         public void enter() {
-             if (DBG) Log.d(TAG, getName() + "\n");
-         }
-    }
-
-    class InactiveState extends State {
-        @Override
-         public void enter() {
-             if (DBG) Log.d(TAG, getName() + "\n");
-         }
-    }
-
-    class DisconnectedState extends State {
-        @Override
-         public void enter() {
-             if (DBG) Log.d(TAG, getName() + "\n");
-             /* If a disconnect event happens after authentication failure
-              * exceeds maximum retries, disable the network
-              */
-             Message message = getCurrentMessage();
-             StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-
-             if (mAuthenticationFailuresCount >= MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
-                 Log.d(TAG, "Failed to authenticate, disabling network " +
-                         stateChangeResult.networkId);
-                 handleNetworkConnectionFailure(stateChangeResult.networkId,
-                         WifiConfiguration.DISABLED_AUTH_FAILURE);
-                 mAuthenticationFailuresCount = 0;
-             }
-             else if (mAssociationRejectCount >= MAX_RETRIES_ON_ASSOCIATION_REJECT) {
-                 Log.d(TAG, "Association getting rejected, disabling network " +
-                         stateChangeResult.networkId);
-                 handleNetworkConnectionFailure(stateChangeResult.networkId,
-                         WifiConfiguration.DISABLED_ASSOCIATION_REJECT);
-                 mAssociationRejectCount = 0;
-            }
-         }
-    }
-
-    class ScanState extends State {
-        @Override
-         public void enter() {
-             if (DBG) Log.d(TAG, getName() + "\n");
-         }
-    }
-
-    class HandshakeState extends State {
-        /**
-         * The max number of the WPA supplicant loop iterations before we
-         * decide that the loop should be terminated:
-         */
-        private static final int MAX_SUPPLICANT_LOOP_ITERATIONS = 4;
-        private int mLoopDetectIndex;
-        private int mLoopDetectCount;
-
-        @Override
-         public void enter() {
-             if (DBG) Log.d(TAG, getName() + "\n");
-             mLoopDetectIndex = 0;
-             mLoopDetectCount = 0;
-         }
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-                    SupplicantState state = stateChangeResult.state;
-                    if (SupplicantState.isHandshakeState(state)) {
-                        if (mLoopDetectIndex > state.ordinal()) {
-                            mLoopDetectCount++;
-                        }
-                        if (mLoopDetectCount > MAX_SUPPLICANT_LOOP_ITERATIONS) {
-                            Log.d(TAG, "Supplicant loop detected, disabling network " +
-                                    stateChangeResult.networkId);
-                            handleNetworkConnectionFailure(stateChangeResult.networkId,
-                                    WifiConfiguration.DISABLED_AUTH_FAILURE);
-                        }
-                        mLoopDetectIndex = state.ordinal();
-                        sendSupplicantStateChangedBroadcast(state,
-                                mAuthFailureInSupplicantBroadcast);
-                    } else {
-                        //Have the DefaultState handle the transition
-                        return NOT_HANDLED;
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class CompletedState extends State {
-        @Override
-         public void enter() {
-             if (DBG) Log.d(TAG, getName() + "\n");
-             /* Reset authentication failure count */
-             mAuthenticationFailuresCount = 0;
-             mAssociationRejectCount = 0;
-             if (mNetworksDisabledDuringConnect) {
-                 mWifiConfigStore.enableAllNetworks();
-                 mNetworksDisabledDuringConnect = false;
-             }
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch(message.what) {
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-                    SupplicantState state = stateChangeResult.state;
-                    sendSupplicantStateChangedBroadcast(state, mAuthFailureInSupplicantBroadcast);
-                    /* Ignore any connecting state in completed state. Group re-keying
-                     * events and other auth events that do not affect connectivity are
-                     * ignored
-                     */
-                    if (SupplicantState.isConnecting(state)) {
-                        break;
-                    }
-                    transitionOnSupplicantStateChange(stateChangeResult);
-                    break;
-                case WifiStateMachine.CMD_RESET_SUPPLICANT_STATE:
-                    sendSupplicantStateChangedBroadcast(SupplicantState.DISCONNECTED, false);
-                    transitionTo(mUninitializedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    //TODO: remove after getting rid of the state in supplicant
-    class DormantState extends State {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
-        pw.println("mAuthenticationFailuresCount " + mAuthenticationFailuresCount);
-        pw.println("mAuthFailureInSupplicantBroadcast " + mAuthFailureInSupplicantBroadcast);
-        pw.println("mNetworksDisabledDuringConnect " + mNetworksDisabledDuringConnect);
-        pw.println();
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiApConfigStore.java b/wifi/java/android/net/wifi/WifiApConfigStore.java
deleted file mode 100644
index 0531ca3..0000000
--- a/wifi/java/android/net/wifi/WifiApConfigStore.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.content.Context;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Message;
-import android.os.Messenger;
-import android.util.Log;
-
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.R;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.UUID;
-
-/**
- * Provides API to the WifiStateMachine for doing read/write access
- * to soft access point configuration
- */
-class WifiApConfigStore extends StateMachine {
-
-    private Context mContext;
-    private static final String TAG = "WifiApConfigStore";
-
-    private static final String AP_CONFIG_FILE = Environment.getDataDirectory() +
-        "/misc/wifi/softap.conf";
-
-    private static final int AP_CONFIG_FILE_VERSION = 1;
-
-    private State mDefaultState = new DefaultState();
-    private State mInactiveState = new InactiveState();
-    private State mActiveState = new ActiveState();
-
-    private WifiConfiguration mWifiApConfig = null;
-    private AsyncChannel mReplyChannel = new AsyncChannel();
-
-    WifiApConfigStore(Context context, Handler target) {
-        super(TAG, target.getLooper());
-
-        mContext = context;
-        addState(mDefaultState);
-            addState(mInactiveState, mDefaultState);
-            addState(mActiveState, mDefaultState);
-
-        setInitialState(mInactiveState);
-    }
-
-    public static WifiApConfigStore makeWifiApConfigStore(Context context, Handler target) {
-        WifiApConfigStore s = new WifiApConfigStore(context, target);
-        s.start();
-        return s;
-    }
-
-    class DefaultState extends State {
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case WifiStateMachine.CMD_SET_AP_CONFIG:
-                case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
-                    Log.e(TAG, "Unexpected message: " + message);
-                    break;
-                case WifiStateMachine.CMD_REQUEST_AP_CONFIG:
-                    mReplyChannel.replyToMessage(message,
-                            WifiStateMachine.CMD_RESPONSE_AP_CONFIG, mWifiApConfig);
-                    break;
-                default:
-                    Log.e(TAG, "Failed to handle " + message);
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-    class InactiveState extends State {
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case WifiStateMachine.CMD_SET_AP_CONFIG:
-                    mWifiApConfig = (WifiConfiguration) message.obj;
-                    transitionTo(mActiveState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class ActiveState extends State {
-        public void enter() {
-            new Thread(new Runnable() {
-                public void run() {
-                    writeApConfiguration(mWifiApConfig);
-                    sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED);
-                }
-            }).start();
-        }
-
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                //TODO: have feedback to the user when we do this
-                //to indicate the write is currently in progress
-                case WifiStateMachine.CMD_SET_AP_CONFIG:
-                    deferMessage(message);
-                    break;
-                case WifiStateMachine.CMD_SET_AP_CONFIG_COMPLETED:
-                    transitionTo(mInactiveState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    void loadApConfiguration() {
-        DataInputStream in = null;
-        try {
-            WifiConfiguration config = new WifiConfiguration();
-            in = new DataInputStream(new BufferedInputStream(new FileInputStream(
-                            AP_CONFIG_FILE)));
-
-            int version = in.readInt();
-            if (version != 1) {
-                Log.e(TAG, "Bad version on hotspot configuration file, set defaults");
-                setDefaultApConfiguration();
-                return;
-            }
-            config.SSID = in.readUTF();
-            int authType = in.readInt();
-            config.allowedKeyManagement.set(authType);
-            if (authType != KeyMgmt.NONE) {
-                config.preSharedKey = in.readUTF();
-            }
-            mWifiApConfig = config;
-        } catch (IOException ignore) {
-            setDefaultApConfiguration();
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException e) {}
-            }
-        }
-    }
-
-    Messenger getMessenger() {
-        return new Messenger(getHandler());
-    }
-
-    private void writeApConfiguration(final WifiConfiguration config) {
-        DataOutputStream out = null;
-        try {
-            out = new DataOutputStream(new BufferedOutputStream(
-                        new FileOutputStream(AP_CONFIG_FILE)));
-
-            out.writeInt(AP_CONFIG_FILE_VERSION);
-            out.writeUTF(config.SSID);
-            int authType = config.getAuthType();
-            out.writeInt(authType);
-            if(authType != KeyMgmt.NONE) {
-                out.writeUTF(config.preSharedKey);
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "Error writing hotspot configuration" + e);
-        } finally {
-            if (out != null) {
-                try {
-                    out.close();
-                } catch (IOException e) {}
-            }
-        }
-    }
-
-    /* Generate a default WPA2 based configuration with a random password.
-       We are changing the Wifi Ap configuration storage from secure settings to a
-       flat file accessible only by the system. A WPA2 based default configuration
-       will keep the device secure after the update */
-    private void setDefaultApConfiguration() {
-        WifiConfiguration config = new WifiConfiguration();
-        config.SSID = mContext.getString(R.string.wifi_tether_configure_ssid_default);
-        config.allowedKeyManagement.set(KeyMgmt.WPA2_PSK);
-        String randomUUID = UUID.randomUUID().toString();
-        //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
-        config.preSharedKey = randomUUID.substring(0, 8) + randomUUID.substring(9,13);
-        sendMessage(WifiStateMachine.CMD_SET_AP_CONFIG, config);
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiChannel.aidl b/wifi/java/android/net/wifi/WifiChannel.aidl
new file mode 100644
index 0000000..c3d06bd
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiChannel.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+parcelable WifiChannel;
diff --git a/wifi/java/android/net/wifi/WifiChannel.java b/wifi/java/android/net/wifi/WifiChannel.java
new file mode 100644
index 0000000..640481e
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiChannel.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Wifi Channel
+ *
+ * @see ScanSettings
+ *
+ * @hide
+ */
+public class WifiChannel implements Parcelable {
+
+    private static final int MIN_FREQ_MHZ = 2412;
+    private static final int MAX_FREQ_MHZ = 5825;
+
+    private static final int MIN_CHANNEL_NUM = 1;
+    private static final int MAX_CHANNEL_NUM = 196;
+
+    /** frequency */
+    public int freqMHz;
+
+    /** channel number */
+    public int channelNum;
+
+    /** is it a DFS channel? */
+    public boolean isDFS;
+
+    /** public constructor */
+    public WifiChannel() { }
+
+    /** check for validity */
+    public boolean isValid() {
+        if (freqMHz < MIN_FREQ_MHZ || freqMHz > MAX_FREQ_MHZ) return false;
+        if (channelNum < MIN_CHANNEL_NUM || channelNum > MAX_CHANNEL_NUM) return false;
+        return true;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** implement Parcelable interface */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(freqMHz);
+        out.writeInt(channelNum);
+        out.writeInt(isDFS ? 1 : 0);
+    }
+
+    /** implement Parcelable interface */
+    public static final Parcelable.Creator<WifiChannel> CREATOR =
+            new Parcelable.Creator<WifiChannel>() {
+        @Override
+        public WifiChannel createFromParcel(Parcel in) {
+            WifiChannel channel = new WifiChannel();
+            channel.freqMHz = in.readInt();
+            channel.channelNum = in.readInt();
+            channel.isDFS = in.readInt() != 0;
+            return channel;
+        }
+
+        @Override
+        public WifiChannel[] newArray(int size) {
+            return new WifiChannel[size];
+        }
+    };
+}
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
deleted file mode 100644
index a6ae215..0000000
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ /dev/null
@@ -1,1728 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkUtils;
-import android.net.NetworkInfo.DetailedState;
-import android.net.ProxyProperties;
-import android.net.RouteInfo;
-import android.net.wifi.WifiConfiguration.IpAssignment;
-import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.ProxySettings;
-import android.net.wifi.WifiConfiguration.Status;
-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;
-import java.net.UnknownHostException;
-import java.security.PublicKey;
-import java.util.ArrayList;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * This class provides the API to manage configured
- * wifi networks. The API is not thread safe is being
- * used only from WifiStateMachine.
- *
- * It deals with the following
- * - Add/update/remove a WifiConfiguration
- *   The configuration contains two types of information.
- *     = IP and proxy configuration that is handled by WifiConfigStore and
- *       is saved to disk on any change.
- *
- *       The format of configuration file is as follows:
- *       <version>
- *       <netA_key1><netA_value1><netA_key2><netA_value2>...<EOS>
- *       <netB_key1><netB_value1><netB_key2><netB_value2>...<EOS>
- *       ..
- *
- *       (key, value) pairs for a given network are grouped together and can
- *       be in any order. A EOS at the end of a set of (key, value) pairs
- *       indicates that the next set of (key, value) pairs are for a new
- *       network. A network is identified by a unique ID_KEY. If there is no
- *       ID_KEY in the (key, value) pairs, the data is discarded.
- *
- *       An invalid version on read would result in discarding the contents of
- *       the file. On the next write, the latest version is written to file.
- *
- *       Any failures during read or write to the configuration file are ignored
- *       without reporting to the user since the likelihood of these errors are
- *       low and the impact on connectivity is low.
- *
- *     = SSID & security details that is pushed to the supplicant.
- *       supplicant saves these details to the disk on calling
- *       saveConfigCommand().
- *
- *       We have two kinds of APIs exposed:
- *        > public API calls that provide fine grained control
- *          - enableNetwork, disableNetwork, addOrUpdateNetwork(),
- *          removeNetwork(). For these calls, the config is not persisted
- *          to the disk. (TODO: deprecate these calls in WifiManager)
- *        > The new API calls - selectNetwork(), saveNetwork() & forgetNetwork().
- *          These calls persist the supplicant config to disk.
- *
- * - Maintain a list of configured networks for quick access
- *
- */
-class WifiConfigStore {
-
-    private Context mContext;
-    private static final String TAG = "WifiConfigStore";
-    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 =
-            new HashMap<Integer, WifiConfiguration>();
-
-    /* A network id is a unique identifier for a network configured in the
-     * supplicant. Network ids are generated when the supplicant reads
-     * the configuration file at start and can thus change for networks.
-     * We store the IP configuration for networks along with a unique id
-     * that is generated from SSID and security type of the network. A mapping
-     * from the generated unique id to network id of the network is needed to
-     * map supplicant config to IP configuration. */
-    private HashMap<Integer, Integer> mNetworkIds =
-            new HashMap<Integer, Integer>();
-
-    /* Tracks the highest priority of configured networks */
-    private int mLastPriority = -1;
-
-    private static final String ipConfigFile = Environment.getDataDirectory() +
-            "/misc/wifi/ipconfig.txt";
-
-    private static final int IPCONFIG_FILE_VERSION = 2;
-
-    /* IP and proxy configuration keys */
-    private static final String ID_KEY = "id";
-    private static final String IP_ASSIGNMENT_KEY = "ipAssignment";
-    private static final String LINK_ADDRESS_KEY = "linkAddress";
-    private static final String GATEWAY_KEY = "gateway";
-    private static final String DNS_KEY = "dns";
-    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.
-     */
-    void loadAndEnableAllNetworks() {
-        if (DBG) log("Loading config and enabling all networks");
-        loadConfiguredNetworks();
-        enableAllNetworks();
-    }
-
-    /**
-     * Fetch the list of currently configured networks
-     * @return List of networks
-     */
-    List<WifiConfiguration> getConfiguredNetworks() {
-        List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-        for(WifiConfiguration config : mConfiguredNetworks.values()) {
-            networks.add(new WifiConfiguration(config));
-        }
-        return networks;
-    }
-
-    /**
-     * enable all networks and save config. This will be a no-op if the list
-     * of configured networks indicates all networks as being enabled
-     */
-    void enableAllNetworks() {
-        boolean networkEnabledStateChanged = false;
-        for(WifiConfiguration config : mConfiguredNetworks.values()) {
-            if(config != null && config.status == Status.DISABLED) {
-                if(mWifiNative.enableNetwork(config.networkId, false)) {
-                    networkEnabledStateChanged = true;
-                    config.status = Status.ENABLED;
-                } else {
-                    loge("Enable network failed on " + config.networkId);
-                }
-            }
-        }
-
-        if (networkEnabledStateChanged) {
-            mWifiNative.saveConfig();
-            sendConfiguredNetworksChangedBroadcast();
-        }
-    }
-
-
-    /**
-     * Selects the specified network for connection. This involves
-     * updating the priority of all the networks and enabling the given
-     * network while disabling others.
-     *
-     * Selecting a network will leave the other networks disabled and
-     * a call to enableAllNetworks() needs to be issued upon a connection
-     * or a failure event from supplicant
-     *
-     * @param netId network to select for connection
-     * @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.
-        if (mLastPriority == -1 || mLastPriority > 1000000) {
-            for(WifiConfiguration config : mConfiguredNetworks.values()) {
-                if (config.networkId != INVALID_NETWORK_ID) {
-                    config.priority = 0;
-                    addOrUpdateNetworkNative(config);
-                }
-            }
-            mLastPriority = 0;
-        }
-
-        // Set to the highest priority and save the configuration.
-        WifiConfiguration config = new WifiConfiguration();
-        config.networkId = netId;
-        config.priority = ++mLastPriority;
-
-        addOrUpdateNetworkNative(config);
-        mWifiNative.saveConfig();
-
-        /* Enable the given network while disabling all other networks */
-        enableNetworkWithoutBroadcast(netId, true);
-
-       /* Avoid saving the config & sending a broadcast to prevent settings
-        * from displaying a disabled list of networks */
-        return true;
-    }
-
-    /**
-     * Add/update the specified configuration and save config
-     *
-     * @param config WifiConfiguration to be saved
-     * @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)) {
-            return new NetworkUpdateResult(INVALID_NETWORK_ID);
-        }
-
-        boolean newNetwork = (config.networkId == INVALID_NETWORK_ID);
-        NetworkUpdateResult result = addOrUpdateNetworkNative(config);
-        int netId = result.getNetworkId();
-        /* enable a new network */
-        if (newNetwork && netId != INVALID_NETWORK_ID) {
-            mWifiNative.enableNetwork(netId, false);
-            mConfiguredNetworks.get(netId).status = Status.ENABLED;
-        }
-        mWifiNative.saveConfig();
-        sendConfiguredNetworksChangedBroadcast(config, result.isNewNetwork() ?
-                WifiManager.CHANGE_REASON_ADDED : WifiManager.CHANGE_REASON_CONFIG_CHANGE);
-        return result;
-    }
-
-    void updateStatus(int netId, DetailedState state) {
-        if (netId != INVALID_NETWORK_ID) {
-            WifiConfiguration config = mConfiguredNetworks.get(netId);
-            if (config == null) return;
-            switch (state) {
-                case CONNECTED:
-                    config.status = Status.CURRENT;
-                    break;
-                case DISCONNECTED:
-                    //If network is already disabled, keep the status
-                    if (config.status == Status.CURRENT) {
-                        config.status = Status.ENABLED;
-                    }
-                    break;
-                default:
-                    //do nothing, retain the existing state
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Forget the specified network and save config
-     *
-     * @param netId network to forget
-     * @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);
-            return true;
-        } else {
-            loge("Failed to remove network " + netId);
-            return false;
-        }
-    }
-
-    /**
-     * Add/update a network. Note that there is no saveConfig operation.
-     * This function is retained for compatibility with the public
-     * API. The more powerful saveNetwork() is used by the
-     * state machine
-     *
-     * @param config wifi configuration to add/update
-     * @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);
-        }
-        return result.getNetworkId();
-    }
-
-    /**
-     * Remove a network. Note that there is no saveConfig operation.
-     * This function is retained for compatibility with the public
-     * API. The more powerful forgetNetwork() is used by the
-     * state machine for network removal
-     *
-     * @param netId network to be removed
-     * @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);
-        }
-        return ret;
-    }
-
-    private void removeConfigAndSendBroadcastIfNeeded(int netId) {
-        WifiConfiguration config = mConfiguredNetworks.get(netId);
-        if (config != null) {
-            // Remove any associated keys
-            if (config.enterpriseConfig != null) {
-                config.enterpriseConfig.removeKeys(mKeyStore);
-            }
-            mConfiguredNetworks.remove(netId);
-            mNetworkIds.remove(configKey(config));
-
-            writeIpAndProxyConfigurations();
-            sendConfiguredNetworksChangedBroadcast(config, WifiManager.CHANGE_REASON_REMOVED);
-        }
-    }
-
-    /**
-     * Enable a network. Note that there is no saveConfig operation.
-     * This function is retained for compatibility with the public
-     * API. The more powerful selectNetwork()/saveNetwork() is used by the
-     * state machine for connecting to a network
-     *
-     * @param netId network to be enabled
-     * @return {@code true} if it succeeds, {@code false} otherwise
-     */
-    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);
-            }
-            // check just in case the network was removed by someone else.
-            if (enabledNetwork != null) {
-                sendConfiguredNetworksChangedBroadcast(enabledNetwork,
-                        WifiManager.CHANGE_REASON_CONFIG_CHANGE);
-            }
-        }
-        return ret;
-    }
-
-    boolean enableNetworkWithoutBroadcast(int netId, boolean disableOthers) {
-        boolean ret = mWifiNative.enableNetwork(netId, disableOthers);
-
-        WifiConfiguration config = mConfiguredNetworks.get(netId);
-        if (config != null) config.status = Status.ENABLED;
-
-        if (disableOthers) {
-            markAllNetworksDisabledExcept(netId);
-        }
-        return ret;
-    }
-
-    void disableAllNetworks() {
-        if (VDBG) localLog("disableAllNetworks");
-        boolean networkDisabled = false;
-        for(WifiConfiguration config : mConfiguredNetworks.values()) {
-            if(config != null && config.status != Status.DISABLED) {
-                if(mWifiNative.disableNetwork(config.networkId)) {
-                    networkDisabled = true;
-                    config.status = Status.DISABLED;
-                } else {
-                    loge("Disable network failed on " + config.networkId);
-                }
-            }
-        }
-
-        if (networkDisabled) {
-            sendConfiguredNetworksChangedBroadcast();
-        }
-    }
-    /**
-     * Disable a network. Note that there is no saveConfig operation.
-     * @param netId network to be disabled
-     * @return {@code true} if it succeeds, {@code false} otherwise
-     */
-    boolean disableNetwork(int netId) {
-        return disableNetwork(netId, WifiConfiguration.DISABLED_UNKNOWN_REASON);
-    }
-
-    /**
-     * Disable a network. Note that there is no saveConfig operation.
-     * @param netId network to be disabled
-     * @param reason reason code network was disabled
-     * @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);
-        /* Only change the reason if the network was not previously disabled */
-        if (config != null && config.status != Status.DISABLED) {
-            config.status = Status.DISABLED;
-            config.disableReason = reason;
-            network = config;
-        }
-        if (network != null) {
-            sendConfiguredNetworksChangedBroadcast(network,
-                    WifiManager.CHANGE_REASON_CONFIG_CHANGE);
-        }
-        return ret;
-    }
-
-    /**
-     * Save the configured networks in supplicant to disk
-     * @return {@code true} if it succeeds, {@code false} otherwise
-     */
-    boolean saveConfig() {
-        return mWifiNative.saveConfig();
-    }
-
-    /**
-     * Start WPS pin method configuration with pin obtained
-     * from the access point
-     * @param config WPS configuration
-     * @return Wps result containing status and pin
-     */
-    WpsResult startWpsWithPinFromAccessPoint(WpsInfo config) {
-        WpsResult result = new WpsResult();
-        if (mWifiNative.startWpsRegistrar(config.BSSID, config.pin)) {
-            /* WPS leaves all networks disabled */
-            markAllNetworksDisabled();
-            result.status = WpsResult.Status.SUCCESS;
-        } else {
-            loge("Failed to start WPS pin method configuration");
-            result.status = WpsResult.Status.FAILURE;
-        }
-        return result;
-    }
-
-    /**
-     * Start WPS pin method configuration with pin obtained
-     * from the device
-     * @return WpsResult indicating status and pin
-     */
-    WpsResult startWpsWithPinFromDevice(WpsInfo config) {
-        WpsResult result = new WpsResult();
-        result.pin = mWifiNative.startWpsPinDisplay(config.BSSID);
-        /* WPS leaves all networks disabled */
-        if (!TextUtils.isEmpty(result.pin)) {
-            markAllNetworksDisabled();
-            result.status = WpsResult.Status.SUCCESS;
-        } else {
-            loge("Failed to start WPS pin method configuration");
-            result.status = WpsResult.Status.FAILURE;
-        }
-        return result;
-    }
-
-    /**
-     * Start WPS push button configuration
-     * @param config WPS configuration
-     * @return WpsResult indicating status and pin
-     */
-    WpsResult startWpsPbc(WpsInfo config) {
-        WpsResult result = new WpsResult();
-        if (mWifiNative.startWpsPbc(config.BSSID)) {
-            /* WPS leaves all networks disabled */
-            markAllNetworksDisabled();
-            result.status = WpsResult.Status.SUCCESS;
-        } else {
-            loge("Failed to start WPS push button configuration");
-            result.status = WpsResult.Status.FAILURE;
-        }
-        return result;
-    }
-
-    /**
-     * Fetch the link properties for a given network id
-     * @return LinkProperties for the given network id
-     */
-    LinkProperties getLinkProperties(int netId) {
-        WifiConfiguration config = mConfiguredNetworks.get(netId);
-        if (config != null) return new LinkProperties(config.linkProperties);
-        return null;
-    }
-
-    /**
-     * set IP configuration for a given network id
-     */
-    void setLinkProperties(int netId, LinkProperties linkProperties) {
-        WifiConfiguration config = mConfiguredNetworks.get(netId);
-        if (config != null) {
-            // add old proxy details - TODO - is this still needed?
-            if(config.linkProperties != null) {
-                linkProperties.setHttpProxy(config.linkProperties.getHttpProxy());
-            }
-            config.linkProperties = linkProperties;
-        }
-    }
-
-    /**
-     * clear IP configuration for a given network id
-     * @param network id
-     */
-    void clearLinkProperties(int netId) {
-        WifiConfiguration config = mConfiguredNetworks.get(netId);
-        if (config != null && config.linkProperties != null) {
-            // Clear everything except proxy
-            ProxyProperties proxy = config.linkProperties.getHttpProxy();
-            config.linkProperties.clear();
-            config.linkProperties.setHttpProxy(proxy);
-        }
-    }
-
-
-    /**
-     * Fetch the proxy properties for a given network id
-     * @param network id
-     * @return ProxyProperties for the network id
-     */
-    ProxyProperties getProxyProperties(int netId) {
-        LinkProperties linkProperties = getLinkProperties(netId);
-        if (linkProperties != null) {
-            return new ProxyProperties(linkProperties.getHttpProxy());
-        }
-        return null;
-    }
-
-    /**
-     * Return if the specified network is using static IP
-     * @param network id
-     * @return {@code true} if using static ip for netId
-     */
-    boolean isUsingStaticIp(int netId) {
-        WifiConfiguration config = mConfiguredNetworks.get(netId);
-        if (config != null && config.ipAssignment == IpAssignment.STATIC) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Should be called when a single network configuration is made.
-     * @param network The network configuration that changed.
-     * @param reason The reason for the change, should be one of WifiManager.CHANGE_REASON_ADDED,
-     * WifiManager.CHANGE_REASON_REMOVED, or WifiManager.CHANGE_REASON_CHANGE.
-     */
-    private void sendConfiguredNetworksChangedBroadcast(WifiConfiguration network,
-            int reason) {
-        Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, false);
-        intent.putExtra(WifiManager.EXTRA_WIFI_CONFIGURATION, network);
-        intent.putExtra(WifiManager.EXTRA_CHANGE_REASON, reason);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    /**
-     * Should be called when multiple network configuration changes are made.
-     */
-    private void sendConfiguredNetworksChangedBroadcast() {
-        Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_MULTIPLE_NETWORKS_CHANGED, true);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    void loadConfiguredNetworks() {
-        String listStr = mWifiNative.listNetworks();
-        mLastPriority = 0;
-
-        mConfiguredNetworks.clear();
-        mNetworkIds.clear();
-
-        if (listStr == null)
-            return;
-
-        String[] lines = listStr.split("\n");
-        // Skip the first line, which is a header
-        for (int i = 1; i < lines.length; i++) {
-            String[] result = lines[i].split("\t");
-            // network-id | ssid | bssid | flags
-            WifiConfiguration config = new WifiConfiguration();
-            try {
-                config.networkId = Integer.parseInt(result[0]);
-            } catch(NumberFormatException e) {
-                loge("Failed to read network-id '" + result[0] + "'");
-                continue;
-            }
-            if (result.length > 3) {
-                if (result[3].indexOf("[CURRENT]") != -1)
-                    config.status = WifiConfiguration.Status.CURRENT;
-                else if (result[3].indexOf("[DISABLED]") != -1)
-                    config.status = WifiConfiguration.Status.DISABLED;
-                else
-                    config.status = WifiConfiguration.Status.ENABLED;
-            } else {
-                config.status = WifiConfiguration.Status.ENABLED;
-            }
-            readNetworkVariables(config);
-            if (config.priority > mLastPriority) {
-                mLastPriority = config.priority;
-            }
-            config.ipAssignment = IpAssignment.DHCP;
-            config.proxySettings = ProxySettings.NONE;
-
-            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 */
-    private void markAllNetworksDisabledExcept(int netId) {
-        for(WifiConfiguration config : mConfiguredNetworks.values()) {
-            if(config != null && config.networkId != netId) {
-                if (config.status != Status.DISABLED) {
-                    config.status = Status.DISABLED;
-                    config.disableReason = WifiConfiguration.DISABLED_UNKNOWN_REASON;
-                }
-            }
-        }
-    }
-
-    private void markAllNetworksDisabled() {
-        markAllNetworksDisabledExcept(INVALID_NETWORK_ID);
-    }
-
-    boolean needsUnlockedKeyStore() {
-
-        // Any network using certificates to authenticate access requires
-        // unlocked key store; unless the certificates can be stored with
-        // hardware encryption
-
-        for(WifiConfiguration config : mConfiguredNetworks.values()) {
-
-            if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP)
-                    && config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
-
-                if (config.enterpriseConfig.needsSoftwareBackedKeyStore()) {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    private void writeIpAndProxyConfigurations() {
-
-        /* Make a copy */
-        List<WifiConfiguration> networks = new ArrayList<WifiConfiguration>();
-        for(WifiConfiguration config : mConfiguredNetworks.values()) {
-            networks.add(new WifiConfiguration(config));
-        }
-
-        DelayedDiskWrite.write(networks);
-    }
-
-    private static class DelayedDiskWrite {
-
-        private static HandlerThread sDiskWriteHandlerThread;
-        private static Handler sDiskWriteHandler;
-        /* Tracks multiple writes on the same thread */
-        private static int sWriteSequence = 0;
-        private static final String TAG = "DelayedDiskWrite";
-
-        static void write (final List<WifiConfiguration> networks) {
-
-            /* Do a delayed write to disk on a seperate handler thread */
-            synchronized (DelayedDiskWrite.class) {
-                if (++sWriteSequence == 1) {
-                    sDiskWriteHandlerThread = new HandlerThread("WifiConfigThread");
-                    sDiskWriteHandlerThread.start();
-                    sDiskWriteHandler = new Handler(sDiskWriteHandlerThread.getLooper());
-                }
-            }
-
-            sDiskWriteHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        onWriteCalled(networks);
-                    }
-                });
-        }
-
-        private static void onWriteCalled(List<WifiConfiguration> networks) {
-
-            DataOutputStream out = null;
-            try {
-                out = new DataOutputStream(new BufferedOutputStream(
-                            new FileOutputStream(ipConfigFile)));
-
-                out.writeInt(IPCONFIG_FILE_VERSION);
-
-                for(WifiConfiguration config : networks) {
-                    boolean writeToFile = false;
-
-                    try {
-                        LinkProperties linkProperties = config.linkProperties;
-                        switch (config.ipAssignment) {
-                            case STATIC:
-                                out.writeUTF(IP_ASSIGNMENT_KEY);
-                                out.writeUTF(config.ipAssignment.toString());
-                                for (LinkAddress linkAddr : linkProperties.getLinkAddresses()) {
-                                    out.writeUTF(LINK_ADDRESS_KEY);
-                                    out.writeUTF(linkAddr.getAddress().getHostAddress());
-                                    out.writeInt(linkAddr.getNetworkPrefixLength());
-                                }
-                                for (RouteInfo route : linkProperties.getRoutes()) {
-                                    out.writeUTF(GATEWAY_KEY);
-                                    LinkAddress dest = route.getDestination();
-                                    if (dest != null) {
-                                        out.writeInt(1);
-                                        out.writeUTF(dest.getAddress().getHostAddress());
-                                        out.writeInt(dest.getNetworkPrefixLength());
-                                    } else {
-                                        out.writeInt(0);
-                                    }
-                                    if (route.getGateway() != null) {
-                                        out.writeInt(1);
-                                        out.writeUTF(route.getGateway().getHostAddress());
-                                    } else {
-                                        out.writeInt(0);
-                                    }
-                                }
-                                for (InetAddress inetAddr : linkProperties.getDnses()) {
-                                    out.writeUTF(DNS_KEY);
-                                    out.writeUTF(inetAddr.getHostAddress());
-                                }
-                                writeToFile = true;
-                                break;
-                            case DHCP:
-                                out.writeUTF(IP_ASSIGNMENT_KEY);
-                                out.writeUTF(config.ipAssignment.toString());
-                                writeToFile = true;
-                                break;
-                            case UNASSIGNED:
-                                /* Ignore */
-                                break;
-                            default:
-                                loge("Ignore invalid ip assignment while writing");
-                                break;
-                        }
-
-                        switch (config.proxySettings) {
-                            case STATIC:
-                                ProxyProperties proxyProperties = linkProperties.getHttpProxy();
-                                String exclusionList = proxyProperties.getExclusionList();
-                                out.writeUTF(PROXY_SETTINGS_KEY);
-                                out.writeUTF(config.proxySettings.toString());
-                                out.writeUTF(PROXY_HOST_KEY);
-                                out.writeUTF(proxyProperties.getHost());
-                                out.writeUTF(PROXY_PORT_KEY);
-                                out.writeInt(proxyProperties.getPort());
-                                out.writeUTF(EXCLUSION_LIST_KEY);
-                                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());
-                                writeToFile = true;
-                                break;
-                            case UNASSIGNED:
-                                /* Ignore */
-                                break;
-                            default:
-                                loge("Ignthisore invalid proxy settings while writing");
-                                break;
-                        }
-                        if (writeToFile) {
-                            out.writeUTF(ID_KEY);
-                            out.writeInt(configKey(config));
-                        }
-                    } catch (NullPointerException e) {
-                        loge("Failure in writing " + config.linkProperties + e);
-                    }
-                    out.writeUTF(EOS);
-                }
-
-            } catch (IOException e) {
-                loge("Error writing data file");
-            } finally {
-                if (out != null) {
-                    try {
-                        out.close();
-                    } catch (Exception e) {}
-                }
-
-                //Quit if no more writes sent
-                synchronized (DelayedDiskWrite.class) {
-                    if (--sWriteSequence == 0) {
-                        sDiskWriteHandler.getLooper().quit();
-                        sDiskWriteHandler = null;
-                        sDiskWriteHandlerThread = null;
-                    }
-                }
-            }
-        }
-
-        private static void loge(String s) {
-            Log.e(TAG, s);
-        }
-    }
-
-    private void readIpAndProxyConfigurations() {
-
-        DataInputStream in = null;
-        try {
-            in = new DataInputStream(new BufferedInputStream(new FileInputStream(
-                    ipConfigFile)));
-
-            int version = in.readInt();
-            if (version != 2 && version != 1) {
-                loge("Bad version on IP configuration file, ignore read");
-                return;
-            }
-
-            while (true) {
-                int id = -1;
-                // Default is DHCP with no proxy
-                IpAssignment ipAssignment = IpAssignment.DHCP;
-                ProxySettings proxySettings = ProxySettings.NONE;
-                LinkProperties linkProperties = new LinkProperties();
-                String proxyHost = null;
-                String pacFileUrl = null;
-                int proxyPort = -1;
-                String exclusionList = null;
-                String key;
-
-                do {
-                    key = in.readUTF();
-                    try {
-                        if (key.equals(ID_KEY)) {
-                            id = in.readInt();
-                        } else if (key.equals(IP_ASSIGNMENT_KEY)) {
-                            ipAssignment = IpAssignment.valueOf(in.readUTF());
-                        } else if (key.equals(LINK_ADDRESS_KEY)) {
-                            LinkAddress linkAddr = new LinkAddress(
-                                    NetworkUtils.numericToInetAddress(in.readUTF()), in.readInt());
-                            linkProperties.addLinkAddress(linkAddr);
-                        } else if (key.equals(GATEWAY_KEY)) {
-                            LinkAddress dest = null;
-                            InetAddress gateway = null;
-                            if (version == 1) {
-                                // only supported default gateways - leave the dest/prefix empty
-                                gateway = NetworkUtils.numericToInetAddress(in.readUTF());
-                            } else {
-                                if (in.readInt() == 1) {
-                                    dest = new LinkAddress(
-                                            NetworkUtils.numericToInetAddress(in.readUTF()),
-                                            in.readInt());
-                                }
-                                if (in.readInt() == 1) {
-                                    gateway = NetworkUtils.numericToInetAddress(in.readUTF());
-                                }
-                            }
-                            linkProperties.addRoute(new RouteInfo(dest, gateway));
-                        } else if (key.equals(DNS_KEY)) {
-                            linkProperties.addDns(
-                                    NetworkUtils.numericToInetAddress(in.readUTF()));
-                        } else if (key.equals(PROXY_SETTINGS_KEY)) {
-                            proxySettings = ProxySettings.valueOf(in.readUTF());
-                        } else if (key.equals(PROXY_HOST_KEY)) {
-                            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)) {
-                            break;
-                        } else {
-                            loge("Ignore unknown key " + key + "while reading");
-                        }
-                    } catch (IllegalArgumentException e) {
-                        loge("Ignore invalid address while reading" + e);
-                    }
-                } while (true);
-
-                if (id != -1) {
-                    WifiConfiguration config = mConfiguredNetworks.get(
-                            mNetworkIds.get(id));
-
-                    if (config == null) {
-                        loge("configuration found for missing network, ignored");
-                    } else {
-                        config.linkProperties = linkProperties;
-                        switch (ipAssignment) {
-                            case STATIC:
-                            case DHCP:
-                                config.ipAssignment = ipAssignment;
-                                break;
-                            case UNASSIGNED:
-                                loge("BUG: Found UNASSIGNED IP on file, use DHCP");
-                                config.ipAssignment = IpAssignment.DHCP;
-                                break;
-                            default:
-                                loge("Ignore invalid ip assignment while reading");
-                                break;
-                        }
-
-                        switch (proxySettings) {
-                            case STATIC:
-                                config.proxySettings = proxySettings;
-                                ProxyProperties proxyProperties =
-                                    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;
-                            case UNASSIGNED:
-                                loge("BUG: Found UNASSIGNED proxy on file, use NONE");
-                                config.proxySettings = ProxySettings.NONE;
-                                break;
-                            default:
-                                loge("Ignore invalid proxy settings while reading");
-                                break;
-                        }
-                    }
-                } else {
-                    if (DBG) log("Missing id while parsing configuration");
-                }
-            }
-        } catch (EOFException ignore) {
-        } catch (IOException e) {
-            loge("Error parsing configuration" + e);
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (Exception e) {}
-            }
-        }
-    }
-
-    private NetworkUpdateResult addOrUpdateNetworkNative(WifiConfiguration config) {
-        /*
-         * If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
-         * 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
-        if (netId == INVALID_NETWORK_ID) {
-            Integer savedNetId = mNetworkIds.get(configKey(config));
-            if (savedNetId != null) {
-                netId = savedNetId;
-            } else {
-                newNetwork = true;
-                netId = mWifiNative.addNetwork();
-                if (netId < 0) {
-                    loge("Failed to add a network!");
-                    return new NetworkUpdateResult(INVALID_NETWORK_ID);
-                }
-            }
-        }
-
-        boolean updateFailed = true;
-
-        setVariables: {
-
-            if (config.SSID != null &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.ssidVarName,
-                        config.SSID)) {
-                loge("failed to set SSID: "+config.SSID);
-                break setVariables;
-            }
-
-            if (config.BSSID != null &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.bssidVarName,
-                        config.BSSID)) {
-                loge("failed to set BSSID: "+config.BSSID);
-                break setVariables;
-            }
-
-            String allowedKeyManagementString =
-                makeString(config.allowedKeyManagement, WifiConfiguration.KeyMgmt.strings);
-            if (config.allowedKeyManagement.cardinality() != 0 &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.KeyMgmt.varName,
-                        allowedKeyManagementString)) {
-                loge("failed to set key_mgmt: "+
-                        allowedKeyManagementString);
-                break setVariables;
-            }
-
-            String allowedProtocolsString =
-                makeString(config.allowedProtocols, WifiConfiguration.Protocol.strings);
-            if (config.allowedProtocols.cardinality() != 0 &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.Protocol.varName,
-                        allowedProtocolsString)) {
-                loge("failed to set proto: "+
-                        allowedProtocolsString);
-                break setVariables;
-            }
-
-            String allowedAuthAlgorithmsString =
-                makeString(config.allowedAuthAlgorithms, WifiConfiguration.AuthAlgorithm.strings);
-            if (config.allowedAuthAlgorithms.cardinality() != 0 &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.AuthAlgorithm.varName,
-                        allowedAuthAlgorithmsString)) {
-                loge("failed to set auth_alg: "+
-                        allowedAuthAlgorithmsString);
-                break setVariables;
-            }
-
-            String allowedPairwiseCiphersString =
-                    makeString(config.allowedPairwiseCiphers,
-                    WifiConfiguration.PairwiseCipher.strings);
-            if (config.allowedPairwiseCiphers.cardinality() != 0 &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.PairwiseCipher.varName,
-                        allowedPairwiseCiphersString)) {
-                loge("failed to set pairwise: "+
-                        allowedPairwiseCiphersString);
-                break setVariables;
-            }
-
-            String allowedGroupCiphersString =
-                makeString(config.allowedGroupCiphers, WifiConfiguration.GroupCipher.strings);
-            if (config.allowedGroupCiphers.cardinality() != 0 &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.GroupCipher.varName,
-                        allowedGroupCiphersString)) {
-                loge("failed to set group: "+
-                        allowedGroupCiphersString);
-                break setVariables;
-            }
-
-            // Prevent client screw-up by passing in a WifiConfiguration we gave it
-            // by preventing "*" as a key.
-            if (config.preSharedKey != null && !config.preSharedKey.equals("*") &&
-                    !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.pskVarName,
-                        config.preSharedKey)) {
-                loge("failed to set psk");
-                break setVariables;
-            }
-
-            boolean hasSetKey = false;
-            if (config.wepKeys != null) {
-                for (int i = 0; i < config.wepKeys.length; i++) {
-                    // Prevent client screw-up by passing in a WifiConfiguration we gave it
-                    // by preventing "*" as a key.
-                    if (config.wepKeys[i] != null && !config.wepKeys[i].equals("*")) {
-                        if (!mWifiNative.setNetworkVariable(
-                                    netId,
-                                    WifiConfiguration.wepKeyVarNames[i],
-                                    config.wepKeys[i])) {
-                            loge("failed to set wep_key" + i + ": " + config.wepKeys[i]);
-                            break setVariables;
-                        }
-                        hasSetKey = true;
-                    }
-                }
-            }
-
-            if (hasSetKey) {
-                if (!mWifiNative.setNetworkVariable(
-                            netId,
-                            WifiConfiguration.wepTxKeyIdxVarName,
-                            Integer.toString(config.wepTxKeyIndex))) {
-                    loge("failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
-                    break setVariables;
-                }
-            }
-
-            if (!mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.priorityVarName,
-                        Integer.toString(config.priority))) {
-                loge(config.SSID + ": failed to set priority: "
-                        +config.priority);
-                break setVariables;
-            }
-
-            if (config.hiddenSSID && !mWifiNative.setNetworkVariable(
-                        netId,
-                        WifiConfiguration.hiddenSSIDVarName,
-                        Integer.toString(config.hiddenSSID ? 1 : 0))) {
-                loge(config.SSID + ": failed to set hiddenSSID: "+
-                        config.hiddenSSID);
-                break setVariables;
-            }
-
-            if (config.enterpriseConfig != null &&
-                    config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
-
-                WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
-
-                if (enterpriseConfig.needsKeyStore()) {
-                    /**
-                     * Keyguard settings may eventually be controlled by device policy.
-                     * We check here if keystore is unlocked before installing
-                     * credentials.
-                     * TODO: Do we need a dialog here ?
-                     */
-                    if (mKeyStore.state() != KeyStore.State.UNLOCKED) {
-                        loge(config.SSID + ": key store is locked");
-                        break setVariables;
-                    }
-
-                    try {
-                        /* config passed may include only fields being updated.
-                         * In order to generate the key id, fetch uninitialized
-                         * fields from the currently tracked configuration
-                         */
-                        WifiConfiguration currentConfig = mConfiguredNetworks.get(netId);
-                        String keyId = config.getKeyIdForCredentials(currentConfig);
-
-                        if (!enterpriseConfig.installKeys(mKeyStore, keyId)) {
-                            loge(config.SSID + ": failed to install keys");
-                            break setVariables;
-                        }
-                    } catch (IllegalStateException e) {
-                        loge(config.SSID + " invalid config for key installation");
-                        break setVariables;
-                    }
-                }
-
-                HashMap<String, String> enterpriseFields = enterpriseConfig.getFields();
-                for (String key : enterpriseFields.keySet()) {
-                        String value = enterpriseFields.get(key);
-                        if (!mWifiNative.setNetworkVariable(
-                                    netId,
-                                    key,
-                                    value)) {
-                            enterpriseConfig.removeKeys(mKeyStore);
-                            loge(config.SSID + ": failed to set " + key +
-                                    ": " + value);
-                            break setVariables;
-                        }
-                }
-            }
-            updateFailed = false;
-        } //end of setVariables
-
-        if (updateFailed) {
-            if (newNetwork) {
-                mWifiNative.removeNetwork(netId);
-                loge("Failed to set a network variable, removed network: " + netId);
-            }
-            return new NetworkUpdateResult(INVALID_NETWORK_ID);
-        }
-
-        /* An update of the network variables requires reading them
-         * back from the supplicant to update mConfiguredNetworks.
-         * This is because some of the variables (SSID, wep keys &
-         * passphrases) reflect different values when read back than
-         * when written. For example, wep key is stored as * irrespective
-         * of the value sent to the supplicant
-         */
-        WifiConfiguration currentConfig = mConfiguredNetworks.get(netId);
-        if (currentConfig == null) {
-            currentConfig = new WifiConfiguration();
-            currentConfig.ipAssignment = IpAssignment.DHCP;
-            currentConfig.proxySettings = ProxySettings.NONE;
-            currentConfig.networkId = netId;
-        }
-
-        readNetworkVariables(currentConfig);
-
-        mConfiguredNetworks.put(netId, currentConfig);
-        mNetworkIds.put(configKey(currentConfig), netId);
-
-        NetworkUpdateResult result = writeIpAndProxyConfigurationsOnChange(currentConfig, config);
-        result.setIsNewNetwork(newNetwork);
-        result.setNetworkId(netId);
-        return result;
-    }
-
-    /* Compare current and new configuration and write to file on change */
-    private NetworkUpdateResult writeIpAndProxyConfigurationsOnChange(
-            WifiConfiguration currentConfig,
-            WifiConfiguration newConfig) {
-        boolean ipChanged = false;
-        boolean proxyChanged = false;
-        LinkProperties linkProperties = null;
-
-        switch (newConfig.ipAssignment) {
-            case STATIC:
-                Collection<LinkAddress> currentLinkAddresses = currentConfig.linkProperties
-                        .getLinkAddresses();
-                Collection<LinkAddress> newLinkAddresses = newConfig.linkProperties
-                        .getLinkAddresses();
-                Collection<InetAddress> currentDnses = currentConfig.linkProperties.getDnses();
-                Collection<InetAddress> newDnses = newConfig.linkProperties.getDnses();
-                Collection<RouteInfo> currentRoutes = currentConfig.linkProperties.getRoutes();
-                Collection<RouteInfo> newRoutes = newConfig.linkProperties.getRoutes();
-
-                boolean linkAddressesDiffer =
-                        (currentLinkAddresses.size() != newLinkAddresses.size()) ||
-                        !currentLinkAddresses.containsAll(newLinkAddresses);
-                boolean dnsesDiffer = (currentDnses.size() != newDnses.size()) ||
-                        !currentDnses.containsAll(newDnses);
-                boolean routesDiffer = (currentRoutes.size() != newRoutes.size()) ||
-                        !currentRoutes.containsAll(newRoutes);
-
-                if ((currentConfig.ipAssignment != newConfig.ipAssignment) ||
-                        linkAddressesDiffer ||
-                        dnsesDiffer ||
-                        routesDiffer) {
-                    ipChanged = true;
-                }
-                break;
-            case DHCP:
-                if (currentConfig.ipAssignment != newConfig.ipAssignment) {
-                    ipChanged = true;
-                }
-                break;
-            case UNASSIGNED:
-                /* Ignore */
-                break;
-            default:
-                loge("Ignore invalid ip assignment during write");
-                break;
-        }
-
-        switch (newConfig.proxySettings) {
-            case STATIC:
-            case PAC:
-                ProxyProperties newHttpProxy = newConfig.linkProperties.getHttpProxy();
-                ProxyProperties currentHttpProxy = currentConfig.linkProperties.getHttpProxy();
-
-                if (newHttpProxy != null) {
-                    proxyChanged = !newHttpProxy.equals(currentHttpProxy);
-                } else {
-                    proxyChanged = (currentHttpProxy != null);
-                }
-                break;
-            case NONE:
-                if (currentConfig.proxySettings != newConfig.proxySettings) {
-                    proxyChanged = true;
-                }
-                break;
-            case UNASSIGNED:
-                /* Ignore */
-                break;
-            default:
-                loge("Ignore invalid proxy configuration during write");
-                break;
-        }
-
-        if (!ipChanged) {
-            linkProperties = copyIpSettingsFromConfig(currentConfig);
-        } else {
-            currentConfig.ipAssignment = newConfig.ipAssignment;
-            linkProperties = copyIpSettingsFromConfig(newConfig);
-            log("IP config changed SSID = " + currentConfig.SSID + " linkProperties: " +
-                    linkProperties.toString());
-        }
-
-
-        if (!proxyChanged) {
-            linkProperties.setHttpProxy(currentConfig.linkProperties.getHttpProxy());
-        } else {
-            currentConfig.proxySettings = newConfig.proxySettings;
-            linkProperties.setHttpProxy(newConfig.linkProperties.getHttpProxy());
-            log("proxy changed SSID = " + currentConfig.SSID);
-            if (linkProperties.getHttpProxy() != null) {
-                log(" proxyProperties: " + linkProperties.getHttpProxy().toString());
-            }
-        }
-
-        if (ipChanged || proxyChanged) {
-            currentConfig.linkProperties = linkProperties;
-            writeIpAndProxyConfigurations();
-            sendConfiguredNetworksChangedBroadcast(currentConfig,
-                    WifiManager.CHANGE_REASON_CONFIG_CHANGE);
-        }
-        return new NetworkUpdateResult(ipChanged, proxyChanged);
-    }
-
-    private LinkProperties copyIpSettingsFromConfig(WifiConfiguration config) {
-        LinkProperties linkProperties = new LinkProperties();
-        linkProperties.setInterfaceName(config.linkProperties.getInterfaceName());
-        for (LinkAddress linkAddr : config.linkProperties.getLinkAddresses()) {
-            linkProperties.addLinkAddress(linkAddr);
-        }
-        for (RouteInfo route : config.linkProperties.getRoutes()) {
-            linkProperties.addRoute(route);
-        }
-        for (InetAddress dns : config.linkProperties.getDnses()) {
-            linkProperties.addDns(dns);
-        }
-        return linkProperties;
-    }
-
-    /**
-     * Read the variables from the supplicant daemon that are needed to
-     * fill in the WifiConfiguration object.
-     *
-     * @param config the {@link WifiConfiguration} object to be filled in.
-     */
-    private void readNetworkVariables(WifiConfiguration config) {
-
-        int netId = config.networkId;
-        if (netId < 0)
-            return;
-
-        /*
-         * TODO: maybe should have a native method that takes an array of
-         * variable names and returns an array of values. But we'd still
-         * be doing a round trip to the supplicant daemon for each variable.
-         */
-        String value;
-
-        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.ssidVarName);
-        if (!TextUtils.isEmpty(value)) {
-            if (value.charAt(0) != '"') {
-                config.SSID = "\"" + WifiSsid.createFromHex(value).toString() + "\"";
-                //TODO: convert a hex string that is not UTF-8 decodable to a P-formatted
-                //supplicant string
-            } else {
-                config.SSID = value;
-            }
-        } else {
-            config.SSID = null;
-        }
-
-        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.bssidVarName);
-        if (!TextUtils.isEmpty(value)) {
-            config.BSSID = value;
-        } else {
-            config.BSSID = null;
-        }
-
-        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.priorityVarName);
-        config.priority = -1;
-        if (!TextUtils.isEmpty(value)) {
-            try {
-                config.priority = Integer.parseInt(value);
-            } catch (NumberFormatException ignore) {
-            }
-        }
-
-        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.hiddenSSIDVarName);
-        config.hiddenSSID = false;
-        if (!TextUtils.isEmpty(value)) {
-            try {
-                config.hiddenSSID = Integer.parseInt(value) != 0;
-            } catch (NumberFormatException ignore) {
-            }
-        }
-
-        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.wepTxKeyIdxVarName);
-        config.wepTxKeyIndex = -1;
-        if (!TextUtils.isEmpty(value)) {
-            try {
-                config.wepTxKeyIndex = Integer.parseInt(value);
-            } catch (NumberFormatException ignore) {
-            }
-        }
-
-        for (int i = 0; i < 4; i++) {
-            value = mWifiNative.getNetworkVariable(netId,
-                    WifiConfiguration.wepKeyVarNames[i]);
-            if (!TextUtils.isEmpty(value)) {
-                config.wepKeys[i] = value;
-            } else {
-                config.wepKeys[i] = null;
-            }
-        }
-
-        value = mWifiNative.getNetworkVariable(netId, WifiConfiguration.pskVarName);
-        if (!TextUtils.isEmpty(value)) {
-            config.preSharedKey = value;
-        } else {
-            config.preSharedKey = null;
-        }
-
-        value = mWifiNative.getNetworkVariable(config.networkId,
-                WifiConfiguration.Protocol.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.Protocol.strings);
-                if (0 <= index) {
-                    config.allowedProtocols.set(index);
-                }
-            }
-        }
-
-        value = mWifiNative.getNetworkVariable(config.networkId,
-                WifiConfiguration.KeyMgmt.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.KeyMgmt.strings);
-                if (0 <= index) {
-                    config.allowedKeyManagement.set(index);
-                }
-            }
-        }
-
-        value = mWifiNative.getNetworkVariable(config.networkId,
-                WifiConfiguration.AuthAlgorithm.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.AuthAlgorithm.strings);
-                if (0 <= index) {
-                    config.allowedAuthAlgorithms.set(index);
-                }
-            }
-        }
-
-        value = mWifiNative.getNetworkVariable(config.networkId,
-                WifiConfiguration.PairwiseCipher.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.PairwiseCipher.strings);
-                if (0 <= index) {
-                    config.allowedPairwiseCiphers.set(index);
-                }
-            }
-        }
-
-        value = mWifiNative.getNetworkVariable(config.networkId,
-                WifiConfiguration.GroupCipher.varName);
-        if (!TextUtils.isEmpty(value)) {
-            String vals[] = value.split(" ");
-            for (String val : vals) {
-                int index =
-                    lookupString(val, WifiConfiguration.GroupCipher.strings);
-                if (0 <= index) {
-                    config.allowedGroupCiphers.set(index);
-                }
-            }
-        }
-
-        if (config.enterpriseConfig == null) {
-            config.enterpriseConfig = new WifiEnterpriseConfig();
-        }
-        HashMap<String, String> enterpriseFields = config.enterpriseConfig.getFields();
-        for (String key : WifiEnterpriseConfig.getSupplicantKeys()) {
-            value = mWifiNative.getNetworkVariable(netId, key);
-            if (!TextUtils.isEmpty(value)) {
-                enterpriseFields.put(key, removeDoubleQuotes(value));
-            } else {
-                enterpriseFields.put(key, WifiEnterpriseConfig.EMPTY_VALUE);
-            }
-        }
-
-        if (config.enterpriseConfig.migrateOldEapTlsNative(mWifiNative, netId)) {
-            saveConfig();
-        }
-
-        config.enterpriseConfig.migrateCerts(mKeyStore);
-        config.enterpriseConfig.initializeSoftwareKeystoreFlag(mKeyStore);
-    }
-
-    private String removeDoubleQuotes(String string) {
-        int length = string.length();
-        if ((length > 1) && (string.charAt(0) == '"')
-                && (string.charAt(length - 1) == '"')) {
-            return string.substring(1, length - 1);
-        }
-        return string;
-    }
-
-    private String convertToQuotedString(String string) {
-        return "\"" + string + "\"";
-    }
-
-    private String makeString(BitSet set, String[] strings) {
-        StringBuffer buf = new StringBuffer();
-        int nextSetBit = -1;
-
-        /* Make sure all set bits are in [0, strings.length) to avoid
-         * going out of bounds on strings.  (Shouldn't happen, but...) */
-        set = set.get(0, strings.length);
-
-        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
-            buf.append(strings[nextSetBit].replace('_', '-')).append(' ');
-        }
-
-        // remove trailing space
-        if (set.cardinality() > 0) {
-            buf.setLength(buf.length() - 1);
-        }
-
-        return buf.toString();
-    }
-
-    private int lookupString(String string, String[] strings) {
-        int size = strings.length;
-
-        string = string.replace('-', '_');
-
-        for (int i = 0; i < size; i++)
-            if (string.equals(strings[i]))
-                return i;
-
-        // if we ever get here, we should probably add the
-        // value to WifiConfiguration to reflect that it's
-        // supported by the WPA supplicant
-        loge("Failed to look-up a string: " + string);
-
-        return -1;
-    }
-
-    /* Returns a unique for a given configuration */
-    private static int configKey(WifiConfiguration config) {
-        String key;
-
-        if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
-            key = config.SSID + KeyMgmt.strings[KeyMgmt.WPA_PSK];
-        } else if (config.allowedKeyManagement.get(KeyMgmt.WPA_EAP) ||
-                config.allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
-            key = config.SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
-        } else if (config.wepKeys[0] != null) {
-            key = config.SSID + "WEP";
-        } else {
-            key = config.SSID + KeyMgmt.strings[KeyMgmt.NONE];
-        }
-
-        return key.hashCode();
-    }
-
-    void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("WifiConfigStore");
-        pw.println("mLastPriority " + mLastPriority);
-        pw.println("Configured networks");
-        for (WifiConfiguration conf : getConfiguredNetworks()) {
-            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() {
-        return ipConfigFile;
-    }
-
-    private void loge(String s) {
-        Log.e(TAG, s);
-    }
-
-    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 87afa88..6562462 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -499,7 +499,7 @@
      * @throws IllegalStateException if config is invalid for key id generation
      * @hide
      */
-    String getKeyIdForCredentials(WifiConfiguration current) {
+    public String getKeyIdForCredentials(WifiConfiguration current) {
         String keyMgmt = null;
 
         try {
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index c7ebecb..69be2cf 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -17,19 +17,13 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.Process;
 import android.security.Credentials;
-import android.security.KeyChain;
-import android.security.KeyStore;
 import android.text.TextUtils;
-import android.util.Slog;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.security.KeyFactory;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
-import java.security.cert.Certificate;
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
@@ -39,67 +33,71 @@
 import java.util.HashMap;
 import java.util.Map;
 
-/** 
+/**
  * Enterprise configuration details for Wi-Fi. Stores details about the EAP method
  * and any associated credentials.
  */
 public class WifiEnterpriseConfig implements Parcelable {
-    private static final String TAG = "WifiEnterpriseConfig";
-    private static final boolean DBG = false;
-    /**
-     * In old configurations, the "private_key" field was used. However, newer
-     * configurations use the key_id field with the engine_id set to "keystore".
-     * If this field is found in the configuration, the migration code is
-     * triggered.
-     */
-    private static final String OLD_PRIVATE_KEY_NAME = "private_key";
 
+    /** @hide */
+    public static final String EMPTY_VALUE         = "NULL";
+    /** @hide */
+    public static final String EAP_KEY             = "eap";
+    /** @hide */
+    public static final String PHASE2_KEY          = "phase2";
+    /** @hide */
+    public static final String IDENTITY_KEY        = "identity";
+    /** @hide */
+    public static final String ANON_IDENTITY_KEY   = "anonymous_identity";
+    /** @hide */
+    public static final String PASSWORD_KEY        = "password";
+    /** @hide */
+    public static final String SUBJECT_MATCH_KEY   = "subject_match";
+    /** @hide */
+    public static final String OPP_KEY_CACHING     = "proactive_key_caching";
     /**
      * String representing the keystore OpenSSL ENGINE's ID.
+     * @hide
      */
-    private static final String ENGINE_ID_KEYSTORE = "keystore";
+    public static final String ENGINE_ID_KEYSTORE = "keystore";
 
     /**
      * String representing the keystore URI used for wpa_supplicant.
+     * @hide
      */
-    private static final String KEYSTORE_URI = "keystore://";
+    public static final String KEYSTORE_URI = "keystore://";
 
     /**
      * String to set the engine value to when it should be enabled.
+     * @hide
      */
-    private static final String ENGINE_ENABLE = "1";
+    public static final String ENGINE_ENABLE = "1";
 
     /**
      * String to set the engine value to when it should be disabled.
+     * @hide
      */
-    private static final String ENGINE_DISABLE = "0";
+    public static final String ENGINE_DISABLE = "0";
 
-    private static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
-    private static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE;
-
-    private static final String EAP_KEY             = "eap";
-    private static final String PHASE2_KEY          = "phase2";
-    private static final String IDENTITY_KEY        = "identity";
-    private static final String ANON_IDENTITY_KEY   = "anonymous_identity";
-    private static final String PASSWORD_KEY        = "password";
-    private static final String CLIENT_CERT_KEY     = "client_cert";
-    private static final String CA_CERT_KEY         = "ca_cert";
-    private static final String SUBJECT_MATCH_KEY   = "subject_match";
-    private static final String ENGINE_KEY          = "engine";
-    private static final String ENGINE_ID_KEY       = "engine_id";
-    private static final String PRIVATE_KEY_ID_KEY  = "key_id";
-    private static final String OPP_KEY_CACHING     = "proactive_key_caching";
+    /** @hide */
+    public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
+    /** @hide */
+    public static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE;
+    /** @hide */
+    public static final String CLIENT_CERT_KEY     = "client_cert";
+    /** @hide */
+    public static final String CA_CERT_KEY         = "ca_cert";
+    /** @hide */
+    public static final String ENGINE_KEY          = "engine";
+    /** @hide */
+    public static final String ENGINE_ID_KEY       = "engine_id";
+    /** @hide */
+    public static final String PRIVATE_KEY_ID_KEY  = "key_id";
 
     private HashMap<String, String> mFields = new HashMap<String, String>();
     private X509Certificate mCaCert;
     private PrivateKey mClientPrivateKey;
     private X509Certificate mClientCertificate;
-    private boolean mNeedsSoftwareKeystore = false;
-
-    /** This represents an empty value of an enterprise field.
-     * NULL is used at wpa_supplicant to indicate an empty value
-     */
-    static final String EMPTY_VALUE = "NULL";
 
     public WifiEnterpriseConfig() {
         // Do not set defaults so that the enterprise fields that are not changed
@@ -246,24 +244,20 @@
         public static final int GTC         = 4;
         private static final String PREFIX = "auth=";
         /** @hide */
-        public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP", "MSCHAPV2", "GTC" };
+        public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP",
+                "MSCHAPV2", "GTC" };
 
         /** Prevent initialization */
         private Phase2() {}
     }
 
-    /** Internal use only */
-    HashMap<String, String> getFields() {
+    /** Internal use only
+     * @hide
+     */
+    public HashMap<String, String> getFields() {
         return mFields;
     }
 
-    /** Internal use only */
-    static String[] getSupplicantKeys() {
-        return new String[] { EAP_KEY, PHASE2_KEY, IDENTITY_KEY, ANON_IDENTITY_KEY, PASSWORD_KEY,
-                CLIENT_CERT_KEY, CA_CERT_KEY, SUBJECT_MATCH_KEY, ENGINE_KEY, ENGINE_ID_KEY,
-                PRIVATE_KEY_ID_KEY };
-    }
-
     /**
      * Set the EAP authentication method.
      * @param  eapMethod is one {@link Eap#PEAP}, {@link Eap#TLS}, {@link Eap#TTLS} or
@@ -431,7 +425,6 @@
 
     /**
      * Get CA certificate
-     *
      * @return X.509 CA certificate
      */
     public X509Certificate getCaCertificate() {
@@ -439,7 +432,13 @@
     }
 
     /**
-     * Set Client certificate alias.
+     * @hide
+     */
+    public void resetCaCertificate() {
+        mCaCert = null;
+    }
+
+    /** Set Client certificate alias.
      *
      * <p> See the {@link android.security.KeyChain} for details on installing or choosing
      * a certificate
@@ -507,116 +506,19 @@
         return mClientCertificate;
     }
 
-    boolean needsKeyStore() {
-        // Has no keys to be installed
-        if (mClientCertificate == null && mCaCert == null) return false;
-        return true;
+    /**
+     * @hide
+     */
+    public void resetClientKeyEntry() {
+        mClientPrivateKey = null;
+        mClientCertificate = null;
     }
 
-    static boolean isHardwareBackedKey(PrivateKey key) {
-        return KeyChain.isBoundKeyAlgorithm(key.getAlgorithm());
-    }
-
-    static boolean hasHardwareBackedKey(Certificate certificate) {
-        return KeyChain.isBoundKeyAlgorithm(certificate.getPublicKey().getAlgorithm());
-    }
-
-    boolean needsSoftwareBackedKeyStore() {
-        return mNeedsSoftwareKeystore;
-    }
-
-    boolean installKeys(android.security.KeyStore keyStore, String name) {
-        boolean ret = true;
-        String privKeyName = Credentials.USER_PRIVATE_KEY + name;
-        String userCertName = Credentials.USER_CERTIFICATE + name;
-        String caCertName = Credentials.CA_CERTIFICATE + name;
-        if (mClientCertificate != null) {
-            byte[] privKeyData = mClientPrivateKey.getEncoded();
-            if (isHardwareBackedKey(mClientPrivateKey)) {
-                // Hardware backed key store is secure enough to store keys un-encrypted, this
-                // removes the need for user to punch a PIN to get access to these keys
-                if (DBG) Slog.d(TAG, "importing keys " + name + " in hardware backed " +
-                        "store");
-                ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
-                                KeyStore.FLAG_NONE);
-            } else {
-                // Software backed key store is NOT secure enough to store keys un-encrypted.
-                // Save keys encrypted so they are protected with user's PIN. User will
-                // have to unlock phone before being able to use these keys and connect to
-                // networks.
-                if (DBG) Slog.d(TAG, "importing keys " + name + " in software backed store");
-                ret = keyStore.importKey(privKeyName, privKeyData, Process.WIFI_UID,
-                        KeyStore.FLAG_ENCRYPTED);
-                mNeedsSoftwareKeystore = true;
-            }
-            if (ret == false) {
-                return ret;
-            }
-
-            ret = putCertInKeyStore(keyStore, userCertName, mClientCertificate);
-            if (ret == false) {
-                // Remove private key installed
-                keyStore.delKey(privKeyName, Process.WIFI_UID);
-                return ret;
-            }
-        }
-
-        if (mCaCert != null) {
-            ret = putCertInKeyStore(keyStore, caCertName, mCaCert);
-            if (ret == false) {
-                if (mClientCertificate != null) {
-                    // Remove client key+cert
-                    keyStore.delKey(privKeyName, Process.WIFI_UID);
-                    keyStore.delete(userCertName, Process.WIFI_UID);
-                }
-                return ret;
-            }
-        }
-
-        // Set alias names
-        if (mClientCertificate != null) {
-            setClientCertificateAlias(name);
-            mClientPrivateKey = null;
-            mClientCertificate = null;
-        }
-
-        if (mCaCert != null) {
-            setCaCertificateAlias(name);
-            mCaCert = null;
-        }
-
-        return ret;
-    }
-
-    private boolean putCertInKeyStore(android.security.KeyStore keyStore, String name,
-            Certificate cert) {
-        try {
-            byte[] certData = Credentials.convertToPem(cert);
-            if (DBG) Slog.d(TAG, "putting certificate " + name + " in keystore");
-            return keyStore.put(name, certData, Process.WIFI_UID, KeyStore.FLAG_NONE);
-
-        } catch (IOException e1) {
-            return false;
-        } catch (CertificateException e2) {
-            return false;
-        }
-    }
-
-    void removeKeys(KeyStore keyStore) {
-        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
-        // a valid client certificate is configured
-        if (!TextUtils.isEmpty(client)) {
-            if (DBG) Slog.d(TAG, "removing client private key and user cert");
-            keyStore.delKey(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
-            keyStore.delete(Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
-        }
-
-        String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
-        // a valid ca certificate is configured
-        if (!TextUtils.isEmpty(ca)) {
-            if (DBG) Slog.d(TAG, "removing CA cert");
-            keyStore.delete(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
-        }
+    /**
+     * @hide
+     */
+    public PrivateKey getClientPrivateKey() {
+        return mClientPrivateKey;
     }
 
     /**
@@ -651,129 +553,6 @@
         return eap + "_" + phase2;
     }
 
-    /** Migrates the old style TLS config to the new config style. This should only be used
-     * when restoring an old wpa_supplicant.conf or upgrading from a previous
-     * platform version.
-     * @return true if the config was updated
-     * @hide
-     */
-    boolean migrateOldEapTlsNative(WifiNative wifiNative, int netId) {
-        String oldPrivateKey = wifiNative.getNetworkVariable(netId, OLD_PRIVATE_KEY_NAME);
-        /*
-         * If the old configuration value is not present, then there is nothing
-         * to do.
-         */
-        if (TextUtils.isEmpty(oldPrivateKey)) {
-            return false;
-        } else {
-            // Also ignore it if it's empty quotes.
-            oldPrivateKey = removeDoubleQuotes(oldPrivateKey);
-            if (TextUtils.isEmpty(oldPrivateKey)) {
-                return false;
-            }
-        }
-
-        mFields.put(ENGINE_KEY, ENGINE_ENABLE);
-        mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE));
-
-        /*
-        * The old key started with the keystore:// URI prefix, but we don't
-        * need that anymore. Trim it off if it exists.
-        */
-        final String keyName;
-        if (oldPrivateKey.startsWith(KEYSTORE_URI)) {
-            keyName = new String(oldPrivateKey.substring(KEYSTORE_URI.length()));
-        } else {
-            keyName = oldPrivateKey;
-        }
-        mFields.put(PRIVATE_KEY_ID_KEY, convertToQuotedString(keyName));
-
-        wifiNative.setNetworkVariable(netId, ENGINE_KEY, mFields.get(ENGINE_KEY));
-        wifiNative.setNetworkVariable(netId, ENGINE_ID_KEY, mFields.get(ENGINE_ID_KEY));
-        wifiNative.setNetworkVariable(netId, PRIVATE_KEY_ID_KEY, mFields.get(PRIVATE_KEY_ID_KEY));
-        // Remove old private_key string so we don't run this again.
-        wifiNative.setNetworkVariable(netId, OLD_PRIVATE_KEY_NAME, EMPTY_VALUE);
-        return true;
-    }
-
-    /** Migrate certs from global pool to wifi UID if not already done */
-    void migrateCerts(android.security.KeyStore keyStore) {
-        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
-        // a valid client certificate is configured
-        if (!TextUtils.isEmpty(client)) {
-            if (!keyStore.contains(Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID)) {
-                keyStore.duplicate(Credentials.USER_PRIVATE_KEY + client, -1,
-                        Credentials.USER_PRIVATE_KEY + client, Process.WIFI_UID);
-                keyStore.duplicate(Credentials.USER_CERTIFICATE + client, -1,
-                        Credentials.USER_CERTIFICATE + client, Process.WIFI_UID);
-            }
-        }
-
-        String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
-        // a valid ca certificate is configured
-        if (!TextUtils.isEmpty(ca)) {
-            if (!keyStore.contains(Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID)) {
-                keyStore.duplicate(Credentials.CA_CERTIFICATE + ca, -1,
-                        Credentials.CA_CERTIFICATE + ca, Process.WIFI_UID);
-            }
-        }
-    }
-
-    void initializeSoftwareKeystoreFlag(android.security.KeyStore keyStore) {
-        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
-        if (!TextUtils.isEmpty(client)) {
-            // a valid client certificate is configured
-
-            // BUGBUG: keyStore.get() never returns certBytes; because it is not
-            // taking WIFI_UID as a parameter. It always looks for certificate
-            // with SYSTEM_UID, and never finds any Wifi certificates. Assuming that
-            // all certificates need software keystore until we get the get() API
-            // fixed.
-
-            mNeedsSoftwareKeystore = true;
-
-            /*
-            try {
-
-                if (DBG) Slog.d(TAG, "Loading client certificate " + Credentials
-                        .USER_CERTIFICATE + client);
-
-                CertificateFactory factory = CertificateFactory.getInstance("X.509");
-                if (factory == null) {
-                    Slog.e(TAG, "Error getting certificate factory");
-                    return;
-                }
-
-                byte[] certBytes = keyStore.get(Credentials.USER_CERTIFICATE + client);
-                if (certBytes != null) {
-                    Certificate cert = (X509Certificate) factory.generateCertificate(
-                            new ByteArrayInputStream(certBytes));
-
-                    if (cert != null) {
-                        mNeedsSoftwareKeystore = hasHardwareBackedKey(cert);
-
-                        if (DBG) Slog.d(TAG, "Loaded client certificate " + Credentials
-                                .USER_CERTIFICATE + client);
-                        if (DBG) Slog.d(TAG, "It " + (mNeedsSoftwareKeystore ? "needs" :
-                                "does not need" ) + " software key store");
-                    } else {
-                        Slog.d(TAG, "could not generate certificate");
-                    }
-                } else {
-                    Slog.e(TAG, "Could not load client certificate " + Credentials
-                            .USER_CERTIFICATE + client);
-                    mNeedsSoftwareKeystore = true;
-                }
-
-            } catch(CertificateException e) {
-                Slog.e(TAG, "Could not read certificates");
-                mCaCert = null;
-                mClientCertificate = null;
-            }
-            */
-        }
-    }
-
     private String removeDoubleQuotes(String string) {
         if (TextUtils.isEmpty(string)) return "";
         int length = string.length();
@@ -806,8 +585,9 @@
      * @param key into the hash
      * @param prefix is the prefix that the value may have
      * @return value
+     * @hide
      */
-    private String getFieldValue(String key, String prefix) {
+    public String getFieldValue(String key, String prefix) {
         String value = mFields.get(key);
         // Uninitialized or known to be empty after reading from supplicant
         if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
@@ -824,8 +604,9 @@
      * @param key into the hash
      * @param value to be set
      * @param prefix an optional value to be prefixed to actual value
+     * @hide
      */
-    private void setFieldValue(String key, String value, String prefix) {
+    public void setFieldValue(String key, String value, String prefix) {
         if (TextUtils.isEmpty(value)) {
             mFields.put(key, EMPTY_VALUE);
         } else {
@@ -833,6 +614,21 @@
         }
     }
 
+
+    /** Set a value with an optional prefix at key
+     * @param key into the hash
+     * @param value to be set
+     * @param prefix an optional value to be prefixed to actual value
+     * @hide
+     */
+    public void setFieldValue(String key, String value) {
+        if (TextUtils.isEmpty(value)) {
+           mFields.put(key, EMPTY_VALUE);
+        } else {
+            mFields.put(key, convertToQuotedString(value));
+        }
+    }
+
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 5d130c6..4a6821c 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -62,7 +62,6 @@
     private String mBSSID;
     private WifiSsid mWifiSsid;
     private int mNetworkId;
-    private boolean mHiddenSSID;
     /** Received Signal Strength Indicator */
     private int mRssi;
 
@@ -70,6 +69,10 @@
     public static final String LINK_SPEED_UNITS = "Mbps";
     private int mLinkSpeed;
 
+    /** Frequency in MHz */
+    public static final String FREQUENCY_UNITS = "MHz";
+    private int mFrequency;
+
     private InetAddress mIpAddress;
     private String mMacAddress;
 
@@ -79,14 +82,15 @@
      */
     private boolean mMeteredHint;
 
-    WifiInfo() {
+    /** @hide */
+    public WifiInfo() {
         mWifiSsid = null;
         mBSSID = null;
         mNetworkId = -1;
         mSupplicantState = SupplicantState.UNINITIALIZED;
         mRssi = -9999;
         mLinkSpeed = -1;
-        mHiddenSSID = false;
+        mFrequency = -1;
     }
 
     /**
@@ -99,19 +103,18 @@
             mBSSID = source.mBSSID;
             mWifiSsid = source.mWifiSsid;
             mNetworkId = source.mNetworkId;
-            mHiddenSSID = source.mHiddenSSID;
             mRssi = source.mRssi;
             mLinkSpeed = source.mLinkSpeed;
+            mFrequency = source.mFrequency;
             mIpAddress = source.mIpAddress;
             mMacAddress = source.mMacAddress;
             mMeteredHint = source.mMeteredHint;
         }
     }
 
-    void setSSID(WifiSsid wifiSsid) {
+    /** @hide */
+    public void setSSID(WifiSsid wifiSsid) {
         mWifiSsid = wifiSsid;
-        // network is considered not hidden by default
-        mHiddenSSID = false;
     }
 
     /**
@@ -138,7 +141,8 @@
         return mWifiSsid;
     }
 
-    void setBSSID(String BSSID) {
+    /** @hide */
+    public void setBSSID(String BSSID) {
         mBSSID = BSSID;
     }
 
@@ -161,7 +165,8 @@
         return mRssi;
     }
 
-    void setRssi(int rssi) {
+    /** @hide */
+    public void setRssi(int rssi) {
         mRssi = rssi;
     }
 
@@ -174,15 +179,31 @@
         return mLinkSpeed;
     }
 
-    void setLinkSpeed(int linkSpeed) {
+    /** @hide */
+    public void setLinkSpeed(int linkSpeed) {
         this.mLinkSpeed = linkSpeed;
     }
 
     /**
+     * Returns the current frequency in {@link #FREQUENCY_UNITS}.
+     * @return the frequency.
+     * @see #FREQUENCY_UNITS
+     */
+    public int getFrequency() {
+        return mFrequency;
+    }
+
+    /** @hide */
+    public void setFrequency(int frequency) {
+        this.mFrequency = frequency;
+    }
+
+    /**
      * Record the MAC address of the WLAN interface
      * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
+     * @hide
      */
-    void setMacAddress(String macAddress) {
+    public void setMacAddress(String macAddress) {
         this.mMacAddress = macAddress;
     }
 
@@ -200,7 +221,8 @@
         return mMeteredHint;
     }
 
-    void setNetworkId(int id) {
+    /** @hide */
+    public void setNetworkId(int id) {
         mNetworkId = id;
     }
 
@@ -223,11 +245,13 @@
         return mSupplicantState;
     }
 
-    void setSupplicantState(SupplicantState state) {
+    /** @hide */
+    public void setSupplicantState(SupplicantState state) {
         mSupplicantState = state;
     }
 
-    void setInetAddress(InetAddress address) {
+    /** @hide */
+    public void setInetAddress(InetAddress address) {
         mIpAddress = address;
     }
 
@@ -244,12 +268,7 @@
      * SSID-specific probe request must be used for scans.
      */
     public boolean getHiddenSSID() {
-        return mHiddenSSID;
-    }
-
-    /** {@hide} */
-    public void setHiddenSSID(boolean hiddenSSID) {
-        mHiddenSSID = hiddenSSID;
+        return mWifiSsid.isHidden();
     }
 
    /**
@@ -304,7 +323,8 @@
             append(", Supplicant state: ").
             append(mSupplicantState == null ? none : mSupplicantState).
             append(", RSSI: ").append(mRssi).
-            append(", Link speed: ").append(mLinkSpeed).
+            append(", Link speed: ").append(mLinkSpeed).append(LINK_SPEED_UNITS).
+            append(", Frequency: ").append(mFrequency).append(FREQUENCY_UNITS).
             append(", Net ID: ").append(mNetworkId).
             append(", Metered hint: ").append(mMeteredHint);
 
@@ -321,6 +341,7 @@
         dest.writeInt(mNetworkId);
         dest.writeInt(mRssi);
         dest.writeInt(mLinkSpeed);
+        dest.writeInt(mFrequency);
         if (mIpAddress != null) {
             dest.writeByte((byte)1);
             dest.writeByteArray(mIpAddress.getAddress());
@@ -347,6 +368,7 @@
                 info.setNetworkId(in.readInt());
                 info.setRssi(in.readInt());
                 info.setLinkSpeed(in.readInt());
+                info.setFrequency(in.readInt());
                 if (in.readByte() == 1) {
                     try {
                         info.setInetAddress(InetAddress.getByAddress(in.createByteArray()));
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 3b47e63..0862b7e 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -20,6 +20,8 @@
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
 import android.net.DhcpInfo;
+import android.net.wifi.ScanSettings;
+import android.net.wifi.WifiChannel;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.Handler;
@@ -35,7 +37,6 @@
 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;
 
@@ -523,6 +524,9 @@
     /** @hide */
     public static final int DATA_ACTIVITY_INOUT        = 0x03;
 
+    /** @hide */
+    public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false;
+
     /* Maximum number of active locks we allow.
      * This limit was added to prevent apps from creating a ridiculous number
      * of locks and crashing the system by overflowing the global ref table.
@@ -761,6 +765,22 @@
     }
 
     /**
+     * Get a list of available channels for customized scan.
+     *
+     * @see {@link WifiChannel}
+     *
+     * @return the channel list, or null if not available
+     * @hide
+     */
+    public List<WifiChannel> getChannelList() {
+        try {
+            return mService.getChannelList();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Request a scan for access points. Returns immediately. The availability
      * of the results is made known later by means of an asynchronous event sent
      * on completion of the scan.
@@ -768,8 +788,7 @@
      */
     public boolean startScan() {
         try {
-            final WorkSource workSource = null;
-            mService.startScan(workSource);
+            mService.startScan(null, null);
             return true;
         } catch (RemoteException e) {
             return false;
@@ -779,7 +798,42 @@
     /** @hide */
     public boolean startScan(WorkSource workSource) {
         try {
-            mService.startScan(workSource);
+            mService.startScan(null, workSource);
+            return true;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Request a scan for access points in specified channel list. Each channel is specified by its
+     * frequency in MHz, e.g. "5500" (do NOT include "DFS" even though it is). The availability of
+     * the results is made known later in the same way as {@link #startScan}.
+     *
+     * Note:
+     *
+     * 1. Customized scan is for non-connection purposes, i.e. it won't trigger a wifi connection
+     *    even though it finds some known networks.
+     *
+     * 2. Customized scan result may include access points that is not specified in the channel
+     *    list. An app will need to do frequency filtering if it wants to get pure results for the
+     *    channel list it specified.
+     *
+     * @hide
+     */
+    public boolean startCustomizedScan(ScanSettings requested) {
+        try {
+            mService.startScan(requested, null);
+            return true;
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /** @hide */
+    public boolean startCustomizedScan(ScanSettings requested, WorkSource workSource) {
+        try {
+            mService.startScan(requested, workSource);
             return true;
         } catch (RemoteException e) {
             return false;
@@ -2163,13 +2217,6 @@
         }
     }
 
-    /** @hide */
-    public void captivePortalCheckComplete() {
-        try {
-            mService.captivePortalCheckComplete();
-        } catch (RemoteException e) {}
-    }
-
     protected void finalize() throws Throwable {
         try {
             synchronized (sThreadRefLock) {
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
deleted file mode 100644
index 6817777..0000000
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.NetworkInfo;
-import android.net.wifi.p2p.WifiP2pConfig;
-import android.net.wifi.p2p.WifiP2pDevice;
-import android.net.wifi.p2p.WifiP2pGroup;
-import android.net.wifi.p2p.WifiP2pService;
-import android.net.wifi.p2p.WifiP2pService.P2pStatus;
-import android.net.wifi.p2p.WifiP2pProvDiscEvent;
-import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
-import android.net.wifi.StateChangeResult;
-import android.os.Message;
-import android.util.Log;
-
-
-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;
-
-/**
- * Listens for events from the wpa_supplicant server, and passes them on
- * to the {@link StateMachine} for handling. Runs in its own thread.
- *
- * @hide
- */
-public class WifiMonitor {
-
-    private static final boolean DBG = false;
-    private static final String TAG = "WifiMonitor";
-
-    /** Events we receive from the supplicant daemon */
-
-    private static final int CONNECTED    = 1;
-    private static final int DISCONNECTED = 2;
-    private static final int STATE_CHANGE = 3;
-    private static final int SCAN_RESULTS = 4;
-    private static final int LINK_SPEED   = 5;
-    private static final int TERMINATING  = 6;
-    private static final int DRIVER_STATE = 7;
-    private static final int EAP_FAILURE  = 8;
-    private static final int ASSOC_REJECT = 9;
-    private static final int UNKNOWN      = 10;
-
-    /** All events coming from the supplicant start with this prefix */
-    private static final String EVENT_PREFIX_STR = "CTRL-EVENT-";
-    private static final int EVENT_PREFIX_LEN_STR = EVENT_PREFIX_STR.length();
-
-    /** All WPA events coming from the supplicant start with this prefix */
-    private static final String WPA_EVENT_PREFIX_STR = "WPA:";
-    private static final String PASSWORD_MAY_BE_INCORRECT_STR =
-       "pre-shared key may be incorrect";
-
-    /* WPS events */
-    private static final String WPS_SUCCESS_STR = "WPS-SUCCESS";
-
-    /* Format: WPS-FAIL msg=%d [config_error=%d] [reason=%d (%s)] */
-    private static final String WPS_FAIL_STR    = "WPS-FAIL";
-    private static final String WPS_FAIL_PATTERN =
-            "WPS-FAIL msg=\\d+(?: config_error=(\\d+))?(?: reason=(\\d+))?";
-
-    /* config error code values for config_error=%d */
-    private static final int CONFIG_MULTIPLE_PBC_DETECTED = 12;
-    private static final int CONFIG_AUTH_FAILURE = 18;
-
-    /* reason code values for reason=%d */
-    private static final int REASON_TKIP_ONLY_PROHIBITED = 1;
-    private static final int REASON_WEP_PROHIBITED = 2;
-
-    private static final String WPS_OVERLAP_STR = "WPS-OVERLAP-DETECTED";
-    private static final String WPS_TIMEOUT_STR = "WPS-TIMEOUT";
-
-    /**
-     * Names of events from wpa_supplicant (minus the prefix). In the
-     * format descriptions, * &quot;<code>x</code>&quot;
-     * designates a dynamic value that needs to be parsed out from the event
-     * string
-     */
-    /**
-     * <pre>
-     * CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed
-     * </pre>
-     * <code>xx:xx:xx:xx:xx:xx</code> is the BSSID of the associated access point
-     */
-    private static final String CONNECTED_STR =    "CONNECTED";
-    /**
-     * <pre>
-     * CTRL-EVENT-DISCONNECTED - Disconnect event - remove keys
-     * </pre>
-     */
-    private static final String DISCONNECTED_STR = "DISCONNECTED";
-    /**
-     * <pre>
-     * CTRL-EVENT-STATE-CHANGE x
-     * </pre>
-     * <code>x</code> is the numerical value of the new state.
-     */
-    private static final String STATE_CHANGE_STR =  "STATE-CHANGE";
-    /**
-     * <pre>
-     * CTRL-EVENT-SCAN-RESULTS ready
-     * </pre>
-     */
-    private static final String SCAN_RESULTS_STR =  "SCAN-RESULTS";
-
-    /**
-     * <pre>
-     * CTRL-EVENT-LINK-SPEED x Mb/s
-     * </pre>
-     * {@code x} is the link speed in Mb/sec.
-     */
-    private static final String LINK_SPEED_STR = "LINK-SPEED";
-    /**
-     * <pre>
-     * CTRL-EVENT-TERMINATING - signal x
-     * </pre>
-     * <code>x</code> is the signal that caused termination.
-     */
-    private static final String TERMINATING_STR =  "TERMINATING";
-    /**
-     * <pre>
-     * CTRL-EVENT-DRIVER-STATE state
-     * </pre>
-     * <code>state</code> can be HANGED
-     */
-    private static final String DRIVER_STATE_STR = "DRIVER-STATE";
-    /**
-     * <pre>
-     * CTRL-EVENT-EAP-FAILURE EAP authentication failed
-     * </pre>
-     */
-    private static final String EAP_FAILURE_STR = "EAP-FAILURE";
-
-    /**
-     * This indicates an authentication failure on EAP FAILURE event
-     */
-    private static final String EAP_AUTH_FAILURE_STR = "EAP authentication failed";
-
-    /**
-     * This indicates an assoc reject event
-     */
-    private static final String ASSOC_REJECT_STR = "ASSOC-REJECT";
-
-    /**
-     * Regex pattern for extracting an Ethernet-style MAC address from a string.
-     * Matches a strings like the following:<pre>
-     * CTRL-EVENT-CONNECTED - Connection to 00:1e:58:ec:d5:6d completed (reauth) [id=1 id_str=]</pre>
-     */
-    private static Pattern mConnectedEventPattern =
-        Pattern.compile("((?:[0-9a-f]{2}:){5}[0-9a-f]{2}) .* \\[id=([0-9]+) ");
-
-    /** P2P events */
-    private static final String P2P_EVENT_PREFIX_STR = "P2P";
-
-    /* P2P-DEVICE-FOUND fa:7b:7a:42:02:13 p2p_dev_addr=fa:7b:7a:42:02:13 pri_dev_type=1-0050F204-1
-       name='p2p-TEST1' config_methods=0x188 dev_capab=0x27 group_capab=0x0 */
-    private static final String P2P_DEVICE_FOUND_STR = "P2P-DEVICE-FOUND";
-
-    /* P2P-DEVICE-LOST p2p_dev_addr=42:fc:89:e1:e2:27 */
-    private static final String P2P_DEVICE_LOST_STR = "P2P-DEVICE-LOST";
-
-    /* P2P-FIND-STOPPED */
-    private static final String P2P_FIND_STOPPED_STR = "P2P-FIND-STOPPED";
-
-    /* P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 */
-    private static final String P2P_GO_NEG_REQUEST_STR = "P2P-GO-NEG-REQUEST";
-
-    private static final String P2P_GO_NEG_SUCCESS_STR = "P2P-GO-NEG-SUCCESS";
-
-    /* P2P-GO-NEG-FAILURE status=x */
-    private static final String P2P_GO_NEG_FAILURE_STR = "P2P-GO-NEG-FAILURE";
-
-    private static final String P2P_GROUP_FORMATION_SUCCESS_STR =
-            "P2P-GROUP-FORMATION-SUCCESS";
-
-    private static final String P2P_GROUP_FORMATION_FAILURE_STR =
-            "P2P-GROUP-FORMATION-FAILURE";
-
-    /* P2P-GROUP-STARTED p2p-wlan0-0 [client|GO] ssid="DIRECT-W8" freq=2437
-       [psk=2182b2e50e53f260d04f3c7b25ef33c965a3291b9b36b455a82d77fd82ca15bc|passphrase="fKG4jMe3"]
-       go_dev_addr=fa:7b:7a:42:02:13 [PERSISTENT] */
-    private static final String P2P_GROUP_STARTED_STR = "P2P-GROUP-STARTED";
-
-    /* P2P-GROUP-REMOVED p2p-wlan0-0 [client|GO] reason=REQUESTED */
-    private static final String P2P_GROUP_REMOVED_STR = "P2P-GROUP-REMOVED";
-
-    /* P2P-INVITATION-RECEIVED sa=fa:7b:7a:42:02:13 go_dev_addr=f8:7b:7a:42:02:13
-        bssid=fa:7b:7a:42:82:13 unknown-network */
-    private static final String P2P_INVITATION_RECEIVED_STR = "P2P-INVITATION-RECEIVED";
-
-    /* P2P-INVITATION-RESULT status=1 */
-    private static final String P2P_INVITATION_RESULT_STR = "P2P-INVITATION-RESULT";
-
-    /* P2P-PROV-DISC-PBC-REQ 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
-       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
-       group_capab=0x0 */
-    private static final String P2P_PROV_DISC_PBC_REQ_STR = "P2P-PROV-DISC-PBC-REQ";
-
-    /* P2P-PROV-DISC-PBC-RESP 02:12:47:f2:5a:36 */
-    private static final String P2P_PROV_DISC_PBC_RSP_STR = "P2P-PROV-DISC-PBC-RESP";
-
-    /* P2P-PROV-DISC-ENTER-PIN 42:fc:89:e1:e2:27 p2p_dev_addr=42:fc:89:e1:e2:27
-       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
-       group_capab=0x0 */
-    private static final String P2P_PROV_DISC_ENTER_PIN_STR = "P2P-PROV-DISC-ENTER-PIN";
-    /* P2P-PROV-DISC-SHOW-PIN 42:fc:89:e1:e2:27 44490607 p2p_dev_addr=42:fc:89:e1:e2:27
-       pri_dev_type=1-0050F204-1 name='p2p-TEST2' config_methods=0x188 dev_capab=0x27
-       group_capab=0x0 */
-    private static final String P2P_PROV_DISC_SHOW_PIN_STR = "P2P-PROV-DISC-SHOW-PIN";
-    /* P2P-PROV-DISC-FAILURE p2p_dev_addr=42:fc:89:e1:e2:27 */
-    private static final String P2P_PROV_DISC_FAILURE_STR = "P2P-PROV-DISC-FAILURE";
-
-    /*
-     * Protocol format is as follows.<br>
-     * See the Table.62 in the WiFi Direct specification for the detail.
-     * ______________________________________________________________
-     * |           Length(2byte)     | Type(1byte) | TransId(1byte)}|
-     * ______________________________________________________________
-     * | status(1byte)  |            vendor specific(variable)      |
-     *
-     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300000101
-     * length=3, service type=0(ALL Service), transaction id=1,
-     * status=1(service protocol type not available)<br>
-     *
-     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 0300020201
-     * length=3, service type=2(UPnP), transaction id=2,
-     * status=1(service protocol type not available)
-     *
-     * P2P-SERV-DISC-RESP 42:fc:89:e1:e2:27 1 990002030010757569643a3131323
-     * 2646534652d383537342d353961622d393332322d3333333435363738393034343a3
-     * a75726e3a736368656d61732d75706e702d6f72673a736572766963653a436f6e746
-     * 56e744469726563746f72793a322c757569643a36383539646564652d383537342d3
-     * 53961622d393333322d3132333435363738393031323a3a75706e703a726f6f74646
-     * 576696365
-     * length=153,type=2(UPnP),transaction id=3,status=0
-     *
-     * UPnP Protocol format is as follows.
-     * ______________________________________________________
-     * |  Version (1)  |          USN (Variable)            |
-     *
-     * version=0x10(UPnP1.0) data=usn:uuid:1122de4e-8574-59ab-9322-33345678
-     * 9044::urn:schemas-upnp-org:service:ContentDirectory:2,usn:uuid:6859d
-     * ede-8574-59ab-9332-123456789012::upnp:rootdevice
-     *
-     * P2P-SERV-DISC-RESP 58:17:0c:bc:dd:ca 21 1900010200045f6970
-     * 70c00c000c01094d795072696e746572c027
-     * length=25, type=1(Bonjour),transaction id=2,status=0
-     *
-     * Bonjour Protocol format is as follows.
-     * __________________________________________________________
-     * |DNS Name(Variable)|DNS Type(1)|Version(1)|RDATA(Variable)|
-     *
-     * DNS Name=_ipp._tcp.local.,DNS type=12(PTR), Version=1,
-     * RDATA=MyPrinter._ipp._tcp.local.
-     *
-     */
-    private static final String P2P_SERV_DISC_RESP_STR = "P2P-SERV-DISC-RESP";
-
-    private static final String HOST_AP_EVENT_PREFIX_STR = "AP";
-    /* AP-STA-CONNECTED 42:fc:89:a8:96:09 dev_addr=02:90:4c:a0:92:54 */
-    private static final String AP_STA_CONNECTED_STR = "AP-STA-CONNECTED";
-    /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 */
-    private static final String AP_STA_DISCONNECTED_STR = "AP-STA-DISCONNECTED";
-
-    /* Supplicant events reported to a state machine */
-    private static final int BASE = Protocol.BASE_WIFI_MONITOR;
-
-    /* Connection to supplicant established */
-    public static final int SUP_CONNECTION_EVENT                 = BASE + 1;
-    /* Connection to supplicant lost */
-    public static final int SUP_DISCONNECTION_EVENT              = BASE + 2;
-   /* Network connection completed */
-    public static final int NETWORK_CONNECTION_EVENT             = BASE + 3;
-    /* Network disconnection completed */
-    public static final int NETWORK_DISCONNECTION_EVENT          = BASE + 4;
-    /* Scan results are available */
-    public static final int SCAN_RESULTS_EVENT                   = BASE + 5;
-    /* Supplicate state changed */
-    public static final int SUPPLICANT_STATE_CHANGE_EVENT        = BASE + 6;
-    /* Password failure and EAP authentication failure */
-    public static final int AUTHENTICATION_FAILURE_EVENT         = BASE + 7;
-    /* WPS success detected */
-    public static final int WPS_SUCCESS_EVENT                    = BASE + 8;
-    /* WPS failure detected */
-    public static final int WPS_FAIL_EVENT                       = BASE + 9;
-     /* WPS overlap detected */
-    public static final int WPS_OVERLAP_EVENT                    = BASE + 10;
-     /* WPS timeout detected */
-    public static final int WPS_TIMEOUT_EVENT                    = BASE + 11;
-    /* Driver was hung */
-    public static final int DRIVER_HUNG_EVENT                    = BASE + 12;
-
-    /* P2P events */
-    public static final int P2P_DEVICE_FOUND_EVENT               = BASE + 21;
-    public static final int P2P_DEVICE_LOST_EVENT                = BASE + 22;
-    public static final int P2P_GO_NEGOTIATION_REQUEST_EVENT     = BASE + 23;
-    public static final int P2P_GO_NEGOTIATION_SUCCESS_EVENT     = BASE + 25;
-    public static final int P2P_GO_NEGOTIATION_FAILURE_EVENT     = BASE + 26;
-    public static final int P2P_GROUP_FORMATION_SUCCESS_EVENT    = BASE + 27;
-    public static final int P2P_GROUP_FORMATION_FAILURE_EVENT    = BASE + 28;
-    public static final int P2P_GROUP_STARTED_EVENT              = BASE + 29;
-    public static final int P2P_GROUP_REMOVED_EVENT              = BASE + 30;
-    public static final int P2P_INVITATION_RECEIVED_EVENT        = BASE + 31;
-    public static final int P2P_INVITATION_RESULT_EVENT          = BASE + 32;
-    public static final int P2P_PROV_DISC_PBC_REQ_EVENT          = BASE + 33;
-    public static final int P2P_PROV_DISC_PBC_RSP_EVENT          = BASE + 34;
-    public static final int P2P_PROV_DISC_ENTER_PIN_EVENT        = BASE + 35;
-    public static final int P2P_PROV_DISC_SHOW_PIN_EVENT         = BASE + 36;
-    public static final int P2P_FIND_STOPPED_EVENT               = BASE + 37;
-    public static final int P2P_SERV_DISC_RESP_EVENT             = BASE + 38;
-    public static final int P2P_PROV_DISC_FAILURE_EVENT          = BASE + 39;
-
-    /* hostap events */
-    public static final int AP_STA_DISCONNECTED_EVENT            = BASE + 41;
-    public static final int AP_STA_CONNECTED_EVENT               = BASE + 42;
-
-    /* Indicates assoc reject event */
-    public static final int ASSOCIATION_REJECTION_EVENT          = BASE + 43;
-    /**
-     * This indicates the supplicant connection for the monitor is closed
-     */
-    private static final String MONITOR_SOCKET_CLOSED_STR = "connection closed";
-
-    /**
-     * This indicates a read error on the monitor socket conenction
-     */
-    private static final String WPA_RECV_ERROR_STR = "recv error";
-
-    /**
-     * 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) {
-        if (DBG) Log.d(TAG, "Creating WifiMonitor");
-        mWifiNative = wifiNative;
-        mInterfaceName = wifiNative.mInterfaceName;
-        mWifiStateMachine = wifiStateMachine;
-        mMonitoring = false;
-
-        WifiMonitorSingleton.getMonitor().registerInterfaceMonitor(mInterfaceName, this);
-    }
-
-    public void startMonitoring() {
-        WifiMonitorSingleton.getMonitor().startMonitoring(mInterfaceName);
-    }
-
-    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() {
-        }
-
-        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;
-        }
-
-        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 (DBG && eventStr.indexOf(SCAN_RESULTS_STR) == -1) {
-                    Log.d(TAG, "Event [" + eventStr + "]");
-                }
-
-                String iface = "p2p0";
-                WifiMonitor m = null;
-                mStateMachine = null;
-
-                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 {
-                    // 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 (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;
-                        }
-                    }
-
-                    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;
-                    }
-                }
-            }
-        }
-
-        /* @return true if the event was supplicant disconnection */
-        private boolean dispatchEvent(String 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);
-                }
-                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;
-        }
-
-        private void handleDriverEvent(String state) {
-            if (state == null) {
-                return;
-            }
-            if (state.equals("HANGED")) {
-                mStateMachine.sendMessage(DRIVER_HUNG_EVENT);
-            }
-        }
-
-        /**
-         * Handle all supplicant events except STATE-CHANGE
-         * @param event the event type
-         * @param remainder the rest of the string following the
-         * event name and &quot;&#8195;&#8212;&#8195;&quot;
-         */
-        void handleEvent(int event, String remainder) {
-            switch (event) {
-                case DISCONNECTED:
-                    handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED, remainder);
-                    break;
-
-                case CONNECTED:
-                    handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED, remainder);
-                    break;
-
-                case SCAN_RESULTS:
-                    mStateMachine.sendMessage(SCAN_RESULTS_EVENT);
-                    break;
-
-                case UNKNOWN:
-                    break;
-            }
-        }
-
-        private void handleWpsFailEvent(String dataString) {
-            final Pattern p = Pattern.compile(WPS_FAIL_PATTERN);
-            Matcher match = p.matcher(dataString);
-            if (match.find()) {
-                String cfgErr = match.group(1);
-                String reason = match.group(2);
-
-                if (reason != null) {
-                    switch(Integer.parseInt(reason)) {
-                        case REASON_TKIP_ONLY_PROHIBITED:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_TKIP_ONLY_PROHIBITED, 0));
-                            return;
-                        case REASON_WEP_PROHIBITED:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_WEP_PROHIBITED, 0));
-                            return;
-                    }
-                }
-                if (cfgErr != null) {
-                    switch(Integer.parseInt(cfgErr)) {
-                        case CONFIG_AUTH_FAILURE:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_AUTH_FAILURE, 0));
-                            return;
-                        case CONFIG_MULTIPLE_PBC_DETECTED:
-                            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                                    WifiManager.WPS_OVERLAP_ERROR, 0));
-                            return;
-                    }
-                }
-            }
-            //For all other errors, return a generic internal error
-            mStateMachine.sendMessage(mStateMachine.obtainMessage(WPS_FAIL_EVENT,
-                    WifiManager.ERROR, 0));
-        }
-
-        /* <event> status=<err> and the special case of <event> reason=FREQ_CONFLICT */
-        private P2pStatus p2pError(String dataString) {
-            P2pStatus err = P2pStatus.UNKNOWN;
-            String[] tokens = dataString.split(" ");
-            if (tokens.length < 2) return err;
-            String[] nameValue = tokens[1].split("=");
-            if (nameValue.length != 2) return err;
-
-            /* Handle the special case of reason=FREQ+CONFLICT */
-            if (nameValue[1].equals("FREQ_CONFLICT")) {
-                return P2pStatus.NO_COMMON_CHANNEL;
-            }
-            try {
-                err = P2pStatus.valueOf(Integer.parseInt(nameValue[1]));
-            } catch (NumberFormatException e) {
-                e.printStackTrace();
-            }
-            return err;
-        }
-
-        /**
-         * Handle p2p events
-         */
-        private void handleP2pEvents(String dataString) {
-            if (dataString.startsWith(P2P_DEVICE_FOUND_STR)) {
-                mStateMachine.sendMessage(P2P_DEVICE_FOUND_EVENT, new WifiP2pDevice(dataString));
-            } else if (dataString.startsWith(P2P_DEVICE_LOST_STR)) {
-                mStateMachine.sendMessage(P2P_DEVICE_LOST_EVENT, new WifiP2pDevice(dataString));
-            } else if (dataString.startsWith(P2P_FIND_STOPPED_STR)) {
-                mStateMachine.sendMessage(P2P_FIND_STOPPED_EVENT);
-            } else if (dataString.startsWith(P2P_GO_NEG_REQUEST_STR)) {
-                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_REQUEST_EVENT,
-                        new WifiP2pConfig(dataString));
-            } else if (dataString.startsWith(P2P_GO_NEG_SUCCESS_STR)) {
-                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_SUCCESS_EVENT);
-            } else if (dataString.startsWith(P2P_GO_NEG_FAILURE_STR)) {
-                mStateMachine.sendMessage(P2P_GO_NEGOTIATION_FAILURE_EVENT, p2pError(dataString));
-            } else if (dataString.startsWith(P2P_GROUP_FORMATION_SUCCESS_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_FORMATION_SUCCESS_EVENT);
-            } else if (dataString.startsWith(P2P_GROUP_FORMATION_FAILURE_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_FORMATION_FAILURE_EVENT, p2pError(dataString));
-            } else if (dataString.startsWith(P2P_GROUP_STARTED_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_STARTED_EVENT, new WifiP2pGroup(dataString));
-            } else if (dataString.startsWith(P2P_GROUP_REMOVED_STR)) {
-                mStateMachine.sendMessage(P2P_GROUP_REMOVED_EVENT, new WifiP2pGroup(dataString));
-            } else if (dataString.startsWith(P2P_INVITATION_RECEIVED_STR)) {
-                mStateMachine.sendMessage(P2P_INVITATION_RECEIVED_EVENT,
-                        new WifiP2pGroup(dataString));
-            } else if (dataString.startsWith(P2P_INVITATION_RESULT_STR)) {
-                mStateMachine.sendMessage(P2P_INVITATION_RESULT_EVENT, p2pError(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_REQ_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_REQ_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_PBC_RSP_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_PBC_RSP_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_ENTER_PIN_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_ENTER_PIN_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_SHOW_PIN_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_SHOW_PIN_EVENT,
-                        new WifiP2pProvDiscEvent(dataString));
-            } else if (dataString.startsWith(P2P_PROV_DISC_FAILURE_STR)) {
-                mStateMachine.sendMessage(P2P_PROV_DISC_FAILURE_EVENT);
-            } else if (dataString.startsWith(P2P_SERV_DISC_RESP_STR)) {
-                List<WifiP2pServiceResponse> list = WifiP2pServiceResponse.newInstance(dataString);
-                if (list != null) {
-                    mStateMachine.sendMessage(P2P_SERV_DISC_RESP_EVENT, list);
-                } else {
-                    Log.e(TAG, "Null service resp " + dataString);
-                }
-            }
-        }
-
-        /**
-         * Handle hostap events
-         */
-        private void handleHostApEvents(String dataString) {
-            String[] tokens = dataString.split(" ");
-            /* AP-STA-CONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
-            if (tokens[0].equals(AP_STA_CONNECTED_STR)) {
-                mStateMachine.sendMessage(AP_STA_CONNECTED_EVENT, new WifiP2pDevice(dataString));
-            /* AP-STA-DISCONNECTED 42:fc:89:a8:96:09 p2p_dev_addr=02:90:4c:a0:92:54 */
-            } else if (tokens[0].equals(AP_STA_DISCONNECTED_STR)) {
-                mStateMachine.sendMessage(AP_STA_DISCONNECTED_EVENT, new WifiP2pDevice(dataString));
-            }
-        }
-
-        /**
-         * Handle the supplicant STATE-CHANGE event
-         * @param dataString New supplicant state string in the format:
-         * id=network-id state=new-state
-         */
-        private void handleSupplicantStateChange(String dataString) {
-            WifiSsid wifiSsid = null;
-            int index = dataString.lastIndexOf("SSID=");
-            if (index != -1) {
-                wifiSsid = WifiSsid.createFromAsciiEncoded(
-                        dataString.substring(index + 5));
-            }
-            String[] dataTokens = dataString.split(" ");
-
-            String BSSID = null;
-            int networkId = -1;
-            int newState  = -1;
-            for (String token : dataTokens) {
-                String[] nameValue = token.split("=");
-                if (nameValue.length != 2) {
-                    continue;
-                }
-
-                if (nameValue[0].equals("BSSID")) {
-                    BSSID = nameValue[1];
-                    continue;
-                }
-
-                int value;
-                try {
-                    value = Integer.parseInt(nameValue[1]);
-                } catch (NumberFormatException e) {
-                    continue;
-                }
-
-                if (nameValue[0].equals("id")) {
-                    networkId = value;
-                } else if (nameValue[0].equals("state")) {
-                    newState = value;
-                }
-            }
-
-            if (newState == -1) return;
-
-            SupplicantState newSupplicantState = SupplicantState.INVALID;
-            for (SupplicantState state : SupplicantState.values()) {
-                if (state.ordinal() == newState) {
-                    newSupplicantState = state;
-                    break;
-                }
-            }
-            if (newSupplicantState == SupplicantState.INVALID) {
-                Log.w(TAG, "Invalid supplicant state: " + newState);
-            }
-            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 (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);
-            }
-        }
-
-        /**
-         * 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)));
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
deleted file mode 100644
index c2f278a..0000000
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ /dev/null
@@ -1,970 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import android.net.wifi.p2p.WifiP2pConfig;
-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
- * sending requests to the supplicant daemon
- *
- * waitForEvent() is called on the monitor thread for events. All other methods
- * must be serialized from the framework.
- *
- * {@hide}
- */
-public class WifiNative {
-
-    private static final boolean DBG = false;
-    private final String mTAG;
-    private static final int DEFAULT_GROUP_OWNER_INTENT     = 6;
-
-    static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED     = 0;
-    static final int BLUETOOTH_COEXISTENCE_MODE_DISABLED    = 1;
-    static final int BLUETOOTH_COEXISTENCE_MODE_SENSE       = 2;
-
-    static final int SCAN_WITHOUT_CONNECTION_SETUP          = 1;
-    static final int SCAN_WITH_CONNECTION_SETUP             = 2;
-
-    // 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();
-
-    public native static boolean isDriverLoaded();
-
-    public native static boolean unloadDriver();
-
-    public native static boolean startSupplicant(boolean p2pSupported);
-
-    /* Sends a kill signal to supplicant. To be used when we have lost connection
-       or when the supplicant is hung */
-    public native static boolean killSupplicant(boolean p2pSupported);
-
-    private native boolean connectToSupplicantNative();
-
-    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 waitForEventNative();
-
-    private native boolean doBooleanCommandNative(String command);
-
-    private native int doIntCommandNative(String command);
-
-    private native String doStringCommandNative(String command);
-
-    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() {
-        // No synchronization necessary .. it is implemented in WifiMonitor
-        localLog(mInterfacePrefix + "connectToSupplicant");
-        return connectToSupplicantNative();
-    }
-
-    public void closeSupplicantConnection() {
-        localLog(mInterfacePrefix + "closeSupplicantConnection");
-        closeSupplicantConnectionNative();
-    }
-
-    public String waitForEvent() {
-        // No synchronization necessary .. it is implemented in WifiMonitor
-        return waitForEventNative();
-    }
-
-    private boolean doBooleanCommand(String command) {
-        if (DBG) Log.d(mTAG, "doBoolean: " + command);
-        synchronized (mLock) {
-            int cmdId = getNewCmdIdLocked();
-            localLog(cmdId + "->" + mInterfacePrefix + command);
-            boolean result = doBooleanCommandNative(mInterfacePrefix + command);
-            localLog(cmdId + "<-" + result);
-            if (DBG) Log.d(mTAG, "   returned " + result);
-            return result;
-        }
-    }
-
-    private int doIntCommand(String command) {
-        if (DBG) Log.d(mTAG, "doInt: " + command);
-        synchronized (mLock) {
-            int cmdId = getNewCmdIdLocked();
-            localLog(cmdId + "->" + mInterfacePrefix + command);
-            int result = doIntCommandNative(mInterfacePrefix + command);
-            localLog(cmdId + "<-" + result);
-            if (DBG) Log.d(mTAG, "   returned " + result);
-            return result;
-        }
-    }
-
-    private String doStringCommand(String command) {
-        if (DBG) Log.d(mTAG, "doString: " + command);
-        synchronized (mLock) {
-            int cmdId = getNewCmdIdLocked();
-            localLog(cmdId + "->" + mInterfacePrefix + command);
-            String result = doStringCommandNative(mInterfacePrefix + command);
-            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() {
-        String pong = doStringCommand("PING");
-        return (pong != null && pong.equals("PONG"));
-    }
-
-    public boolean scan(int type) {
-        if (type == SCAN_WITHOUT_CONNECTION_SETUP) {
-            return doBooleanCommand("SCAN TYPE=ONLY");
-        } else if (type == SCAN_WITH_CONNECTION_SETUP) {
-            return doBooleanCommand("SCAN");
-        } else {
-            throw new IllegalArgumentException("Invalid scan type");
-        }
-    }
-
-    /* Does a graceful shutdown of supplicant. Is a common stop function for both p2p and sta.
-     *
-     * Note that underneath we use a harsh-sounding "terminate" supplicant command
-     * for a graceful stop and a mild-sounding "stop" interface
-     * to kill the process
-     */
-    public boolean stopSupplicant() {
-        return doBooleanCommand("TERMINATE");
-    }
-
-    public String listNetworks() {
-        return doStringCommand("LIST_NETWORKS");
-    }
-
-    public int addNetwork() {
-        return doIntCommand("ADD_NETWORK");
-    }
-
-    public boolean setNetworkVariable(int netId, String name, String value) {
-        if (TextUtils.isEmpty(name) || TextUtils.isEmpty(value)) return false;
-        return doBooleanCommand("SET_NETWORK " + netId + " " + name + " " + value);
-    }
-
-    public String getNetworkVariable(int netId, String name) {
-        if (TextUtils.isEmpty(name)) return null;
-
-        // GET_NETWORK will likely flood the logs ...
-        return doStringCommandWithoutLogging("GET_NETWORK " + netId + " " + name);
-    }
-
-    public boolean removeNetwork(int netId) {
-        return doBooleanCommand("REMOVE_NETWORK " + netId);
-    }
-
-    public boolean enableNetwork(int netId, boolean disableOthers) {
-        if (disableOthers) {
-            return doBooleanCommand("SELECT_NETWORK " + netId);
-        } else {
-            return doBooleanCommand("ENABLE_NETWORK " + netId);
-        }
-    }
-
-    public boolean disableNetwork(int netId) {
-        return doBooleanCommand("DISABLE_NETWORK " + netId);
-    }
-
-    public boolean reconnect() {
-        return doBooleanCommand("RECONNECT");
-    }
-
-    public boolean reassociate() {
-        return doBooleanCommand("REASSOCIATE");
-    }
-
-    public boolean disconnect() {
-        return doBooleanCommand("DISCONNECT");
-    }
-
-    public String status() {
-        return doStringCommand("STATUS");
-    }
-
-    public String getMacAddress() {
-        //Macaddr = XX.XX.XX.XX.XX.XX
-        String ret = doStringCommand("DRIVER MACADDR");
-        if (!TextUtils.isEmpty(ret)) {
-            String[] tokens = ret.split(" = ");
-            if (tokens.length == 2) return tokens[1];
-        }
-        return null;
-    }
-
-    /**
-     * Format of results:
-     * =================
-     * id=1
-     * bssid=68:7f:74:d7:1b:6e
-     * freq=2412
-     * level=-43
-     * tsf=1344621975160944
-     * age=2623
-     * flags=[WPA2-PSK-CCMP][WPS][ESS]
-     * ssid=zubyb
-     * ====
-     *
-     * RANGE=ALL gets all scan results
-     * RANGE=ID- gets results from ID
-     * MASK=<N> see wpa_supplicant/src/common/wpa_ctrl.h for details
-     */
-    public String scanResults(int sid) {
-        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() {
-        return doBooleanCommand("DRIVER START");
-    }
-
-    public boolean stopDriver() {
-        return doBooleanCommand("DRIVER STOP");
-    }
-
-
-    /**
-     * Start filtering out Multicast V4 packets
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     *
-     * Multicast filtering rules work as follows:
-     *
-     * The driver can filter multicast (v4 and/or v6) and broadcast packets when in
-     * a power optimized mode (typically when screen goes off).
-     *
-     * In order to prevent the driver from filtering the multicast/broadcast packets, we have to
-     * add a DRIVER RXFILTER-ADD rule followed by DRIVER RXFILTER-START to make the rule effective
-     *
-     * DRIVER RXFILTER-ADD Num
-     *   where Num = 0 - Unicast, 1 - Broadcast, 2 - Mutil4 or 3 - Multi6
-     *
-     * and DRIVER RXFILTER-START
-     * In order to stop the usage of these rules, we do
-     *
-     * DRIVER RXFILTER-STOP
-     * DRIVER RXFILTER-REMOVE Num
-     *   where Num is as described for RXFILTER-ADD
-     *
-     * The  SETSUSPENDOPT driver command overrides the filtering rules
-     */
-    public boolean startFilteringMulticastV4Packets() {
-        return doBooleanCommand("DRIVER RXFILTER-STOP")
-            && doBooleanCommand("DRIVER RXFILTER-REMOVE 2")
-            && doBooleanCommand("DRIVER RXFILTER-START");
-    }
-
-    /**
-     * Stop filtering out Multicast V4 packets.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     */
-    public boolean stopFilteringMulticastV4Packets() {
-        return doBooleanCommand("DRIVER RXFILTER-STOP")
-            && doBooleanCommand("DRIVER RXFILTER-ADD 2")
-            && doBooleanCommand("DRIVER RXFILTER-START");
-    }
-
-    /**
-     * Start filtering out Multicast V6 packets
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     */
-    public boolean startFilteringMulticastV6Packets() {
-        return doBooleanCommand("DRIVER RXFILTER-STOP")
-            && doBooleanCommand("DRIVER RXFILTER-REMOVE 3")
-            && doBooleanCommand("DRIVER RXFILTER-START");
-    }
-
-    /**
-     * Stop filtering out Multicast V6 packets.
-     * @return {@code true} if the operation succeeded, {@code false} otherwise
-     */
-    public boolean stopFilteringMulticastV6Packets() {
-        return doBooleanCommand("DRIVER RXFILTER-STOP")
-            && doBooleanCommand("DRIVER RXFILTER-ADD 3")
-            && doBooleanCommand("DRIVER RXFILTER-START");
-    }
-
-    public int getBand() {
-       String ret = doStringCommand("DRIVER GETBAND");
-        if (!TextUtils.isEmpty(ret)) {
-            //reply is "BAND X" where X is the band
-            String[] tokens = ret.split(" ");
-            try {
-                if (tokens.length == 2) return Integer.parseInt(tokens[1]);
-            } catch (NumberFormatException e) {
-                return -1;
-            }
-        }
-        return -1;
-    }
-
-    public boolean setBand(int band) {
-        return doBooleanCommand("DRIVER SETBAND " + band);
-    }
-
-   /**
-     * Sets the bluetooth coexistence mode.
-     *
-     * @param mode One of {@link #BLUETOOTH_COEXISTENCE_MODE_DISABLED},
-     *            {@link #BLUETOOTH_COEXISTENCE_MODE_ENABLED}, or
-     *            {@link #BLUETOOTH_COEXISTENCE_MODE_SENSE}.
-     * @return Whether the mode was successfully set.
-     */
-    public boolean setBluetoothCoexistenceMode(int mode) {
-        return doBooleanCommand("DRIVER BTCOEXMODE " + mode);
-    }
-
-    /**
-     * Enable or disable Bluetooth coexistence scan mode. When this mode is on,
-     * some of the low-level scan parameters used by the driver are changed to
-     * reduce interference with A2DP streaming.
-     *
-     * @param isSet whether to enable or disable this mode
-     * @return {@code true} if the command succeeded, {@code false} otherwise.
-     */
-    public boolean setBluetoothCoexistenceScanMode(boolean setCoexScanMode) {
-        if (setCoexScanMode) {
-            return doBooleanCommand("DRIVER BTCOEXSCAN-START");
-        } else {
-            return doBooleanCommand("DRIVER BTCOEXSCAN-STOP");
-        }
-    }
-
-    public boolean saveConfig() {
-        return doBooleanCommand("SAVE_CONFIG");
-    }
-
-    public boolean addToBlacklist(String bssid) {
-        if (TextUtils.isEmpty(bssid)) return false;
-        return doBooleanCommand("BLACKLIST " + bssid);
-    }
-
-    public boolean clearBlacklist() {
-        return doBooleanCommand("BLACKLIST clear");
-    }
-
-    public boolean setSuspendOptimizations(boolean enabled) {
-        if (mSuspendOptEnabled == enabled) return true;
-        mSuspendOptEnabled = enabled;
-        if (enabled) {
-            return doBooleanCommand("DRIVER SETSUSPENDMODE 1");
-        } else {
-            return doBooleanCommand("DRIVER SETSUSPENDMODE 0");
-        }
-    }
-
-    public boolean setCountryCode(String countryCode) {
-        return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
-    }
-
-    public void enableBackgroundScan(boolean enable) {
-        if (enable) {
-            doBooleanCommand("SET pno 1");
-        } else {
-            doBooleanCommand("SET pno 0");
-        }
-    }
-
-    public void setScanInterval(int scanInterval) {
-        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
-     * NOISE=9999
-     * FREQUENCY=0
-     */
-    public String signalPoll() {
-        return doStringCommandWithoutLogging("SIGNAL_POLL");
-    }
-
-    /** Example outout:
-     * TXGOOD=396
-     * TXBAD=1
-     */
-    public String pktcntPoll() {
-        return doStringCommand("PKTCNT_POLL");
-    }
-
-    public void bssFlush() {
-        doBooleanCommand("BSS_FLUSH 0");
-    }
-
-    public boolean startWpsPbc(String bssid) {
-        if (TextUtils.isEmpty(bssid)) {
-            return doBooleanCommand("WPS_PBC");
-        } else {
-            return doBooleanCommand("WPS_PBC " + bssid);
-        }
-    }
-
-    public boolean startWpsPbc(String iface, String bssid) {
-        synchronized (mLock) {
-            if (TextUtils.isEmpty(bssid)) {
-                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC");
-            } else {
-                return doBooleanCommandNative("IFNAME=" + iface + " WPS_PBC " + bssid);
-            }
-        }
-    }
-
-    public boolean startWpsPinKeypad(String pin) {
-        if (TextUtils.isEmpty(pin)) return false;
-        return doBooleanCommand("WPS_PIN any " + pin);
-    }
-
-    public boolean startWpsPinKeypad(String iface, String pin) {
-        if (TextUtils.isEmpty(pin)) return false;
-        synchronized (mLock) {
-            return doBooleanCommandNative("IFNAME=" + iface + " WPS_PIN any " + pin);
-        }
-    }
-
-
-    public String startWpsPinDisplay(String bssid) {
-        if (TextUtils.isEmpty(bssid)) {
-            return doStringCommand("WPS_PIN any");
-        } else {
-            return doStringCommand("WPS_PIN " + bssid);
-        }
-    }
-
-    public String startWpsPinDisplay(String iface, String bssid) {
-        synchronized (mLock) {
-            if (TextUtils.isEmpty(bssid)) {
-                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN any");
-            } else {
-                return doStringCommandNative("IFNAME=" + iface + " WPS_PIN " + bssid);
-            }
-        }
-    }
-
-    /* Configures an access point connection */
-    public boolean startWpsRegistrar(String bssid, String pin) {
-        if (TextUtils.isEmpty(bssid) || TextUtils.isEmpty(pin)) return false;
-        return doBooleanCommand("WPS_REG " + bssid + " " + pin);
-    }
-
-    public boolean cancelWps() {
-        return doBooleanCommand("WPS_CANCEL");
-    }
-
-    public boolean setPersistentReconnect(boolean enabled) {
-        int value = (enabled == true) ? 1 : 0;
-        return doBooleanCommand("SET persistent_reconnect " + value);
-    }
-
-    public boolean setDeviceName(String name) {
-        return doBooleanCommand("SET device_name " + name);
-    }
-
-    public boolean setDeviceType(String type) {
-        return doBooleanCommand("SET device_type " + type);
-    }
-
-    public boolean setConfigMethods(String cfg) {
-        return doBooleanCommand("SET config_methods " + cfg);
-    }
-
-    public boolean setManufacturer(String value) {
-        return doBooleanCommand("SET manufacturer " + value);
-    }
-
-    public boolean setModelName(String value) {
-        return doBooleanCommand("SET model_name " + value);
-    }
-
-    public boolean setModelNumber(String value) {
-        return doBooleanCommand("SET model_number " + value);
-    }
-
-    public boolean setSerialNumber(String value) {
-        return doBooleanCommand("SET serial_number " + value);
-    }
-
-    public boolean setP2pSsidPostfix(String postfix) {
-        return doBooleanCommand("SET p2p_ssid_postfix " + postfix);
-    }
-
-    public boolean setP2pGroupIdle(String iface, int time) {
-        synchronized (mLock) {
-            return doBooleanCommandNative("IFNAME=" + iface + " SET p2p_group_idle " + time);
-        }
-    }
-
-    public void setPowerSave(boolean enabled) {
-        if (enabled) {
-            doBooleanCommand("SET ps 1");
-        } else {
-            doBooleanCommand("SET ps 0");
-        }
-    }
-
-    public boolean setP2pPowerSave(String iface, boolean enabled) {
-        synchronized (mLock) {
-            if (enabled) {
-                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 1");
-            } else {
-                return doBooleanCommandNative("IFNAME=" + iface + " P2P_SET ps 0");
-            }
-        }
-    }
-
-    public boolean setWfdEnable(boolean enable) {
-        return doBooleanCommand("SET wifi_display " + (enable ? "1" : "0"));
-    }
-
-    public boolean setWfdDeviceInfo(String hex) {
-        return doBooleanCommand("WFD_SUBELEM_SET 0 " + hex);
-    }
-
-    /**
-     * "sta" prioritizes STA connection over P2P and "p2p" prioritizes
-     * P2P connection over STA
-     */
-    public boolean setConcurrencyPriority(String s) {
-        return doBooleanCommand("P2P_SET conc_pref " + s);
-    }
-
-    public boolean p2pFind() {
-        return doBooleanCommand("P2P_FIND");
-    }
-
-    public boolean p2pFind(int timeout) {
-        if (timeout <= 0) {
-            return p2pFind();
-        }
-        return doBooleanCommand("P2P_FIND " + timeout);
-    }
-
-    public boolean p2pStopFind() {
-       return doBooleanCommand("P2P_STOP_FIND");
-    }
-
-    public boolean p2pListen() {
-        return doBooleanCommand("P2P_LISTEN");
-    }
-
-    public boolean p2pListen(int timeout) {
-        if (timeout <= 0) {
-            return p2pListen();
-        }
-        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");
-    }
-
-    /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
-        [persistent] [join|auth] [go_intent=<0..15>] [freq=<in MHz>] */
-    public String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) {
-        if (config == null) return null;
-        List<String> args = new ArrayList<String>();
-        WpsInfo wps = config.wps;
-        args.add(config.deviceAddress);
-
-        switch (wps.setup) {
-            case WpsInfo.PBC:
-                args.add("pbc");
-                break;
-            case WpsInfo.DISPLAY:
-                if (TextUtils.isEmpty(wps.pin)) {
-                    args.add("pin");
-                } else {
-                    args.add(wps.pin);
-                }
-                args.add("display");
-                break;
-            case WpsInfo.KEYPAD:
-                args.add(wps.pin);
-                args.add("keypad");
-                break;
-            case WpsInfo.LABEL:
-                args.add(wps.pin);
-                args.add("label");
-            default:
-                break;
-        }
-
-        if (config.netId == WifiP2pGroup.PERSISTENT_NET_ID) {
-            args.add("persistent");
-        }
-
-        if (joinExistingGroup) {
-            args.add("join");
-        } else {
-            //TODO: This can be adapted based on device plugged in state and
-            //device battery state
-            int groupOwnerIntent = config.groupOwnerIntent;
-            if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
-                groupOwnerIntent = DEFAULT_GROUP_OWNER_INTENT;
-            }
-            args.add("go_intent=" + groupOwnerIntent);
-        }
-
-        String command = "P2P_CONNECT ";
-        for (String s : args) command += s + " ";
-
-        return doStringCommand(command);
-    }
-
-    public boolean p2pCancelConnect() {
-        return doBooleanCommand("P2P_CANCEL");
-    }
-
-    public boolean p2pProvisionDiscovery(WifiP2pConfig config) {
-        if (config == null) return false;
-
-        switch (config.wps.setup) {
-            case WpsInfo.PBC:
-                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " pbc");
-            case WpsInfo.DISPLAY:
-                //We are doing display, so provision discovery is keypad
-                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " keypad");
-            case WpsInfo.KEYPAD:
-                //We are doing keypad, so provision discovery is display
-                return doBooleanCommand("P2P_PROV_DISC " + config.deviceAddress + " display");
-            default:
-                break;
-        }
-        return false;
-    }
-
-    public boolean p2pGroupAdd(boolean persistent) {
-        if (persistent) {
-            return doBooleanCommand("P2P_GROUP_ADD persistent");
-        }
-        return doBooleanCommand("P2P_GROUP_ADD");
-    }
-
-    public boolean p2pGroupAdd(int netId) {
-        return doBooleanCommand("P2P_GROUP_ADD persistent=" + netId);
-    }
-
-    public boolean p2pGroupRemove(String iface) {
-        if (TextUtils.isEmpty(iface)) return false;
-        synchronized (mLock) {
-            return doBooleanCommandNative("IFNAME=" + iface + " P2P_GROUP_REMOVE " + iface);
-        }
-    }
-
-    public boolean p2pReject(String deviceAddress) {
-        return doBooleanCommand("P2P_REJECT " + deviceAddress);
-    }
-
-    /* Invite a peer to a group */
-    public boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
-        if (TextUtils.isEmpty(deviceAddress)) return false;
-
-        if (group == null) {
-            return doBooleanCommand("P2P_INVITE peer=" + deviceAddress);
-        } else {
-            return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
-                    + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
-        }
-    }
-
-    /* Reinvoke a persistent connection */
-    public boolean p2pReinvoke(int netId, String deviceAddress) {
-        if (TextUtils.isEmpty(deviceAddress) || netId < 0) return false;
-
-        return doBooleanCommand("P2P_INVITE persistent=" + netId + " peer=" + deviceAddress);
-    }
-
-    public String p2pGetSsid(String deviceAddress) {
-        return p2pGetParam(deviceAddress, "oper_ssid");
-    }
-
-    public String p2pGetDeviceAddress() {
-        String status = status();
-        if (status == null) return "";
-
-        String[] tokens = status.split("\n");
-        for (String token : tokens) {
-            if (token.startsWith("p2p_device_address=")) {
-                String[] nameValue = token.split("=");
-                if (nameValue.length != 2) break;
-                return nameValue[1];
-            }
-        }
-        return "";
-    }
-
-    public int getGroupCapability(String deviceAddress) {
-        int gc = 0;
-        if (TextUtils.isEmpty(deviceAddress)) return gc;
-        String peerInfo = p2pPeer(deviceAddress);
-        if (TextUtils.isEmpty(peerInfo)) return gc;
-
-        String[] tokens = peerInfo.split("\n");
-        for (String token : tokens) {
-            if (token.startsWith("group_capab=")) {
-                String[] nameValue = token.split("=");
-                if (nameValue.length != 2) break;
-                try {
-                    return Integer.decode(nameValue[1]);
-                } catch(NumberFormatException e) {
-                    return gc;
-                }
-            }
-        }
-        return gc;
-    }
-
-    public String p2pPeer(String deviceAddress) {
-        return doStringCommand("P2P_PEER " + deviceAddress);
-    }
-
-    private String p2pGetParam(String deviceAddress, String key) {
-        if (deviceAddress == null) return null;
-
-        String peerInfo = p2pPeer(deviceAddress);
-        if (peerInfo == null) return null;
-        String[] tokens= peerInfo.split("\n");
-
-        key += "=";
-        for (String token : tokens) {
-            if (token.startsWith(key)) {
-                String[] nameValue = token.split("=");
-                if (nameValue.length != 2) break;
-                return nameValue[1];
-            }
-        }
-        return null;
-    }
-
-    public boolean p2pServiceAdd(WifiP2pServiceInfo servInfo) {
-        /*
-         * P2P_SERVICE_ADD bonjour <query hexdump> <RDATA hexdump>
-         * P2P_SERVICE_ADD upnp <version hex> <service>
-         *
-         * e.g)
-         * [Bonjour]
-         * # IP Printing over TCP (PTR) (RDATA=MyPrinter._ipp._tcp.local.)
-         * P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027
-         * # IP Printing over TCP (TXT) (RDATA=txtvers=1,pdl=application/postscript)
-         * P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001
-         *  09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074
-         *
-         * [UPnP]
-         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012
-         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice
-         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp
-         * -org:device:InternetGatewayDevice:1
-         * P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9322-123456789012::urn:schemas-upnp
-         * -org:service:ContentDirectory:2
-         */
-        for (String s : servInfo.getSupplicantQueryList()) {
-            String command = "P2P_SERVICE_ADD";
-            command += (" " + s);
-            if (!doBooleanCommand(command)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public boolean p2pServiceDel(WifiP2pServiceInfo servInfo) {
-        /*
-         * P2P_SERVICE_DEL bonjour <query hexdump>
-         * P2P_SERVICE_DEL upnp <version hex> <service>
-         */
-        for (String s : servInfo.getSupplicantQueryList()) {
-            String command = "P2P_SERVICE_DEL ";
-
-            String[] data = s.split(" ");
-            if (data.length < 2) {
-                return false;
-            }
-            if ("upnp".equals(data[0])) {
-                command += s;
-            } else if ("bonjour".equals(data[0])) {
-                command += data[0];
-                command += (" " + data[1]);
-            } else {
-                return false;
-            }
-            if (!doBooleanCommand(command)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public boolean p2pServiceFlush() {
-        return doBooleanCommand("P2P_SERVICE_FLUSH");
-    }
-
-    public String p2pServDiscReq(String addr, String query) {
-        String command = "P2P_SERV_DISC_REQ";
-        command += (" " + addr);
-        command += (" " + query);
-
-        return doStringCommand(command);
-    }
-
-    public boolean p2pServDiscCancelReq(String id) {
-        return doBooleanCommand("P2P_SERV_DISC_CANCEL_REQ " + id);
-    }
-
-    /* Set the current mode of miracast operation.
-     *  0 = disabled
-     *  1 = operating as source
-     *  2 = operating as sink
-     */
-    public void setMiracastMode(int mode) {
-        // Note: optional feature on the driver. It is ok for this to fail.
-        doBooleanCommand("DRIVER MIRACAST " + mode);
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiSsid.java b/wifi/java/android/net/wifi/WifiSsid.java
index a35a34b..f8ba95d 100644
--- a/wifi/java/android/net/wifi/WifiSsid.java
+++ b/wifi/java/android/net/wifi/WifiSsid.java
@@ -16,9 +16,8 @@
 
 package android.net.wifi;
 
-import android.os.Parcelable;
 import android.os.Parcel;
-import android.util.Log;
+import android.os.Parcelable;
 
 import java.io.ByteArrayOutputStream;
 import java.nio.ByteBuffer;
@@ -42,7 +41,7 @@
 public class WifiSsid implements Parcelable {
     private static final String TAG = "WifiSsid";
 
-    public ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
+    public final ByteArrayOutputStream octets = new ByteArrayOutputStream(32);
 
     private static final int HEX_RADIX = 16;
     public static final String NONE = "<unknown ssid>";
@@ -58,7 +57,6 @@
 
     public static WifiSsid createFromHex(String hexStr) {
         WifiSsid a = new WifiSsid();
-        int length = 0;
         if (hexStr == null) return a;
 
         if (hexStr.startsWith("0x") || hexStr.startsWith("0X")) {
@@ -191,8 +189,13 @@
     }
 
     /** @hide */
+    public boolean isHidden() {
+        return isArrayAllZeroes(octets.toByteArray());
+    }
+
+    /** @hide */
     public byte[] getOctets() {
-        return  octets.toByteArray();
+        return octets.toByteArray();
     }
 
     /** @hide */
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
deleted file mode 100644
index 0fffd373..0000000
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ /dev/null
@@ -1,4454 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.wifi;
-
-import static android.net.wifi.WifiManager.WIFI_STATE_DISABLED;
-import static android.net.wifi.WifiManager.WIFI_STATE_DISABLING;
-import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_STATE_ENABLING;
-import static android.net.wifi.WifiManager.WIFI_STATE_UNKNOWN;
-
-/**
- * TODO:
- * Deprecate WIFI_STATE_UNKNOWN
- */
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLING;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
-import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.backup.IBackupManager;
-import android.bluetooth.BluetoothAdapter;
-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.net.ConnectivityManager;
-import android.net.DhcpResults;
-import android.net.DhcpStateMachine;
-import android.net.InterfaceConfiguration;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-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.Bundle;
-import android.os.IBinder;
-import android.os.INetworkManagementService;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.PowerManager;
-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;
-
-import com.android.internal.R;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-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;
-import java.util.regex.Pattern;
-
-/**
- * Track the state of Wifi connectivity. All event handling is done here,
- * and all changes in connectivity state are initiated here.
- *
- * Wi-Fi now supports three modes of operation: Client, SoftAp and p2p
- * In the current implementation, we support concurrent wifi p2p and wifi operation.
- * The WifiStateMachine handles SoftAp and Client operations while WifiP2pService
- * handles p2p operation.
- *
- * @hide
- */
-public class WifiStateMachine extends StateMachine {
-
-    private static final String NETWORKTYPE = "WIFI";
-    private static final boolean DBG = false;
-
-    private WifiMonitor mWifiMonitor;
-    private WifiNative mWifiNative;
-    private WifiConfigStore mWifiConfigStore;
-    private INetworkManagementService mNwService;
-    private ConnectivityManager mCm;
-
-    private final boolean mP2pSupported;
-    private final AtomicBoolean mP2pConnected = new AtomicBoolean(false);
-    private boolean mTemporarilyDisconnectWifi = false;
-    private final String mPrimaryDeviceType;
-
-    /* Scan results handling */
-    private List<ScanResult> mScanResults = new ArrayList<ScanResult>();
-    private static final Pattern scanResultPattern = Pattern.compile("\t+");
-    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;
-
-    private String mInterfaceName;
-    /* Tethering interface could be separate from wlan interface */
-    private String mTetherInterfaceName;
-
-    private int mLastSignalLevel = -1;
-    private String mLastBssid;
-    private int mLastNetworkId;
-    private boolean mEnableRssiPolling = false;
-    private boolean mEnableBackgroundScan = false;
-    private int mRssiPollToken = 0;
-    private int mReconnectCount = 0;
-    /* 3 operational states for STA operation: CONNECT_MODE, SCAN_ONLY_MODE, SCAN_ONLY_WIFI_OFF_MODE
-    * In CONNECT_MODE, the STA can scan and connect to an access point
-    * In SCAN_ONLY_MODE, the STA can only scan for access points
-    * In SCAN_ONLY_WIFI_OFF_MODE, the STA can only scan for access points with wifi toggle being off
-    */
-    private int mOperationalMode = CONNECT_MODE;
-    private boolean mScanResultIsPending = false;
-    private WorkSource mScanWorkSource = null;
-    private static final int UNKNOWN_SCAN_SOURCE = -1;
-    /* Tracks if state machine has received any screen state change broadcast yet.
-     * We can miss one of these at boot.
-     */
-    private AtomicBoolean mScreenBroadcastReceived = new AtomicBoolean(false);
-
-    private boolean mBluetoothConnectionActive = false;
-
-    private PowerManager.WakeLock mSuspendWakeLock;
-
-    /**
-     * Interval in milliseconds between polling for RSSI
-     * and linkspeed information
-     */
-    private static final int POLL_RSSI_INTERVAL_MSECS = 3000;
-
-    /**
-     * Delay between supplicant restarts upon failure to establish connection
-     */
-    private static final int SUPPLICANT_RESTART_INTERVAL_MSECS = 5000;
-
-    /**
-     * Number of times we attempt to restart supplicant
-     */
-    private static final int SUPPLICANT_RESTART_TRIES = 5;
-
-    private int mSupplicantRestartCount = 0;
-    /* Tracks sequence number on stop failure message */
-    private int mSupplicantStopFailureToken = 0;
-
-    /**
-     * Tether state change notification time out
-     */
-    private static final int TETHER_NOTIFICATION_TIME_OUT_MSECS = 5000;
-
-    /* Tracks sequence number on a tether notification time out */
-    private int mTetherToken = 0;
-
-    /**
-     * Driver start time out.
-     */
-    private static final int DRIVER_START_TIME_OUT_MSECS = 10000;
-
-    /* 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;
-
-    // Wakelock held during wifi start/stop and driver load/unload
-    private PowerManager.WakeLock mWakeLock;
-
-    private Context mContext;
-
-    private final Object mDhcpResultsLock = new Object();
-    private DhcpResults mDhcpResults;
-    private WifiInfo mWifiInfo;
-    private NetworkInfo mNetworkInfo;
-    private SupplicantStateTracker mSupplicantStateTracker;
-    private DhcpStateMachine mDhcpStateMachine;
-    private boolean mDhcpActive = false;
-
-    // Delay in switching to null country code (non-null has no delay)
-    private final int COUNTRY_CODE_DELAY_MS = 15000;
-    private final AtomicInteger mCountryCodeSequence = new AtomicInteger();
-
-    private class InterfaceObserver extends BaseNetworkObserver {
-        private WifiStateMachine mWifiStateMachine;
-
-        InterfaceObserver(WifiStateMachine wifiStateMachine) {
-            super();
-            mWifiStateMachine = wifiStateMachine;
-        }
-
-        private void maybeLog(String operation, String iface, LinkAddress address) {
-            if (DBG) {
-                log(operation + ": " + address + " on " + iface +
-                    " flags " + address.getFlags() + " scope " + address.getScope());
-            }
-        }
-
-        @Override
-        public void addressUpdated(String iface, LinkAddress address) {
-            if (mWifiStateMachine.mInterfaceName.equals(iface)) {
-                maybeLog("addressUpdated", iface, address);
-                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_UPDATED, address);
-            }
-        }
-
-        @Override
-        public void addressRemoved(String iface, LinkAddress address) {
-            if (mWifiStateMachine.mInterfaceName.equals(iface)) {
-                maybeLog("addressRemoved", iface, address);
-                mWifiStateMachine.sendMessage(CMD_IP_ADDRESS_REMOVED, 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);
-
-    /* Tracks if we are filtering Multicast v4 packets. Default is to filter. */
-    private AtomicBoolean mFilteringMulticastV4Packets = new AtomicBoolean(true);
-
-    // Channel for sending replies.
-    private AsyncChannel mReplyChannel = new AsyncChannel();
-
-    private WifiP2pManager mWifiP2pManager;
-    //Used to initiate a connection with WifiP2pService
-    private AsyncChannel mWifiP2pChannel;
-    private AsyncChannel mWifiApConfigChannel;
-
-    /* The base for wifi message types */
-    static final int BASE = Protocol.BASE_WIFI;
-    /* Start the supplicant */
-    static final int CMD_START_SUPPLICANT                 = BASE + 11;
-    /* Stop the supplicant */
-    static final int CMD_STOP_SUPPLICANT                  = BASE + 12;
-    /* Start the driver */
-    static final int CMD_START_DRIVER                     = BASE + 13;
-    /* Stop the driver */
-    static final int CMD_STOP_DRIVER                      = BASE + 14;
-    /* Indicates Static IP succeeded */
-    static final int CMD_STATIC_IP_SUCCESS                = BASE + 15;
-    /* Indicates Static IP failed */
-    static final int CMD_STATIC_IP_FAILURE                = BASE + 16;
-    /* Indicates supplicant stop failed */
-    static final int CMD_STOP_SUPPLICANT_FAILED           = BASE + 17;
-    /* Delayed stop to avoid shutting down driver too quick*/
-    static final int CMD_DELAYED_STOP_DRIVER              = BASE + 18;
-    /* A delayed message sent to start driver when it fail to come up */
-    static final int CMD_DRIVER_START_TIMED_OUT           = BASE + 19;
-    /* Ready to switch to network as default */
-    static final int CMD_CAPTIVE_CHECK_COMPLETE           = BASE + 20;
-
-    /* Start the soft access point */
-    static final int CMD_START_AP                         = BASE + 21;
-    /* Indicates soft ap start succeeded */
-    static final int CMD_START_AP_SUCCESS                 = BASE + 22;
-    /* Indicates soft ap start failed */
-    static final int CMD_START_AP_FAILURE                 = BASE + 23;
-    /* Stop the soft access point */
-    static final int CMD_STOP_AP                          = BASE + 24;
-    /* Set the soft access point configuration */
-    static final int CMD_SET_AP_CONFIG                    = BASE + 25;
-    /* Soft access point configuration set completed */
-    static final int CMD_SET_AP_CONFIG_COMPLETED          = BASE + 26;
-    /* Request the soft access point configuration */
-    static final int CMD_REQUEST_AP_CONFIG                = BASE + 27;
-    /* Response to access point configuration request */
-    static final int CMD_RESPONSE_AP_CONFIG               = BASE + 28;
-    /* Invoked when getting a tether state change notification */
-    static final int CMD_TETHER_STATE_CHANGE              = BASE + 29;
-    /* A delayed message sent to indicate tether state change failed to arrive */
-    static final int CMD_TETHER_NOTIFICATION_TIMED_OUT    = BASE + 30;
-
-    static final int CMD_BLUETOOTH_ADAPTER_STATE_CHANGE   = BASE + 31;
-
-    /* Supplicant commands */
-    /* Is supplicant alive ? */
-    static final int CMD_PING_SUPPLICANT                  = BASE + 51;
-    /* Add/update a network configuration */
-    static final int CMD_ADD_OR_UPDATE_NETWORK            = BASE + 52;
-    /* Delete a network */
-    static final int CMD_REMOVE_NETWORK                   = BASE + 53;
-    /* Enable a network. The device will attempt a connection to the given network. */
-    static final int CMD_ENABLE_NETWORK                   = BASE + 54;
-    /* Enable all networks */
-    static final int CMD_ENABLE_ALL_NETWORKS              = BASE + 55;
-    /* Blacklist network. De-prioritizes the given BSSID for connection. */
-    static final int CMD_BLACKLIST_NETWORK                = BASE + 56;
-    /* Clear the blacklist network list */
-    static final int CMD_CLEAR_BLACKLIST                  = BASE + 57;
-    /* Save configuration */
-    static final int CMD_SAVE_CONFIG                      = BASE + 58;
-    /* Get configured networks*/
-    static final int CMD_GET_CONFIGURED_NETWORKS          = BASE + 59;
-
-    /* Supplicant commands after driver start*/
-    /* Initiate a scan */
-    static final int CMD_START_SCAN                       = BASE + 71;
-    /* Set operational mode. CONNECT, SCAN ONLY, SCAN_ONLY with Wi-Fi off mode */
-    static final int CMD_SET_OPERATIONAL_MODE             = BASE + 72;
-    /* Disconnect from a network */
-    static final int CMD_DISCONNECT                       = BASE + 73;
-    /* Reconnect to a network */
-    static final int CMD_RECONNECT                        = BASE + 74;
-    /* Reassociate to a network */
-    static final int CMD_REASSOCIATE                      = BASE + 75;
-    /* Controls suspend mode optimizations
-     *
-     * When high perf mode is enabled, suspend mode optimizations are disabled
-     *
-     * When high perf mode is disabled, suspend mode optimizations are enabled
-     *
-     * Suspend mode optimizations include:
-     * - packet filtering
-     * - turn off roaming
-     * - DTIM wake up settings
-     */
-    static final int CMD_SET_HIGH_PERF_MODE               = BASE + 77;
-    /* Set the country code */
-    static final int CMD_SET_COUNTRY_CODE                 = BASE + 80;
-    /* Enables RSSI poll */
-    static final int CMD_ENABLE_RSSI_POLL                 = BASE + 82;
-    /* RSSI poll */
-    static final int CMD_RSSI_POLL                        = BASE + 83;
-    /* Set up packet filtering */
-    static final int CMD_START_PACKET_FILTERING           = BASE + 84;
-    /* Clear packet filter */
-    static final int CMD_STOP_PACKET_FILTERING            = BASE + 85;
-    /* Enable suspend mode optimizations in the driver */
-    static final int CMD_SET_SUSPEND_OPT_ENABLED          = BASE + 86;
-    /* When there are no saved networks, we do a periodic scan to notify user of
-     * an open network */
-    static final int CMD_NO_NETWORKS_PERIODIC_SCAN        = BASE + 88;
-
-    /* arg1 values to CMD_STOP_PACKET_FILTERING and CMD_START_PACKET_FILTERING */
-    static final int MULTICAST_V6  = 1;
-    static final int MULTICAST_V4  = 0;
-
-   /* Set the frequency band */
-    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 */
-    static final int CMD_RESET_SUPPLICANT_STATE           = BASE + 111;
-
-    /* P2p commands */
-    /* We are ok with no response here since we wont do much with it anyway */
-    public static final int CMD_ENABLE_P2P                = BASE + 131;
-    /* In order to shut down supplicant cleanly, we wait till p2p has
-     * been disabled */
-    public static final int CMD_DISABLE_P2P_REQ           = BASE + 132;
-    public static final int CMD_DISABLE_P2P_RSP           = BASE + 133;
-
-    public static final int CMD_BOOT_COMPLETED            = BASE + 134;
-
-    /* change the batch scan settings.
-     * arg1 = responsible UID
-     * arg2 = csph (channel scans per hour)
-     * obj = bundle with the new settings and the optional worksource
-     */
-    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;
-    /* Reload all networks and reconnect */
-    static final int CMD_RELOAD_TLS_AND_RECONNECT         = BASE + 142;
-
-    /* Wifi state machine modes of operation */
-    /* CONNECT_MODE - connect to any 'known' AP when it becomes available */
-    public static final int CONNECT_MODE                   = 1;
-    /* SCAN_ONLY_MODE - don't connect to any APs; scan, but only while apps hold lock */
-    public static final int SCAN_ONLY_MODE                 = 2;
-    /* SCAN_ONLY_WITH_WIFI_OFF - scan, but don't connect to any APs */
-    public static final int SCAN_ONLY_WITH_WIFI_OFF_MODE   = 3;
-
-    private static final int SUCCESS = 1;
-    private static final int FAILURE = -1;
-
-    /**
-     * The maximum number of times we will retry a connection to an access point
-     * for which we have failed in acquiring an IP address from DHCP. A value of
-     * N means that we will make N+1 connection attempts in all.
-     * <p>
-     * See {@link Settings.Secure#WIFI_MAX_DHCP_RETRY_COUNT}. This is the default
-     * value if a Settings value is not present.
-     */
-    private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
-
-    /* Tracks if suspend optimizations need to be disabled by DHCP,
-     * screen or due to high perf mode.
-     * When any of them needs to disable it, we keep the suspend optimizations
-     * disabled
-     */
-    private int mSuspendOptNeedsDisabled = 0;
-
-    private static final int SUSPEND_DUE_TO_DHCP       = 1;
-    private static final int SUSPEND_DUE_TO_HIGH_PERF  = 1<<1;
-    private static final int SUSPEND_DUE_TO_SCREEN     = 1<<2;
-
-    /* Tracks if user has enabled suspend optimizations through settings */
-    private AtomicBoolean mUserWantsSuspendOpt = new AtomicBoolean(true);
-
-    /**
-     * Default framework scan interval in milliseconds. This is used in the scenario in which
-     * wifi chipset does not support background scanning to set up a
-     * periodic wake up scan so that the device can connect to a new access
-     * point on the move. {@link Settings.Global#WIFI_FRAMEWORK_SCAN_INTERVAL_MS} can
-     * override this.
-     */
-    private final int mDefaultFrameworkScanIntervalMs;
-
-    /**
-     * Supplicant scan interval in milliseconds.
-     * Comes from {@link Settings.Global#WIFI_SUPPLICANT_SCAN_INTERVAL_MS} or
-     * from the default config if the setting is not set
-     */
-    private long mSupplicantScanIntervalMs;
-
-    /**
-     * Minimum time interval between enabling all networks.
-     * A device can end up repeatedly connecting to a bad network on screen on/off toggle
-     * due to enabling every time. We add a threshold to avoid this.
-     */
-    private static final int MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS = 10 * 60 * 1000; /* 10 minutes */
-    private long mLastEnableAllNetworksTime;
-
-    /**
-     * Starting and shutting down driver too quick causes problems leading to driver
-     * being in a bad state. Delay driver stop.
-     */
-    private final int mDriverStopDelayMs;
-    private int mDelayedStopCounter;
-    private boolean mInDelayedStop = false;
-
-    // sometimes telephony gives us this data before boot is complete and we can't store it
-    // until after, so the write is deferred
-    private volatile String mPersistedCountryCode;
-
-    // Supplicant doesn't like setting the same country code multiple times (it may drop
-    // currently connected network), so we save the country code here to avoid redundency
-    private String mLastSetCountryCode;
-
-    private static final int MIN_RSSI = -200;
-    private static final int MAX_RSSI = 256;
-
-    /* Default parent state */
-    private State mDefaultState = new DefaultState();
-    /* Temporary initial state */
-    private State mInitialState = new InitialState();
-    /* Driver loaded, waiting for supplicant to start */
-    private State mSupplicantStartingState = new SupplicantStartingState();
-    /* Driver loaded and supplicant ready */
-    private State mSupplicantStartedState = new SupplicantStartedState();
-    /* Waiting for supplicant to stop and monitor to exit */
-    private State mSupplicantStoppingState = new SupplicantStoppingState();
-    /* Driver start issued, waiting for completed event */
-    private State mDriverStartingState = new DriverStartingState();
-    /* Driver started */
-    private State mDriverStartedState = new DriverStartedState();
-    /* Wait until p2p is disabled
-     * This is a special state which is entered right after we exit out of DriverStartedState
-     * before transitioning to another state.
-     */
-    private State mWaitForP2pDisableState = new WaitForP2pDisableState();
-    /* Driver stopping */
-    private State mDriverStoppingState = new DriverStoppingState();
-    /* Driver stopped */
-    private State mDriverStoppedState = new DriverStoppedState();
-    /* Scan for networks, no connection will be established */
-    private State mScanModeState = new ScanModeState();
-    /* Connecting to an access point */
-    private State mConnectModeState = new ConnectModeState();
-    /* Connected at 802.11 (L2) level */
-    private State mL2ConnectedState = new L2ConnectedState();
-    /* fetching IP after connection to access point (assoc+auth complete) */
-    private State mObtainingIpState = new ObtainingIpState();
-    /* Waiting for link quality verification to be complete */
-    private State mVerifyingLinkState = new VerifyingLinkState();
-    /* Waiting for captive portal check to be complete */
-    private State mCaptivePortalCheckState = new CaptivePortalCheckState();
-    /* Connected with IP addr */
-    private State mConnectedState = new ConnectedState();
-    /* disconnect issued, waiting for network disconnect confirmation */
-    private State mDisconnectingState = new DisconnectingState();
-    /* Network is not connected, supplicant assoc+auth is not complete */
-    private State mDisconnectedState = new DisconnectedState();
-    /* Waiting for WPS to be completed*/
-    private State mWpsRunningState = new WpsRunningState();
-
-    /* Soft ap is starting up */
-    private State mSoftApStartingState = new SoftApStartingState();
-    /* Soft ap is running */
-    private State mSoftApStartedState = new SoftApStartedState();
-    /* Soft ap is running and we are waiting for tether notification */
-    private State mTetheringState = new TetheringState();
-    /* Soft ap is running and we are tethered through connectivity service */
-    private State mTetheredState = new TetheredState();
-    /* Waiting for untether confirmation before stopping soft Ap */
-    private State mUntetheringState = new UntetheringState();
-
-    private class TetherStateChange {
-        ArrayList<String> available;
-        ArrayList<String> active;
-        TetherStateChange(ArrayList<String> av, ArrayList<String> ac) {
-            available = av;
-            active = ac;
-        }
-    }
-
-
-    /**
-     * One of  {@link WifiManager#WIFI_STATE_DISABLED},
-     *         {@link WifiManager#WIFI_STATE_DISABLING},
-     *         {@link WifiManager#WIFI_STATE_ENABLED},
-     *         {@link WifiManager#WIFI_STATE_ENABLING},
-     *         {@link WifiManager#WIFI_STATE_UNKNOWN}
-     *
-     */
-    private final AtomicInteger mWifiState = new AtomicInteger(WIFI_STATE_DISABLED);
-
-    /**
-     * One of  {@link WifiManager#WIFI_AP_STATE_DISABLED},
-     *         {@link WifiManager#WIFI_AP_STATE_DISABLING},
-     *         {@link WifiManager#WIFI_AP_STATE_ENABLED},
-     *         {@link WifiManager#WIFI_AP_STATE_ENABLING},
-     *         {@link WifiManager#WIFI_AP_STATE_FAILED}
-     *
-     */
-    private final AtomicInteger mWifiApState = new AtomicInteger(WIFI_AP_STATE_DISABLED);
-
-    private static final int SCAN_REQUEST = 0;
-    private static final String ACTION_START_SCAN =
-        "com.android.server.WifiManager.action.START_SCAN";
-
-    private static final String DELAYED_STOP_COUNTER = "DelayedStopCounter";
-    private static final int DRIVER_STOP_REQUEST = 0;
-    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.
-     */
-    private boolean mIsRunning = false;
-
-    /**
-     * Keep track of whether we last told the battery stats we had started.
-     */
-    private boolean mReportedRunning = false;
-
-    /**
-     * Most recently set source of starting WIFI.
-     */
-    private final WorkSource mRunningWifiUids = new WorkSource();
-
-    /**
-     * The last reported UIDs that were responsible for starting WIFI.
-     */
-    private final WorkSource mLastRunningWifiUids = new WorkSource();
-
-    private final IBatteryStats mBatteryStats;
-
-    private BatchedScanSettings mBatchedScanSettings = null;
-
-    /**
-     * Track the worksource/cost of the current settings and track what's been noted
-     * to the battery stats, so we can mark the end of the previous when changing.
-     */
-    private WorkSource mBatchedScanWorkSource = null;
-    private int mBatchedScanCsph = 0;
-    private WorkSource mNotedBatchedScanWorkSource = null;
-    private int mNotedBatchedScanCsph = 0;
-
-
-    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(
-                BatteryStats.SERVICE_NAME));
-
-        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-        mNwService = INetworkManagementService.Stub.asInterface(b);
-
-        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_WIFI_DIRECT);
-
-        mWifiNative = new WifiNative(mInterfaceName);
-        mWifiConfigStore = new WifiConfigStore(context, mWifiNative);
-        mWifiMonitor = new WifiMonitor(this, mWifiNative);
-        mWifiInfo = new WifiInfo();
-        mSupplicantStateTracker = new SupplicantStateTracker(context, this, mWifiConfigStore,
-                getHandler());
-        mLinkProperties = new LinkProperties();
-        mNetlinkLinkProperties = new LinkProperties();
-
-        mWifiP2pManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE);
-
-        mNetworkInfo.setIsAvailable(false);
-        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);
-
-        mDriverStopDelayMs = mContext.getResources().getInteger(
-                R.integer.config_wifi_driver_stop_delay);
-
-        mBackgroundScanSupported = mContext.getResources().getBoolean(
-                R.bool.config_wifi_background_scan_support);
-
-        mPrimaryDeviceType = mContext.getResources().getString(
-                R.string.config_wifi_p2p_device_type);
-
-        mUserWantsSuspendOpt.set(Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
-
-        mContext.registerReceiver(
-            new BroadcastReceiver() {
-                @Override
-                public void onReceive(Context context, Intent intent) {
-                    ArrayList<String> available = intent.getStringArrayListExtra(
-                            ConnectivityManager.EXTRA_AVAILABLE_TETHER);
-                    ArrayList<String> active = intent.getStringArrayListExtra(
-                            ConnectivityManager.EXTRA_ACTIVE_TETHER);
-                    sendMessage(CMD_TETHER_STATE_CHANGE, new TetherStateChange(available, active));
-                }
-            },new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED));
-
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        final WorkSource workSource = null;
-                        startScan(UNKNOWN_SCAN_SOURCE, workSource);
-                    }
-                },
-                new IntentFilter(ACTION_START_SCAN));
-
-        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);
-                        } else if (action.equals(ACTION_REFRESH_BATCHED_SCAN)) {
-                            startNextBatchedScanAsync();
-                        }
-                    }
-                }, filter);
-
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                       int counter = intent.getIntExtra(DELAYED_STOP_COUNTER, 0);
-                       sendMessage(CMD_DELAYED_STOP_DRIVER, counter, 0);
-                    }
-                },
-                new IntentFilter(ACTION_DELAYED_DRIVER_STOP));
-
-        mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
-                Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED), false,
-                new ContentObserver(getHandler()) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        mUserWantsSuspendOpt.set(Settings.Global.getInt(mContext.getContentResolver(),
-                                Settings.Global.WIFI_SUSPEND_OPTIMIZATIONS_ENABLED, 1) == 1);
-                    }
-                });
-
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        sendMessage(CMD_BOOT_COMPLETED);
-                    }
-                },
-                new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
-
-        mScanResultCache = new LruCache<String, ScanResult>(SCAN_RESULT_CACHE_SIZE);
-
-        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getName());
-
-        mSuspendWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WifiSuspend");
-        mSuspendWakeLock.setReferenceCounted(false);
-
-        addState(mDefaultState);
-            addState(mInitialState, mDefaultState);
-            addState(mSupplicantStartingState, mDefaultState);
-            addState(mSupplicantStartedState, mDefaultState);
-                addState(mDriverStartingState, mSupplicantStartedState);
-                addState(mDriverStartedState, mSupplicantStartedState);
-                    addState(mScanModeState, mDriverStartedState);
-                    addState(mConnectModeState, mDriverStartedState);
-                        addState(mL2ConnectedState, mConnectModeState);
-                            addState(mObtainingIpState, mL2ConnectedState);
-                            addState(mVerifyingLinkState, mL2ConnectedState);
-                            addState(mCaptivePortalCheckState, mL2ConnectedState);
-                            addState(mConnectedState, mL2ConnectedState);
-                        addState(mDisconnectingState, mConnectModeState);
-                        addState(mDisconnectedState, mConnectModeState);
-                        addState(mWpsRunningState, mConnectModeState);
-                addState(mWaitForP2pDisableState, mSupplicantStartedState);
-                addState(mDriverStoppingState, mSupplicantStartedState);
-                addState(mDriverStoppedState, mSupplicantStartedState);
-            addState(mSupplicantStoppingState, mDefaultState);
-            addState(mSoftApStartingState, mDefaultState);
-            addState(mSoftApStartedState, mDefaultState);
-                addState(mTetheringState, mSoftApStartedState);
-                addState(mTetheredState, mSoftApStartedState);
-                addState(mUntetheringState, mSoftApStartedState);
-
-        setInitialState(mInitialState);
-
-        setLogRecSize(2000);
-        setLogOnlyTransitions(false);
-        if (DBG) setDbg(true);
-
-        //start the state machine
-        start();
-
-        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);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    /*********************************************************
-     * Methods exposed for public use
-     ********************************************************/
-
-    public Messenger getMessenger() {
-        return new Messenger(getHandler());
-    }
-    /**
-     * TODO: doc
-     */
-    public boolean syncPingSupplicant(AsyncChannel channel) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
-        boolean result = (resultMsg.arg1 != FAILURE);
-        resultMsg.recycle();
-        return result;
-    }
-
-    /**
-     * 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, WorkSource workSource) {
-        sendMessage(CMD_START_SCAN, callingUid, 0, workSource);
-    }
-
-    /**
-     * start or stop batched scanning using the given settings
-     */
-    private static final String BATCHED_SETTING = "batched_settings";
-    private static final String BATCHED_WORKSOURCE = "batched_worksource";
-    public void setBatchedScanSettings(BatchedScanSettings settings, int callingUid, int csph,
-            WorkSource workSource) {
-        Bundle bundle = new Bundle();
-        bundle.putParcelable(BATCHED_SETTING, settings);
-        bundle.putParcelable(BATCHED_WORKSOURCE, workSource);
-        sendMessage(CMD_SET_BATCHED_SCAN, callingUid, csph, bundle);
-    }
-
-    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() {
-        if (mBatchedScanSettings == null) return;
-
-        if (mDhcpActive) {
-            if (DBG) log("not starting Batched Scans due to DHCP");
-            return;
-        }
-
-        // first grab any existing data
-        retrieveBatchedScanData();
-
-        mAlarmManager.cancel(mBatchedScanIntervalIntent);
-
-        String scansExpected = mWifiNative.setBatchedScanSettings(mBatchedScanSettings);
-        try {
-            mExpectedBatchedScans = Integer.parseInt(scansExpected);
-            setNextBatchedAlarm(mExpectedBatchedScans);
-            if (mExpectedBatchedScans > 0) noteBatchedScanStart();
-        } 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(int responsibleUid, int csph, Bundle bundle) {
-        BatchedScanSettings settings = bundle.getParcelable(BATCHED_SETTING);
-        WorkSource responsibleWorkSource = bundle.getParcelable(BATCHED_WORKSOURCE);
-
-        if (DBG) {
-            log("set batched scan to " + settings + " for uid=" + responsibleUid +
-                    ", worksource=" + responsibleWorkSource);
-        }
-        if (settings != null) {
-            if (settings.equals(mBatchedScanSettings)) return false;
-        } else {
-            if (mBatchedScanSettings == null) return false;
-        }
-        mBatchedScanSettings = settings;
-        if (responsibleWorkSource == null) responsibleWorkSource = new WorkSource(responsibleUid);
-        mBatchedScanWorkSource = responsibleWorkSource;
-        mBatchedScanCsph = csph;
-        return true;
-    }
-
-    private void stopBatchedScan() {
-        mAlarmManager.cancel(mBatchedScanIntervalIntent);
-        retrieveBatchedScanData();
-        mWifiNative.setBatchedScanSettings(null);
-        noteBatchedScanStop();
-    }
-
-    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;
-            final long now = SystemClock.elapsedRealtime();
-            final int bssidStrLen = BSSID_STR.length();
-
-            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 = new String(splitData[n].getBytes(), bssidStrLen,
-                                splitData[n].length() - bssidStrLen);
-                    } 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) {
-                log(e.toString());
-            }
-        }
-    }
-
-    private void noteScanEnd() {
-        if (mScanWorkSource != null) {
-            try {
-                mBatteryStats.noteWifiScanStoppedFromSource(mScanWorkSource);
-            } catch (RemoteException e) {
-                log(e.toString());
-            } finally {
-                mScanWorkSource = null;
-            }
-        }
-    }
-
-    private void noteBatchedScanStart() {
-        // note the end of a previous scan set
-        if (mNotedBatchedScanWorkSource != null &&
-                (mNotedBatchedScanWorkSource.equals(mBatchedScanWorkSource) == false ||
-                 mNotedBatchedScanCsph != mBatchedScanCsph)) {
-            try {
-                mBatteryStats.noteWifiBatchedScanStoppedFromSource(mNotedBatchedScanWorkSource);
-            } catch (RemoteException e) {
-                log(e.toString());
-            } finally {
-                mNotedBatchedScanWorkSource = null;
-                mNotedBatchedScanCsph = 0;
-            }
-        }
-        // note the start of the new
-        try {
-            mBatteryStats.noteWifiBatchedScanStartedFromSource(mBatchedScanWorkSource,
-                    mBatchedScanCsph);
-            mNotedBatchedScanWorkSource = mBatchedScanWorkSource;
-            mNotedBatchedScanCsph = mBatchedScanCsph;
-        } catch (RemoteException e) {
-            log(e.toString());
-        }
-    }
-
-    private void noteBatchedScanStop() {
-        if (mNotedBatchedScanWorkSource != null) {
-            try {
-                mBatteryStats.noteWifiBatchedScanStoppedFromSource(mNotedBatchedScanWorkSource);
-            } catch (RemoteException e) {
-                log(e.toString());
-            } finally {
-                mNotedBatchedScanWorkSource = null;
-                mNotedBatchedScanCsph = 0;
-            }
-        }
-    }
-
-    private void startScanNative(int type) {
-        mWifiNative.scan(type);
-        mScanResultIsPending = true;
-    }
-
-    /**
-     * TODO: doc
-     */
-    public void setSupplicantRunning(boolean enable) {
-        if (enable) {
-            sendMessage(CMD_START_SUPPLICANT);
-        } else {
-            sendMessage(CMD_STOP_SUPPLICANT);
-        }
-    }
-
-    /**
-     * TODO: doc
-     */
-    public void setHostApRunning(WifiConfiguration wifiConfig, boolean enable) {
-        if (enable) {
-            sendMessage(CMD_START_AP, wifiConfig);
-        } else {
-            sendMessage(CMD_STOP_AP);
-        }
-    }
-
-    public void setWifiApConfiguration(WifiConfiguration config) {
-        mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
-    }
-
-    public WifiConfiguration syncGetWifiApConfiguration() {
-        Message resultMsg = mWifiApConfigChannel.sendMessageSynchronously(CMD_REQUEST_AP_CONFIG);
-        WifiConfiguration ret = (WifiConfiguration) resultMsg.obj;
-        resultMsg.recycle();
-        return ret;
-    }
-
-    /**
-     * TODO: doc
-     */
-    public int syncGetWifiState() {
-        return mWifiState.get();
-    }
-
-    /**
-     * TODO: doc
-     */
-    public String syncGetWifiStateByName() {
-        switch (mWifiState.get()) {
-            case WIFI_STATE_DISABLING:
-                return "disabling";
-            case WIFI_STATE_DISABLED:
-                return "disabled";
-            case WIFI_STATE_ENABLING:
-                return "enabling";
-            case WIFI_STATE_ENABLED:
-                return "enabled";
-            case WIFI_STATE_UNKNOWN:
-                return "unknown state";
-            default:
-                return "[invalid state]";
-        }
-    }
-
-    /**
-     * TODO: doc
-     */
-    public int syncGetWifiApState() {
-        return mWifiApState.get();
-    }
-
-    /**
-     * TODO: doc
-     */
-    public String syncGetWifiApStateByName() {
-        switch (mWifiApState.get()) {
-            case WIFI_AP_STATE_DISABLING:
-                return "disabling";
-            case WIFI_AP_STATE_DISABLED:
-                return "disabled";
-            case WIFI_AP_STATE_ENABLING:
-                return "enabling";
-            case WIFI_AP_STATE_ENABLED:
-                return "enabled";
-            case WIFI_AP_STATE_FAILED:
-                return "failed";
-            default:
-                return "[invalid state]";
-        }
-    }
-
-    /**
-     * Get status information for the current connection, if any.
-     * @return a {@link WifiInfo} object containing information about the current connection
-     *
-     */
-    public WifiInfo syncRequestConnectionInfo() {
-        return mWifiInfo;
-    }
-
-    public DhcpResults syncGetDhcpResults() {
-        synchronized (mDhcpResultsLock) {
-            return new DhcpResults(mDhcpResults);
-        }
-    }
-
-    /**
-     * TODO: doc
-     */
-    public void setDriverStart(boolean enable) {
-        if (enable) {
-            sendMessage(CMD_START_DRIVER);
-        } else {
-            sendMessage(CMD_STOP_DRIVER);
-        }
-    }
-
-    public void captivePortalCheckComplete() {
-        sendMessage(CMD_CAPTIVE_CHECK_COMPLETE);
-    }
-
-    /**
-     * TODO: doc
-     */
-    public void setOperationalMode(int mode) {
-        if (DBG) log("setting operational mode to " + String.valueOf(mode));
-        sendMessage(CMD_SET_OPERATIONAL_MODE, mode, 0);
-    }
-
-    /**
-     * TODO: doc
-     */
-    public List<ScanResult> syncGetScanResultsList() {
-        synchronized (mScanResultCache) {
-            List<ScanResult> scanList = new ArrayList<ScanResult>();
-            for(ScanResult result: mScanResults) {
-                scanList.add(new ScanResult(result));
-            }
-            return scanList;
-        }
-    }
-
-    /**
-     * Disconnect from Access Point
-     */
-    public void disconnectCommand() {
-        sendMessage(CMD_DISCONNECT);
-    }
-
-    /**
-     * Initiate a reconnection to AP
-     */
-    public void reconnectCommand() {
-        sendMessage(CMD_RECONNECT);
-    }
-
-    /**
-     * Initiate a re-association to AP
-     */
-    public void reassociateCommand() {
-        sendMessage(CMD_REASSOCIATE);
-    }
-
-    /**
-     * Reload networks and then reconnect; helps load correct data for TLS networks
-     */
-
-    public void reloadTlsNetworksAndReconnect() {
-        sendMessage(CMD_RELOAD_TLS_AND_RECONNECT);
-    }
-
-    /**
-     * Add a network synchronously
-     *
-     * @return network id of the new network
-     */
-    public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
-        int result = resultMsg.arg1;
-        resultMsg.recycle();
-        return result;
-    }
-
-    public List<WifiConfiguration> syncGetConfiguredNetworks(AsyncChannel channel) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_GET_CONFIGURED_NETWORKS);
-        List<WifiConfiguration> result = (List<WifiConfiguration>) resultMsg.obj;
-        resultMsg.recycle();
-        return result;
-    }
-
-    /**
-     * Delete a network
-     *
-     * @param networkId id of the network to be removed
-     */
-    public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
-        boolean result = (resultMsg.arg1 != FAILURE);
-        resultMsg.recycle();
-        return result;
-    }
-
-    /**
-     * Enable a network
-     *
-     * @param netId network id of the network
-     * @param disableOthers true, if all other networks have to be disabled
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     */
-    public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
-                disableOthers ? 1 : 0);
-        boolean result = (resultMsg.arg1 != FAILURE);
-        resultMsg.recycle();
-        return result;
-    }
-
-    /**
-     * Disable a network
-     *
-     * @param netId network id of the network
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     */
-    public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
-        Message resultMsg = channel.sendMessageSynchronously(WifiManager.DISABLE_NETWORK, netId);
-        boolean result = (resultMsg.arg1 != WifiManager.DISABLE_NETWORK_FAILED);
-        resultMsg.recycle();
-        return result;
-    }
-
-    /**
-     * Blacklist a BSSID. This will avoid the AP if there are
-     * alternate APs to connect
-     *
-     * @param bssid BSSID of the network
-     */
-    public void addToBlacklist(String bssid) {
-        sendMessage(CMD_BLACKLIST_NETWORK, bssid);
-    }
-
-    /**
-     * Clear the blacklist list
-     *
-     */
-    public void clearBlacklist() {
-        sendMessage(CMD_CLEAR_BLACKLIST);
-    }
-
-    public void enableRssiPolling(boolean enabled) {
-       sendMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0);
-    }
-
-    public void enableBackgroundScanCommand(boolean enabled) {
-       sendMessage(CMD_ENABLE_BACKGROUND_SCAN, enabled ? 1 : 0, 0);
-    }
-
-    public void enableAllNetworks() {
-        sendMessage(CMD_ENABLE_ALL_NETWORKS);
-    }
-
-    /**
-     * Start filtering Multicast v4 packets
-     */
-    public void startFilteringMulticastV4Packets() {
-        mFilteringMulticastV4Packets.set(true);
-        sendMessage(CMD_START_PACKET_FILTERING, MULTICAST_V4, 0);
-    }
-
-    /**
-     * Stop filtering Multicast v4 packets
-     */
-    public void stopFilteringMulticastV4Packets() {
-        mFilteringMulticastV4Packets.set(false);
-        sendMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V4, 0);
-    }
-
-    /**
-     * Start filtering Multicast v4 packets
-     */
-    public void startFilteringMulticastV6Packets() {
-        sendMessage(CMD_START_PACKET_FILTERING, MULTICAST_V6, 0);
-    }
-
-    /**
-     * Stop filtering Multicast v4 packets
-     */
-    public void stopFilteringMulticastV6Packets() {
-        sendMessage(CMD_STOP_PACKET_FILTERING, MULTICAST_V6, 0);
-    }
-
-    /**
-     * Set high performance mode of operation.
-     * Enabling would set active power mode and disable suspend optimizations;
-     * disabling would set auto power mode and enable suspend optimizations
-     * @param enable true if enable, false otherwise
-     */
-    public void setHighPerfModeEnabled(boolean enable) {
-        sendMessage(CMD_SET_HIGH_PERF_MODE, enable ? 1 : 0, 0);
-    }
-
-    /**
-     * Set the country code
-     * @param countryCode following ISO 3166 format
-     * @param persist {@code true} if the setting should be remembered.
-     */
-    public void setCountryCode(String countryCode, boolean persist) {
-        // If it's a country code, apply immediately,
-        // If it's empty, delay it in case it's a momentary dropout
-        int countryCodeSequence = mCountryCodeSequence.incrementAndGet();
-        if (TextUtils.isEmpty(countryCode)) {
-            String defaultCountryCode = mContext.getResources().getString(
-                    R.string.config_wifi_unknown_country_code);
-
-            sendMessageDelayed(CMD_SET_COUNTRY_CODE, countryCodeSequence, persist ? 1 : 0,
-                    defaultCountryCode, COUNTRY_CODE_DELAY_MS);
-        } else {
-            sendMessage(CMD_SET_COUNTRY_CODE, countryCodeSequence, persist ? 1 : 0, countryCode);
-        }
-    }
-
-    /**
-     * Set the operational frequency band
-     * @param band
-     * @param persist {@code true} if the setting should be remembered.
-     */
-    public void setFrequencyBand(int band, boolean persist) {
-        if (persist) {
-            Settings.Global.putInt(mContext.getContentResolver(),
-                    Settings.Global.WIFI_FREQUENCY_BAND,
-                    band);
-        }
-        sendMessage(CMD_SET_FREQUENCY_BAND, band, 0);
-    }
-
-    /**
-     * 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() {
-        return mFrequencyBand.get();
-    }
-
-    /**
-     * Returns the wifi configuration file
-     */
-    public String getConfigFile() {
-        return mWifiConfigStore.getConfigFile();
-    }
-
-    /**
-     * Send a message indicating bluetooth adapter connection state changed
-     */
-    public void sendBluetoothAdapterStateChange(int state) {
-        sendMessage(CMD_BLUETOOTH_ADAPTER_STATE_CHANGE, state, 0);
-    }
-
-    /**
-     * Save configuration on supplicant
-     *
-     * @return {@code true} if the operation succeeds, {@code false} otherwise
-     *
-     * TODO: deprecate this
-     */
-    public boolean syncSaveConfig(AsyncChannel channel) {
-        Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
-        boolean result = (resultMsg.arg1 != FAILURE);
-        resultMsg.recycle();
-        return result;
-    }
-
-    public void updateBatteryWorkSource(WorkSource newSource) {
-        synchronized (mRunningWifiUids) {
-            try {
-                if (newSource != null) {
-                    mRunningWifiUids.set(newSource);
-                }
-                if (mIsRunning) {
-                    if (mReportedRunning) {
-                        // If the work source has changed since last time, need
-                        // to remove old work from battery stats.
-                        if (mLastRunningWifiUids.diff(mRunningWifiUids)) {
-                            mBatteryStats.noteWifiRunningChanged(mLastRunningWifiUids,
-                                    mRunningWifiUids);
-                            mLastRunningWifiUids.set(mRunningWifiUids);
-                        }
-                    } else {
-                        // Now being started, report it.
-                        mBatteryStats.noteWifiRunning(mRunningWifiUids);
-                        mLastRunningWifiUids.set(mRunningWifiUids);
-                        mReportedRunning = true;
-                    }
-                } else {
-                    if (mReportedRunning) {
-                        // Last reported we were running, time to stop.
-                        mBatteryStats.noteWifiStopped(mLastRunningWifiUids);
-                        mLastRunningWifiUids.clear();
-                        mReportedRunning = false;
-                    }
-                }
-                mWakeLock.setWorkSource(newSource);
-            } catch (RemoteException ignore) {
-            }
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
-        mSupplicantStateTracker.dump(fd, pw, args);
-        pw.println("mLinkProperties " + mLinkProperties);
-        pw.println("mWifiInfo " + mWifiInfo);
-        pw.println("mDhcpResults " + mDhcpResults);
-        pw.println("mNetworkInfo " + mNetworkInfo);
-        pw.println("mLastSignalLevel " + mLastSignalLevel);
-        pw.println("mLastBssid " + mLastBssid);
-        pw.println("mLastNetworkId " + mLastNetworkId);
-        pw.println("mReconnectCount " + mReconnectCount);
-        pw.println("mOperationalMode " + mOperationalMode);
-        pw.println("mUserWantsSuspendOpt " + mUserWantsSuspendOpt);
-        pw.println("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
-        pw.println("Supplicant status " + mWifiNative.status());
-        pw.println("mEnableBackgroundScan " + mEnableBackgroundScan);
-        pw.println();
-        mWifiConfigStore.dump(fd, pw, args);
-    }
-
-    /*********************************************************
-     * Internal private functions
-     ********************************************************/
-
-    private void handleScreenStateChanged(boolean screenOn) {
-        if (DBG) log("handleScreenStateChanged: " + screenOn);
-        enableRssiPolling(screenOn);
-        if (mBackgroundScanSupported) {
-            enableBackgroundScanCommand(screenOn == false);
-        }
-
-        if (screenOn) enableAllNetworks();
-        if (mUserWantsSuspendOpt.get()) {
-            if (screenOn) {
-                sendMessage(CMD_SET_SUSPEND_OPT_ENABLED, 0, 0);
-            } else {
-                //Allow 2s for suspend optimizations to be set
-                mSuspendWakeLock.acquire(2000);
-                sendMessage(CMD_SET_SUSPEND_OPT_ENABLED, 1, 0);
-            }
-        }
-        mScreenBroadcastReceived.set(true);
-    }
-
-    private void checkAndSetConnectivityInstance() {
-        if (mCm == null) {
-            mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-        }
-    }
-
-    private boolean startTethering(ArrayList<String> available) {
-
-        boolean wifiAvailable = false;
-
-        checkAndSetConnectivityInstance();
-
-        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
-
-        for (String intf : available) {
-            for (String regex : wifiRegexs) {
-                if (intf.matches(regex)) {
-
-                    InterfaceConfiguration ifcg = null;
-                    try {
-                        ifcg = mNwService.getInterfaceConfig(intf);
-                        if (ifcg != null) {
-                            /* IP/netmask: 192.168.43.1/255.255.255.0 */
-                            ifcg.setLinkAddress(new LinkAddress(
-                                    NetworkUtils.numericToInetAddress("192.168.43.1"), 24));
-                            ifcg.setInterfaceUp();
-
-                            mNwService.setInterfaceConfig(intf, ifcg);
-                        }
-                    } catch (Exception e) {
-                        loge("Error configuring interface " + intf + ", :" + e);
-                        return false;
-                    }
-
-                    if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-                        loge("Error tethering on " + intf);
-                        return false;
-                    }
-                    mTetherInterfaceName = intf;
-                    return true;
-                }
-            }
-        }
-        // We found no interfaces to tether
-        return false;
-    }
-
-    private void stopTethering() {
-
-        checkAndSetConnectivityInstance();
-
-        /* Clear the interface config to allow dhcp correctly configure new
-           ip settings */
-        InterfaceConfiguration ifcg = null;
-        try {
-            ifcg = mNwService.getInterfaceConfig(mTetherInterfaceName);
-            if (ifcg != null) {
-                ifcg.setLinkAddress(
-                        new LinkAddress(NetworkUtils.numericToInetAddress("0.0.0.0"), 0));
-                mNwService.setInterfaceConfig(mTetherInterfaceName, ifcg);
-            }
-        } catch (Exception e) {
-            loge("Error resetting interface " + mTetherInterfaceName + ", :" + e);
-        }
-
-        if (mCm.untether(mTetherInterfaceName) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-            loge("Untether initiate failed!");
-        }
-    }
-
-    private boolean isWifiTethered(ArrayList<String> active) {
-
-        checkAndSetConnectivityInstance();
-
-        String[] wifiRegexs = mCm.getTetherableWifiRegexs();
-        for (String intf : active) {
-            for (String regex : wifiRegexs) {
-                if (intf.matches(regex)) {
-                    return true;
-                }
-            }
-        }
-        // We found no interfaces that are tethered
-        return false;
-    }
-
-    /**
-     * Set the country code from the system setting value, if any.
-     */
-    private void setCountryCode() {
-        String countryCode = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.WIFI_COUNTRY_CODE);
-        if (countryCode != null && !countryCode.isEmpty()) {
-            setCountryCode(countryCode, false);
-        } else {
-            //use driver default
-        }
-    }
-
-    /**
-     * Set the frequency band from the system setting value, if any.
-     */
-    private void setFrequencyBand() {
-        int band = Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.WIFI_FREQUENCY_BAND, WifiManager.WIFI_FREQUENCY_BAND_AUTO);
-        setFrequencyBand(band, false);
-    }
-
-    private void setSuspendOptimizationsNative(int reason, boolean enabled) {
-        if (DBG) log("setSuspendOptimizationsNative: " + reason + " " + enabled);
-        if (enabled) {
-            mSuspendOptNeedsDisabled &= ~reason;
-            /* None of dhcp, screen or highperf need it disabled and user wants it enabled */
-            if (mSuspendOptNeedsDisabled == 0 && mUserWantsSuspendOpt.get()) {
-                mWifiNative.setSuspendOptimizations(true);
-            }
-        } else {
-            mSuspendOptNeedsDisabled |= reason;
-            mWifiNative.setSuspendOptimizations(false);
-        }
-    }
-
-    private void setSuspendOptimizations(int reason, boolean enabled) {
-        if (DBG) log("setSuspendOptimizations: " + reason + " " + enabled);
-        if (enabled) {
-            mSuspendOptNeedsDisabled &= ~reason;
-        } else {
-            mSuspendOptNeedsDisabled |= reason;
-        }
-        if (DBG) log("mSuspendOptNeedsDisabled " + mSuspendOptNeedsDisabled);
-    }
-
-    private void setWifiState(int wifiState) {
-        final int previousWifiState = mWifiState.get();
-
-        try {
-            if (wifiState == WIFI_STATE_ENABLED) {
-                mBatteryStats.noteWifiOn();
-            } else if (wifiState == WIFI_STATE_DISABLED) {
-                mBatteryStats.noteWifiOff();
-            }
-        } catch (RemoteException e) {
-            loge("Failed to note battery stats in wifi");
-        }
-
-        mWifiState.set(wifiState);
-
-        if (DBG) log("setWifiState: " + syncGetWifiStateByName());
-
-        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_WIFI_STATE, wifiState);
-        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_STATE, previousWifiState);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void setWifiApState(int wifiApState) {
-        final int previousWifiApState = mWifiApState.get();
-
-        try {
-            if (wifiApState == WIFI_AP_STATE_ENABLED) {
-                mBatteryStats.noteWifiOn();
-            } else if (wifiApState == WIFI_AP_STATE_DISABLED) {
-                mBatteryStats.noteWifiOff();
-            }
-        } catch (RemoteException e) {
-            loge("Failed to note battery stats in wifi");
-        }
-
-        // Update state
-        mWifiApState.set(wifiApState);
-
-        if (DBG) log("setWifiApState: " + syncGetWifiApStateByName());
-
-        final Intent intent = new Intent(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_WIFI_AP_STATE, wifiApState);
-        intent.putExtra(WifiManager.EXTRA_PREVIOUS_WIFI_AP_STATE, previousWifiApState);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private static final String ID_STR = "id=";
-    private static final String BSSID_STR = "bssid=";
-    private static final String FREQ_STR = "freq=";
-    private static final String LEVEL_STR = "level=";
-    private static final String TSF_STR = "tsf=";
-    private static final String FLAGS_STR = "flags=";
-    private static final String SSID_STR = "ssid=";
-    private static final String DELIMITER_STR = "====";
-    private static final String END_STR = "####";
-
-    /**
-     * Format:
-     *
-     * id=1
-     * bssid=68:7f:76:d7:1a:6e
-     * freq=2412
-     * level=-44
-     * tsf=1344626243700342
-     * flags=[WPA2-PSK-CCMP][WPS][ESS]
-     * ssid=zfdy
-     * ====
-     * id=2
-     * bssid=68:5f:74:d7:1a:6f
-     * freq=5180
-     * level=-73
-     * tsf=1344626243700373
-     * flags=[WPA2-PSK-CCMP][WPS][ESS]
-     * ssid=zuby
-     * ====
-     */
-    private void setScanResults() {
-        String bssid = "";
-        int level = 0;
-        int freq = 0;
-        long tsf = 0;
-        String flags = "";
-        WifiSsid wifiSsid = null;
-        String scanResults;
-        String tmpResults;
-        StringBuffer scanResultsBuf = new StringBuffer();
-        int sid = 0;
-
-        while (true) {
-            tmpResults = mWifiNative.scanResults(sid);
-            if (TextUtils.isEmpty(tmpResults)) break;
-            scanResultsBuf.append(tmpResults);
-            scanResultsBuf.append("\n");
-            String[] lines = tmpResults.split("\n");
-            sid = -1;
-            for (int i=lines.length - 1; i >= 0; i--) {
-                if (lines[i].startsWith(END_STR)) {
-                    break;
-                } else if (lines[i].startsWith(ID_STR)) {
-                    try {
-                        sid = Integer.parseInt(lines[i].substring(ID_STR.length())) + 1;
-                    } catch (NumberFormatException e) {
-                        // Nothing to do
-                    }
-                    break;
-                }
-            }
-            if (sid == -1) break;
-        }
-
-        scanResults = scanResultsBuf.toString();
-        if (TextUtils.isEmpty(scanResults)) {
-           return;
-        }
-
-        // note that all these splits and substrings keep references to the original
-        // huge string buffer while the amount we really want is generally pretty small
-        // so make copies instead (one example b/11087956 wasted 400k of heap here).
-        synchronized(mScanResultCache) {
-            mScanResults = new ArrayList<ScanResult>();
-            String[] lines = scanResults.split("\n");
-            final int bssidStrLen = BSSID_STR.length();
-            final int flagLen = FLAGS_STR.length();
-
-            for (String line : lines) {
-                if (line.startsWith(BSSID_STR)) {
-                    bssid = new String(line.getBytes(), bssidStrLen, line.length() - bssidStrLen);
-                } else if (line.startsWith(FREQ_STR)) {
-                    try {
-                        freq = Integer.parseInt(line.substring(FREQ_STR.length()));
-                    } catch (NumberFormatException e) {
-                        freq = 0;
-                    }
-                } else if (line.startsWith(LEVEL_STR)) {
-                    try {
-                        level = Integer.parseInt(line.substring(LEVEL_STR.length()));
-                        /* some implementations avoid negative values by adding 256
-                         * so we need to adjust for that here.
-                         */
-                        if (level > 0) level -= 256;
-                    } catch(NumberFormatException e) {
-                        level = 0;
-                    }
-                } else if (line.startsWith(TSF_STR)) {
-                    try {
-                        tsf = Long.parseLong(line.substring(TSF_STR.length()));
-                    } catch (NumberFormatException e) {
-                        tsf = 0;
-                    }
-                } else if (line.startsWith(FLAGS_STR)) {
-                    flags = new String(line.getBytes(), flagLen, line.length() - flagLen);
-                } else if (line.startsWith(SSID_STR)) {
-                    wifiSsid = WifiSsid.createFromAsciiEncoded(
-                            line.substring(SSID_STR.length()));
-                } else if (line.startsWith(DELIMITER_STR) || line.startsWith(END_STR)) {
-                    if (bssid != null) {
-                        String ssid = (wifiSsid != null) ? wifiSsid.toString() : WifiSsid.NONE;
-                        String key = bssid + ssid;
-                        ScanResult scanResult = mScanResultCache.get(key);
-                        if (scanResult != null) {
-                            scanResult.level = level;
-                            scanResult.wifiSsid = wifiSsid;
-                            // Keep existing API
-                            scanResult.SSID = (wifiSsid != null) ? wifiSsid.toString() :
-                                    WifiSsid.NONE;
-                            scanResult.capabilities = flags;
-                            scanResult.frequency = freq;
-                            scanResult.timestamp = tsf;
-                        } else {
-                            scanResult =
-                                new ScanResult(
-                                        wifiSsid, bssid, flags, level, freq, tsf);
-                            mScanResultCache.put(key, scanResult);
-                        }
-                        mScanResults.add(scanResult);
-                    }
-                    bssid = null;
-                    level = 0;
-                    freq = 0;
-                    tsf = 0;
-                    flags = "";
-                    wifiSsid = null;
-                }
-            }
-        }
-    }
-
-    /*
-     * Fetch RSSI and linkspeed on current connection
-     */
-    private void fetchRssiAndLinkSpeedNative() {
-        int newRssi = -1;
-        int newLinkSpeed = -1;
-
-        String signalPoll = mWifiNative.signalPoll();
-
-        if (signalPoll != null) {
-            String[] lines = signalPoll.split("\n");
-            for (String line : lines) {
-                String[] prop = line.split("=");
-                if (prop.length < 2) continue;
-                try {
-                    if (prop[0].equals("RSSI")) {
-                        newRssi = Integer.parseInt(prop[1]);
-                    } else if (prop[0].equals("LINKSPEED")) {
-                        newLinkSpeed = Integer.parseInt(prop[1]);
-                    }
-                } catch (NumberFormatException e) {
-                    //Ignore, defaults on rssi and linkspeed are assigned
-                }
-            }
-        }
-
-        if (newRssi != -1 && MIN_RSSI < newRssi && newRssi < MAX_RSSI) { // screen out invalid values
-            /* some implementations avoid negative values by adding 256
-             * so we need to adjust for that here.
-             */
-            if (newRssi > 0) newRssi -= 256;
-            mWifiInfo.setRssi(newRssi);
-            /*
-             * Rather then sending the raw RSSI out every time it
-             * changes, we precalculate the signal level that would
-             * be displayed in the status bar, and only send the
-             * broadcast if that much more coarse-grained number
-             * changes. This cuts down greatly on the number of
-             * broadcasts, at the cost of not informing others
-             * interested in RSSI of all the changes in signal
-             * level.
-             */
-            int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, WifiManager.RSSI_LEVELS);
-            if (newSignalLevel != mLastSignalLevel) {
-                sendRssiChangeBroadcast(newRssi);
-            }
-            mLastSignalLevel = newSignalLevel;
-        } else {
-            mWifiInfo.setRssi(MIN_RSSI);
-        }
-
-        if (newLinkSpeed != -1) {
-            mWifiInfo.setLinkSpeed(newLinkSpeed);
-        }
-    }
-
-    /*
-     * Fetch TX packet counters on current connection
-     */
-    private void fetchPktcntNative(RssiPacketCountInfo info) {
-        String pktcntPoll = mWifiNative.pktcntPoll();
-
-        if (pktcntPoll != null) {
-            String[] lines = pktcntPoll.split("\n");
-            for (String line : lines) {
-                String[] prop = line.split("=");
-                if (prop.length < 2) continue;
-                try {
-                    if (prop[0].equals("TXGOOD")) {
-                        info.txgood = Integer.parseInt(prop[1]);
-                    } else if (prop[0].equals("TXBAD")) {
-                        info.txbad = Integer.parseInt(prop[1]);
-                    }
-                } catch (NumberFormatException e) {
-                    //Ignore
-                }
-            }
-        }
-    }
-
-    /**
-     * 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());
-            }
-        }
-
-        // 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() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                                      Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
-                                      DEFAULT_MAX_DHCP_RETRIES);
-    }
-
-    private void sendScanResultsAvailableBroadcast() {
-        noteScanEnd();
-        Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendRssiChangeBroadcast(final int newRssi) {
-        Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendNetworkStateChangeBroadcast(String bssid) {
-        Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
-        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties));
-        if (bssid != null)
-            intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
-        if (mNetworkInfo.getDetailedState() == DetailedState.VERIFYING_POOR_LINK ||
-                mNetworkInfo.getDetailedState() == DetailedState.CONNECTED) {
-            intent.putExtra(WifiManager.EXTRA_WIFI_INFO, new WifiInfo(mWifiInfo));
-        }
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendLinkConfigurationChangedBroadcast() {
-        Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties));
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
-        Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    /**
-     * Record the detailed state of a network.
-     * @param state the new {@code DetailedState}
-     */
-    private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
-        if (DBG) {
-            log("setDetailed state, old ="
-                    + mNetworkInfo.getDetailedState() + " and new state=" + state);
-        }
-
-        if (state != mNetworkInfo.getDetailedState()) {
-            mNetworkInfo.setDetailedState(state, null, mWifiInfo.getSSID());
-        }
-    }
-
-    private DetailedState getNetworkDetailedState() {
-        return mNetworkInfo.getDetailedState();
-    }
-
-
-    private SupplicantState handleSupplicantStateChange(Message message) {
-        StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-        SupplicantState state = stateChangeResult.state;
-        // Supplicant state change
-        // [31-13] Reserved for future use
-        // [8 - 0] Supplicant state (as defined in SupplicantState.java)
-        // 50023 supplicant_state_changed (custom|1|5)
-        mWifiInfo.setSupplicantState(state);
-        // Network id is only valid when we start connecting
-        if (SupplicantState.isConnecting(state)) {
-            mWifiInfo.setNetworkId(stateChangeResult.networkId);
-        } else {
-            mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
-        }
-
-        mWifiInfo.setBSSID(stateChangeResult.BSSID);
-        mWifiInfo.setSSID(stateChangeResult.wifiSsid);
-
-        mSupplicantStateTracker.sendMessage(Message.obtain(message));
-
-        return state;
-    }
-
-    /**
-     * Resets the Wi-Fi Connections by clearing any state, resetting any sockets
-     * using the interface, stopping DHCP & disabling interface
-     */
-    private void handleNetworkDisconnect() {
-        if (DBG) log("Stopping DHCP and clearing IP");
-
-        stopDhcp();
-
-        try {
-            mNwService.clearInterfaceAddresses(mInterfaceName);
-            mNwService.disableIpv6(mInterfaceName);
-        } catch (Exception e) {
-            loge("Failed to clear addresses or disable ipv6" + e);
-        }
-
-        /* Reset data structures */
-        mWifiInfo.setInetAddress(null);
-        mWifiInfo.setBSSID(null);
-        mWifiInfo.setSSID(null);
-        mWifiInfo.setNetworkId(WifiConfiguration.INVALID_NETWORK_ID);
-        mWifiInfo.setRssi(MIN_RSSI);
-        mWifiInfo.setLinkSpeed(-1);
-        mWifiInfo.setMeteredHint(false);
-
-        setNetworkDetailedState(DetailedState.DISCONNECTED);
-        mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
-
-        /* Clear network properties */
-        clearLinkProperties();
-
-        /* send event to CM & network change broadcast */
-        sendNetworkStateChangeBroadcast(mLastBssid);
-
-        mLastBssid= null;
-        mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-    }
-
-    private void handleSupplicantConnectionLoss() {
-        /* Socket connection can be lost when we do a graceful shutdown
-        * or when the driver is hung. Ensure supplicant is stopped here.
-        */
-        mWifiMonitor.killSupplicant(mP2pSupported);
-        sendSupplicantConnectionChangedBroadcast(false);
-        setWifiState(WIFI_STATE_DISABLED);
-    }
-
-    void handlePreDhcpSetup() {
-        mDhcpActive = true;
-        if (!mBluetoothConnectionActive) {
-            /*
-             * There are problems setting the Wi-Fi driver's power
-             * mode to active when bluetooth coexistence mode is
-             * enabled or sense.
-             * <p>
-             * We set Wi-Fi to active mode when
-             * obtaining an IP address because we've found
-             * compatibility issues with some routers with low power
-             * mode.
-             * <p>
-             * In order for this active power mode to properly be set,
-             * we disable coexistence mode until we're done with
-             * obtaining an IP address.  One exception is if we
-             * are currently connected to a headset, since disabling
-             * coexistence would interrupt that connection.
-             */
-            // Disable the coexistence mode
-            mWifiNative.setBluetoothCoexistenceMode(
-                    mWifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
-        }
-
-        /* Disable power save and suspend optimizations during DHCP */
-        // Note: The order here is important for now. Brcm driver changes
-        // power settings when we control suspend mode optimizations.
-        // TODO: Remove this comment when the driver is fixed.
-        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, false);
-        mWifiNative.setPowerSave(false);
-
-        stopBatchedScan();
-
-        /* P2p discovery breaks dhcp, shut it down in order to get through this */
-        Message msg = new Message();
-        msg.what = WifiP2pService.BLOCK_DISCOVERY;
-        msg.arg1 = WifiP2pService.ENABLED;
-        msg.arg2 = DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE;
-        msg.obj = mDhcpStateMachine;
-        mWifiP2pChannel.sendMessage(msg);
-    }
-
-
-    void startDhcp() {
-        if (mDhcpStateMachine == null) {
-            mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
-                    mContext, WifiStateMachine.this, mInterfaceName);
-
-        }
-        mDhcpStateMachine.registerForPreDhcpNotification();
-        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
-    }
-
-    void stopDhcp() {
-        if (mDhcpStateMachine != null) {
-            /* In case we were in middle of DHCP operation restore back powermode */
-            handlePostDhcpSetup();
-            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-        }
-    }
-
-    void handlePostDhcpSetup() {
-        /* Restore power save and suspend optimizations */
-        setSuspendOptimizationsNative(SUSPEND_DUE_TO_DHCP, true);
-        mWifiNative.setPowerSave(true);
-
-        mWifiP2pChannel.sendMessage(WifiP2pService.BLOCK_DISCOVERY, WifiP2pService.DISABLED);
-
-        // Set the coexistence mode back to its default value
-        mWifiNative.setBluetoothCoexistenceMode(
-                mWifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
-
-        mDhcpActive = false;
-
-        startBatchedScan();
-    }
-
-    private void handleSuccessfulIpConfiguration(DhcpResults dhcpResults) {
-        mLastSignalLevel = -1; // force update of signal strength
-        mReconnectCount = 0; //Reset IP failure tracking
-        synchronized (mDhcpResultsLock) {
-            mDhcpResults = dhcpResults;
-        }
-        LinkProperties linkProperties = dhcpResults.linkProperties;
-        mWifiConfigStore.setLinkProperties(mLastNetworkId, new LinkProperties(linkProperties));
-        InetAddress addr = null;
-        Iterator<InetAddress> addrs = linkProperties.getAddresses().iterator();
-        if (addrs.hasNext()) {
-            addr = addrs.next();
-        }
-        mWifiInfo.setInetAddress(addr);
-        mWifiInfo.setMeteredHint(dhcpResults.hasMeteredHint());
-        updateLinkProperties();
-    }
-
-    private void handleFailedIpConfiguration() {
-        loge("IP configuration failed");
-
-        mWifiInfo.setInetAddress(null);
-        mWifiInfo.setMeteredHint(false);
-        /**
-         * If we've exceeded the maximum number of retries for DHCP
-         * to a given network, disable the network
-         */
-        int maxRetries = getMaxDhcpRetries();
-        // maxRetries == 0 means keep trying forever
-        if (maxRetries > 0 && ++mReconnectCount > maxRetries) {
-            loge("Failed " +
-                    mReconnectCount + " times, Disabling " + mLastNetworkId);
-            mWifiConfigStore.disableNetwork(mLastNetworkId,
-                    WifiConfiguration.DISABLED_DHCP_FAILURE);
-            mReconnectCount = 0;
-        }
-
-        /* DHCP times out after about 30 seconds, we do a
-         * disconnect and an immediate reconnect to try again
-         */
-        mWifiNative.disconnect();
-        mWifiNative.reconnect();
-    }
-
-    /* Current design is to not set the config on a running hostapd but instead
-     * stop and start tethering when user changes config on a running access point
-     *
-     * TODO: Add control channel setup through hostapd that allows changing config
-     * on a running daemon
-     */
-    private void startSoftApWithConfig(final WifiConfiguration config) {
-        // start hostapd on a seperate thread
-        new Thread(new Runnable() {
-            public void run() {
-                try {
-                    mNwService.startAccessPoint(config, mInterfaceName);
-                } catch (Exception e) {
-                    loge("Exception in softap start " + e);
-                    try {
-                        mNwService.stopAccessPoint(mInterfaceName);
-                        mNwService.startAccessPoint(config, mInterfaceName);
-                    } catch (Exception e1) {
-                        loge("Exception in softap re-start " + e1);
-                        sendMessage(CMD_START_AP_FAILURE);
-                        return;
-                    }
-                }
-                if (DBG) log("Soft AP start successful");
-                sendMessage(CMD_START_AP_SUCCESS);
-            }
-        }).start();
-    }
-
-    /********************************************************
-     * HSM states
-     *******************************************************/
-
-    class DefaultState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        mWifiP2pChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
-                    } else {
-                        loge("WifiP2pService connection failure, error=" + message.arg1);
-                    }
-                    break;
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                    loge("WifiP2pService channel lost, message.arg1 =" + message.arg1);
-                    //TODO: Re-establish connection to state machine after a delay
-                    //mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
-                    break;
-                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
-                    mBluetoothConnectionActive = (message.arg1 !=
-                            BluetoothAdapter.STATE_DISCONNECTED);
-                    break;
-                    /* Synchronous call returns */
-                case CMD_PING_SUPPLICANT:
-                case CMD_ENABLE_NETWORK:
-                case CMD_ADD_OR_UPDATE_NETWORK:
-                case CMD_REMOVE_NETWORK:
-                case CMD_SAVE_CONFIG:
-                    replyToMessage(message, message.what, FAILURE);
-                    break;
-                case CMD_GET_CONFIGURED_NETWORKS:
-                    replyToMessage(message, message.what, (List<WifiConfiguration>) null);
-                    break;
-                case CMD_ENABLE_RSSI_POLL:
-                    mEnableRssiPolling = (message.arg1 == 1);
-                    break;
-                case CMD_ENABLE_BACKGROUND_SCAN:
-                    mEnableBackgroundScan = (message.arg1 == 1);
-                    break;
-                case CMD_SET_HIGH_PERF_MODE:
-                    if (message.arg1 == 1) {
-                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, false);
-                    } else {
-                        setSuspendOptimizations(SUSPEND_DUE_TO_HIGH_PERF, true);
-                    }
-                    break;
-                case CMD_BOOT_COMPLETED:
-                    String countryCode = mPersistedCountryCode;
-                    if (TextUtils.isEmpty(countryCode) == false) {
-                        Settings.Global.putString(mContext.getContentResolver(),
-                                Settings.Global.WIFI_COUNTRY_CODE,
-                                countryCode);
-                        // it may be that the state transition that should send this info
-                        // to the driver happened between mPersistedCountryCode getting set
-                        // and now, so simply persisting it here would mean we have sent
-                        // nothing to the driver.  Send the cmd so it might be set now.
-                        int sequenceNum = mCountryCodeSequence.incrementAndGet();
-                        sendMessageAtFrontOfQueue(CMD_SET_COUNTRY_CODE,
-                                sequenceNum, 0, countryCode);
-                    }
-                    break;
-                case CMD_SET_BATCHED_SCAN:
-                    recordBatchedScanSettings(message.arg1, message.arg2, (Bundle)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:
-                case CMD_STOP_SUPPLICANT:
-                case CMD_STOP_SUPPLICANT_FAILED:
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_DELAYED_STOP_DRIVER:
-                case CMD_DRIVER_START_TIMED_OUT:
-                case CMD_CAPTIVE_CHECK_COMPLETE:
-                case CMD_START_AP:
-                case CMD_START_AP_SUCCESS:
-                case CMD_START_AP_FAILURE:
-                case CMD_STOP_AP:
-                case CMD_TETHER_STATE_CHANGE:
-                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
-                case CMD_DISCONNECT:
-                case CMD_RECONNECT:
-                case CMD_REASSOCIATE:
-                case CMD_RELOAD_TLS_AND_RECONNECT:
-                case WifiMonitor.SUP_CONNECTION_EVENT:
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                case WifiMonitor.SCAN_RESULTS_EVENT:
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
-                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
-                case WifiMonitor.WPS_OVERLAP_EVENT:
-                case CMD_BLACKLIST_NETWORK:
-                case CMD_CLEAR_BLACKLIST:
-                case CMD_SET_OPERATIONAL_MODE:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_RSSI_POLL:
-                case CMD_ENABLE_ALL_NETWORKS:
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
-                /* Handled by WifiApConfigStore */
-                case CMD_SET_AP_CONFIG:
-                case CMD_SET_AP_CONFIG_COMPLETED:
-                case CMD_REQUEST_AP_CONFIG:
-                case CMD_RESPONSE_AP_CONFIG:
-                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
-                case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
-                case CMD_NO_NETWORKS_PERIODIC_SCAN:
-                case CMD_DISABLE_P2P_RSP:
-                    break;
-                case DhcpStateMachine.CMD_ON_QUIT:
-                    mDhcpStateMachine = null;
-                    break;
-                case CMD_SET_SUSPEND_OPT_ENABLED:
-                    if (message.arg1 == 1) {
-                        mSuspendWakeLock.release();
-                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, true);
-                    } else {
-                        setSuspendOptimizations(SUSPEND_DUE_TO_SCREEN, false);
-                    }
-                    break;
-                case WifiMonitor.DRIVER_HUNG_EVENT:
-                    setSupplicantRunning(false);
-                    setSupplicantRunning(true);
-                    break;
-                case WifiManager.CONNECT_NETWORK:
-                    replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
-                            WifiManager.BUSY);
-                    break;
-                case WifiManager.FORGET_NETWORK:
-                    replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
-                            WifiManager.BUSY);
-                    break;
-                case WifiManager.SAVE_NETWORK:
-                    replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
-                            WifiManager.BUSY);
-                    break;
-                case WifiManager.START_WPS:
-                    replyToMessage(message, WifiManager.WPS_FAILED,
-                            WifiManager.BUSY);
-                    break;
-                case WifiManager.CANCEL_WPS:
-                    replyToMessage(message, WifiManager.CANCEL_WPS_FAILED,
-                            WifiManager.BUSY);
-                    break;
-                case WifiManager.DISABLE_NETWORK:
-                    replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
-                            WifiManager.BUSY);
-                    break;
-                case WifiManager.RSSI_PKTCNT_FETCH:
-                    replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_FAILED,
-                            WifiManager.BUSY);
-                    break;
-                case WifiP2pService.P2P_CONNECTION_CHANGED:
-                    NetworkInfo info = (NetworkInfo) message.obj;
-                    mP2pConnected.set(info.isConnected());
-                    break;
-                case WifiP2pService.DISCONNECT_WIFI_REQUEST:
-                    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;
-            }
-            return HANDLED;
-        }
-    }
-
-    class InitialState extends State {
-        @Override
-        public void enter() {
-            mWifiNative.unloadDriver();
-
-            if (mWifiP2pChannel == null) {
-                mWifiP2pChannel = new AsyncChannel();
-                mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
-            }
-
-            if (mWifiApConfigChannel == null) {
-                mWifiApConfigChannel = new AsyncChannel();
-                WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
-                        mContext, getHandler());
-                wifiApConfigStore.loadApConfiguration();
-                mWifiApConfigChannel.connectSync(mContext, getHandler(),
-                        wifiApConfigStore.getMessenger());
-            }
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_START_SUPPLICANT:
-                    if (mWifiNative.loadDriver()) {
-                        try {
-                            mNwService.wifiFirmwareReload(mInterfaceName, "STA");
-                        } catch (Exception e) {
-                            loge("Failed to reload STA firmware " + e);
-                            // continue
-                        }
-
-                        try {
-                            // A runtime crash can leave the interface up and
-                            // this affects connectivity when supplicant starts up.
-                            // Ensure interface is down before a supplicant start.
-                            mNwService.setInterfaceDown(mInterfaceName);
-                            // Set privacy extensions
-                            mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
-
-                           // IPv6 is enabled only as long as access point is connected since:
-                           // - IPv6 addresses and routes stick around after disconnection
-                           // - kernel is unaware when connected and fails to start IPv6 negotiation
-                           // - kernel can start autoconfiguration when 802.1x is not complete
-                            mNwService.disableIpv6(mInterfaceName);
-                        } catch (RemoteException re) {
-                            loge("Unable to change interface settings: " + re);
-                        } catch (IllegalStateException ie) {
-                            loge("Unable to change interface settings: " + ie);
-                        }
-
-                       /* Stop a running supplicant after a runtime restart
-                        * Avoids issues with drivers that do not handle interface down
-                        * on a running supplicant properly.
-                        */
-                        mWifiMonitor.killSupplicant(mP2pSupported);
-                        if(mWifiNative.startSupplicant(mP2pSupported)) {
-                            setWifiState(WIFI_STATE_ENABLING);
-                            if (DBG) log("Supplicant start successful");
-                            mWifiMonitor.startMonitoring();
-                            transitionTo(mSupplicantStartingState);
-                        } else {
-                            loge("Failed to start supplicant!");
-                        }
-                    } else {
-                        loge("Failed to load driver");
-                    }
-                    break;
-                case CMD_START_AP:
-                    if (mWifiNative.loadDriver()) {
-                        setWifiApState(WIFI_AP_STATE_ENABLING);
-                        transitionTo(mSoftApStartingState);
-                    } else {
-                        loge("Failed to load driver for softap");
-                    }
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class SupplicantStartingState extends State {
-        private void initializeWpsDetails() {
-            String detail;
-            detail = SystemProperties.get("ro.product.name", "");
-            if (!mWifiNative.setDeviceName(detail)) {
-                loge("Failed to set device name " +  detail);
-            }
-            detail = SystemProperties.get("ro.product.manufacturer", "");
-            if (!mWifiNative.setManufacturer(detail)) {
-                loge("Failed to set manufacturer " + detail);
-            }
-            detail = SystemProperties.get("ro.product.model", "");
-            if (!mWifiNative.setModelName(detail)) {
-                loge("Failed to set model name " + detail);
-            }
-            detail = SystemProperties.get("ro.product.model", "");
-            if (!mWifiNative.setModelNumber(detail)) {
-                loge("Failed to set model number " + detail);
-            }
-            detail = SystemProperties.get("ro.serialno", "");
-            if (!mWifiNative.setSerialNumber(detail)) {
-                loge("Failed to set serial number " + detail);
-            }
-            if (!mWifiNative.setConfigMethods("physical_display virtual_push_button")) {
-                loge("Failed to set WPS config methods");
-            }
-            if (!mWifiNative.setDeviceType(mPrimaryDeviceType)) {
-                loge("Failed to set primary device type " + mPrimaryDeviceType);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case WifiMonitor.SUP_CONNECTION_EVENT:
-                    if (DBG) log("Supplicant connection established");
-                    setWifiState(WIFI_STATE_ENABLED);
-                    mSupplicantRestartCount = 0;
-                    /* Reset the supplicant state to indicate the supplicant
-                     * state is not known at this time */
-                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
-                    /* Initialize data structures */
-                    mLastBssid = null;
-                    mLastNetworkId = WifiConfiguration.INVALID_NETWORK_ID;
-                    mLastSignalLevel = -1;
-
-                    mWifiInfo.setMacAddress(mWifiNative.getMacAddress());
-                    mWifiConfigStore.loadAndEnableAllNetworks();
-                    initializeWpsDetails();
-
-                    sendSupplicantConnectionChangedBroadcast(true);
-                    transitionTo(mDriverStartedState);
-                    break;
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    if (++mSupplicantRestartCount <= SUPPLICANT_RESTART_TRIES) {
-                        loge("Failed to setup control channel, restart supplicant");
-                        mWifiMonitor.killSupplicant(mP2pSupported);
-                        transitionTo(mInitialState);
-                        sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
-                    } else {
-                        loge("Failed " + mSupplicantRestartCount +
-                                " times to start supplicant, unload driver");
-                        mSupplicantRestartCount = 0;
-                        setWifiState(WIFI_STATE_UNKNOWN);
-                        transitionTo(mInitialState);
-                    }
-                    break;
-                case CMD_START_SUPPLICANT:
-                case CMD_STOP_SUPPLICANT:
-                case CMD_START_AP:
-                case CMD_STOP_AP:
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_SET_OPERATIONAL_MODE:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class SupplicantStartedState extends State {
-        @Override
-        public void enter() {
-            /* Wifi is available as long as we have a connection to supplicant */
-            mNetworkInfo.setIsAvailable(true);
-
-            int defaultInterval = mContext.getResources().getInteger(
-                    R.integer.config_wifi_supplicant_scan_interval);
-
-            mSupplicantScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
-                    Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
-                    defaultInterval);
-
-            mWifiNative.setScanInterval((int)mSupplicantScanIntervalMs / 1000);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_STOP_SUPPLICANT:   /* Supplicant stopped by user */
-                    if (mP2pSupported) {
-                        transitionTo(mWaitForP2pDisableState);
-                    } else {
-                        transitionTo(mSupplicantStoppingState);
-                    }
-                    break;
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:  /* Supplicant connection lost */
-                    loge("Connection lost, restart supplicant");
-                    handleSupplicantConnectionLoss();
-                    handleNetworkDisconnect();
-                    mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
-                    if (mP2pSupported) {
-                        transitionTo(mWaitForP2pDisableState);
-                    } else {
-                        transitionTo(mInitialState);
-                    }
-                    sendMessageDelayed(CMD_START_SUPPLICANT, SUPPLICANT_RESTART_INTERVAL_MSECS);
-                    break;
-                case WifiMonitor.SCAN_RESULTS_EVENT:
-                    setScanResults();
-                    sendScanResultsAvailableBroadcast();
-                    mScanResultIsPending = false;
-                    break;
-                case CMD_PING_SUPPLICANT:
-                    boolean ok = mWifiNative.ping();
-                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
-                    break;
-                    /* Cannot start soft AP while in client mode */
-                case CMD_START_AP:
-                    loge("Failed to start soft AP with a running supplicant");
-                    setWifiApState(WIFI_AP_STATE_FAILED);
-                    break;
-                case CMD_SET_OPERATIONAL_MODE:
-                    mOperationalMode = message.arg1;
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        @Override
-        public void exit() {
-            mNetworkInfo.setIsAvailable(false);
-        }
-    }
-
-    class SupplicantStoppingState extends State {
-        @Override
-        public void enter() {
-            /* Send any reset commands to supplicant before shutting it down */
-            handleNetworkDisconnect();
-            if (mDhcpStateMachine != null) {
-                mDhcpStateMachine.doQuit();
-            }
-
-            if (DBG) log("stopping supplicant");
-            mWifiMonitor.stopSupplicant();
-
-            /* Send ourselves a delayed message to indicate failure after a wait time */
-            sendMessageDelayed(obtainMessage(CMD_STOP_SUPPLICANT_FAILED,
-                    ++mSupplicantStopFailureToken, 0), SUPPLICANT_RESTART_INTERVAL_MSECS);
-            setWifiState(WIFI_STATE_DISABLING);
-            mSupplicantStateTracker.sendMessage(CMD_RESET_SUPPLICANT_STATE);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case WifiMonitor.SUP_CONNECTION_EVENT:
-                    loge("Supplicant connection received while stopping");
-                    break;
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    if (DBG) log("Supplicant connection lost");
-                    handleSupplicantConnectionLoss();
-                    transitionTo(mInitialState);
-                    break;
-                case CMD_STOP_SUPPLICANT_FAILED:
-                    if (message.arg1 == mSupplicantStopFailureToken) {
-                        loge("Timed out on a supplicant stop, kill and proceed");
-                        handleSupplicantConnectionLoss();
-                        transitionTo(mInitialState);
-                    }
-                    break;
-                case CMD_START_SUPPLICANT:
-                case CMD_STOP_SUPPLICANT:
-                case CMD_START_AP:
-                case CMD_STOP_AP:
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_SET_OPERATIONAL_MODE:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class DriverStartingState extends State {
-        private int mTries;
-        @Override
-        public void enter() {
-            mTries = 1;
-            /* Send ourselves a delayed message to start driver a second time */
-            sendMessageDelayed(obtainMessage(CMD_DRIVER_START_TIMED_OUT,
-                        ++mDriverStartToken, 0), DRIVER_START_TIME_OUT_MSECS);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-               case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    SupplicantState state = handleSupplicantStateChange(message);
-                    /* If suplicant is exiting out of INTERFACE_DISABLED state into
-                     * a state that indicates driver has started, it is ready to
-                     * receive driver commands
-                     */
-                    if (SupplicantState.isDriverActive(state)) {
-                        transitionTo(mDriverStartedState);
-                    }
-                    break;
-                case CMD_DRIVER_START_TIMED_OUT:
-                    if (message.arg1 == mDriverStartToken) {
-                        if (mTries >= 2) {
-                            loge("Failed to start driver after " + mTries);
-                            transitionTo(mDriverStoppedState);
-                        } else {
-                            loge("Driver start failed, retrying");
-                            mWakeLock.acquire();
-                            mWifiNative.startDriver();
-                            mWakeLock.release();
-
-                            ++mTries;
-                            /* Send ourselves a delayed message to start driver again */
-                            sendMessageDelayed(obtainMessage(CMD_DRIVER_START_TIMED_OUT,
-                                        ++mDriverStartToken, 0), DRIVER_START_TIME_OUT_MSECS);
-                        }
-                    }
-                    break;
-                    /* Queue driver commands & connection events */
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
-                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
-                case WifiMonitor.WPS_OVERLAP_EVENT:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                case CMD_START_SCAN:
-                case CMD_DISCONNECT:
-                case CMD_REASSOCIATE:
-                case CMD_RECONNECT:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class DriverStartedState extends State {
-        @Override
-        public void enter() {
-            mIsRunning = true;
-            mInDelayedStop = false;
-            mDelayedStopCounter++;
-            updateBatteryWorkSource(null);
-            /**
-             * Enable bluetooth coexistence scan mode when bluetooth connection is active.
-             * When this mode is on, some of the low-level scan parameters used by the
-             * driver are changed to reduce interference with bluetooth
-             */
-            mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
-            /* set country code */
-            setCountryCode();
-            /* set frequency band of operation */
-            setFrequencyBand();
-            /* initialize network state */
-            setNetworkDetailedState(DetailedState.DISCONNECTED);
-
-            /* Remove any filtering on Multicast v6 at start */
-            mWifiNative.stopFilteringMulticastV6Packets();
-
-            /* Reset Multicast v4 filtering state */
-            if (mFilteringMulticastV4Packets.get()) {
-                mWifiNative.startFilteringMulticastV4Packets();
-            } else {
-                mWifiNative.stopFilteringMulticastV4Packets();
-            }
-
-            mDhcpActive = false;
-
-            startBatchedScan();
-
-            if (mOperationalMode != CONNECT_MODE) {
-                mWifiNative.disconnect();
-                mWifiConfigStore.disableAllNetworks();
-                if (mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
-                    setWifiState(WIFI_STATE_DISABLED);
-                }
-                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
-                mWifiNative.status();
-                transitionTo(mDisconnectedState);
-            }
-
-            // We may have missed screen update at boot
-            if (mScreenBroadcastReceived.get() == false) {
-                PowerManager powerManager = (PowerManager)mContext.getSystemService(
-                        Context.POWER_SERVICE);
-                handleScreenStateChanged(powerManager.isScreenOn());
-            } else {
-                // Set the right suspend mode settings
-                mWifiNative.setSuspendOptimizations(mSuspendOptNeedsDisabled == 0
-                        && mUserWantsSuspendOpt.get());
-            }
-            mWifiNative.setPowerSave(true);
-
-            if (mP2pSupported) {
-                if (mOperationalMode == CONNECT_MODE) {
-                    mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P);
-                } else {
-                    // P2P statemachine starts in disabled state, and is not enabled until
-                    // CMD_ENABLE_P2P is sent from here; so, nothing needs to be done to
-                    // keep it disabled.
-                }
-            }
-
-            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_ENABLED);
-            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_START_SCAN:
-                    noteScanStart(message.arg1, (WorkSource) message.obj);
-                    startScanNative(WifiNative.SCAN_WITH_CONNECTION_SETUP);
-                    break;
-                case CMD_SET_BATCHED_SCAN:
-                    if (recordBatchedScanSettings(message.arg1, message.arg2,
-                            (Bundle)message.obj)) {
-                        if (mBatchedScanSettings != null) {
-                            startBatchedScan();
-                        } else {
-                            stopBatchedScan();
-                        }
-                    }
-                    break;
-                case CMD_SET_COUNTRY_CODE:
-                    String country = (String) message.obj;
-                    final boolean persist = (message.arg2 == 1);
-                    final int sequence = message.arg1;
-                    if (sequence != mCountryCodeSequence.get()) {
-                        if (DBG) log("set country code ignored due to sequence num");
-                        break;
-                    }
-                    if (DBG) log("set country code " + country);
-                    if (persist) {
-                        mPersistedCountryCode = country;
-                        Settings.Global.putString(mContext.getContentResolver(),
-                                Settings.Global.WIFI_COUNTRY_CODE,
-                                country);
-                    }
-                    country = country.toUpperCase(Locale.ROOT);
-                    if (mLastSetCountryCode == null
-                            || country.equals(mLastSetCountryCode) == false) {
-                        if (mWifiNative.setCountryCode(country)) {
-                            mLastSetCountryCode = country;
-                        } else {
-                            loge("Failed to set country code " + country);
-                        }
-                    }
-                    mWifiP2pChannel.sendMessage(WifiP2pService.SET_COUNTRY_CODE, country);
-                    break;
-                case CMD_SET_FREQUENCY_BAND:
-                    int band =  message.arg1;
-                    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 {
-                        loge("Failed to set frequency band " + band);
-                    }
-                    break;
-                case CMD_BLUETOOTH_ADAPTER_STATE_CHANGE:
-                    mBluetoothConnectionActive = (message.arg1 !=
-                            BluetoothAdapter.STATE_DISCONNECTED);
-                    mWifiNative.setBluetoothCoexistenceScanMode(mBluetoothConnectionActive);
-                    break;
-                case CMD_STOP_DRIVER:
-                    int mode = message.arg1;
-
-                    /* Already doing a delayed stop */
-                    if (mInDelayedStop) {
-                        if (DBG) log("Already in delayed stop");
-                        break;
-                    }
-                    /* disconnect right now, but leave the driver running for a bit */
-                    mWifiConfigStore.disableAllNetworks();
-
-                    mInDelayedStop = true;
-                    mDelayedStopCounter++;
-                    if (DBG) log("Delayed stop message " + mDelayedStopCounter);
-
-                    /* send regular delayed shut down */
-                    Intent driverStopIntent = new Intent(ACTION_DELAYED_DRIVER_STOP, null);
-                    driverStopIntent.putExtra(DELAYED_STOP_COUNTER, mDelayedStopCounter);
-                    mDriverStopIntent = PendingIntent.getBroadcast(mContext,
-                            DRIVER_STOP_REQUEST, driverStopIntent,
-                            PendingIntent.FLAG_UPDATE_CURRENT);
-
-                    mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
-                            + mDriverStopDelayMs, mDriverStopIntent);
-                    break;
-                case CMD_START_DRIVER:
-                    if (mInDelayedStop) {
-                        mInDelayedStop = false;
-                        mDelayedStopCounter++;
-                        mAlarmManager.cancel(mDriverStopIntent);
-                        if (DBG) log("Delayed stop ignored due to start");
-                        if (mOperationalMode == CONNECT_MODE) {
-                            mWifiConfigStore.enableAllNetworks();
-                        }
-                    }
-                    break;
-                case CMD_DELAYED_STOP_DRIVER:
-                    if (DBG) log("delayed stop " + message.arg1 + " " + mDelayedStopCounter);
-                    if (message.arg1 != mDelayedStopCounter) break;
-                    if (getCurrentState() != mDisconnectedState) {
-                        mWifiNative.disconnect();
-                        handleNetworkDisconnect();
-                    }
-                    mWakeLock.acquire();
-                    mWifiNative.stopDriver();
-                    mWakeLock.release();
-                    if (mP2pSupported) {
-                        transitionTo(mWaitForP2pDisableState);
-                    } else {
-                        transitionTo(mDriverStoppingState);
-                    }
-                    break;
-                case CMD_START_PACKET_FILTERING:
-                    if (message.arg1 == MULTICAST_V6) {
-                        mWifiNative.startFilteringMulticastV6Packets();
-                    } else if (message.arg1 == MULTICAST_V4) {
-                        mWifiNative.startFilteringMulticastV4Packets();
-                    } else {
-                        loge("Illegal arugments to CMD_START_PACKET_FILTERING");
-                    }
-                    break;
-                case CMD_STOP_PACKET_FILTERING:
-                    if (message.arg1 == MULTICAST_V6) {
-                        mWifiNative.stopFilteringMulticastV6Packets();
-                    } else if (message.arg1 == MULTICAST_V4) {
-                        mWifiNative.stopFilteringMulticastV4Packets();
-                    } else {
-                        loge("Illegal arugments to CMD_STOP_PACKET_FILTERING");
-                    }
-                    break;
-                case CMD_SET_SUSPEND_OPT_ENABLED:
-                    if (message.arg1 == 1) {
-                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, true);
-                        mSuspendWakeLock.release();
-                    } else {
-                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_SCREEN, false);
-                    }
-                    break;
-                case CMD_SET_HIGH_PERF_MODE:
-                    if (message.arg1 == 1) {
-                        setSuspendOptimizationsNative(SUSPEND_DUE_TO_HIGH_PERF, false);
-                    } else {
-                        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;
-            }
-            return HANDLED;
-        }
-        @Override
-        public void exit() {
-            mIsRunning = false;
-            updateBatteryWorkSource(null);
-            mScanResults = new ArrayList<ScanResult>();
-
-            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);
-            mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-            noteScanEnd(); // wrap up any pending request.
-
-            mLastSetCountryCode = null;
-        }
-    }
-
-    class WaitForP2pDisableState extends State {
-        private State mTransitionToState;
-        @Override
-        public void enter() {
-            switch (getCurrentMessage().what) {
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    mTransitionToState = mInitialState;
-                    break;
-                case CMD_DELAYED_STOP_DRIVER:
-                    mTransitionToState = mDriverStoppingState;
-                    break;
-                case CMD_STOP_SUPPLICANT:
-                    mTransitionToState = mSupplicantStoppingState;
-                    break;
-                default:
-                    mTransitionToState = mDriverStoppingState;
-                    break;
-            }
-            mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_REQ);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case WifiStateMachine.CMD_DISABLE_P2P_RSP:
-                    transitionTo(mTransitionToState);
-                    break;
-                /* Defer wifi start/shut and driver commands */
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                case CMD_START_SUPPLICANT:
-                case CMD_STOP_SUPPLICANT:
-                case CMD_START_AP:
-                case CMD_STOP_AP:
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_SET_OPERATIONAL_MODE:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                case CMD_START_SCAN:
-                case CMD_DISCONNECT:
-                case CMD_REASSOCIATE:
-                case CMD_RECONNECT:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class DriverStoppingState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    SupplicantState state = handleSupplicantStateChange(message);
-                    if (state == SupplicantState.INTERFACE_DISABLED) {
-                        transitionTo(mDriverStoppedState);
-                    }
-                    break;
-                    /* Queue driver commands */
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                case CMD_START_SCAN:
-                case CMD_DISCONNECT:
-                case CMD_REASSOCIATE:
-                case CMD_RECONNECT:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class DriverStoppedState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-                    SupplicantState state = stateChangeResult.state;
-                    // A WEXT bug means that we can be back to driver started state
-                    // unexpectedly
-                    if (SupplicantState.isDriverActive(state)) {
-                        transitionTo(mDriverStartedState);
-                    }
-                    break;
-                case CMD_START_DRIVER:
-                    mWakeLock.acquire();
-                    mWifiNative.startDriver();
-                    mWakeLock.release();
-                    transitionTo(mDriverStartingState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class ScanModeState extends State {
-        private int mLastOperationMode;
-        @Override
-        public void enter() {
-            mLastOperationMode = mOperationalMode;
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_SET_OPERATIONAL_MODE:
-                    if (message.arg1 == CONNECT_MODE) {
-
-                        if (mLastOperationMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
-                            setWifiState(WIFI_STATE_ENABLED);
-                            // Load and re-enable networks when going back to enabled state
-                            // This is essential for networks to show up after restore
-                            mWifiConfigStore.loadAndEnableAllNetworks();
-                            mWifiP2pChannel.sendMessage(CMD_ENABLE_P2P);
-                        } else {
-                            mWifiConfigStore.enableAllNetworks();
-                        }
-
-                        mWifiNative.reconnect();
-
-                        mOperationalMode = CONNECT_MODE;
-                        transitionTo(mDisconnectedState);
-                    } else {
-                        // Nothing to do
-                        return HANDLED;
-                    }
-                    break;
-                // Handle scan. All the connection related commands are
-                // handled only in ConnectModeState
-                case CMD_START_SCAN:
-                    noteScanStart(message.arg1, (WorkSource) message.obj);
-                    startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class ConnectModeState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            WifiConfiguration config;
-            boolean ok;
-            switch(message.what) {
-                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
-                    mSupplicantStateTracker.sendMessage(WifiMonitor.ASSOCIATION_REJECTION_EVENT);
-                    break;
-                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
-                    mSupplicantStateTracker.sendMessage(WifiMonitor.AUTHENTICATION_FAILURE_EVENT);
-                    break;
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    SupplicantState state = handleSupplicantStateChange(message);
-                    // A driver/firmware hang can now put the interface in a down state.
-                    // We detect the interface going down and recover from it
-                    if (!SupplicantState.isDriverActive(state)) {
-                        if (mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
-                            handleNetworkDisconnect();
-                        }
-                        log("Detected an interface down, restart driver");
-                        transitionTo(mDriverStoppedState);
-                        sendMessage(CMD_START_DRIVER);
-                        break;
-                    }
-
-                    // Supplicant can fail to report a NETWORK_DISCONNECTION_EVENT
-                    // when authentication times out after a successful connection,
-                    // we can figure this from the supplicant state. If supplicant
-                    // state is DISCONNECTED, but the mNetworkInfo says we are not
-                    // disconnected, we need to handle a disconnection
-                    if (state == SupplicantState.DISCONNECTED &&
-                            mNetworkInfo.getState() != NetworkInfo.State.DISCONNECTED) {
-                        if (DBG) log("Missed CTRL-EVENT-DISCONNECTED, disconnect");
-                        handleNetworkDisconnect();
-                        transitionTo(mDisconnectedState);
-                    }
-                    break;
-                case WifiP2pService.DISCONNECT_WIFI_REQUEST:
-                    if (message.arg1 == 1) {
-                        mWifiNative.disconnect();
-                        mTemporarilyDisconnectWifi = true;
-                    } else {
-                        mWifiNative.reconnect();
-                        mTemporarilyDisconnectWifi = false;
-                    }
-                    break;
-                case CMD_ADD_OR_UPDATE_NETWORK:
-                    config = (WifiConfiguration) message.obj;
-                    replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
-                            mWifiConfigStore.addOrUpdateNetwork(config));
-                    break;
-                case CMD_REMOVE_NETWORK:
-                    ok = mWifiConfigStore.removeNetwork(message.arg1);
-                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
-                    break;
-                case CMD_ENABLE_NETWORK:
-                    ok = mWifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
-                    replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
-                    break;
-                case CMD_ENABLE_ALL_NETWORKS:
-                    long time =  android.os.SystemClock.elapsedRealtime();
-                    if (time - mLastEnableAllNetworksTime > MIN_INTERVAL_ENABLE_ALL_NETWORKS_MS) {
-                        mWifiConfigStore.enableAllNetworks();
-                        mLastEnableAllNetworksTime = time;
-                    }
-                    break;
-                case WifiManager.DISABLE_NETWORK:
-                    if (mWifiConfigStore.disableNetwork(message.arg1,
-                            WifiConfiguration.DISABLED_UNKNOWN_REASON) == true) {
-                        replyToMessage(message, WifiManager.DISABLE_NETWORK_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiManager.DISABLE_NETWORK_FAILED,
-                                WifiManager.ERROR);
-                    }
-                    break;
-                case CMD_BLACKLIST_NETWORK:
-                    mWifiNative.addToBlacklist((String)message.obj);
-                    break;
-                case CMD_CLEAR_BLACKLIST:
-                    mWifiNative.clearBlacklist();
-                    break;
-                case CMD_SAVE_CONFIG:
-                    ok = mWifiConfigStore.saveConfig();
-                    replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
-
-                    // Inform the backup manager about a data change
-                    IBackupManager ibm = IBackupManager.Stub.asInterface(
-                            ServiceManager.getService(Context.BACKUP_SERVICE));
-                    if (ibm != null) {
-                        try {
-                            ibm.dataChanged("com.android.providers.settings");
-                        } catch (Exception e) {
-                            // Try again later
-                        }
-                    }
-                    break;
-                case CMD_GET_CONFIGURED_NETWORKS:
-                    replyToMessage(message, message.what,
-                            mWifiConfigStore.getConfiguredNetworks());
-                    break;
-                    /* Do a redundant disconnect without transition */
-                case CMD_DISCONNECT:
-                    mWifiNative.disconnect();
-                    break;
-                case CMD_RECONNECT:
-                    mWifiNative.reconnect();
-                    break;
-                case CMD_REASSOCIATE:
-                    mWifiNative.reassociate();
-                    break;
-                case CMD_RELOAD_TLS_AND_RECONNECT:
-                    if (mWifiConfigStore.needsUnlockedKeyStore()) {
-                        logd("Reconnecting to give a chance to un-connected TLS networks");
-                        mWifiNative.disconnect();
-                        mWifiNative.reconnect();
-                    }
-                    break;
-                case WifiManager.CONNECT_NETWORK:
-                    /* The connect message can contain a network id passed as arg1 on message or
-                     * or a config passed as obj on message.
-                     * For a new network, a config is passed to create and connect.
-                     * For an existing network, a network id is passed
-                     */
-                    int netId = message.arg1;
-                    config = (WifiConfiguration) message.obj;
-
-                    /* Save the network config */
-                    if (config != null) {
-                        NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
-                        netId = result.getNetworkId();
-                    }
-
-                    if (mWifiConfigStore.selectNetwork(netId) &&
-                            mWifiNative.reconnect()) {
-                        /* The state tracker handles enabling networks upon completion/failure */
-                        mSupplicantStateTracker.sendMessage(WifiManager.CONNECT_NETWORK);
-                        replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);
-                        /* Expect a disconnection from the old connection */
-                        transitionTo(mDisconnectingState);
-                    } else {
-                        loge("Failed to connect config: " + config + " netId: " + netId);
-                        replyToMessage(message, WifiManager.CONNECT_NETWORK_FAILED,
-                                WifiManager.ERROR);
-                        break;
-                    }
-                    break;
-                case WifiManager.SAVE_NETWORK:
-                    config = (WifiConfiguration) message.obj;
-                    NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
-                    if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
-                        replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
-                    } else {
-                        loge("Failed to save network");
-                        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
-                                WifiManager.ERROR);
-                    }
-                    break;
-                case WifiManager.FORGET_NETWORK:
-                    if (mWifiConfigStore.forgetNetwork(message.arg1)) {
-                        replyToMessage(message, WifiManager.FORGET_NETWORK_SUCCEEDED);
-                    } else {
-                        loge("Failed to forget network");
-                        replyToMessage(message, WifiManager.FORGET_NETWORK_FAILED,
-                                WifiManager.ERROR);
-                    }
-                    break;
-                case WifiManager.START_WPS:
-                    WpsInfo wpsInfo = (WpsInfo) message.obj;
-                    WpsResult wpsResult;
-                    switch (wpsInfo.setup) {
-                        case WpsInfo.PBC:
-                            wpsResult = mWifiConfigStore.startWpsPbc(wpsInfo);
-                            break;
-                        case WpsInfo.KEYPAD:
-                            wpsResult = mWifiConfigStore.startWpsWithPinFromAccessPoint(wpsInfo);
-                            break;
-                        case WpsInfo.DISPLAY:
-                            wpsResult = mWifiConfigStore.startWpsWithPinFromDevice(wpsInfo);
-                            break;
-                        default:
-                            wpsResult = new WpsResult(Status.FAILURE);
-                            loge("Invalid setup for WPS");
-                            break;
-                    }
-                    if (wpsResult.status == Status.SUCCESS) {
-                        replyToMessage(message, WifiManager.START_WPS_SUCCEEDED, wpsResult);
-                        transitionTo(mWpsRunningState);
-                    } else {
-                        loge("Failed to start WPS with config " + wpsInfo.toString());
-                        replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.ERROR);
-                    }
-                    break;
-                case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                    if (DBG) log("Network connection established");
-                    mLastNetworkId = message.arg1;
-                    mLastBssid = (String) message.obj;
-
-                    mWifiInfo.setBSSID(mLastBssid);
-                    mWifiInfo.setNetworkId(mLastNetworkId);
-                    /* send event to CM & network change broadcast */
-                    setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
-                    sendNetworkStateChangeBroadcast(mLastBssid);
-                    transitionTo(mObtainingIpState);
-                    break;
-                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                    if (DBG) log("Network connection lost");
-                    handleNetworkDisconnect();
-                    transitionTo(mDisconnectedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class L2ConnectedState extends State {
-        @Override
-        public void enter() {
-            mRssiPollToken++;
-            if (mEnableRssiPolling) {
-                sendMessage(CMD_RSSI_POLL, mRssiPollToken, 0);
-            }
-        }
-
-        @Override
-        public void exit() {
-            handleNetworkDisconnect();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-              case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                  handlePreDhcpSetup();
-                  break;
-              case DhcpStateMachine.CMD_POST_DHCP_ACTION:
-                  handlePostDhcpSetup();
-                  if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
-                      if (DBG) log("DHCP successful");
-                      handleSuccessfulIpConfiguration((DhcpResults) message.obj);
-                      transitionTo(mVerifyingLinkState);
-                  } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
-                      if (DBG) log("DHCP failed");
-                      handleFailedIpConfiguration();
-                      transitionTo(mDisconnectingState);
-                  }
-                  break;
-                case CMD_DISCONNECT:
-                    mWifiNative.disconnect();
-                    transitionTo(mDisconnectingState);
-                    break;
-                case WifiP2pService.DISCONNECT_WIFI_REQUEST:
-                    if (message.arg1 == 1) {
-                        mWifiNative.disconnect();
-                        mTemporarilyDisconnectWifi = true;
-                        transitionTo(mDisconnectingState);
-                    }
-                    break;
-                case CMD_SET_OPERATIONAL_MODE:
-                    if (message.arg1 != CONNECT_MODE) {
-                        sendMessage(CMD_DISCONNECT);
-                        deferMessage(message);
-                    }
-                    break;
-                case CMD_START_SCAN:
-                    /* Do not attempt to connect when we are already connected */
-                    noteScanStart(message.arg1, (WorkSource) message.obj);
-                    startScanNative(WifiNative.SCAN_WITHOUT_CONNECTION_SETUP);
-                    break;
-                    /* Ignore connection to same network */
-                case WifiManager.CONNECT_NETWORK:
-                    int netId = message.arg1;
-                    if (mWifiInfo.getNetworkId() == netId) {
-                        break;
-                    }
-                    return NOT_HANDLED;
-                case WifiManager.SAVE_NETWORK:
-                    WifiConfiguration config = (WifiConfiguration) message.obj;
-                    NetworkUpdateResult result = mWifiConfigStore.saveNetwork(config);
-                    if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
-                        if (result.hasIpChanged()) {
-                            log("Reconfiguring IP on connection");
-                            transitionTo(mObtainingIpState);
-                        }
-                        if (result.hasProxyChanged()) {
-                            log("Reconfiguring proxy on connection");
-                            updateLinkProperties();
-                        }
-                    }
-
-                    if (result.getNetworkId() != WifiConfiguration.INVALID_NETWORK_ID) {
-                        replyToMessage(message, WifiManager.SAVE_NETWORK_SUCCEEDED);
-                    } else {
-                        loge("Failed to save network");
-                        replyToMessage(message, WifiManager.SAVE_NETWORK_FAILED,
-                                WifiManager.ERROR);
-                    }
-                    break;
-                    /* Ignore */
-                case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                    break;
-                case CMD_RSSI_POLL:
-                    if (message.arg1 == mRssiPollToken) {
-                        // Get Info and continue polling
-                        fetchRssiAndLinkSpeedNative();
-                        sendMessageDelayed(obtainMessage(CMD_RSSI_POLL,
-                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
-                    } else {
-                        // Polling has completed
-                    }
-                    break;
-                case CMD_ENABLE_RSSI_POLL:
-                    mEnableRssiPolling = (message.arg1 == 1);
-                    mRssiPollToken++;
-                    if (mEnableRssiPolling) {
-                        // first poll
-                        fetchRssiAndLinkSpeedNative();
-                        sendMessageDelayed(obtainMessage(CMD_RSSI_POLL,
-                                mRssiPollToken, 0), POLL_RSSI_INTERVAL_MSECS);
-                    }
-                    break;
-                case WifiManager.RSSI_PKTCNT_FETCH:
-                    RssiPacketCountInfo info = new RssiPacketCountInfo();
-                    fetchRssiAndLinkSpeedNative();
-                    info.rssi = mWifiInfo.getRssi();
-                    fetchPktcntNative(info);
-                    replyToMessage(message, WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED, info);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-
-            return HANDLED;
-        }
-    }
-
-    class ObtainingIpState extends State {
-        @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));
-                InterfaceConfiguration ifcg = new InterfaceConfiguration();
-                Iterator<LinkAddress> addrs =
-                        dhcpResults.linkProperties.getLinkAddresses().iterator();
-                if (!addrs.hasNext()) {
-                    loge("Static IP lacks address");
-                    sendMessage(CMD_STATIC_IP_FAILURE);
-                } else {
-                    ifcg.setLinkAddress(addrs.next());
-                    ifcg.setInterfaceUp();
-                    try {
-                        mNwService.setInterfaceConfig(mInterfaceName, ifcg);
-                        if (DBG) log("Static IP configuration succeeded");
-                        sendMessage(CMD_STATIC_IP_SUCCESS, dhcpResults);
-                    } catch (RemoteException re) {
-                        loge("Static IP configuration failed: " + re);
-                        sendMessage(CMD_STATIC_IP_FAILURE);
-                    } catch (IllegalStateException e) {
-                        loge("Static IP configuration failed: " + e);
-                        sendMessage(CMD_STATIC_IP_FAILURE);
-                    }
-                }
-            }
-        }
-      @Override
-      public boolean processMessage(Message message) {
-          if (DBG) log(getName() + message.toString() + "\n");
-          switch(message.what) {
-            case CMD_STATIC_IP_SUCCESS:
-                  handleSuccessfulIpConfiguration((DhcpResults) message.obj);
-                  transitionTo(mVerifyingLinkState);
-                  break;
-              case CMD_STATIC_IP_FAILURE:
-                  handleFailedIpConfiguration();
-                  transitionTo(mDisconnectingState);
-                  break;
-             case WifiManager.SAVE_NETWORK:
-                  deferMessage(message);
-                  break;
-                  /* Defer any power mode changes since we must keep active power mode at DHCP */
-              case CMD_SET_HIGH_PERF_MODE:
-                  deferMessage(message);
-                  break;
-                  /* Defer scan request since we should not switch to other channels at DHCP */
-              case CMD_START_SCAN:
-                  deferMessage(message);
-                  break;
-              default:
-                  return NOT_HANDLED;
-          }
-          return HANDLED;
-      }
-    }
-
-    class VerifyingLinkState extends State {
-        @Override
-        public void enter() {
-            log(getName() + " enter");
-            setNetworkDetailedState(DetailedState.VERIFYING_POOR_LINK);
-            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.VERIFYING_POOR_LINK);
-            sendNetworkStateChangeBroadcast(mLastBssid);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
-                    //stay here
-                    log(getName() + " POOR_LINK_DETECTED: no transition");
-                    break;
-                case WifiWatchdogStateMachine.GOOD_LINK_DETECTED:
-                    log(getName() + " GOOD_LINK_DETECTED: transition to captive portal check");
-                    transitionTo(mCaptivePortalCheckState);
-                    break;
-                default:
-                    if (DBG) log(getName() + " what=" + message.what + " NOT_HANDLED");
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class CaptivePortalCheckState extends State {
-        @Override
-        public void enter() {
-            log(getName() + " enter");
-            setNetworkDetailedState(DetailedState.CAPTIVE_PORTAL_CHECK);
-            mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CAPTIVE_PORTAL_CHECK);
-            sendNetworkStateChangeBroadcast(mLastBssid);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_CAPTIVE_CHECK_COMPLETE:
-                    log(getName() + " CMD_CAPTIVE_CHECK_COMPLETE");
-                    try {
-                        mNwService.enableIpv6(mInterfaceName);
-                    } catch (RemoteException re) {
-                        loge("Failed to enable IPv6: " + re);
-                    } catch (IllegalStateException e) {
-                        loge("Failed to enable IPv6: " + e);
-                    }
-                    setNetworkDetailedState(DetailedState.CONNECTED);
-                    mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.CONNECTED);
-                    sendNetworkStateChangeBroadcast(mLastBssid);
-                    transitionTo(mConnectedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class ConnectedState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-               case WifiWatchdogStateMachine.POOR_LINK_DETECTED:
-                    if (DBG) log("Watchdog reports poor link");
-                    try {
-                        mNwService.disableIpv6(mInterfaceName);
-                    } catch (RemoteException re) {
-                        loge("Failed to disable IPv6: " + re);
-                    } catch (IllegalStateException e) {
-                        loge("Failed to disable IPv6: " + e);
-                    }
-                    /* Report a disconnect */
-                    setNetworkDetailedState(DetailedState.DISCONNECTED);
-                    mWifiConfigStore.updateStatus(mLastNetworkId, DetailedState.DISCONNECTED);
-                    sendNetworkStateChangeBroadcast(mLastBssid);
-
-                    transitionTo(mVerifyingLinkState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-        @Override
-        public void exit() {
-            /* Request a CS wakelock during transition to mobile */
-            checkAndSetConnectivityInstance();
-            mCm.requestNetworkTransitionWakelock(getName());
-        }
-    }
-
-    class DisconnectingState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case CMD_SET_OPERATIONAL_MODE:
-                    if (message.arg1 != CONNECT_MODE) {
-                        deferMessage(message);
-                    }
-                    break;
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    /* If we get a SUPPLICANT_STATE_CHANGE_EVENT before NETWORK_DISCONNECTION_EVENT
-                     * we have missed the network disconnection, transition to mDisconnectedState
-                     * and handle the rest of the events there
-                     */
-                    deferMessage(message);
-                    handleNetworkDisconnect();
-                    transitionTo(mDisconnectedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class DisconnectedState extends State {
-        private boolean mAlarmEnabled = false;
-        /* This is set from the overlay config file or from a secure setting.
-         * A value of 0 disables scanning in the framework.
-         */
-        private long mFrameworkScanIntervalMs;
-
-        private void setScanAlarm(boolean enabled) {
-            if (enabled == mAlarmEnabled) return;
-            if (enabled) {
-                if (mFrameworkScanIntervalMs > 0) {
-                    mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
-                            System.currentTimeMillis() + mFrameworkScanIntervalMs,
-                            mFrameworkScanIntervalMs,
-                            mScanIntent);
-                    mAlarmEnabled = true;
-                }
-            } else {
-                mAlarmManager.cancel(mScanIntent);
-                mAlarmEnabled = false;
-            }
-        }
-
-        @Override
-        public void enter() {
-            // We dont scan frequently if this is a temporary disconnect
-            // due to p2p
-            if (mTemporarilyDisconnectWifi) {
-                mWifiP2pChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_RESPONSE);
-                return;
-            }
-
-            mFrameworkScanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
-                    Settings.Global.WIFI_FRAMEWORK_SCAN_INTERVAL_MS,
-                    mDefaultFrameworkScanIntervalMs);
-            /*
-             * We initiate background scanning if it is enabled, otherwise we
-             * initiate an infrequent scan that wakes up the device to ensure
-             * a user connects to an access point on the move
-             */
-            if (mEnableBackgroundScan) {
-                /* If a regular scan result is pending, do not initiate background
-                 * scan until the scan results are returned. This is needed because
-                 * initiating a background scan will cancel the regular scan and
-                 * scan results will not be returned until background scanning is
-                 * cleared
-                 */
-                if (!mScanResultIsPending) {
-                    mWifiNative.enableBackgroundScan(true);
-                }
-            } else {
-                setScanAlarm(true);
-            }
-
-            /**
-             * If we have no networks saved, the supplicant stops doing the periodic scan.
-             * The scans are useful to notify the user of the presence of an open network.
-             * Note that these are not wake up scans.
-             */
-            if (!mP2pConnected.get() && mWifiConfigStore.getConfiguredNetworks().size() == 0) {
-                sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
-                            ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
-            }
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            boolean ret = HANDLED;
-            switch (message.what) {
-                case CMD_NO_NETWORKS_PERIODIC_SCAN:
-                    if (mP2pConnected.get()) break;
-                    if (message.arg1 == mPeriodicScanToken &&
-                            mWifiConfigStore.getConfiguredNetworks().size() == 0) {
-                        sendMessage(CMD_START_SCAN, UNKNOWN_SCAN_SOURCE, 0, (WorkSource) null);
-                        sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
-                                    ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
-                    }
-                    break;
-                case WifiManager.FORGET_NETWORK:
-                case CMD_REMOVE_NETWORK:
-                    // Set up a delayed message here. After the forget/remove is handled
-                    // the handled delayed message will determine if there is a need to
-                    // scan and continue
-                    sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
-                                ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
-                    ret = NOT_HANDLED;
-                    break;
-                case CMD_SET_OPERATIONAL_MODE:
-                    if (message.arg1 != CONNECT_MODE) {
-                        mOperationalMode = message.arg1;
-
-                        mWifiConfigStore.disableAllNetworks();
-                        if (mOperationalMode == SCAN_ONLY_WITH_WIFI_OFF_MODE) {
-                            mWifiP2pChannel.sendMessage(CMD_DISABLE_P2P_REQ);
-                            setWifiState(WIFI_STATE_DISABLED);
-                        }
-
-                        transitionTo(mScanModeState);
-                    }
-                    break;
-                case CMD_ENABLE_BACKGROUND_SCAN:
-                    mEnableBackgroundScan = (message.arg1 == 1);
-                    if (mEnableBackgroundScan) {
-                        mWifiNative.enableBackgroundScan(true);
-                        setScanAlarm(false);
-                    } else {
-                        mWifiNative.enableBackgroundScan(false);
-                        setScanAlarm(true);
-                    }
-                    break;
-                    /* Ignore network disconnect */
-                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                    break;
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
-                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
-                    /* ConnectModeState does the rest of the handling */
-                    ret = NOT_HANDLED;
-                    break;
-                case CMD_START_SCAN:
-                    /* Disable background scan temporarily during a regular scan */
-                    if (mEnableBackgroundScan) {
-                        mWifiNative.enableBackgroundScan(false);
-                    }
-                    /* Handled in parent state */
-                    ret = NOT_HANDLED;
-                    break;
-                case WifiMonitor.SCAN_RESULTS_EVENT:
-                    /* Re-enable background scan when a pending scan result is received */
-                    if (mEnableBackgroundScan && mScanResultIsPending) {
-                        mWifiNative.enableBackgroundScan(true);
-                    }
-                    /* Handled in parent state */
-                    ret = NOT_HANDLED;
-                    break;
-                case WifiP2pService.P2P_CONNECTION_CHANGED:
-                    NetworkInfo info = (NetworkInfo) message.obj;
-                    mP2pConnected.set(info.isConnected());
-                    if (mP2pConnected.get()) {
-                        int defaultInterval = mContext.getResources().getInteger(
-                                R.integer.config_wifi_scan_interval_p2p_connected);
-                        long scanIntervalMs = Settings.Global.getLong(mContext.getContentResolver(),
-                                Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
-                                defaultInterval);
-                        mWifiNative.setScanInterval((int) scanIntervalMs/1000);
-                    } else if (mWifiConfigStore.getConfiguredNetworks().size() == 0) {
-                        if (DBG) log("Turn on scanning after p2p disconnected");
-                        sendMessageDelayed(obtainMessage(CMD_NO_NETWORKS_PERIODIC_SCAN,
-                                    ++mPeriodicScanToken, 0), mSupplicantScanIntervalMs);
-                    }
-                case CMD_RECONNECT:
-                case CMD_REASSOCIATE:
-                    if (mTemporarilyDisconnectWifi) {
-                        // Drop a third party reconnect/reassociate if STA is
-                        // temporarily disconnected for p2p
-                        break;
-                    } else {
-                        // ConnectModeState handles it
-                        ret = NOT_HANDLED;
-                    }
-                    break;
-                default:
-                    ret = NOT_HANDLED;
-            }
-            return ret;
-        }
-
-        @Override
-        public void exit() {
-            /* No need for a background scan upon exit from a disconnected state */
-            if (mEnableBackgroundScan) {
-                mWifiNative.enableBackgroundScan(false);
-            }
-            setScanAlarm(false);
-        }
-    }
-
-    class WpsRunningState extends State {
-        //Tracks the source to provide a reply
-        private Message mSourceMessage;
-        @Override
-        public void enter() {
-            mSourceMessage = Message.obtain(getCurrentMessage());
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-                case WifiMonitor.WPS_SUCCESS_EVENT:
-                    // Ignore intermediate success, wait for full connection
-                    break;
-                case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                    replyToMessage(mSourceMessage, WifiManager.WPS_COMPLETED);
-                    mSourceMessage.recycle();
-                    mSourceMessage = null;
-                    deferMessage(message);
-                    transitionTo(mDisconnectedState);
-                    break;
-                case WifiMonitor.WPS_OVERLAP_EVENT:
-                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED,
-                            WifiManager.WPS_OVERLAP_ERROR);
-                    mSourceMessage.recycle();
-                    mSourceMessage = null;
-                    transitionTo(mDisconnectedState);
-                    break;
-                case WifiMonitor.WPS_FAIL_EVENT:
-                    //arg1 has the reason for the failure
-                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED, message.arg1);
-                    mSourceMessage.recycle();
-                    mSourceMessage = null;
-                    transitionTo(mDisconnectedState);
-                    break;
-                case WifiMonitor.WPS_TIMEOUT_EVENT:
-                    replyToMessage(mSourceMessage, WifiManager.WPS_FAILED,
-                            WifiManager.WPS_TIMED_OUT);
-                    mSourceMessage.recycle();
-                    mSourceMessage = null;
-                    transitionTo(mDisconnectedState);
-                    break;
-                case WifiManager.START_WPS:
-                    replyToMessage(message, WifiManager.WPS_FAILED, WifiManager.IN_PROGRESS);
-                    break;
-                case WifiManager.CANCEL_WPS:
-                    if (mWifiNative.cancelWps()) {
-                        replyToMessage(message, WifiManager.CANCEL_WPS_SUCCEDED);
-                    } else {
-                        replyToMessage(message, WifiManager.CANCEL_WPS_FAILED, WifiManager.ERROR);
-                    }
-                    transitionTo(mDisconnectedState);
-                    break;
-                /* Defer all commands that can cause connections to a different network
-                 * or put the state machine out of connect mode
-                 */
-                case CMD_STOP_DRIVER:
-                case CMD_SET_OPERATIONAL_MODE:
-                case WifiManager.CONNECT_NETWORK:
-                case CMD_ENABLE_NETWORK:
-                case CMD_RECONNECT:
-                case CMD_REASSOCIATE:
-                    deferMessage(message);
-                    break;
-                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                    if (DBG) log("Network connection lost");
-                    handleNetworkDisconnect();
-                    break;
-                case WifiMonitor.ASSOCIATION_REJECTION_EVENT:
-                    if (DBG) log("Ignore Assoc reject event during WPS Connection");
-                    break;
-                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
-                    // Disregard auth failure events during WPS connection. The
-                    // EAP sequence is retried several times, and there might be
-                    // failures (especially for wps pin). We will get a WPS_XXX
-                    // event at the end of the sequence anyway.
-                    if (DBG) log("Ignore auth failure during WPS connection");
-                    break;
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                    //Throw away supplicant state changes when WPS is running.
-                    //We will start getting supplicant state changes once we get
-                    //a WPS success or failure
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        @Override
-        public void exit() {
-            mWifiConfigStore.enableAllNetworks();
-            mWifiConfigStore.loadConfiguredNetworks();
-        }
-    }
-
-    class SoftApStartingState extends State {
-        @Override
-        public void enter() {
-            final Message message = getCurrentMessage();
-            if (message.what == CMD_START_AP) {
-                final WifiConfiguration config = (WifiConfiguration) message.obj;
-
-                if (config == null) {
-                    mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
-                } else {
-                    mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
-                    startSoftApWithConfig(config);
-                }
-            } else {
-                throw new RuntimeException("Illegal transition to SoftApStartingState: " + message);
-            }
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_START_SUPPLICANT:
-                case CMD_STOP_SUPPLICANT:
-                case CMD_START_AP:
-                case CMD_STOP_AP:
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_SET_OPERATIONAL_MODE:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                case CMD_TETHER_STATE_CHANGE:
-                    deferMessage(message);
-                    break;
-                case WifiStateMachine.CMD_RESPONSE_AP_CONFIG:
-                    WifiConfiguration config = (WifiConfiguration) message.obj;
-                    if (config != null) {
-                        startSoftApWithConfig(config);
-                    } else {
-                        loge("Softap config is null!");
-                        sendMessage(CMD_START_AP_FAILURE);
-                    }
-                    break;
-                case CMD_START_AP_SUCCESS:
-                    setWifiApState(WIFI_AP_STATE_ENABLED);
-                    transitionTo(mSoftApStartedState);
-                    break;
-                case CMD_START_AP_FAILURE:
-                    setWifiApState(WIFI_AP_STATE_FAILED);
-                    transitionTo(mInitialState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class SoftApStartedState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_STOP_AP:
-                    if (DBG) log("Stopping Soft AP");
-                    /* We have not tethered at this point, so we just shutdown soft Ap */
-                    try {
-                        mNwService.stopAccessPoint(mInterfaceName);
-                    } catch(Exception e) {
-                        loge("Exception in stopAccessPoint()");
-                    }
-                    setWifiApState(WIFI_AP_STATE_DISABLED);
-                    transitionTo(mInitialState);
-                    break;
-                case CMD_START_AP:
-                    // Ignore a start on a running access point
-                    break;
-                    /* Fail client mode operation when soft AP is enabled */
-                case CMD_START_SUPPLICANT:
-                    loge("Cannot start supplicant with a running soft AP");
-                    setWifiState(WIFI_STATE_UNKNOWN);
-                    break;
-                case CMD_TETHER_STATE_CHANGE:
-                    TetherStateChange stateChange = (TetherStateChange) message.obj;
-                    if (startTethering(stateChange.available)) {
-                        transitionTo(mTetheringState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class TetheringState extends State {
-        @Override
-        public void enter() {
-            /* Send ourselves a delayed message to shut down if tethering fails to notify */
-            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
-                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_TETHER_STATE_CHANGE:
-                    TetherStateChange stateChange = (TetherStateChange) message.obj;
-                    if (isWifiTethered(stateChange.active)) {
-                        transitionTo(mTetheredState);
-                    }
-                    return HANDLED;
-                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
-                    if (message.arg1 == mTetherToken) {
-                        loge("Failed to get tether update, shutdown soft access point");
-                        transitionTo(mSoftApStartedState);
-                        // Needs to be first thing handled
-                        sendMessageAtFrontOfQueue(CMD_STOP_AP);
-                    }
-                    break;
-                case CMD_START_SUPPLICANT:
-                case CMD_STOP_SUPPLICANT:
-                case CMD_START_AP:
-                case CMD_STOP_AP:
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_SET_OPERATIONAL_MODE:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class TetheredState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_TETHER_STATE_CHANGE:
-                    TetherStateChange stateChange = (TetherStateChange) message.obj;
-                    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:
-                    if (DBG) log("Untethering before stopping AP");
-                    setWifiApState(WIFI_AP_STATE_DISABLING);
-                    stopTethering();
-                    transitionTo(mUntetheringState);
-                    // More work to do after untethering
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class UntetheringState extends State {
-        @Override
-        public void enter() {
-            /* Send ourselves a delayed message to shut down if tethering fails to notify */
-            sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
-                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
-
-        }
-        @Override
-        public boolean processMessage(Message message) {
-            switch(message.what) {
-                case CMD_TETHER_STATE_CHANGE:
-                    TetherStateChange stateChange = (TetherStateChange) message.obj;
-
-                    /* Wait till wifi is untethered */
-                    if (isWifiTethered(stateChange.active)) break;
-
-                    transitionTo(mSoftApStartedState);
-                    break;
-                case CMD_TETHER_NOTIFICATION_TIMED_OUT:
-                    if (message.arg1 == mTetherToken) {
-                        loge("Failed to get tether update, force stop access point");
-                        transitionTo(mSoftApStartedState);
-                    }
-                    break;
-                case CMD_START_SUPPLICANT:
-                case CMD_STOP_SUPPLICANT:
-                case CMD_START_AP:
-                case CMD_STOP_AP:
-                case CMD_START_DRIVER:
-                case CMD_STOP_DRIVER:
-                case CMD_SET_OPERATIONAL_MODE:
-                case CMD_SET_COUNTRY_CODE:
-                case CMD_SET_FREQUENCY_BAND:
-                case CMD_START_PACKET_FILTERING:
-                case CMD_STOP_PACKET_FILTERING:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    //State machine initiated requests can have replyTo set to null indicating
-    //there are no recepients, we ignore those reply actions
-    private void replyToMessage(Message msg, int what) {
-        if (msg.replyTo == null) return;
-        Message dstMsg = obtainMessageWithArg2(msg);
-        dstMsg.what = what;
-        mReplyChannel.replyToMessage(msg, dstMsg);
-    }
-
-    private void replyToMessage(Message msg, int what, int arg1) {
-        if (msg.replyTo == null) return;
-        Message dstMsg = obtainMessageWithArg2(msg);
-        dstMsg.what = what;
-        dstMsg.arg1 = arg1;
-        mReplyChannel.replyToMessage(msg, dstMsg);
-    }
-
-    private void replyToMessage(Message msg, int what, Object obj) {
-        if (msg.replyTo == null) return;
-        Message dstMsg = obtainMessageWithArg2(msg);
-        dstMsg.what = what;
-        dstMsg.obj = obj;
-        mReplyChannel.replyToMessage(msg, dstMsg);
-    }
-
-    /**
-     * 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) {
-        Message msg = Message.obtain();
-        msg.arg2 = srcMsg.arg2;
-        return msg;
-    }
-}
diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java
index 615c893..7ded171 100644
--- a/wifi/java/android/net/wifi/WifiStateTracker.java
+++ b/wifi/java/android/net/wifi/WifiStateTracker.java
@@ -115,14 +115,6 @@
         return true;
     }
 
-    /**
-     * Captive check is complete, switch to network
-     */
-    @Override
-    public void captivePortalCheckComplete() {
-        mWifiManager.captivePortalCheckComplete();
-    }
-
     @Override
     public void captivePortalCheckCompleted(boolean isCaptivePortal) {
         // not implemented
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
deleted file mode 100644
index 6278c89..0000000
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ /dev/null
@@ -1,1212 +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.net.wifi;
-
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.database.ContentObserver;
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.NetworkInfo;
-import android.net.wifi.RssiPacketCountInfo;
-import android.os.Message;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.provider.Settings.Secure;
-import android.util.Log;
-import android.util.LruCache;
-
-import com.android.internal.R;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.text.DecimalFormat;
-
-/**
- * WifiWatchdogStateMachine monitors the connection to a WiFi network. When WiFi
- * connects at L2 layer, the beacons from access point reach the device and it
- * can maintain a connection, but the application connectivity can be flaky (due
- * to bigger packet size exchange).
- * <p>
- * We now monitor the quality of the last hop on WiFi using packet loss ratio as
- * an indicator to decide if the link is good enough to switch to Wi-Fi as the
- * uplink.
- * <p>
- * When WiFi is connected, the WiFi watchdog keeps sampling the RSSI and the
- * instant packet loss, and record it as per-AP loss-to-rssi statistics. When
- * the instant packet loss is higher than a threshold, the WiFi watchdog sends a
- * poor link notification to avoid WiFi connection temporarily.
- * <p>
- * While WiFi is being avoided, the WiFi watchdog keep watching the RSSI to
- * bring the WiFi connection back. Once the RSSI is high enough to achieve a
- * lower packet loss, a good link detection is sent such that the WiFi
- * connection become available again.
- * <p>
- * BSSID roaming has been taken into account. When user is moving across
- * multiple APs, the WiFi watchdog will detect that and keep watching the
- * currently connected AP.
- * <p>
- * Power impact should be minimal since much of the measurement relies on
- * passive statistics already being tracked at the driver and the polling is
- * done when screen is turned on and the RSSI is in a certain range.
- *
- * @hide
- */
-public class WifiWatchdogStateMachine extends StateMachine {
-
-    private static final boolean DBG = false;
-
-    private static final int BASE = Protocol.BASE_WIFI_WATCHDOG;
-
-    /* Internal events */
-    private static final int EVENT_WATCHDOG_TOGGLED                 = BASE + 1;
-    private static final int EVENT_NETWORK_STATE_CHANGE             = BASE + 2;
-    private static final int EVENT_RSSI_CHANGE                      = BASE + 3;
-    private static final int EVENT_SUPPLICANT_STATE_CHANGE          = BASE + 4;
-    private static final int EVENT_WIFI_RADIO_STATE_CHANGE          = BASE + 5;
-    private static final int EVENT_WATCHDOG_SETTINGS_CHANGE         = BASE + 6;
-    private static final int EVENT_BSSID_CHANGE                     = BASE + 7;
-    private static final int EVENT_SCREEN_ON                        = BASE + 8;
-    private static final int EVENT_SCREEN_OFF                       = BASE + 9;
-
-    /* Internal messages */
-    private static final int CMD_RSSI_FETCH                         = BASE + 11;
-
-    /* Notifications from/to WifiStateMachine */
-    static final int POOR_LINK_DETECTED                             = BASE + 21;
-    static final int GOOD_LINK_DETECTED                             = BASE + 22;
-
-    public static final boolean DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED = false;
-
-    /*
-     * RSSI levels as used by notification icon
-     * Level 4  -55 <= RSSI
-     * Level 3  -66 <= RSSI < -55
-     * Level 2  -77 <= RSSI < -67
-     * Level 1  -88 <= RSSI < -78
-     * Level 0         RSSI < -88
-     */
-
-    /**
-     * WiFi link statistics is monitored and recorded actively below this threshold.
-     * <p>
-     * Larger threshold is more adaptive but increases sampling cost.
-     */
-    private static final int LINK_MONITOR_LEVEL_THRESHOLD = WifiManager.RSSI_LEVELS - 1;
-
-    /**
-     * Remember packet loss statistics of how many BSSIDs.
-     * <p>
-     * Larger size is usually better but requires more space.
-     */
-    private static final int BSSID_STAT_CACHE_SIZE = 20;
-
-    /**
-     * RSSI range of a BSSID statistics.
-     * Within the range, (RSSI -> packet loss %) mappings are stored.
-     * <p>
-     * Larger range is usually better but requires more space.
-     */
-    private static final int BSSID_STAT_RANGE_LOW_DBM  = -105;
-
-    /**
-     * See {@link #BSSID_STAT_RANGE_LOW_DBM}.
-     */
-    private static final int BSSID_STAT_RANGE_HIGH_DBM = -45;
-
-    /**
-     * How many consecutive empty data point to trigger a empty-cache detection.
-     * In this case, a preset/default loss value (function on RSSI) is used.
-     * <p>
-     * In normal uses, some RSSI values may never be seen due to channel randomness.
-     * However, the size of such empty RSSI chunk in normal use is generally 1~2.
-     */
-    private static final int BSSID_STAT_EMPTY_COUNT = 3;
-
-    /**
-     * Sample interval for packet loss statistics, in msec.
-     * <p>
-     * Smaller interval is more accurate but increases sampling cost (battery consumption).
-     */
-    private static final long LINK_SAMPLING_INTERVAL_MS = 1 * 1000;
-
-    /**
-     * Coefficients (alpha) for moving average for packet loss tracking.
-     * Must be within (0.0, 1.0).
-     * <p>
-     * Equivalent number of samples: N = 2 / alpha - 1 .
-     * We want the historic loss to base on more data points to be statistically reliable.
-     * We want the current instant loss to base on less data points to be responsive.
-     */
-    private static final double EXP_COEFFICIENT_RECORD  = 0.1;
-
-    /**
-     * See {@link #EXP_COEFFICIENT_RECORD}.
-     */
-    private static final double EXP_COEFFICIENT_MONITOR = 0.5;
-
-    /**
-     * Thresholds for sending good/poor link notifications, in packet loss %.
-     * Good threshold must be smaller than poor threshold.
-     * Use smaller poor threshold to avoid WiFi more aggressively.
-     * Use smaller good threshold to bring back WiFi more conservatively.
-     * <p>
-     * When approaching the boundary, loss ratio jumps significantly within a few dBs.
-     * 50% loss threshold is a good balance between accuracy and reponsiveness.
-     * <=10% good threshold is a safe value to avoid jumping back to WiFi too easily.
-     */
-    private static final double POOR_LINK_LOSS_THRESHOLD = 0.5;
-
-    /**
-     * See {@link #POOR_LINK_LOSS_THRESHOLD}.
-     */
-    private static final double GOOD_LINK_LOSS_THRESHOLD = 0.1;
-
-    /**
-     * Number of samples to confirm before sending a poor link notification.
-     * Response time = confirm_count * sample_interval .
-     * <p>
-     * A smaller threshold improves response speed but may suffer from randomness.
-     * According to experiments, 3~5 are good values to achieve a balance.
-     * These parameters should be tuned along with {@link #LINK_SAMPLING_INTERVAL_MS}.
-     */
-    private static final int POOR_LINK_SAMPLE_COUNT = 3;
-
-    /**
-     * Minimum volume (converted from pkt/sec) to detect a poor link, to avoid randomness.
-     * <p>
-     * According to experiments, 1pkt/sec is too sensitive but 3pkt/sec is slightly unresponsive.
-     */
-    private static final double POOR_LINK_MIN_VOLUME = 2.0 * LINK_SAMPLING_INTERVAL_MS / 1000.0;
-
-    /**
-     * When a poor link is detected, we scan over this range (based on current
-     * poor link RSSI) for a target RSSI that satisfies a target packet loss.
-     * Refer to {@link #GOOD_LINK_TARGET}.
-     * <p>
-     * We want range_min not too small to avoid jumping back to WiFi too easily.
-     */
-    private static final int GOOD_LINK_RSSI_RANGE_MIN = 3;
-
-    /**
-     * See {@link #GOOD_LINK_RSSI_RANGE_MIN}.
-     */
-    private static final int GOOD_LINK_RSSI_RANGE_MAX = 20;
-
-    /**
-     * Adaptive good link target to avoid flapping.
-     * When a poor link is detected, a good link target is calculated as follows:
-     * <p>
-     *      targetRSSI = min { rssi | loss(rssi) < GOOD_LINK_LOSS_THRESHOLD } + rssi_adj[i],
-     *                   where rssi is within the above GOOD_LINK_RSSI_RANGE.
-     *      targetCount = sample_count[i] .
-     * <p>
-     * While WiFi is being avoided, we keep monitoring its signal strength.
-     * Good link notification is sent when we see current RSSI >= targetRSSI
-     * for targetCount consecutive times.
-     * <p>
-     * Index i is incremented each time after a poor link detection.
-     * Index i is decreased to at most k if the last poor link was at lease reduce_time[k] ago.
-     * <p>
-     * Intuitively, larger index i makes it more difficult to get back to WiFi, avoiding flapping.
-     * In experiments, (+9 dB / 30 counts) makes it quite difficult to achieve.
-     * Avoid using it unless flapping is really bad (say, last poor link is < 1 min ago).
-     */
-    private static final GoodLinkTarget[] GOOD_LINK_TARGET = {
-        /*                  rssi_adj,       sample_count,   reduce_time */
-        new GoodLinkTarget( 0,              3,              30 * 60000   ),
-        new GoodLinkTarget( 3,              5,              5  * 60000   ),
-        new GoodLinkTarget( 6,              10,             1  * 60000   ),
-        new GoodLinkTarget( 9,              30,             0  * 60000   ),
-    };
-
-    /**
-     * The max time to avoid a BSSID, to prevent avoiding forever.
-     * If current RSSI is at least min_rssi[i], the max avoidance time is at most max_time[i]
-     * <p>
-     * It is unusual to experience high packet loss at high RSSI. Something unusual must be
-     * happening (e.g. strong interference). For higher signal strengths, we set the avoidance
-     * time to be low to allow for quick turn around from temporary interference.
-     * <p>
-     * See {@link BssidStatistics#poorLinkDetected}.
-     */
-    private static final MaxAvoidTime[] MAX_AVOID_TIME = {
-        /*                  max_time,           min_rssi */
-        new MaxAvoidTime(   30 * 60000,         -200      ),
-        new MaxAvoidTime(   5  * 60000,         -70       ),
-        new MaxAvoidTime(   0  * 60000,         -55       ),
-    };
-
-    /* Framework related */
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private WifiManager mWifiManager;
-    private IntentFilter mIntentFilter;
-    private BroadcastReceiver mBroadcastReceiver;
-    private AsyncChannel mWsmChannel = new AsyncChannel();
-    private WifiInfo mWifiInfo;
-    private LinkProperties mLinkProperties;
-
-    /* System settingss related */
-    private static boolean sWifiOnly = false;
-    private boolean mPoorNetworkDetectionEnabled;
-
-    /* Poor link detection related */
-    private LruCache<String, BssidStatistics> mBssidCache =
-            new LruCache<String, BssidStatistics>(BSSID_STAT_CACHE_SIZE);
-    private int mRssiFetchToken = 0;
-    private int mCurrentSignalLevel;
-    private BssidStatistics mCurrentBssid;
-    private VolumeWeightedEMA mCurrentLoss;
-    private boolean mIsScreenOn = true;
-    private static double sPresetLoss[];
-
-    /* WiFi watchdog state machine related */
-    private DefaultState mDefaultState = new DefaultState();
-    private WatchdogDisabledState mWatchdogDisabledState = new WatchdogDisabledState();
-    private WatchdogEnabledState mWatchdogEnabledState = new WatchdogEnabledState();
-    private NotConnectedState mNotConnectedState = new NotConnectedState();
-    private VerifyingLinkState mVerifyingLinkState = new VerifyingLinkState();
-    private ConnectedState mConnectedState = new ConnectedState();
-    private OnlineWatchState mOnlineWatchState = new OnlineWatchState();
-    private LinkMonitoringState mLinkMonitoringState = new LinkMonitoringState();
-    private OnlineState mOnlineState = new OnlineState();
-
-    /**
-     * STATE MAP
-     *          Default
-     *         /       \
-     * Disabled      Enabled
-     *             /     \     \
-     * NotConnected  Verifying  Connected
-     *                         /---------\
-     *                       (all other states)
-     */
-    private WifiWatchdogStateMachine(Context context) {
-        super("WifiWatchdogStateMachine");
-        mContext = context;
-        mContentResolver = context.getContentResolver();
-        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        mWsmChannel.connectSync(mContext, getHandler(),
-                mWifiManager.getWifiStateMachineMessenger());
-
-        setupNetworkReceiver();
-
-        // the content observer to listen needs a handler
-        registerForSettingsChanges();
-        registerForWatchdogToggle();
-        addState(mDefaultState);
-            addState(mWatchdogDisabledState, mDefaultState);
-            addState(mWatchdogEnabledState, mDefaultState);
-                addState(mNotConnectedState, mWatchdogEnabledState);
-                addState(mVerifyingLinkState, mWatchdogEnabledState);
-                addState(mConnectedState, mWatchdogEnabledState);
-                    addState(mOnlineWatchState, mConnectedState);
-                    addState(mLinkMonitoringState, mConnectedState);
-                    addState(mOnlineState, mConnectedState);
-
-        if (isWatchdogEnabled()) {
-            setInitialState(mNotConnectedState);
-        } else {
-            setInitialState(mWatchdogDisabledState);
-        }
-        setLogRecSize(25);
-        setLogOnlyTransitions(true);
-        updateSettings();
-    }
-
-    public static WifiWatchdogStateMachine makeWifiWatchdogStateMachine(Context context) {
-        ContentResolver contentResolver = context.getContentResolver();
-
-        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        sWifiOnly = (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false);
-
-        // Watchdog is always enabled. Poor network detection can be seperately turned on/off
-        // TODO: Remove this setting & clean up state machine since we always have
-        // watchdog in an enabled state
-        putSettingsGlobalBoolean(contentResolver, Settings.Global.WIFI_WATCHDOG_ON, true);
-
-        WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context);
-        wwsm.start();
-        return wwsm;
-    }
-
-    private void setupNetworkReceiver() {
-        mBroadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                String action = intent.getAction();
-                if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
-                    obtainMessage(EVENT_RSSI_CHANGE,
-                            intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200), 0).sendToTarget();
-                } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) {
-                    sendMessage(EVENT_SUPPLICANT_STATE_CHANGE, intent);
-                } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
-                    sendMessage(EVENT_NETWORK_STATE_CHANGE, intent);
-                } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
-                    sendMessage(EVENT_SCREEN_ON);
-                } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
-                    sendMessage(EVENT_SCREEN_OFF);
-                } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
-                    sendMessage(EVENT_WIFI_RADIO_STATE_CHANGE,intent.getIntExtra(
-                            WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN));
-                }
-            }
-        };
-
-        mIntentFilter = new IntentFilter();
-        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
-        mIntentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
-        mIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
-        mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
-        mContext.registerReceiver(mBroadcastReceiver, mIntentFilter);
-    }
-
-    /**
-     * Observes the watchdog on/off setting, and takes action when changed.
-     */
-    private void registerForWatchdogToggle() {
-        ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
-            @Override
-            public void onChange(boolean selfChange) {
-                sendMessage(EVENT_WATCHDOG_TOGGLED);
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.WIFI_WATCHDOG_ON),
-                false, contentObserver);
-    }
-
-    /**
-     * Observes watchdogs secure setting changes.
-     */
-    private void registerForSettingsChanges() {
-        ContentObserver contentObserver = new ContentObserver(this.getHandler()) {
-            @Override
-            public void onChange(boolean selfChange) {
-                sendMessage(EVENT_WATCHDOG_SETTINGS_CHANGE);
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED),
-                false, contentObserver);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
-        pw.println("mWifiInfo: [" + mWifiInfo + "]");
-        pw.println("mLinkProperties: [" + mLinkProperties + "]");
-        pw.println("mCurrentSignalLevel: [" + mCurrentSignalLevel + "]");
-        pw.println("mPoorNetworkDetectionEnabled: [" + mPoorNetworkDetectionEnabled + "]");
-    }
-
-    private boolean isWatchdogEnabled() {
-        boolean ret = getSettingsGlobalBoolean(
-                mContentResolver, Settings.Global.WIFI_WATCHDOG_ON, true);
-        if (DBG) logd("Watchdog enabled " + ret);
-        return ret;
-    }
-
-    private void updateSettings() {
-        if (DBG) logd("Updating secure settings");
-
-        // disable poor network avoidance
-        if (sWifiOnly) {
-            logd("Disabling poor network avoidance for wi-fi only device");
-            mPoorNetworkDetectionEnabled = false;
-        } else {
-            mPoorNetworkDetectionEnabled = getSettingsGlobalBoolean(mContentResolver,
-                    Settings.Global.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED,
-                    DEFAULT_POOR_NETWORK_AVOIDANCE_ENABLED);
-        }
-    }
-
-    /**
-     * Default state, guard for unhandled messages.
-     */
-    class DefaultState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_WATCHDOG_SETTINGS_CHANGE:
-                    updateSettings();
-                    if (DBG) logd("Updating wifi-watchdog secure settings");
-                    break;
-                case EVENT_RSSI_CHANGE:
-                    mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
-                    break;
-                case EVENT_WIFI_RADIO_STATE_CHANGE:
-                case EVENT_NETWORK_STATE_CHANGE:
-                case EVENT_SUPPLICANT_STATE_CHANGE:
-                case EVENT_BSSID_CHANGE:
-                case CMD_RSSI_FETCH:
-                case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
-                case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
-                    // ignore
-                    break;
-                case EVENT_SCREEN_ON:
-                    mIsScreenOn = true;
-                    break;
-                case EVENT_SCREEN_OFF:
-                    mIsScreenOn = false;
-                    break;
-                default:
-                    loge("Unhandled message " + msg + " in state " + getCurrentState().getName());
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-    /**
-     * WiFi watchdog is disabled by the setting.
-     */
-    class WatchdogDisabledState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_WATCHDOG_TOGGLED:
-                    if (isWatchdogEnabled())
-                        transitionTo(mNotConnectedState);
-                    return HANDLED;
-                case EVENT_NETWORK_STATE_CHANGE:
-                    Intent intent = (Intent) msg.obj;
-                    NetworkInfo networkInfo = (NetworkInfo)
-                            intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-
-                    switch (networkInfo.getDetailedState()) {
-                        case VERIFYING_POOR_LINK:
-                            if (DBG) logd("Watchdog disabled, verify link");
-                            sendLinkStatusNotification(true);
-                            break;
-                        default:
-                            break;
-                    }
-                    break;
-            }
-            return NOT_HANDLED;
-        }
-    }
-
-    /**
-     * WiFi watchdog is enabled by the setting.
-     */
-    class WatchdogEnabledState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            Intent intent;
-            switch (msg.what) {
-                case EVENT_WATCHDOG_TOGGLED:
-                    if (!isWatchdogEnabled())
-                        transitionTo(mWatchdogDisabledState);
-                    break;
-
-                case EVENT_NETWORK_STATE_CHANGE:
-                    intent = (Intent) msg.obj;
-                    NetworkInfo networkInfo =
-                            (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
-                    if (DBG) logd("Network state change " + networkInfo.getDetailedState());
-
-                    mWifiInfo = (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
-                    updateCurrentBssid(mWifiInfo != null ? mWifiInfo.getBSSID() : null);
-
-                    switch (networkInfo.getDetailedState()) {
-                        case VERIFYING_POOR_LINK:
-                            mLinkProperties = (LinkProperties) intent.getParcelableExtra(
-                                    WifiManager.EXTRA_LINK_PROPERTIES);
-                            if (mPoorNetworkDetectionEnabled) {
-                                if (mWifiInfo == null || mCurrentBssid == null) {
-                                    loge("Ignore, wifiinfo " + mWifiInfo +" bssid " + mCurrentBssid);
-                                    sendLinkStatusNotification(true);
-                                } else {
-                                    transitionTo(mVerifyingLinkState);
-                                }
-                            } else {
-                                sendLinkStatusNotification(true);
-                            }
-                            break;
-                        case CONNECTED:
-                            transitionTo(mOnlineWatchState);
-                            break;
-                        default:
-                            transitionTo(mNotConnectedState);
-                            break;
-                    }
-                    break;
-
-                case EVENT_SUPPLICANT_STATE_CHANGE:
-                    intent = (Intent) msg.obj;
-                    SupplicantState supplicantState = (SupplicantState) intent.getParcelableExtra(
-                            WifiManager.EXTRA_NEW_STATE);
-                    if (supplicantState == SupplicantState.COMPLETED) {
-                        mWifiInfo = mWifiManager.getConnectionInfo();
-                        updateCurrentBssid(mWifiInfo.getBSSID());
-                    }
-                    break;
-
-                case EVENT_WIFI_RADIO_STATE_CHANGE:
-                    if (msg.arg1 == WifiManager.WIFI_STATE_DISABLING) {
-                        transitionTo(mNotConnectedState);
-                    }
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-
-            return HANDLED;
-        }
-    }
-
-    /**
-     * WiFi is disconnected.
-     */
-    class NotConnectedState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-    }
-
-    /**
-     * WiFi is connected, but waiting for good link detection message.
-     */
-    class VerifyingLinkState extends State {
-
-        private int mSampleCount;
-
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            mSampleCount = 0;
-            mCurrentBssid.newLinkDetected();
-            sendMessage(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0));
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_WATCHDOG_SETTINGS_CHANGE:
-                    updateSettings();
-                    if (!mPoorNetworkDetectionEnabled) {
-                        sendLinkStatusNotification(true);
-                    }
-                    break;
-
-                case EVENT_BSSID_CHANGE:
-                    transitionTo(mVerifyingLinkState);
-                    break;
-
-                case CMD_RSSI_FETCH:
-                    if (msg.arg1 == mRssiFetchToken) {
-                        mWsmChannel.sendMessage(WifiManager.RSSI_PKTCNT_FETCH);
-                        sendMessageDelayed(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0),
-                                LINK_SAMPLING_INTERVAL_MS);
-                    }
-                    break;
-
-                case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
-                    RssiPacketCountInfo info = (RssiPacketCountInfo) msg.obj;
-                    int rssi = info.rssi;
-                    if (DBG) logd("Fetch RSSI succeed, rssi=" + rssi);
-
-                    long time = mCurrentBssid.mBssidAvoidTimeMax - SystemClock.elapsedRealtime();
-                    if (time <= 0) {
-                        // max avoidance time is met
-                        if (DBG) logd("Max avoid time elapsed");
-                        sendLinkStatusNotification(true);
-                    } else {
-                        if (rssi >= mCurrentBssid.mGoodLinkTargetRssi) {
-                            if (++mSampleCount >= mCurrentBssid.mGoodLinkTargetCount) {
-                                // link is good again
-                                if (DBG) logd("Good link detected, rssi=" + rssi);
-                                mCurrentBssid.mBssidAvoidTimeMax = 0;
-                                sendLinkStatusNotification(true);
-                            }
-                        } else {
-                            mSampleCount = 0;
-                            if (DBG) logd("Link is still poor, time left=" + time);
-                        }
-                    }
-                    break;
-
-                case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
-                    if (DBG) logd("RSSI_FETCH_FAILED");
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    /**
-     * WiFi is connected and link is verified.
-     */
-    class ConnectedState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_WATCHDOG_SETTINGS_CHANGE:
-                    updateSettings();
-                    if (mPoorNetworkDetectionEnabled) {
-                        transitionTo(mOnlineWatchState);
-                    } else {
-                        transitionTo(mOnlineState);
-                    }
-                    return HANDLED;
-            }
-            return NOT_HANDLED;
-        }
-    }
-
-    /**
-     * RSSI is high enough and don't need link monitoring.
-     */
-    class OnlineWatchState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            if (mPoorNetworkDetectionEnabled) {
-                // treat entry as an rssi change
-                handleRssiChange();
-            } else {
-                transitionTo(mOnlineState);
-            }
-        }
-
-        private void handleRssiChange() {
-            if (mCurrentSignalLevel <= LINK_MONITOR_LEVEL_THRESHOLD && mCurrentBssid != null) {
-                transitionTo(mLinkMonitoringState);
-            } else {
-                // stay here
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_RSSI_CHANGE:
-                    mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
-                    handleRssiChange();
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    /**
-     * Keep sampling the link and monitor any poor link situation.
-     */
-    class LinkMonitoringState extends State {
-
-        private int mSampleCount;
-
-        private int mLastRssi;
-        private int mLastTxGood;
-        private int mLastTxBad;
-
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            mSampleCount = 0;
-            mCurrentLoss = new VolumeWeightedEMA(EXP_COEFFICIENT_MONITOR);
-            sendMessage(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0));
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_RSSI_CHANGE:
-                    mCurrentSignalLevel = calculateSignalLevel(msg.arg1);
-                    if (mCurrentSignalLevel <= LINK_MONITOR_LEVEL_THRESHOLD) {
-                        // stay here;
-                    } else {
-                        // we don't need frequent RSSI monitoring any more
-                        transitionTo(mOnlineWatchState);
-                    }
-                    break;
-
-                case EVENT_BSSID_CHANGE:
-                    transitionTo(mLinkMonitoringState);
-                    break;
-
-                case CMD_RSSI_FETCH:
-                    if (!mIsScreenOn) {
-                        transitionTo(mOnlineState);
-                    } else if (msg.arg1 == mRssiFetchToken) {
-                        mWsmChannel.sendMessage(WifiManager.RSSI_PKTCNT_FETCH);
-                        sendMessageDelayed(obtainMessage(CMD_RSSI_FETCH, ++mRssiFetchToken, 0),
-                                LINK_SAMPLING_INTERVAL_MS);
-                    }
-                    break;
-
-                case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
-                    RssiPacketCountInfo info = (RssiPacketCountInfo) msg.obj;
-                    int rssi = info.rssi;
-                    int mrssi = (mLastRssi + rssi) / 2;
-                    int txbad = info.txbad;
-                    int txgood = info.txgood;
-                    if (DBG) logd("Fetch RSSI succeed, rssi=" + rssi + " mrssi=" + mrssi + " txbad="
-                            + txbad + " txgood=" + txgood);
-
-                    // skip the first data point as we want incremental values
-                    long now = SystemClock.elapsedRealtime();
-                    if (now - mCurrentBssid.mLastTimeSample < LINK_SAMPLING_INTERVAL_MS * 2) {
-
-                        // update packet loss statistics
-                        int dbad = txbad - mLastTxBad;
-                        int dgood = txgood - mLastTxGood;
-                        int dtotal = dbad + dgood;
-
-                        if (dtotal > 0) {
-                            // calculate packet loss in the last sampling interval
-                            double loss = ((double) dbad) / ((double) dtotal);
-
-                            mCurrentLoss.update(loss, dtotal);
-
-                            if (DBG) {
-                                DecimalFormat df = new DecimalFormat("#.##");
-                                logd("Incremental loss=" + dbad + "/" + dtotal + " Current loss="
-                                        + df.format(mCurrentLoss.mValue * 100) + "% volume="
-                                        + df.format(mCurrentLoss.mVolume));
-                            }
-
-                            mCurrentBssid.updateLoss(mrssi, loss, dtotal);
-
-                            // check for high packet loss and send poor link notification
-                            if (mCurrentLoss.mValue > POOR_LINK_LOSS_THRESHOLD
-                                    && mCurrentLoss.mVolume > POOR_LINK_MIN_VOLUME) {
-                                if (++mSampleCount >= POOR_LINK_SAMPLE_COUNT)
-                                    if (mCurrentBssid.poorLinkDetected(rssi)) {
-                                        sendLinkStatusNotification(false);
-                                        ++mRssiFetchToken;
-                                    }
-                            } else {
-                                mSampleCount = 0;
-                            }
-                        }
-                    }
-
-                    mCurrentBssid.mLastTimeSample = now;
-                    mLastTxBad = txbad;
-                    mLastTxGood = txgood;
-                    mLastRssi = rssi;
-                    break;
-
-                case WifiManager.RSSI_PKTCNT_FETCH_FAILED:
-                    // can happen if we are waiting to get a disconnect notification
-                    if (DBG) logd("RSSI_FETCH_FAILED");
-                    break;
-
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-   }
-
-    /**
-     * Child state of ConnectedState indicating that we are online and there is nothing to do.
-     */
-    class OnlineState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_SCREEN_ON:
-                    mIsScreenOn = true;
-                    if (mPoorNetworkDetectionEnabled)
-                        transitionTo(mOnlineWatchState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    private void updateCurrentBssid(String bssid) {
-        if (DBG) logd("Update current BSSID to " + (bssid != null ? bssid : "null"));
-
-        // if currently not connected, then set current BSSID to null
-        if (bssid == null) {
-            if (mCurrentBssid == null) return;
-            mCurrentBssid = null;
-            if (DBG) logd("BSSID changed");
-            sendMessage(EVENT_BSSID_CHANGE);
-            return;
-        }
-
-        // if it is already the current BSSID, then done
-        if (mCurrentBssid != null && bssid.equals(mCurrentBssid.mBssid)) return;
-
-        // search for the new BSSID in the cache, add to cache if not found
-        mCurrentBssid = mBssidCache.get(bssid);
-        if (mCurrentBssid == null) {
-            mCurrentBssid = new BssidStatistics(bssid);
-            mBssidCache.put(bssid, mCurrentBssid);
-        }
-
-        // send BSSID change notification
-        if (DBG) logd("BSSID changed");
-        sendMessage(EVENT_BSSID_CHANGE);
-    }
-
-    private int calculateSignalLevel(int rssi) {
-        int signalLevel = WifiManager.calculateSignalLevel(rssi, WifiManager.RSSI_LEVELS);
-        if (DBG)
-            logd("RSSI current: " + mCurrentSignalLevel + " new: " + rssi + ", " + signalLevel);
-        return signalLevel;
-    }
-
-    private void sendLinkStatusNotification(boolean isGood) {
-        if (DBG) logd("########################################");
-        if (isGood) {
-            mWsmChannel.sendMessage(GOOD_LINK_DETECTED);
-            if (mCurrentBssid != null) {
-                mCurrentBssid.mLastTimeGood = SystemClock.elapsedRealtime();
-            }
-            if (DBG) logd("Good link notification is sent");
-        } else {
-            mWsmChannel.sendMessage(POOR_LINK_DETECTED);
-            if (mCurrentBssid != null) {
-                mCurrentBssid.mLastTimePoor = SystemClock.elapsedRealtime();
-            }
-            logd("Poor link notification is sent");
-        }
-    }
-
-    /**
-     * Convenience function for retrieving a single secure settings value as a
-     * boolean. Note that internally setting values are always stored as
-     * strings; this function converts the string to a boolean for you. The
-     * default value will be returned if the setting is not defined or not a
-     * valid boolean.
-     *
-     * @param cr The ContentResolver to access.
-     * @param name The name of the setting to retrieve.
-     * @param def Value to return if the setting is not defined.
-     * @return The setting's current value, or 'def' if it is not defined or not
-     *         a valid boolean.
-     */
-    private static boolean getSettingsGlobalBoolean(ContentResolver cr, String name, boolean def) {
-        return Settings.Global.getInt(cr, name, def ? 1 : 0) == 1;
-    }
-
-    /**
-     * Convenience function for updating a single settings value as an integer.
-     * This will either create a new entry in the table if the given name does
-     * not exist, or modify the value of the existing row with that name. Note
-     * that internally setting values are always stored as strings, so this
-     * function converts the given value to a string before storing it.
-     *
-     * @param cr The ContentResolver to access.
-     * @param name The name of the setting to modify.
-     * @param value The new value for the setting.
-     * @return true if the value was set, false on database errors
-     */
-    private static boolean putSettingsGlobalBoolean(ContentResolver cr, String name, boolean value) {
-        return Settings.Global.putInt(cr, name, value ? 1 : 0);
-    }
-
-    /**
-     * Bundle of good link count parameters
-     */
-    private static class GoodLinkTarget {
-        public final int RSSI_ADJ_DBM;
-        public final int SAMPLE_COUNT;
-        public final int REDUCE_TIME_MS;
-        public GoodLinkTarget(int adj, int count, int time) {
-            RSSI_ADJ_DBM = adj;
-            SAMPLE_COUNT = count;
-            REDUCE_TIME_MS = time;
-        }
-    }
-
-    /**
-     * Bundle of max avoidance time parameters
-     */
-    private static class MaxAvoidTime {
-        public final int TIME_MS;
-        public final int MIN_RSSI_DBM;
-        public MaxAvoidTime(int time, int rssi) {
-            TIME_MS = time;
-            MIN_RSSI_DBM = rssi;
-        }
-    }
-
-    /**
-     * Volume-weighted Exponential Moving Average (V-EMA)
-     *    - volume-weighted:  each update has its own weight (number of packets)
-     *    - exponential:      O(1) time and O(1) space for both update and query
-     *    - moving average:   reflect most recent results and expire old ones
-     */
-    private class VolumeWeightedEMA {
-        private double mValue;
-        private double mVolume;
-        private double mProduct;
-        private final double mAlpha;
-
-        public VolumeWeightedEMA(double coefficient) {
-            mValue   = 0.0;
-            mVolume  = 0.0;
-            mProduct = 0.0;
-            mAlpha   = coefficient;
-        }
-
-        public void update(double newValue, int newVolume) {
-            if (newVolume <= 0) return;
-            // core update formulas
-            double newProduct = newValue * newVolume;
-            mProduct = mAlpha * newProduct + (1 - mAlpha) * mProduct;
-            mVolume  = mAlpha * newVolume  + (1 - mAlpha) * mVolume;
-            mValue   = mProduct / mVolume;
-        }
-    }
-
-    /**
-     * Record (RSSI -> pakce loss %) mappings of one BSSID
-     */
-    private class BssidStatistics {
-
-        /* MAC address of this BSSID */
-        private final String mBssid;
-
-        /* RSSI -> packet loss % mappings */
-        private VolumeWeightedEMA[] mEntries;
-        private int mRssiBase;
-        private int mEntriesSize;
-
-        /* Target to send good link notification, set when poor link is detected */
-        private int mGoodLinkTargetRssi;
-        private int mGoodLinkTargetCount;
-
-        /* Index of GOOD_LINK_TARGET array */
-        private int mGoodLinkTargetIndex;
-
-        /* Timestamps of some last events */
-        private long mLastTimeSample;
-        private long mLastTimeGood;
-        private long mLastTimePoor;
-
-        /* Max time to avoid this BSSID */
-        private long mBssidAvoidTimeMax;
-
-        /**
-         * Constructor
-         *
-         * @param bssid is the address of this BSSID
-         */
-        public BssidStatistics(String bssid) {
-            this.mBssid = bssid;
-            mRssiBase = BSSID_STAT_RANGE_LOW_DBM;
-            mEntriesSize = BSSID_STAT_RANGE_HIGH_DBM - BSSID_STAT_RANGE_LOW_DBM + 1;
-            mEntries = new VolumeWeightedEMA[mEntriesSize];
-            for (int i = 0; i < mEntriesSize; i++)
-                mEntries[i] = new VolumeWeightedEMA(EXP_COEFFICIENT_RECORD);
-        }
-
-        /**
-         * Update this BSSID cache
-         *
-         * @param rssi is the RSSI
-         * @param value is the new instant loss value at this RSSI
-         * @param volume is the volume for this single update
-         */
-        public void updateLoss(int rssi, double value, int volume) {
-            if (volume <= 0) return;
-            int index = rssi - mRssiBase;
-            if (index < 0 || index >= mEntriesSize) return;
-            mEntries[index].update(value, volume);
-            if (DBG) {
-                DecimalFormat df = new DecimalFormat("#.##");
-                logd("Cache updated: loss[" + rssi + "]=" + df.format(mEntries[index].mValue * 100)
-                        + "% volume=" + df.format(mEntries[index].mVolume));
-            }
-        }
-
-        /**
-         * Get preset loss if the cache has insufficient data, observed from experiments.
-         *
-         * @param rssi is the input RSSI
-         * @return preset loss of the given RSSI
-         */
-        public double presetLoss(int rssi) {
-            if (rssi <= -90) return 1.0;
-            if (rssi > 0) return 0.0;
-
-            if (sPresetLoss == null) {
-                // pre-calculate all preset losses only once, then reuse them
-                final int size = 90;
-                sPresetLoss = new double[size];
-                for (int i = 0; i < size; i++) sPresetLoss[i] = 1.0 / Math.pow(90 - i, 1.5);
-            }
-            return sPresetLoss[-rssi];
-        }
-
-        /**
-         * A poor link is detected, calculate a target RSSI to bring WiFi back.
-         *
-         * @param rssi is the current RSSI
-         * @return true iff the current BSSID should be avoided
-         */
-        public boolean poorLinkDetected(int rssi) {
-            if (DBG) logd("Poor link detected, rssi=" + rssi);
-
-            long now = SystemClock.elapsedRealtime();
-            long lastGood = now - mLastTimeGood;
-            long lastPoor = now - mLastTimePoor;
-
-            // reduce the difficulty of good link target if last avoidance was long time ago
-            while (mGoodLinkTargetIndex > 0
-                    && lastPoor >= GOOD_LINK_TARGET[mGoodLinkTargetIndex - 1].REDUCE_TIME_MS)
-                mGoodLinkTargetIndex--;
-            mGoodLinkTargetCount = GOOD_LINK_TARGET[mGoodLinkTargetIndex].SAMPLE_COUNT;
-
-            // scan for a target RSSI at which the link is good
-            int from = rssi + GOOD_LINK_RSSI_RANGE_MIN;
-            int to = rssi + GOOD_LINK_RSSI_RANGE_MAX;
-            mGoodLinkTargetRssi = findRssiTarget(from, to, GOOD_LINK_LOSS_THRESHOLD);
-            mGoodLinkTargetRssi += GOOD_LINK_TARGET[mGoodLinkTargetIndex].RSSI_ADJ_DBM;
-            if (mGoodLinkTargetIndex < GOOD_LINK_TARGET.length - 1) mGoodLinkTargetIndex++;
-
-            // calculate max avoidance time to prevent avoiding forever
-            int p = 0, pmax = MAX_AVOID_TIME.length - 1;
-            while (p < pmax && rssi >= MAX_AVOID_TIME[p + 1].MIN_RSSI_DBM) p++;
-            long avoidMax = MAX_AVOID_TIME[p].TIME_MS;
-
-            // don't avoid if max avoidance time is 0 (RSSI is super high)
-            if (avoidMax <= 0) return false;
-
-            // set max avoidance time, send poor link notification
-            mBssidAvoidTimeMax = now + avoidMax;
-
-            if (DBG) logd("goodRssi=" + mGoodLinkTargetRssi + " goodCount=" + mGoodLinkTargetCount
-                    + " lastGood=" + lastGood + " lastPoor=" + lastPoor + " avoidMax=" + avoidMax);
-
-            return true;
-        }
-
-        /**
-         * A new BSSID is connected, recalculate target RSSI threshold
-         */
-        public void newLinkDetected() {
-            // if this BSSID is currently being avoided, the reuse those values
-            if (mBssidAvoidTimeMax > 0) {
-                if (DBG) logd("Previous avoidance still in effect, rssi=" + mGoodLinkTargetRssi
-                        + " count=" + mGoodLinkTargetCount);
-                return;
-            }
-
-            // calculate a new RSSI threshold for new link verifying
-            int from = BSSID_STAT_RANGE_LOW_DBM;
-            int to = BSSID_STAT_RANGE_HIGH_DBM;
-            mGoodLinkTargetRssi = findRssiTarget(from, to, GOOD_LINK_LOSS_THRESHOLD);
-            mGoodLinkTargetCount = 1;
-            mBssidAvoidTimeMax = SystemClock.elapsedRealtime() + MAX_AVOID_TIME[0].TIME_MS;
-            if (DBG) logd("New link verifying target set, rssi=" + mGoodLinkTargetRssi + " count="
-                    + mGoodLinkTargetCount);
-        }
-
-        /**
-         * Return the first RSSI within the range where loss[rssi] < threshold
-         *
-         * @param from start scanning from this RSSI
-         * @param to stop scanning at this RSSI
-         * @param threshold target threshold for scanning
-         * @return target RSSI
-         */
-        public int findRssiTarget(int from, int to, double threshold) {
-            from -= mRssiBase;
-            to -= mRssiBase;
-            int emptyCount = 0;
-            int d = from < to ? 1 : -1;
-            for (int i = from; i != to; i += d)
-                // don't use a data point if it volume is too small (statistically unreliable)
-                if (i >= 0 && i < mEntriesSize && mEntries[i].mVolume > 1.0) {
-                    emptyCount = 0;
-                    if (mEntries[i].mValue < threshold) {
-                        // scan target found
-                        int rssi = mRssiBase + i;
-                        if (DBG) {
-                            DecimalFormat df = new DecimalFormat("#.##");
-                            logd("Scan target found: rssi=" + rssi + " threshold="
-                                    + df.format(threshold * 100) + "% value="
-                                    + df.format(mEntries[i].mValue * 100) + "% volume="
-                                    + df.format(mEntries[i].mVolume));
-                        }
-                        return rssi;
-                    }
-                } else if (++emptyCount >= BSSID_STAT_EMPTY_COUNT) {
-                    // cache has insufficient data around this RSSI, use preset loss instead
-                    int rssi = mRssiBase + i;
-                    double lossPreset = presetLoss(rssi);
-                    if (lossPreset < threshold) {
-                        if (DBG) {
-                            DecimalFormat df = new DecimalFormat("#.##");
-                            logd("Scan target found: rssi=" + rssi + " threshold="
-                                    + df.format(threshold * 100) + "% value="
-                                    + df.format(lossPreset * 100) + "% volume=preset");
-                        }
-                        return rssi;
-                    }
-                }
-
-            return mRssiBase + to;
-        }
-    }
-}
diff --git a/wifi/java/android/net/wifi/WpsInfo.java b/wifi/java/android/net/wifi/WpsInfo.java
index b80df21..2ad4ad0 100644
--- a/wifi/java/android/net/wifi/WpsInfo.java
+++ b/wifi/java/android/net/wifi/WpsInfo.java
@@ -19,8 +19,6 @@
 import android.os.Parcelable;
 import android.os.Parcel;
 
-import java.util.BitSet;
-
 /**
  * A class representing Wi-Fi Protected Setup
  *
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index 482d9cb..b019fd7 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -60,7 +60,8 @@
         wps.setup = WpsInfo.PBC;
     }
 
-    void invalidate() {
+    /** @hide */
+    public void invalidate() {
         deviceAddress = "";
     }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
index 7196c1b..a0cb035 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java
@@ -126,7 +126,7 @@
         "config_methods=(0x[0-9a-fA-F]+) " +
         "dev_capab=(0x[0-9a-fA-F]+) " +
         "group_capab=(0x[0-9a-fA-F]+)" +
-        "( wfd_dev_info=0x000006([0-9a-fA-F]{12}))?"
+        "( wfd_dev_info=0x([0-9a-fA-F]{12}))?"
     );
 
     /** 2 token device address pattern
@@ -274,7 +274,7 @@
     }
 
     /** Updates details obtained from supplicant @hide */
-    void updateSupplicantDetails(WifiP2pDevice device) {
+    public void updateSupplicantDetails(WifiP2pDevice device) {
         if (device == null) {
             throw new IllegalArgumentException("device is null");
         }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
index 0900351..3d0bb3d 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java
@@ -20,7 +20,6 @@
 import android.os.Parcel;
 import android.net.wifi.p2p.WifiP2pDevice;
 import android.text.TextUtils;
-import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -90,7 +89,7 @@
     }
 
     /** Only updates details fetched from the supplicant @hide */
-    void updateSupplicantDetails(WifiP2pDevice device) {
+    public void updateSupplicantDetails(WifiP2pDevice device) {
         validateDevice(device);
         WifiP2pDevice d = mDevices.get(device.deviceAddress);
         if (d != null) {
@@ -108,7 +107,7 @@
     }
 
     /** @hide */
-    void updateGroupCapability(String deviceAddress, int groupCapab) {
+    public void updateGroupCapability(String deviceAddress, int groupCapab) {
         validateDeviceAddress(deviceAddress);
         WifiP2pDevice d = mDevices.get(deviceAddress);
         if (d != null) {
@@ -117,7 +116,7 @@
     }
 
     /** @hide */
-    void updateStatus(String deviceAddress, int status) {
+    public void updateStatus(String deviceAddress, int status) {
         validateDeviceAddress(deviceAddress);
         WifiP2pDevice d = mDevices.get(deviceAddress);
         if (d != null) {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
index 98f0972..64bb00b 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroupList.java
@@ -42,11 +42,13 @@
         public void onDeleteGroup(int netId);
     }
 
-    WifiP2pGroupList() {
+    /** @hide */
+    public WifiP2pGroupList() {
         this(null, null);
     }
 
-    WifiP2pGroupList(WifiP2pGroupList source, GroupDeleteListener listener) {
+    /** @hide */
+    public WifiP2pGroupList(WifiP2pGroupList source, GroupDeleteListener listener) {
         mListener = listener;
         mGroups = new LruCache<Integer, WifiP2pGroup>(CREDENTIAL_MAX_NUM) {
             @Override
@@ -78,8 +80,9 @@
      * Add the specified group to this group list.
      *
      * @param group
+     * @hide
      */
-    void add(WifiP2pGroup group) {
+    public void add(WifiP2pGroup group) {
         mGroups.put(group.getNetworkId(), group);
     }
 
@@ -87,8 +90,9 @@
      * Remove the group with the specified network id from this group list.
      *
      * @param netId
+     * @hide
      */
-    void remove(int netId) {
+    public void remove(int netId) {
         mGroups.remove(netId);
     }
 
@@ -103,8 +107,9 @@
 
     /**
      * Clear the group.
+     * @hide
      */
-    boolean clear() {
+    public boolean clear() {
         if (mGroups.size() == 0) return false;
         isClearCalled = true;
         mGroups.evictAll();
@@ -120,8 +125,9 @@
      *
      * @param deviceAddress p2p device address.
      * @return the network id. if not found, return -1.
+     * @hide
      */
-    int getNetworkId(String deviceAddress) {
+    public int getNetworkId(String deviceAddress) {
         if (deviceAddress == null) return -1;
 
         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
@@ -142,8 +148,9 @@
      * @param deviceAddress p2p device address.
      * @param ssid ssid.
      * @return the network id. if not found, return -1.
+     * @hide
      */
-    int getNetworkId(String deviceAddress, String ssid) {
+    public int getNetworkId(String deviceAddress, String ssid) {
         if (deviceAddress == null || ssid == null) {
             return -1;
         }
@@ -166,8 +173,9 @@
      *
      * @param netId network id.
      * @return the address. if not found, return null.
+     * @hide
      */
-    String getOwnerAddr(int netId) {
+    public String getOwnerAddr(int netId) {
         WifiP2pGroup grp = mGroups.get(netId);
         if (grp != null) {
             return grp.getOwner().deviceAddress;
@@ -182,8 +190,9 @@
      *
      * @param netId network id.
      * @return true if the specified network id is present in this group list.
+     * @hide
      */
-    boolean contains(int netId) {
+    public boolean contains(int netId) {
         final Collection<WifiP2pGroup> groups = mGroups.snapshot().values();
         for (WifiP2pGroup grp: groups) {
             if (netId == grp.getNetworkId()) {
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 4988b92..3ed2406 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -19,8 +19,6 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
 import android.net.wifi.WpsInfo;
 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pDnsSdServiceResponse;
@@ -29,16 +27,12 @@
 import android.net.wifi.p2p.nsd.WifiP2pServiceResponse;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceInfo;
 import android.net.wifi.p2p.nsd.WifiP2pUpnpServiceResponse;
-import android.os.Binder;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
 import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.WorkSource;
 import android.text.TextUtils;
 import android.util.Log;
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
index b3f34b4..98683cb 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pProvDiscEvent.java
@@ -16,10 +16,6 @@
 
 package android.net.wifi.p2p;
 
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.util.Log;
-
 /**
  * A class representing a Wi-Fi p2p provisional discovery request/response
  * See {@link #WifiP2pProvDiscEvent} for supported types
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
deleted file mode 100644
index 8b07208..0000000
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ /dev/null
@@ -1,2959 +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.net.wifi.p2p;
-
-import android.app.AlertDialog;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.net.IConnectivityManager;
-import android.net.ConnectivityManager;
-import android.net.DhcpResults;
-import android.net.DhcpStateMachine;
-import android.net.InterfaceConfiguration;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkInfo;
-import android.net.NetworkUtils;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiMonitor;
-import android.net.wifi.WifiNative;
-import android.net.wifi.WifiStateMachine;
-import android.net.wifi.WpsInfo;
-import android.net.wifi.p2p.WifiP2pGroupList.GroupDeleteListener;
-import android.net.wifi.p2p.nsd.WifiP2pServiceInfo;
-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;
-import android.os.HandlerThread;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.text.TextUtils;
-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.WindowManager;
-import android.widget.EditText;
-import android.widget.TextView;
-
-import com.android.internal.R;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.AsyncChannel;
-import com.android.internal.util.Protocol;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-
-
-/**
- * WifiP2pService includes a state machine to perform Wi-Fi p2p operations. Applications
- * communicate with this service to issue device discovery and connectivity requests
- * through the WifiP2pManager interface. The state machine communicates with the wifi
- * driver through wpa_supplicant and handles the event responses through WifiMonitor.
- *
- * Note that the term Wifi when used without a p2p suffix refers to the client mode
- * of Wifi operation
- * @hide
- */
-public class WifiP2pService extends IWifiP2pManager.Stub {
-    private static final String TAG = "WifiP2pService";
-    private static final boolean DBG = false;
-    private static final String NETWORKTYPE = "WIFI_P2P";
-
-    private Context mContext;
-    private String mInterface;
-    private Notification mNotification;
-
-    INetworkManagementService mNwService;
-    private DhcpStateMachine mDhcpStateMachine;
-
-    private P2pStateMachine mP2pStateMachine;
-    private AsyncChannel mReplyChannel = new AsyncChannel();
-    private AsyncChannel mWifiChannel;
-
-    private static final Boolean JOIN_GROUP = true;
-    private static final Boolean FORM_GROUP = false;
-
-    private static final Boolean RELOAD = true;
-    private static final Boolean NO_RELOAD = false;
-
-    /* Two minutes comes from the wpa_supplicant setting */
-    private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000;
-    private static int mGroupCreatingTimeoutIndex = 0;
-
-    private static final int DISABLE_P2P_WAIT_TIME_MS = 5 * 1000;
-    private static int mDisableP2pTimeoutIndex = 0;
-
-    /* Set a two minute discover timeout to avoid STA scans from being blocked */
-    private static final int DISCOVER_TIMEOUT_S = 120;
-
-    /* Idle time after a peer is gone when the group is torn down */
-    private static final int GROUP_IDLE_TIME_S = 10;
-
-    private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
-
-    /* Delayed message to timeout group creation */
-    public static final int GROUP_CREATING_TIMED_OUT        =   BASE + 1;
-
-    /* User accepted a peer request */
-    private static final int PEER_CONNECTION_USER_ACCEPT    =   BASE + 2;
-    /* User rejected a peer request */
-    private static final int PEER_CONNECTION_USER_REJECT    =   BASE + 3;
-    /* User wants to disconnect wifi in favour of p2p */
-    private static final int DROP_WIFI_USER_ACCEPT          =   BASE + 4;
-    /* User wants to keep his wifi connection and drop p2p */
-    private static final int DROP_WIFI_USER_REJECT          =   BASE + 5;
-    /* Delayed message to timeout p2p disable */
-    public static final int DISABLE_P2P_TIMED_OUT           =   BASE + 6;
-
-
-    /* Commands to the WifiStateMachine */
-    public static final int P2P_CONNECTION_CHANGED          =   BASE + 11;
-
-    /* These commands are used to temporarily disconnect wifi when we detect
-     * a frequency conflict which would make it impossible to have with p2p
-     * and wifi active at the same time.
-     *
-     * If the user chooses to disable wifi temporarily, we keep wifi disconnected
-     * until the p2p connection is done and terminated at which point we will
-     * bring back wifi up
-     *
-     * DISCONNECT_WIFI_REQUEST
-     *      msg.arg1 = 1 enables temporary disconnect and 0 disables it.
-     */
-    public static final int DISCONNECT_WIFI_REQUEST         =   BASE + 12;
-    public static final int DISCONNECT_WIFI_RESPONSE        =   BASE + 13;
-
-    public static final int SET_MIRACAST_MODE               =   BASE + 14;
-
-    // During dhcp (and perhaps other times) we can't afford to drop packets
-    // but Discovery will switch our channel enough we will.
-    //   msg.arg1 = ENABLED for blocking, DISABLED for resumed.
-    //   msg.arg2 = msg to send when blocked
-    //   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;
-
-    private final boolean mP2pSupported;
-
-    private WifiP2pDevice mThisDevice = new WifiP2pDevice();
-
-    /* When a group has been explicitly created by an app, we persist the group
-     * even after all clients have been disconnected until an explicit remove
-     * is invoked */
-    private boolean mAutonomousGroup;
-
-    /* Invitation to join an existing p2p group */
-    private boolean mJoinExistingGroup;
-
-    /* Track whether we are in p2p discovery. This is used to avoid sending duplicate
-     * broadcasts
-     */
-    private boolean mDiscoveryStarted;
-    /* Track whether servcice/peer discovery is blocked in favor of other wifi actions
-     * (notably dhcp)
-     */
-    private boolean mDiscoveryBlocked;
-
-    // Supplicant doesn't like setting the same country code multiple times (it may drop
-    // current connected network), so we save the country code here to avoid redundency
-    private String mLastSetCountryCode;
-
-    /*
-     * remember if we were in a scan when it had to be stopped
-     */
-    private boolean mDiscoveryPostponed = false;
-
-    private NetworkInfo mNetworkInfo;
-
-    private boolean mTempoarilyDisconnectedWifi = false;
-
-    /* The transaction Id of service discovery request */
-    private byte mServiceTransactionId = 0;
-
-    /* Service discovery request ID of wpa_supplicant.
-     * null means it's not set yet. */
-    private String mServiceDiscReqId;
-
-    /* clients(application) information list. */
-    private HashMap<Messenger, ClientInfo> mClientInfoList = new HashMap<Messenger, ClientInfo>();
-
-    /* Is chosen as a unique range to avoid conflict with
-       the range defined in Tethering.java */
-    private static final String[] DHCP_RANGE = {"192.168.49.2", "192.168.49.254"};
-    private static final String SERVER_ADDRESS = "192.168.49.1";
-
-    /**
-     * Error code definition.
-     * see the Table.8 in the WiFi Direct specification for the detail.
-     */
-    public static enum P2pStatus {
-        /* Success. */
-        SUCCESS,
-
-        /* The target device is currently unavailable. */
-        INFORMATION_IS_CURRENTLY_UNAVAILABLE,
-
-        /* Protocol error. */
-        INCOMPATIBLE_PARAMETERS,
-
-        /* The target device reached the limit of the number of the connectable device.
-         * For example, device limit or group limit is set. */
-        LIMIT_REACHED,
-
-        /* Protocol error. */
-        INVALID_PARAMETER,
-
-        /* Unable to accommodate request. */
-        UNABLE_TO_ACCOMMODATE_REQUEST,
-
-        /* Previous protocol error, or disruptive behavior. */
-        PREVIOUS_PROTOCOL_ERROR,
-
-        /* There is no common channels the both devices can use. */
-        NO_COMMON_CHANNEL,
-
-        /* Unknown p2p group. For example, Device A tries to invoke the previous persistent group,
-         *  but device B has removed the specified credential already. */
-        UNKNOWN_P2P_GROUP,
-
-        /* Both p2p devices indicated an intent of 15 in group owner negotiation. */
-        BOTH_GO_INTENT_15,
-
-        /* Incompatible provisioning method. */
-        INCOMPATIBLE_PROVISIONING_METHOD,
-
-        /* Rejected by user */
-        REJECTED_BY_USER,
-
-        /* Unknown error */
-        UNKNOWN;
-
-        public static P2pStatus valueOf(int error) {
-            switch(error) {
-            case 0 :
-                return SUCCESS;
-            case 1:
-                return INFORMATION_IS_CURRENTLY_UNAVAILABLE;
-            case 2:
-                return INCOMPATIBLE_PARAMETERS;
-            case 3:
-                return LIMIT_REACHED;
-            case 4:
-                return INVALID_PARAMETER;
-            case 5:
-                return UNABLE_TO_ACCOMMODATE_REQUEST;
-            case 6:
-                return PREVIOUS_PROTOCOL_ERROR;
-            case 7:
-                return NO_COMMON_CHANNEL;
-            case 8:
-                return UNKNOWN_P2P_GROUP;
-            case 9:
-                return BOTH_GO_INTENT_15;
-            case 10:
-                return INCOMPATIBLE_PROVISIONING_METHOD;
-            case 11:
-                return REJECTED_BY_USER;
-            default:
-                return UNKNOWN;
-            }
-        }
-    }
-
-    public WifiP2pService(Context context) {
-        mContext = context;
-
-        //STOPSHIP: get this from native side
-        mInterface = "p2p0";
-        mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
-
-        mP2pSupported = mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_WIFI_DIRECT);
-
-        mThisDevice.primaryDeviceType = mContext.getResources().getString(
-                com.android.internal.R.string.config_wifi_p2p_device_type);
-
-        mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported);
-        mP2pStateMachine.start();
-    }
-
-    public void connectivityServiceReady() {
-        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-        mNwService = INetworkManagementService.Stub.asInterface(b);
-    }
-
-    private void enforceAccessPermission() {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE,
-                "WifiP2pService");
-    }
-
-    private void enforceChangePermission() {
-        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CHANGE_WIFI_STATE,
-                "WifiP2pService");
-    }
-
-    private void enforceConnectivityInternalPermission() {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CONNECTIVITY_INTERNAL,
-                "WifiP2pService");
-    }
-
-    /**
-     * Get a reference to handler. This is used by a client to establish
-     * an AsyncChannel communication with WifiP2pService
-     */
-    public Messenger getMessenger() {
-        enforceAccessPermission();
-        enforceChangePermission();
-        return new Messenger(mP2pStateMachine.getHandler());
-    }
-
-    /** This is used to provide information to drivers to optimize performance depending
-     * on the current mode of operation.
-     * 0 - disabled
-     * 1 - source operation
-     * 2 - sink operation
-     *
-     * As an example, the driver could reduce the channel dwell time during scanning
-     * when acting as a source or sink to minimize impact on miracast.
-     */
-    public void setMiracastMode(int mode) {
-        enforceConnectivityInternalPermission();
-        mP2pStateMachine.sendMessage(SET_MIRACAST_MODE, mode);
-    }
-
-    @Override
-    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
-                != PackageManager.PERMISSION_GRANTED) {
-            pw.println("Permission Denial: can't dump WifiP2pService from from pid="
-                    + Binder.getCallingPid()
-                    + ", uid=" + Binder.getCallingUid());
-            return;
-        }
-        mP2pStateMachine.dump(fd, pw, args);
-        pw.println("mAutonomousGroup " + mAutonomousGroup);
-        pw.println("mJoinExistingGroup " + mJoinExistingGroup);
-        pw.println("mDiscoveryStarted " + mDiscoveryStarted);
-        pw.println("mNetworkInfo " + mNetworkInfo);
-        pw.println("mTempoarilyDisconnectedWifi " + mTempoarilyDisconnectedWifi);
-        pw.println("mServiceDiscReqId " + mServiceDiscReqId);
-        pw.println();
-    }
-
-
-    /**
-     * Handles interaction with WifiStateMachine
-     */
-    private class P2pStateMachine extends StateMachine {
-
-        private DefaultState mDefaultState = new DefaultState();
-        private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState();
-        private P2pDisablingState mP2pDisablingState = new P2pDisablingState();
-        private P2pDisabledState mP2pDisabledState = new P2pDisabledState();
-        private P2pEnablingState mP2pEnablingState = new P2pEnablingState();
-        private P2pEnabledState mP2pEnabledState = new P2pEnabledState();
-        // Inactive is when p2p is enabled with no connectivity
-        private InactiveState mInactiveState = new InactiveState();
-        private GroupCreatingState mGroupCreatingState = new GroupCreatingState();
-        private UserAuthorizingInviteRequestState mUserAuthorizingInviteRequestState
-                = new UserAuthorizingInviteRequestState();
-        private UserAuthorizingNegotiationRequestState mUserAuthorizingNegotiationRequestState
-                = new UserAuthorizingNegotiationRequestState();
-        private ProvisionDiscoveryState mProvisionDiscoveryState = new ProvisionDiscoveryState();
-        private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState();
-        private FrequencyConflictState mFrequencyConflictState =new FrequencyConflictState();
-
-        private GroupCreatedState mGroupCreatedState = new GroupCreatedState();
-        private UserAuthorizingJoinState mUserAuthorizingJoinState = new UserAuthorizingJoinState();
-        private OngoingGroupRemovalState mOngoingGroupRemovalState = new OngoingGroupRemovalState();
-
-        private WifiNative mWifiNative = new WifiNative(mInterface);
-        private WifiMonitor mWifiMonitor = new WifiMonitor(this, mWifiNative);
-
-        private final WifiP2pDeviceList mPeers = new WifiP2pDeviceList();
-        /* During a connection, supplicant can tell us that a device was lost. From a supplicant's
-         * perspective, the discovery stops during connection and it purges device since it does
-         * not get latest updates about the device without being in discovery state.
-         *
-         * From the framework perspective, the device is still there since we are connecting or
-         * connected to it. so we keep these devices in a separate list, so that they are removed
-         * when connection is cancelled or lost
-         */
-        private final WifiP2pDeviceList mPeersLostDuringConnection = new WifiP2pDeviceList();
-        private final WifiP2pGroupList mGroups = new WifiP2pGroupList(null,
-                new GroupDeleteListener() {
-            @Override
-            public void onDeleteGroup(int netId) {
-                if (DBG) logd("called onDeleteGroup() netId=" + netId);
-                mWifiNative.removeNetwork(netId);
-                mWifiNative.saveConfig();
-                sendP2pPersistentGroupsChangedBroadcast();
-            }
-        });
-        private final WifiP2pInfo mWifiP2pInfo = new WifiP2pInfo();
-        private WifiP2pGroup mGroup;
-
-        // Saved WifiP2pConfig for an ongoing peer connection. This will never be null.
-        // The deviceAddress will be an empty string when the device is inactive
-        // or if it is connected without any ongoing join request
-        private WifiP2pConfig mSavedPeerConfig = new WifiP2pConfig();
-
-        // Saved WifiP2pGroup from invitation request
-        private WifiP2pGroup mSavedP2pGroup;
-
-        P2pStateMachine(String name, boolean p2pSupported) {
-            super(name);
-
-            addState(mDefaultState);
-                addState(mP2pNotSupportedState, mDefaultState);
-                addState(mP2pDisablingState, mDefaultState);
-                addState(mP2pDisabledState, mDefaultState);
-                addState(mP2pEnablingState, mDefaultState);
-                addState(mP2pEnabledState, mDefaultState);
-                    addState(mInactiveState, mP2pEnabledState);
-                    addState(mGroupCreatingState, mP2pEnabledState);
-                        addState(mUserAuthorizingInviteRequestState, mGroupCreatingState);
-                        addState(mUserAuthorizingNegotiationRequestState, mGroupCreatingState);
-                        addState(mProvisionDiscoveryState, mGroupCreatingState);
-                        addState(mGroupNegotiationState, mGroupCreatingState);
-                        addState(mFrequencyConflictState, mGroupCreatingState);
-                    addState(mGroupCreatedState, mP2pEnabledState);
-                        addState(mUserAuthorizingJoinState, mGroupCreatedState);
-                        addState(mOngoingGroupRemovalState, mGroupCreatedState);
-
-            if (p2pSupported) {
-                setInitialState(mP2pDisabledState);
-            } else {
-                setInitialState(mP2pNotSupportedState);
-            }
-            setLogRecSize(50);
-            setLogOnlyTransitions(true);
-        }
-
-    class DefaultState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
-                    if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
-                        if (DBG) logd("Full connection with WifiStateMachine established");
-                        mWifiChannel = (AsyncChannel) message.obj;
-                    } else {
-                        loge("Full connection failure, error = " + message.arg1);
-                        mWifiChannel = null;
-                    }
-                    break;
-
-                case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                    if (message.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
-                        loge("Send failed, client connection lost");
-                    } else {
-                        loge("Client connection lost with reason: " + message.arg1);
-                    }
-                    mWifiChannel = null;
-                    break;
-
-                case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
-                    AsyncChannel ac = new AsyncChannel();
-                    ac.connect(mContext, getHandler(), message.replyTo);
-                    break;
-                case BLOCK_DISCOVERY:
-                    mDiscoveryBlocked = (message.arg1 == ENABLED ? true : false);
-                    // always reset this - we went to a state that doesn't support discovery so
-                    // it would have stopped regardless
-                    mDiscoveryPostponed = false;
-                    if (mDiscoveryBlocked) {
-                        try {
-                            StateMachine m = (StateMachine)message.obj;
-                            m.sendMessage(message.arg2);
-                        } catch (Exception e) {
-                            loge("unable to send BLOCK_DISCOVERY response: " + e);
-                        }
-                    }
-                    break;
-                case WifiP2pManager.DISCOVER_PEERS:
-                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.STOP_DISCOVERY:
-                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.DISCOVER_SERVICES:
-                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.CONNECT:
-                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.CANCEL_CONNECT:
-                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.CREATE_GROUP:
-                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.REMOVE_GROUP:
-                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.ADD_LOCAL_SERVICE:
-                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
-                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
-                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.ADD_SERVICE_REQUEST:
-                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
-                    replyToMessage(message,
-                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
-                    replyToMessage(message,
-                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.SET_DEVICE_NAME:
-                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
-                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.SET_WFD_INFO:
-                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.REQUEST_PEERS:
-                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS,
-                            new WifiP2pDeviceList(mPeers));
-                    break;
-                case WifiP2pManager.REQUEST_CONNECTION_INFO:
-                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO,
-                            new WifiP2pInfo(mWifiP2pInfo));
-                    break;
-                case WifiP2pManager.REQUEST_GROUP_INFO:
-                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO,
-                            mGroup != null ? new WifiP2pGroup(mGroup) : null);
-                    break;
-                case WifiP2pManager.REQUEST_PERSISTENT_GROUP_INFO:
-                    replyToMessage(message, WifiP2pManager.RESPONSE_PERSISTENT_GROUP_INFO,
-                            new WifiP2pGroupList(mGroups, null));
-                    break;
-                case WifiP2pManager.START_WPS:
-                    replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
-                        WifiP2pManager.BUSY);
-                    break;
-                    // Ignore
-                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
-                case WifiMonitor.SCAN_RESULTS_EVENT:
-                case WifiMonitor.SUP_CONNECTION_EVENT:
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                case WifiMonitor.NETWORK_CONNECTION_EVENT:
-                case WifiMonitor.NETWORK_DISCONNECTION_EVENT:
-                case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT:
-                case WifiMonitor.AUTHENTICATION_FAILURE_EVENT:
-                case WifiMonitor.WPS_SUCCESS_EVENT:
-                case WifiMonitor.WPS_FAIL_EVENT:
-                case WifiMonitor.WPS_OVERLAP_EVENT:
-                case WifiMonitor.WPS_TIMEOUT_EVENT:
-                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
-                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
-                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
-                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
-                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
-                case PEER_CONNECTION_USER_ACCEPT:
-                case PEER_CONNECTION_USER_REJECT:
-                case DISCONNECT_WIFI_RESPONSE:
-                case DROP_WIFI_USER_ACCEPT:
-                case DROP_WIFI_USER_REJECT:
-                case GROUP_CREATING_TIMED_OUT:
-                case DISABLE_P2P_TIMED_OUT:
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
-                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
-                    break;
-                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
-                    // If we end up handling in default, p2p is not enabled
-                    mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP);
-                    break;
-                    /* unexpected group created, remove */
-                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
-                    mGroup = (WifiP2pGroup) message.obj;
-                    loge("Unexpected group creation, remove " + mGroup);
-                    mWifiNative.p2pGroupRemove(mGroup.getInterface());
-                    break;
-                // A group formation failure is always followed by
-                // a group removed event. Flushing things at group formation
-                // failure causes supplicant issues. Ignore right now.
-                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
-                    break;
-                default:
-                    loge("Unhandled message " + message);
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class P2pNotSupportedState extends State {
-        @Override
-        public boolean processMessage(Message message) {
-            switch (message.what) {
-               case WifiP2pManager.DISCOVER_PEERS:
-                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.STOP_DISCOVERY:
-                    replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.DISCOVER_SERVICES:
-                    replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.CONNECT:
-                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.CANCEL_CONNECT:
-                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-               case WifiP2pManager.CREATE_GROUP:
-                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.REMOVE_GROUP:
-                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.ADD_LOCAL_SERVICE:
-                    replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
-                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
-                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.ADD_SERVICE_REQUEST:
-                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
-                    replyToMessage(message,
-                            WifiP2pManager.REMOVE_SERVICE_REQUEST_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
-                    replyToMessage(message,
-                            WifiP2pManager.CLEAR_SERVICE_REQUESTS_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.SET_DEVICE_NAME:
-                    replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
-                    replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.SET_WFD_INFO:
-                    replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                case WifiP2pManager.START_WPS:
-                    replyToMessage(message, WifiP2pManager.START_WPS_FAILED,
-                            WifiP2pManager.P2P_UNSUPPORTED);
-                    break;
-                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;
-        }
-    }
-
-    class P2pDisablingState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            sendMessageDelayed(obtainMessage(DISABLE_P2P_TIMED_OUT,
-                    ++mDisableP2pTimeoutIndex, 0), DISABLE_P2P_WAIT_TIME_MS);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    if (DBG) logd("p2p socket connection lost");
-                    transitionTo(mP2pDisabledState);
-                    break;
-                case WifiStateMachine.CMD_ENABLE_P2P:
-                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
-                    deferMessage(message);
-                    break;
-                case DISABLE_P2P_TIMED_OUT:
-                    if (mGroupCreatingTimeoutIndex == message.arg1) {
-                        loge("P2p disable timed out");
-                        transitionTo(mP2pDisabledState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        @Override
-        public void exit() {
-            mWifiChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P_RSP);
-        }
-    }
-
-    class P2pDisabledState extends State {
-       @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiStateMachine.CMD_ENABLE_P2P:
-                    try {
-                        mNwService.setInterfaceUp(mInterface);
-                    } catch (RemoteException re) {
-                        loge("Unable to change interface settings: " + re);
-                    } catch (IllegalStateException ie) {
-                        loge("Unable to change interface settings: " + ie);
-                    }
-                    mWifiMonitor.startMonitoring();
-                    transitionTo(mP2pEnablingState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class P2pEnablingState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiMonitor.SUP_CONNECTION_EVENT:
-                    if (DBG) logd("P2p socket connection successful");
-                    transitionTo(mInactiveState);
-                    break;
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    loge("P2p socket connection failed");
-                    transitionTo(mP2pDisabledState);
-                    break;
-                case WifiStateMachine.CMD_ENABLE_P2P:
-                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
-                    deferMessage(message);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class P2pEnabledState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            sendP2pStateChangedBroadcast(true);
-            mNetworkInfo.setIsAvailable(true);
-            sendP2pConnectionChangedBroadcast();
-            initializeP2pSettings();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiMonitor.SUP_DISCONNECTION_EVENT:
-                    loge("Unexpected loss of p2p socket connection");
-                    transitionTo(mP2pDisabledState);
-                    break;
-                case WifiStateMachine.CMD_ENABLE_P2P:
-                    //Nothing to do
-                    break;
-                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
-                    if (mPeers.clear()) {
-                        sendPeersChangedBroadcast();
-                    }
-                    if (mGroups.clear()) sendP2pPersistentGroupsChangedBroadcast();
-
-                    mWifiMonitor.stopMonitoring();
-                    transitionTo(mP2pDisablingState);
-                    break;
-                case WifiP2pManager.SET_DEVICE_NAME:
-                {
-                    WifiP2pDevice d = (WifiP2pDevice) message.obj;
-                    if (d != null && setAndPersistDeviceName(d.deviceName)) {
-                        if (DBG) logd("set device name " + d.deviceName);
-                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.SET_DEVICE_NAME_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    break;
-                }
-                case WifiP2pManager.SET_WFD_INFO:
-                {
-                    WifiP2pWfdInfo d = (WifiP2pWfdInfo) message.obj;
-                    if (d != null && setWfdInfo(d)) {
-                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.SET_WFD_INFO_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    break;
-                }
-                case BLOCK_DISCOVERY:
-                    boolean blocked = (message.arg1 == ENABLED ? true : false);
-                    if (mDiscoveryBlocked == blocked) break;
-                    mDiscoveryBlocked = blocked;
-                    if (blocked && mDiscoveryStarted) {
-                        mWifiNative.p2pStopFind();
-                        mDiscoveryPostponed = true;
-                    }
-                    if (!blocked && mDiscoveryPostponed) {
-                        mDiscoveryPostponed = false;
-                        mWifiNative.p2pFind(DISCOVER_TIMEOUT_S);
-                    }
-                    if (blocked) {
-                        try {
-                            StateMachine m = (StateMachine)message.obj;
-                            m.sendMessage(message.arg2);
-                        } catch (Exception e) {
-                            loge("unable to send BLOCK_DISCOVERY response: " + e);
-                        }
-                    }
-                    break;
-                case WifiP2pManager.DISCOVER_PEERS:
-                    if (mDiscoveryBlocked) {
-                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
-                                WifiP2pManager.BUSY);
-                        break;
-                    }
-                    // do not send service discovery request while normal find operation.
-                    clearSupplicantServiceRequest();
-                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
-                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
-                        sendP2pDiscoveryChangedBroadcast(true);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    break;
-                case WifiMonitor.P2P_FIND_STOPPED_EVENT:
-                    sendP2pDiscoveryChangedBroadcast(false);
-                    break;
-                case WifiP2pManager.STOP_DISCOVERY:
-                    if (mWifiNative.p2pStopFind()) {
-                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    break;
-                case WifiP2pManager.DISCOVER_SERVICES:
-                    if (mDiscoveryBlocked) {
-                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
-                                WifiP2pManager.BUSY);
-                        break;
-                    }
-                    if (DBG) logd(getName() + " discover services");
-                    if (!updateSupplicantServiceRequest()) {
-                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
-                                WifiP2pManager.NO_SERVICE_REQUESTS);
-                        break;
-                    }
-                    if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) {
-                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.DISCOVER_SERVICES_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    break;
-                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
-                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
-                    if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break;
-                    mPeers.updateSupplicantDetails(device);
-                    sendPeersChangedBroadcast();
-                    break;
-                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
-                    device = (WifiP2pDevice) message.obj;
-                    // Gets current details for the one removed
-                    device = mPeers.remove(device.deviceAddress);
-                    if (device != null) {
-                        sendPeersChangedBroadcast();
-                    }
-                    break;
-                case WifiP2pManager.ADD_LOCAL_SERVICE:
-                    if (DBG) logd(getName() + " add service");
-                    WifiP2pServiceInfo servInfo = (WifiP2pServiceInfo)message.obj;
-                    if (addLocalService(message.replyTo, servInfo)) {
-                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.ADD_LOCAL_SERVICE_FAILED);
-                    }
-                    break;
-                case WifiP2pManager.REMOVE_LOCAL_SERVICE:
-                    if (DBG) logd(getName() + " remove service");
-                    servInfo = (WifiP2pServiceInfo)message.obj;
-                    removeLocalService(message.replyTo, servInfo);
-                    replyToMessage(message, WifiP2pManager.REMOVE_LOCAL_SERVICE_SUCCEEDED);
-                    break;
-                case WifiP2pManager.CLEAR_LOCAL_SERVICES:
-                    if (DBG) logd(getName() + " clear service");
-                    clearLocalServices(message.replyTo);
-                    replyToMessage(message, WifiP2pManager.CLEAR_LOCAL_SERVICES_SUCCEEDED);
-                    break;
-                case WifiP2pManager.ADD_SERVICE_REQUEST:
-                    if (DBG) logd(getName() + " add service request");
-                    if (!addServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj)) {
-                        replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_FAILED);
-                        break;
-                    }
-                    replyToMessage(message, WifiP2pManager.ADD_SERVICE_REQUEST_SUCCEEDED);
-                    break;
-                case WifiP2pManager.REMOVE_SERVICE_REQUEST:
-                    if (DBG) logd(getName() + " remove service request");
-                    removeServiceRequest(message.replyTo, (WifiP2pServiceRequest)message.obj);
-                    replyToMessage(message, WifiP2pManager.REMOVE_SERVICE_REQUEST_SUCCEEDED);
-                    break;
-                case WifiP2pManager.CLEAR_SERVICE_REQUESTS:
-                    if (DBG) logd(getName() + " clear service request");
-                    clearServiceRequests(message.replyTo);
-                    replyToMessage(message, WifiP2pManager.CLEAR_SERVICE_REQUESTS_SUCCEEDED);
-                    break;
-                case WifiMonitor.P2P_SERV_DISC_RESP_EVENT:
-                    if (DBG) logd(getName() + " receive service response");
-                    List<WifiP2pServiceResponse> sdRespList =
-                        (List<WifiP2pServiceResponse>) message.obj;
-                    for (WifiP2pServiceResponse resp : sdRespList) {
-                        WifiP2pDevice dev =
-                            mPeers.get(resp.getSrcDevice().deviceAddress);
-                        resp.setSrcDevice(dev);
-                        sendServiceResponse(resp);
-                    }
-                    break;
-                case WifiP2pManager.DELETE_PERSISTENT_GROUP:
-                   if (DBG) logd(getName() + " delete persistent group");
-                   mGroups.remove(message.arg1);
-                   replyToMessage(message, WifiP2pManager.DELETE_PERSISTENT_GROUP_SUCCEEDED);
-                   break;
-                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;
-                    countryCode = countryCode.toUpperCase(Locale.ROOT);
-                    if (mLastSetCountryCode == null ||
-                            countryCode.equals(mLastSetCountryCode) == false) {
-                        if (mWifiNative.setCountryCode(countryCode)) {
-                            mLastSetCountryCode = countryCode;
-                        }
-                    }
-                    break;
-                default:
-                   return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        @Override
-        public void exit() {
-            sendP2pStateChangedBroadcast(false);
-            mNetworkInfo.setIsAvailable(false);
-
-            mLastSetCountryCode = null;
-        }
-    }
-
-    class InactiveState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            mSavedPeerConfig.invalidate();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiP2pManager.CONNECT:
-                    if (DBG) logd(getName() + " sending connect");
-                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
-                    if (isConfigInvalid(config)) {
-                        loge("Dropping connect requeset " + config);
-                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
-                        break;
-                    }
-
-                    mAutonomousGroup = false;
-                    mWifiNative.p2pStopFind();
-                    if (reinvokePersistentGroup(config)) {
-                        transitionTo(mGroupNegotiationState);
-                    } else {
-                        transitionTo(mProvisionDiscoveryState);
-                    }
-                    mSavedPeerConfig = config;
-                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
-                    sendPeersChangedBroadcast();
-                    replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
-                    break;
-                case WifiP2pManager.STOP_DISCOVERY:
-                    if (mWifiNative.p2pStopFind()) {
-                        // When discovery stops in inactive state, flush to clear
-                        // state peer data
-                        mWifiNative.p2pFlush();
-                        mServiceDiscReqId = null;
-                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    break;
-                case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT:
-                    config = (WifiP2pConfig) message.obj;
-                    if (isConfigInvalid(config)) {
-                        loge("Dropping GO neg request " + config);
-                        break;
-                    }
-                    mSavedPeerConfig = config;
-                    mAutonomousGroup = false;
-                    mJoinExistingGroup = false;
-                    transitionTo(mUserAuthorizingNegotiationRequestState);
-                    break;
-                case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT:
-                    WifiP2pGroup group = (WifiP2pGroup) message.obj;
-                    WifiP2pDevice owner = group.getOwner();
-
-                    if (owner == null) {
-                        loge("Ignored invitation from null owner");
-                        break;
-                    }
-
-                    config = new WifiP2pConfig();
-                    config.deviceAddress = group.getOwner().deviceAddress;
-
-                    if (isConfigInvalid(config)) {
-                        loge("Dropping invitation request " + config);
-                        break;
-                    }
-                    mSavedPeerConfig = config;
-
-                    //Check if we have the owner in peer list and use appropriate
-                    //wps method. Default is to use PBC.
-                    if ((owner = mPeers.get(owner.deviceAddress)) != null) {
-                        if (owner.wpsPbcSupported()) {
-                            mSavedPeerConfig.wps.setup = WpsInfo.PBC;
-                        } else if (owner.wpsKeypadSupported()) {
-                            mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
-                        } else if (owner.wpsDisplaySupported()) {
-                            mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
-                        }
-                    }
-
-                    mAutonomousGroup = false;
-                    mJoinExistingGroup = true;
-                    transitionTo(mUserAuthorizingInviteRequestState);
-                    break;
-                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
-                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
-                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
-                    //We let the supplicant handle the provision discovery response
-                    //and wait instead for the GO_NEGOTIATION_REQUEST_EVENT.
-                    //Handling provision discovery and issuing a p2p_connect before
-                    //group negotiation comes through causes issues
-                    break;
-                case WifiP2pManager.CREATE_GROUP:
-                    mAutonomousGroup = true;
-                    int netId = message.arg1;
-                    boolean ret = false;
-                    if (netId == WifiP2pGroup.PERSISTENT_NET_ID) {
-                        // check if the go persistent group is present.
-                        netId = mGroups.getNetworkId(mThisDevice.deviceAddress);
-                        if (netId != -1) {
-                            ret = mWifiNative.p2pGroupAdd(netId);
-                        } else {
-                            ret = mWifiNative.p2pGroupAdd(true);
-                        }
-                    } else {
-                        ret = mWifiNative.p2pGroupAdd(false);
-                    }
-
-                    if (ret) {
-                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
-                        transitionTo(mGroupNegotiationState);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
-                                WifiP2pManager.ERROR);
-                        // remain at this state.
-                    }
-                    break;
-                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
-                    mGroup = (WifiP2pGroup) message.obj;
-                    if (DBG) logd(getName() + " group started");
-
-                    // We hit this scenario when a persistent group is reinvoked
-                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
-                        mAutonomousGroup = false;
-                        deferMessage(message);
-                        transitionTo(mGroupNegotiationState);
-                    } else {
-                        loge("Unexpected group creation, remove " + mGroup);
-                        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;
-            }
-            return HANDLED;
-        }
-    }
-
-    class GroupCreatingState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            sendMessageDelayed(obtainMessage(GROUP_CREATING_TIMED_OUT,
-                    ++mGroupCreatingTimeoutIndex, 0), GROUP_CREATING_WAIT_TIME_MS);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            boolean ret = HANDLED;
-            switch (message.what) {
-               case GROUP_CREATING_TIMED_OUT:
-                    if (mGroupCreatingTimeoutIndex == message.arg1) {
-                        if (DBG) logd("Group negotiation timed out");
-                        handleGroupCreationFailure();
-                        transitionTo(mInactiveState);
-                    }
-                    break;
-                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
-                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
-                    if (!mSavedPeerConfig.deviceAddress.equals(device.deviceAddress)) {
-                        if (DBG) {
-                            logd("mSavedPeerConfig " + mSavedPeerConfig.deviceAddress +
-                                "device " + device.deviceAddress);
-                        }
-                        // Do the regular device lost handling
-                        ret = NOT_HANDLED;
-                        break;
-                    }
-                    // Do nothing
-                    if (DBG) logd("Add device to lost list " + device);
-                    mPeersLostDuringConnection.updateSupplicantDetails(device);
-                    break;
-                case WifiP2pManager.DISCOVER_PEERS:
-                    /* Discovery will break negotiation */
-                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
-                            WifiP2pManager.BUSY);
-                    break;
-                case WifiP2pManager.CANCEL_CONNECT:
-                    //Do a supplicant p2p_cancel which only cancels an ongoing
-                    //group negotiation. This will fail for a pending provision
-                    //discovery or for a pending user action, but at the framework
-                    //level, we always treat cancel as succeeded and enter
-                    //an inactive state
-                    mWifiNative.p2pCancelConnect();
-                    handleGroupCreationFailure();
-                    transitionTo(mInactiveState);
-                    replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED);
-                    break;
-                default:
-                    ret = NOT_HANDLED;
-            }
-            return ret;
-        }
-    }
-
-    class UserAuthorizingNegotiationRequestState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            notifyInvitationReceived();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            boolean ret = HANDLED;
-            switch (message.what) {
-                case PEER_CONNECTION_USER_ACCEPT:
-                    mWifiNative.p2pStopFind();
-                    p2pConnectWithPinDisplay(mSavedPeerConfig);
-                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
-                    sendPeersChangedBroadcast();
-                    transitionTo(mGroupNegotiationState);
-                   break;
-                case PEER_CONNECTION_USER_REJECT:
-                    if (DBG) logd("User rejected negotiation " + mSavedPeerConfig);
-                    transitionTo(mInactiveState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return ret;
-        }
-
-        @Override
-        public void exit() {
-            //TODO: dismiss dialog if not already done
-        }
-    }
-
-    class UserAuthorizingInviteRequestState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            notifyInvitationReceived();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            boolean ret = HANDLED;
-            switch (message.what) {
-                case PEER_CONNECTION_USER_ACCEPT:
-                    mWifiNative.p2pStopFind();
-                    if (!reinvokePersistentGroup(mSavedPeerConfig)) {
-                        // Do negotiation when persistence fails
-                        p2pConnectWithPinDisplay(mSavedPeerConfig);
-                    }
-                    mPeers.updateStatus(mSavedPeerConfig.deviceAddress, WifiP2pDevice.INVITED);
-                    sendPeersChangedBroadcast();
-                    transitionTo(mGroupNegotiationState);
-                   break;
-                case PEER_CONNECTION_USER_REJECT:
-                    if (DBG) logd("User rejected invitation " + mSavedPeerConfig);
-                    transitionTo(mInactiveState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return ret;
-        }
-
-        @Override
-        public void exit() {
-            //TODO: dismiss dialog if not already done
-        }
-    }
-
-
-
-    class ProvisionDiscoveryState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            mWifiNative.p2pProvisionDiscovery(mSavedPeerConfig);
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            WifiP2pProvDiscEvent provDisc;
-            WifiP2pDevice device;
-            switch (message.what) {
-                case WifiMonitor.P2P_PROV_DISC_PBC_RSP_EVENT:
-                    provDisc = (WifiP2pProvDiscEvent) message.obj;
-                    device = provDisc.device;
-                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
-
-                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
-                        if (DBG) logd("Found a match " + mSavedPeerConfig);
-                        p2pConnectWithPinDisplay(mSavedPeerConfig);
-                        transitionTo(mGroupNegotiationState);
-                    }
-                    break;
-                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
-                    provDisc = (WifiP2pProvDiscEvent) message.obj;
-                    device = provDisc.device;
-                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
-
-                    if (mSavedPeerConfig.wps.setup == WpsInfo.KEYPAD) {
-                        if (DBG) logd("Found a match " + mSavedPeerConfig);
-                        /* we already have the pin */
-                        if (!TextUtils.isEmpty(mSavedPeerConfig.wps.pin)) {
-                            p2pConnectWithPinDisplay(mSavedPeerConfig);
-                            transitionTo(mGroupNegotiationState);
-                        } else {
-                            mJoinExistingGroup = false;
-                            transitionTo(mUserAuthorizingNegotiationRequestState);
-                        }
-                    }
-                    break;
-                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
-                    provDisc = (WifiP2pProvDiscEvent) message.obj;
-                    device = provDisc.device;
-                    if (!device.deviceAddress.equals(mSavedPeerConfig.deviceAddress)) break;
-
-                    if (mSavedPeerConfig.wps.setup == WpsInfo.DISPLAY) {
-                        if (DBG) logd("Found a match " + mSavedPeerConfig);
-                        mSavedPeerConfig.wps.pin = provDisc.pin;
-                        p2pConnectWithPinDisplay(mSavedPeerConfig);
-                        notifyInvitationSent(provDisc.pin, device.deviceAddress);
-                        transitionTo(mGroupNegotiationState);
-                    }
-                    break;
-                case WifiMonitor.P2P_PROV_DISC_FAILURE_EVENT:
-                    loge("provision discovery failed");
-                    handleGroupCreationFailure();
-                    transitionTo(mInactiveState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class GroupNegotiationState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                // We ignore these right now, since we get a GROUP_STARTED notification
-                // afterwards
-                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
-                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
-                    if (DBG) logd(getName() + " go success");
-                    break;
-                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
-                    mGroup = (WifiP2pGroup) message.obj;
-                    if (DBG) logd(getName() + " group started");
-
-                    if (mGroup.getNetworkId() == WifiP2pGroup.PERSISTENT_NET_ID) {
-                        /*
-                         * update cache information and set network id to mGroup.
-                         */
-                        updatePersistentNetworks(NO_RELOAD);
-                        String devAddr = mGroup.getOwner().deviceAddress;
-                        mGroup.setNetworkId(mGroups.getNetworkId(devAddr,
-                                mGroup.getNetworkName()));
-                    }
-
-                    if (mGroup.isGroupOwner()) {
-                        /* Setting an idle time out on GO causes issues with certain scenarios
-                         * on clients where it can be off-channel for longer and with the power
-                         * save modes used.
-                         *
-                         * TODO: Verify multi-channel scenarios and supplicant behavior are
-                         * better before adding a time out in future
-                         */
-                        //Set group idle timeout of 10 sec, to avoid GO beaconing incase of any
-                        //failure during 4-way Handshake.
-                        if (!mAutonomousGroup) {
-                            mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
-                        }
-                        startDhcpServer(mGroup.getInterface());
-                    } else {
-                        mWifiNative.setP2pGroupIdle(mGroup.getInterface(), GROUP_IDLE_TIME_S);
-                        mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
-                                P2pStateMachine.this, mGroup.getInterface());
-                        // TODO: We should use DHCP state machine PRE message like WifiStateMachine
-                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), false);
-                        mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
-                        WifiP2pDevice groupOwner = mGroup.getOwner();
-                        WifiP2pDevice peer = mPeers.get(groupOwner.deviceAddress);
-                        if (peer != null) {
-                            // update group owner details with peer details found at discovery
-                            groupOwner.updateSupplicantDetails(peer);
-                            mPeers.updateStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED);
-                            sendPeersChangedBroadcast();
-                        } else {
-                            // A supplicant bug can lead to reporting an invalid
-                            // group owner address (all zeroes) at times. Avoid a
-                            // crash, but continue group creation since it is not
-                            // essential.
-                            logw("Unknown group owner " + groupOwner);
-                        }
-                    }
-                    transitionTo(mGroupCreatedState);
-                    break;
-                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
-                    P2pStatus status = (P2pStatus) message.obj;
-                    if (status == P2pStatus.NO_COMMON_CHANNEL) {
-                        transitionTo(mFrequencyConflictState);
-                        break;
-                    }
-                    /* continue with group removal handling */
-                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
-                    if (DBG) logd(getName() + " go failure");
-                    handleGroupCreationFailure();
-                    transitionTo(mInactiveState);
-                    break;
-                // A group formation failure is always followed by
-                // a group removed event. Flushing things at group formation
-                // failure causes supplicant issues. Ignore right now.
-                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
-                    status = (P2pStatus) message.obj;
-                    if (status == P2pStatus.NO_COMMON_CHANNEL) {
-                        transitionTo(mFrequencyConflictState);
-                        break;
-                    }
-                    break;
-                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
-                    status = (P2pStatus)message.obj;
-                    if (status == P2pStatus.SUCCESS) {
-                        // invocation was succeeded.
-                        // wait P2P_GROUP_STARTED_EVENT.
-                        break;
-                    }
-                    loge("Invitation result " + status);
-                    if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
-                        // target device has already removed the credential.
-                        // So, remove this credential accordingly.
-                        int netId = mSavedPeerConfig.netId;
-                        if (netId >= 0) {
-                            if (DBG) logd("Remove unknown client from the list");
-                            removeClientFromList(netId, mSavedPeerConfig.deviceAddress, true);
-                        }
-
-                        // Reinvocation has failed, try group negotiation
-                        mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
-                        p2pConnectWithPinDisplay(mSavedPeerConfig);
-                    } else if (status == P2pStatus.INFORMATION_IS_CURRENTLY_UNAVAILABLE) {
-
-                        // Devices setting persistent_reconnect to 0 in wpa_supplicant
-                        // always defer the invocation request and return
-                        // "information is currently unable" error.
-                        // So, try another way to connect for interoperability.
-                        mSavedPeerConfig.netId = WifiP2pGroup.PERSISTENT_NET_ID;
-                        p2pConnectWithPinDisplay(mSavedPeerConfig);
-                    } else if (status == P2pStatus.NO_COMMON_CHANNEL) {
-                        transitionTo(mFrequencyConflictState);
-                    } else {
-                        handleGroupCreationFailure();
-                        transitionTo(mInactiveState);
-                    }
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    class FrequencyConflictState extends State {
-        private AlertDialog mFrequencyConflictDialog;
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            notifyFrequencyConflict();
-        }
-
-        private void notifyFrequencyConflict() {
-            logd("Notify frequency conflict");
-            Resources r = Resources.getSystem();
-
-            AlertDialog dialog = new AlertDialog.Builder(mContext)
-                .setMessage(r.getString(R.string.wifi_p2p_frequency_conflict_message,
-                        getDeviceName(mSavedPeerConfig.deviceAddress)))
-                .setPositiveButton(r.getString(R.string.dlg_ok), new OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            sendMessage(DROP_WIFI_USER_ACCEPT);
-                        }
-                    })
-                .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            sendMessage(DROP_WIFI_USER_REJECT);
-                        }
-                    })
-                .setOnCancelListener(new DialogInterface.OnCancelListener() {
-                        @Override
-                        public void onCancel(DialogInterface arg0) {
-                            sendMessage(DROP_WIFI_USER_REJECT);
-                        }
-                    })
-                .create();
-
-            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-            dialog.show();
-            mFrequencyConflictDialog = dialog;
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiMonitor.P2P_GO_NEGOTIATION_SUCCESS_EVENT:
-                case WifiMonitor.P2P_GROUP_FORMATION_SUCCESS_EVENT:
-                    loge(getName() + "group sucess during freq conflict!");
-                    break;
-                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
-                    loge(getName() + "group started after freq conflict, handle anyway");
-                    deferMessage(message);
-                    transitionTo(mGroupNegotiationState);
-                    break;
-                case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT:
-                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
-                case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT:
-                    // Ignore failures since we retry again
-                    break;
-                case DROP_WIFI_USER_REJECT:
-                    // User rejected dropping wifi in favour of p2p
-                    handleGroupCreationFailure();
-                    transitionTo(mInactiveState);
-                    break;
-                case DROP_WIFI_USER_ACCEPT:
-                    // User accepted dropping wifi in favour of p2p
-                    mWifiChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_REQUEST, 1);
-                    mTempoarilyDisconnectedWifi = true;
-                    break;
-                case DISCONNECT_WIFI_RESPONSE:
-                    // Got a response from wifistatemachine, retry p2p
-                    if (DBG) logd(getName() + "Wifi disconnected, retry p2p");
-                    transitionTo(mInactiveState);
-                    sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        public void exit() {
-            if (mFrequencyConflictDialog != null) mFrequencyConflictDialog.dismiss();
-        }
-    }
-
-    class GroupCreatedState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            // Once connected, peer config details are invalid
-            mSavedPeerConfig.invalidate();
-            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
-
-            updateThisDevice(WifiP2pDevice.CONNECTED);
-
-            //DHCP server has already been started if I am a group owner
-            if (mGroup.isGroupOwner()) {
-                setWifiP2pInfoOnGroupFormation(NetworkUtils.numericToInetAddress(SERVER_ADDRESS));
-            }
-
-            // In case of a negotiation group, connection changed is sent
-            // after a client joins. For autonomous, send now
-            if (mAutonomousGroup) {
-                sendP2pConnectionChangedBroadcast();
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiMonitor.AP_STA_CONNECTED_EVENT:
-                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
-                    String deviceAddress = device.deviceAddress;
-                    // Clear timeout that was set when group was started.
-                    mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
-                    if (deviceAddress != null) {
-                        if (mPeers.get(deviceAddress) != null) {
-                            mGroup.addClient(mPeers.get(deviceAddress));
-                        } else {
-                            mGroup.addClient(deviceAddress);
-                        }
-                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.CONNECTED);
-                        if (DBG) logd(getName() + " ap sta connected");
-                        sendPeersChangedBroadcast();
-                    } else {
-                        loge("Connect on null device address, ignore");
-                    }
-                    sendP2pConnectionChangedBroadcast();
-                    break;
-                case WifiMonitor.AP_STA_DISCONNECTED_EVENT:
-                    device = (WifiP2pDevice) message.obj;
-                    deviceAddress = device.deviceAddress;
-                    if (deviceAddress != null) {
-                        mPeers.updateStatus(deviceAddress, WifiP2pDevice.AVAILABLE);
-                        if (mGroup.removeClient(deviceAddress)) {
-                            if (DBG) logd("Removed client " + deviceAddress);
-                            if (!mAutonomousGroup && mGroup.isClientListEmpty()) {
-                                logd("Client list empty, remove non-persistent p2p group");
-                                mWifiNative.p2pGroupRemove(mGroup.getInterface());
-                                // We end up sending connection changed broadcast
-                                // when this happens at exit()
-                            } else {
-                                // Notify when a client disconnects from group
-                                sendP2pConnectionChangedBroadcast();
-                            }
-                        } else {
-                            if (DBG) logd("Failed to remove client " + deviceAddress);
-                            for (WifiP2pDevice c : mGroup.getClientList()) {
-                                if (DBG) logd("client " + c.deviceAddress);
-                            }
-                        }
-                        sendPeersChangedBroadcast();
-                        if (DBG) logd(getName() + " ap sta disconnected");
-                    } else {
-                        loge("Disconnect on unknown device: " + device);
-                    }
-                    break;
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
-                    DhcpResults dhcpResults = (DhcpResults) message.obj;
-                    if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS &&
-                            dhcpResults != null) {
-                        if (DBG) logd("DhcpResults: " + dhcpResults);
-                        setWifiP2pInfoOnGroupFormation(dhcpResults.serverAddress);
-                        sendP2pConnectionChangedBroadcast();
-                        //Turn on power save on client
-                        mWifiNative.setP2pPowerSave(mGroup.getInterface(), true);
-                    } else {
-                        loge("DHCP failed");
-                        mWifiNative.p2pGroupRemove(mGroup.getInterface());
-                    }
-                    break;
-                case WifiP2pManager.REMOVE_GROUP:
-                    if (DBG) logd(getName() + " remove group");
-                    if (mWifiNative.p2pGroupRemove(mGroup.getInterface())) {
-                        transitionTo(mOngoingGroupRemovalState);
-                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
-                    } else {
-                        handleGroupRemoved();
-                        transitionTo(mInactiveState);
-                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    break;
-                /* We do not listen to NETWORK_DISCONNECTION_EVENT for group removal
-                 * handling since supplicant actually tries to reconnect after a temporary
-                 * disconnect until group idle time out. Eventually, a group removal event
-                 * will come when group has been removed.
-                 *
-                 * When there are connectivity issues during temporary disconnect, the application
-                 * will also just remove the group.
-                 *
-                 * Treating network disconnection as group removal causes race conditions since
-                 * supplicant would still maintain the group at that stage.
-                 */
-                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
-                    if (DBG) logd(getName() + " group removed");
-                    handleGroupRemoved();
-                    transitionTo(mInactiveState);
-                    break;
-                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
-                    device = (WifiP2pDevice) message.obj;
-                    //Device loss for a connected device indicates it is not in discovery any more
-                    if (mGroup.contains(device)) {
-                        if (DBG) logd("Add device to lost list " + device);
-                        mPeersLostDuringConnection.updateSupplicantDetails(device);
-                        return HANDLED;
-                    }
-                    // Do the regular device lost handling
-                    return NOT_HANDLED;
-                case WifiStateMachine.CMD_DISABLE_P2P_REQ:
-                    sendMessage(WifiP2pManager.REMOVE_GROUP);
-                    deferMessage(message);
-                    break;
-                    // This allows any client to join the GO during the
-                    // WPS window
-                case WifiP2pManager.START_WPS:
-                    WpsInfo wps = (WpsInfo) message.obj;
-                    if (wps == null) {
-                        replyToMessage(message, WifiP2pManager.START_WPS_FAILED);
-                        break;
-                    }
-                    boolean ret = true;
-                    if (wps.setup == WpsInfo.PBC) {
-                        ret = mWifiNative.startWpsPbc(mGroup.getInterface(), null);
-                    } else {
-                        if (wps.pin == null) {
-                            String pin = mWifiNative.startWpsPinDisplay(mGroup.getInterface());
-                            try {
-                                Integer.parseInt(pin);
-                                notifyInvitationSent(pin, "any");
-                            } catch (NumberFormatException ignore) {
-                                ret = false;
-                            }
-                        } else {
-                            ret = mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
-                                    wps.pin);
-                        }
-                    }
-                    replyToMessage(message, ret ? WifiP2pManager.START_WPS_SUCCEEDED :
-                            WifiP2pManager.START_WPS_FAILED);
-                    break;
-                case WifiP2pManager.CONNECT:
-                    WifiP2pConfig config = (WifiP2pConfig) message.obj;
-                    if (isConfigInvalid(config)) {
-                        loge("Dropping connect requeset " + config);
-                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
-                        break;
-                    }
-                    logd("Inviting device : " + config.deviceAddress);
-                    mSavedPeerConfig = config;
-                    if (mWifiNative.p2pInvite(mGroup, config.deviceAddress)) {
-                        mPeers.updateStatus(config.deviceAddress, WifiP2pDevice.INVITED);
-                        sendPeersChangedBroadcast();
-                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
-                    } else {
-                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
-                                WifiP2pManager.ERROR);
-                    }
-                    // TODO: figure out updating the status to declined when invitation is rejected
-                    break;
-                case WifiMonitor.P2P_INVITATION_RESULT_EVENT:
-                    P2pStatus status = (P2pStatus)message.obj;
-                    if (status == P2pStatus.SUCCESS) {
-                        // invocation was succeeded.
-                        break;
-                    }
-                    loge("Invitation result " + status);
-                    if (status == P2pStatus.UNKNOWN_P2P_GROUP) {
-                        // target device has already removed the credential.
-                        // So, remove this credential accordingly.
-                        int netId = mGroup.getNetworkId();
-                        if (netId >= 0) {
-                            if (DBG) logd("Remove unknown client from the list");
-                            if (!removeClientFromList(netId,
-                                    mSavedPeerConfig.deviceAddress, false)) {
-                                // not found the client on the list
-                                loge("Already removed the client, ignore");
-                                break;
-                            }
-                            // try invitation.
-                            sendMessage(WifiP2pManager.CONNECT, mSavedPeerConfig);
-                        }
-                    }
-                    break;
-                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
-                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
-                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
-                    WifiP2pProvDiscEvent provDisc = (WifiP2pProvDiscEvent) message.obj;
-                    mSavedPeerConfig = new WifiP2pConfig();
-                    mSavedPeerConfig.deviceAddress = provDisc.device.deviceAddress;
-                    if (message.what == WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT) {
-                        mSavedPeerConfig.wps.setup = WpsInfo.KEYPAD;
-                    } else if (message.what == WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT) {
-                        mSavedPeerConfig.wps.setup = WpsInfo.DISPLAY;
-                        mSavedPeerConfig.wps.pin = provDisc.pin;
-                    } else {
-                        mSavedPeerConfig.wps.setup = WpsInfo.PBC;
-                    }
-                    transitionTo(mUserAuthorizingJoinState);
-                    break;
-                case WifiMonitor.P2P_GROUP_STARTED_EVENT:
-                    loge("Duplicate group creation event notice, ignore");
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        public void exit() {
-            updateThisDevice(WifiP2pDevice.AVAILABLE);
-            resetWifiP2pInfo();
-            mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
-            sendP2pConnectionChangedBroadcast();
-        }
-    }
-
-    class UserAuthorizingJoinState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-            notifyInvitationReceived();
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                case WifiMonitor.P2P_PROV_DISC_PBC_REQ_EVENT:
-                case WifiMonitor.P2P_PROV_DISC_ENTER_PIN_EVENT:
-                case WifiMonitor.P2P_PROV_DISC_SHOW_PIN_EVENT:
-                    //Ignore more client requests
-                    break;
-                case PEER_CONNECTION_USER_ACCEPT:
-                    //Stop discovery to avoid failure due to channel switch
-                    mWifiNative.p2pStopFind();
-                    if (mSavedPeerConfig.wps.setup == WpsInfo.PBC) {
-                        mWifiNative.startWpsPbc(mGroup.getInterface(), null);
-                    } else {
-                        mWifiNative.startWpsPinKeypad(mGroup.getInterface(),
-                                mSavedPeerConfig.wps.pin);
-                    }
-                    transitionTo(mGroupCreatedState);
-                    break;
-                case PEER_CONNECTION_USER_REJECT:
-                    if (DBG) logd("User rejected incoming request");
-                    transitionTo(mGroupCreatedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        @Override
-        public void exit() {
-            //TODO: dismiss dialog if not already done
-        }
-    }
-
-    class OngoingGroupRemovalState extends State {
-        @Override
-        public void enter() {
-            if (DBG) logd(getName());
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) logd(getName() + message.toString());
-            switch (message.what) {
-                // Group removal ongoing. Multiple calls
-                // end up removing persisted network. Do nothing.
-                case WifiP2pManager.REMOVE_GROUP:
-                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
-                    break;
-                // Parent state will transition out of this state
-                // when removal is complete
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
-        pw.println("mWifiP2pInfo " + mWifiP2pInfo);
-        pw.println("mGroup " + mGroup);
-        pw.println("mSavedPeerConfig " + mSavedPeerConfig);
-        pw.println("mSavedP2pGroup " + mSavedP2pGroup);
-        pw.println();
-    }
-
-    private void sendP2pStateChangedBroadcast(boolean enabled) {
-        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        if (enabled) {
-            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
-                    WifiP2pManager.WIFI_P2P_STATE_ENABLED);
-        } else {
-            intent.putExtra(WifiP2pManager.EXTRA_WIFI_STATE,
-                    WifiP2pManager.WIFI_P2P_STATE_DISABLED);
-        }
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendP2pDiscoveryChangedBroadcast(boolean started) {
-        if (mDiscoveryStarted == started) return;
-        mDiscoveryStarted = started;
-
-        if (DBG) logd("discovery change broadcast " + started);
-
-        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, started ?
-                WifiP2pManager.WIFI_P2P_DISCOVERY_STARTED :
-                WifiP2pManager.WIFI_P2P_DISCOVERY_STOPPED);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendThisDeviceChangedBroadcast() {
-        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice));
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendPeersChangedBroadcast() {
-        final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
-        intent.putExtra(WifiP2pManager.EXTRA_P2P_DEVICE_LIST, new WifiP2pDeviceList(mPeers));
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void sendP2pConnectionChangedBroadcast() {
-        if (DBG) logd("sending p2p connection changed broadcast");
-        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
-                | Intent.FLAG_RECEIVER_REPLACE_PENDING);
-        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO, new WifiP2pInfo(mWifiP2pInfo));
-        intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
-        intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP, new WifiP2pGroup(mGroup));
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-        mWifiChannel.sendMessage(WifiP2pService.P2P_CONNECTION_CHANGED,
-                new NetworkInfo(mNetworkInfo));
-    }
-
-    private void sendP2pPersistentGroupsChangedBroadcast() {
-        if (DBG) logd("sending p2p persistent groups changed broadcast");
-        Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
-    }
-
-    private void startDhcpServer(String intf) {
-        InterfaceConfiguration ifcg = null;
-        try {
-            ifcg = mNwService.getInterfaceConfig(intf);
-            ifcg.setLinkAddress(new LinkAddress(NetworkUtils.numericToInetAddress(
-                        SERVER_ADDRESS), 24));
-            ifcg.setInterfaceUp();
-            mNwService.setInterfaceConfig(intf, ifcg);
-            /* This starts the dnsmasq server */
-            mNwService.startTethering(DHCP_RANGE);
-        } catch (Exception e) {
-            loge("Error configuring interface " + intf + ", :" + e);
-            return;
-        }
-
-        logd("Started Dhcp server on " + intf);
-   }
-
-    private void stopDhcpServer(String intf) {
-        try {
-            mNwService.stopTethering();
-        } catch (Exception e) {
-            loge("Error stopping Dhcp server" + e);
-            return;
-        }
-
-        logd("Stopped Dhcp server");
-    }
-
-    private void notifyP2pEnableFailure() {
-        Resources r = Resources.getSystem();
-        AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_dialog_title))
-            .setMessage(r.getString(R.string.wifi_p2p_failed_message))
-            .setPositiveButton(r.getString(R.string.ok), null)
-            .create();
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
-    private void addRowToDialog(ViewGroup group, int stringId, String value) {
-        Resources r = Resources.getSystem();
-        View row = LayoutInflater.from(mContext).inflate(R.layout.wifi_p2p_dialog_row,
-                group, false);
-        ((TextView) row.findViewById(R.id.name)).setText(r.getString(stringId));
-        ((TextView) row.findViewById(R.id.value)).setText(value);
-        group.addView(row);
-    }
-
-    private void notifyInvitationSent(String pin, String peerAddress) {
-        Resources r = Resources.getSystem();
-
-        final View textEntryView = LayoutInflater.from(mContext)
-                .inflate(R.layout.wifi_p2p_dialog, null);
-
-        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
-        addRowToDialog(group, R.string.wifi_p2p_to_message, getDeviceName(peerAddress));
-        addRowToDialog(group, R.string.wifi_p2p_show_pin_message, pin);
-
-        AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_invitation_sent_title))
-            .setView(textEntryView)
-            .setPositiveButton(r.getString(R.string.ok), null)
-            .create();
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
-    private void notifyInvitationReceived() {
-        Resources r = Resources.getSystem();
-        final WpsInfo wps = mSavedPeerConfig.wps;
-        final View textEntryView = LayoutInflater.from(mContext)
-                .inflate(R.layout.wifi_p2p_dialog, null);
-
-        ViewGroup group = (ViewGroup) textEntryView.findViewById(R.id.info);
-        addRowToDialog(group, R.string.wifi_p2p_from_message, getDeviceName(
-                mSavedPeerConfig.deviceAddress));
-
-        final EditText pin = (EditText) textEntryView.findViewById(R.id.wifi_p2p_wps_pin);
-
-        AlertDialog dialog = new AlertDialog.Builder(mContext)
-            .setTitle(r.getString(R.string.wifi_p2p_invitation_to_connect_title))
-            .setView(textEntryView)
-            .setPositiveButton(r.getString(R.string.accept), new OnClickListener() {
-                        public void onClick(DialogInterface dialog, int which) {
-                            if (wps.setup == WpsInfo.KEYPAD) {
-                                mSavedPeerConfig.wps.pin = pin.getText().toString();
-                            }
-                            if (DBG) logd(getName() + " accept invitation " + mSavedPeerConfig);
-                            sendMessage(PEER_CONNECTION_USER_ACCEPT);
-                        }
-                    })
-            .setNegativeButton(r.getString(R.string.decline), new OnClickListener() {
-                        @Override
-                        public void onClick(DialogInterface dialog, int which) {
-                            if (DBG) logd(getName() + " ignore connect");
-                            sendMessage(PEER_CONNECTION_USER_REJECT);
-                        }
-                    })
-            .setOnCancelListener(new DialogInterface.OnCancelListener() {
-                        @Override
-                        public void onCancel(DialogInterface arg0) {
-                            if (DBG) logd(getName() + " ignore connect");
-                            sendMessage(PEER_CONNECTION_USER_REJECT);
-                        }
-                    })
-            .create();
-
-        //make the enter pin area or the display pin area visible
-        switch (wps.setup) {
-            case WpsInfo.KEYPAD:
-                if (DBG) logd("Enter pin section visible");
-                textEntryView.findViewById(R.id.enter_pin_section).setVisibility(View.VISIBLE);
-                break;
-            case WpsInfo.DISPLAY:
-                if (DBG) logd("Shown pin section visible");
-                addRowToDialog(group, R.string.wifi_p2p_show_pin_message, wps.pin);
-                break;
-            default:
-                break;
-        }
-
-        if ((r.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_APPLIANCE) ==
-                Configuration.UI_MODE_TYPE_APPLIANCE) {
-            // For appliance devices, add a key listener which accepts.
-            dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
-
-                @Override
-                public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-                    // TODO: make the actual key come from a config value.
-                    if (keyCode == KeyEvent.KEYCODE_VOLUME_MUTE) {
-                        sendMessage(PEER_CONNECTION_USER_ACCEPT);
-                        dialog.dismiss();
-                        return true;
-                    }
-                    return false;
-                }
-            });
-            // TODO: add timeout for this dialog.
-            // TODO: update UI in appliance mode to tell user what to do.
-        }
-
-        dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        dialog.show();
-    }
-
-    /**
-     * Synchronize the persistent group list between
-     * wpa_supplicant and mGroups.
-     */
-    private void updatePersistentNetworks(boolean reload) {
-        String listStr = mWifiNative.listNetworks();
-        if (listStr == null) return;
-
-        boolean isSaveRequired = false;
-        String[] lines = listStr.split("\n");
-        if (lines == null) return;
-
-        if (reload) mGroups.clear();
-
-        // Skip the first line, which is a header
-        for (int i = 1; i < lines.length; i++) {
-            String[] result = lines[i].split("\t");
-            if (result == null || result.length < 4) {
-                continue;
-            }
-            // network-id | ssid | bssid | flags
-            int netId = -1;
-            String ssid = result[1];
-            String bssid = result[2];
-            String flags = result[3];
-            try {
-                netId = Integer.parseInt(result[0]);
-            } catch(NumberFormatException e) {
-                e.printStackTrace();
-                continue;
-            }
-
-            if (flags.indexOf("[CURRENT]") != -1) {
-                continue;
-            }
-            if (flags.indexOf("[P2P-PERSISTENT]") == -1) {
-                /*
-                 * The unused profile is sometimes remained when the p2p group formation is failed.
-                 * So, we clean up the p2p group here.
-                 */
-                if (DBG) logd("clean up the unused persistent group. netId=" + netId);
-                mWifiNative.removeNetwork(netId);
-                isSaveRequired = true;
-                continue;
-            }
-
-            if (mGroups.contains(netId)) {
-                continue;
-            }
-
-            WifiP2pGroup group = new WifiP2pGroup();
-            group.setNetworkId(netId);
-            group.setNetworkName(ssid);
-            String mode = mWifiNative.getNetworkVariable(netId, "mode");
-            if (mode != null && mode.equals("3")) {
-                group.setIsGroupOwner(true);
-            }
-            if (bssid.equalsIgnoreCase(mThisDevice.deviceAddress)) {
-                group.setOwner(mThisDevice);
-            } else {
-                WifiP2pDevice device = new WifiP2pDevice();
-                device.deviceAddress = bssid;
-                group.setOwner(device);
-            }
-            mGroups.add(group);
-            isSaveRequired = true;
-        }
-
-        if (reload || isSaveRequired) {
-            mWifiNative.saveConfig();
-            sendP2pPersistentGroupsChangedBroadcast();
-        }
-    }
-
-    /**
-     * A config is valid if it has a peer address that has already been
-     * discovered
-     * @return true if it is invalid, false otherwise
-     */
-    private boolean isConfigInvalid(WifiP2pConfig config) {
-        if (config == null) return true;
-        if (TextUtils.isEmpty(config.deviceAddress)) return true;
-        if (mPeers.get(config.deviceAddress) == null) return true;
-        return false;
-    }
-
-    /* TODO: The supplicant does not provide group capability changes as an event.
-     * Having it pushed as an event would avoid polling for this information right
-     * before a connection
-     */
-    private WifiP2pDevice fetchCurrentDeviceDetails(WifiP2pConfig config) {
-        /* Fetch & update group capability from supplicant on the device */
-        int gc = mWifiNative.getGroupCapability(config.deviceAddress);
-        mPeers.updateGroupCapability(config.deviceAddress, gc);
-        return mPeers.get(config.deviceAddress);
-    }
-
-    /**
-     * Start a p2p group negotiation and display pin if necessary
-     * @param config for the peer
-     */
-    private void p2pConnectWithPinDisplay(WifiP2pConfig config) {
-        WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
-
-        String pin = mWifiNative.p2pConnect(config, dev.isGroupOwner());
-        try {
-            Integer.parseInt(pin);
-            notifyInvitationSent(pin, config.deviceAddress);
-        } catch (NumberFormatException ignore) {
-            // do nothing if p2pConnect did not return a pin
-        }
-    }
-
-    /**
-     * Reinvoke a persistent group.
-     *
-     * @param config for the peer
-     * @return true on success, false on failure
-     */
-    private boolean reinvokePersistentGroup(WifiP2pConfig config) {
-        WifiP2pDevice dev = fetchCurrentDeviceDetails(config);
-
-        boolean join = dev.isGroupOwner();
-        String ssid = mWifiNative.p2pGetSsid(dev.deviceAddress);
-        if (DBG) logd("target ssid is " + ssid + " join:" + join);
-
-        if (join && dev.isGroupLimit()) {
-            if (DBG) logd("target device reaches group limit.");
-
-            // if the target group has reached the limit,
-            // try group formation.
-            join = false;
-        } else if (join) {
-            int netId = mGroups.getNetworkId(dev.deviceAddress, ssid);
-            if (netId >= 0) {
-                // Skip WPS and start 4way handshake immediately.
-                if (!mWifiNative.p2pGroupAdd(netId)) {
-                    return false;
-                }
-                return true;
-            }
-        }
-
-        if (!join && dev.isDeviceLimit()) {
-            loge("target device reaches the device limit.");
-            return false;
-        }
-
-        if (!join && dev.isInvitationCapable()) {
-            int netId = WifiP2pGroup.PERSISTENT_NET_ID;
-            if (config.netId >= 0) {
-                if (config.deviceAddress.equals(mGroups.getOwnerAddr(config.netId))) {
-                    netId = config.netId;
-                }
-            } else {
-                netId = mGroups.getNetworkId(dev.deviceAddress);
-            }
-            if (netId < 0) {
-                netId = getNetworkIdFromClientList(dev.deviceAddress);
-            }
-            if (DBG) logd("netId related with " + dev.deviceAddress + " = " + netId);
-            if (netId >= 0) {
-                // Invoke the persistent group.
-                if (mWifiNative.p2pReinvoke(netId, dev.deviceAddress)) {
-                    // Save network id. It'll be used when an invitation result event is received.
-                    config.netId = netId;
-                    return true;
-                } else {
-                    loge("p2pReinvoke() failed, update networks");
-                    updatePersistentNetworks(RELOAD);
-                    return false;
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Return the network id of the group owner profile which has the p2p client with
-     * the specified device address in it's client list.
-     * If more than one persistent group of the same address is present in its client
-     * lists, return the first one.
-     *
-     * @param deviceAddress p2p device address.
-     * @return the network id. if not found, return -1.
-     */
-    private int getNetworkIdFromClientList(String deviceAddress) {
-        if (deviceAddress == null) return -1;
-
-        Collection<WifiP2pGroup> groups = mGroups.getGroupList();
-        for (WifiP2pGroup group : groups) {
-            int netId = group.getNetworkId();
-            String[] p2pClientList = getClientList(netId);
-            if (p2pClientList == null) continue;
-            for (String client : p2pClientList) {
-                if (deviceAddress.equalsIgnoreCase(client)) {
-                    return netId;
-                }
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Return p2p client list associated with the specified network id.
-     * @param netId network id.
-     * @return p2p client list. if not found, return null.
-     */
-    private String[] getClientList(int netId) {
-        String p2pClients = mWifiNative.getNetworkVariable(netId, "p2p_client_list");
-        if (p2pClients == null) {
-            return null;
-        }
-        return p2pClients.split(" ");
-    }
-
-    /**
-     * Remove the specified p2p client from the specified profile.
-     * @param netId network id of the profile.
-     * @param addr p2p client address to be removed.
-     * @param isRemovable if true, remove the specified profile if its client list becomes empty.
-     * @return whether removing the specified p2p client is successful or not.
-     */
-    private boolean removeClientFromList(int netId, String addr, boolean isRemovable) {
-        StringBuilder modifiedClientList =  new StringBuilder();
-        String[] currentClientList = getClientList(netId);
-        boolean isClientRemoved = false;
-        if (currentClientList != null) {
-            for (String client : currentClientList) {
-                if (!client.equalsIgnoreCase(addr)) {
-                    modifiedClientList.append(" ");
-                    modifiedClientList.append(client);
-                } else {
-                    isClientRemoved = true;
-                }
-            }
-        }
-        if (modifiedClientList.length() == 0 && isRemovable) {
-            // the client list is empty. so remove it.
-            if (DBG) logd("Remove unknown network");
-            mGroups.remove(netId);
-            return true;
-        }
-
-        if (!isClientRemoved) {
-            // specified p2p client is not found. already removed.
-            return false;
-        }
-
-        if (DBG) logd("Modified client list: " + modifiedClientList);
-        if (modifiedClientList.length() == 0) {
-            modifiedClientList.append("\"\"");
-        }
-        mWifiNative.setNetworkVariable(netId,
-                "p2p_client_list", modifiedClientList.toString());
-        mWifiNative.saveConfig();
-        return true;
-    }
-
-    private void setWifiP2pInfoOnGroupFormation(InetAddress serverInetAddress) {
-        mWifiP2pInfo.groupFormed = true;
-        mWifiP2pInfo.isGroupOwner = mGroup.isGroupOwner();
-        mWifiP2pInfo.groupOwnerAddress = serverInetAddress;
-    }
-
-    private void resetWifiP2pInfo() {
-        mWifiP2pInfo.groupFormed = false;
-        mWifiP2pInfo.isGroupOwner = false;
-        mWifiP2pInfo.groupOwnerAddress = null;
-    }
-
-    private String getDeviceName(String deviceAddress) {
-        WifiP2pDevice d = mPeers.get(deviceAddress);
-        if (d != null) {
-                return d.deviceName;
-        }
-        //Treat the address as name if there is no match
-        return deviceAddress;
-    }
-
-    private String getPersistedDeviceName() {
-        String deviceName = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.WIFI_P2P_DEVICE_NAME);
-        if (deviceName == null) {
-            /* We use the 4 digits of the ANDROID_ID to have a friendly
-             * default that has low likelihood of collision with a peer */
-            String id = Settings.Secure.getString(mContext.getContentResolver(),
-                    Settings.Secure.ANDROID_ID);
-            return "Android_" + id.substring(0,4);
-        }
-        return deviceName;
-    }
-
-    private boolean setAndPersistDeviceName(String devName) {
-        if (devName == null) return false;
-
-        if (!mWifiNative.setDeviceName(devName)) {
-            loge("Failed to set device name " + devName);
-            return false;
-        }
-
-        mThisDevice.deviceName = devName;
-        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
-
-        Settings.Global.putString(mContext.getContentResolver(),
-                Settings.Global.WIFI_P2P_DEVICE_NAME, devName);
-        sendThisDeviceChangedBroadcast();
-        return true;
-    }
-
-    private boolean setWfdInfo(WifiP2pWfdInfo wfdInfo) {
-        boolean success;
-
-        if (!wfdInfo.isWfdEnabled()) {
-            success = mWifiNative.setWfdEnable(false);
-        } else {
-            success =
-                mWifiNative.setWfdEnable(true)
-                && mWifiNative.setWfdDeviceInfo(wfdInfo.getDeviceInfoHex());
-        }
-
-        if (!success) {
-            loge("Failed to set wfd properties");
-            return false;
-        }
-
-        mThisDevice.wfdInfo = wfdInfo;
-        sendThisDeviceChangedBroadcast();
-        return true;
-    }
-
-    private void initializeP2pSettings() {
-        mWifiNative.setPersistentReconnect(true);
-        mThisDevice.deviceName = getPersistedDeviceName();
-        mWifiNative.setDeviceName(mThisDevice.deviceName);
-        // DIRECT-XY-DEVICENAME (XY is randomly generated)
-        mWifiNative.setP2pSsidPostfix("-" + mThisDevice.deviceName);
-        mWifiNative.setDeviceType(mThisDevice.primaryDeviceType);
-        // Supplicant defaults to using virtual display with display
-        // which refers to a remote display. Use physical_display
-        mWifiNative.setConfigMethods("virtual_push_button physical_display keypad");
-        // STA has higher priority over P2P
-        mWifiNative.setConcurrencyPriority("sta");
-
-        mThisDevice.deviceAddress = mWifiNative.p2pGetDeviceAddress();
-        updateThisDevice(WifiP2pDevice.AVAILABLE);
-        if (DBG) logd("DeviceAddress: " + mThisDevice.deviceAddress);
-
-        mClientInfoList.clear();
-        mWifiNative.p2pFlush();
-        mWifiNative.p2pServiceFlush();
-        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);
-    }
-
-    private void updateThisDevice(int status) {
-        mThisDevice.status = status;
-        sendThisDeviceChangedBroadcast();
-    }
-
-    private void handleGroupCreationFailure() {
-        resetWifiP2pInfo();
-        mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.FAILED, null, null);
-        sendP2pConnectionChangedBroadcast();
-
-        // Remove only the peer we failed to connect to so that other devices discovered
-        // that have not timed out still remain in list for connection
-        boolean peersChanged = mPeers.remove(mPeersLostDuringConnection);
-        if (mPeers.remove(mSavedPeerConfig.deviceAddress) != null) {
-            peersChanged = true;
-        }
-        if (peersChanged) {
-            sendPeersChangedBroadcast();
-        }
-
-        mPeersLostDuringConnection.clear();
-        mServiceDiscReqId = null;
-        sendMessage(WifiP2pManager.DISCOVER_PEERS);
-    }
-
-    private void handleGroupRemoved() {
-        if (mGroup.isGroupOwner()) {
-            stopDhcpServer(mGroup.getInterface());
-        } else {
-            if (DBG) logd("stop DHCP client");
-            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-            mDhcpStateMachine.doQuit();
-            mDhcpStateMachine = null;
-        }
-
-        try {
-            mNwService.clearInterfaceAddresses(mGroup.getInterface());
-        } catch (Exception e) {
-            loge("Failed to clear addresses " + e);
-        }
-        NetworkUtils.resetConnections(mGroup.getInterface(), NetworkUtils.RESET_ALL_ADDRESSES);
-
-        // Clear any timeout that was set. This is essential for devices
-        // that reuse the main p2p interface for a created group.
-        mWifiNative.setP2pGroupIdle(mGroup.getInterface(), 0);
-
-        boolean peersChanged = false;
-        // Remove only peers part of the group, so that other devices discovered
-        // that have not timed out still remain in list for connection
-        for (WifiP2pDevice d : mGroup.getClientList()) {
-            if (mPeers.remove(d)) peersChanged = true;
-        }
-        if (mPeers.remove(mGroup.getOwner())) peersChanged = true;
-        if (mPeers.remove(mPeersLostDuringConnection)) peersChanged = true;
-        if (peersChanged) {
-            sendPeersChangedBroadcast();
-        }
-
-        mGroup = null;
-        mPeersLostDuringConnection.clear();
-        mServiceDiscReqId = null;
-
-        if (mTempoarilyDisconnectedWifi) {
-            mWifiChannel.sendMessage(WifiP2pService.DISCONNECT_WIFI_REQUEST, 0);
-            mTempoarilyDisconnectedWifi = false;
-        }
-   }
-
-    //State machine initiated requests can have replyTo set to null indicating
-    //there are no recipients, we ignore those reply actions
-    private void replyToMessage(Message msg, int what) {
-        if (msg.replyTo == null) return;
-        Message dstMsg = obtainMessage(msg);
-        dstMsg.what = what;
-        mReplyChannel.replyToMessage(msg, dstMsg);
-    }
-
-    private void replyToMessage(Message msg, int what, int arg1) {
-        if (msg.replyTo == null) return;
-        Message dstMsg = obtainMessage(msg);
-        dstMsg.what = what;
-        dstMsg.arg1 = arg1;
-        mReplyChannel.replyToMessage(msg, dstMsg);
-    }
-
-    private void replyToMessage(Message msg, int what, Object obj) {
-        if (msg.replyTo == null) return;
-        Message dstMsg = obtainMessage(msg);
-        dstMsg.what = what;
-        dstMsg.obj = obj;
-        mReplyChannel.replyToMessage(msg, dstMsg);
-    }
-
-    /* arg2 on the source message has a hash code that needs to be retained in replies
-     * see WifiP2pManager for details */
-    private Message obtainMessage(Message srcMsg) {
-        Message msg = Message.obtain();
-        msg.arg2 = srcMsg.arg2;
-        return msg;
-    }
-
-    @Override
-    protected void logd(String s) {
-        Slog.d(TAG, s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        Slog.e(TAG, s);
-    }
-
-    /**
-     * Update service discovery request to wpa_supplicant.
-     */
-    private boolean updateSupplicantServiceRequest() {
-        clearSupplicantServiceRequest();
-
-        StringBuffer sb = new StringBuffer();
-        for (ClientInfo c: mClientInfoList.values()) {
-            int key;
-            WifiP2pServiceRequest req;
-            for (int i=0; i < c.mReqList.size(); i++) {
-                req = c.mReqList.valueAt(i);
-                if (req != null) {
-                    sb.append(req.getSupplicantQuery());
-                }
-            }
-        }
-
-        if (sb.length() == 0) {
-            return false;
-        }
-
-        mServiceDiscReqId = mWifiNative.p2pServDiscReq("00:00:00:00:00:00", sb.toString());
-        if (mServiceDiscReqId == null) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Clear service discovery request in wpa_supplicant
-     */
-    private void clearSupplicantServiceRequest() {
-        if (mServiceDiscReqId == null) return;
-
-        mWifiNative.p2pServDiscCancelReq(mServiceDiscReqId);
-        mServiceDiscReqId = null;
-    }
-
-    /* TODO: We could track individual service adds separately and avoid
-     * having to do update all service requests on every new request
-     */
-    private boolean addServiceRequest(Messenger m, WifiP2pServiceRequest req) {
-        clearClientDeadChannels();
-        ClientInfo clientInfo = getClientInfo(m, true);
-        if (clientInfo == null) {
-            return false;
-        }
-
-        ++mServiceTransactionId;
-        //The Wi-Fi p2p spec says transaction id should be non-zero
-        if (mServiceTransactionId == 0) ++mServiceTransactionId;
-        req.setTransactionId(mServiceTransactionId);
-        clientInfo.mReqList.put(mServiceTransactionId, req);
-
-        if (mServiceDiscReqId == null) {
-            return true;
-        }
-
-        return updateSupplicantServiceRequest();
-    }
-
-    private void removeServiceRequest(Messenger m, WifiP2pServiceRequest req) {
-        ClientInfo clientInfo = getClientInfo(m, false);
-        if (clientInfo == null) {
-            return;
-        }
-
-        //Application does not have transaction id information
-        //go through stored requests to remove
-        boolean removed = false;
-        for (int i=0; i<clientInfo.mReqList.size(); i++) {
-            if (req.equals(clientInfo.mReqList.valueAt(i))) {
-                removed = true;
-                clientInfo.mReqList.removeAt(i);
-                break;
-            }
-        }
-
-        if (!removed) return;
-
-        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
-            if (DBG) logd("remove client information from framework");
-            mClientInfoList.remove(clientInfo.mMessenger);
-        }
-
-        if (mServiceDiscReqId == null) {
-            return;
-        }
-
-        updateSupplicantServiceRequest();
-    }
-
-    private void clearServiceRequests(Messenger m) {
-
-        ClientInfo clientInfo = getClientInfo(m, false);
-        if (clientInfo == null) {
-            return;
-        }
-
-        if (clientInfo.mReqList.size() == 0) {
-            return;
-        }
-
-        clientInfo.mReqList.clear();
-
-        if (clientInfo.mServList.size() == 0) {
-            if (DBG) logd("remove channel information from framework");
-            mClientInfoList.remove(clientInfo.mMessenger);
-        }
-
-        if (mServiceDiscReqId == null) {
-            return;
-        }
-
-        updateSupplicantServiceRequest();
-    }
-
-    private boolean addLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
-        clearClientDeadChannels();
-        ClientInfo clientInfo = getClientInfo(m, true);
-        if (clientInfo == null) {
-            return false;
-        }
-
-        if (!clientInfo.mServList.add(servInfo)) {
-            return false;
-        }
-
-        if (!mWifiNative.p2pServiceAdd(servInfo)) {
-            clientInfo.mServList.remove(servInfo);
-            return false;
-        }
-
-        return true;
-    }
-
-    private void removeLocalService(Messenger m, WifiP2pServiceInfo servInfo) {
-        ClientInfo clientInfo = getClientInfo(m, false);
-        if (clientInfo == null) {
-            return;
-        }
-
-        mWifiNative.p2pServiceDel(servInfo);
-
-        clientInfo.mServList.remove(servInfo);
-        if (clientInfo.mReqList.size() == 0 && clientInfo.mServList.size() == 0) {
-            if (DBG) logd("remove client information from framework");
-            mClientInfoList.remove(clientInfo.mMessenger);
-        }
-    }
-
-    private void clearLocalServices(Messenger m) {
-        ClientInfo clientInfo = getClientInfo(m, false);
-        if (clientInfo == null) {
-            return;
-        }
-
-        for (WifiP2pServiceInfo servInfo: clientInfo.mServList) {
-            mWifiNative.p2pServiceDel(servInfo);
-        }
-
-        clientInfo.mServList.clear();
-        if (clientInfo.mReqList.size() == 0) {
-            if (DBG) logd("remove client information from framework");
-            mClientInfoList.remove(clientInfo.mMessenger);
-        }
-    }
-
-    private void clearClientInfo(Messenger m) {
-        clearLocalServices(m);
-        clearServiceRequests(m);
-    }
-
-    /**
-     * Send the service response to the WifiP2pManager.Channel.
-     *
-     * @param resp
-     */
-    private void sendServiceResponse(WifiP2pServiceResponse resp) {
-        for (ClientInfo c : mClientInfoList.values()) {
-            WifiP2pServiceRequest req = c.mReqList.get(resp.getTransactionId());
-            if (req != null) {
-                Message msg = Message.obtain();
-                msg.what = WifiP2pManager.RESPONSE_SERVICE;
-                msg.arg1 = 0;
-                msg.arg2 = 0;
-                msg.obj = resp;
-                try {
-                    c.mMessenger.send(msg);
-                } catch (RemoteException e) {
-                    if (DBG) logd("detect dead channel");
-                    clearClientInfo(c.mMessenger);
-                    return;
-                }
-            }
-        }
-    }
-
-    /**
-     * We dont get notifications of clients that have gone away.
-     * We detect this actively when services are added and throw
-     * them away.
-     *
-     * TODO: This can be done better with full async channels.
-     */
-    private void clearClientDeadChannels() {
-        ArrayList<Messenger> deadClients = new ArrayList<Messenger>();
-
-        for (ClientInfo c : mClientInfoList.values()) {
-            Message msg = Message.obtain();
-            msg.what = WifiP2pManager.PING;
-            msg.arg1 = 0;
-            msg.arg2 = 0;
-            msg.obj = null;
-            try {
-                c.mMessenger.send(msg);
-            } catch (RemoteException e) {
-                if (DBG) logd("detect dead channel");
-                deadClients.add(c.mMessenger);
-            }
-        }
-
-        for (Messenger m : deadClients) {
-            clearClientInfo(m);
-        }
-    }
-
-    /**
-     * Return the specified ClientInfo.
-     * @param m Messenger
-     * @param createIfNotExist if true and the specified channel info does not exist,
-     * create new client info.
-     * @return the specified ClientInfo.
-     */
-    private ClientInfo getClientInfo(Messenger m, boolean createIfNotExist) {
-        ClientInfo clientInfo = mClientInfoList.get(m);
-
-        if (clientInfo == null && createIfNotExist) {
-            if (DBG) logd("add a new client");
-            clientInfo = new ClientInfo(m);
-            mClientInfoList.put(m, clientInfo);
-        }
-
-        return clientInfo;
-    }
-
-    }
-
-    /**
-     * Information about a particular client and we track the service discovery requests
-     * and the local services registered by the client.
-     */
-    private class ClientInfo {
-
-        /*
-         * A reference to WifiP2pManager.Channel handler.
-         * The response of this request is notified to WifiP2pManager.Channel handler
-         */
-        private Messenger mMessenger;
-
-        /*
-         * A service discovery request list.
-         */
-        private SparseArray<WifiP2pServiceRequest> mReqList;
-
-        /*
-         * A local service information list.
-         */
-        private List<WifiP2pServiceInfo> mServList;
-
-        private ClientInfo(Messenger m) {
-            mMessenger = m;
-            mReqList = new SparseArray();
-            mServList = new ArrayList<WifiP2pServiceInfo>();
-        }
-    }
-}